Преглед на файлове

选择权益功能 图片bug

@dongkboy преди 5 месеца
родител
ревизия
3f564f7e71

+ 2 - 0
index.html

@@ -10,6 +10,8 @@
     <meta http-equiv="Cache-control" content="no-cache">
     <meta http-equiv="Cache" content="no-cache">
     <title>%VITE_APP_TITLE%</title>
+    <!-- 天地图SDK -->
+    <script src="https://api.tianditu.gov.cn/api?v=4.0&tk=2699ecce1a53fa83c2a0c683397c9449"></script>
   </head>
   <body>
     <div id="app">

+ 51 - 0
package-lock.json

@@ -18,6 +18,7 @@
         "axios": "^1.7.9",
         "chinese-days": "^1.5.1",
         "dayjs": "^1.11.13",
+        "decimal.js": "^10.6.0",
         "defu": "^6.1.4",
         "disable-devtool": "^0.3.8",
         "echarts": "^6.0.0",
@@ -8173,6 +8174,11 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/decimal.js": {
+      "version": "10.6.0",
+      "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz",
+      "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg=="
+    },
     "node_modules/decode-named-character-reference": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz",
@@ -22722,6 +22728,51 @@
         "node": ">= 14"
       }
     },
+    "node_modules/zip-stream/node_modules/readable-stream": {
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
+      "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
+      "dev": true,
+      "dependencies": {
+        "abort-controller": "^3.0.0",
+        "buffer": "^6.0.3",
+        "events": "^3.3.0",
+        "process": "^0.11.10",
+        "string_decoder": "^1.3.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      }
+    },
+    "node_modules/zip-stream/node_modules/safe-buffer": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
+    },
+    "node_modules/zip-stream/node_modules/string_decoder": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "~5.2.0"
+      }
+    },
     "node_modules/zrender": {
       "version": "6.0.0",
       "resolved": "https://registry.npmmirror.com/zrender/-/zrender-6.0.0.tgz",

+ 1 - 0
package.json

@@ -32,6 +32,7 @@
     "axios": "^1.7.9",
     "chinese-days": "^1.5.1",
     "dayjs": "^1.11.13",
+    "decimal.js": "^10.6.0",
     "defu": "^6.1.4",
     "disable-devtool": "^0.3.8",
     "echarts": "^6.0.0",

+ 4 - 2
src/api/modules/additional.ts

@@ -14,8 +14,8 @@ const additionalApi = (axiosInstance: ApiInstance) => ({
   drivingPermit: (data: any) => axiosInstance.post('/order/identify/drivingPermit', data), // 行驶证识别
   idCard: (data: any) => axiosInstance.post('/order/identify/idCard', data), // 身份证识别
   businessLicense: (data: any) => axiosInstance.post('/order/identify/businessLicense', data), // 营业执照识别
-  vinSearch:(data: string) => axiosInstance.get(`/order/carModel/vinSearch?frameNo=${data}`), // 根据车辆识别码查询车辆信息
-  licenseSearch:(data: any) => axiosInstance.post(`/order/carModel/modelsQuery`, data), // 根据车牌查询车辆信息
+  vinSearch: (data: string) => axiosInstance.get(`/order/carModel/vinSearch?frameNo=${data}`), // 根据车辆识别码查询车辆信息
+  licenseSearch: (data: any) => axiosInstance.post(`/order/carModel/modelsQuery`, data), // 根据车牌查询车辆信息
   saveOrders: (data: any) => axiosInstance.post('/supplementOrder/saveOrders', data), // 暂存/提交
   pageList: (data: any) => axiosInstance.post('/supplementOrder/pageList', data), // 订单列表
   deleteById: (data: string) => axiosInstance.get(`/supplementOrder/deleteById?id=${data}`), // 订单删除
@@ -23,6 +23,8 @@ const additionalApi = (axiosInstance: ApiInstance) => ({
   updateOrders: (data: any) => axiosInstance.post('/supplementOrder/updateOrders', data), // 编辑
   getContactAgreement: (id: string) => axiosInstance.get(`agreement/getContactAgreement?companyId=${id}`), // 获取外部协议
   getContactAgreementCost: (data: { agreementId: string, productId: string, isInquiry: string | number }) => axiosInstance.get(`agreement/getContactAgreementCost?agreementId=${data.agreementId}&&productId=${data.productId}&&isInquiry=${data.isInquiry}`),
+  // 权益相关接口
+  getIPLocation: () => axiosInstance.get('https://ipapi.co/json/'), // ip定位查询
   rightsGrantList: (data: any) => axiosInstance.post('/rightsGrant/package/list', data), // 权益套餐分页查询
   rightsGrant: (data: string) => axiosInstance.get(`/rightsGrant/package/detail/${data}`), // 补录订单权益详情
   rightsList: (data: any) => axiosInstance.post('/rightsGrant/rights/list', data), // 权益券分页查询

+ 1 - 0
src/api/modules/insurancePolicy.ts

@@ -40,6 +40,7 @@ const insurancePolicyApi = (axiosInstance: ApiInstance) => ({
   delNewCar: (data: any) => axiosInstance.post('newCarJudgeRules/delNewCar', data), // 删除
   // 导出订单
   exportDynamicFields: (data: any) => axiosInstance.post('supplementOrder/exportDynamicFields', data), // 导出订单
+  downloadPolicy: (data: any) => axiosInstance.post(`/unify/order/downloadPolicy`,data), // 下载电子保单
 })
 
 export default insurancePolicyApi

+ 0 - 366
src/components/Equities/index.vue

@@ -1,366 +0,0 @@
-<template>
-    <div>
-        <el-dialog
-            title="权益选择"
-            v-model="props.show"
-            width="1000"
-        >
-            <el-form :model="equitiesForm">
-                <el-row :gutter="20" style="display: flex; align-items: flex-end">
-                    <el-col :span="10">
-                        <el-form-item label="选择权益接收人">
-                            <el-select v-model="equitiesForm.person">
-                                <el-option value="1" label="1"></el-option>
-                            </el-select>
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="10">
-                        <el-form-item label="用户所在地区">
-                            <el-select v-model="equitiesForm.area">
-                                <el-option value="1" label="1"></el-option>
-                            </el-select>
-                        </el-form-item>
-                    </el-col>
-<!--                    <el-col :span="4">
-                        <el-button type="primary" @click="handleEquitiesSearch">查询</el-button>
-                    </el-col>-->
-                </el-row>
-            </el-form>
-            <div class="change">
-                <span class="common" :class="{ 'changeActive': changeIndex === index }" v-for="(item, index) in ['权益套餐', '权益单品']" @click="initEquities(item, index)">{{ item }}</span>
-            </div>
-            <div class="combo" v-show="changeIndex == 0">
-                <el-row :gutter="10">
-                    <el-col :span="6">
-                        <div class="comboList">
-                            <div class="comboItem" :class="{'comboActive': comboIndex == index}" v-for="(item, index) in comboList" @click="handleCombo(item, index)">{{ item.equityPackageName }}</div>
-                        </div>
-<!--                        <div class="tips">1年12次洗车,2次救援,3次小保养</div>-->
-                    </el-col>
-                    <el-col :span="12">
-                        <div>套餐明细</div>
-                        <div class="count">
-                            <span>数量:{{ comboList?.[comboIndex]?.rightsCount }}张</span>
-                            <span>价格:{{ comboList?.[comboIndex]?.packagePrice }}元</span>
-                            <span style="width: 60px; display: flex; align-items: center">
-                              <span class="countIcon" @click="handleSubtract">
-                                  <el-icon size="small" color="#0083FF">
-                                      <Minus />
-                                  </el-icon>
-                              </span>
-                              <span style="width: calc(100% - 32px); text-align: center">{{ comboList?.[comboIndex]?.countOne }}</span>
-                              <span class="countIcon" @click="handleAdd">
-                                  <el-icon size="small" color="#0083FF">
-                                      <Plus />
-                                  </el-icon>
-                              </span>
-                          </span>
-                        </div>
-                        <el-table
-                            :show-header="false"
-                            :data="comboData"
-                            style="width: 100%"
-                        >
-                            <el-table-column prop="rightsName"></el-table-column>
-                            <el-table-column prop="rightsCount"></el-table-column>
-                            <el-table-column prop="marketPrice"></el-table-column>
-                        </el-table>
-                    </el-col>
-                    <el-col :span="6">
-                        <div class="chosed">
-                            <span>已选择:{{ chosedList.length }}份驾意险</span>
-                            <span style="display: flex; align-items: center; cursor: pointer; color: #0083FF;">
-                              <el-icon size="small" color="#0083FF">
-                                  <Delete />
-                              </el-icon>
-                              清除
-                          </span>
-                        </div>
-                        <div class="chosedList">
-                            <div class="chosedItem" v-for="(item, index) in chosedList">
-                                <div class="top">
-                                    <span>{{ item.equityPackageName }}</span>
-                                    <span>x{{ item.countOne }}</span>
-                                </div>
-                                <div class="bottom">
-                                    <span>数量:{{ item.rightsCount }}张</span>
-                                    <span>价格:{{ item.packagePrice }}元</span>
-                                    <span style="display: flex; align-items: center; cursor: pointer; color: #0083FF;">
-                                      <el-icon>
-                                          <Delete />
-                                      </el-icon>
-                                  </span>
-                                </div>
-                            </div>
-                        </div>
-                    </el-col>
-                </el-row>
-            </div>
-            <div class="single" v-show="changeIndex == 1">
-                <el-row :gutter="10">
-                    <el-col :span="17">
-                        <el-table
-                            :data="comboData"
-                            style="width: 100%"
-                        >
-                            <el-table-column prop="rightsName" label="权益名称"></el-table-column>
-                            <el-table-column prop="marketPrice" label="单价"></el-table-column>
-                            <el-table-column prop="rightsCount" label="发放数量">
-                                <template #default="scope">
-                                    <el-input-number v-model="scope.row.rightsCount" />
-                                </template>
-                            </el-table-column>
-                            <el-table-column prop="settlePrice" label="总价">
-                                <template #default=""></template>
-                            </el-table-column>
-                        </el-table>
-                    </el-col>
-                    <el-col :span="6">
-                        <div class="chosed">
-                            <span>已选择:{{ chosedList.length }}份驾意险</span>
-                            <span style="display: flex; align-items: center; cursor: pointer; color: #0083FF;">
-                              <el-icon size="small" color="#0083FF">
-                                  <Delete />
-                              </el-icon>
-                              清除
-                          </span>
-                        </div>
-                        <div class="chosedList">
-                            <div class="chosedItem" v-for="(item, index) in singleList">
-                                <div class="top">
-                                    <span>xxx权益xxx权益xxx权益xxx权益xxx权益</span>
-                                    <span>x2</span>
-                                </div>
-                                <div class="bottom">
-                                    <span>数量:12张</span>
-                                    <span>价格:200.00元</span>
-                                    <span style="display: flex; align-items: center; cursor: pointer; color: #0083FF;">
-                                      <el-icon>
-                                          <Delete />
-                                      </el-icon>
-                                  </span>
-                                </div>
-                            </div>
-                        </div>
-                    </el-col>
-                </el-row>
-            </div>
-            <template #footer>
-                <div class="btns">
-                    <el-button @click="handelCancel">取消</el-button>
-                    <el-button @click="handelConfirm" type="primary">确定</el-button>
-                </div>
-            </template>
-        </el-dialog>
-    </div>
-</template>
-
-<script setup lang="ts">
-
-import api from '@/api'
-import {ElMessage} from "element-plus";
-
-let props = defineProps({
-    show: {
-        type: Boolean,
-        default: false
-    }
-})
-let emits = defineEmits(['close'])
-
-let equitiesForm = ref({
-    person: '',
-    area: ''
-})
-let changeIndex = ref(0)
-// const handleEquitiesSearch = ()=> {
-//
-// }
-
-let comboList = ref([])
-let comboIndex = ref(0)
-const handleCombo = (item, index) => {
-    comboIndex.value = index
-    api.additionalApi.rightsGrant(item.rightsId).then((res: any) => {
-        if(res.code == 200) {
-            comboData.value = res.data
-        } else {
-            ElMessage({
-                message: res.msg,
-                type: 'warning'
-            })
-        }
-    })
-}
-
-const mergeArrays = (originalArr, newArr, key) => {
-    // 创建 Map 存储原始数组,以指定键为索引
-    const map = new Map();
-    originalArr.forEach(item => {
-        map.set(item[key], item);
-    });
-
-    // 遍历新数组,替换或添加
-    newArr.forEach(item => {
-        map.set(item[key], item);
-    });
-
-    // 返回合并后的数组
-    return Array.from(map.values());
-}
-
-const handleAdd = () => {
-    comboList.value[comboIndex.value].countOne += 1
-    let list = comboList.value.filter(item => item.countOne > 0)
-    if(list.length > 0) {
-        chosedList.value = mergeArrays(chosedList.value, list, 'rightsId')
-        console.log(21312321321, chosedList.value)
-    }
-}
-const handleSubtract = () => {
-    if(comboList.value[comboIndex.value].countOne > 0) {
-        comboList.value[comboIndex.value].countOne -= 1
-    } else {
-        comboList.value[comboIndex.value].countOne = 0
-    }
-}
-
-let comboData = ref([])
-let chosedList = ref([]) // 已选的套餐
-let singleList = ref([]) // 已选的单品
-
-
-const handelCancel = () => {
-    emits('close', false)
-}
-const handelConfirm = () => {
-    emits('close', false)
-}
-
-const initEquities = (str, index) => {
-    changeIndex.value = index
-    if(index === 0) {
-        api.additionalApi.rightsGrantList({
-            pageNo: 1,
-            pageSize: 1000
-        }).then((res: any) => {
-            if(res.code == 200) {
-                comboList.value = res.data.records?.map(item => {
-                    return {
-                        ...item,
-                        countOne: 0
-                    }
-                })
-                handleCombo(comboList.value[0], 0)
-            } else {
-                ElMessage({
-                    message: res.msg,
-                    type: 'warning'
-                })
-            }
-        })
-    } else if (index === 1) {
-        api.additionalApi.rightsList({
-            pageNo: 1,
-            pageSize: 1000
-        }).then((res: any) => {
-            if(res.code == 200) {
-                comboData.value = res.data.records
-            } else {
-                ElMessage({
-                    message: res.msg,
-                    type: 'warning'
-                })
-            }
-        })
-    }
-}
-
-onMounted(() => {
-    initEquities('', 0)
-})
-
-</script>
-
-<style scoped lang="scss">
-.change{
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    margin: 20px 0;
-    .common{
-        padding: 6px 10px;
-        border: 1px solid #E5E5E5;
-        cursor: pointer;
-    }
-    .changeActive{
-        background: linear-gradient( 93deg, #4FCAFF 0%, #2B62FF 100%), #0083FF;
-        color: #ffffff;
-        border-color: #0083FF;
-    }
-}
-.combo, .single{
-    max-height: 400px;
-    .comboList{
-        width: 100%;
-        height: 100%;
-        overflow-y: auto;
-        .comboItem{
-            width: 100%;
-            overflow: hidden;
-            text-overflow: ellipsis;
-            white-space: nowrap;
-            line-height: 34px;
-            cursor: pointer;
-        }
-        .comboActive{
-            background: #f6fbff;
-            border-radius: 4px;
-            color: #0083FF;
-        }
-    }
-    .tips{
-        line-height: 20px;
-    }
-    .count{
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-        .countIcon{
-            border: 1px solid #ccc;
-            width: 16px;
-            height: 16px;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            border-radius: 50%;
-            cursor: pointer;
-        }
-    }
-    .chosed{
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-    }
-    .chosedList{
-        margin-top: 10px;
-        .chosedItem{
-            background: #F7F7F7;
-            padding: 10px;
-            border-radius: 4px;
-            margin-bottom: 10px;
-            .top{
-                display: flex;
-                align-items: flex-start;
-                justify-content: space-between;
-                margin-bottom: 10px;
-            }
-            .bottom{
-                display: flex;
-                align-items: center;
-                justify-content: space-between;
-            }
-        }
-    }
-}
-</style>

+ 10 - 10
src/views/index.vue

@@ -11,16 +11,16 @@ import api from '@/api'
 
 import { useRouter } from 'vue-router'
 
-import up from '@/assets/images/home/up.png'
-import down from '@/assets/images/home/down.png'
-import cxcd from '@/assets/images/home/cxcd.png'
-import bldd from '@/assets/images/home/bldd.png'
-import ddcx from '@/assets/images/home/ddcx.png'
-import xygl from '@/assets/images/home/xygl.png'
-import fygl from '@/assets/images/home/fygl.png'
-import bxgs from '@/assets/images/home/bxgs.png'
-import bxgszh from '@/assets/images/home/bxgszh.png'
-import ywygl from '@/assets/images/home/ywygl.png'
+import up from '../assets/images/home/up.png'
+import down from '../assets/images/home/down.png'
+import cxcd from '../assets/images/home/cxcd.png'
+import bldd from '../assets/images/home/bldd.png'
+import ddcx from '../assets/images/home/ddcx.png'
+import xygl from '../assets/images/home/xygl.png'
+import fygl from '../assets/images/home/fygl.png'
+import bxgs from '../assets/images/home/bxgs.png'
+import bxgszh from '../assets/images/home/bxgszh.png'
+import ywygl from '../assets/images/home/ywygl.png'
 
 import chinaMap from '@/assets/json/china.Json';
 import anhui from '@/assets/json/anhui.json'

+ 123 - 101
src/views/insurancePolicy/index.vue

@@ -393,8 +393,8 @@
             <div class="title">
               投保人信息
               <div class="ml-5 flex a-c">
-                <span class="ordinary" :class="{ 'active': item.checked }" v-for="item in btns.owner1"
-                  :key="item.text" @click.stop="handleChange(item, 'owner1')">
+                <span class="ordinary" :class="{ 'active': item.checked }" v-for="item in btns.owner1" :key="item.text"
+                  @click.stop="handleChange(item, 'owner1')">
                   {{ item.text }}
                 </span>
               </div>
@@ -435,14 +435,14 @@
               <el-form-item prop="identifyValidDate2" label="有效期起期">
                 <el-date-picker v-model="insurancePolicyForm.identifyValidDate2" type="date" placeholder="请选择"
                   value-format="YYYY-MM-DD" style="width: 100%"
-                  @blur="(e:any) => insurancePolicyForm.identifyValidDate2 = changeDate(e)" />
+                  @blur="(e: any) => insurancePolicyForm.identifyValidDate2 = changeDate(e)" />
               </el-form-item>
             </el-col>
             <el-col :span="6">
               <el-form-item prop="identifyValidEndDate2" label="有效期止期">
                 <el-date-picker v-model="insurancePolicyForm.identifyValidEndDate2" type="date" placeholder="请选择"
                   value-format="YYYY-MM-DD" style="width: 100%"
-                  @blur="(e:any) => insurancePolicyForm.identifyValidEndDate2 = changeDate(e)" />
+                  @blur="(e: any) => insurancePolicyForm.identifyValidEndDate2 = changeDate(e)" />
               </el-form-item>
             </el-col>
             <el-col :span="6">
@@ -574,14 +574,14 @@
               <el-form-item prop="identifyValidDate3" label="有效期起期">
                 <el-date-picker v-model="insurancePolicyForm.identifyValidDate3" type="date" placeholder="请选择"
                   value-format="YYYY-MM-DD" style="width: 100%"
-                  @blur="(e:any) => insurancePolicyForm.identifyValidDate3 = changeDate(e)" />
+                  @blur="(e: any) => insurancePolicyForm.identifyValidDate3 = changeDate(e)" />
               </el-form-item>
             </el-col>
             <el-col :span="6">
               <el-form-item prop="identifyValidEndDate3" label="有效期止期">
                 <el-date-picker v-model="insurancePolicyForm.identifyValidEndDate3" type="date" placeholder="请选择"
                   value-format="YYYY-MM-DD" style="width: 100%"
-                  @blur="(e:any) => insurancePolicyForm.identifyValidEndDate3 = changeDate(e)" />
+                  @blur="(e: any) => insurancePolicyForm.identifyValidEndDate3 = changeDate(e)" />
               </el-form-item>
             </el-col>
             <el-col :span="6">
@@ -670,8 +670,8 @@
             <div class="title">
               车船税
               <div class="ml-5 flex a-c">
-                <span class="ordinary" :class="{ 'active': item.checked }" v-for="item in btns.owner3"
-                  :key="item.text" @click.stop="handleChange(item, 'owner3')">
+                <span class="ordinary" :class="{ 'active': item.checked }" v-for="item in btns.owner3" :key="item.text"
+                  @click.stop="handleChange(item, 'owner3')">
                   {{ item.text }}
                 </span>
               </div>
@@ -812,9 +812,8 @@
             <div class="title">
               投保信息
               <div class="ml-5 flex a-c">
-                <span class="ordinary" :class="{ 'active': item.checked }"
-                  v-for="item in optionObj.insuranceType" :key="item.value"
-                  @click.stop="handleChange(item, 'insurance')">
+                <span class="ordinary" :class="{ 'active': item.checked }" v-for="item in optionObj.insuranceType"
+                  :key="item.value" @click.stop="handleChange(item, 'insurance')">
                   {{ item.label }}
                 </span>
               </div>
@@ -896,10 +895,11 @@
                     <div class="circle"></div>
                     <div>为车主提供 "省心、省时、又省钱" 的全场景服务</div>
                     <el-button style="margin: 0 20px" size="small" type="primary"
-                      @click="handleOpenEquities">选择权益</el-button>
+                      @click="handleOpenEquities(scope.row.quoteResult.ordersNo)">选择权益</el-button>
                   </div>
                   <div class="equitiesChoice">
-                    已选<span style="color: #0083FF">12</span>项去权益,共计<span style="color: #FF8C21">135.35</span>元
+                    已选<span style="color: #0083FF">{{ insOrderRightsInfoDto.length }}</span>项去权益,共计<span
+                      style="color: #FF8C21">{{ insOrderRightsInfoDto.totalPriceCount }}</span>元
                   </div>
                 </div>
                 <div class="expandFlex">
@@ -999,7 +999,7 @@
                           <el-table-column label="产品名称" prop="productName" align="center">
                             <template #default="props">
                               <el-button link type="primary" @click="getJYXDetail(props.row)">{{ props.row.productName
-                                }}</el-button>
+                              }}</el-button>
                             </template>
                           </el-table-column>
                           <el-table-column label="数量" align="center">
@@ -1118,7 +1118,8 @@
               <template #default="scope">
                 <el-select v-model="scope.row.agreement"
                   :disabled="!!scope.row.isDispatch || scope.row.agreements?.length == 1"
-                  v-if="currentRow.some((a:any) => a.id === scope.row.id)" :placeholder="scope.row.isDispatch ? '默认' : '请选择'">
+                  v-if="currentRow.some((a: any) => a.id === scope.row.id)"
+                  :placeholder="scope.row.isDispatch ? '默认' : '请选择'">
                   <el-option v-for="item in scope.row.agreements" :value="item.id"
                     :label="item.agreementName"></el-option>
                 </el-select>
@@ -1132,7 +1133,7 @@
                 </div>
               </template>
               <template #default="scope">
-                <div class="result" v-if="currentRow.some((a:any) => a.id === scope.row.id) && !scope.row.loading">
+                <div class="result" v-if="currentRow.some((a: any) => a.id === scope.row.id) && !scope.row.loading">
                   <div class="resultItem">
                     <span v-if="scope.row.quoteResult?.costs?.sumPremium">总保费:{{
                       scope.row.quoteResult?.costs?.sumPremium }}</span>
@@ -1184,13 +1185,15 @@
             </el-table-column>
             <el-table-column label="操作" align="center" width="360">
               <template #default="scope">
-                <div v-if="currentRow.some((a:any) => a.id === scope.row.id)">
+                <div v-if="currentRow.some((a: any) => a.id === scope.row.id)">
                   <el-button v-if="scope.row.quoteResult" link type="primary"
                     @click="handleCount(scope)">优惠测算</el-button>
-                  <el-button v-if="scope.row.quoteResult" link type="primary" @click="toDetail(scope)">详情</el-button>
+                  <el-button v-if="scope.row.quoteResult" link type="primary"
+                    @click="toDetail(scope.row.quoteResult.ordersNo)">详情</el-button>
                   <el-button link type="primary" :loading="scope.row.loading"
                     @click="handleSubmit(InsurancePolicyRefs, scope)">计算保费</el-button>
-                  <el-button v-if="scope.row.quoteResult" link type="primary" @click="handleShare(scope)">分享</el-button>
+                  <el-button v-if="scope.row.quoteResult" link type="primary"
+                    @click="handleShare(scope.row.quoteResult.ordersNo)">分享</el-button>
                   <el-button v-if="scope.row.quoteResult" link type="primary"
                     @click="handleUnderwriting(scope)">核保</el-button>
                 </div>
@@ -1302,7 +1305,9 @@
       <calculating ref="calculatingRefs"></calculating>
     </el-dialog>
     <el-dialog title="提交核保" width="1100" v-model="underwritingShow">
-      <underwriting ref="UnderwritingRefs" @close="handleUnderwritingClose"></underwriting>
+      <underwriting v-if="underwritingShow" ref="UnderwritingRefs" :insOrderRightsInfoDto="insOrderRightsInfoDto"
+        :availableAmount="availableAmount" :recipientInfo="[owerFormInfo, policyHolderInfo, insuredPersonInfo]"
+        @close="handleUnderwritingClose"></underwriting>
     </el-dialog>
     <el-dialog title="证件识别" width="800" v-model="imageShow">
       <recognition ref="RecognitionRefs" :option="optionObj.car_type_code" @close="handleImageClose"></recognition>
@@ -1367,7 +1372,9 @@
         <el-button size="small" type="primary" @click="handlePayCodeClose">关闭</el-button>
       </template>
     </el-dialog>
-    <Equities v-if="equitiesShow" :show="equitiesShow" @cancel="handleEquities"></Equities>
+    <Equities v-if="equitiesShow" :show="equitiesShow"
+      :recipientInfo="[owerFormInfo, policyHolderInfo, insuredPersonInfo]" :availableAmount="availableAmount"
+      @cancel="equitiesShow = false" @save="handleEquitiesSave"></Equities>
   </div>
 </template>
 
@@ -1389,6 +1396,7 @@ import salesmanSelect from '../additionalOrder/additional/modules/salesmanSelect
 import insurance from "../additionalOrder/additional/modules/insuranceSelect.vue"; // 保险选择模块
 import driving from '../../layouts/components/DrivingType/index.vue' // 驾意险模块
 import detail from '../../layouts/components/JYXDetail/index.vue' // 驾意险详情模块
+import Equities from './modules/Equities.vue' // 驾意险详情模块
 // 导入二维码生成库
 import QRCode from 'qrcode'
 // 导入日期处理库
@@ -1633,7 +1641,7 @@ const handleFocus = () => {
  * 处理业务员选择回调
  * @param data 选中的业务员数据
  */
-const handleSalesmanSelect = (data:any) => {
+const handleSalesmanSelect = (data: any) => {
   salesmanShow.value = false
   if (data) {
     // 如果已有业务员信息且选择了险种,则清空报价数据并重新过滤公司
@@ -1832,11 +1840,7 @@ let insurancePolicyRules = ref<FormRules>({
   ],
   engineNo: [
     { required: true, trigger: 'blur', message: '请输入发动机号' },
-    {
-      pattern: /^(?=.*[a-z])(?=.*\d).+$/i,
-      message: '请填写正确的发动机号',
-      trigger: 'blur'
-    }
+
   ],
   carNatureCode: [
     { required: true, trigger: 'change', message: '请选择车辆是否上牌' },
@@ -2070,8 +2074,8 @@ const licenseNoDataSubmit = () => {
     insurancePolicyForm.value.purchasePrice = carData.replacementValue
     insurancePolicyForm.value.displacement = carData.displacement
     insurancePolicyForm.value.powerScale = carData.powerScale
-  licenseNoShow.value = false
-  }else{
+    licenseNoShow.value = false
+  } else {
     ElMessage({
       message: '请选择车型',
       type: 'warning'
@@ -2143,7 +2147,7 @@ const longTime = () => {
   insurancePolicyForm.value.identifyValidEndDate1 = '9999-12-31'
 }
 
-const issueDateChange = (e:any) => {
+const issueDateChange = (e: any) => {
   insurancePolicyForm.value.transferDate = insurancePolicyForm.value.issueDate
 }
 
@@ -2185,7 +2189,7 @@ let btns = ref({
     checked: false
   }],
 })
-const handleChange = (item:any, type:any) => {
+const handleChange = (item: any, type: any) => {
 
   switch (type) {
     case 'owner1':
@@ -2305,7 +2309,7 @@ const initOption = () => {
   api.commonApi.personInfo('insurance_type').then((res: any) => {
     if (res.code == 200) {
       if (res.data && res.data.length > 0) {
-        res.data.forEach((a:any) => {
+        res.data.forEach((a: any) => {
           a.checked = false
         })
         optionObj.value.insuranceType = res.data
@@ -2346,7 +2350,7 @@ const getAgeByIdCard = (idCard: any, type?: any) => {
   // type.age = age
   return age
 }
-const noeYearPast = (time:any) => {
+const noeYearPast = (time: any) => {
   let strYear: any = time.getFullYear();
   let strDay: any = time.getDate();
   let strMonth: any = time.getMonth() + 1;
@@ -2382,7 +2386,7 @@ const noeYearPast = (time:any) => {
     Seconds;
   return datastr;
 }
-const oneYearPast1 = (time:any) => {
+const oneYearPast1 = (time: any) => {
   //明年减一秒
   let date = new Date(time);
   date.setSeconds(date.getSeconds() - 1);
@@ -2444,7 +2448,7 @@ const transformTime1 = () => {
   let datastr = strYear + "-" + strMonth + "-" + strDay + " " + "00:00:00";
   return datastr;
 }
-const JQChange = (item:any) => {
+const JQChange = (item: any) => {
   item.checked = !item.checked
   if (jqWork.value.some(a => a.checked)) {
     let date: any = new Date();
@@ -2460,7 +2464,7 @@ const JQChange = (item:any) => {
     insurancePolicyForm.value.JQInstantFlag = false
   }
 }
-const jqChange = (e:any) => {
+const jqChange = (e: any) => {
   insurancePolicyForm.value.JQEndDate = oneYearPast1(e)
 }
 // 日期限制函数
@@ -2476,7 +2480,7 @@ const disabledDate = (time: any) => {
 let syWork = ref([
   { text: '即时生效', checked: false }
 ])
-const SYChange = (item:any) => {
+const SYChange = (item: any) => {
   item.checked = !item.checked
   if (syWork.value.some(a => a.checked)) {
     let date: any = new Date();
@@ -2492,7 +2496,7 @@ const SYChange = (item:any) => {
     insurancePolicyForm.value.SYInstantFlag = false
   }
 }
-const syChange = (e:any) => {
+const syChange = (e: any) => {
   insurancePolicyForm.value.SYEndDate = oneYearPast1(e)
 }
 
@@ -2501,22 +2505,33 @@ let currentRow = ref([])
 let quoteData = ref<QuoteDataItem[]>([])
 
 // 选择权益
-let equitiesShow = ref(false)
-const handleOpenEquities = () => {
+let equitiesShow = ref(false)//权益弹窗是否显示
+const availableAmount = ref(1700)//可选金额
+const insOrderRightsInfoDto = ref<any>({})//权益信息
+const handleOpenEquities = (row: string) => {
+  console.log(row)
   equitiesShow.value = true
+  // api.insurancePolicyApi.getOrderDetail(row).then((res: any) => {
+  //   if (res.code == '200') {
+  //     availableAmount.value = res.data?.insFeeOrders.availableAmount || 0
+  //   }
+  // })
 }
-const handleEquities = (bool:any) => {
-  equitiesShow.value = bool
+// 保存权益
+const handleEquitiesSave = (data: any) => {
+  insOrderRightsInfoDto.value = data
+  console.log(insOrderRightsInfoDto.value)
+  equitiesShow.value = false
 }
 
-const handleSelect = (a:any, b:any) => {
+const handleSelect = (a: any, b: any) => {
   currentRow.value = a
   // currentRow.value = a
   // insurancePolicyForm.value.order.insuranceCompanyCode = a[0].id
 }
-const handelSelectRow = (a:any, b:any) => {
+const handelSelectRow = (a: any, b: any) => {
   currentRow.value = a
-  if (a.some((c:any) => c.id === b.id)) {
+  if (a.some((c: any) => c.id === b.id)) {
     insurancePolicyForm.value.order.insuranceCompanyCode = b.id
     if (insurancePolicyForm.value.productId) {
       api.insurancePolicyApi.getSchemeResult({
@@ -2529,14 +2544,14 @@ const handelSelectRow = (a:any, b:any) => {
           console.log(123123123, list)
         }
         if (list.length > 0) {
-          list.forEach((item:any) => {
+          list.forEach((item: any) => {
             item.checked = false
           })
         }
-        quoteData.value.forEach((item:any) => {
+        quoteData.value.forEach((item: any) => {
           item.productIndex = 0
           if (item.id === b.id) {
-            item.projectList = list.map((item:any) => {
+            item.projectList = list.map((item: any) => {
               return {
                 ...item,
                 rescue: [],
@@ -2553,7 +2568,7 @@ const handelSelectRow = (a:any, b:any) => {
     insurancePolicyForm.value.order.insuranceCompanyCode = ''
   }
 }
-const handelExpend = (e:any) => {
+const handelExpend = (e: any) => {
   insurancePolicyForm.value.order.insuranceCompanyCode = e.id
   if (insurancePolicyForm.value.productId) {
     api.insurancePolicyApi.getSchemeResult({
@@ -2566,14 +2581,14 @@ const handelExpend = (e:any) => {
         console.log(123123123, list)
       }
       if (list.length > 0) {
-        list.forEach((item:any) => {
+        list.forEach((item: any) => {
           item.checked = false
         })
       }
-      quoteData.value.forEach((item:any) => {
+      quoteData.value.forEach((item: any) => {
         item.productIndex = 0
         if (item.id === e.id) {
-          item.projectList = list.map((item:any) => {
+          item.projectList = list.map((item: any) => {
             return {
               ...item,
               rescue: [],
@@ -2587,39 +2602,39 @@ const handelExpend = (e:any) => {
     })
   }
 }
-const handleClickRow = (a:any, b:any) => {
+const handleClickRow = (a: any, b: any) => {
 
 }
-const handleViewSuccess = (e:any) => {
+const handleViewSuccess = (e: any) => {
   console.log(11111, quoteData.value)
 }
 // 选择险种
 let insuranceShow = ref(false)
-const handlePopover = (scope:any) => {
+const handlePopover = (scope: any) => {
   insuranceShow.value = true
   nextTick(() => {
     InsuranceTypeRef.value.initEditData(scope.row.projectList[scope.row.productIndex].kinds)
   })
 }
 // 删除险种
-const handleInsuranceDel = (scope:any, props:any) => {
-  let obj = scope.row.projectList[scope.row.productIndex].kinds.filter((a:any) => a.id != props.row.id)
-  quoteData.value.forEach((a:any) => {
+const handleInsuranceDel = (scope: any, props: any) => {
+  let obj = scope.row.projectList[scope.row.productIndex].kinds.filter((a: any) => a.id != props.row.id)
+  quoteData.value.forEach((a: any) => {
     if (a.id === scope.row.id) {
       a.projectList[scope.row.productIndex].kinds = obj
     }
   })
 }
-const handleClose = (data:any) => {
+const handleClose = (data: any) => {
   insuranceShow.value = false
   if (data && data.list.length > 0) {
-    data.list.forEach((item:any) => {
-      let obj = item.options.find((b:any) => b.checked)
+    data.list.forEach((item: any) => {
+      let obj = item.options.find((b: any) => b.checked)
       item.amount = obj.value
       item.unitAmount = obj.value
     })
   }
-  quoteData.value.forEach((a:any) => {
+  quoteData.value.forEach((a: any) => {
     if (insurancePolicyForm.value.order.insuranceCompanyCode === a.id) {
       a.projectList[a.productIndex].kinds = data.list
     }
@@ -2630,7 +2645,7 @@ const handleClose = (data:any) => {
 let drivingShow = ref(false)
 let drivingRow = ref(0)
 let JYXDetailShow = ref(false)
-const handleDriving = (scope:any) => {
+const handleDriving = (scope: any) => {
   drivingRow.value = scope.$index
   drivingShow.value = true
   nextTick(() => {
@@ -2638,24 +2653,24 @@ const handleDriving = (scope:any) => {
   })
 }
 // 删除驾意险
-const handleDrivingDel = (scope:any, props:any) => {
-  let obj = scope.row.projectList[scope.row.productIndex].drivings.filter((a:any) => a.id != props.row.id)
-  quoteData.value.forEach((a:any) => {
+const handleDrivingDel = (scope: any, props: any) => {
+  let obj = scope.row.projectList[scope.row.productIndex].drivings.filter((a: any) => a.id != props.row.id)
+  quoteData.value.forEach((a: any) => {
     if (a.id === scope.row.id) {
       a.projectList[scope.row.productIndex].drivings = obj
     }
   })
 }
 // 驾意险详情
-const getJYXDetail = (row:any) => {
+const getJYXDetail = (row: any) => {
   JYXDetailShow.value = true
   nextTick(() => {
     JYXDetail.value.initData(row.drivingIntentionId)
   })
 }
-const handleDrivingClose = (data:any) => {
+const handleDrivingClose = (data: any) => {
   if (data && data.list.length > 0) {
-    data.list.forEach((a:any) => {
+    data.list.forEach((a: any) => {
       a.quantity = 1
     })
     const quoteItem = quoteData.value[drivingRow.value]
@@ -2674,7 +2689,7 @@ let specialIndex = ref(-1)
 let specialShow = ref(false)
 let specialTableData = ref([])
 let specialSelectList = ref<any[]>([])
-const handleSelectSpecial = (scope:any) => {
+const handleSelectSpecial = (scope: any) => {
   specialIndex.value = scope.$index
   specialShow.value = true
   api.insurancePolicyApi.getClausePage({
@@ -2691,7 +2706,7 @@ const handleSelectSpecial = (scope:any) => {
     }
   })
 }
-const handleSpecialSelectChage = (a:any) => {
+const handleSpecialSelectChage = (a: any) => {
   specialSelectList.value = [...a]
 }
 const handleSpecialTableDataCancel = () => {
@@ -2713,7 +2728,7 @@ const handleSpecialTableDataSubmit = () => {
 // 优惠信息
 let discounts = ref([])
 let productIndex = ref(0)
-const handleProduct = (scope:any, e:any, index:any) => {
+const handleProduct = (scope: any, e: any, index: any) => {
   scope.row.productIndex = index
 }
 
@@ -2723,7 +2738,7 @@ let tableData = ref([])
 // 分享
 let shareShow = ref(false)
 let shareImageUrl = ref('')
-const handleShare = async (scope:any) => {
+const handleShare = async (scope: any) => {
   shareShow.value = true
   shareImageUrl.value = await QRCode.toDataURL(`http://test-tennat.baoxianzhanggui.com/h5/#/pages/quote/paymentCode?ordersNo=${scope.row.quoteResult.ordersNo}`, {
     width: 150,
@@ -2755,7 +2770,7 @@ const handleCopyLink = async () => {
 
 // 优惠测算
 let calculatingShow = ref(false)
-const handleCount = (scope:any) => {
+const handleCount = (scope: any) => {
   calculatingShow.value = true
 }
 
@@ -2771,10 +2786,10 @@ const toDetail = (scope: any) => {
 }
 
 // 上传影像
-const handleImageSave = (scope:any) => {
-  let list = images.value.filter((a:any) => a.checked)
+const handleImageSave = (scope: any) => {
+  let list = images.value.filter((a: any) => a.checked)
   if (list.length > 0) {
-    let arr = list.map((a:any) => {
+    let arr = list.map((a: any) => {
       return {
         imageCode: a.imageType,
         imageBase64List: [
@@ -2806,7 +2821,7 @@ const handleImageSave = (scope:any) => {
 }
 
 //支付码
-const getPayCode = (orderNo:any) => {
+const getPayCode = (orderNo: any) => {
   api.insurancePolicyApi.getQrCode(orderNo).then((res: any) => {
     if (res.code == 200) {
       payCodeUrl.value = res.data?.qrcode
@@ -2823,7 +2838,7 @@ const getPayCode = (orderNo:any) => {
 //分享
 let qrImageUrl = ref('')
 let payCodeUrl = ref('')
-const handleCode = async (orderNo:any) => {
+const handleCode = async (orderNo: any) => {
   api.insurancePolicyApi.getQrCode(orderNo).then((res: any) => {
     if (res.code == 200) {
       payCodeUrl.value = res.data?.qrcode
@@ -2864,7 +2879,7 @@ const handlePopoverConfirm = async () => {
 // 提交核保
 let underwritingShow = ref(false)
 let underwritingIndex = ref(-1)
-const handleUnderwriting = (scope:any) => {
+const handleUnderwriting = (scope: any) => {
   console.log('要去核保的数据', scope.row)
   underwritingShow.value = true
   underwritingIndex.value = scope.$index
@@ -2901,7 +2916,8 @@ const handleUnderwriting = (scope:any) => {
 
 let underwritingMsgShow = ref(false)
 
-const handleUnderwritingClose = (bool:any, msg:any) => {
+const handleUnderwritingClose = (bool: any, msg: any) => {
+  console.log(bool, msg)
   underwritingShow.value = false
   if (msg) {
     console.log(msg)
@@ -2930,7 +2946,7 @@ const handleGetPayCode = () => {
     }
   })
 }
-const srcChange = async (url:any) => {
+const srcChange = async (url: any) => {
   payCodeSrc.value = await QRCode.toDataURL(url, {
     width: 150,
     margin: 2
@@ -2941,14 +2957,17 @@ const handlePayCodeClose = () => {
   payCodeShow.value = false
 }
 
+const owerFormInfo = ref<any>({})
+const policyHolderInfo = ref<any>({})
+const insuredPersonInfo = ref<any>({})
 // 证件识别
 let imageShow = ref(false)
 let images = ref([])
-const handleImageClose = (data:any) => {
-  btns.value.owner1.forEach((a:any) => {
+const handleImageClose = (data: any) => {
+  btns.value.owner1.forEach((a: any) => {
     a.checked = false
   })
-  btns.value.owner2.forEach((a:any) => {
+  btns.value.owner2.forEach((a: any) => {
     a.checked = false
   })
   imageShow.value = false
@@ -3046,7 +3065,7 @@ const handleImageClose = (data:any) => {
       }
     }
     if (imageVoList && imageVoList.length > 0) {
-      insurancePolicyForm.value.imageVoList = imageVoList.filter((a:any) => a.imageBase64List[0].imageId)
+      insurancePolicyForm.value.imageVoList = imageVoList.filter((a: any) => a.imageBase64List[0].imageId)
     }
     if (list && list.length > 0) {
       images.value = list
@@ -3056,7 +3075,7 @@ const handleImageClose = (data:any) => {
 
 // 记录已填好的信息,防止再次进行证件识别
 let hadWritedData = ref<Partial<typeof insurancePolicyForm.value>>({})
-const handleRecognition = (achor:any) => {
+const handleRecognition = (achor: any) => {
   imageShow.value = true
   hadWritedData.value = JSON.parse(JSON.stringify(insurancePolicyForm.value))
   nextTick(() => {
@@ -3073,7 +3092,7 @@ let loading = ref(false)  // 提交加载状态
  * @param InsurancePolicyRefs 表单引用实例
  * @param scope 当前行作用域
  */
-const handleSubmit = async (InsurancePolicyRefs: FormInstance | undefined, scope :any) => {
+const handleSubmit = async (InsurancePolicyRefs: FormInstance | undefined, scope: any) => {
   // 检查货车是否填写核定载质量
   if (insurancePolicyForm.value.plateType == 'A1') {
     if (!insurancePolicyForm.value.limitLoad) {
@@ -3088,7 +3107,7 @@ const handleSubmit = async (InsurancePolicyRefs: FormInstance | undefined, scope
     InsurancePolicyRefs?.resetFields()
     return
   }
-  await InsurancePolicyRefs.validate((valid:any) => {
+  await InsurancePolicyRefs.validate((valid: any) => {
     if (valid) {
       // 设置当前报价项的加载状态
       quoteData.value[scope.$index].loading = true
@@ -3099,17 +3118,17 @@ const handleSubmit = async (InsurancePolicyRefs: FormInstance | undefined, scope
         let obj = quoteData.value.find((a: QuoteDataItem) => a.id === insurancePolicyForm.value.order.insuranceCompanyCode)
         if (obj && obj.projectList && obj.productIndex !== undefined) {
           // 收集险种信息
-          obj.projectList[obj.productIndex].kinds?.forEach((a:any) => {
+          obj.projectList[obj.productIndex].kinds?.forEach((a: any) => {
             arr.push(a)
           })
           // 收集驾意险信息
-          obj.projectList[obj.productIndex].drivings?.forEach((a:any) => {
+          obj.projectList[obj.productIndex].drivings?.forEach((a: any) => {
             brr.push(a)
           })
         }
         // 收集特约信息
         if (obj?.specialSelectedList && obj.specialSelectedList.length > 0) {
-          obj.specialSelectedList.forEach((a:any) => {
+          obj.specialSelectedList.forEach((a: any) => {
             crr.push(a)
           })
         }
@@ -3124,7 +3143,7 @@ const handleSubmit = async (InsurancePolicyRefs: FormInstance | undefined, scope
       }
 
       // 处理车主与投保人关系
-      let obj1 = btns.value.owner1.find((a:any) => a.checked)
+      let obj1 = btns.value.owner1.find((a: any) => a.checked)
       btns.value.owner1Text = obj1.text
       if (obj1.text === '同车主') {
         // 如果选择"同车主",则将投保人信息设为车主信息
@@ -3144,7 +3163,7 @@ const handleSubmit = async (InsurancePolicyRefs: FormInstance | undefined, scope
       }
 
       // 处理投保人与被保人关系
-      let obj2 = btns.value.owner2.find((a:any) => a.checked)
+      let obj2 = btns.value.owner2.find((a: any) => a.checked)
       btns.value.owner2Text = obj2.text
       if (obj2.text === '同车主') {
         // 如果被保人选择"同车主",则将被保人信息设为车主信息
@@ -3296,6 +3315,9 @@ const handleSubmit = async (InsurancePolicyRefs: FormInstance | undefined, scope
         accidentalDrivings: [...brr],
         specialInfoVo: [...crr]
       }
+      owerFormInfo.value = { ...data.ownersInfo, title: '车主', policyPersonType: '1' };
+      policyHolderInfo.value = { ...data.policyHolderInfo, title: '投保人', policyPersonType: '2' };
+      insuredPersonInfo.value = { ...data.insuredPersonInfo, title: '被保人', policyPersonType: '3' };
       // 先保存影像资料
       api.insurancePolicyApi.imageSave({
         order: {
@@ -3367,11 +3389,11 @@ const handleSubmit = async (InsurancePolicyRefs: FormInstance | undefined, scope
               quoteData.value[scope.$index].loading = false
             }
             // InsurancePolicyRefs.resetFields()
-          }).catch((e:any) => {
+          }).catch((e: any) => {
             // 处理异常情况,重置加载状态
             loading.value = false
             quoteData.value[scope.$index].loading = false
-            quoteData.value.forEach((a:any) => {
+            quoteData.value.forEach((a: any) => {
               a.loading = false
             })
           })
@@ -3482,7 +3504,7 @@ const handleNext = () => {
  * 显示费用匹配错误信息
  * @param scope 当前行作用域
  */
-const handleOpen = (scope:any) => {
+const handleOpen = (scope: any) => {
   ElNotification({
     title: '费用匹配错误信息',
     message: h('p', { style: 'white-space: pre-line' }, `${scope.row.quoteResult?.feeNoDescription}`),
@@ -3494,7 +3516,7 @@ const handleOpen = (scope:any) => {
  * 根据产品ID和车辆及人员信息获取可报价的保险公司列表
  * @param item 选中的产品信息
  */
-const ruleFilterCompany = (item:any) => {
+const ruleFilterCompany = (item: any) => {
   let data = {
     productId: item.value,  // 产品ID
     carInfo: {  // 车辆信息
@@ -3568,12 +3590,12 @@ const ruleFilterCompany = (item:any) => {
   api.insurancePolicyApi.ruleFilterCompany(data).then((res: any) => {
     if (res.code == 200) {
       // 设置每个保险公司的加载状态
-      res.data.forEach((a:any) => {
+      res.data.forEach((a: any) => {
         a.loading = false
       })
       quoteData.value = res.data
       // 如果只有一个协议,自动选择
-      quoteData.value.forEach((item:any) => {
+      quoteData.value.forEach((item: any) => {
         if (item.agreements && item.agreements.length == 1) {
           item.agreement = item.agreements[0].id
         }
@@ -3997,4 +4019,4 @@ onMounted(() => {
     }
   }
 }
-</style>
+</style>

+ 504 - 0
src/views/insurancePolicy/modules/Equities.vue

@@ -0,0 +1,504 @@
+<!-- 模板区域 -->
+<template>
+  <div>
+    <el-dialog v-model="dialogVisible" title="选择权益" width="60%" @close="cancel">
+      <el-form :model="form" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="10">
+            <el-form-item label="接收人">
+              <el-select v-model="form.recipient" placeholder="请选择接收人" style="width: 100%">
+                <el-option v-for="item in props.recipientInfo" :key="item.title"
+                  :label="`${item.title}--${item.mobile}`" :value="item.title" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="10">
+            <el-form-item label="用户所在地区">
+              <el-cascader v-model="provinceoptions" style="width: 100%;" filterable clearable :options="regionOptions"
+                :props="areaProps" @change="provinceChange" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <!-- tab切换 -->
+      <div class="tabs mt-5 flex a-c j-c">
+        <div class="item" @click="changeTab(index)" v-for="(item, index) in tabslist" :key="index"
+          :class="{ 'active': index == changeTabIndex }">{{ item.label }}</div>
+      </div>
+      <div class="flex mt-4">
+        <div class="tab-content">
+          <template v-if="changeTabIndex == 0">
+            <!-- 权益套餐 -->
+            <div class="flex ">
+              <div class="flex f-c a-c benefit">
+                <div class="benefitList flex f-c">
+                  <span class="item " v-for="(item, index) in benefitPackageList"
+                    :class="{ 'active': item.rightsId == selectedPackageDetail.rightsId }" :key="item.rightsId"
+                    @click="rightsDetails(item, index)">{{
+                      item.equityPackageName }}</span>
+                </div>
+                <el-pagination size="small" v-model:current-page="pageInfo.pageNum"
+                  v-model:page-size="pageInfo.pageSize" :page-sizes="pageInfo.sizes" layout="prev,pager,next,total"
+                  :total="pageInfo.total" />
+              </div>
+              <div class="benefitDetails" v-if="selectedPackageDetail.rightsId">
+                <div class="header">
+                  <span class="title">套餐明细</span>
+                  <div class="configuration flex a-c j-s ">
+                    <span>数量:{{ selectedPackageDetail.totalNumber }}张</span>
+                    <span>价格:{{ selectedPackageDetail.packagePrice }}元</span>
+                    <el-input-number :model-value="selectedPackageDetail.rightsCount" :min="0"
+                      @update:model-value="val => onRightsCountChange(val, benefitPackageIndex, 'benefitPackageList', 'packagePrice')">
+                      <template #decrease-icon>
+                        <el-icon>
+                          <Remove />
+                        </el-icon>
+                      </template>
+                      <template #increase-icon>
+                        <el-icon>
+                          <CirclePlus />
+                        </el-icon>
+                      </template>
+                    </el-input-number>
+                  </div>
+                </div>
+                <div style="overflow-y: auto; max-height: 250px;"
+                  v-if="selectedPackageDetail.rightsDetailsList && selectedPackageDetail.rightsDetailsList.length > 0">
+                  <div class="Details-list">
+                    <div class="view flex a-c  " v-for="item in selectedPackageDetail.rightsDetailsList">
+                      <div class="item">{{ item.rightsName }}</div>
+                      <div class="item">¥{{ item.settlePrice }}元</div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </template>
+          <template v-else>
+            <!-- 权益单品 -->
+            <el-table :data="privilegeItem" style="width: 100%" max-height="300px" overflow="auto">
+              <el-table-column prop="rightsName" label="权益名称" width="180" align="center" />
+              <el-table-column prop="settlePrice" label="单价" width="180" align="center" />
+              <el-table-column prop="rightsCount" label="发放数量" align="center">
+                <template #default="scope">
+                  <el-input-number size="small" :model-value="scope.row.rightsCount"
+                    @update:model-value="val => onRightsCountChange(val, scope.$index, 'privilegeItem', 'settlePrice')"
+                    :min="0" />
+                </template>
+              </el-table-column>
+              <el-table-column prop="totalsum" label="总价" align="center">
+                <template #default="scope">
+                  <span>{{ scope.row.settlePrice * scope.row.rightsCount }}</span>
+                </template>
+              </el-table-column>
+            </el-table>
+          </template>
+
+        </div>
+        <!-- 已选择权益 -->
+        <div class="displaySelected ">
+          <span>可用金额:{{ props.availableAmount }}元</span>
+          <div class="header-sum flex a-c j-s ">
+            <span>已选{{ selectedRights.length }}个,共计{{ totalPriceCount }}元</span>
+            <el-button type="primary" size="small" link @click="clearSelectedRights">
+              <el-icon>
+                <Delete />
+              </el-icon>
+              清空</el-button>
+          </div>
+          <!-- 已选列表视图 -->
+          <div class="selectedList flex f-c">
+            <div v-for="item in selectedRights" :key="item.rightsId" class="item">
+              <div class="flex f-c ">
+                <div class="flex a-c j-s">
+                  <span class="equityPackageName">{{ item.equityPackageName || item.rightsName }}</span>
+                  <span class="rightsCount">x{{ item.rightsCount }}</span>
+                </div>
+                <div class="mt-5 flex a-c j-s">
+                  <span v-if="item.totalNumber">数量:{{ item.totalNumber }}张</span>
+                  <span>价格:{{ item.packagePrice || item.settlePrice }}元</span>
+                  <el-icon @click="removeSelectedRight(item)">
+                    <Delete />
+                  </el-icon>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="cancel">取消</el-button>
+          <el-button type="primary" @click="save">
+            确定
+          </el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<!-- 行为区域 -->
+<script lang='ts' setup>
+import { ref, reactive, computed, onBeforeMount, watch } from 'vue'
+import api from '@/api'
+import { ElMessage } from 'element-plus'
+import Decimal from 'decimal.js'
+const props = defineProps<{
+  show: boolean,
+  recipientInfo: Array<any>,//接收人信息
+  availableAmount: number
+}>();
+console.log(props.availableAmount)
+// 使用本地变量管理对话框显示状态
+const dialogVisible = ref(false);
+// 监听props.show变化,同步到本地变量
+watch(() => props.show, (newVal) => {
+  dialogVisible.value = newVal;
+}, { immediate: true });
+watch(() => props.recipientInfo, (newVal) => {
+  recipientOptions.value = newVal;
+});
+// 组件挂载时获取地区数据
+onBeforeMount(async () => {
+  await queryTreeQuery();
+  await getBenefitPackageList();
+  await getPrivilegeItem();
+  provinceoptions.value = ['110000', '110100', '110101']
+
+});
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 20,
+  sizes: [20],
+  total: 50,
+});
+const queryInfo = ref({
+  countryAll: '', //山西省太原太原市  //省市区
+  minPrice: 0,
+  maxPrice: 1000,
+  sortType: 0, //排序  0 默认 1低价  2高价
+  pageNo: 1,
+  pageSize: 20,
+});
+const benefitPackageList = ref(); //权益套餐列表
+const privilegeItem = ref(); //权益单品列表
+const insOrderRightsPackageList = ref([]); //权益套餐选中列表
+const insOrderRightsList = ref([]); //权益单品选中列表
+const benefitPackageIndex = ref(0); //选中的权益套餐索引
+const selectedPackageDetail = ref<any>({}) //选中的权益套餐详情
+const emits = defineEmits(["cancel", 'save']);
+const changeTabIndex = ref(0);
+const totalPriceCount = computed(() => {
+  // 计算权益套餐的总价
+  const packageTotal = benefitPackageList.value?.reduce((sum: Decimal, item: any) => {
+    if (item.rightsCount > 0) {
+      const itemTotal = new Decimal(item.packagePrice || 0).times(new Decimal(item.rightsCount || 0));
+      return sum.plus(itemTotal);
+    }
+    return sum;
+  }, new Decimal(0)) || new Decimal(0);
+  // 计算权益单品的总价
+  const itemTotal = privilegeItem.value?.reduce((sum: Decimal, item: any) => {
+    if (item.rightsCount > 0) {
+      const itemTotal = new Decimal(item.settlePrice || 0).times(new Decimal(item.rightsCount || 0));
+      return sum.plus(itemTotal);
+    }
+    return sum;
+  }, new Decimal(0)) || new Decimal(0);
+
+  // 合并所有总价
+  const sum = new Decimal(packageTotal).plus(itemTotal);
+  return sum.toString(); // 返回字符串
+});
+//合并所有已选权益套餐和权益单品
+const selectedRights = computed(() => {
+  const selectedPackages = benefitPackageList.value?.filter((item: any) => item.rightsCount > 0) || []
+  insOrderRightsPackageList.value = selectedPackages
+  // 收集选择的权益单品
+  const selectedItems = privilegeItem.value?.filter((item: any) => item.rightsCount > 0) || []
+  insOrderRightsList.value = selectedItems
+  return selectedPackages.concat(selectedItems)
+})
+// 清空已选权益套餐和权益单品
+const  clearSelectedRights = () => {
+  benefitPackageList.value.forEach((item: any) => {
+    item.rightsCount = 0;
+  });
+  privilegeItem.value.forEach((item: any) => {
+    item.rightsCount = 0;
+  });
+}
+// 移除已选权益套餐或权益单品
+const removeSelectedRight = (item: any) => {
+  if (item.rightsCount > 0) {
+    item.rightsCount = 0;
+  }
+}
+const onRightsCountChange = (e: any, index: any, name: any, field: string) => {
+  // 根据数组名称获取对应的数组
+  let targetArray: any[] = [];
+  if (name === 'benefitPackageList') {
+    targetArray = benefitPackageList.value || [];
+  } else if (name === 'privilegeItem') {
+    targetArray = privilegeItem.value || [];
+  }
+  // 获取当前项
+  const item = targetArray[index];
+  if (!item) {
+    console.error('无法找到对应数据,数组:', name, '索引:', index)
+    return
+  }
+  // 获取当前数量和新数量
+  const currentCount = item.rightsCount || 0;
+  const newCount = e;
+  // 计算价格
+  const price = parseFloat(item[field] || 0);
+  // 计算当前总价
+  const currentTotalPrice = parseFloat(totalPriceCount.value || 0);
+  // 计算数量变化和价格变化
+  const countChange = newCount - currentCount;
+  const priceChange = countChange * price;
+  // 计算新总价
+  const newTotalPrice = currentTotalPrice + priceChange;
+  console.log(countChange)
+  // 如果是增加数量,检查是否超过可用金额
+  if (countChange > 0 && newTotalPrice > props.availableAmount) {
+    ElMessage({
+      type: 'success',
+      message: `权益总价不能超过可用金额${props.availableAmount}元`,
+      plain: true,
+    })
+  } else {
+    // 无论是减少数量还是增加数量且未超过限制,都允许更新
+    item.rightsCount = newCount;
+  }
+}
+// 表单数据
+const form = reactive({
+  recipient: '',
+  region: []
+});
+const areaProps = {
+  expandTrigger: 'hover' as const,
+  value: 'areaCode',
+  label: 'areaCname',
+  children: 'child'
+}
+// 接收人选项
+const recipientOptions = ref()
+const tabslist = ref([
+  {
+    label: '权益套餐',
+  },
+  {
+    label: '权益单品',
+  }
+]);
+// 地区选择器改变时触发
+// 获取权益套餐列表
+const getBenefitPackageList = async () => {
+  try {
+    const response = await api.additionalApi.rightsGrantList(queryInfo.value);
+    benefitPackageList.value = response.data.records || [];
+  } catch (error) {
+    console.error('获取权益套餐列表失败:', error);
+  }
+};
+
+// 获取权益单品列表
+const getPrivilegeItem = async () => {
+  try {
+    const response = await api.additionalApi.rightsList(queryInfo.value);
+    privilegeItem.value = response.data.records || [];
+  } catch (error) {
+    console.error('获取权益单品列表失败:', error);
+  }
+}
+// 选中的权益套餐详情
+const rightsDetails = async (item: any, index: any) => {
+  selectedPackageDetail.value = item;
+  benefitPackageIndex.value = index;
+  try {
+    const response = await api.additionalApi.rightsGrant(item.rightsId);
+    selectedPackageDetail.value.rightsDetailsList = response.data || {};
+  } catch (error) {
+    console.error('获取权益套餐详情失败:', error);
+  }
+}
+// 地区选项
+const regionOptions = ref();
+const provinceoptions = ref();
+
+// 获取地区数据
+const queryTreeQuery = () => {
+  api.areaApi.areaList({}).then((res: any) => {
+    if (res.code == '200') {
+      regionOptions.value = res.data;
+    } else {
+      ElMessage({
+        type: 'success',
+        message: res.msg,
+        plain: true,
+      })
+    }
+  });
+}
+const provinceChange = (value: any) => {
+  if (value && value[0] != null && value[1] != null && value[2] != null) {
+
+  } else {
+  }
+}
+// 切换tab
+const changeTab = (index: number) => {
+  changeTabIndex.value = index;
+}
+
+const cancel = () => {
+  // 重置表单
+  form.recipient = '';
+  form.region = [];
+  emits("cancel")
+}
+
+const save = () => {
+  if (!form.recipient) {
+    ElMessage({
+      type: 'warning',
+      message: '请选择接收人',
+      plain: true,
+    })
+    return
+  }
+  let info = props.recipientInfo.find((item: any) => item.title == form.recipient);
+  console.log(info)
+  let insOrderRightsInfoDto = {
+    length: selectedRights.value.length,
+    totalPriceCount: totalPriceCount.value,
+    recipient: info.title,
+    insOrderRightsPackageList: insOrderRightsPackageList.value,
+    insOrderRightsList: insOrderRightsList.value,
+    rightsGrantReceiverDTO: {
+      receiverType: info.policyPersonType,
+      receiverName: info.name,
+      receiverMobile: info.mobile
+    }
+  }
+  // 发送表单数据
+  emits("save", insOrderRightsInfoDto)
+}
+</script>
+<!-- 样式区域 -->
+<style lang='scss' scoped>
+.tabs {
+  .item {
+    padding: 5px 12px;
+    border: 1px solid #E5E5E5;
+    cursor: pointer;
+    border-radius: 2px 0px 0px 2px;
+  }
+
+  .item:last-child {
+    border-left: none;
+    border-radius: 0px 2px 2px 0px;
+  }
+
+  .item.active {
+    background: linear-gradient(93deg, #4FCAFF 0%, #2B62FF 100%), #0083FF;
+    color: #fff;
+    border-color: #4FCAFF;
+  }
+}
+
+.tab-content {
+  width: 70%;
+  flex: 1;
+
+  .benefit {
+    width: 35%;
+
+    .benefitList {
+      height: 300px;
+      overflow-y: auto;
+      width: 100%;
+
+      .item {
+        margin-bottom: 5px;
+        padding: 6px 8px;
+        box-sizing: border-box;
+        cursor: pointer;
+        font-size: 14px;
+        color: #333;
+      }
+
+      .item.active {
+        background: #F6FBFF;
+        border-radius: 4px 4px 4px 4px;
+        color: #0083FF;
+      }
+    }
+  }
+
+  .benefitDetails {
+    margin-left: 20px;
+    flex: 1;
+
+    .title {
+      font-size: 14px;
+      color: #333;
+      font-weight: bold;
+    }
+
+    .configuration {
+      margin-top: 10px;
+    }
+
+    .Details-list {
+      margin-top: 20px;
+      border-top: 1px solid #E5E5E5;
+      border-left: 1px solid #E5E5E5;
+
+      .view {
+        border-bottom: 1px solid #E5E5E5;
+      }
+
+      .item {
+        padding: 6px 15px;
+        box-sizing: border-box;
+        border-right: 1px solid #E5E5E5;
+      }
+
+      .item:first-child {
+        flex: 1;
+      }
+
+      .item:last-child {}
+    }
+  }
+}
+
+.displaySelected {
+  width: 30%;
+  margin-left: 30px;
+
+  .header-sum {
+    margin-bottom: 10px;
+    font-size: 14px;
+    color: #333;
+  }
+
+  .selectedList {
+    height: 300px;
+    overflow-y: auto;
+
+    .item {
+      background: #F7F7F7;
+      border-radius: 4px 4px 4px 4px;
+      padding: 10px;
+      box-sizing: border-box;
+      margin-bottom: 10px;
+    }
+  }
+}
+</style>

+ 335 - 203
src/views/insurancePolicy/modules/underwriting.vue

@@ -1,108 +1,139 @@
 <template>
-  <div class="underwriting">
-      <div class="change">
-          <span class="common" :class="{ 'changeActive': changeIndex === index }" v-for="(item, index) in ['核保信息', '权益信息']" @click="changeIndex = index">{{ item }}</span>
-      </div>
-        <div v-show="changeIndex == 0">
-            <div class="title">
-                <span class="text">影像信息</span>
-                <el-popover :visible="imageTypeShow" placement="bottom-start" :width="600" trigger="click">
-                    <template #reference>
-                        <el-button plain type="primary" icon="Plus" size="small" @click="addImages">添加影像资料</el-button>
-                    </template>
-                    <imageTypeSelect ref="ImageTypeSelect" @close="handleImageTypeSelect"></imageTypeSelect>
-                </el-popover>
-            </div>
-            <div class="images">
-                <el-row :gutter="20">
-                    <el-col class="col-m-b-16" style="margin-bottom: 16px" :span="6" v-for="(item, index) in images" :key="index">
-                        <el-upload v-if="!item.fileUrl" :auto-upload="false" :show-file-list="false"@change="uploadImage($event, item)">
-                            <div class="upload-box">
-                                <div class="icon-box">
-                                    <el-icon style="font-size: 20px"><Camera /></el-icon>
-                                    <p>{{ item.label }}</p>
-                                </div>
-                            </div>
-                        </el-upload>
-                        <div class="fileInfo" v-else>
-                            <div class="file-box">
-                                <div class="btn-top">
-                                    <img class="image-close" @click="deleteImage(item)" src="@/assets/images/close.png" />
-                                </div>
-                                <img class="file-img" :src="item.fileUrl" />
-                                <div class="btn-bottom">
-                                    <el-upload class="width-50" :show-file-list="false" :auto-upload="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, item)" style="display: flex; align-items: center; justify-content: center; color: white">
-                                        <el-icon><Upload /></el-icon>重新上传
-                                    </el-upload>
-                                    <div class="width-50" style="display: flex; align-items: center; justify-content: center; color: white; cursor:pointer;" @click="downloadImage(item)">
-                                        <el-icon><Download /></el-icon>下载资料
-                                    </div>
-                                </div>
-                            </div>
-                        </div>
-                    </el-col>
-                </el-row>
-            </div>
-            <div class="title">
-                <span class="text">特别约定</span>
-            </div>
-            <el-table
-                    ref="ClauseRefs"
-                    :data="tableData"
-                    row-key="id"
-                    @selection-change="selectionChange"
-            >
-                <el-table-column type="selection" width="50" align="center" :selectable="selectable"></el-table-column>
-                <el-table-column label="特约类型" prop="riskCode" align="center">
-                    <template #default="scope">
-                        <div v-if="scope.row.riskCode == '0507'">交强</div>
-                        <div v-if="scope.row.riskCode == '0510'">商业</div>
-                    </template>
-                </el-table-column>
-                <el-table-column label="特约名称" prop="clauseName" align="center"></el-table-column>
-                <el-table-column label="编码" prop="clauseCode" align="center"></el-table-column>
-                <el-table-column label="特别约定内容" prop="" width="300" align="center">
-                    <template #default="scope">
-                        <div v-if="!scope.row.edit" @click="() => { scope.row.edit = true }">{{ scope.row.clauseContent }}</div>
-                        <el-input type="textarea" v-model="scope.row.clauseContent" v-if="scope.row.edit"></el-input>
-                    </template>
-                </el-table-column>
-            </el-table>
+  <div class="">
+    <div class="change">
+      <span class="common" :class="{ 'changeActive': changeIndex === index }" v-for="(item, index) in ['核保信息', '权益信息']"
+        @click="changeIndex = index">{{ item }}</span>
+    </div>
+    <div class="underwriting">
+      <div v-show="changeIndex == 0">
+        <div class="title">
+          <span class="text">影像信息</span>
+          <el-popover :visible="imageTypeShow" placement="bottom-start" :width="600" trigger="click">
+            <template #reference>
+              <el-button plain type="primary" icon="Plus" size="small" @click="addImages">添加影像资料</el-button>
+            </template>
+            <imageTypeSelect ref="ImageTypeSelect" @close="handleImageTypeSelect"></imageTypeSelect>
+          </el-popover>
         </div>
-      <div v-show="changeIndex == 1">
-          <el-button icon="plus" type="primary" @click="handleOpenEquities">选择权益</el-button>
-          <el-table
-              :data="equitiesData"
-              style="margin-top: 20px"
-          >
-              <el-table-column prop="a" label="权益名称"></el-table-column>
-              <el-table-column prop="a" label="权益类型"></el-table-column>
-              <el-table-column prop="a" label="接收人"></el-table-column>
-              <el-table-column prop="a" label="发放数量"></el-table-column>
-              <el-table-column prop="a" label="价格"></el-table-column>
-          </el-table>
-          <div class="total">
-              <div class="money">
-                  <div class="totalItem">
-                      <span>可用金额:</span>
-                      <span>{{ useMoney }}</span>
+        <div class="images">
+          <el-row :gutter="20">
+            <el-col class="col-m-b-16" style="margin-bottom: 16px" :span="6" v-for="(item, index) in images"
+              :key="index">
+              <el-upload v-if="!item.fileUrl" :auto-upload="false" :show-file-list="false"
+                @change="uploadImage($event, item)">
+                <div class="upload-box">
+                  <div class="icon-box">
+                    <el-icon style="font-size: 20px">
+                      <Camera />
+                    </el-icon>
+                    <p>{{ item.label }}</p>
                   </div>
-                  <div class="totalItem">
-                      <span>已使用:</span>
-                      <span>{{ usedMoney }}</span>
+                </div>
+              </el-upload>
+              <div class="fileInfo" v-else>
+                <div class="file-box">
+                  <div class="btn-top">
+                    <img class="image-close" @click="deleteImage(item)" src="@/assets/images/close.png" />
                   </div>
-                  <div class="totalItem">
-                      <span>剩余金额:</span>
-                      <span style="color: #FF8C21">{{ lastMoney }}</span>
+                  <img class="file-img" :src="item.fileUrl" />
+                  <div class="btn-bottom">
+                    <el-upload class="width-50" :show-file-list="false" :auto-upload="false" accept=".png, .jpg, .jpeg"
+                      @change="uploadImage($event, item)"
+                      style="display: flex; align-items: center; justify-content: center; color: white">
+                      <el-icon>
+                        <Upload />
+                      </el-icon>重新上传
+                    </el-upload>
+                    <div class="width-50"
+                      style="display: flex; align-items: center; justify-content: center; color: white; cursor:pointer;"
+                      @click="downloadImage(item)">
+                      <el-icon>
+                        <Download />
+                      </el-icon>下载资料
+                    </div>
                   </div>
+                </div>
               </div>
+            </el-col>
+          </el-row>
+        </div>
+        <div class="title">
+          <span class="text">特别约定</span>
+        </div>
+        <el-table ref="ClauseRefs" :data="tableData" row-key="id" @selection-change="selectionChange">
+          <el-table-column type="selection" width="50" align="center" :selectable="selectable"></el-table-column>
+          <el-table-column label="特约类型" prop="riskCode" align="center">
+            <template #default="scope">
+              <div v-if="scope.row.riskCode == '0507'">交强</div>
+              <div v-if="scope.row.riskCode == '0510'">商业</div>
+            </template>
+          </el-table-column>
+          <el-table-column label="特约名称" prop="clauseName" align="center"></el-table-column>
+          <el-table-column label="编码" prop="clauseCode" align="center"></el-table-column>
+          <el-table-column label="特别约定内容" prop="" width="300" align="center">
+            <template #default="scope">
+              <div v-if="!scope.row.edit" @click="() => { scope.row.edit = true }">{{ scope.row.clauseContent }}</div>
+              <el-input type="textarea" v-model="scope.row.clauseContent" v-if="scope.row.edit"></el-input>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+      <div v-show="changeIndex == 1">
+        <div class="flex a-c recipient ">
+          <span>选择权益接收人</span>
+          <el-select v-model="recipient" placeholder="请选择接收人" style="width: 100%">
+            <el-option v-for="item in props.recipientInfo" :key="item.title" :label="`${item.title}--${item.mobile}`"
+              :value="item.title" />
+          </el-select>
+        </div>
+        <el-button icon="plus" type="primary" @click="handleOpenEquities">选择权益</el-button>
+        <el-table :data="equitiesData" style="margin-top: 20px" height="200px">
+          <el-table-column prop="equityPackageName" label="权益名称" align="center">
+            <template #default="scope">
+              <div>{{ scope.row.equityPackageName || scope.row.rightsName }}</div>
+            </template>
+          </el-table-column>
+          <el-table-column prop="rightsType" label="权益类型" align="center">
+            <template #default="scope">
+              <span v-if="scope.row.equityPackageName">套餐</span>
+              <span v-else>单品</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="rightsCount" label="发放数量" align="center"></el-table-column>
+          <el-table-column prop="packagePrice" label="总价" align="center">
+            <template #default="scope">
+              <div>{{ scope.row.packagePrice * scope.row.rightsCount || scope.row.settlePrice * scope.row.rightsCount }}
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column label="操作" align="center">
+            <template #default="scope">
+              <el-button type="primary" link size="small" @click="equitiesDelete(scope.row)">删除</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+        <div class="total">
+          <div class="money">
+            <div class="totalItem">
+              <span>可用金额:</span>
+              <span>{{ props.availableAmount }}</span>
+            </div>
+            <div class="totalItem">
+              <span>已使用:</span>
+              <span>{{ totalPriceCount }}</span>
+            </div>
+            <div class="totalItem">
+              <span>剩余金额:</span>
+              <span style="color: #FF8C21">{{ props.availableAmount - parseFloat(totalPriceCount) }}</span>
+            </div>
           </div>
+        </div>
       </div>
+    </div>
     <div class="footer">
       <el-button plain type="primary" @click="handleSubmit(false)">取消</el-button>
       <el-button type="primary" @click="handleSubmit(true)">提交核保</el-button>
     </div>
-      <Equities :show="equitiesShow" @close="handleEquities"></Equities>
   </div>
 </template>
 
@@ -110,12 +141,71 @@
 import api from '@/api'
 import { ElMessage } from 'element-plus'
 import imageTypeSelect from './imageTypeSelect.vue'
+import Decimal from 'decimal.js'
 
+const props = defineProps<{
+  insOrderRightsInfoDto: any,//权益信息
+  availableAmount: number,//可用金额
+  recipientInfo: Array<any>,//接收人信息
+}>();
+const insOrderRightsInfoDto = ref()//权益信息
+const equitiesData = ref()//权益数据
+const recipient = ref('')//接收人
+const useMoney = ref(0)//可用金额
+const usedMoney = ref(0)//已使用金额
+const lastMoney = ref(0)//剩余金额
 const ImageTypeSelect = ref()
 const emit = defineEmits(['close'])
-
 let images = ref([])
+watch(() => props.insOrderRightsInfoDto, (newVal) => {
+  console.log('权益信息', newVal)
+  recipient.value = newVal?.recipient || ''
+  insOrderRightsInfoDto.value = newVal;
+  equitiesData.value = insOrderRightsInfoDto.value?.insOrderRightsPackageList?.concat(insOrderRightsInfoDto.value?.insOrderRightsList || []) || [];
+  console.log('权益数据', equitiesData.value)
+}, { immediate: true });
+
+// 计算已使用金额
+const totalPriceCount = computed(() => {
+  // 计算权益套餐的总价
+  const packageTotal = insOrderRightsInfoDto.value?.insOrderRightsPackageList?.reduce((sum: Decimal, item: any) => {
+    if (item.rightsCount > 0) {
+      const itemTotal = new Decimal(item.packagePrice || 0).times(new Decimal(item.rightsCount || 0));
+      return sum.plus(itemTotal);
+    }
+    return sum;
+  }, new Decimal(0)) || new Decimal(0);
+  // 计算权益单品的总价
+  const itemTotal = insOrderRightsInfoDto.value?.insOrderRightsList?.reduce((sum: Decimal, item: any) => {
+    if (item.rightsCount > 0) {
+      const itemTotal = new Decimal(item.settlePrice || 0).times(new Decimal(item.rightsCount || 0));
+      return sum.plus(itemTotal);
+    }
+    return sum;
+  }, new Decimal(0)) || new Decimal(0);
+
+  // 合并所有总价
+  const sum = new Decimal(packageTotal).plus(itemTotal);
+  return sum.toString(); // 返回字符串
+});
+// 删除权益
+const equitiesDelete = (item: any) => {
+  console.log('删除权益', item)
+  equitiesData.value = equitiesData.value.filter((i: any) => i !== item)
+  if (item.rightsId) {
+    // 从权益套餐数组中删除
+    if (insOrderRightsInfoDto.value?.insOrderRightsPackageList) {
+      insOrderRightsInfoDto.value.insOrderRightsPackageList =
+        insOrderRightsInfoDto.value.insOrderRightsPackageList.filter((i: any) => i.rightsId !== item.rightsId)
+    }
 
+    // 从权益单品数组中删除
+    if (insOrderRightsInfoDto.value?.insOrderRightsList) {
+      insOrderRightsInfoDto.value.insOrderRightsList =
+        insOrderRightsInfoDto.value.insOrderRightsList.filter((i: any) => i.rightsId !== item.rightsId)
+    }
+  }
+}
 // 添加影像资料
 let imageTypeShow = ref(false)
 const addImages = () => {
@@ -126,7 +216,7 @@ const addImages = () => {
 }
 const handleImageTypeSelect = (data) => {
   imageTypeShow.value = false
-  if(data&&data.list?.length>0) {
+  if (data && data.list?.length > 0) {
     images.value = data.list
   }
 }
@@ -145,8 +235,8 @@ const uploadImage = async (file, item) => {
   params.append("file", files);
   params.append("type", "image");
   const { code, data, msg } = await api.commonApi.fileUpload(params)
-  if(code == 200) {
-    let result: any = {...data}
+  if (code == 200) {
+    let result: any = { ...data }
     item.fileUrl = result.downloadUrl
     item.imageId = result.id
     item.fileName = result.fileName
@@ -180,7 +270,7 @@ const download = (url, name) => {
   image.src = url
 }
 const downloadImage = (item) => {
-  download(item.fileUrl,item.fileName)
+  download(item.fileUrl, item.fileName)
 }
 
 // 特别约定
@@ -188,64 +278,74 @@ let tableData = ref([])
 let ClauseRefs = ref()
 let clauseList = ref([])
 const queryClauseData = () => {
-    api.insurancePolicyApi.queryClauseData({
-        order: {
-            ordersNo: ordersNo.value
-        }
-    }).then((res: any) => {
-        if(res.code == 200) {
-            tableData.value = res.data.map((item) => {
-                return {
-                    ...item,
-                    edit: false
-                }
-            })
-            clauseList.value = tableData.value?.filter(item => item.clientStatus != '3')
-            nextTick(() => {
-                tableData.value?.forEach(item => {
-                    if(item.clientStatus != '3') {
-                        ClauseRefs.value.toggleRowSelection(item, true)
-                    }
-                })
-            })
-        } else {
-            ElMessage({
-                message: res.msg,
-                type: 'warning'
-            })
+  api.insurancePolicyApi.queryClauseData({
+    order: {
+      ordersNo: ordersNo.value
+    }
+  }).then((res: any) => {
+    if (res.code == 200) {
+      tableData.value = res.data.map((item) => {
+        return {
+          ...item,
+          edit: false
         }
-    })
+      })
+      clauseList.value = tableData.value?.filter(item => item.clientStatus != '3')
+      nextTick(() => {
+        tableData.value?.forEach(item => {
+          if (item.clientStatus != '3') {
+            ClauseRefs.value.toggleRowSelection(item, true)
+          }
+        })
+      })
+    } else {
+      ElMessage({
+        message: res.msg,
+        type: 'warning'
+      })
+    }
+  })
 }
 const selectable = (row) => !['2'].includes(row.clientStatus)
 const selectionChange = (val) => {
-    clauseList.value = val
+  clauseList.value = val
 }
 
 // 提交核保
 const handleSubmit = (bool) => {
-  if(bool) {
+  if (bool) {
+    let info = props.recipientInfo.find((item: any) => item.title == recipient.value);
     api.insurancePolicyApi.underwriting({
       order: {
         ordersNo: ordersNo.value
       },
+      insOrderRightsInfoDto: {
+        insOrderRightsPackageList: insOrderRightsInfoDto.value.insOrderRightsPackageList,
+        insOrderRightsList: insOrderRightsInfoDto.value.insOrderRightsList,
+        rightsGrantReceiverDTO: {
+          receiverType: info.policyPersonType,
+          receiverName: info.name,
+          receiverMobile: info.mobile
+        }
+      },
       specialAppointmentsVos: [...clauseList.value]
     }).then((res: any) => {
-      if(res.code === 200) {
+      if (res.code === 200) {
         ElMessage({
           message: res.msg,
           type: 'success'
         })
-          emit('close', 'success')
+        emit('close', 'success')
       } else {
-          if(res.code == 500) {
-              emit('close', 'error', res.msg)
-          } else {
-              emit('close', 'error')
-          }
-          ElMessage({
-            message: res.msg,
-            type: 'warning'
-          })
+        if (res.code == 500) {
+          emit('close', 'error', res.msg)
+        } else {
+          emit('close', 'error')
+        }
+        ElMessage({
+          message: res.msg,
+          type: 'warning'
+        })
       }
     })
   } else {
@@ -256,33 +356,28 @@ const handleSubmit = (bool) => {
 //数据交互
 let ordersNo = ref('')
 const initEdit = (data) => {
-    console.log('核保的数据', data)
+  console.log('核保的数据', data)
   ordersNo.value = data.ordersNo
   images.value = data.list.map(item => {
-      return {
-          ...item,
-          fileUrl: item.fileUrl || item.downloadUrl
-      }
-  })
-    if(ordersNo.value) {
-        queryClauseData()
+    return {
+      ...item,
+      fileUrl: item.fileUrl || item.downloadUrl
     }
+  })
+  if (ordersNo.value) {
+    queryClauseData()
+  }
 }
 
 let changeIndex = ref(1)
 
-// 权益
-let equitiesData = ref([])
-let useMoney = ref(0)
-let usedMoney = ref(0)
-let lastMoney = ref(0)
 // 选择权益
 let equitiesShow = ref(false)
 const handleOpenEquities = () => {
-    equitiesShow.value = true
+  equitiesShow.value = true
 }
 const handleEquities = (bool) => {
-    equitiesShow.value = bool
+  equitiesShow.value = bool
 }
 
 defineExpose({
@@ -292,38 +387,46 @@ defineExpose({
 </script>
 
 <style scoped lang="scss">
-.underwriting{
-  max-height: 400px;
+.change {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin: 20px 0;
+
+  .common {
+    padding: 6px 10px;
+    border: 1px solid #E5E5E5;
+    cursor: pointer;
+  }
+
+  .changeActive {
+    background: linear-gradient(93deg, #4FCAFF 0%, #2B62FF 100%), #0083FF;
+    color: #ffffff;
+    border-color: #0083FF;
+  }
+}
+
+.underwriting {
+  max-height: 500px;
   overflow-y: auto;
   overflow-x: hidden;
-  .change{
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    margin: 20px 0;
-    .common{
-      padding: 6px 10px;
-      border: 1px solid #E5E5E5;
-      cursor: pointer;
-    }
-    .changeActive{
-      background: linear-gradient( 93deg, #4FCAFF 0%, #2B62FF 100%), #0083FF;
-      color: #ffffff;
-      border-color: #0083FF;
-    }
-  }
-  .title{
+
+
+
+  .title {
     display: flex;
     align-items: center;
     justify-content: flex-start;
     margin-bottom: 10px;
-    .text{
+
+    .text {
       margin-right: 10px;
       border-left: 3px solid #00a0f4;
       padding-left: 10px;
     }
   }
-  .upload-box{
+
+  .upload-box {
     width: 208px;
     height: 130px;
     background: #EEEEEE;
@@ -332,47 +435,55 @@ defineExpose({
     display: flex;
     align-items: center;
     justify-content: center;
-    .icon-box{
+
+    .icon-box {
       text-align: center;
       color: #999999;
-      p{
+
+      p {
         margin: 0 0;
         font-size: 14px;
       }
     }
   }
-  .fileInfo{
+
+  .fileInfo {
     display: flex;
     align-items: center;
     justify-content: flex-start;
     //padding: 2px 20px;
     border-radius: 5px;
     margin: 0 10px;
+
     //&:hover{
     //  background: #ccc;
     //}
-    .fileName{
+    .fileName {
       width: 200px;
       overflow: hidden;
       text-overflow: ellipsis;
       white-space: nowrap;
     }
-    .fileBtn{
+
+    .fileBtn {
       display: flex;
       align-items: center;
-      .btn-icon{
+
+      .btn-icon {
         margin: 0 10px;
         font-size: 16px;
         cursor: pointer;
-        &:hover{
+
+        &:hover {
           color: #00a0f4;
         }
       }
     }
 
-    .file-box{
+    .file-box {
       position: relative;
-      .btn-top{
+
+      .btn-top {
         width: 100%;
         display: flex;
         align-items: center;
@@ -380,19 +491,22 @@ defineExpose({
         position: absolute;
         top: 0;
         left: 0;
-        .image-close{
+
+        .image-close {
           display: block;
           width: 12px;
           height: 12px;
         }
       }
-      .file-img{
+
+      .file-img {
         display: block;
         width: 208px;
         height: 130px;
         border-radius: 5px;
       }
-      .btn-bottom{
+
+      .btn-bottom {
         position: absolute;
         left: 0;
         bottom: 0;
@@ -403,31 +517,49 @@ defineExpose({
         width: 100%;
         background: url("@/assets/images/btn-bg.png") no-repeat;
         background-size: 100% 100%;
-        .width-50{
+
+        .width-50 {
           width: 50%;
         }
       }
     }
   }
-    .total{
-        display: flex;
-        justify-content: flex-end;
-        margin-top: 20px;
-        .money{
-            width: 200px;
-            margin-right: 30px;
-            .totalItem{
-                display: flex;
-                align-items: center;
-                justify-content: space-between;
-            }
-        }
-    }
-  .footer{
+
+  .total {
     display: flex;
-    align-items: center;
     justify-content: flex-end;
-    margin-top: 10px;
+    margin-top: 20px;
+
+    .money {
+      width: 200px;
+      margin-right: 30px;
+
+      .totalItem {
+        margin-bottom: 10px;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+      }
+    }
+  }
+
+
+}
+
+.footer {
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
+  margin-top: 10px;
+}
+
+.recipient {
+  margin-bottom: 10px;
+  box-sizing: border-box;
+
+  span {
+    flex: 0 0 120px;
+    margin-right: 10px;
   }
 }
 </style>