wupengfei
2025-04-02 d82fea569f9bb487364d667cdf3af626cf06f20e
src/views/Home/components/InsureOrderInfoView.vue
@@ -1,70 +1,72 @@
<template>
  <LoadingLayout :loading="state.loading">
    <AppScrollContainer>
    <AppContainer>
      <ChunkCell title="">
        <ProForm :model="detail" ref="formRef" label-width="120px" :is-read="true">
          <ProFormCol>
            <ProFormColItem :span="8">
              <ProFormItemV2 label="保单号:" prop="orderNo">
                <ProFormText v-model.trim="detail.orderNo" />
              <ProFormItemV2 label="保单号:" prop="insureBillNo">
                <ProFormText v-model.trim="detail.insureBillNo" />
              </ProFormItemV2>
            </ProFormColItem>
            <ProFormColItem :span="8">
              <ProFormItemV2 label="生效状态:" prop="insuranceTypeCode">
                <ProFormRadio v-model="detail.insuranceType" :value-enum="insuranceTypeText" />
              <ProFormItemV2 label="生效状态:" prop="status">
                <ProFormRadio v-model="detail.status" :value-enum="InsurancePolicyStatusEnumText" />
              </ProFormItemV2>
            </ProFormColItem>
          </ProFormCol>
          <ProFormCol>
            <ProFormColItem :span="8">
              <ProFormItemV2 label="保险起期:" prop="applyTime">
                <ProFormDatePicker v-model.trim="detail.createTime" format="YYYY-MM-DD HH:mm" />
              <ProFormItemV2 label="保险起期:" prop="effectStartTime">
                <ProFormDatePicker v-model.trim="detail.effectStartTime" format="YYYY-MM-DD" />
              </ProFormItemV2>
            </ProFormColItem>
            <ProFormColItem :span="8">
              <ProFormItemV2 label="保险止期:" prop="insuranceTypeCode">
                <ProFormDatePicker v-model.trim="detail.createTime" format="YYYY-MM-DD HH:mm" />
              <ProFormItemV2 label="保险止期:" prop="effectEndTime">
                <ProFormDatePicker v-model.trim="detail.effectEndTime" format="YYYY-MM-DD" />
              </ProFormItemV2>
            </ProFormColItem>
            <ProFormColItem :span="8">
              <ProFormItemV2 label="投保方式:" prop="insureWay">
                <ProFormRadio v-model="detail.insuranceType" :value-enum="insuranceTypeText" />
              <ProFormItemV2 label="投保方式:" prop="insurancePeriod">
                <ProFormRadio v-model="detail.insurancePeriod" :value-enum="insuranceTypeText" />
              </ProFormItemV2>
            </ProFormColItem>
          </ProFormCol>
          <ProFormCol>
            <ProFormColItem :span="8">
              <ProFormItemV2 label="参保机构:" prop="applyTime">
                <ProFormText v-model.trim="detail.orderNo" />
              <ProFormItemV2 label="参保机构:" prop="insuranceOrg">
                <!-- <ProFormRadio v-model="detail.insuranceOrg" :value-enum="InsuredInstitutionEnum" /> -->
                <ProFormText v-model.trim="detail.insuranceOrg" />
              </ProFormItemV2>
            </ProFormColItem>
            <ProFormColItem :span="8">
              <ProFormItemV2 label="投保方案:" prop="applyTime">
                <ProFormText v-model.trim="detail.orderNo" />
              <ProFormItemV2 label="投保方案:" prop="insuranceScheme">
                <!-- <ProFormRadio v-model="detail.insuranceScheme" :value-enum="InsuranceSchemeEnum" /> -->
                <ProFormText v-model.trim="detail.insuranceScheme" />
              </ProFormItemV2>
            </ProFormColItem>
            <ProFormColItem :span="8">
              <ProFormItemV2 label="投保人数:" prop="numberOfFailed">
                <ProFormInputNumber v-model.trim="detail.incDecAmount" unit="人" />
              <ProFormItemV2 label="投保人数:" prop="insureCount">
                <ProFormInputNumber v-model.trim="detail.insureCount" unit="人" />
              </ProFormItemV2>
            </ProFormColItem>
          </ProFormCol>
          <ProFormCol>
            <ProFormColItem :span="8">
              <ProFormItemV2 label="投保人:" prop="companyName">
                <ProFormText v-model.trim="detail.orderNo" />
              <ProFormItemV2 label="投保人:" prop="insurerName">
                <ProFormText v-model.trim="detail.insurerName" />
              </ProFormItemV2>
            </ProFormColItem>
            <ProFormColItem :span="8">
              <ProFormItemV2 label="被保人:" prop="insuranceTypeCode">
                <ProFormText v-model.trim="detail.orderNo" />
              <ProFormItemV2 label="被保人:" prop="policyerName">
                <ProFormText v-model.trim="detail.policyerName" />
              </ProFormItemV2>
            </ProFormColItem>
          </ProFormCol>
        </ProForm>
      </ChunkCell>
      <ChunkCell title="人员信息">
        <template #titleRight>
      <ChunkCell title="人员信息" class="full-table-chunk">
        <template #titleRight v-if="detail.status !== InsurancePolicyStatusEnum.WaitEffect">
          <el-button type="primary" @click="handleBatchChange">批改申请</el-button>
        </template>
        <ProTableQueryFilterBar @on-reset="reset">
@@ -73,34 +75,48 @@
              <SearchInput
                v-model="extraParamState.keyWord"
                style="width: 300px"
                placeholder="人员姓名/身份证号/手机号"
                @on-click-search="getBatchRefundInfoDetail"
                placeholder="姓名/身份证号/手机号"
                @on-click-search="getInsuranceStaffList"
              >
              </SearchInput>
            </QueryFilterItem>
          </template>
          <template #btn>
            <el-button @click="handleTemplateDownload()" link type="primary">模板下载</el-button>
            <el-button @click="handleImport()" type="primary">导入</el-button>
            <el-button @click="handleClear()" type="primary">清空数据</el-button>
            <el-button @click="handleDownloadPerson()" type="primary">人员清单下载</el-button>
            <el-button @click="handleDownloadOrder()" type="primary">保单下载</el-button>
            <template v-if="detail.status === InsurancePolicyStatusEnum.WaitEffect">
              <el-button @click="handleTemplateDownload()" link type="primary">模板下载</el-button>
              <BlFileUpload
                :limitFileSize="10"
                accept="xls,xlsx"
                :showTip="false"
                :show-file-list="false"
                :on-success="handleUploadSuccess"
                style="margin-right: 10px; margin-left: 10px"
              >
                <template #default>
                  <el-button icon="Plus" type="primary">导入</el-button>
                </template>
              </BlFileUpload>
              <el-button @click="handleClear()" type="primary">清空数据</el-button>
            </template>
            <template v-else>
              <el-button @click="handleDownloadPerson()" type="primary">下载人员清单</el-button>
              <el-button @click="handleDownloadOrder()" type="primary">下载保单</el-button>
            </template>
          </template>
        </ProTableQueryFilterBar>
        <ProTableV2
          v-bind="proTableProps"
          :columns="column"
          :operationBtns="operationBtns"
          :auto-height="false"
          ref="proTable"
          :tableProps="{
            maxHeight: '400px',
          }"
        >
        </ProTableV2>
        <div class="full-table-chunk-table">
          <ProTableV2
            v-bind="proTableProps"
            :columns="column"
            :operationBtns="operationBtns"
            ref="proTable"
          >
          </ProTableV2>
        </div>
      </ChunkCell>
      <ChangePersonInfoDialog v-bind="dialogProps"></ChangePersonInfoDialog>
    </AppScrollContainer>
      <InsureClaimDetailDialog v-bind="dialogInsureClaimProps"></InsureClaimDetailDialog>
    </AppContainer>
  </LoadingLayout>
</template>
@@ -124,12 +140,24 @@
  ProFormRadio,
  defineOperationBtns,
  useFormDialog,
  BlFileUpload,
  UploadUserFile,
  XLSXUtils,
} from '@bole-core/components';
import { InsuranceOrderTempPath, insuranceTypeText } from '@/constants';
import {
  InsuranceOrderTempPath,
  insuranceTypeText,
  InsurancePolicyStatusEnum,
  InsurancePolicyStatusEnumText,
} from '@/constants';
import ChangePersonInfoDialog from './ChangePersonInfoDialog.vue';
import InsureClaimDetailDialog from './InsureClaimDetailDialog.vue';
import * as insuranceOrderServices from '@/services/api/InsuranceOrder';
import * as insuranceClaimServices from '@/services/api/InsuranceClaim';
import { useQuery, useQueryClient } from '@tanstack/vue-query';
import { downloadFileByUrl, OrderInputType } from '@bole-core/core';
import { downloadFile, downloadFileByUrl, Message, OrderInputType } from '@bole-core/core';
import { setOSSLink } from '@/utils';
import dayjs from 'dayjs';
defineOptions({
  name: 'InsureOrderInfoView',
@@ -143,53 +171,60 @@
  },
  {
    id: '2',
    enCode: 'name',
    enCode: 'gender',
    name: '性别',
    width: 80,
  },
  {
    id: '3',
    enCode: 'name',
    enCode: 'certType',
    name: '证件类型',
    width: 100,
  },
  {
    id: '4',
    enCode: 'idNumber',
    enCode: 'certNo',
    name: '证件号码',
    width: 180,
  },
  {
    id: '5',
    enCode: 'idNumber',
    enCode: 'jobName',
    name: '雇员工种',
  },
  {
    id: '6',
    enCode: 'idNumber',
    enCode: 'userEmploer',
    name: '用工单位',
  },
  {
    id: '7',
    enCode: 'idNumber',
    enCode: 'address',
    name: '用工地点',
  },
  {
    id: '8',
    enCode: 'idNumber',
    enCode: 'age',
    name: '年龄',
    width: 80,
  },
  {
    id: '9',
    enCode: 'idNumber',
    enCode: 'birthDay',
    name: '出生日期',
    width: 120,
  },
  {
    id: '10',
    enCode: 'idNumber',
    enCode: 'phone',
    name: '手机号码',
    width: 140,
  },
  {
    id: '11',
    enCode: 'idNumber',
    enCode: 'claimCount',
    name: '理赔',
    width: 100,
  },
];
@@ -202,9 +237,10 @@
    emits: {
      onClick: (role) => handleChangeInfo(role),
    },
    // extraProps: {
    //   hide: (row: API.InsuranceOrderListOutput) => !row.orderBillFile,
    // },
    extraProps: {
      hide: (row: API.GetInsuranceStaffPageTemplate) =>
        detail.value?.status !== InsurancePolicyStatusEnum.WaitEffect,
    },
  },
  {
    data: {
@@ -212,11 +248,12 @@
      name: '理赔详情',
    },
    emits: {
      onClick: (role) => handleInsureClaimDetail(role),
      onClick: (role) => handleDetail(role),
    },
    // extraProps: {
    //   hide: (row: API.InsuranceOrderListOutput) => !row.orderBillFile,
    // },
    extraProps: {
      hide: (row: API.GetInsuranceStaffPageTemplate) =>
        !(row.claimCount && detail.value?.status !== InsurancePolicyStatusEnum.WaitEffect),
    },
  },
]);
@@ -230,16 +267,16 @@
const state = reactive({ ...BaseState });
const { data: detail, isLoading } = useQuery({
  queryKey: ['insuranceOrderServices/getInsuranceOrderDetail', id],
  queryKey: ['insuranceOrderServices/getInsurancePolicyHeadDto', id],
  queryFn: async () => {
    return await insuranceOrderServices.getInsuranceOrderDetail(
    return await insuranceOrderServices.getInsurancePolicyHeadDto(
      { id: id },
      {
        showLoading: !state.loading,
      }
    );
  },
  placeholderData: () => ({} as API.InsuranceOrderListOutput),
  placeholderData: () => ({} as API.GetInsurancePageOutput),
  enabled: !!id,
});
@@ -247,14 +284,14 @@
onMounted(async () => {
  await queryClient.ensureQueryData({
    queryKey: ['insuranceOrderServices/getInsuranceOrderDetail', id],
    queryKey: ['insuranceOrderServices/getInsurancePolicyHeadDto', id],
  });
  await getBatchRefundInfoDetail();
  await getInsuranceStaffList();
  state.loading = false;
});
const {
  getDataSource: getBatchRefundInfoDetail,
  getDataSource: getInsuranceStaffList,
  proTableProps,
  paginationState,
  extraParamState,
@@ -262,16 +299,16 @@
} = useTable(
  async ({ pageIndex, pageSize }, extraParamState) => {
    try {
      let params: API.QueryInsuranceOrderPageInput = {
      let params: API.GetInsuranceStaffListInput = {
        pageModel: {
          rows: pageSize,
          page: pageIndex,
          orderInput: extraParamState.orderInput,
        },
        condition: extraParamState.keyWord,
        // insurePolicyOperateHistoryId: id,
        insurancePolicyId: id,
      };
      let res = await insuranceOrderServices.getInsuranceOrderPage(params, {
      let res = await insuranceOrderServices.getInsuranceStaffList(params, {
        showLoading: !state.loading,
      });
      return res;
@@ -289,48 +326,182 @@
function handleTemplateDownload() {
  downloadFileByUrl(InsuranceOrderTempPath, '人员信息模板');
}
function handleClear() {}
function handleImport() {}
async function handleClear() {
  try {
    if (paginationState.total === 0) {
      Message.warnMessage('没有需要清空的数据~');
      return;
    }
    await Message.tipMessage('是否清空人员信息');
    let res = await insuranceOrderServices.clearInsuranceStaffData({
      id: id,
    });
    if (res) {
      Message.successMessage('操作成功');
      getInsuranceStaffList(paginationState.pageIndex);
    }
  } catch (error) {}
}
async function handleUploadSuccess(response: UploadUserFile) {
  try {
    let res = await insuranceOrderServices.importInsDetailStaffToList({
      id: id,
      url: response.url,
    });
    if (res?.length > 0) {
      await Message.tipMessage('存在错误数据,是否导出?');
      XLSXUtils.exportToXLSX({
        workbookDataList: res,
        fileName: '错误人员名单',
        workbookHeaderMap: {
          name: '雇员姓名',
          sex: '性别',
          certType: '证件类型',
          certNo: '证件号码',
          jobName: '雇员工种',
          useEmploer: '用工单位',
          address: '用工地点',
          note: '备注',
        },
      });
    }
    queryClient.invalidateQueries({
      queryKey: ['insuranceOrderServices/getInsuranceStaffList'],
    });
    getInsuranceStaffList();
  } catch (error) {}
}
function handleDownloadPerson() {}
function handleDownloadOrder() {}
async function handleDownloadPerson() {
  try {
    if (paginationState.total === 0) {
      Message.warnMessage('没有数据可以导出哦~');
      return;
    }
    let res = await insuranceOrderServices.getInsuranceStaffListExport(
      { id: id },
      {
        responseType: 'blob',
        getResponse: true,
      }
    );
    if (res) {
      downloadFile(res.data, `人员清单`, 'xlsx');
    }
  } catch (error) {}
}
function handleDownloadOrder() {
  downloadFileByUrl(setOSSLink(detail.value?.insureBillUrl));
}
function handleBatchChange() {
  if (
    dayjs(detail.value?.effectEndTime).isBefore(dayjs()) ||
    dayjs(detail.value?.effectEndTime).isSame(dayjs(), 'day')
  ) {
    Message.errorMessage('保险今天到期,无法批改');
    return;
  }
  router.push({
    name: 'BatchChange',
    params: {
      id: id,
    },
    query: {
      insurerName: detail.value?.insurerName ?? '',
      insureBillNo: detail.value?.insureBillNo ?? '',
      effectEndTime: detail.value?.effectEndTime ?? '',
    },
  });
}
const { dialogProps, handleEdit, editForm } = useFormDialog({
  onConfirm: changeInfo,
const { dialogProps, handleEdit, editForm, dialogState } = useFormDialog({
  onConfirm: updateInsuranceStaffInfo,
  defaultFormParams: {
    id: '',
    name: '',
    idNumber: '',
    phone: '',
  },
  closeAfterConfirm: false,
});
function handleChangeInfo(row: API.GetInsuranceStaffPageTemplate) {
  handleEdit({
    id: row.id,
    name: row.name,
    idNumber: row.certNo,
    phone: row.phone,
  });
}
async function updateInsuranceStaffInfo() {
  try {
    let params: API.UpdateInsuranceStaffInfoInput = {
      insurancePolicyId: id,
      id: editForm.id,
      name: editForm.name,
      idNumber: editForm.idNumber,
      phone: editForm.phone,
    };
    let res = await insuranceOrderServices.updateInsuranceStaffInfo(params);
    if (res) {
      Message.successMessage('修改成功');
      dialogState.dialogVisible = false;
      getInsuranceStaffList(paginationState.pageIndex);
    }
  } catch (error) {}
}
const { dialogProps: dialogInsureClaimProps, handleEdit: handleInsureClaimEdit } = useFormDialog({
  defaultFormParams: {
    id: '',
    routeId: '',
    staffList: [] as API.InsuranceClaimDetailOutput[],
  },
});
function handleChangeInfo(row: API.InsuranceOrderListOutput) {
  handleEdit({
    name: row.name,
  });
async function getInsuranceClaimDetailList(id: string) {
  try {
    return await insuranceClaimServices.getInsuranceClaimDetailList({ id: id });
  } catch (error) {}
}
async function changeInfo() {}
function handleInsureClaimDetail(row: API.InsuranceOrderListOutput) {
  router.push({
    name: 'InsuranceClaimDetail',
    params: {
async function handleDetail(row: API.GetInsuranceStaffPageTemplate) {
  try {
    const res = await getInsuranceClaimDetailList(row.id);
    handleInsureClaimEdit({
      id: row.id,
    },
    query: {
      fromRoute: 'InsuranceOrderDetail',
    },
  });
      staffList: res,
      routeId: id,
    });
  } catch (error) {}
}
</script>
<style lang="scss" scoped>
@use '@/style/common.scss' as *;
.full-table-chunk {
  display: flex;
  min-height: 0;
  flex: 1;
  flex-direction: column;
  :deep() {
    .chunk-cell-content {
      display: flex;
      flex-direction: column;
      flex: 1;
      min-height: 0;
    }
  }
  .full-table-chunk-table {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
  }
}
</style>