wupengfei
2025-03-24 ee36747f2db9ac3a641e1cbaeb01f726ce9faa98
src/views/InsuranceClaim/InsuranceClaimDetail.vue
@@ -1,587 +1,11 @@
<template>
  <LoadingLayout :loading="isLoading">
    <AppScrollContainer>
      <ChunkCell title="报案信息">
        <ProForm :model="form" ref="formRef" label-width="120px">
          <ProFormCol>
            <ProFormColItem :span="6">
              <ProFormItemV2
                label="身份证号码:"
                prop="idNumber"
                :check-rules="[{ message: '请输入身份证号码', type: 'idCard' }]"
              >
                <ProFormText
                  v-model.trim="form.idNumber"
                  placeholder="请输入身份证号码"
                  @change="handleIdNumberChange"
                />
              </ProFormItemV2>
            </ProFormColItem>
            <ProFormColItem :span="6">
              <ProFormItemV2
                label="报案时间:"
                prop="reportedTime"
                :check-rules="[{ message: '请选择报案时间' }]"
              >
                <ProFormDatePicker
                  v-model="form.reportedTime"
                  type="datetime"
                  format="YYYY-MM-DD HH:mm:ss"
                  value-format="YYYY-MM-DD HH:mm:ss"
                  placeholder="请选择报案时间"
                  :disabled-date="disabledReportedDate"
                  @change="handleReportedTimeChange"
                  :key="datePickerKey"
                ></ProFormDatePicker>
              </ProFormItemV2>
            </ProFormColItem>
            <ProFormColItem :span="6">
              <ProFormItemV2
                label="联系电话:"
                prop="contactNumber"
                :check-rules="[{ message: '请输入联系电话', type: 'phone' }]"
              >
                <ProFormText v-model.trim="form.contactNumber" placeholder="请输入联系电话" />
              </ProFormItemV2>
            </ProFormColItem>
            <ProFormColItem :span="6">
              <ProFormItemV2
                label="备用联系电话:"
                prop="bakContactNumber"
                :check-rules="[{ message: '请输入备用联系电话', type: 'phone', required: false }]"
              >
                <ProFormText
                  v-model.trim="form.bakContactNumber"
                  placeholder="请输入备用联系电话"
                />
              </ProFormItemV2>
            </ProFormColItem>
            <ProFormColItem :span="6">
              <ProFormItemV2 label="姓名:" prop="name" :check-rules="[{ message: '请输入姓名' }]">
                <ProFormText v-model.trim="form.name" placeholder="请输入姓名" :maxlength="30" />
              </ProFormItemV2>
            </ProFormColItem>
          </ProFormCol>
        </ProForm>
      </ChunkCell>
      <ChunkCell title="保单信息">
        <ProForm :model="form" ref="insuranceBaseFormRef" label-width="120px">
          <ProFormCol>
            <ProFormColItem :span="6">
              <ProFormItemV2
                label="参保机构:"
                prop="insuredInstitution"
                :check-rules="[{ message: '请选择参保机构' }]"
              >
                <ProFormSelect
                  placeholder="请选择参保机构"
                  :value-enum="InsuredInstitutionEnum"
                  clearable
                  v-model="form.insuredInstitution"
                ></ProFormSelect>
              </ProFormItemV2>
            </ProFormColItem>
            <ProFormColItem :span="6">
              <ProFormItemV2
                label="投保方案:"
                prop="insuranceScheme"
                :check-rules="[{ message: '请选择投保方案' }]"
              >
                <ProFormSelect
                  placeholder="请选择投保方案"
                  :value-enum="InsuranceSchemeEnum"
                  clearable
                  v-model="form.insuranceScheme"
                ></ProFormSelect>
              </ProFormItemV2>
            </ProFormColItem>
          </ProFormCol>
          <ProFormMixinsItemContainer>
            <ProFormCol>
              <ProFormColItem :span="6">
                <ProFormItemV2 label="起保日期:" prop="insuranceBeginTime" mode="read">
                  <ProFormDatePicker
                    v-model="form.insuranceBeginTime"
                    type="date"
                    value-format="YYYY-MM-DD"
                    placeholder="请选择起保日期"
                  ></ProFormDatePicker>
                </ProFormItemV2>
              </ProFormColItem>
              <ProFormColItem :span="6">
                <ProFormItemV2 label="劳动合同单位:" prop="laborContractEnterprise" mode="read">
                  <ProFormText
                    v-model.trim="form.laborContractEnterprise"
                    placeholder="请输入劳动合同单位"
                  />
                </ProFormItemV2>
              </ProFormColItem>
              <ProFormColItem :span="6">
                <ProFormItemV2 label="工种:" prop="workType" mode="read">
                  <ProFormText v-model.trim="form.workType" placeholder="请输入工种" />
                </ProFormItemV2>
              </ProFormColItem>
            </ProFormCol>
          </ProFormMixinsItemContainer>
          <ProFormMixinsItemContainer>
            <ProFormCol>
              <ProFormColItem :span="6">
                <ProFormItemV2 label="终保日期:" prop="insuranceEndTime" mode="read">
                  <ProFormDatePicker
                    v-model="form.insuranceEndTime"
                    type="date"
                    value-format="YYYY-MM-DD"
                    placeholder="请选择终保日期"
                  ></ProFormDatePicker>
                </ProFormItemV2>
              </ProFormColItem>
              <ProFormColItem :span="6">
                <ProFormItemV2 label="实际工作单位:" prop="workEnterprise" mode="read">
                  <ProFormText
                    v-model.trim="form.workEnterprise"
                    placeholder="请输入实际工作单位"
                  />
                </ProFormItemV2>
              </ProFormColItem>
            </ProFormCol>
          </ProFormMixinsItemContainer>
        </ProForm>
      </ChunkCell>
      <ChunkCell title="保单信息">
        <ProForm :model="form" ref="insuranceFormRef" label-width="120px">
          <ProFormCol>
            <ProFormColItem :span="6">
              <ProFormItemV2
                label="事故类型:"
                prop="accidentType"
                :check-rules="[{ message: '请选择事故类型' }]"
              >
                <ProFormSelect
                  placeholder="请选择事故类型"
                  :value-enum="AccidentTypeEnum"
                  clearable
                  v-model="form.accidentType"
                ></ProFormSelect>
              </ProFormItemV2>
            </ProFormColItem>
            <ProFormColItem :span="6">
              <ProFormItemV2
                label="事故发生时间:"
                prop="accidentTime"
                :check-rules="[{ message: '请选择事故发生时间' }]"
              >
                <ProFormDatePicker
                  v-model="form.accidentTime"
                  type="datetime"
                  format="YYYY-MM-DD HH:mm:ss"
                  placeholder="请选择事故发生时间"
                ></ProFormDatePicker>
              </ProFormItemV2>
            </ProFormColItem>
          </ProFormCol>
          <ProFormCol>
            <ProFormColItem :span="6">
              <ProFormItemV2 label="伤残比例:" prop="disabilityRatio">
                <ProFormInputNumber
                  v-model="form.disabilityRatio"
                  :controls="false"
                  :min="0"
                  :max="100"
                  unit="%"
                ></ProFormInputNumber>
              </ProFormItemV2>
            </ProFormColItem>
            <ProFormColItem :span="18">
              <ProFormItemV2
                label="事发地点:"
                prop="accidentAddress"
                :check-rules="[{ message: '请输入事发地点' }]"
              >
                <ProFormText
                  v-model.trim="form.accidentAddress"
                  placeholder="请输入事发地点"
                  :maxlength="100"
                />
              </ProFormItemV2>
            </ProFormColItem>
          </ProFormCol>
          <ProFormCol>
            <ProFormColItem :span="24">
              <ProFormItemV2
                label="事故经过:"
                prop="accidentProcess"
                :check-rules="[{ message: '请输入事故经过' }]"
              >
                <ProFormTextArea
                  v-model="form.accidentProcess"
                  :rows="10"
                  placeholder="请输入事故经过"
                  :maxlength="500"
                  show-word-limit
                ></ProFormTextArea>
              </ProFormItemV2>
            </ProFormColItem>
          </ProFormCol>
          <div class="attachments-wrapper">
            <div class="attachments">
              <ProFormItemV2 label="伤者身份证照片(正反):">
                <div class="id-imgUrl-wrapper">
                  <ProFormItemV2 prop="attachmentFrontIdCards" class="pro-form-item-label-hidden">
                    <ProFormImageUpload
                      v-model:file-url="form.attachmentFrontIdCards"
                      :limitFileSize="10"
                      btnText="身份证人像面"
                      :showTip="false"
                    >
                    </ProFormImageUpload>
                  </ProFormItemV2>
                  <ProFormItemV2 prop="attachmentBackIdCards" class="pro-form-item-label-hidden">
                    <ProFormImageUpload
                      v-model:file-url="form.attachmentBackIdCards"
                      :limitFileSize="10"
                      btnText="身份证国徽面"
                      :showTip="false"
                    >
                    </ProFormImageUpload>
                  </ProFormItemV2>
                </div>
              </ProFormItemV2>
              <ProFormItemV2 prop="attachmentSites" label="受伤场地:">
                <ProFormImageUpload
                  v-model:file-url="form.attachmentSites"
                  :limitFileSize="10"
                  :showTip="false"
                >
                </ProFormImageUpload>
              </ProFormItemV2>
              <ProFormItemV2 prop="attachmentHandheldIdCards" label="伤者手持身份证照:">
                <ProFormImageUpload
                  v-model:file-url="form.attachmentHandheldIdCards"
                  :limitFileSize="10"
                  :showTip="false"
                >
                </ProFormImageUpload>
              </ProFormItemV2>
              <ProFormItemV2 prop="attachmentAreas" label="受伤部位:">
                <ProFormImageUpload
                  v-model:file-url="form.attachmentAreas"
                  :limitFileSize="10"
                  :showTip="false"
                  :limitFileCount="0"
                >
                </ProFormImageUpload>
              </ProFormItemV2>
              <ProFormItemV2 prop="attachmentCases" label="病例照片:">
                <ProFormImageUpload
                  v-model:file-url="form.attachmentCases"
                  :limitFileSize="10"
                  :showTip="false"
                  :limitFileCount="0"
                >
                </ProFormImageUpload>
              </ProFormItemV2>
            </div>
            <ClaimPicDemoView />
          </div>
          <div class="chuck-add-or-edit-actions">
            <el-button @click="handleBack">关闭</el-button>
            <el-button type="primary" @click="handleSubmit">提交</el-button>
          </div>
        </ProForm>
      </ChunkCell>
      <!-- <ChunkCell title="理赔结果">
        <ProForm :model="form" ref="claimFormRef" label-width="120px">
          <ProFormCol>
            <ProFormColItem :span="6">
              <ProFormItemV2 label="理赔结果:" prop="claimResult">
                <ProFormSelect
                  placeholder="请选择理赔结果"
                  :value-enum="InsuranceClaimResultEnumText"
                  clearable
                  v-model="form.claimResult"
                ></ProFormSelect>
              </ProFormItemV2>
            </ProFormColItem>
            <ProFormColItem :span="6">
              <ProFormItemV2 label="结/撤案时间:" prop="claimResultTime">
                <ProFormDatePicker
                  v-model="form.claimResultTime"
                  type="datetime"
                  format="YYYY-MM-DD"
                  value-format="YYYY-MM-DD"
                  placeholder="请选择结/撤案时间"
                ></ProFormDatePicker>
              </ProFormItemV2>
            </ProFormColItem>
          </ProFormCol>
          <ProFormItemV2 label="下款金额:" prop="downPaymentAmount">
            <ProFormInputNumber
              v-model="form.downPaymentAmount"
              :controls="false"
              :min="0"
              :precision="2"
            ></ProFormInputNumber>
          </ProFormItemV2>
          <div class="chuck-add-or-edit-actions">
            <el-button @click="handleBack">关闭</el-button>
            <el-button type="primary" @click="handleSubmit">提交</el-button>
          </div>
        </ProForm>
      </ChunkCell> -->
    </AppScrollContainer>
    <SelectOrderDialog v-bind="dialogProps" />
  </LoadingLayout>
  <InsuranceClaimView :isDetail="true"></InsuranceClaimView>
</template>
<script setup lang="ts">
import * as insuranceOrderServices from '@/services/api/InsuranceOrder';
import * as insuranceClaimServices from '@/services/api/InsuranceClaim';
import {
  ChunkCell,
  AppScrollContainer,
  LoadingLayout,
  ProForm,
  ProFormCol,
  ProFormColItem,
  ProFormText,
  ProFormDatePicker,
  ProFormSelect,
  ProFormImageUpload,
  ProFormTextArea,
  ProFormItemV2,
  ProFormMixinsItemContainer,
  ProFormInputNumber,
  useFormDialog,
} from '@bole-core/components';
import { FormInstance, DatePickerInstance } from 'element-plus';
import { validateFormList, format } from '@/utils';
import { convertFormToattAchments } from './utils';
import {
  InsuredInstitutionEnum,
  InsuranceSchemeEnum,
  AccidentTypeEnum,
  InsuranceClaimAttachmentBusinessTypeEnum,
  InsuranceClaimResultEnumText,
} from '@/constants';
import { useRouteView } from '@/hooks';
import { Message, BoleRegExp } from '@bole-core/core';
import { useInsuranceClaimDetail, useInsuranceOrderListByOrderRelevance } from './hooks';
import ClaimPicDemoView from './components/ClaimPicDemoView.vue';
import SelectOrderDialog from './components/SelectOrderDialog.vue';
import { useQueryClient } from '@tanstack/vue-query';
import InsuranceClaimView from './components/InsuranceClaimView.vue';
defineOptions({
  name: 'InsuranceClaimDetail',
  name: 'InsuranceClaim',
});
const route = useRoute();
const insuranceOrderId = (route.params.id as string) ?? '';
const { closeViewPush } = useRouteView();
const datePickerKey = ref(1);
const { form, isLoading, claimDetail, disabledReportedDate, queryClaimDetailByOrderId, resetForm } =
  useInsuranceClaimDetail({
    insuranceOrderId,
  });
// const { existedInsuranceOrderList } = useInsuranceOrderListByOrderRelevance({
//   params: computed(() => ({
//     idIdNumber: form.idNumber,
//     reportedTime: form.reportedTime,
//   })),
//   onSuccess(data) {
//     if (data.length == 1) {
//       // importInsuranceOrderData(data[0]);
//       form.insuranceOrderId = data[0].id;
//     } else if (data.length > 1) {
//       handleAdd({
//         insuranceOrderList: data,
//       });
//     }
//   },
// });
const { dialogProps, handleAdd, editForm } = useFormDialog({
  onConfirm: handleSelectedOrder,
  defaultFormParams: {
    insuranceOrderId: '',
    insuranceOrderList: [] as API.InsuranceOrderListOutput[],
  },
});
async function handleSelectedOrder() {
  try {
    datePickerKey.value += 1;
    resetForm();
    await nextTick();
    form.insuranceOrderId = editForm.insuranceOrderId;
    // let claimDetail = await queryClaimDetailByOrderId();
    // if (claimDetail) {
    //   Message.errorMessage('该保单已理赔');
    // }
  } catch (error) {}
}
const queryClient = useQueryClient();
async function ensureInsuranceOrderList() {
  try {
    if (BoleRegExp.RegIDCard.test(form.idNumber) && !!form.reportedTime) {
      let params: API.QueryInsuranceOrderListByOrderRelevanceInput = {
        idIdNumber: form.idNumber,
        reportedTime: form.reportedTime,
      };
      let existedInsuranceOrderList = await queryClient.ensureQueryData({
        queryKey: ['insuranceOrderServices/getInsuranceOrderListByOrderRelevance', params],
        queryFn: async () => {
          return await insuranceOrderServices.getInsuranceOrderListByOrderRelevance(params, {
            showLoading: false,
          });
        },
      });
      if (existedInsuranceOrderList.length == 1) {
        form.insuranceOrderId = existedInsuranceOrderList[0].id;
      } else if (existedInsuranceOrderList.length > 1) {
        handleAdd({
          insuranceOrderList: existedInsuranceOrderList,
        });
      } else {
        Message.errorMessage('未找到匹配的保单信息');
      }
    }
    // return existedInsuranceOrderList;
  } catch (error) {}
}
function handleIdNumberChange() {
  ensureInsuranceOrderList();
}
function handleReportedTimeChange() {
  if (form.accidentTime === '') {
    form.accidentTime = form.reportedTime;
  }
  ensureInsuranceOrderList();
}
const formRef = ref<FormInstance>();
const insuranceBaseFormRef = ref<FormInstance>();
const insuranceFormRef = ref<FormInstance>();
const claimFormRef = ref<FormInstance>();
async function handleSubmit() {
  try {
    const valid = await validateFormList([
      formRef.value,
      insuranceBaseFormRef.value,
      insuranceFormRef.value,
    ]);
    if (valid) {
      addInsuranceClaim();
    }
  } catch (error) {}
}
async function addInsuranceClaim() {
  try {
    if (claimDetail.value === undefined) {
      Message.errorMessage('未找到匹配的保单信息');
      return;
    }
    let params: API.AddInsuranceClaimInput = {
      channel: form.channel,
      name: form.name,
      idNumber: form.idNumber,
      workType: form.workType,
      laborContractEnterprise: form.laborContractEnterprise,
      workEnterprise: form.workEnterprise,
      insuranceBeginTime: format(form.insuranceBeginTime),
      insuranceEndTime: format(form.insuranceEndTime),
      insuredInstitution: form.insuredInstitution,
      insuranceScheme: form.insuranceScheme,
      onJobFlag: form.onJobFlag,
      gender: form.gender,
      age: form.age,
      premiumAmount: form.premiumAmount,
      incDecAmount: form.incDecAmount,
      insuranceOrderId: form.insuranceOrderId,
      reportedTime: format(form.reportedTime, 'YYYY-MM-DD HH:mm:ss'),
      contactNumber: form.contactNumber,
      bakContactNumber: form.bakContactNumber,
      accidentType: form.accidentType,
      accidentTime: format(form.accidentTime, 'YYYY-MM-DD HH:mm:ss'),
      // disabilityRatio: form.disabilityRatio,
      accidentAddress: form.accidentAddress,
      accidentProcess: form.accidentProcess,
      // claimResult: form.claimResult,
      // claimResultTime: form.claimResultTime,
      attachments: [
        ...convertFormToattAchments(
          form.attachmentFrontIdCards,
          InsuranceClaimAttachmentBusinessTypeEnum.InjuredIdCardImg
        ),
        ...convertFormToattAchments(
          form.attachmentBackIdCards,
          InsuranceClaimAttachmentBusinessTypeEnum.InjuredIdCardImg
        ),
        ...convertFormToattAchments(
          form.attachmentSites,
          InsuranceClaimAttachmentBusinessTypeEnum.InjurySiteImg
        ),
        ...convertFormToattAchments(
          form.attachmentHandheldIdCards,
          InsuranceClaimAttachmentBusinessTypeEnum.InjuredHandheldIdCardImg
        ),
        ...convertFormToattAchments(
          form.attachmentAreas,
          InsuranceClaimAttachmentBusinessTypeEnum.InjuredAreaImg
        ),
        ...convertFormToattAchments(
          form.attachmentCases,
          InsuranceClaimAttachmentBusinessTypeEnum.CasesImg
        ),
      ],
    };
    // if (form.downPaymentAmount) params.downPaymentAmount = form.downPaymentAmount;
    if (form.disabilityRatio) params.disabilityRatio = form.disabilityRatio;
    let res: number;
    // if (!!claimDetail.value) {
    //   Message.errorMessage('该保单已理赔');
    // } else {
    res = await insuranceClaimServices.addInsuranceClaim(params);
    // }
    if (res) {
      Message.successMessage('操作成功');
      handleBack();
    }
  } catch (error) {}
}
function handleBack() {
  closeViewPush(route, {
    name: 'Home',
  });
}
</script>
<style lang="scss" scoped>
@use '@/style/common.scss' as *;
.attachments-wrapper {
  position: relative;
  display: flex;
  .attachments {
    flex: 1;
    min-width: 0;
  }
}
.id-imgUrl-wrapper {
  display: flex;
  gap: 40px;
}
</style>