Browse Source

报价单预览+下载

祁鹏飞 2 months ago
parent
commit
4168ec74f3

+ 1 - 1
src/views/additionalOrder/additional/index.vue

@@ -1599,7 +1599,7 @@
               <el-col :span="6">
                 <el-form-item label="补录费用" prop="" class="p-l-24px">
                   <el-select v-model="additionalForm.isrecordByLeader"  placeholder="请选择"
-                    filterable >
+                    filterable @change="cvalculateFees" >
                     <el-option :value="true" label="代客录单费用-1"></el-option>
                     <el-option :value="false" label="内部协议费用不做-1"></el-option>
                   </el-select>

+ 11 - 0
src/views/insurancePolicy/index.vue

@@ -1250,6 +1250,8 @@
                     @click="handleSubmit(InsurancePolicyRefs, scope.row)">计算保费</el-button>
                   <el-button v-if="scope.row.quoteCode == 200" link type="primary"
                     @click="handleShare(scope.row.quoteResult.ordersNo)">分享</el-button>
+                  <el-button v-if="scope.row.quoteCode == 200" link type="primary"
+                    @click="handleQuotationView(scope.row)">报价单预览</el-button>
                   <el-button
                     v-if="scope.row.quoteCode == 200 && !(scope.row.quoteResult?.quoteStatus == 4 || scope.row.quoteResult?.order?.orderStatus == 4)"
                     link type="primary" :loading="scope.row.loading" @click="handleUnderwriting(scope)">核保</el-button>
@@ -1508,6 +1510,7 @@
       :recipientInfo="[owerFormInfo, policyHolderInfo, insuredPersonInfo]" :availableAmount="availableAmount"
       @cancel="equitiesShow = false" @save="handleEquitiesSave"></Equities>
   </div>
+  <quotation ref="quotationRef" :quotationObj="quotationObj" :insurancePolicyForm="insurancePolicyForm" />
 </template>
 
 <!-- 保险单页面逻辑脚本 -->
@@ -1529,6 +1532,7 @@ 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 quotation from './modules/quotation.vue' // 报价单
 // 导入二维码生成库
 import QRCode from 'qrcode'
 // 导入日期处理库
@@ -3945,6 +3949,13 @@ const ruleFilterCompany = (item: any, obj: any) => {
   })
 }
 
+const quotationRef = ref(null)
+const quotationObj = ref({})
+const handleQuotationView = (obj) => {
+  quotationObj.value = obj
+  quotationRef.value.show(obj)
+}
+
 // 组件挂载后执行初始化操作
 onMounted(() => {
   getAreaList()    // 获取地区列表

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

@@ -372,7 +372,6 @@ const save = () => {
     return
   }
   let info = props.recipientInfo.find((item: any) => item.title == form.recipient);
-  console.log(info)
   let insOrderRightsInfoDto = {
     length: selectedRights.value.length,
     totalPriceCount: totalPriceCount.value,

+ 201 - 0
src/views/insurancePolicy/modules/quotation.vue

@@ -0,0 +1,201 @@
+<template>
+  <div class="quotation">
+
+    <el-dialog v-model="dialogFormVisible" :show-close="false" width="1200" top="40px">
+      <template #header="{ titleId, titleClass }">
+      </template>
+      <div class="max-h-[calc(100vh-140px)] overflow-y-auto">
+        <div class="content font-size-16px color-[#000] line-height-[1] p-24px">
+          <div class="flex justify-center flex-col items-center">
+            <img class="w-[48px] h-[48px]" :src="quotationObj.logo" />
+            <div class="font-size-[24px]">{{ quotationObj.nameSimple }}</div>
+          </div>
+          <div class="m-t-22px">尊敬的客户,您于{{ dayjs(new Date()).format("YYYY年MM月DD日") }}投保方案如下:</div>
+          <div class="b-t-(1px solid #DDDDDD) b-l-(1px solid #DDDDDD) m-t-[14px]">
+            <div class=" flex" v-for="(row, index) in descriptionsData" :key="index">
+              <div v-for="item in row" :key="item.title" class="flex w-full">
+                <div
+                  class="w-[180px] min-h-[38px] p-[8px_0] h-full flex justify-center items-center b-r-(1px solid #DDDDDD) b-b-(1px solid #DDDDDD)">
+                  {{ item.title }}</div>
+                <div v-html="item.value"
+                  class="w-[calc(100%-180px)] h-full min-h-[38px] p-[8px] flex items-center b-r-(1px solid #DDDDDD) b-b-(1px solid #DDDDDD) line-height-[1.2]">
+                </div>
+              </div>
+            </div>
+          </div>
+          <div class="m-t-[14px]">
+            <div class="bg-[#EDEEF0] flex ">
+              <div class="p-[8px] w-[calc(50%-0px)]">险别名称</div>
+              <div class="p-[8px] w-[calc(50%-160px)]">保额(元)</div>
+              <div class="p-[8px] w-[160px] text-center">保费(元)</div>
+            </div>
+            <div class="b-t-(1px solid #DDDDDD) b-l-(1px solid #DDDDDD)">
+              <div class="w-full flex" v-for="(row, index) in tableData" :key="index">
+                <template v-if="!row.total">
+                  <div
+                    class="w-[calc(50%-0px)] h-full min-h-[38px] p-[8px] flex items-center b-r-(1px solid #DDDDDD) b-b-(1px solid #DDDDDD)">
+                    {{ row.title }}</div>
+                  <div
+                    class="w-[calc(50%-160px)] h-full min-h-[38px] p-[8px] flex items-center b-r-(1px solid #DDDDDD) b-b-(1px solid #DDDDDD)">
+                    {{ row.amount }}</div>
+                  <div
+                    class="w-[160px] min-h-[38px] p-[8px_0] h-full flex justify-center items-center b-r-(1px solid #DDDDDD) b-b-(1px solid #DDDDDD)">
+                    {{ row.premium }}</div>
+                </template>
+                <template v-if="row.total">
+                  <div
+                    class="w-[calc(100%-160px)] color-[#FF4545] h-full min-h-[38px] p-[8px] flex items-center justify-center b-r-(1px solid #DDDDDD) b-b-(1px solid #DDDDDD)">
+                    {{ row.title }}</div>
+                  <div
+                    class="w-[160px] color-[#FF4545] min-h-[38px] p-[8px_0] h-full flex justify-center items-center b-r-(1px solid #DDDDDD) b-b-(1px solid #DDDDDD)">
+                    {{ row.premium }}</div>
+                </template>
+              </div>
+            </div>
+          </div>
+          <div class="flex justify-between m-t-14px">
+            <div class="w-[calc(100%-200px)]">注意:以上保费为试算保费,仅供参考,右下角扫码查看权益订单,并将您的要求通知我们,我们会尽快与您联系,谢谢!</div>
+            <div class="flex-col items-center">
+              <img :src="shareImageUrl" class="" />
+              <div class="font-size-14px color-[#333] m-t-4px text-center">微信扫码看权益单</div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="savePoster()">下载报价单</el-button>
+          <el-button @click="dialogFormVisible = false">
+            取消
+          </el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+<script setup lang="ts">
+import html2canvas from 'html2canvas';
+import QRCode from 'qrcode'
+import dayjs from "dayjs";
+
+const props = defineProps<{
+  quotationObj: object,
+  insurancePolicyForm: object
+}>();
+
+const descriptionsData = computed(() => {
+  return [
+    [
+      { title: '投保人姓名/名称', value: props.insurancePolicyForm.name2, },
+      { title: '车主姓名/名称', value: props.insurancePolicyForm.name1, },
+    ], [
+      { title: '被保人姓名/名称', value: props.insurancePolicyForm.name3 },
+      { title: '车牌号', value: props.insurancePolicyForm.licenseNo },
+    ], [
+      { title: '车型名称', value: props.insurancePolicyForm.brandName },
+    ], [
+      { title: '新车购置价(元)', value: props.insurancePolicyForm.purchasePrice },
+      { title: ' ', value: ' ' },
+    ], [
+      { title: '发动机号、VIN码', value: props.insurancePolicyForm.engineNo },
+      { title: '初登日期', value: props.insurancePolicyForm.registerDate },
+    ], [
+      { title: '使用性质', value: props.insurancePolicyForm.carNatureCode },
+      {
+        title: '承保年数、出险次数', value: `商业险:期间内共出险${props.quotationObj.quoteResult?.scoreVo?.biClaims || 0}次<br>
+        交强险:期间内共出险${props.quotationObj.quoteResult?.scoreVo?.ciClaims || 0}次`
+      },
+    ], [
+      { title: '商业险保险期限', value: props.insurancePolicyForm.SYStartDate + '至' + props.insurancePolicyForm.SYEndDate },
+      { title: '交强险保险期限', value: props.insurancePolicyForm.JQStartDate + '至' + props.insurancePolicyForm.JQEndDate },
+    ],
+  ]
+})
+
+const tableData = computed(() => {
+  let arr = []
+  const quoteResult = props.quotationObj.quoteResult
+  if (quoteResult.kindInfoVo) {
+    for (let i = 0; i < props.quotationObj.quoteResult.kindInfoVo.length; i++) {
+      const element = props.quotationObj.quoteResult.kindInfoVo[i];
+      const obj = {
+        title: element.kindName,
+        amount: element.amount,
+        premium: element.premium,
+      }
+      arr.push(obj)
+    }
+  }
+  if (quoteResult?.costs?.biPremium) arr.push({ total: true, title: '商业险合计保费', premium: quoteResult.costs.biPremium })
+  if (quoteResult?.costs?.ciPremium) arr.push({ total: true, title: '机动车交通事故责任强制保险', premium: quoteResult.costs.ciPremium })
+  if (quoteResult?.costs?.vvTax) arr.push({ total: true, title: '车船税', premium: quoteResult.costs.vvTax })
+  const drivings = props.quotationObj.projectList?.[props.quotationObj.productIndex]?.drivings ?? []
+  if (drivings.length > 0) {
+    for (let i = 0; i < drivings.length; i++) {
+      const element = drivings[i];
+      const obj = {
+        title: element.productName,
+        amount: element.sumAmount,
+        premium: element.premium,
+      }
+      arr.push(obj)
+    }
+  }
+  arr.push({ total: true, title: '保费合计(不含车船税)', premium: quoteResult.costs.totalAmount })
+  arr.push({ total: true, title: '保费合计(含车船税)', premium: quoteResult.costs.sumPremium })
+  return arr
+})
+
+const dialogFormVisible = ref(false)
+
+const shareImageUrl = ref('')
+const show = async (obj) => {
+  dialogFormVisible.value = true
+  shareImageUrl.value = await QRCode.toDataURL(`https://tennat.baoxianzhanggui.com/h5/#/pages/quote/quoteRecordDetail?ordersNo=${obj.quoteResult?.ordersNo}&from=share`, {
+    width: 160,
+    margin: 2
+  });
+}
+const savePoster = () => {
+  html2canvas(document.querySelector(".content"), { useCORS: true }).then((canvas) => {
+    downloadBase64(canvas.toDataURL(), props.insurancePolicyForm.licenseNo + "报价单");
+  });
+};
+
+const downloadBase64 = (dataUrl, fileName = 'download', fileExtension = "png") => {
+  const byteCharacters = atob(dataUrl.split(',')[1]);
+  const byteArrays = [];
+  for (let offset = 0; offset < byteCharacters.length; offset += 10240) {
+    const slice = byteCharacters.slice(offset, offset + 10240);
+    const byteNumbers = new Array(slice.length);
+    for (let i = 0; i < slice.length; i++) {
+      byteNumbers[i] = slice.charCodeAt(i);
+    }
+    const byteArray = new Uint8Array(byteNumbers);
+    byteArrays.push(byteArray);
+  }
+  const blob = new Blob(byteArrays, { type: 'application/octet-stream' });
+  const blobUrl = URL.createObjectURL(blob);
+  const creatDom = document.createElement('a');
+  document.body.appendChild(creatDom);
+  creatDom.href = blobUrl;
+  creatDom.download = `${fileName}.${fileExtension}`;
+  creatDom.click();
+  document.body.removeChild(creatDom);
+  URL.revokeObjectURL(blobUrl);
+};
+
+defineExpose({
+  show,
+})
+</script>
+<style scoped lang="scss">
+:deep(.el-dialog__header) {
+  padding: unset;
+  border-bottom: unset;
+}
+
+:deep(.el-dialog__body) {
+  padding: unset;
+}
+</style>