Browse Source

fix: 修改bug

wuguojie 7 months ago
parent
commit
17f7235f84

+ 1 - 1
src/api/index.ts

@@ -80,7 +80,7 @@ axiosInstance.interceptors.response.use(
       if (response.data.msg !== '') {
         // 错误提示
         Message.error(response.data.msg, {
-          zIndex: 2000,
+          zIndex: 9000,
         })
         return Promise.resolve(response.data)
       }

+ 3 - 1
src/api/modules/agreement.ts

@@ -23,7 +23,9 @@ const agreementApi = (axiosInstance: ApiInstance) => ({
   sysUpAndDown: (data: Types.sysUpAndDownRequest) => axiosInstance.post('agreement/sysUpAndDown', data),
   //批量删除
   agreementDelete: (ids: any) => axiosInstance.delete(`/agreement/agreementDelete?ids=${ids}`),
-  //获取保险公司数结构
+  // 新的费用批量删除
+  deleteByIds: (data: any) => axiosInstance.post('/ptlAgreementCost/deleteByIds', data),
+//获取保险公司数结构
   findTree: (data: any) => axiosInstance.post('esmInsCompany/findTree', data),
   //复制协议
   agreementCopy: (data: any) => axiosInstance.post('/agreement/agreementCopy', data),

+ 4 - 2
src/components/SearchForm/index.vue

@@ -6,7 +6,7 @@
           <component v-if="field.type === 'input'" is="el-input" v-model="formInline[field.model]"
             :placeholder="field.placeholder" clearable class="el-inputs" />
           <component v-else-if="field.type === 'select'" is="el-select" v-model="formInline[field.model]"
-            :placeholder="field.placeholder" clearable class="el-inputs" v-bind="field">
+            :placeholder="field.placeholder" clearable class="el-inputs" v-bind="field" :filterable="field.filterable">
             <el-option v-for="(item, index) in field.options" :key="index" :label="item.label" :value="item.value" />
           </component>
           <component v-else-if="field.type === 'cascader'" is="el-cascader" v-model="formInline[field.model]"
@@ -41,6 +41,7 @@ const props = withDefaults(defineProps<{
     label: string; // 字段标签
     model: string; // v-model 绑定的字段名
     type: string; // 字段类型 ('input', 'select', 'cascader', 'date')
+    filterable?: boolean; // 是否支持筛选
     placeholder?: string; // 占位符
     options?: Array<{ [key: string]: any }>; // 选项列表
     props?: any; // Cascader 组件的其他 props
@@ -56,6 +57,7 @@ const props = withDefaults(defineProps<{
 }>(), {
   span: 8,
   isOffset: false,
+  filterable: false
 });
 const windowWidth = ref(window.innerWidth);
 
@@ -92,7 +94,7 @@ const btnOffset = computed(() => {
 
 	if (itemsOnLastRow === 0) {
 		// 如果刚好占满最后一行,按钮就需要另起一行,并偏移3个位置
-		return (columns - 1) * spanPerItem; 
+		return (columns - 1) * spanPerItem;
 	} else {
 		// 如果最后一行没占满,计算需要空出的位置数量
 		const emptySlots = columns - 1 - itemsOnLastRow;

+ 42 - 4
src/components/ruleCondition/index.vue

@@ -8,7 +8,7 @@
             @keydown.enter="handleEnter" @clear="ruleAttr" />
           <el-button @click="ruleAttr" type="primary">查找</el-button>
         </div>
-        <div class="conditionSet flex ">
+        <div class="conditionSet flex " v-if="searchShow">
           <div class="tabLeft">
             <ul>
               <li :class="{ active: item.name == activename }" v-for="(item, index) in typeList" :key="index"
@@ -44,6 +44,12 @@
             </el-checkbox-group>
           </div>
         </div>
+        <div class="selectList" v-else>
+            <el-checkbox-group v-model="checked.SearchDataStore" @change="change($event, 'SearchDataStore')"
+                               v-for="(item, index) in dataStore.SearchDataStore" :key="index">
+                <el-checkbox v-model="item.id" :label="item.attrName" :value="item.attrName" size="large" />
+            </el-checkbox-group>
+        </div>
       </div>
       <template #footer>
         <div class="dialog-footer">
@@ -81,14 +87,19 @@ watch(props, () => {
     attractivelist.value = props.attrIdList;//获取编辑数据
     const matchedid = matchDataByIds(attractivelist.value);//
     const matchedinfo = matchDataByInfos(attractivelist.value)
-      console.log('编辑的数据', attractivelist.value)
+      console.log('编辑的数据: attractivelist', attractivelist.value)
+      console.log('编辑的数据: matchedid', matchedid)
+      console.log('编辑的数据: matchedinfo', matchedinfo)
     Object.keys(checked).forEach(key => { //复选框回显
       checked[key as keyof checkeddata] = matchedid[key] || [];
     });
     Object.keys(checked).forEach(key => {//条件数据回显
       checkeddata[key as keyof checkeddata] = matchedinfo[key] || [];
     });
-
+    checkeddata['SearchDataStore'] = attractivelist.value
+    checked['SearchDataStore'] = attractivelist.value?.map(item => {
+        return item.attrName
+    })
   }
 
 })
@@ -134,6 +145,7 @@ const checked = reactive<checkeddata>({
   InsuredInformation: [],//车主信息
   InsuranceInformation: [], //车主信息
   InsuranceCostFactor: [],//保司费用因子
+  SearchDataStore: []
 })
 const licensePlateRegion = ref();//车牌地区
 const licensePlateNumber = ref();//车牌号
@@ -209,6 +221,7 @@ const dataStore = reactive<dataStore>({
     InsuredInformation: [],//车主信息
     InsuranceInformation: [], //车主信息
     InsuranceCostFactor: [],//保司费用因子
+    SearchDataStore: [], // 搜索后合并的数据
 })
 interface checkeddata {
   [key: string]: any[]
@@ -220,6 +233,7 @@ const checkeddata = reactive<checkeddata>({
   InsuredInformation: [],//车主信息
   InsuranceInformation: [], //车主信息
   InsuranceCostFactor: [],//保司费用因子
+  SearchDataStore: [], // 搜索后合并的数据
 });
 //已勾选的规则集合
 interface VehicleInformation {
@@ -233,15 +247,24 @@ interface dataStore {
     InsuredInformation: VehicleInformation[],
     InsuranceInformation: VehicleInformation[],
     InsuranceCostFactor: VehicleInformation[],
+    SearchDataStore: VehicleInformation[],
 }
 
 onMounted(() => {
   ruleAttr();
   regionLicenseRegion('0');//车牌地区
   regionLicenseNumber('14');//车牌号
+
 })
 
+
+let searchShow = ref(true)
 const ruleAttr = () => {
+    if(attrName.value) {
+        searchShow.value = false
+    } else {
+        searchShow.value = true
+    }
   api.agreementApi.ruleAttrGroup({ attrName: attrName.value }).then((res: any) => {
     if (res.code == '200') {
       dataStore.VehicleInformation = res.data.VehicleInformation ? processArray(res.data.VehicleInformation) : [];
@@ -250,13 +273,13 @@ const ruleAttr = () => {
       dataStore.InsuredInformation = res.data.InsuredInformation ? processArray(res.data.InsuredInformation) : [];
       dataStore.InsuranceInformation = res.data.InsuranceInformation ? processArray(res.data.InsuranceInformation) : [];
       dataStore.InsuranceCostFactor = res.data.InsuranceCostFactor ? processArray(res.data.InsuranceCostFactor) : [];
+      dataStore.SearchDataStore = [...dataStore.VehicleInformation, ...dataStore.VehicleOwnerInformation, ...dataStore.PolicyholderInformation, ...dataStore.InsuredInformation, ...dataStore.InsuranceInformation, ...dataStore.InsuranceCostFactor ]
     }
   });
 }
 //选择事件集中处理
 type title = keyof typeof dataStore;
 const change = (value: any, title: title) => {
-    console.log('选择了?', value)
   // 使用动态属性访问
   let arrayToUpdate = dataStore[title];//获取对应类型数组
   if (arrayToUpdate) {
@@ -269,6 +292,16 @@ const change = (value: any, title: title) => {
       })
       return val;
     });
+      if(title === 'SearchDataStore' && checkeddata['SearchDataStore'].length > 0) {
+          const matchedid = matchDataByIds(checkeddata['SearchDataStore']);//
+          const matchedinfo = matchDataByInfos(checkeddata['SearchDataStore'])
+          Object.keys(checked).forEach(key => { //复选框回显
+              checked[key as keyof checkeddata] = matchedid[key] || [];
+          });
+          Object.keys(checked).forEach(key => {//条件数据回显
+              checkeddata[key as keyof checkeddata] = matchedinfo[key] || [];
+          });
+      }
   } else {
 
   }
@@ -377,4 +410,9 @@ const regionLicenseNumber = (value: string) => {
     overflow-y: auto;
   }
 }
+.selectList{
+  max-height: 300px;
+  padding: 0 20px;
+  overflow-y: auto;
+}
 </style>

+ 62 - 1
src/layouts/components/ruleSelect/index.vue

@@ -7,7 +7,7 @@
                 </template>
             </el-input>
         </div>
-        <div class="content">
+        <div class="content" v-if="searchShow">
             <div class="types">
                 <div class="typesItem" :class="{'active': itemIndex === index}" v-for="(item, index) in typeList" :key="index" @click="handleItemClick(item, index)">
                     {{ item.name }}
@@ -23,6 +23,14 @@
                 </div>
             </template>
         </div>
+        <div class="content" v-else>
+            <div class="searchList">
+                <div class="selectItem" :class="{'active': item.checked}" v-for="(item,index) in searchDataStore" :key="index" @click="handleSearchClick(item, index)">
+                    <el-icon class="icon"><Select v-show="item.checked" /></el-icon>
+                    <span>{{ item.attrName }}</span>
+                </div>
+            </div>
+        </div>
         <div class="footer">
             <el-button @click="handleCancel">取消</el-button>
             <el-button type="primary" @click="handleSubmit">确定</el-button>
@@ -36,7 +44,13 @@ import api from '@/api'
 const emit = defineEmits(['close'])
 
 let searchValue = ref('')
+let searchShow = ref(true)
 const search = () => {
+    if(searchValue.value) {
+        searchShow.value = false
+    } else {
+        searchShow.value = true
+    }
     ruleAttr();
 }
 
@@ -76,7 +90,9 @@ let itemIndex = ref(0)
 let selectedList = ref([]) // 初始已选数据
 let selectList = ref([]) // 已选的数据
 let dataStore = ref([])
+let searchDataStore = ref([])
 const ruleAttr = () => {
+    searchDataStore.value = []
     api.agreementApi.ruleAttrGroup({ attrName: searchValue.value }).then((res: any) => {
         if (res.code == '200') {
             let arr = typeList.value
@@ -87,6 +103,7 @@ const ruleAttr = () => {
             dataStore.value.forEach(a => {
                 a.list?.forEach(b => {
                     b.checked = false
+                    searchDataStore.value.push(b)
                     selectList.value.forEach(c => {
                         if(c.attrName === b.attrName) {
                             b.checked = true
@@ -108,9 +125,29 @@ const handleSubClick = (item, index) => {
         selectList.value = selectList.value.filter(a => a.attrName != item.attrName)
     }
 }
+const handleSearchClick = (item, index) => {
+    item.checked = !item.checked
+    if(item.checked) {
+        selectList.value.push(item)
+    } else {
+        selectList.value = selectList.value.filter(a => a.attrName != item.attrName)
+    }
+    dataStore.value.forEach(a => {
+        a.list?.forEach(b => {
+            b.checked = false
+            searchDataStore.value.push(b)
+            selectList.value.forEach(c => {
+                if(c.attrName === b.attrName) {
+                    b.checked = true
+                }
+            })
+        })
+    })
+}
 
 // 取消
 const handleCancel = () => {
+    searchShow.value = true
     emit('close', selectedList.value)
 }
 // 确定
@@ -132,6 +169,7 @@ const handleSubmit = () => {
             return acc
         }
     }, [])
+    searchShow.value = true
     emit('close', crr)
 }
 
@@ -220,6 +258,29 @@ defineExpose({
 
             }
         }
+        .searchList {
+            max-height: 260px;
+            overflow-y: auto;
+            width: 100%;
+            .selectItem{
+                display: flex;
+                align-items: center;
+                justify-content: flex-start;
+                cursor: pointer;
+                .icon{
+                    border: 1px solid #ccc;
+                    margin: 5px;
+                }
+            }
+            .active{
+                .icon{
+                    background: #0083ff;
+                    border-color: #0083ff;
+                    color: #FFFFFF;
+                }
+
+            }
+        }
     }
     .footer{
         display: flex;

+ 138 - 5
src/views/additionalOrder/additional/index.vue

@@ -67,7 +67,11 @@
                   </el-upload>
                   <el-upload v-else drag :auto-upload="false" :show-file-list="false" @change="uploadImage($event, 'xszf')">
                     <div class="upload-box">
-                      <img class="upload-image" :src="xszFront"/>
+                        <img class="upload-image" :src="xszFront"/>
+                        <div class="btns">
+                            <span style="margin-right: 20px" @click.stop="handleViewImage('xszf')"><el-icon><ZoomIn /></el-icon>查看大图</span>
+                            <span @click.stop="handleDelImage('xszf')"><el-icon><Delete /></el-icon>删除</span>
+                        </div>
                     </div>
                   </el-upload>
                 </el-form-item>
@@ -83,6 +87,10 @@
                   <el-upload v-else drag :auto-upload="false" :show-file-list="false" @change="uploadImage($event, 'xszb')">
                     <div class="upload-box">
                       <img class="upload-image" :src="xszBack"/>
+                        <div class="btns">
+                            <span style="margin-right: 20px" @click.stop="handleViewImage('xszb')"><el-icon><ZoomIn /></el-icon>查看大图</span>
+                            <span @click.stop="handleDelImage('xszb')"><el-icon><Delete /></el-icon>删除</span>
+                        </div>
                     </div>
                   </el-upload>
                 </el-form-item>
@@ -438,6 +446,10 @@
                   <el-upload v-else drag :auto-upload="false" :show-file-list="false" @change="uploadImage($event, 'sfzf')">
                     <div class="upload-box">
                       <img class="upload-image" :src="sfzFront"/>
+                        <div class="btns">
+                            <span style="margin-right: 20px" @click.stop="handleViewImage('sfzf')"><el-icon><ZoomIn /></el-icon>查看大图</span>
+                            <span @click.stop="handleDelImage('sfzf')"><el-icon><Delete /></el-icon>删除</span>
+                        </div>
                     </div>
                   </el-upload>
                 </el-form-item>
@@ -453,6 +465,10 @@
                   <el-upload v-else drag :auto-upload="false" :show-file-list="false" @change="uploadImage($event, 'sfzb')">
                     <div class="upload-box">
                       <img class="upload-image" :src="sfzBack"/>
+                        <div class="btns">
+                            <span style="margin-right: 20px" @click.stop="handleViewImage('sfzb')"><el-icon><ZoomIn /></el-icon>查看大图</span>
+                            <span @click.stop="handleDelImage('sfzb')"><el-icon><Delete /></el-icon>删除</span>
+                        </div>
                     </div>
                   </el-upload>
                 </el-form-item>
@@ -659,6 +675,10 @@
                   <el-upload v-else drag :auto-upload="false" :show-file-list="false" @change="uploadImage($event, 'sfzf1')">
                     <div class="upload-box">
                       <img class="upload-image" :src="sfz1Front"/>
+                        <div class="btns">
+                            <span style="margin-right: 20px" @click.stop="handleViewImage('sfzf1')"><el-icon><ZoomIn /></el-icon>查看大图</span>
+                            <span @click.stop="handleDelImage('sfzf1')"><el-icon><Delete /></el-icon>删除</span>
+                        </div>
                     </div>
                   </el-upload>
                 </el-form-item>
@@ -674,6 +694,10 @@
                   <el-upload v-else drag :auto-upload="false" :show-file-list="false" @change="uploadImage($event, 'sfzb1')">
                     <div class="upload-box">
                       <img class="upload-image" :src="sfz1Back"/>
+                        <div class="btns">
+                            <span style="margin-right: 20px" @click.stop="handleViewImage('sfzb1')"><el-icon><ZoomIn /></el-icon>查看大图</span>
+                            <span @click.stop="handleDelImage('sfzb1')"><el-icon><Delete /></el-icon>删除</span>
+                        </div>
                     </div>
                   </el-upload>
                 </el-form-item>
@@ -885,6 +909,10 @@
                   <el-upload v-else drag :auto-upload="false" :show-file-list="false" @change="uploadImage($event, 'sfzf2')">
                     <div class="upload-box">
                       <img class="upload-image" :src="sfz2Front"/>
+                        <div class="btns">
+                            <span style="margin-right: 20px" @click.stop="handleViewImage('sfzf2')"><el-icon><ZoomIn /></el-icon>查看大图</span>
+                            <span @click.stop="handleDelImage('sfzf2')"><el-icon><Delete /></el-icon>删除</span>
+                        </div>
                     </div>
                   </el-upload>
                 </el-form-item>
@@ -900,6 +928,10 @@
                   <el-upload v-else drag :auto-upload="false" :show-file-list="false" @change="uploadImage($event, 'sfzb2')">
                     <div class="upload-box">
                       <img class="upload-image" :src="sfz2Back"/>
+                        <div class="btns">
+                            <span style="margin-right: 20px" @click.stop="handleViewImage('sfzb2')"><el-icon><ZoomIn /></el-icon>查看大图</span>
+                            <span @click.stop="handleDelImage('sfzb2')"><el-icon><Delete /></el-icon>删除</span>
+                        </div>
                     </div>
                   </el-upload>
                 </el-form-item>
@@ -1573,9 +1605,15 @@
       <el-button plain type="primary" @click="handleSave">暂存</el-button>
       <el-button type="primary" @click="handleSubmit">提交</el-button>
     </div>
+      <el-image-viewer
+        v-if="showImage"
+        :url-list="showImageUrl"
+        @close="showImage = false"
+      />
     <el-dialog
       title="图片预览"
       v-model="imageShow"
+      width="400"
     >
       <img class="image-view" :src="imageUrl" />
     </el-dialog>
@@ -1819,9 +1857,9 @@ let carRules = ref({
   engineNo: [
     { required: true, message: "请输入发动机号", trigger: "blur" }
   ],
-  carYear: [
-    { required: true, message: "请输入年款", trigger: "blur" }
-  ],
+  // carYear: [
+  //   { required: true, message: "请输入年款", trigger: "blur" }
+  // ],
   seatCount: [
     { required: true, message: "请输入座位数", trigger: "blur" }
   ],
@@ -2765,7 +2803,7 @@ const uploadImage = async (file, type) => {
                   carForm.value.carNatureCode = data.useNature // 使用性质
                   carForm.value.vehicleUseCode = data.vehicleUse // 车辆用途
                   carForm.value.carTypeCode = data.category // 车辆类型
-                  carForm.value.energyTypeCode = carForm.value.licenseNo.length == 8?'1': '0' // 能源种类
+                  carForm.value.energyTypeCode = carForm.value.licenseNo.length == 8?'1':carForm.value.licenseNo.length == 7? '0': '' // 能源种类
                   carForm.value.registerDate = data.registerDate // 注册日期
                   carForm.value.issueDate = data.issueDate // 发证日期
               } else {
@@ -3115,6 +3153,82 @@ const uploadImage = async (file, type) => {
     })
   }
 }
+
+let showImage = ref(false)
+let showImageUrl = ref([])
+const handleViewImage = (type) => {
+    showImage.value = true
+    switch (type) {
+        case 'xszf':
+            showImageUrl.value = [xszFront.value]
+            break;
+        case 'xszb':
+            showImageUrl.value = [xszBack.value]
+            break;
+        case 'sfzf':
+            showImageUrl.value = [sfzFront.value]
+            break;
+        case 'sfzb':
+            showImageUrl.value = [sfzBack.value]
+            break;
+        case 'sfzf1':
+            showImageUrl.value = [sfz1Front.value]
+            break;
+        case 'sfzb1':
+            showImageUrl.value = [sfz1Back.value]
+            break;
+        case 'sfzf2':
+            showImageUrl.value = [sfz2Front.value]
+            break;
+        case 'sfzb2':
+            showImageUrl.value = [sfz2Back.value]
+            break;
+    }
+}
+const handleDelImage = (type) => {
+    switch (type) {
+        case 'xszf':
+            xszFront.value = ''
+            xszFrontFile.value = null
+            xszFrontResult.value = null
+            break;
+        case 'xszb':
+            xszBack.value = ''
+            xszBackFile.value = null
+            xszBackResult.value = null
+            break;
+        case 'sfzf':
+            sfzFront.value = ''
+            sfzFrontFile.value = null
+            sfzFrontResult.value = null
+            break;
+        case 'sfzb':
+            sfzBack.value = ''
+            sfzBackFile.value = null
+            sfzBackResult.value = null
+            break;
+        case 'sfzf1':
+            sfz1Front.value = ''
+            sfz1FrontFile.value = null
+            sfz1FrontResult.value = null
+            break;
+        case 'sfzb1':
+            sfz1Back.value = ''
+            sfz1BackFile.value = null
+            sfz1BackResult.value = null
+            break;
+        case 'sfzf2':
+            sfz2Front.value = ''
+            sfz2FrontFile.value = null
+            sfz2FrontResult.value = null
+            break;
+        case 'sfzb2':
+            sfz2Back.value = ''
+            sfz2BackFile.value = null
+            sfz2BackResult.value = null
+            break;
+    }
+}
 // word预览
 const filePreview = (file) => {
   nextTick(() => {
@@ -6542,6 +6656,7 @@ onMounted(() => {
       display: flex;
       align-items: center;
       justify-content: center;
+      position: relative;
       .icon-box{
         text-align: center;
         color: #999999;
@@ -6554,6 +6669,24 @@ onMounted(() => {
         width: 100%;
         height: 100%;
       }
+      .btns{
+        height: 30px;
+        width: 100%;
+        background: rgba(0, 0, 0, .5);
+        position: absolute;
+        display: flex;
+        align-items: center;
+        justify-content: space-around;
+        left: 0;
+        bottom: 0;
+        span{
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          font-size: 16px;
+          color: #ffffff;
+        }
+      }
     }
     .icon{
       padding-right: 24px;

+ 4 - 4
src/views/insurancePolicy/index.vue

@@ -1789,9 +1789,9 @@ let insurancePolicyRules = ref<FormRules>({
   seatCount: [
     { required: true, trigger: 'blur', message: '请输入座位数' }
   ],
-  carYear: [
-    { required: true, trigger: 'blur', message: '请输入年款' }
-  ],
+  // carYear: [
+  //   { required: true, trigger: 'blur', message: '请输入年款' }
+  // ],
   purchasePrice: [
     { required: true, trigger: 'blur', message: '请输入新车购置价' }
   ],
@@ -2771,7 +2771,7 @@ const handleImageClose = (data) => {
       insurancePolicyForm.value.vehicleUseCode = carForm.vehicleUseCode || hadWritedData.value.vehicleUseCode
       insurancePolicyForm.value.carTypeCode = carForm.carTypeCode || hadWritedData.value.carTypeCode
       insurancePolicyForm.value.plateType = carForm.plateType || hadWritedData.value.plateType
-      insurancePolicyForm.value.energyTypeCode = carForm.energyTypeCode || hadWritedData.value.energyTypeCode
+      insurancePolicyForm.value.energyTypeCode = carForm.energyTypeCode || hadWritedData.value.energyTypeCode || insurancePolicyForm.value.licenseNo.length == 7?'0' : insurancePolicyForm.value.licenseNo.length == 8?'1' : ''
       insurancePolicyForm.value.registerDate = carForm.registerDate || hadWritedData.value.registerDate
       insurancePolicyForm.value.issueDate = carForm.issueDate || hadWritedData.value.issueDate
       insurancePolicyForm.value.completeKerbMass = carForm.completeKerbMass || hadWritedData.value.completeKerbMass

+ 167 - 0
src/views/insurancePolicy/modules/recognition.vue

@@ -21,6 +21,10 @@
           <el-upload v-else drag :auto-upload="false" :show-file-list="false" @change="uploadImage($event, 'xszf')">
             <div class="upload-box">
               <img class="upload-image" :src="xszFront"/>
+                <div class="btns">
+                    <span style="margin-right: 20px" @click.stop="handleViewImage('xszf')"><el-icon><ZoomIn /></el-icon>查看大图</span>
+                    <span @click.stop="handleDelImage('xszf')"><el-icon><Delete /></el-icon>删除</span>
+                </div>
             </div>
           </el-upload>
         </div>
@@ -37,6 +41,10 @@
           <el-upload v-else drag :auto-upload="false" :show-file-list="false" @change="uploadImage($event, 'xszb')">
             <div class="upload-box">
               <img class="upload-image" :src="xszBack"/>
+                <div class="btns">
+                    <span style="margin-right: 20px" @click.stop="handleViewImage('xszb')"><el-icon><ZoomIn /></el-icon>查看大图</span>
+                    <span @click.stop="handleDelImage('xszb')"><el-icon><Delete /></el-icon>删除</span>
+                </div>
             </div>
           </el-upload>
         </div>
@@ -130,6 +138,10 @@
           <el-upload v-else drag :auto-upload="false" :show-file-list="false" @change="uploadImage($event, 'sfzf')">
             <div class="upload-box">
               <img class="upload-image" :src="sfzFront"/>
+                <div class="btns">
+                    <span style="margin-right: 20px" @click.stop="handleViewImage('sfzf')"><el-icon><ZoomIn /></el-icon>查看大图</span>
+                    <span @click.stop="handleDelImage('sfzf')"><el-icon><Delete /></el-icon>删除</span>
+                </div>
             </div>
           </el-upload>
         </div>
@@ -146,6 +158,10 @@
           <el-upload v-else drag :auto-upload="false" :show-file-list="false" @change="uploadImage($event, 'sfzb')">
             <div class="upload-box">
               <img class="upload-image" :src="sfzBack"/>
+                <div class="btns">
+                    <span style="margin-right: 20px" @click.stop="handleViewImage('sfzb')"><el-icon><ZoomIn /></el-icon>查看大图</span>
+                    <span @click.stop="handleDelImage('sfzb')"><el-icon><Delete /></el-icon>删除</span>
+                </div>
             </div>
           </el-upload>
         </div>
@@ -164,6 +180,10 @@
           <el-upload v-else drag :auto-upload="false" :show-file-list="false" @change="uploadImage($event, 'yyzz')">
             <div class="upload-box">
               <img class="upload-image" :src="yyzzFront"/>
+                <div class="btns">
+                    <span style="margin-right: 20px" @click.stop="handleViewImage('yyzz')"><el-icon><ZoomIn /></el-icon>查看大图</span>
+                    <span @click.stop="handleDelImage('yyzz')"><el-icon><Delete /></el-icon>删除</span>
+                </div>
             </div>
           </el-upload>
         </div>
@@ -260,6 +280,10 @@
           <el-upload v-else drag :auto-upload="false" :show-file-list="false" @change="uploadImage($event, 'tbrf')">
             <div class="upload-box">
               <img class="upload-image" :src="tbrFront"/>
+                <div class="btns">
+                    <span style="margin-right: 20px" @click.stop="handleViewImage('tbrf')"><el-icon><ZoomIn /></el-icon>查看大图</span>
+                    <span @click.stop="handleDelImage('tbrf')"><el-icon><Delete /></el-icon>删除</span>
+                </div>
             </div>
           </el-upload>
         </div>
@@ -276,6 +300,10 @@
           <el-upload v-else drag :auto-upload="false" :show-file-list="false" @change="uploadImage($event, 'tbrb')">
             <div class="upload-box">
               <img class="upload-image" :src="tbrBack"/>
+                <div class="btns">
+                    <span style="margin-right: 20px" @click.stop="handleViewImage('tbrb')"><el-icon><ZoomIn /></el-icon>查看大图</span>
+                    <span @click.stop="handleDelImage('tbrb')"><el-icon><Delete /></el-icon>删除</span>
+                </div>
             </div>
           </el-upload>
         </div>
@@ -294,6 +322,10 @@
           <el-upload v-else drag :auto-upload="false" :show-file-list="false" @change="uploadImage($event, 'tbryyzz')">
             <div class="upload-box">
               <img class="upload-image" :src="tbryyzzFront"/>
+                <div class="btns">
+                    <span style="margin-right: 20px" @click.stop="handleViewImage('tbryyzz')"><el-icon><ZoomIn /></el-icon>查看大图</span>
+                    <span @click.stop="handleDelImage('tbryyzz')"><el-icon><Delete /></el-icon>删除</span>
+                </div>
             </div>
           </el-upload>
         </div>
@@ -390,6 +422,10 @@
           <el-upload v-else drag :auto-upload="false" :show-file-list="false" @change="uploadImage($event, 'bbrf')">
             <div class="upload-box">
               <img class="upload-image" :src="bbrFront"/>
+                <div class="btns">
+                    <span style="margin-right: 20px" @click.stop="handleViewImage('bbrf')"><el-icon><ZoomIn /></el-icon>查看大图</span>
+                    <span @click.stop="handleDelImage('bbrf')"><el-icon><Delete /></el-icon>删除</span>
+                </div>
             </div>
           </el-upload>
         </div>
@@ -406,6 +442,10 @@
           <el-upload v-else drag :auto-upload="false" :show-file-list="false" @change="uploadImage($event, 'bbrb')">
             <div class="upload-box">
               <img class="upload-image" :src="bbrBack"/>
+                <div class="btns">
+                    <span style="margin-right: 20px" @click.stop="handleViewImage('bbrb')"><el-icon><ZoomIn /></el-icon>查看大图</span>
+                    <span @click.stop="handleDelImage('bbrb')"><el-icon><Delete /></el-icon>删除</span>
+                </div>
             </div>
           </el-upload>
         </div>
@@ -424,6 +464,10 @@
           <el-upload v-else drag :auto-upload="false" :show-file-list="false" @change="uploadImage($event, 'bbryyzz')">
             <div class="upload-box">
               <img class="upload-image" :src="bbryyzzFront"/>
+                <div class="btns">
+                    <span style="margin-right: 20px" @click.stop="handleViewImage('bbryyzz')"><el-icon><ZoomIn /></el-icon>查看大图</span>
+                    <span @click.stop="handleDelImage('bbryyzz')"><el-icon><Delete /></el-icon>删除</span>
+                </div>
             </div>
           </el-upload>
         </div>
@@ -506,6 +550,11 @@
       <el-button plain type="primary" @click="handleCancel">取消</el-button>
       <el-button type="primary" @click="handleConfirm">确定</el-button>
     </div>
+    <el-image-viewer
+      v-if="showImage"
+      :url-list="showImageUrl"
+      @close="showImage = false"
+    />
   </div>
 </template>
 
@@ -1054,6 +1103,105 @@ const uploadImage = async (file, type) => {
     })
   }
 }
+let showImage = ref(false)
+let showImageUrl = ref([])
+const handleViewImage = (type) => {
+    showImage.value = true
+    switch (type) {
+        case 'xszf':
+            showImageUrl.value = [xszFront.value]
+            break;
+        case 'xszb':
+            showImageUrl.value = [xszBack.value]
+            break;
+        case 'sfzf':
+            showImageUrl.value = [sfzFront.value]
+            break;
+        case 'sfzb':
+            showImageUrl.value = [sfzBack.value]
+            break;
+        case 'yyzz':
+            showImageUrl.value = [yyzzFront.value]
+            break;
+        case 'tbrf':
+            showImageUrl.value = [tbrFront.value]
+            break;
+        case 'tbrb':
+            showImageUrl.value = [tbrBack.value]
+            break;
+        case 'tbryyzz':
+            showImageUrl.value = [tbryyzzFront.value]
+            break;
+        case 'bbrf':
+            showImageUrl.value = [bbrFront.value]
+            break;
+        case 'bbrb':
+            showImageUrl.value = [bbrBack.value]
+            break;
+        case 'bbryyzz':
+            showImageUrl.value = [bbryyzzFront.value]
+            break;
+    }
+}
+const handleDelImage = (type) => {
+    switch (type) {
+        case 'xszf':
+            xszFrontResult.value = null
+            xszFront.value = ''
+            xszFrontFile.value = null
+            break;
+        case 'xszb':
+            xszBackResult.value = null
+            xszBack.value = ''
+            xszBackFile.value = null
+            break;
+        case 'sfzf':
+            sfzFrontResult.value = null
+            sfzFront.value = ''
+            sfzFrontFile.value = null
+            break;
+        case 'sfzb':
+            sfzBackResult.value = null
+            sfzBack.value = ''
+            sfzBackFile.value = null
+            break;
+        case 'yyzz':
+            yyzzFrontResult.value = null
+            yyzzFront.value = ''
+            yyzzFrontFile.value = null
+            break;
+        case 'tbrf':
+            tbrFrontResult.value = null
+            tbrFront.value = ''
+            tbrFrontFile.value = null
+            break;
+        case 'tbrb':
+            tbrBackResult.value = null
+            tbrBack.value = ''
+            tbrBackFile.value = null
+            break;
+        case 'tbryyzz':
+            tbryyzzFrontResult.value = null
+            tbryyzzFront.value = ''
+            tbryyzzFrontFile.value = null
+            break;
+        case 'bbrf':
+            bbrFrontResult.value = null
+            bbrFront.value = ''
+            bbrFrontFile.value = null
+            break;
+        case 'bbrb':
+            bbrBackResult.value = null
+            bbrBack.value = ''
+            bbrBackFile.value = null
+            break;
+        case 'bbryyzz':
+            bbryyzzFrontResult.value = null
+            bbryyzzFront.value = ''
+            bbryyzzFrontFile.value = null
+            break;
+    }
+}
 
 const handleCancel = () => {
   emit('close')
@@ -1255,6 +1403,7 @@ defineExpose({
     display: flex;
     align-items: center;
     justify-content: center;
+    position: relative;
     .icon-box{
       text-align: center;
       color: #999999;
@@ -1267,6 +1416,24 @@ defineExpose({
       width: 100%;
       height: 100%;
     }
+    .btns{
+      height: 30px;
+      width: 100%;
+      background: rgba(0, 0, 0, .5);
+      position: absolute;
+      display: flex;
+      align-items: center;
+      justify-content: space-around;
+      left: 0;
+      bottom: 0;
+      span{
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        font-size: 16px;
+        color: #ffffff;
+      }
+    }
   }
   .m-b-5{
     margin-bottom: 5px !important;

+ 1 - 0
src/views/quoteConfig/agreement/agreementDetails.vue

@@ -469,6 +469,7 @@ const UnderwritingRuleSave = () => {
           name: 'reload',
         })
       } else {
+
       }
     });
   } else {

+ 17 - 7
src/views/quoteConfig/agreement/components/ruleFeeDialog.vue

@@ -213,6 +213,7 @@ const feerules = ref<FormRules>({
 })
 interface RuleCondition {
   min: number | string;
+  operator: number | string;
 }
 onMounted(async () => {
   await loadDicts(['insurance_type'])
@@ -276,6 +277,7 @@ const close = () => {
 }
 const save = async (formEl: FormInstance | undefined | any) => {
   if (!formEl) return
+    console.log('规则', ruleFeeinfo.value[insuranceTypeIndex.value].ptlAgreementCostAddList)
   const validationPromises = ruleFeeinfo.value[insuranceTypeIndex.value].ptlAgreementCostAddList.map((formRef: any, index: any) => {
     // 轮询验证所有表单校验
     return new Promise((resolve, reject) => {
@@ -289,8 +291,15 @@ const save = async (formEl: FormInstance | undefined | any) => {
                 plain: true,
               });
               return;
-            } else {
-              resolve(true);
+            }
+            const resultInputTag = checkArrayValues(ruleFeeinfo.value[insuranceTypeIndex.value].ptlAgreementCostAddList[index].ruleConditions as RuleCondition[], "operator");
+            if(!resultInputTag){
+                ElMessage({
+                    type: 'error',
+                    message: `规则运算符不能为空值`,
+                    plain: true,
+                });
+                return;
             }
             const result = checkArrayValues(ruleFeeinfo.value[insuranceTypeIndex.value].ptlAgreementCostAddList[index].ruleConditions as RuleCondition[], "min");
             if(!result){
@@ -299,8 +308,10 @@ const save = async (formEl: FormInstance | undefined | any) => {
                 message: `规则条件不能为空值`,
                 plain: true,
               });
-            }else{
-              resolve(true);
+              return;
+            }
+            if(ruleFeeinfo.value[insuranceTypeIndex.value].ptlAgreementCostAddList[index].ruleConditions.length && result && resultInputTag) {
+                resolve(true);
             }
           } else {
             reject(index);
@@ -321,8 +332,8 @@ const save = async (formEl: FormInstance | undefined | any) => {
 
       return val;
     })
-    // console.log(ruleFeeinfo.value)
-    // return;
+    console.log('规则条件的数据', ruleFeeinfo.value)
+    return;
     emits("save",{ptlAgreementCode:props.agreementInfo.agreementCode,ptlAgreementName:props.agreementInfo.agreementTitle,costAddList:ruleFeeinfo.value} )
   } catch (error) {
     const invalidIndex: any = error; // 获取未通过校验的表单索引
@@ -356,7 +367,6 @@ const addRuleCondition = (index: number, Costindex: number) => {
 }
 
 const handelRK = (scope) => {
-    console.log(123123123, scope.row.addThrow, typeof scope.row.addThrow)
     if(scope.row.export&&scope.row.addThrow || scope.row.export&&scope.row.addThrow === 0) {
         scope.row.keepPointRatio = scope.row.inlet + scope.row.addThrow - scope.row.export
     }

+ 46 - 7
src/views/quoteConfig/costManagement.vue

@@ -116,6 +116,7 @@ onBeforeMount(async () => {
   findpage();//列表数据
   getDeptTree();
   agreement();
+  initCompany();
   valid_status.value = getDict('valid_status');//生效状态
   is_enable.value = getDict('is_enable');//协议状态
   insurance_type.value = getDict('insurance_type')
@@ -151,8 +152,30 @@ const formInline = reactive({
   validState: "",
   effectiveTime: [],
   failureTime: [],
+  updateTimeArr: [],
 })
 
+// 保险公司
+let companyOption = ref([])
+const initCompany = () => {
+    // api.projectApi.getCompanyList().then(res => {
+    api.insuranceApi.leftList('').then((res: any) => {
+        if(res.code == 200) {
+            companyOption.value = res.data.map(item => {
+                return {
+                    label: item.name,
+                    value: item.id
+                }
+            })
+        } else {
+            ElMessage({
+                message: res.msg,
+                type: 'warning'
+            })
+        }
+    })
+}
+
 //表格字段数据
 const fields = ref([
   { label: "所属协议", model: "agreement", type: "input", placeholder: "输入协议号,名称,简称查找" },
@@ -163,7 +186,7 @@ const fields = ref([
     label: "承保规则", model: "rulesName", type: "input", placeholder: "输入业务规则查找",
   },
   {
-    label: "费用规则", model: "costRules", type: "input", placeholder: "输入费用规则关键字查找",
+    label: "费用描述", model: "costRules", type: "input", placeholder: "输入费用描述关键字查找",
   },
 
   {
@@ -188,6 +211,18 @@ const fields = ref([
       formInline.failureTime = value;
     }
   },
+    {
+        label: "保险公司", model: "companyId", type: "select", placeholder: "选择保险公司", options: companyOption, filterable: true
+    },
+    {
+        label: "对接人", model: "contactPerson", type: "input", placeholder: "输入对接人",
+    },
+    {
+        label: "修改时间", model: "updateTimeArr", type: "date", dateType: "datetimerange", startplaceholder: "开始时间", endplaceholder: "结束时间",
+        onChange: (value: any) => {
+            formInline.updateTimeArr = value;
+        }
+    },
 ]);
 
 //费用数据查询
@@ -212,6 +247,7 @@ function agreement() {
   });
 }
 const columns = [
+    { prop: "companyName", label: "保险公司", width: '120', },
   {
     prop: "agreementAbbreviation", label: "协议信息", width: '300',
     formatter: (row: any) => {
@@ -243,8 +279,10 @@ const columns = [
       }
     }
   },
-  { prop: "effectiveTime", label: "生效时间", width: '200' },
-  { prop: "failureTime", label: "失效时间", width: '200' },
+    { prop: "dockingPerson", label: "对接人", width: '100' },
+    { prop: "effectiveTime", label: "生效时间", width: '200' },
+    { prop: "failureTime", label: "失效时间", width: '200' },
+    { prop: "updateTime", label: "修改时间", width: '200' },
   {
     prop: "ruleConditions", label: "交强费用", width: '300', formatter: (row: any) => {
       let info = row.ruleConditions.find((val: any) => val.costType == '交强险');
@@ -410,14 +448,15 @@ const del = (value: string) => {
     .then(() => {
       api.agreementApi.AgreementFeedeleteByIds([value]).then((res: any) => {
         if (res.code == '200') {
+          findpage()
           ElMessage({
             type: 'success',
             message: res.msg,
             plain: true,
           })
-          router.push({
-            name: 'reload',
-          })
+          // router.push({
+          //   name: 'reload',
+          // })
         }
       });
     })
@@ -435,7 +474,7 @@ const batchDel = () => {
     }
   )
     .then(() => {
-      api.agreementApi.agreementDelete(sysUpAndDownList.value).then((res: any) => {
+      api.agreementApi.deleteByIds(sysUpAndDownList.value).then((res: any) => {
         if (res.code == '200') {
           ElMessage({
             type: 'success',

+ 20 - 13
src/views/quoteConfig/dispatch/index.vue

@@ -38,7 +38,7 @@
               <div
                 class="list-item"
                 :class="currentIndex == index ? 'active' : ''"
-                v-for="(item, index) in tenantList"
+                v-for="(item, index) in filterList"
                 :key="item.id"
                 @click="roleitemClick(item, index)"
               >
@@ -64,7 +64,7 @@
                 class="rule-item"
                 v-for="(item, ruleIndex) in ruleList"
                 :key="item.dispatchId"
-                
+
               >
                 <div class="item-title">
                   <div class="name" v-if="!item.editMode">
@@ -121,7 +121,7 @@
                         <!-- <div class="value">
                           <template
                             v-if="
-                              
+
                               row.operator == 1
                             "
                           >
@@ -134,7 +134,7 @@
                           <template v-else-if="
                               row.operator == 2 ||
                               row.operator == 3
-                              
+
                             ">
                             {{ row.min }}
                           </template>
@@ -343,6 +343,7 @@ const formatAttrLinksBySection = (attrLinks: any[]) => {
 const getCompanyList = () => {
   api.dispatchApi.getCompanyList().then((res) => {
     tenantList.value = res.data || [];
+    filterList.value = tenantList.value
     // 安全获取第一个租户的id(避免数组为空)
     if (tenantList.value.length > 0) {
       currentId.value = tenantList.value[0].id;
@@ -386,16 +387,22 @@ const deleteRule = (id: string) => {
   });
 };
 
+let filterList = ref([])
 // 搜索租户(需后端配合实现,此处预留方法)
 const findpage = () => {
-  if (!searchValue.value.trim()) {
-    getCompanyList(); // 无搜索值时加载全部
-    return;
-  }
-  // 调用搜索接口(示例,需按实际接口调整)
-  api.dispatchApi.searchCompany({ keyword: searchValue.value }).then((res) => {
-    tenantList.value = res.data || [];
-  });
+  // if (!searchValue.value.trim()) {
+  //   getCompanyList(); // 无搜索值时加载全部
+  //   return;
+  // }
+  // // 调用搜索接口(示例,需按实际接口调整)
+  // api.dispatchApi.searchCompany({ keyword: searchValue.value }).then((res) => {
+  //   tenantList.value = res.data || [];
+  // });
+    if(searchValue.value) {
+        filterList.value = tenantList.value.filter(a => a.name.includes(searchValue.value))
+    } else {
+        filterList.value = tenantList.value
+    }
 };
 
 const editDispatch = (item: any) => {
@@ -645,4 +652,4 @@ getCompanyList();
 :deep(.el-drawer__body) {
   padding: 0 24px;
 }
-</style>
+</style>

+ 68 - 3
src/views/quoteConfig/project/modules/projectAdd.vue

@@ -186,11 +186,52 @@ const JYXDetail = ref(null)
 
 let RuleSelect = ref()
 
+const licensePlateRegion = ref();//车牌地区
+const licensePlateNumber = ref();//车牌号
+const regionLicenseRegion = (value: string) => {
+    api.agreementApi.getAreaLicense(value).then((res: any) => {
+        if (res.code == '200') {
+            let data: any = [];
+            res.data.map((val: any) => {
+                data.push({
+                    code: val.areaNumber,
+                    name: val.license,
+                })
+                return val;
+            })
+            licensePlateRegion.value = data;
+        } else {
+        }
+    });
+}
+const regionLicenseNumber = (value: string) => {
+    api.agreementApi.getAreaLicense(value).then((res: any) => {
+        if (res.code == '200') {
+            let data: any = [];
+            res.data.map((val: any) => {
+                data.push({
+                    code: val.areaNumber,
+                    name: val.license,
+                })
+                return val;
+            })
+            licensePlateNumber.value = data;
+        } else {
+        }
+    });
+}
+
 // 规则条件
 let ruleSelectShow = ref(false)
 const handleRuleSelectClose = (data) => {
     if(data&&data.length>0) {
         rulesAttrList.value = data.map(a => {
+            if (a.attrCode == 'LicenseNo') {
+                a.dictLabal = licensePlateNumber.value;
+            }
+            if (a.attrCode == 'LicenseArea') {
+                a.dictLabal = licensePlateRegion.value;
+            }
             return {
                 ...a,
                 min: a.attrName == '能源类型'? '0':a.min?a.min: '',
@@ -331,7 +372,15 @@ const initProduct = (e) => {
             })
           })
           projectAddFrom.value = res.data
-          rulesAttrList.value = res.data.ruleAttrs
+          rulesAttrList.value = res.data.ruleAttrs.map(val => {
+              if (val.attrCode == 'LicenseNo') {
+                  val.dictLabal = licensePlateNumber.value;
+              }
+              if (val.attrCode == 'LicenseArea') {
+                  val.dictLabal = licensePlateRegion.value;
+              }
+              return val
+          })
         }
       } else {
         // projectAddFrom.value.ruleAttrs = []
@@ -468,7 +517,6 @@ const addProject = () => {
 let rulesShow = ref(false)
 const addRules = () => {
     ruleSelectShow.value = true
-    console.log('数据是:', rulesAttrList.value)
     nextTick(() => {
         RuleSelect.value.initEditData(rulesAttrList.value)
     })
@@ -580,8 +628,15 @@ const initAttr = () => {
     if(res.code == 200) {
       let list = res.data?.VehicleInformation?.filter(e => e.attrName === '能源类型' || e.attrName === '使用性质' || e.attrName === '车辆种类')
       rulesAttrList.value = list?.map(a => {
+          if (a.attrCode == 'LicenseNo') {
+              a.dictLabal = licensePlateNumber.value;
+          }
+          if (a.attrCode == 'LicenseArea') {
+              a.dictLabal = licensePlateRegion.value;
+          }
           return {
               ...a,
+              operator: '1',
               min: a.attrName == '能源类型'? '0':'',
               minArray: a.minArray?a.minArray:a.attrName == '使用性质' || a.attrName == '车辆种类'?[a.dictLabal[0].code]:[]
           }
@@ -614,7 +669,15 @@ const initEdit = () => {
           })
         })
         projectAddFrom.value = res.data
-        rulesAttrList.value = res.data.ruleAttrs
+        rulesAttrList.value = res.data.ruleAttrs.map(val => {
+            if (val.attrCode == 'LicenseNo') {
+                val.dictLabal = licensePlateNumber.value;
+            }
+            if (val.attrCode == 'LicenseArea') {
+                val.dictLabal = licensePlateRegion.value;
+            }
+            return val
+        })
       }
     } else {
       ElMessage({
@@ -696,6 +759,8 @@ onMounted(() => {
   initInsurance()
   initType()
   initCompany()
+  regionLicenseRegion('0')
+  regionLicenseNumber('14')
   projectAddFrom.value.companyId = myRoute.query.companyId
   // initAttr()
   if(myRoute.query.id) {