Просмотр исходного кода

Merge branch 'dev' of http://39.101.143.165:8090/dong_k/tenant-Platform into dev

祁鹏飞 1 месяц назад
Родитель
Сommit
d9c46f36b7

+ 3 - 0
src/api/modules/additional.ts

@@ -30,6 +30,9 @@ const additionalApi = (axiosInstance: ApiInstance) => ({
   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), // 权益券分页查询
+  rightsCategory: () => axiosInstance.post(`/rightsGrant/get/category`), // 权益券分类
+  rightsProduct: (data: any) => axiosInstance.post('/rightsGrant/get/product', data), // 权益券商品详情
+  updateAvailableAmount: (data: any) => axiosInstance.post('/insFeeOrder/updateAvailableAmount', data), // 更新权益券可用金额
 })
 
 export default additionalApi

+ 6 - 1
src/views/finance/modules/auditDetail.vue

@@ -999,7 +999,7 @@
             <el-tab-pane v-for="(item, index) in infoList" :label="item.label" :name="item.name">
               <el-row :gutter="10" class="list">
                 <el-col :span="4" class="list-item" v-for="sub in item.list">
-                  <img :src="sub.previewUrl" />
+                  <img :src="sub.previewUrl"  @click="viewImage(sub)"  />
                   <div class="tips">{{ sub.imageType === 'C01' ? '行驶证主页' : sub.imageType === 'D01' ? '行驶证副页' :
                     sub.imageType
                       ===
@@ -1128,6 +1128,7 @@
       <el-button size="small" type="primary" @click="handleUpdateToQuestionOrder">确定</el-button>
     </template>
   </el-dialog>
+
 </template>
 
 <script setup lang="ts">
@@ -1211,6 +1212,10 @@ let optionObj = ref({
   insuranceType: [], // 险种类型
   car_type_code: [], // 车辆类型
 })
+const  viewImage = (item) => {
+  imageUrl.value = item.previewUrl
+  imageShow.value = true
+}
 const initOption = () => {
   let list = ['vehicle_use_code', 'car_nature_code', 'energy_type_code', 'car_kind_code', 'car_type_code']
   list.forEach(item => {

+ 19 - 8
src/views/insurancePolicy/index.vue

@@ -920,7 +920,8 @@
             :preserve-expanded-content="true" @row-click="handleClickRow" @expand-change="handelExpend">
             <el-table-column type="expand">
               <template #default="scope">
-                <div class="equities">
+                <div class="equities"
+                  v-if="scope.row.quoteResult?.ownerRights == '1' && ['1', '3'].includes(scope.row.quoteResult?.clientType)">
                   <div class="mr-3 equitiesTitle">客户权益</div>
                   <div class="equitiesBox">
                     <div class="equitiesLabel">
@@ -1440,7 +1441,7 @@
     </el-dialog>
     <el-dialog :close-on-click-modal="false" title="提交核保" width="1100" v-model="underwritingShow">
       <underwriting v-if="underwritingShow" ref="UnderwritingRefs" :insOrderRightsInfoDto="insOrderRightsInfoDto"
-        :availableAmount="availableAmount" :recipientInfo="[owerFormInfo, policyHolderInfo, insuredPersonInfo]"
+         :recipientInfo="[owerFormInfo, policyHolderInfo, insuredPersonInfo]"
         @close="handleUnderwritingClose" @initDetail="initDetail"></underwriting>
     </el-dialog>
     <el-dialog :close-on-click-modal="false" title="证件识别" width="800" v-model="imageShow">
@@ -1508,9 +1509,9 @@
         <el-button size="small" type="primary" @click="handlePayCodeClose">关闭</el-button>
       </template>
     </el-dialog>
-    <Equities v-if="equitiesShow" :show="equitiesShow"
-      :recipientInfo="[owerFormInfo, policyHolderInfo, insuredPersonInfo]" :availableAmount="availableAmount"
-      @cancel="equitiesShow = false" @save="handleEquitiesSave"></Equities>
+    <Equities v-model:show="equitiesShow"
+      :recipientInfo="[owerFormInfo, policyHolderInfo, insuredPersonInfo]" :EquitiesInfo="EquitiesInfo"
+      @save="handleEquitiesSave"></Equities>
   </div>
   <quotation ref="quotationRef" :quotationObj="quotationObj" :insurancePolicyForm="insurancePolicyForm" />
 </template>
@@ -2708,18 +2709,28 @@ let quoteData = ref<QuoteDataItem[]>([])
 
 // 选择权益
 let equitiesShow = ref(false)//权益弹窗是否显示
-const availableAmount = ref(0)//可选金额
+const EquitiesInfo = ref<any>({
+  insFeeOrders: {},//费用信息
+  insOrderRightsInfoVo: {},//权益信息
+  ordersNo: "",//订单号
+})//相关参数
 const insOrderRightsInfoDto = ref<any>({})//权益信息
 const handleOpenEquities = (row: string) => {
-  equitiesShow.value = true
   api.insurancePolicyApi.getOrderDetail(row).then((res: any) => {
     if (res.code == '200') {
-      availableAmount.value = res.data?.insFeeOrders.availableAmount || 0
+      EquitiesInfo.value.insFeeOrders = res.data?.insFeeOrders || {}
+      EquitiesInfo.value.insOrderRightsInfoVo = res.data?.insOrderRightsInfoVo || {}
+      EquitiesInfo.value.ordersNo = res.data?.ordersNo || ""
+      equitiesShow.value = true
+      // EquitiesInfo.value.insFeeOrders.availableAmount =500 || 0
+
     }
   })
+
 }
 // 保存权益
 const handleEquitiesSave = (data: any) => {
+  console.log(data)
   insOrderRightsInfoDto.value = data
 
   equitiesShow.value = false

+ 390 - 249
src/views/insurancePolicy/modules/Equities.vue

@@ -1,140 +1,181 @@
 <!-- 模板区域 -->
 <template>
   <div>
-    <el-dialog :close-on-click-modal="false" v-model="dialogVisible" title="选择权益" width="60%" @close="cancel">
-      <el-form :model="form" label-width="120px">
+    <el-drawer :model-value="show" @update:model-value="$emit('update:show', $event)" title="权益选择"
+      :direction="direction" size="1100px">
+
+      <el-form :model="form" label-width="80px" label-position="left">
         <el-row :gutter="20">
-          <el-col :span="10">
+          <el-col :span="24">
             <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-radio-group v-model="form.recipient">
+                <el-radio v-for="item in props.recipientInfo" :key="item.title" :value="item.title">{{ item.title
+                  }}</el-radio>
+                <el-radio :value="'other'">其它
+                  <el-input class="ml-2" v-model="form.otherRecipient" style="width: 200px" placeholder="请输入" />
+                </el-radio>
+              </el-radio-group>
             </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 class="orderIssueFee">
+        <div class="expenseInfo flex a-c j-s">
+          <div>
+            <span>出单费用</span>
+            <span>¥{{ insFeeOrders.totalExportPremium || 0 }}</span>
+          </div>
+          <div>
+            <span>可用金额</span>
+            <span>¥{{ insFeeOrders.availableAmount || 0 }}<span
+                style="color: #409EFF;font-weight: 400; cursor: pointer;" @click="adjustDiscountAmount"
+                v-if="insFeeOrders.totalExportKeepPointPremium == 0">修改</span>
+            </span>
+          </div>
+          <div>
+            <span>已使用金额</span>
+            <span>¥{{ insFeeOrders.usedAmount || 0 }}</span>
+          </div>
+          <div>
+            <span>剩余金额</span>
+            <span style="color: #FF8C21;"> ¥{{ insFeeOrders.remainingAmount || 0 }}</span>
+          </div>
+          <div>
+            <span>已选权益价值</span>
+            <span  style="color: #FF8C21;"> ¥{{insOrderRightsPackageList.length > 0 ? totalPriceCount : totalPriceCount1 || 0 }}</span>
+          </div>
+        </div>
+        <!-- 备注信息 -->
+        <div class="commentText flex a-c ">
+          <el-icon color="#0083FF">
+            <InfoFilled />
+          </el-icon>
+          <span>出单后,计算出可使用金额,录入本次使用金额,可使用该金额为用户购买权益,剩余金额会返回到业务员的钱包,业务员可提现。</span>
+        </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.id == selectedPackageDetail.id }" :key="item.id"
-                    @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.id">
-                <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 class="flex mt-4  tab-btn">
+        <div class="left">已选权益</div>
+        <div class="content flex  f-c ">
+          <div class="tabs flex a-c ">
+            <div class="item" :class="{ 'active': insOrderRightsPackageList.length > 0 }" @click="PackageBenefits">
+              选择套餐权益</div>
+            <div class="item ml-[24px]" :class="{ 'active': insOrderRightsList.length > 0 }" @click="RightsBenefits">
+              选择单品权益</div>
+          </div>
+          <span class="text-[14px] text-[#666] mt-[8px]">使用可用金额,可为接收人选购权益套餐 和 权益单品,2选1</span>
+
+          <div class="PackageselectedList mt-[16px] flex " v-if="insOrderRightsPackageList.length > 0">
+            <div class="view-card mr-[20px]">
+              <div class="view-item mb-[10px]  " :class="{ 'active': index === benefitPackageIndex }"
+                v-for="(item, index) in insOrderRightsPackageList" :key="index" @click="rightsDetails(item, index)">
+                <div class="flex f-c ">
+                  <div class="flex a-c j-s">
+                    <span class="equityPackageName text-[14px] text-[#333]">{{ item.equityPackageName }}</span>
+                    <span class="rightsCount text-[14px] text-[#333]">x{{ item.rightsCount }}</span>
                   </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.contractRate }}元</div>
-                    </div>
+                  <div class="mt-5 flex a-c j-s">
+                    <span v-if="item.totalNumber" class="text-[12px] text-[#666]">数量:{{ item.totalNumber }}张</span>
+                    <span class="text-[12px] text-[#666]">价格:{{ item.packagePrice }}元</span>
+                    <el-icon @click="removeSelectedRight(index)" color="#666">
+                      <Delete />
+                    </el-icon>
                   </div>
                 </div>
               </div>
             </div>
-          </template>
-          <template v-else>
-            <!-- 权益单品 -->
-            <el-table :data="privilegeItem" style="width: 100%" max-height="300px" overflow="auto">
+            <el-table class="details" :data="selectedPackageDetail.rightsDetailsList" max-height="300px"
+              style="flex: 1;" border>
               <el-table-column prop="rightsName" label="权益名称" width="180" align="center" />
-              <el-table-column prop="contractRate" label="单价" width="180" align="center" />
-              <el-table-column prop="rightsCount" label="发放数量" align="center">
+              <el-table-column prop="number" label="数量" align="center" />
+              <el-table-column prop="contractRate" label="价格" align="center"></el-table-column>
+              <el-table-column prop="marketPrice" label="价值" align="center">
+              </el-table-column>
+              <el-table-column prop="shareableStoreNum" label="适用门店" align="center" width="180">
                 <template #default="scope">
-                  <el-input-number size="small" :model-value="scope.row.rightsCount"
-                    @update:model-value="val => onRightsCountChange(val, scope.$index, 'privilegeItem', 'contractRate')"
+                  {{ scope.row.shareableStoreNum }}家门店可用
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+          <div class="RightselectedList mt-[16px]  " v-if="insOrderRightsList.length > 0">
+            <el-table class="details" :data="insOrderRightsList" max-height="300px" style="flex: 1;cursor: pointer;"
+              border>
+              <el-table-column prop="rightsName" label="权益名称" align="center">
+                <template #default="scope">
+                  <el-popover placement="right" trigger="click" :width="324">
+                    <div class="iframe-container">
+                      <iframe :src="iframeUrl" frameborder="0" class="external-iframe"></iframe>
+                    </div>
+                    <template #reference>
+                      <span @click="benefitDetail(scope.row)" :class="{ 'clicked': clickedRightsId === scope.row.id }">
+                        {{ scope.row.rightsName }}
+                      </span>
+                    </template>
+                  </el-popover>
+                </template>
+              </el-table-column>
+              <el-table-column prop="contractRate" label="价格" align="center"></el-table-column>
+              <el-table-column prop="marketPrice" label="价值" align="center"></el-table-column>
+              <el-table-column prop="shareableStoreNum" label="适用门店" align="center">
+                <template #default="scope">
+                  {{ scope.row.shareableStoreNum }}家门店可用
+                </template>
+              </el-table-column>
+              <el-table-column prop="number" label="数量" align="center">
+                <template #default="scope">
+                  <el-input-number size="small" :model-value="scope.row.rightsCount" style="width: 80px;"
+                    @update:model-value="val => onRightsCountChange(val, scope.$index, 'insOrderRightsList', 'contractRate')"
                     :min="0" />
                 </template>
               </el-table-column>
-              <el-table-column prop="totalsum" label="总价" align="center">
+              <el-table-column prop="total" label="总价" align="center">
                 <template #default="scope">
-                  <span>{{ scope.row.contractRate * scope.row.rightsCount }}</span>
+                  {{ new Decimal(scope.row.contractRate || 0).times(scope.row.rightsCount || 0).toFixed(2) }}
                 </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.contractRate }}元</span>
-                  <el-icon @click="removeSelectedRight(item)">
-                    <Delete />
-                  </el-icon>
-                </div>
-              </div>
-            </div>
           </div>
         </div>
       </div>
       <template #footer>
-        <div class="dialog-footer">
+        <div class="dialog-footer flex a-c j-c ">
           <el-button class="border-[#0083FF] color-[#0083FF]" plain @click="cancel">取消</el-button>
           <el-button type="primary" @click="save">
             确定
           </el-button>
         </div>
       </template>
+    </el-drawer>
+    <!-- 权益金额调整弹窗 -->
+    <el-dialog v-model="adjustDiscountAmountShow" title="设置可用金额" width="420" draggable>
+      <div class="description flex ">
+        <el-icon color="#FAA21E" size="16" class="mr-[12px] mt-[3px]">
+          <Warning />
+        </el-icon>
+        <span>本次订单共计优惠<span class="font-size-[16px] font-bold">{{ insFeeOrders.availableAmount ||
+            0}}</span>元,您可使用部分优惠金额为客户购买车主服务。</span>
+      </div>
+      <div class="flex a-c mt-[24px]">
+        <span style="flex-shrink: 0;" class="mr-[12px]">可用金额</span>
+        <el-input v-model="availableAmount" placeholder="请输入" />
+      </div>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="adjustDiscountAmountShow = false">取消</el-button>
+          <el-button type="primary" @click="adjustDiscountAmountconfirm">
+            确定
+          </el-button>
+        </div>
+      </template>
     </el-dialog>
+    <!-- 权益套餐子弹窗 -->
+    <EquitiesPage v-model:show="equitiesPageShow" :recipientInfo="recipientInfo" :EquitiesInfo="EquitiesInfo"
+      @save="saveEquitiesPage" />
+
+    <!-- 权益单品子弹窗 -->
+    <EquitiesItem v-model:show="equitiesItemShow" :recipientInfo="recipientInfo" :EquitiesInfo="EquitiesInfo"
+      @save="handleEquitiesItemSave" />
   </div>
 </template>
 
@@ -142,28 +183,33 @@
 <script lang='ts' setup>
 import { ref, reactive, computed, onBeforeMount, watch } from 'vue'
 import api from '@/api'
-import { ElMessage } from 'element-plus'
+import { ElMessage, DrawerProps } from 'element-plus'
 import Decimal from 'decimal.js'
+import EquitiesItem from './EquitiesItem.vue' // 权益单品模块
+import EquitiesPage from './EquitiesPage.vue' // 权益套餐模块
+
+import { useRouter, useRoute } from 'vue-router'
+const direction = ref<DrawerProps['direction']>('rtl')
 const props = defineProps<{
   show: boolean,
   recipientInfo: Array<any>,//接收人信息
-  availableAmount: number
+  EquitiesInfo: any,//权益信息参数
 }>();
-console.log(props.availableAmount)
-// 使用本地变量管理对话框显示状态
-const dialogVisible = ref(false);
-// 监听props.show变化,同步到本地变量
-watch(() => props.show, (newVal) => {
-  dialogVisible.value = newVal;
-}, { immediate: true });
+console.log(props.EquitiesInfo)
+const emits = defineEmits(['update:show', 'cancel', 'save']);
+
+// 子弹窗状态
+const equitiesItemShow = ref(false);
+const equitiesPageShow = ref(false);
 watch(() => props.recipientInfo, (newVal) => {
   recipientOptions.value = newVal;
 });
+watch(() => props.EquitiesInfo?.insFeeOrders, (newVal) => {
+  insFeeOrders.value = newVal || {};
+}, { deep: true });
 // 组件挂载时获取地区数据
 onBeforeMount(async () => {
   await queryTreeQuery();
-  await getBenefitPackageList();
-  await getPrivilegeItem();
   provinceoptions.value = ['110000', '110100', '110101']
 
 });
@@ -181,25 +227,29 @@ const queryInfo = ref({
   pageNo: 1,
   pageSize: 20,
 });
+const adjustDiscountAmountShow = ref(false)
+const availableAmount = ref('')//可用金额
+const insFeeOrders = ref(props.EquitiesInfo.insFeeOrders || {})
 const benefitPackageList = ref(); //权益套餐列表
 const privilegeItem = ref(); //权益单品列表
 const insOrderRightsPackageList = ref([]); //权益套餐选中列表
 const insOrderRightsList = ref([]); //权益单品选中列表
-const benefitPackageIndex = ref(0); //选中的权益套餐索引
+const benefitPackageIndex = ref(null); //选中的权益套餐索引
 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) => {
+  const packageTotal = insOrderRightsPackageList.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) => {
+  const sum = new Decimal(packageTotal);
+  return sum.toString(); // 返回字符串
+});
+const totalPriceCount1 = computed(() => {
+  const itemTotal = insOrderRightsList.value?.reduce((sum: Decimal, item: any) => {
     if (item.rightsCount > 0) {
       const itemTotal = new Decimal(item.contractRate || 0).times(new Decimal(item.rightsCount || 0));
       return sum.plus(itemTotal);
@@ -208,40 +258,27 @@ const totalPriceCount = computed(() => {
   }, new Decimal(0)) || new Decimal(0);
 
   // 合并所有总价
-  const sum = new Decimal(packageTotal).plus(itemTotal);
+  const sum = new Decimal(itemTotal);
   return sum.toString(); // 返回字符串
 });
 //合并所有已选权益套餐和权益单品
 const selectedRights = computed(() => {
-  const selectedPackages = benefitPackageList.value?.filter((item: any) => item.rightsCount > 0) || []
-  insOrderRightsPackageList.value = selectedPackages
+  const selectedPackages = insOrderRightsPackageList.value?.filter((item: any) => item.rightsCount > 0) || []
   // 收集选择的权益单品
-  const selectedItems = privilegeItem.value?.filter((item: any) => item.rightsCount > 0) || []
-  insOrderRightsList.value = selectedItems
+  const selectedItems = insOrderRightsList.value?.filter((item: any) => item.rightsCount > 0) || []
   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 removeSelectedRight = (index: any) => {
+  insOrderRightsPackageList.value.splice(index, 1);
 }
 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 || [];
+  if (name === 'insOrderRightsPackageList') {
+    targetArray = insOrderRightsPackageList.value || [];
+  } else if (name === 'insOrderRightsList') {
+    targetArray = insOrderRightsList.value || [];
   }
   // 获取当前项
   const item = targetArray[index];
@@ -249,24 +286,29 @@ const onRightsCountChange = (e: any, index: any, name: any, field: string) => {
     console.error('无法找到对应数据,数组:', name, '索引:', index)
     return
   }
+  if (e == 0) {
+    targetArray.splice(index, 1);
+  }
   // 获取当前数量和新数量
   const currentCount = item.rightsCount || 0;
   const newCount = e;
   // 计算价格
   const price = parseFloat(item[field] || 0);
+  console.log(price)
   // 计算当前总价
-  const currentTotalPrice = parseFloat(totalPriceCount.value || 0);
+  const currentTotalPrice = parseFloat(name === 'insOrderRightsPackageList' ? totalPriceCount.value : totalPriceCount1.value);
   // 计算数量变化和价格变化
   const countChange = newCount - currentCount;
   const priceChange = countChange * price;
   // 计算新总价
   const newTotalPrice = currentTotalPrice + priceChange;
-  console.log(countChange)
   // 如果是增加数量,检查是否超过可用金额
-  if (countChange > 0 && newTotalPrice > props.availableAmount) {
+  console.log(newTotalPrice)
+  console.log(insFeeOrders.value.availableAmount)
+  if (countChange > 0 && newTotalPrice > parseFloat(insFeeOrders.value.availableAmount)) {
     ElMessage({
       type: 'success',
-      message: `权益总价不能超过可用金额${props.availableAmount}元`,
+      message: `权益总价不能超过可用金额${insFeeOrders.value.availableAmount}元`,
       plain: true,
     })
   } else {
@@ -277,6 +319,7 @@ const onRightsCountChange = (e: any, index: any, name: any, field: string) => {
 // 表单数据
 const form = reactive({
   recipient: '',
+  otherRecipient: '',//其它接收人名称
   region: []
 });
 const areaProps = {
@@ -297,24 +340,7 @@ const tabslist = ref([
 ]);
 // 地区选择器改变时触发
 // 获取权益套餐列表
-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;
@@ -350,18 +376,79 @@ const provinceChange = (value: any) => {
   } else {
   }
 }
-// 切换tab
-const changeTab = (index: number) => {
-  changeTabIndex.value = index;
+const PackageBenefits = () => {
+  if (insOrderRightsList.value.length > 0) {
+    return ElMessage({
+      type: 'warning',
+      message: '套餐和单品只能选择其中1种',
+      plain: true,
+    })
+  }
+  equitiesPageShow.value = true;
+}
+const RightsBenefits = () => {
+  if (insOrderRightsPackageList.value.length > 0) {
+    return ElMessage({
+      type: 'warning',
+      message: '套餐和单品只能选择其中1种',
+      plain: true,
+    })
+  }
+  equitiesItemShow.value = true;
 }
-
 const cancel = () => {
-  // 重置表单
   form.recipient = '';
   form.region = [];
-  emits("cancel")
+  emits('update:show', false);
 }
 
+// 权益单品保存回调
+const handleEquitiesItemSave = (selectedItems: any[]) => {
+  insOrderRightsList.value = selectedItems;
+}
+const saveEquitiesPage = (selectedItems: any[]) => {
+  insOrderRightsPackageList.value = selectedItems;
+}
+const adjustDiscountAmount = () => {
+  adjustDiscountAmountShow.value = true;
+}
+const adjustDiscountAmountconfirm = () => {
+  if (!availableAmount.value) {
+    ElMessage({
+      type: 'warning',
+      message: '请输入可用金额',
+      plain: true,
+    })
+    return
+  }
+  if (parseFloat(availableAmount.value) > parseFloat(insFeeOrders.value.availableAmount || 0)) {
+    ElMessage({
+      type: 'warning',
+      message: `可用金额不能大于优惠金额`,
+      plain: true,
+    })
+    return
+  }
+  api.additionalApi.updateAvailableAmount({
+    orderNo: props.EquitiesInfo.ordersNo,
+    availableAmount: availableAmount.value,
+  }).then((res: any) => {
+    if (res.code == '200') {
+      ElMessage({
+        type: 'success',
+        message: res.msg,
+        plain: true,
+      })
+      api.insurancePolicyApi.getOrderDetail(props.EquitiesInfo.ordersNo).then((res: any) => {
+        if (res.code == '200') {
+          insFeeOrders.value = res.data?.insFeeOrders || {}
+        }
+      })
+      adjustDiscountAmountShow.value = false
+    } else {
+    }
+  });
+}
 const save = () => {
   if (!form.recipient) {
     ElMessage({
@@ -374,130 +461,184 @@ const save = () => {
   let info = props.recipientInfo.find((item: any) => item.title == form.recipient);
   let insOrderRightsInfoDto = {
     length: selectedRights.value.length,
-    totalPriceCount: totalPriceCount.value,
-    recipient: info.title,
+    totalPriceCount: insOrderRightsPackageList.value.length > 0 ? totalPriceCount.value : totalPriceCount1.value,
+    recipient: info ? info.title : '',
     insOrderRightsPackageList: insOrderRightsPackageList.value,
     insOrderRightsList: insOrderRightsList.value,
     rightsGrantReceiverDTO: {
-      receiverType: info.policyPersonType,
-      receiverName: info.name,
-      receiverMobile: info.mobile
+      receiverType: info ? info.policyPersonType : '',
+      receiverName: info ? info.name : '',
+      receiverMobile: info ? info.mobile : ''
     }
   }
   // 发送表单数据
+  console.log(insOrderRightsInfoDto)
   emits("save", insOrderRightsInfoDto)
 }
+const iframeUrl = ref('');//权益单品详情
+const clickedRightsId = ref<string | number | null>(null); // 记录点击的权益ID
+const benefitDetail = (item: any) => {
+  clickedRightsId.value = item.id; // 设置点击状态
+  api.additionalApi.rightsProduct({
+    rightsId: item.id,
+  }).then((res: any) => {
+    if (res.code == '200') {
+      iframeUrl.value = `https://life.baoxianzhanggui.com/custh5/#/packageF/pages/home/details-channel?productId=${res.data[0].productId}`
+    } else {
+    }
+  });
+  console.log(item)
+}
 </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-btn {
+  >.left {
+    width: 80px;
+    font-size: 14px;
+    color: #333;
+    margin-top: 6px;
   }
-}
-
-.tab-content {
-  width: 70%;
-  flex: 1;
-
-  .benefit {
-    width: 35%;
 
-    .benefitList {
-      height: 300px;
-      overflow-y: auto;
-      width: 100%;
+  >.content {
+    margin-left: 16px;
+    flex: 1;
 
+    .tabs {
       .item {
-        margin-bottom: 5px;
-        padding: 6px 8px;
-        box-sizing: border-box;
         cursor: pointer;
+        padding: 5px 12px;
+        box-sizing: border-box;
+        border-radius: 2px 2px 2px 2px;
+        border: 1px solid #E5E5E5;
         font-size: 14px;
         color: #333;
       }
 
       .item.active {
-        background: #F6FBFF;
-        border-radius: 4px 4px 4px 4px;
-        color: #0083FF;
+        background: #0083FF;
+        border: 1px solid #0083FF;
+        color: #fff;
+
       }
     }
   }
+}
 
-  .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;
-      }
+.orderIssueFee {
+  background: #F5F5F5;
+  border-radius: 4px 4px 4px 4px;
+  margin-top: 20px;
+  padding: 12px 16px;
+  box-sizing: border-box;
 
-      .item:first-child {
-        flex: 1;
-      }
+  .expenseInfo {
+    >div span:first-child {
+      font-size: 12px;
+      color: #666;
+    }
 
-      .item:last-child {}
+    >div span:last-child {
+      font-size: 14px;
+      color: #333;
+      margin-left: 4px;
     }
   }
-}
 
-.displaySelected {
-  width: 30%;
-  margin-left: 30px;
+  .commentText {
+    margin-top: 10px;
 
-  .header-sum {
-    margin-bottom: 10px;
-    font-size: 14px;
-    color: #333;
+    span {
+      font-size: 12px;
+      color: #333;
+      margin-left: 2px;
+    }
   }
+}
 
-  .selectedList {
-    height: 300px;
-    overflow-y: auto;
+.PackageselectedList {
+  .view-card {
+    width: 250px;
 
-    .item {
+    .view-item {
+      cursor: pointer;
       background: #F7F7F7;
-      border-radius: 4px 4px 4px 4px;
       padding: 10px;
       box-sizing: border-box;
-      margin-bottom: 10px;
+      border-radius: 4px 4px 4px 4px;
+    }
+
+    .view-item:hover {
+      background: #dfdfdf;
     }
+
+  }
+
+  .view-card .active {
+    background: #dfdfdf;
+    color: #fff;
   }
 }
+
+// 自定义抽屉样式
+:deep(.el-drawer__header) {
+  padding: 18px 24px;
+  box-sizing: border-box;
+  border-bottom: 1px solid #E5E5E5;
+  font-size: 20px;
+  color: #333;
+  font-weight: bold;
+  margin-bottom: 0;
+}
+
+:deep(.el-drawer) {
+  border-radius: 8px 0 0 8px;
+}
+
+:deep(.el-drawer__body) {
+  padding: 24px;
+  box-sizing: border-box;
+}
+
+:deep(.el-drawer__footer) {
+  box-shadow: 0px -1px 1px 0px rgba(0, 0, 0, 0.05);
+}
+
+:deep(.el-popover) {
+  width: auto !important;
+}
+
+.iframe-container {
+  width: 300px;
+  height: 600px;
+  /* 固定高度 */
+}
+
+.external-iframe {
+  width: 100%;
+  height: 100%;
+  border: none;
+}
+
+// 点击权益名称变色效果
+.clicked {
+  color: #409EFF;
+}
+
+// 权益金额调整弹窗
+.description {
+  width: 100%;
+  background: #FFFAEF;
+  border-radius: 6px 6px 6px 6px;
+  border: 1px solid #FAA21E;
+  font-size: 14px;
+  color: #333;
+  padding: 10px 16px;
+  box-sizing: border-box;
+}
 </style>

+ 400 - 0
src/views/insurancePolicy/modules/EquitiesItem.vue

@@ -0,0 +1,400 @@
+<!-- 模板区域 -->
+<template>
+  <div>
+    <el-drawer :model-value="show" @update:model-value="$emit('update:show', $event)" title="权益选择"
+      :direction="direction" size="900px">
+      <el-form :model="form" label-width="120px" label-position="left">
+        <el-row :gutter="20">
+          <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>
+      <!-- 出单费用信息 -->
+      <div class="orderIssueFee">
+        <div class="expenseInfo flex a-c j-s">
+          <div>
+            <span>出单费用</span>
+            <span>¥{{ props.EquitiesInfo.insFeeOrders.totalExportPremium }}</span>
+          </div>
+          <div>
+            <span>可用金额</span>
+            <span>¥{{ props.EquitiesInfo.insFeeOrders.availableAmount }}</span>
+          </div>
+          <div>
+            <span>已使用金额</span>
+            <span>¥{{ props.EquitiesInfo.insFeeOrders.usedAmount }}</span>
+          </div>
+          <div>
+            <span>剩余金额</span>
+            <span style="color: #FF8C21;"> ¥{{ props.EquitiesInfo.insFeeOrders.remainingAmount }}</span>
+          </div>
+          <div>
+            <span>已选权益价值</span>
+            <span style="color: #FF8C21;"> ¥{{ totalPriceCount }}</span>
+          </div>
+        </div>
+        <!-- 备注信息 -->
+        <div class="commentText flex a-c ">
+          <el-icon color="#0083FF">
+            <InfoFilled />
+          </el-icon>
+          <span>出单后,计算出可使用金额,录入本次使用金额,可使用该金额为用户购买权益,剩余金额会返回到业务员的钱包,业务员可提现。</span>
+        </div>
+      </div>
+      <div class="mt-[24px]">
+        <el-form label-width="60px">
+          <el-row :gutter="20">
+            <el-col :span="6" v-for="(item, index) in filterConditions" :key="index">
+              <el-form-item :label="item.name">
+                <el-select v-model="filterConditions[index].list" placeholder="请选择" multiple collapse-tags
+                  collapse-tags-tooltip>
+                  <el-option v-for="childrenitem in item.children" :key="childrenitem.id" :label="childrenitem.name"
+                    :value="childrenitem.id" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+      </div>
+      <div class="flex mt-4  tab-btn">
+        <div class="content flex  f-c ">
+          <div class="RightselectedList">
+            <el-table class="details" :data="privilegeItem" max-height="300px" style="flex: 1;" border>
+              <el-table-column prop="rightsName" label="权益名称" align="center" />
+              <el-table-column prop="contractRate" label="价格" align="center"></el-table-column>
+              <el-table-column prop="marketPrice" label="价值" align="center"></el-table-column>
+              <el-table-column prop="shareableStoreNum" label="适用门店" align="center">
+                <template #default="scope">
+                  {{ scope.row.shareableStoreNum }}家门店可用
+                </template>
+              </el-table-column>
+              <el-table-column prop="number" label="数量" align="center">
+                <template #default="scope">
+                  <el-input-number size="small" :model-value="scope.row.rightsCount" style="width: 80px;"
+                    @update:model-value="val => onRightsCountChange(val, scope.$index, 'privilegeItem', 'contractRate')"
+                    :min="0" />
+                </template>
+              </el-table-column>
+              <el-table-column prop="total" label="总价" align="center">
+                <template #default="scope">
+                  {{ new Decimal(scope.row.contractRate || 0).times(scope.row.rightsCount || 0).toFixed(2) }}
+                </template>
+              </el-table-column>
+
+            </el-table>
+          </div>
+        </div>
+      </div>
+      <template #footer>
+        <div class="dialog-footer flex a-c j-c ">
+          <el-button class="border-[#0083FF] color-[#0083FF]" plain @click="cancel">取消</el-button>
+          <el-button type="primary" @click="save">
+            确定
+          </el-button>
+        </div>
+      </template>
+    </el-drawer>
+  </div>
+</template>
+
+<!-- 行为区域 -->
+<script lang='ts' setup>
+import { ref, reactive, computed, onBeforeMount, watch } from 'vue'
+import api from '@/api'
+import { ElMessage, DrawerProps } from 'element-plus'
+import Decimal from 'decimal.js'
+import { useRouter, useRoute } from 'vue-router'
+const route = useRoute()
+const router = useRouter()
+const direction = ref<DrawerProps['direction']>('rtl')
+const props = defineProps<{
+  show: boolean,
+  recipientInfo: Array<any>,//接收人信息
+  EquitiesInfo: any,//权益信息参数
+}>();
+console.log(props.EquitiesInfo)
+const emits = defineEmits(['update:show', 'cancel', 'save']);
+watch(() => props.recipientInfo, (newVal) => {
+  recipientOptions.value = newVal;
+});
+// 组件挂载时获取地区数据
+onBeforeMount(async () => {
+  await queryTreeQuery();
+  await getRightsCategory();
+  await getPrivilegeItem();
+  provinceoptions.value = ['110000', '110100', '110101']
+
+});
+
+const queryInfo = ref({
+  countryAll: '', //山西省太原太原市  //省市区
+  minPrice: 0,
+  maxPrice: 1000,
+  sortType: 0, //排序  0 默认 1低价  2高价
+  pageNo: 1,
+  pageSize: 20,
+});
+const benefitPackageList = ref(); //权益套餐列表
+const privilegeItem = ref(); //权益单品列表
+const totalPriceCount = computed(() => {
+  // 计算权益单品的总价
+  const itemTotal = privilegeItem.value?.reduce((sum: Decimal, item: any) => {
+    if (item.rightsCount > 0) {
+      const itemTotal = new Decimal(item.contractRate || 0).times(new Decimal(item.rightsCount || 0));
+      return sum.plus(itemTotal);
+    }
+    return sum;
+  }, new Decimal(0)) || new Decimal(0);
+
+  // 合并所有总价
+  const sum = new Decimal(itemTotal);
+  return sum.toString(); // 返回字符串
+});
+
+
+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.EquitiesInfo.insFeeOrders.availableAmount) {
+    ElMessage({
+      type: 'success',
+      message: `权益总价不能超过可用金额${props.EquitiesInfo.insFeeOrders.availableAmount}元`,
+      plain: true,
+    })
+  } else {
+    // 无论是减少数量还是增加数量且未超过限制,都允许更新
+    item.rightsCount = newCount;
+  }
+}
+// 表单数据
+const form = reactive({
+  recipient: '',
+  otherRecipient: '',//其它接收人名称
+  region: []
+});
+const areaProps = {
+  expandTrigger: 'hover' as const,
+  value: 'areaCode',
+  label: 'areaCname',
+  children: 'child'
+}
+// 接收人选项
+const recipientOptions = ref()
+// 获取权益单品列表
+const getPrivilegeItem = async () => {
+  try {
+    const response = await api.additionalApi.rightsList(queryInfo.value);
+    privilegeItem.value = response.data.records || [];
+  } catch (error) {
+    console.error('获取权益单品列表失败:', error);
+  }
+}
+// 获取权益分类
+const filterConditions = ref([]);
+const getRightsCategory = async () => {
+  try {
+    const response = await api.additionalApi.rightsCategory();
+    filterConditions.value = response.data || [];
+    console.log(filterConditions.value)
+    filterConditions.value.forEach((item: any) => {
+      item.list = [];
+    })
+    console.log(filterConditions.value)
+  } 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 {
+  }
+}
+const cancel = () => {
+  // 重置表单
+  form.recipient = '';
+  form.region = [];
+  emits('update:show', false);
+}
+
+const save = () => {
+  console.log(privilegeItem.value)
+  const selectedItems = privilegeItem.value?.filter((item: any) => item.rightsCount > 0) || []
+  // 发送表单数据
+  emits("save", selectedItems)
+  emits('update:show', false);
+}
+</script>
+<!-- 样式区域 -->
+<style lang='scss' scoped>
+.tab-btn {
+
+  >.content {
+    flex: 1;
+
+    .tabs {
+      .item {
+        cursor: pointer;
+        padding: 5px 12px;
+        box-sizing: border-box;
+        border-radius: 2px 2px 2px 2px;
+        border: 1px solid #E5E5E5;
+        font-size: 14px;
+        color: #333;
+      }
+
+      .item.active {
+        background: #0083FF;
+        border: 1px solid #0083FF;
+        color: #fff;
+
+      }
+    }
+  }
+}
+
+
+
+
+
+
+.orderIssueFee {
+  background: #F5F5F5;
+  border-radius: 4px 4px 4px 4px;
+  margin-top: 20px;
+  padding: 12px 16px;
+  box-sizing: border-box;
+
+  .expenseInfo {
+    >div span:first-child {
+      font-size: 12px;
+      color: #666;
+    }
+
+    >div span:last-child {
+      font-size: 14px;
+      color: #333;
+      margin-left: 4px;
+    }
+  }
+
+  .commentText {
+    margin-top: 10px;
+
+    span {
+      font-size: 12px;
+      color: #333;
+      margin-left: 2px;
+    }
+  }
+}
+
+.PackageselectedList {
+  .view-card {
+    width: 250px;
+
+    .view-item {
+      cursor: pointer;
+      background: #F7F7F7;
+      padding: 10px;
+      box-sizing: border-box;
+      border-radius: 4px 4px 4px 4px;
+    }
+
+    .view-item:hover {
+      background: #dfdfdf;
+    }
+
+  }
+
+  .view-card .active {
+    background: #dfdfdf;
+    color: #fff;
+  }
+}
+
+// 自定义抽屉样式
+:deep(.el-drawer__header) {
+  padding: 18px 24px;
+  box-sizing: border-box;
+  border-bottom: 1px solid #E5E5E5;
+  font-size: 20px;
+  color: #333;
+  font-weight: bold;
+  margin-bottom: 0;
+}
+
+:deep(.el-drawer) {
+  border-radius: 8px 0 0 8px;
+}
+
+:deep(.el-drawer__body) {
+  padding: 24px;
+  box-sizing: border-box;
+}
+
+:deep(.el-drawer__footer) {
+  box-shadow: 0px -1px 1px 0px rgba(0, 0, 0, 0.05);
+}
+
+.iframe-container {
+  width: 100%;
+  height: 600px;
+  /* 固定高度 */
+  border: 1px solid #ddd;
+}
+
+.external-iframe {
+  width: 100%;
+  height: 100%;
+  border: none;
+}
+</style>

+ 513 - 0
src/views/insurancePolicy/modules/EquitiesPage.vue

@@ -0,0 +1,513 @@
+<!-- 模板区域 -->
+<template>
+  <div>
+    <el-drawer :model-value="show" @update:model-value="$emit('update:show', $event)" title="权益选择" :direction="direction" size="900px">
+      <el-form :model="form" label-width="120px" label-position="left">
+        <el-row :gutter="20">
+          <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>
+      <!-- 出单费用信息 -->
+      <div class="orderIssueFee">
+        <div class="expenseInfo flex a-c j-s">
+          <div>
+            <span>出单费用</span>
+            <span>¥{{ props.EquitiesInfo.insFeeOrders.totalExportPremium }}</span>
+          </div>
+          <div>
+            <span>可用金额</span>
+            <span>¥{{ props.EquitiesInfo.insFeeOrders.availableAmount }}</span>
+          </div>
+          <div>
+            <span>已使用金额</span>
+            <span>¥{{ props.EquitiesInfo.insFeeOrders.usedAmount }}</span>
+          </div>
+          <div>
+            <span>剩余金额</span>
+            <span style="color: #FF8C21;"> ¥{{ props.EquitiesInfo.insFeeOrders.remainingAmount }}</span>
+          </div>
+          <div>
+            <span>已选权益价值</span>
+            <span style="color: #FF8C21;"> ¥{{ totalPriceCount }}</span>
+          </div>
+        </div>
+        <!-- 备注信息 -->
+        <div class="commentText flex a-c ">
+          <el-icon color="#0083FF">
+            <InfoFilled />
+          </el-icon>
+          <span>出单后,计算出可使用金额,录入本次使用金额,可使用该金额为用户购买权益,剩余金额会返回到业务员的钱包,业务员可提现。</span>
+        </div>
+      </div>
+      <div class="flex mt-4  tab-btn">
+        <div class="content flex  f-c ">
+          <div class="PackageselectedList mt-[16px] flex ">
+            <div class="view-card mr-[20px]">
+              <div class="view-item mb-[10px] " v-for="(item, index) in benefitPackageList" :key="item.id"
+                @click="rightsDetails(item, index)">
+                <div class="flex f-c ">
+                  <div class="flex a-c j-s">
+                    <span class="equityPackageName text-[14px] text-[#333]">{{ item.equityPackageName }}</span>
+                    <el-input-number size="small" :model-value="item.rightsCount" style="width: 80px;"
+                    @update:model-value="val => onRightsCountChange(val, index, 'benefitPackageList', 'packagePrice')"
+                    :min="0" />
+
+                  </div>
+                  <div class="mt-5 flex a-c j-s">
+                    <span v-if="item.totalNumber" class="text-[12px] text-[#666]">数量:{{ item.totalNumber }}张</span>
+                    <span class="text-[12px] text-[#666]">价格:{{ item.packagePrice }}元</span>
+                    <el-icon @click="removeSelectedRight(item)" color="#666">
+                      <Delete />
+                    </el-icon>
+                  </div>
+                </div>
+              </div>
+            </div>
+            <el-table class="details" :data="selectedPackageDetail.rightsDetailsList" max-height="300px"
+              style="flex: 1;" border>
+              <el-table-column prop="rightsName" label="权益名称" width="180" align="center" />
+              <el-table-column prop="number" label="数量" align="center" />
+              <el-table-column prop="contractRate" label="价格" align="center"></el-table-column>
+              <el-table-column prop="marketPrice" label="价值" align="center">
+              </el-table-column>
+              <el-table-column prop="shareableStoreNum" label="适用门店" align="center"></el-table-column>
+            </el-table>
+          </div>
+        </div>
+        <!-- <div class="tab-content">
+          <template >
+            <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.id == selectedPackageDetail.id }" :key="item.id"
+                    @click="rightsDetails(item, index)">{{
+                      item.equityPackageName }}</span>
+                </div>
+              </div>
+              <div class="benefitDetails" v-if="selectedPackageDetail.id">
+                <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.contractRate }}元</div>
+    </div>
+  </div>
+</div>
+</div>
+</div>
+</template>
+<template>
+            <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="contractRate" 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', 'contractRate')"
+                    :min="0" />
+                </template>
+</el-table-column>
+<el-table-column prop="totalsum" label="总价" align="center">
+  <template #default="scope">
+                  <span>{{ scope.row.contractRate * 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.contractRate }}元</span>
+          <el-icon @click="removeSelectedRight(item)">
+            <Delete />
+          </el-icon>
+        </div>
+      </div>
+    </div>
+  </div>
+</div> -->
+      </div>
+      <template #footer>
+        <div class="dialog-footer flex a-c j-c ">
+          <el-button class="border-[#0083FF] color-[#0083FF]" plain @click="cancel">取消</el-button>
+          <el-button type="primary" @click="save">
+            确定
+          </el-button>
+        </div>
+      </template>
+    </el-drawer>
+  </div>
+</template>
+
+<!-- 行为区域 -->
+<script lang='ts' setup>
+import { ref, reactive, computed, onBeforeMount, watch } from 'vue'
+import api from '@/api'
+import { ElMessage, DrawerProps } from 'element-plus'
+import Decimal from 'decimal.js'
+import { useRouter, useRoute } from 'vue-router'
+const direction = ref<DrawerProps['direction']>('rtl')
+const props = defineProps<{
+  show: boolean,
+  recipientInfo: Array<any>,//接收人信息
+  EquitiesInfo: any,//权益信息参数
+}>();
+console.log(11111, props.EquitiesInfo)
+
+const emits = defineEmits(['update:show', 'cancel', 'save']);
+watch(() => props.recipientInfo, (newVal) => {
+  recipientOptions.value = newVal;
+});
+// 组件挂载时获取地区数据
+onBeforeMount(async () => {
+  await queryTreeQuery();
+  await getBenefitPackageList();
+  provinceoptions.value = ['110000', '110100', '110101']
+
+});
+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 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 sum = new Decimal(packageTotal);
+  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 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.EquitiesInfo.insFeeOrders.availableAmount) {
+    ElMessage({
+      type: 'success',
+      message: `权益总价不能超过可用金额${props.EquitiesInfo.insFeeOrders.availableAmount}元`,
+      plain: true,
+    })
+  } else {
+    // 无论是减少数量还是增加数量且未超过限制,都允许更新
+    item.rightsCount = newCount;
+  }
+}
+// 表单数据
+const form = reactive({
+  recipient: '',
+  otherRecipient: '',//其它接收人名称
+  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);
+    if(response.code == '200'){
+      benefitPackageList.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.id);
+    console.log(response)
+    if(response.code == '200'){
+      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 {
+  }
+}
+const cancel = () => {
+  // 重置表单
+  form.recipient = '';
+  form.region = [];
+  emits('update:show', false);
+}
+
+const save = () => {
+  const packageItems = benefitPackageList.value?.filter((item: any) => item.rightsCount > 0) || []
+  // 发送表单数据
+  emits("save", packageItems)
+  emits('update:show', false);
+}
+</script>
+<!-- 样式区域 -->
+<style lang='scss' scoped>
+.tab-btn {
+  >.left {
+    width: 80px;
+    font-size: 14px;
+    color: #333;
+    margin-top: 6px;
+  }
+
+  >.content {
+    margin-left: 16px;
+    flex: 1;
+
+    .tabs {
+      .item {
+        cursor: pointer;
+        padding: 5px 12px;
+        box-sizing: border-box;
+        border-radius: 2px 2px 2px 2px;
+        border: 1px solid #E5E5E5;
+        font-size: 14px;
+        color: #333;
+      }
+
+      .item.active {
+        background: #0083FF;
+        border: 1px solid #0083FF;
+        color: #fff;
+
+      }
+    }
+  }
+}
+
+
+
+
+
+
+.orderIssueFee {
+  background: #F5F5F5;
+  border-radius: 4px 4px 4px 4px;
+  margin-top: 20px;
+  padding: 12px 16px;
+  box-sizing: border-box;
+
+  .expenseInfo {
+    >div span:first-child {
+      font-size: 12px;
+      color: #666;
+    }
+
+    >div span:last-child {
+      font-size: 14px;
+      color: #333;
+      margin-left: 4px;
+    }
+  }
+
+  .commentText {
+    margin-top: 10px;
+
+    span {
+      font-size: 12px;
+      color: #333;
+      margin-left: 2px;
+    }
+  }
+}
+
+.PackageselectedList {
+  .view-card {
+    width: 250px;
+
+    .view-item {
+      cursor: pointer;
+      background: #F7F7F7;
+      padding: 10px;
+      box-sizing: border-box;
+      border-radius: 4px 4px 4px 4px;
+    }
+
+    .view-item:hover {
+      background: #dfdfdf;
+    }
+
+  }
+
+  .view-card .active {
+    background: #dfdfdf;
+    color: #fff;
+  }
+}
+
+// 自定义抽屉样式
+:deep(.el-drawer__header) {
+  padding: 18px 24px;
+  box-sizing: border-box;
+  border-bottom: 1px solid #E5E5E5;
+  font-size: 20px;
+  color: #333;
+  font-weight: bold;
+  margin-bottom: 0;
+}
+
+:deep(.el-drawer) {
+  border-radius: 8px 0 0 8px;
+}
+
+:deep(.el-drawer__body) {
+  padding: 24px;
+  box-sizing: border-box;
+}
+
+:deep(.el-drawer__footer) {
+  box-shadow: 0px -1px 1px 0px rgba(0, 0, 0, 0.05);
+}
+
+.iframe-container {
+  width: 100%;
+  height: 600px;
+  /* 固定高度 */
+  border: 1px solid #ddd;
+}
+
+.external-iframe {
+  width: 100%;
+  height: 100%;
+  border: none;
+}
+</style>

+ 32 - 18
src/views/insurancePolicy/modules/underwriting.vue

@@ -102,7 +102,7 @@
           <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>{{ new Decimal(scope.row.packagePrice || scope.row.contractRate).times(scope.row.rightsCount).toFixed(2) }}
               </div>
             </template>
           </el-table-column>
@@ -116,7 +116,7 @@
           <div class="money">
             <div class="totalItem">
               <span>可用金额:</span>
-              <span>{{ props.availableAmount }}</span>
+              <span>{{ EquitiesInfo.value?.insFeeOrders?.availableAmount || 0 }}</span>
             </div>
             <div class="totalItem">
               <span>已使用:</span>
@@ -124,7 +124,7 @@
             </div>
             <div class="totalItem">
               <span>剩余金额:</span>
-              <span style="color: #FF8C21">{{ props.availableAmount - parseFloat(totalPriceCount) }}</span>
+              <span style="color: #FF8C21">{{ EquitiesInfo.value?.insFeeOrders?.remainingAmount || 0 }}</span>
             </div>
           </div>
         </div>
@@ -135,8 +135,8 @@
         @click="handleSubmit(false)">取消</el-button>
       <el-button type="primary" @click="handleSubmit(true)" :loading="loading">提交核保</el-button>
     </div>
-    <Equities v-if="equitiesShow" :show="equitiesShow" :recipientInfo="recipientInfo"
-      :availableAmount="props.availableAmount" @cancel="equitiesShow = false" @save="handleEquitiesSave"></Equities>
+    <Equities v-model:show="equitiesShow" :recipientInfo="recipientInfo" :EquitiesInfo="EquitiesInfo"
+      @save="handleEquitiesSave"></Equities>
   </div>
 </template>
 
@@ -148,21 +148,21 @@ import Decimal from 'decimal.js'
 import Equities from './Equities.vue' // 驾意险详情模块
 const props = defineProps<{
   insOrderRightsInfoDto: any,//权益信息
-  availableAmount: number,//可用金额
   recipientInfo: Array<any>,//接收人信息
+
 }>();
-const insOrderRightsInfoDto = ref()//权益信息
+const insOrderRightsInfoDto = ref(props.insOrderRightsInfoDto)//权益信息
 const equitiesData = ref()//权益数据
 const recipient = ref('')//接收人
 const recipientInfo = ref(props.recipientInfo)//接收人信息
-const useMoney = ref(0)//可用金额
-const usedMoney = ref(0)//已使用金额
-const lastMoney = ref(0)//剩余金额
 const ImageTypeSelect = ref()
 const loading = ref(false)//提交loading
-const emit = defineEmits(['close','initDetail'])
+const emit = defineEmits(['close', 'initDetail'])
 let images = ref([])
 watch(() => props.insOrderRightsInfoDto, (newVal) => {
+  if (!newVal) {
+    return
+  }
   console.log('权益信息', newVal)
   recipient.value = newVal?.recipient || ''
   insOrderRightsInfoDto.value = newVal;
@@ -183,7 +183,7 @@ const totalPriceCount = computed(() => {
   // 计算权益单品的总价
   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));
+      const itemTotal = new Decimal(item.contractRate || 0).times(new Decimal(item.rightsCount || 0));
       return sum.plus(itemTotal);
     }
     return sum;
@@ -364,9 +364,9 @@ const handleSubmit = (bool) => {
             equitiesData: equitiesData.value.length,
             totalPriceCount: totalPriceCount.value
           })
-        }).finally(()=>(loading.value = false,emit('initDetail')))
+        }).finally(() => (loading.value = false, emit('initDetail')))
       }
-    }).catch(()=>loading.value = false)
+    }).catch(() => loading.value = false)
   } else {
     emit('close', false)
   }
@@ -375,7 +375,7 @@ const handleSubmit = (bool) => {
 //数据交互
 let ordersNo = ref('')
 const uploadData = ref({})
-const initEdit = (data: any) => {
+const initEdit = async (data: any) => {
   uploadData.value = data
   ordersNo.value = data.order.ordersNo
   images.value = data.list.map(item => {
@@ -385,16 +385,30 @@ const initEdit = (data: any) => {
     }
   })
   if (ordersNo.value) {
-    queryClauseData()
+    await queryClauseData()
+    await initEquities()
   }
 }
+const EquitiesInfo = ref<any>({
+  insFeeOrders: {},//费用信息
+  insOrderRightsInfoVo: {},//权益信息
+  ordersNo: "",//订单号
+})//相关参数
+const initEquities = () => {
+  api.insurancePolicyApi.getOrderDetail(ordersNo.value).then((res: any) => {
+    if (res.code == '200') {
+      EquitiesInfo.value.insFeeOrders = res.data?.insFeeOrders || {}
+      EquitiesInfo.value.insOrderRightsInfoVo = res.data?.insOrderRightsInfoVo || {}
+      EquitiesInfo.value.ordersNo = res.data?.ordersNo || ""
 
+    }
+  })
+}
 let changeIndex = ref(1)
 
 // 选择权益
 let equitiesShow = ref(false)
 const handleOpenEquities = () => {
-  console.log(1)
   equitiesShow.value = true
 }
 const handleEquitiesSave = (data: any) => {
@@ -586,4 +600,4 @@ defineExpose({
     margin-right: 10px;
   }
 }
-</style>
+</style>

+ 3 - 1
src/views/payCredit/myTask.vue

@@ -456,7 +456,9 @@ const handleVerifyAmount = () => {
         type: 'success'
       })
       drawShow.value = false
-      initData(activeName.value)
+      initData('0')
+      initData('1')
+      initData('2')
     }
   })
 }

+ 1 - 1
src/views/platform/platformRecord.vue

@@ -252,7 +252,7 @@ const getSummaries = (param) => {
   const { columns, data } = param
   const sums: (string | VNode)[] = []
   // 指定需要计算的字段列表(可根据需求添加字段名)
-  const specifiedFields = ['taxPoint', 'actualReceivedAmount'] // 替换为您需要的字段名
+  const specifiedFields = ['receivableSupervisePremium', 'actualReceivedAmount','settlementPaymentDifference'] // 替换为您需要的字段名
 
   columns.forEach((column, index) => {
     if (index === 0) {