From 77f32b6d96237dc874ca81c0ecab1a21500cc5ab Mon Sep 17 00:00:00 2001
From: wupengfei <834520024@qq.com>
Date: 星期五, 21 三月 2025 16:31:00 +0800
Subject: [PATCH] feat: init

---
 src/views/Home/BatchChange.vue                              |  228 +++++++
 src/views/Home/components/BatchChangeRecordView.vue         |  156 +++++
 src/views/Home/components/UploadInsurePersonDialog.vue      |  112 +++
 src/services/api/typings.d.ts                               |   47 +
 src/views/Home/components/InsureOrderInfoView.vue           |  328 ++++++++++
 src/views/Home/InsuranceOrderDetail.vue                     |   38 +
 src/views/Home/components/BatchChangeRecordDetailDialog.vue |  151 +++++
 src/views/Home/constants/index.ts                           |  173 ++---
 src/views/Home/components/ChangePersonInfoDialog.vue        |  107 +++
 src/views/Home/components/UploadStampFileDialog.vue         |   95 +++
 src/router/index.ts                                         |   41 +
 src/constants/app.ts                                        |    5 
 src/views/Home/Home.vue                                     |  234 +++----
 src/services/api/InsuranceOrder.ts                          |   45 +
 14 files changed, 1,515 insertions(+), 245 deletions(-)

diff --git a/src/constants/app.ts b/src/constants/app.ts
index f859e59..b435003 100644
--- a/src/constants/app.ts
+++ b/src/constants/app.ts
@@ -1,4 +1 @@
-export const AppType = import.meta.env.VITE_AppType || 'one';
-
-export const isJYB =
-  AppType === 'other' || AppType === 'jx' || AppType === 'jy' || AppType === 'backup';
+export const AppType = import.meta.env.VITE_AppType || 'other';
diff --git a/src/router/index.ts b/src/router/index.ts
index 7d7ffa3..0e33721 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -73,6 +73,12 @@
     component: Layout,
     redirect: '/home',
     alwaysShow: true,
+    meta: {
+      rank: 1001,
+      icon: 'home',
+      title: '淇濆崟绠$悊',
+      rootMenu: true,
+    },
     children: [
       {
         path: 'home',
@@ -80,21 +86,40 @@
         hidden: false,
         component: () => import('@/views/Home/Home.vue'),
         meta: {
-          rank: 10001,
-          title: '棣栭〉',
+          rank: 1001,
+          title: '淇濆崟绠$悊',
           affix: true,
           // rootMenu: true,
           icon: 'home',
         },
       },
+      {
+        path: '/InsuranceOrderDetail/:id',
+        name: 'InsuranceOrderDetail',
+        hidden: true,
+        component: () => import('@/views/Home/InsuranceOrderDetail.vue'),
+        meta: {
+          rank: 10002,
+          title: '淇濆崟璇︽儏',
+          // rootMenu: true,
+          icon: 'home',
+        },
+      },
+      {
+        path: '/BatchChange/:id',
+        name: 'BatchChange',
+        hidden: true,
+        component: () => import('@/views/Home/BatchChange.vue'),
+        meta: {
+          rank: 10002,
+          title: '鎵规敼',
+          // rootMenu: true,
+          icon: 'home',
+        },
+      },
     ],
-    meta: {
-      rank: 1001,
-      icon: 'home',
-      title: '棣栭〉',
-      rootMenu: true,
-    },
   },
+
   {
     path: '/InsuranceClaim',
     redirect: 'noRedirect',
diff --git a/src/services/api/InsuranceOrder.ts b/src/services/api/InsuranceOrder.ts
index 7c965b7..80e6549 100644
--- a/src/services/api/InsuranceOrder.ts
+++ b/src/services/api/InsuranceOrder.ts
@@ -2,6 +2,21 @@
 // @ts-ignore
 import { request } from '@/utils/request';
 
+/** 鎵归噺娣诲姞淇濆崟鏂囦欢 POST /api/InsuranceOrder/AddInsuranceOrderBillFile */
+export async function addInsuranceOrderBillFile(
+  body: API.AddInsuranceOrderBillFile,
+  options?: API.RequestConfig
+) {
+  return request<number>('/api/InsuranceOrder/AddInsuranceOrderBillFile', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json',
+    },
+    data: body,
+    ...(options || {}),
+  });
+}
+
 /** 娣诲姞淇濆崟鏉愭枡 POST /api/InsuranceOrder/AddInsuranceOrderMaterial */
 export async function addInsuranceOrderMaterial(
   body: API.AddInsuranceOrderMaterialInput,
@@ -17,9 +32,9 @@
   });
 }
 
-/** 妫�鏌ュ鍏ヤ繚鍗曟ā鏉� POST /api/InsuranceOrder/CheckImportInsuranceOrderData */
-export async function checkImportInsuranceOrderData(body: string, options?: API.RequestConfig) {
-  return request<number>('/api/InsuranceOrder/CheckImportInsuranceOrderData', {
+/** 鍒犻櫎淇濆崟鏉愭枡 POST /api/InsuranceOrder/DeleteInsuranceOrderMaterial */
+export async function deleteInsuranceOrderMaterial(body: string, options?: API.RequestConfig) {
+  return request<number>('/api/InsuranceOrder/DeleteInsuranceOrderMaterial', {
     method: 'POST',
     headers: {
       'Content-Type': 'application/json',
@@ -29,9 +44,27 @@
   });
 }
 
-/** 鍒犻櫎淇濆崟鏉愭枡 POST /api/InsuranceOrder/DeleteInsuranceOrderMaterial */
-export async function deleteInsuranceOrderMaterial(body: string, options?: API.RequestConfig) {
-  return request<number>('/api/InsuranceOrder/DeleteInsuranceOrderMaterial', {
+/** 鎵归噺鍑忓憳淇濆崟鏁版嵁 POST /api/InsuranceOrder/DownsizingInsuranceOrderData */
+export async function downsizingInsuranceOrderData(
+  body: API.DownsizingInsuranceOrderData,
+  options?: API.RequestConfig
+) {
+  return request<any>('/api/InsuranceOrder/DownsizingInsuranceOrderData', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json',
+    },
+    data: body,
+    ...(options || {}),
+  });
+}
+
+/** 鎵归噺鍑忓憳淇濆崟鏁版嵁鏍¢獙 POST /api/InsuranceOrder/DownsizingInsuranceOrderDataCheck */
+export async function downsizingInsuranceOrderDataCheck(
+  body: API.DownsizingInsuranceOrderData,
+  options?: API.RequestConfig
+) {
+  return request<number>('/api/InsuranceOrder/DownsizingInsuranceOrderDataCheck', {
     method: 'POST',
     headers: {
       'Content-Type': 'application/json',
diff --git a/src/services/api/typings.d.ts b/src/services/api/typings.d.ts
index 3ebe7a9..1f45a49 100644
--- a/src/services/api/typings.d.ts
+++ b/src/services/api/typings.d.ts
@@ -94,6 +94,13 @@
     attachments?: AddInsuranceClaimAttachmentInput[];
   }
 
+  interface AddInsuranceOrderBillFile {
+    /** 淇濆崟鍙� */
+    orderNo?: string;
+    /** 淇濆崟鏂囦欢 */
+    orderBillFile?: string;
+  }
+
   interface AddInsuranceOrderMaterialInput {
     insuranceOrderId?: string;
     /** 鏂囦欢鍚嶇О */
@@ -457,6 +464,12 @@
     clientId?: string;
     /** 瑙掕壊 */
     roleNames?: string[];
+    /** 鏄惁鐞嗚禂鎻愰啋 */
+    sendClaimMessage?: boolean;
+    /** 鏄惁淇濆崟鍒版湡鎻愰啋 */
+    sendBillExpireMessage?: boolean;
+    /** 鏄惁鐭俊鎻愰啋 */
+    isSendMessage?: boolean;
   }
 
   interface CreateOrUpdateRoleInput {
@@ -518,6 +531,15 @@
     dateSeparator?: string;
     shortTimePattern?: string;
     longTimePattern?: string;
+  }
+
+  interface DownsizingInsuranceOrderData {
+    /** 瀵煎叆鍦板潃 */
+    url?: string;
+    /** 淇濆崟鍙� */
+    orderNo?: string;
+    /** 鍑忓憳淇濆崟id */
+    downsizingInsuranceList?: string[];
   }
 
   interface EntityExtensionDto {
@@ -895,6 +917,7 @@
     laborContractEnterprise?: string;
     /** 瀹為檯宸ヤ綔鍗曚綅 */
     workEnterprise?: string;
+    workAddress?: string;
     /** 淇濋櫓璧峰鏃堕棿 */
     insuranceBeginTime?: string;
     insuranceBeginTimeShow?: string;
@@ -905,6 +928,8 @@
     insuredInstitution?: string;
     /** 鎶曚繚鏂规 */
     insuranceScheme?: string;
+    /** 鎶曚繚鏂瑰紡 */
+    insuranceType?: string;
     /** 鍦ㄨ亴鏍囪瘑 */
     onJobFlag?: string;
     /** 鎬у埆 */
@@ -934,6 +959,8 @@
     orderNo?: string;
     /** 淇濆崟鍏宠仈鍞竴瀛楃涓� */
     orderRelevanceStr?: string;
+    /** 淇濆崟鏂囦欢 */
+    orderBillFile?: string;
   }
 
   interface InsuranceOrderListOutputPageOutput {
@@ -1217,6 +1244,8 @@
     condition?: string;
     /** 澧炲噺鍛樻煡璇� */
     onJobFlag?: string;
+    /** 鎶曚繚鏂瑰紡鏌ヨ 鏈堜繚/骞翠繚 */
+    insuranceType?: string;
     importChannel?: string;
   }
 
@@ -1383,6 +1412,12 @@
     phoneNumber: string;
     /** 娓犻亾 */
     channel?: string;
+    /** 鏄惁鐞嗚禂鎻愰啋 */
+    sendClaimMessage?: boolean;
+    /** 鏄惁淇濆崟鍒版湡鎻愰啋 */
+    sendBillExpireMessage?: boolean;
+    /** 鏄惁鐭俊鎻愰啋 */
+    isSendMessage?: boolean;
     /** 瑙掕壊 */
     roleNames?: string[];
   }
@@ -1520,6 +1555,12 @@
     channel?: string;
     /** 鐢ㄦ埛绔疘d */
     clientId?: string;
+    /** 鏄惁鐞嗚禂鎻愰啋 */
+    sendClaimMessage?: boolean;
+    /** 鏄惁淇濆崟鍒版湡鎻愰啋 */
+    sendBillExpireMessage?: boolean;
+    /** 鏄惁鐭俊鎻愰啋 */
+    isSendMessage?: boolean;
     /** 瑙掕壊 */
     roleNames?: string[];
   }
@@ -1538,6 +1579,12 @@
     channel?: string;
     /** 鐢ㄦ埛绔疘d */
     clientId?: string;
+    /** 鏄惁鐞嗚禂鎻愰啋 */
+    sendClaimMessage?: boolean;
+    /** 鏄惁淇濆崟鍒版湡鎻愰啋 */
+    sendBillExpireMessage?: boolean;
+    /** 鏄惁鐭俊鎻愰啋 */
+    isSendMessage?: boolean;
     /** 瑙掕壊 */
     roleNames?: string[];
   }
diff --git a/src/views/Home/BatchChange.vue b/src/views/Home/BatchChange.vue
new file mode 100644
index 0000000..3bda0ec
--- /dev/null
+++ b/src/views/Home/BatchChange.vue
@@ -0,0 +1,228 @@
+<template>
+  <LoadingLayout :loading="state.loading">
+    <AppScrollContainer>
+      <ChunkCell title="1">
+        <template #title>
+          <el-text>{{ `淇濆崟鍙凤細${'958585860689'}` }}</el-text>
+          <el-text>{{ `鎶曚繚浜猴細${'浜哄姏鏃犲咖'}` }}</el-text>
+        </template>
+        <ProForm :model="state.form" ref="formRef" label-width="120px">
+          <ProFormCol>
+            <ProFormColItem :span="8">
+              <ProFormItemV2
+                label="鏈熸湜鐢熸晥鏃ユ湡:"
+                prop="time"
+                :check-rules="[{ message: '璇烽�夋嫨鏃ユ湡' }]"
+              >
+                <ProFormDatePicker
+                  v-model="state.form.time"
+                  type="date"
+                  value-format="YYYY-MM-DD"
+                  placeholder="璇烽�夋嫨鏃ユ湡"
+                ></ProFormDatePicker>
+              </ProFormItemV2>
+            </ProFormColItem>
+          </ProFormCol>
+          <ProFormCol>
+            <ProFormColItem :span="8">
+              <ProFormItemV2 label="" prop="url" label-width="0">
+                <ProFormUpload
+                  v-model:file-url="state.form.url"
+                  :limit="1"
+                  :limitFileSize="10"
+                  accept="xlsx,xls"
+                  :showTip="false"
+                >
+                  <template #default>
+                    <el-button type="primary">鍔犲噺浜�</el-button>
+                    <el-button link type="primary" @click.stop="handleTemplateDownload"
+                      >涓嬭浇妯℃澘</el-button
+                    >
+                  </template>
+                </ProFormUpload>
+              </ProFormItemV2>
+            </ProFormColItem>
+          </ProFormCol>
+          <ProFormCol>
+            <ProFormColItem :span="8">
+              <ProFormItemV2 label="" prop="url" label-width="0">
+                <ProFormUpload
+                  v-model:file-url="state.form.url"
+                  :limit="1"
+                  :limitFileSize="10"
+                  accept="xlsx,xls"
+                  :showTip="false"
+                >
+                  <template #default>
+                    <el-button type="primary">鏇挎崲浜�</el-button>
+                    <el-button link type="primary" @click.stop="handleTemplateDownload"
+                      >涓嬭浇妯℃澘</el-button
+                    >
+                  </template>
+                </ProFormUpload>
+              </ProFormItemV2>
+            </ProFormColItem>
+          </ProFormCol>
+        </ProForm>
+      </ChunkCell>
+      <ChunkCell title="鎵规敼浜哄憳璇︽儏">
+        <template #titleRight>
+          <el-button type="primary" @click="handleClear">娓呯┖鏁版嵁</el-button>
+        </template>
+        <ProTableV2
+          v-bind="proTableProps"
+          :columns="column"
+          :show-operation-column="false"
+          :auto-height="false"
+          ref="proTable"
+          :tableProps="{
+            maxHeight: '400px',
+          }"
+        >
+        </ProTableV2>
+        <div class="chuck-add-or-edit-actions">
+          <el-button class="chuck-add-or-edit-actions" type="primary" @click="handleSubmit"
+            >鎻愪氦</el-button
+          >
+        </div>
+      </ChunkCell>
+    </AppScrollContainer>
+  </LoadingLayout>
+</template>
+
+<script setup lang="ts">
+import {
+  LoadingLayout,
+  AppScrollContainer,
+  ProForm,
+  ProFormItemV2,
+  ChunkCell,
+  ProFormText,
+  ProTableQueryFilterBar,
+  QueryFilterItem,
+  SearchInput,
+  ProFormCol,
+  ProFormColItem,
+  ProFormDatePicker,
+  ProFormInputNumber,
+  useTable,
+  ProTableV2,
+  ProFormRadio,
+  FieldSelect,
+  defineOperationBtns,
+  useFormDialog,
+  ProFormUpload,
+  UploadUserFile,
+} from '@bole-core/components';
+import * as insuranceOrderServices from '@/services/api/InsuranceOrder';
+import { OrderInputType } from '@bole-core/core';
+
+defineOptions({
+  name: 'BatchChange',
+});
+
+const column: API.CustomModuleColumnDto[] = [
+  {
+    id: '1',
+    enCode: 'name',
+    name: '鎵规敼绫诲瀷',
+  },
+  {
+    id: '2',
+    enCode: 'name',
+    name: '濮撳悕',
+  },
+  {
+    id: '3',
+    enCode: 'name',
+    name: '韬唤璇佸彿',
+  },
+  {
+    id: '4',
+    enCode: 'idNumber',
+    name: '闆囧憳宸ョ',
+  },
+  {
+    id: '5',
+    enCode: 'idNumber',
+    name: '鎬у埆',
+  },
+  {
+    id: '6',
+    enCode: 'idNumber',
+    name: '骞撮緞',
+  },
+  {
+    id: '7',
+    enCode: 'idNumber',
+    name: '鍑虹敓鏃ユ湡',
+  },
+  {
+    id: '8',
+    enCode: 'idNumber',
+    name: '鎵嬫満鍙风爜',
+  },
+];
+
+const route = useRoute();
+const id = route.params.id as string;
+const BaseState = {
+  loading: true,
+  form: {
+    time: '',
+    url: [] as UploadUserFile[],
+  },
+};
+
+const state = reactive({ ...BaseState });
+
+const {
+  getDataSource: getBatchRefundInfoDetail,
+  proTableProps,
+  paginationState,
+  extraParamState,
+  reset,
+} = useTable(
+  async ({ pageIndex, pageSize }, extraParamState) => {
+    try {
+      let params: API.QueryInsuranceOrderPageInput = {
+        pageModel: {
+          rows: pageSize,
+          page: pageIndex,
+          orderInput: extraParamState.orderInput,
+        },
+        condition: extraParamState.keyWord,
+        // insurePolicyOperateHistoryId: id,
+      };
+      let res = await insuranceOrderServices.getInsuranceOrderPage(params, {
+        showLoading: !state.loading,
+      });
+      return res;
+    } catch (error) {}
+  },
+  {
+    defaultExtraParams: {
+      keyWord: '',
+      orderInput: [{ property: 'id', order: OrderInputType.Asc }],
+    },
+    columnsRenderProps: {},
+  }
+);
+
+function handleClear() {}
+function handleSubmit() {}
+function handleTemplateDownload() {}
+
+onMounted(async () => {
+  await getBatchRefundInfoDetail();
+  state.loading = false;
+});
+</script>
+
+<style lang="scss" scoped>
+@use '@/style/common.scss' as *;
+
+.chuck-add-or-edit-actions {
+  //   margin-bottom: 20px;
+}
+</style>
diff --git a/src/views/Home/Home.vue b/src/views/Home/Home.vue
index 3111cb1..6f780af 100644
--- a/src/views/Home/Home.vue
+++ b/src/views/Home/Home.vue
@@ -37,7 +37,7 @@
             <SearchInput
               v-model="extraParamState.keyword"
               style="width: 260px"
-              placeholder="濮撳悕/韬唤璇�/鍗曚綅/淇濆崟鍙风瓑"
+              placeholder="鍗曚綅/淇濆崟鍙�/鍙備繚鏈烘瀯"
               @on-click-search="getList"
             >
             </SearchInput>
@@ -53,39 +53,22 @@
             >妯℃澘涓嬭浇</el-button
           >
 
-          <BlFileUpload
-            :limitFileSize="10"
-            accept="xls,xlsx"
-            :showTip="false"
-            :show-file-list="false"
-            :on-success="handleUploadSuccess"
+          <el-button @click="handleUpload()" icon="Upload" type="primary" style="margin-right: 10px"
+            >瀵煎叆</el-button
           >
-            <template #default>
-              <el-button icon="Plus" type="primary">瀵煎叆</el-button>
-            </template>
-          </BlFileUpload>
 
-          <el-button
-            @click="handleEnterpriseBatchRefund()"
-            type="primary"
-            style="margin-right: 10px"
-            >鎵归噺鍑忓憳</el-button
+          <el-button @click="downloadInsureOrder()" type="primary" icon="Download" link
+            >瀵煎嚭淇濆崟鍒楄〃</el-button
           >
-          <el-button
-            @click="handleExport()"
-            icon="Download"
-            type="primary"
-            style="margin-left: 10px"
-            >瀵煎嚭</el-button
+          <el-button @click="downloadInsurePerson()" icon="Download" type="primary" link
+            >瀵煎嚭鍦ㄤ繚浜哄憳</el-button
           >
         </template>
       </ProTableQueryFilterBar>
       <ProTableV2
         v-bind="proTableProps"
-        :columns="HomeColumns"
+        :columns="columns"
         :operationBtns="operationBtns"
-        :show-column-check="true"
-        :column-selectable="columnSelectable"
         ref="proTable"
         :table-props="{
           rowStyle: handleRowStyle,
@@ -94,11 +77,8 @@
       >
       </ProTableV2>
     </AppContainer>
-    <UploadMaterialDialog
-      v-bind="dialogProps"
-      @onAddUpdateMaterial="getList(paginationState.pageIndex)"
-    />
-    <BatchDownsizingDialog v-bind="dialogBatchDownsizingProps" />
+    <UploadInsurePersonDialog v-bind="dialogProps" />
+    <UploadStampFileDialog v-bind="dialogStampFileProps" />
   </LoadingLayout>
 </template>
 
@@ -121,9 +101,9 @@
 } from '@bole-core/components';
 import * as insuranceOrderServices from '@/services/api/InsuranceOrder';
 import { Message, OrderInputType, downloadFileByUrl } from '@bole-core/core';
-import { HomeColumns } from './constants';
-import UploadMaterialDialog from './components/UploadMaterialDialog.vue';
-import BatchDownsizingDialog from './components/BatchDownsizingDialog.vue';
+import { columns } from './constants';
+import UploadInsurePersonDialog from './components/UploadInsurePersonDialog.vue';
+import UploadStampFileDialog from './components/UploadStampFileDialog.vue';
 import { toThousand, format, downloadFile, setOSSLink } from '@/utils';
 import { omit } from 'lodash';
 import { ModelValueType } from 'element-plus';
@@ -154,11 +134,40 @@
       hide: (row: API.InsuranceOrderListOutput) => !row.orderBillFile,
     },
   },
+  {
+    data: {
+      enCode: 'batchBtn',
+      name: '鎵规敼',
+    },
+    emits: {
+      onClick: (role) => handleBatch(role),
+    },
+    // extraProps: {
+    //   hide: (row: API.InsuranceOrderListOutput) => !row.orderBillFile,
+    // },
+  },
+  {
+    data: {
+      enCode: 'uploadStampFileBtn',
+      name: '涓婁紶鐩栫珷鏂囦欢',
+    },
+    emits: {
+      onClick: (role) => handleUploadStampFile(role),
+    },
+    extraProps: {
+      hide: (row: API.InsuranceOrderListOutput) => !row.orderBillFile,
+    },
+  },
+  {
+    data: {
+      enCode: 'detailBtn',
+      name: '璇︽儏',
+    },
+    emits: {
+      onClick: (role) => handleDetail(role),
+    },
+  },
 ]).filter(Boolean);
-
-const columnSelectable = (row: API.InsuranceOrderListOutput) => {
-  return row.onJobFlag === '澧炲憳';
-};
 
 const BaseState = {
   loading: true,
@@ -236,60 +245,36 @@
   return params;
 }
 
-const queryClient = useQueryClient();
-
-async function handleUploadSuccess(response: UploadUserFile) {
-  try {
-    let res = await insuranceOrderServices.importInsuranceOrderData(response.url, {
-      getResponse: true,
-      responseType: 'blob',
-    });
-    if (res?.data?.size) {
-      await Message.tipMessage('瀛樺湪閿欒鏁版嵁锛屾槸鍚﹀鍑猴紵');
-      downloadFile(res.data, `閿欒浜哄憳鍚嶅崟`, 'xlsx');
-      // XLSXUtils.exportToXLSX({
-      //   workbookDataList: res,
-      //   fileName: '閿欒浜哄憳鍚嶅崟',
-      //   workbookHeaderMap: {
-      //     ...omit(Object.fromEntries(HomeColumns.map((x) => [x.enCode, x.name])), [
-      //       'channel',
-      //       'salesmanName',
-      //       'createTime',
-      //     ]),
-      //     erroMsg: '澶囨敞',
-      //   },
-      // });
-    }
-    queryClient.invalidateQueries({
-      queryKey: ['insuranceOrderServices/getInsuranceOrderListByOrderRelevance'],
-    });
-    getList();
-  } catch (error) {}
-}
-
-const { dialogProps, handleAdd } = useFormDialog({
+const { dialogProps, handleAdd, editForm } = useFormDialog({
+  onConfirm: uploadInsurePerson,
   defaultFormParams: {
-    id: '',
-    materialName: '',
+    orderNo: '',
     url: [] as UploadUserFile[],
   },
 });
 
-function openDialog(row: API.InsuranceOrderListOutput) {
+function handleUpload() {
   handleAdd({
-    id: row.id,
+    orderNo: '',
+    url: [] as UploadUserFile[],
   });
 }
 
-const router = useRouter();
-function goDetail(row: API.InsuranceOrderListOutput) {
-  router.push({
-    name: 'InsuranceClaimDetail',
-    params: {
-      id: row.id,
-    },
-  });
+async function uploadInsurePerson() {
+  try {
+    let params = {
+      orderNo: editForm.orderNo,
+      url: editForm.url?.[0]?.path,
+    };
+    // let res = await insuranceOrderServices.uploadStampFile(params);
+    // if (res) {
+    //   Message.successMessage('涓婁紶鎴愬姛');
+    //   getList(paginationState.pageIndex);
+    // }
+  } catch (error) {}
 }
+
+const router = useRouter();
 
 async function handleExport() {
   try {
@@ -323,72 +308,59 @@
   }
 }
 
-const proTable = ref<InstanceType<typeof ProTableV2>>();
-function handleEnterpriseBatchRefund() {
-  if (proTableProps.value.tableData.length) {
-    const res: API.InsuranceOrderListOutput[] = proTable.value.innerTableRef.getSelectionRows();
-    if (res.length > 0) {
-      const orderNos = _.uniq(res.map((x) => x.orderNo));
-      if (orderNos.length > 1) {
-        Message.errorMessage('瀛樺湪涓嶅悓鐨勪繚鍗曞彿锛屾棤娉曟壒閲忓噺鍛�');
-        return;
-      }
-      handleBatchDownsizing(res);
-    } else {
-      Message.errorMessage('璇峰厛鍕鹃�夊噺鍛樹汉鍛�');
-    }
-  } else {
-    Message.errorMessage('鏆傛棤鏁版嵁');
-  }
-}
-
 const {
-  dialogProps: dialogBatchDownsizingProps,
-  handleAdd: handleBatchDownsizingAdd,
-  editForm: batchDownsizingForm,
+  dialogProps: dialogStampFileProps,
+  handleEdit: handleStampFileEdit,
+  editForm: stampFileForm,
 } = useFormDialog({
-  onConfirm: downsizingInsuranceOrderData,
+  onConfirm: uploadStampFile,
   defaultFormParams: {
-    orderNo: '',
-    checkOrderNo: '',
+    id: '',
     url: [] as UploadUserFile[],
-    downsizingInsuranceList: [] as string[],
   },
 });
 
-function handleBatchDownsizing(res: API.InsuranceOrderListOutput[]) {
-  handleBatchDownsizingAdd({
-    checkOrderNo: res[0]?.orderNo,
-    downsizingInsuranceList: res.map((x) => x.id),
+function handleUploadStampFile(row: API.InsuranceOrderListOutput) {
+  handleStampFileEdit({
+    id: row.id,
+    url: [] as UploadUserFile[],
   });
 }
 
-async function downsizingInsuranceOrderData() {
+async function uploadStampFile() {
   try {
-    let params: API.DownsizingInsuranceOrderData = {
-      orderNo: batchDownsizingForm.checkOrderNo,
-      downsizingInsuranceList: batchDownsizingForm.downsizingInsuranceList,
-      url: batchDownsizingForm.url?.[0]?.path ?? '',
+    let params = {
+      id: stampFileForm.id,
+      url: stampFileForm.url?.[0]?.path,
     };
-    let res = await insuranceOrderServices.downsizingInsuranceOrderDataCheck(params);
-    if (res) {
-      let downRes = await insuranceOrderServices.downsizingInsuranceOrderData(params, {
-        getResponse: true,
-        responseType: 'blob',
-      });
-      if (downRes?.data?.size) {
-        await Message.tipMessage('瀛樺湪閿欒鏁版嵁锛屾槸鍚﹀鍑猴紵');
-        downloadFile(downRes.data, `閿欒浜哄憳鍚嶅崟`, 'xlsx');
-      }
-      queryClient.invalidateQueries({
-        queryKey: ['insuranceOrderServices/getInsuranceOrderListByOrderRelevance'],
-      });
-      getList(paginationState.pageIndex);
-    }
+    // let res = await insuranceOrderServices.uploadStampFile(params);
+    // if (res) {
+    //   Message.successMessage('涓婁紶鎴愬姛');
+    //   getList(paginationState.pageIndex);
+    // }
   } catch (error) {}
 }
 
 function handleDownloadOrderNo(row: API.InsuranceOrderListOutput) {
   downloadFileByUrl(setOSSLink(row.orderBillFile));
 }
+
+function handleDetail(row: API.InsuranceOrderListOutput) {
+  router.push({
+    name: 'InsuranceOrderDetail',
+    params: {
+      id: row.id,
+    },
+  });
+}
+function handleBatch(row: API.InsuranceOrderListOutput) {
+  router.push({
+    name: 'BatchChange',
+    params: {
+      id: row.id,
+    },
+  });
+}
+function downloadInsureOrder() {}
+function downloadInsurePerson() {}
 </script>
diff --git a/src/views/Home/InsuranceOrderDetail.vue b/src/views/Home/InsuranceOrderDetail.vue
new file mode 100644
index 0000000..e2c745b
--- /dev/null
+++ b/src/views/Home/InsuranceOrderDetail.vue
@@ -0,0 +1,38 @@
+<template>
+  <LoadingLayout>
+    <AppScrollContainer>
+      <ProTabs v-model="state.tabType" hasBorder>
+        <ProTabPane lazy label="淇濆崟淇℃伅" :name="InsureOrderTabType.InsureOrderInfo">
+          <InsureOrderInfoView />
+        </ProTabPane>
+        <ProTabPane lazy label="鎵规敼璁板綍" :name="InsureOrderTabType.BatchOrder">
+          <BatchChangeRecordView />
+        </ProTabPane>
+      </ProTabs>
+    </AppScrollContainer>
+  </LoadingLayout>
+</template>
+
+<script setup lang="ts">
+import { AppScrollContainer, ProTabs, ProTabPane } from '@bole-core/components';
+import InsureOrderInfoView from './components/InsureOrderInfoView.vue';
+import BatchChangeRecordView from './components/BatchChangeRecordView.vue';
+
+defineOptions({
+  name: 'InsuranceOrderDetail',
+});
+
+enum InsureOrderTabType {
+  InsureOrderInfo = 1,
+  BatchOrder = 2,
+}
+
+const state = reactive({
+  activeIndex: 1,
+  tabType: InsureOrderTabType.InsureOrderInfo,
+});
+</script>
+
+<style lang="scss" scoped>
+@use '@/style/common.scss' as *;
+</style>
diff --git a/src/views/Home/components/BatchChangeRecordDetailDialog.vue b/src/views/Home/components/BatchChangeRecordDetailDialog.vue
new file mode 100644
index 0000000..486371e
--- /dev/null
+++ b/src/views/Home/components/BatchChangeRecordDetailDialog.vue
@@ -0,0 +1,151 @@
+<template>
+  <ProDialog title="鎵规敼淇℃伅" v-model="innerVisible" width="1200px" destroy-on-close>
+    <ProDialogTableWrapper :height="400">
+      <ProTableV2
+        :table-data="proTableProps.tableData"
+        :columns="column"
+        :show-operation-column="false"
+      >
+      </ProTableV2>
+    </ProDialogTableWrapper>
+  </ProDialog>
+</template>
+
+<script setup lang="ts">
+import { ProDialog, ProTableV2, ProDialogTableWrapper, useTable } from '@bole-core/components';
+import * as insuranceOrderServices from '@/services/api/InsuranceOrder';
+import { OrderInputType } from '@bole-core/core';
+
+defineOptions({
+  name: 'BatchChangeRecordDetailDialog',
+});
+
+type Props = {
+  modelValue: boolean;
+  form?: {
+    id: string;
+  };
+};
+
+const props = withDefaults(defineProps<Props>(), {
+  modelValue: false,
+});
+
+const emit = defineEmits<{
+  (e: 'update:modelValue', value: boolean): void;
+  (e: 'onCancel'): void;
+}>();
+
+const column: API.CustomModuleColumnDto[] = [
+  {
+    id: '1',
+    enCode: 'name',
+    name: '鎵规敼绫诲瀷',
+    width: 120,
+  },
+  {
+    id: '2',
+    enCode: 'name',
+    name: '濮撳悕',
+    width: 120,
+  },
+  {
+    id: '3',
+    enCode: 'name',
+    name: '韬唤璇佸彿',
+    width: 120,
+  },
+  {
+    id: '4',
+    enCode: 'name',
+    name: '闆囧憳宸ョ',
+    width: 120,
+  },
+  {
+    id: '5',
+    enCode: 'name',
+    name: '鎬у埆',
+    width: 120,
+  },
+  {
+    id: '6',
+    enCode: 'name',
+    name: '骞撮緞',
+    width: 120,
+  },
+  {
+    id: '7',
+    enCode: 'name',
+    name: '鍑虹敓鏃ユ湡',
+    width: 120,
+  },
+  {
+    id: '8',
+    enCode: 'name',
+    name: '鐢佃瘽鍙风爜',
+    width: 120,
+  },
+  {
+    id: '9',
+    enCode: 'name',
+    name: '淇敼鍐呭',
+    width: 120,
+  },
+];
+
+const innerVisible = computed({
+  get() {
+    return props.modelValue;
+  },
+  set(val) {
+    emit('update:modelValue', val);
+  },
+});
+
+watch(
+  () => props.modelValue,
+  (val) => {
+    if (val) {
+      getBatchRefundInfoDetail();
+    }
+  },
+  {
+    immediate: true,
+  }
+);
+
+const {
+  getDataSource: getBatchRefundInfoDetail,
+  proTableProps,
+  paginationState,
+  extraParamState,
+  reset,
+} = useTable(
+  async ({ pageIndex, pageSize }, extraParamState) => {
+    try {
+      let params: API.QueryInsuranceOrderPageInput = {
+        pageModel: {
+          rows: pageSize,
+          page: pageIndex,
+          orderInput: extraParamState.orderInput,
+        },
+        condition: extraParamState.keyWord,
+        // insurePolicyOperateHistoryId: id,
+      };
+      let res = await insuranceOrderServices.getInsuranceOrderPage(params);
+      return res;
+    } catch (error) {}
+  },
+  {
+    defaultExtraParams: {
+      keyWord: '',
+      orderInput: [{ property: 'id', order: OrderInputType.Asc }],
+    },
+    columnsRenderProps: {},
+  }
+);
+</script>
+
+<style lang="scss" scoped>
+@use '@/style/common.scss' as *;
+</style>
diff --git a/src/views/Home/components/BatchChangeRecordView.vue b/src/views/Home/components/BatchChangeRecordView.vue
new file mode 100644
index 0000000..c79d563
--- /dev/null
+++ b/src/views/Home/components/BatchChangeRecordView.vue
@@ -0,0 +1,156 @@
+<template>
+  <AppContainer>
+    <ProTableV2
+      v-bind="proTableProps"
+      :columns="column"
+      :operationBtns="operationBtns"
+      :autoHeight="false"
+      :tableProps="{
+        maxHeight: '400px',
+      }"
+    >
+    </ProTableV2>
+    <BatchChangeRecordDetailDialog v-bind="dialogProps"></BatchChangeRecordDetailDialog>
+  </AppContainer>
+</template>
+
+<script setup lang="ts">
+import {
+  AppContainer,
+  useTable,
+  ProTableV2,
+  defineOperationBtns,
+  useFormDialog,
+} from '@bole-core/components';
+import * as insuranceOrderServices from '@/services/api/InsuranceOrder';
+import { OrderInputType } from '@bole-core/core';
+import BatchChangeRecordDetailDialog from './BatchChangeRecordDetailDialog.vue';
+
+defineOptions({
+  name: 'BatchChangeRecordView',
+});
+
+const column: API.CustomModuleColumnDto[] = [
+  {
+    id: '1',
+    enCode: 'name',
+    name: '鎵瑰崟鍙�',
+  },
+  {
+    id: '2',
+    enCode: 'name',
+    name: '鎵规敼绫诲瀷',
+  },
+  {
+    id: '3',
+    enCode: 'name',
+    name: '鐢宠鏃ユ湡',
+  },
+  {
+    id: '4',
+    enCode: 'idNumber',
+    name: '鎵规敼鐢熸晥鏃ユ湡',
+  },
+  {
+    id: '5',
+    enCode: 'idNumber',
+    name: '鍦ㄤ繚浜烘暟',
+  },
+  {
+    id: '6',
+    enCode: 'idNumber',
+    name: '鍘熷湪淇濅汉鏁�',
+  },
+  {
+    id: '7',
+    enCode: 'idNumber',
+    name: '鏂板',
+  },
+  {
+    id: '8',
+    enCode: 'idNumber',
+    name: '鍑忓皯',
+  },
+  {
+    id: '9',
+    enCode: 'idNumber',
+    name: '鎵瑰崟鐘舵��',
+  },
+];
+
+const operationBtns = defineOperationBtns([
+  {
+    data: {
+      enCode: 'detailBtn',
+      name: '璇︽儏',
+    },
+    emits: {
+      onClick: (role) => handleDetail(role),
+    },
+    // extraProps: {
+    //   hide: (row: API.InsuranceOrderListOutput) => !row.orderBillFile,
+    // },
+  },
+]);
+
+const route = useRoute();
+const id = route.params.id as string;
+const BaseState = {
+  loading: true,
+};
+
+const state = reactive({ ...BaseState });
+
+const {
+  getDataSource: getBatchRefundInfoDetail,
+  proTableProps,
+  paginationState,
+  extraParamState,
+  reset,
+} = useTable(
+  async ({ pageIndex, pageSize }, extraParamState) => {
+    try {
+      let params: API.QueryInsuranceOrderPageInput = {
+        pageModel: {
+          rows: pageSize,
+          page: pageIndex,
+          orderInput: extraParamState.orderInput,
+        },
+        condition: extraParamState.keyWord,
+        // insurePolicyOperateHistoryId: id,
+      };
+      let res = await insuranceOrderServices.getInsuranceOrderPage(params, {
+        showLoading: !state.loading,
+      });
+      return res;
+    } catch (error) {}
+  },
+  {
+    defaultExtraParams: {
+      keyWord: '',
+      orderInput: [{ property: 'id', order: OrderInputType.Asc }],
+    },
+    columnsRenderProps: {},
+  }
+);
+
+const { dialogProps, handleEdit } = useFormDialog({
+  defaultFormParams: {
+    id: '',
+  },
+});
+
+function handleDetail(row: API.InsuranceOrderListOutput) {
+  handleEdit({
+    id: row.id,
+  });
+}
+
+onMounted(() => {
+  getBatchRefundInfoDetail();
+});
+</script>
+
+<style lang="scss" scoped>
+@use '@/style/common.scss' as *;
+</style>
diff --git a/src/views/Home/components/ChangePersonInfoDialog.vue b/src/views/Home/components/ChangePersonInfoDialog.vue
new file mode 100644
index 0000000..7fc6898
--- /dev/null
+++ b/src/views/Home/components/ChangePersonInfoDialog.vue
@@ -0,0 +1,107 @@
+<template>
+  <ProDialog
+    title="淇敼淇℃伅"
+    v-model="innerVisible"
+    destroy-on-close
+    draggable
+    bodyNoPaddingBottom
+    @close="onDialogClose"
+    width="700px"
+  >
+    <el-text type="danger"
+      >*韬唤璇佸彿涓庝繚闄╀汉濮撳悕涓嶈兘鍚屾椂鍙樻洿锛屽彧鑳戒慨鏀瑰叾涓竴椤癸紝涓斾粎鑳戒慨鏀逛竴娆�</el-text
+    >
+    <ProForm :model="innerForm" ref="dialogForm" label-width="100px" style="margin-top: 20px">
+      <ProFormItemV2 label="濮撳悕锛�" prop="name" :check-rules="[{ message: '璇疯緭鍏ュ鍚�' }]">
+        <ProFormText
+          placeholder="璇疯緭鍏ュ鍚�"
+          v-model.trim="innerForm.name"
+          :maxlength="30"
+        ></ProFormText>
+      </ProFormItemV2>
+      <ProFormItemV2 label="韬唤璇佸彿锛�" prop="name" :check-rules="[{ message: '璇疯緭鍏ヨ韩浠借瘉鍙�' }]">
+        <ProFormText
+          placeholder="璇疯緭鍏ヨ韩浠借瘉鍙�"
+          v-model.trim="innerForm.name"
+          :maxlength="30"
+        ></ProFormText>
+      </ProFormItemV2>
+      <ProFormItemV2 label="鎵嬫満鍙凤細" prop="name" :check-rules="[{ message: '璇疯緭鍏ユ墜鏈哄彿' }]">
+        <ProFormText
+          placeholder="璇疯緭鍏ユ墜鏈哄彿"
+          v-model.trim="innerForm.name"
+          :maxlength="30"
+        ></ProFormText>
+      </ProFormItemV2>
+    </ProForm>
+    <template #footer>
+      <span class="dialog-footer">
+        <el-button @click="emit('onCancel')">鍙� 娑�</el-button>
+        <el-button type="primary" @click="handleConfirm">纭� 瀹�</el-button>
+      </span>
+    </template>
+  </ProDialog>
+</template>
+
+<script setup lang="ts">
+import { ProDialog, ProForm, ProFormItemV2, ProFormText } from '@bole-core/components';
+import { FormInstance } from 'element-plus';
+
+defineOptions({
+  name: 'ChangePersonInfoDialog',
+});
+
+type Props = {
+  modelValue: boolean;
+  form?: {
+    name: string;
+  };
+};
+
+const props = withDefaults(defineProps<Props>(), {
+  modelValue: false,
+});
+
+const emit = defineEmits<{
+  (e: 'update:modelValue', value: boolean): void;
+  (e: 'update:form', value: Props['form']): void;
+  (e: 'onConfirm'): void;
+  (e: 'onCancel'): void;
+}>();
+
+const innerVisible = computed({
+  get() {
+    return props.modelValue;
+  },
+  set(val) {
+    emit('update:modelValue', val);
+  },
+});
+
+const innerForm = computed({
+  get() {
+    return props.form;
+  },
+  set(val) {
+    emit('update:form', val);
+  },
+});
+
+const dialogForm = ref<FormInstance>();
+
+function onDialogClose() {
+  if (!dialogForm.value) return;
+  dialogForm.value.resetFields();
+}
+
+function handleConfirm() {
+  if (!dialogForm.value) return;
+  dialogForm.value.validate((valid) => {
+    if (valid) {
+      emit('onConfirm');
+    } else {
+      return;
+    }
+  });
+}
+</script>
diff --git a/src/views/Home/components/InsureOrderInfoView.vue b/src/views/Home/components/InsureOrderInfoView.vue
new file mode 100644
index 0000000..fba6353
--- /dev/null
+++ b/src/views/Home/components/InsureOrderInfoView.vue
@@ -0,0 +1,328 @@
+<template>
+  <AppScrollContainer>
+    <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>
+          </ProFormColItem>
+          <ProFormColItem :span="8">
+            <ProFormItemV2 label="鐢熸晥鐘舵��:" prop="insuranceTypeCode">
+              <ProFormRadio v-model="detail.insuranceType" :value-enum="insuranceTypeText" />
+            </ProFormItemV2>
+          </ProFormColItem>
+        </ProFormCol>
+        <ProFormCol>
+          <ProFormColItem :span="8">
+            <ProFormItemV2 label="淇濋櫓璧锋湡:" prop="applyTime">
+              <ProFormDatePicker v-model.trim="detail.createTime" format="YYYY-MM-DD HH:mm" />
+            </ProFormItemV2>
+          </ProFormColItem>
+          <ProFormColItem :span="8">
+            <ProFormItemV2 label="淇濋櫓姝㈡湡:" prop="insuranceTypeCode">
+              <ProFormDatePicker v-model.trim="detail.createTime" format="YYYY-MM-DD HH:mm" />
+            </ProFormItemV2>
+          </ProFormColItem>
+          <ProFormColItem :span="8">
+            <ProFormItemV2 label="鎶曚繚鏂瑰紡:" prop="insureWay">
+              <ProFormRadio v-model="detail.insuranceType" :value-enum="insuranceTypeText" />
+            </ProFormItemV2>
+          </ProFormColItem>
+        </ProFormCol>
+        <ProFormCol>
+          <ProFormColItem :span="8">
+            <ProFormItemV2 label="鍙備繚鏈烘瀯:" prop="applyTime">
+              <ProFormText v-model.trim="detail.orderNo" />
+            </ProFormItemV2>
+          </ProFormColItem>
+          <ProFormColItem :span="8">
+            <ProFormItemV2 label="鎶曚繚鏂规:" prop="applyTime">
+              <ProFormText v-model.trim="detail.orderNo" />
+            </ProFormItemV2>
+          </ProFormColItem>
+          <ProFormColItem :span="8">
+            <ProFormItemV2 label="鎶曚繚浜烘暟:" prop="numberOfFailed">
+              <ProFormInputNumber v-model.trim="detail.incDecAmount" unit="浜�" />
+            </ProFormItemV2>
+          </ProFormColItem>
+        </ProFormCol>
+        <ProFormCol>
+          <ProFormColItem :span="8">
+            <ProFormItemV2 label="鎶曚繚浜�:" prop="companyName">
+              <ProFormText v-model.trim="detail.orderNo" />
+            </ProFormItemV2>
+          </ProFormColItem>
+          <ProFormColItem :span="8">
+            <ProFormItemV2 label="琚繚浜�:" prop="insuranceTypeCode">
+              <ProFormText v-model.trim="detail.orderNo" />
+            </ProFormItemV2>
+          </ProFormColItem>
+        </ProFormCol>
+      </ProForm>
+    </ChunkCell>
+    <ChunkCell title="浜哄憳淇℃伅">
+      <template #titleRight>
+        <el-button type="primary" @click="handleBatchChange">鎵规敼鐢宠</el-button>
+      </template>
+      <ProTableQueryFilterBar @on-reset="reset">
+        <template #query>
+          <QueryFilterItem>
+            <SearchInput
+              v-model="extraParamState.keyWord"
+              style="width: 300px"
+              placeholder="浜哄憳濮撳悕/韬唤璇佸彿/鎵嬫満鍙�"
+              @on-click-search="getBatchRefundInfoDetail"
+            >
+            </SearchInput>
+          </QueryFilterItem>
+        </template>
+        <template #btn>
+          <el-button @click="handleTemplateDownload()" icon="Download" type="primary"
+            >妯℃澘涓嬭浇</el-button
+          >
+          <el-button @click="handleImport()" icon="Download" type="primary">瀵煎叆</el-button>
+          <el-button @click="handleClear()" icon="Download" type="primary">娓呯┖鏁版嵁</el-button>
+          <el-button @click="handleDownloadPerson()" icon="Download" type="primary"
+            >浜哄憳娓呭崟涓嬭浇</el-button
+          >
+          <el-button @click="handleDownloadOrder()" icon="Download" type="primary"
+            >淇濆崟涓嬭浇</el-button
+          >
+        </template>
+      </ProTableQueryFilterBar>
+      <ProTableV2
+        v-bind="proTableProps"
+        :columns="column"
+        :operationBtns="operationBtns"
+        :auto-height="false"
+        ref="proTable"
+        :tableProps="{
+          maxHeight: '400px',
+        }"
+      >
+      </ProTableV2>
+    </ChunkCell>
+    <ChangePersonInfoDialog v-bind="dialogProps"></ChangePersonInfoDialog>
+  </AppScrollContainer>
+</template>
+
+<script setup lang="ts">
+import {
+  LoadingLayout,
+  AppScrollContainer,
+  ProForm,
+  ProFormItemV2,
+  ChunkCell,
+  ProFormText,
+  ProTableQueryFilterBar,
+  QueryFilterItem,
+  SearchInput,
+  ProFormCol,
+  ProFormColItem,
+  ProFormDatePicker,
+  ProFormInputNumber,
+  useTable,
+  ProTableV2,
+  ProFormRadio,
+  FieldSelect,
+  defineOperationBtns,
+  useFormDialog,
+} from '@bole-core/components';
+import { insuranceTypeText } from '@/constants';
+import ChangePersonInfoDialog from './ChangePersonInfoDialog.vue';
+import * as insuranceOrderServices from '@/services/api/InsuranceOrder';
+import { useQuery, useQueryClient } from '@tanstack/vue-query';
+import { OrderInputType } from '@bole-core/core';
+
+defineOptions({
+  name: 'InsureOrderInfoView',
+});
+
+const column: API.CustomModuleColumnDto[] = [
+  {
+    id: '1',
+    enCode: 'name',
+    name: '濮撳悕',
+  },
+  {
+    id: '2',
+    enCode: 'name',
+    name: '鎬у埆',
+  },
+  {
+    id: '3',
+    enCode: 'name',
+    name: '璇佷欢绫诲瀷',
+  },
+  {
+    id: '4',
+    enCode: 'idNumber',
+    name: '璇佷欢鍙风爜',
+  },
+  {
+    id: '5',
+    enCode: 'idNumber',
+    name: '闆囧憳宸ョ',
+  },
+  {
+    id: '6',
+    enCode: 'idNumber',
+    name: '鐢ㄥ伐鍗曚綅',
+  },
+  {
+    id: '7',
+    enCode: 'idNumber',
+    name: '鐢ㄥ伐鍦扮偣',
+  },
+  {
+    id: '8',
+    enCode: 'idNumber',
+    name: '骞撮緞',
+  },
+  {
+    id: '9',
+    enCode: 'idNumber',
+    name: '鍑虹敓鏃ユ湡',
+  },
+  {
+    id: '10',
+    enCode: 'idNumber',
+    name: '鎵嬫満鍙风爜',
+  },
+  {
+    id: '11',
+    enCode: 'idNumber',
+    name: '鐞嗚禂',
+  },
+];
+
+const operationBtns = defineOperationBtns([
+  {
+    data: {
+      enCode: 'changeInfoBtn',
+      name: '淇敼淇℃伅',
+    },
+    emits: {
+      onClick: (role) => handleChangeInfo(role),
+    },
+    extraProps: {
+      hide: (row: API.InsuranceOrderListOutput) => !row.orderBillFile,
+    },
+  },
+  {
+    data: {
+      enCode: 'insureClaimDetailBtn',
+      name: '鐞嗚禂璇︽儏',
+    },
+    emits: {
+      onClick: (role) => handleInsureClaimDetail(),
+    },
+    extraProps: {
+      hide: (row: API.InsuranceOrderListOutput) => !row.orderBillFile,
+    },
+  },
+]);
+
+const route = useRoute();
+const router = useRouter();
+const id = route.params.id as string;
+const BaseState = {
+  loading: true,
+};
+
+const state = reactive({ ...BaseState });
+
+const { data: detail, isLoading } = useQuery({
+  queryKey: ['insuranceOrderServices/getInsuranceOrderDetail', id],
+  queryFn: async () => {
+    return await insuranceOrderServices.getInsuranceOrderDetail(
+      { id: id },
+      {
+        showLoading: false,
+      }
+    );
+  },
+  placeholderData: () => ({} as API.InsuranceOrderListOutput),
+  enabled: !!id,
+});
+
+const queryClient = useQueryClient();
+
+onMounted(async () => {
+  await queryClient.ensureQueryData({
+    queryKey: ['insuranceOrderServices/getInsuranceOrderDetail', id],
+  });
+  getBatchRefundInfoDetail();
+});
+
+const {
+  getDataSource: getBatchRefundInfoDetail,
+  proTableProps,
+  paginationState,
+  extraParamState,
+  reset,
+} = useTable(
+  async ({ pageIndex, pageSize }, extraParamState) => {
+    try {
+      let params: API.QueryInsuranceOrderPageInput = {
+        pageModel: {
+          rows: pageSize,
+          page: pageIndex,
+          orderInput: extraParamState.orderInput,
+        },
+        condition: extraParamState.keyWord,
+        // insurePolicyOperateHistoryId: id,
+      };
+      let res = await insuranceOrderServices.getInsuranceOrderPage(params, {
+        showLoading: !state.loading,
+      });
+      return res;
+    } catch (error) {}
+  },
+  {
+    defaultExtraParams: {
+      keyWord: '',
+      orderInput: [{ property: 'id', order: OrderInputType.Asc }],
+    },
+    columnsRenderProps: {},
+  }
+);
+
+function handleTemplateDownload() {}
+function handleClear() {}
+function handleImport() {}
+
+function handleDownloadPerson() {}
+function handleDownloadOrder() {}
+function handleBatchChange() {
+  router.push({
+    name: 'BatchChange',
+    params: {
+      id: id,
+    },
+  });
+}
+
+const { dialogProps, handleEdit, editForm } = useFormDialog({
+  onConfirm: changeInfo,
+  defaultFormParams: {
+    name: '',
+  },
+});
+
+function handleChangeInfo(row: API.InsuranceOrderListOutput) {
+  handleEdit({
+    name: row.name,
+  });
+}
+
+async function changeInfo() {}
+
+function handleInsureClaimDetail() {}
+</script>
+
+<style lang="scss" scoped>
+@use '@/style/common.scss' as *;
+</style>
diff --git a/src/views/Home/components/UploadInsurePersonDialog.vue b/src/views/Home/components/UploadInsurePersonDialog.vue
new file mode 100644
index 0000000..ffba7d8
--- /dev/null
+++ b/src/views/Home/components/UploadInsurePersonDialog.vue
@@ -0,0 +1,112 @@
+<template>
+  <ProDialog
+    title="涓婁紶鎶曚繚浜哄憳娓呭崟"
+    v-model="innerVisible"
+    destroy-on-close
+    draggable
+    bodyNoPaddingBottom
+    @close="onDialogClose"
+  >
+    <ProForm :model="innerForm" ref="dialogForm" label-width="120px">
+      <ProFormItemV2
+        label="鎵规鍙凤細"
+        prop="materialName"
+        :check-rules="[{ message: '璇疯緭鍏ユ壒娆″彿' }]"
+      >
+        <ProFormText
+          placeholder="璇疯緭鍏ユ壒娆″彿"
+          v-model.trim="innerForm.orderNo"
+          :maxlength="30"
+        ></ProFormText>
+      </ProFormItemV2>
+      <ProFormItemV2
+        label="涓婁紶鏂囦欢锛�"
+        prop="url"
+        :check-rules="[{ message: '璇蜂笂浼犳枃浠�', type: 'upload' }]"
+      >
+        <ProFormUpload
+          v-model:file-url="innerForm.url"
+          :limit="1"
+          :limitFileSize="10"
+          accept="xlsx,xls"
+        ></ProFormUpload>
+      </ProFormItemV2>
+    </ProForm>
+    <template #footer>
+      <span class="dialog-footer">
+        <el-button type="primary" @click="handleConfirm">纭� 瀹�</el-button>
+      </span>
+    </template>
+  </ProDialog>
+</template>
+
+<script setup lang="ts">
+import {
+  ProDialog,
+  UploadUserFile,
+  ProForm,
+  ProFormItemV2,
+  ProFormText,
+  ProFormUpload,
+} from '@bole-core/components';
+import { FormInstance } from 'element-plus';
+
+defineOptions({
+  name: 'UploadInsurePersonDialog',
+});
+
+type Props = {
+  modelValue: boolean;
+  form?: {
+    orderNo: string;
+    url: UploadUserFile[];
+  };
+};
+
+const props = withDefaults(defineProps<Props>(), {
+  modelValue: false,
+});
+
+const emit = defineEmits<{
+  (e: 'update:modelValue', value: boolean): void;
+  (e: 'update:form', value: Props['form']): void;
+  (e: 'onConfirm'): void;
+  (e: 'onCancel'): void;
+}>();
+
+const innerVisible = computed({
+  get() {
+    return props.modelValue;
+  },
+  set(val) {
+    emit('update:modelValue', val);
+  },
+});
+
+const innerForm = computed({
+  get() {
+    return props.form;
+  },
+  set(val) {
+    emit('update:form', val);
+  },
+});
+
+const dialogForm = ref<FormInstance>();
+
+function onDialogClose() {
+  if (!dialogForm.value) return;
+  dialogForm.value.resetFields();
+}
+
+function handleConfirm() {
+  if (!dialogForm.value) return;
+  dialogForm.value.validate((valid) => {
+    if (valid) {
+      emit('onConfirm');
+    } else {
+      return;
+    }
+  });
+}
+</script>
diff --git a/src/views/Home/components/UploadStampFileDialog.vue b/src/views/Home/components/UploadStampFileDialog.vue
new file mode 100644
index 0000000..2b3d93d
--- /dev/null
+++ b/src/views/Home/components/UploadStampFileDialog.vue
@@ -0,0 +1,95 @@
+<template>
+  <ProDialog
+    title="涓婁紶鐩栫珷鏂囦欢"
+    v-model="innerVisible"
+    destroy-on-close
+    draggable
+    bodyNoPaddingBottom
+    @close="onDialogClose"
+  >
+    <ProForm :model="innerForm" ref="dialogForm" label-width="120px">
+      <ProFormItemV2
+        label="涓婁紶鏂囦欢锛�"
+        prop="url"
+        :check-rules="[{ message: '璇蜂笂浼犳枃浠�', type: 'upload' }]"
+      >
+        <ProFormUpload v-model:file-url="innerForm.url" accept="pdf,jpg,jpeg,png"></ProFormUpload>
+      </ProFormItemV2>
+    </ProForm>
+    <template #footer>
+      <span class="dialog-footer">
+        <el-button type="primary" @click="handleConfirm">纭� 瀹�</el-button>
+      </span>
+    </template>
+  </ProDialog>
+</template>
+
+<script setup lang="ts">
+import {
+  ProDialog,
+  UploadUserFile,
+  ProForm,
+  ProFormItemV2,
+  ProFormUpload,
+} from '@bole-core/components';
+import { FormInstance } from 'element-plus';
+
+defineOptions({
+  name: 'UploadStampFileDialog',
+});
+
+type Props = {
+  modelValue: boolean;
+  form?: {
+    id: string;
+    url: UploadUserFile[];
+  };
+};
+
+const props = withDefaults(defineProps<Props>(), {
+  modelValue: false,
+});
+
+const emit = defineEmits<{
+  (e: 'update:modelValue', value: boolean): void;
+  (e: 'update:form', value: Props['form']): void;
+  (e: 'onConfirm'): void;
+  (e: 'onCancel'): void;
+}>();
+
+const innerVisible = computed({
+  get() {
+    return props.modelValue;
+  },
+  set(val) {
+    emit('update:modelValue', val);
+  },
+});
+
+const innerForm = computed({
+  get() {
+    return props.form;
+  },
+  set(val) {
+    emit('update:form', val);
+  },
+});
+
+const dialogForm = ref<FormInstance>();
+
+function onDialogClose() {
+  if (!dialogForm.value) return;
+  dialogForm.value.resetFields();
+}
+
+function handleConfirm() {
+  if (!dialogForm.value) return;
+  dialogForm.value.validate((valid) => {
+    if (valid) {
+      emit('onConfirm');
+    } else {
+      return;
+    }
+  });
+}
+</script>
diff --git a/src/views/Home/constants/index.ts b/src/views/Home/constants/index.ts
index f6f7668..4e26fcb 100644
--- a/src/views/Home/constants/index.ts
+++ b/src/views/Home/constants/index.ts
@@ -1,6 +1,6 @@
 import { defineColumns } from '@bole-core/components';
 
-export const HomeColumns = defineColumns([
+export const columns = defineColumns([
   {
     id: '1',
     enCode: 'channel',
@@ -8,112 +8,93 @@
     width: 160,
   },
   {
+    id: '2',
+    enCode: 'channel',
+    name: '鎵规鍙�',
+    width: 160,
+  },
+  {
     id: '3',
-    enCode: 'name',
-    name: '濮撳悕',
-    width: 160,
-  },
-  {
-    id: '4',
-    enCode: 'idNumber',
-    name: '韬唤璇佸彿',
-    width: 200,
-  },
-  {
-    id: '5',
-    enCode: 'workType',
-    name: '闆囧憳宸ョ',
-    width: 160,
-  },
-  {
-    id: '6',
-    enCode: 'laborContractEnterprise',
-    name: '鍔冲姩鍚堝悓鍗曚綅',
-    width: 160,
-  },
-  {
-    id: '7',
-    enCode: 'workEnterprise',
-    name: '瀹為檯宸ヤ綔鍗曚綅',
-    width: 160,
-  },
-  {
-    id: '8',
-    enCode: 'workAddress',
-    name: '鐢ㄥ伐鍦扮偣',
-    width: 160,
-  },
-  {
-    id: '9',
-    enCode: 'insuranceBeginTime',
-    name: '淇濋櫓璧锋湡',
-    width: 160,
-  },
-  {
-    id: '10',
-    enCode: 'insuranceEndTime',
-    name: '淇濋櫓姝㈡湡',
-    width: 160,
-  },
-  {
-    id: '11',
-    enCode: 'insuredInstitution',
-    name: '鍙備繚鏈烘瀯',
-    width: 160,
-  },
-  {
-    id: '12',
-    enCode: 'insuranceScheme',
-    name: '鎶曚繚鏂规',
-    width: 160,
-  },
-  {
-    id: '13',
-    enCode: 'insuranceType',
-    name: '鎶曚繚鏂瑰紡',
-    width: 160,
-  },
-  {
-    id: '14',
     enCode: 'orderNo',
     name: '淇濆崟鍙�',
     width: 160,
   },
   {
+    id: '4',
+    enCode: 'orderNo',
+    name: '鎶曚繚浜�',
+    width: 160,
+  },
+  {
+    id: '5',
+    enCode: 'orderNo',
+    name: '琚繚浜�',
+    width: 160,
+  },
+  {
+    id: '6',
+    enCode: 'insuranceBeginTime',
+    name: '淇濋櫓璧锋湡',
+    width: 160,
+  },
+  {
+    id: '7',
+    enCode: 'insuranceEndTime',
+    name: '淇濋櫓姝㈡湡',
+    width: 160,
+  },
+  {
+    id: '8',
+    enCode: 'insuredInstitution',
+    name: '鍙備繚鏈烘瀯',
+    width: 160,
+  },
+  {
+    id: '9',
+    enCode: 'insuranceScheme',
+    name: '鎶曚繚鏂规',
+    width: 160,
+  },
+  {
+    id: '10',
+    enCode: 'insuranceType',
+    name: '鎶曚繚鏂瑰紡',
+    width: 160,
+  },
+  {
+    id: '11',
+    enCode: 'insuranceType',
+    name: '鎶曚繚浜烘暟',
+    width: 160,
+  },
+  {
+    id: '12',
+    enCode: 'insuranceType',
+    name: '鎬讳繚棰�(鍏�)',
+    width: 200,
+  },
+  {
+    id: '13',
+    enCode: 'insuranceType',
+    name: '鎬讳繚璐�(鍏�)',
+    width: 160,
+  },
+  {
+    id: '14',
+    enCode: 'createTime',
+    name: '鏈�杩戝鍏ユ棩鏈�',
+    width: 160,
+  },
+  {
     id: '15',
-    enCode: 'onJobFlag',
-    name: '鍦ㄨ亴鏍囪瘑',
+    enCode: 'insuranceType',
+    name: '鎶曚繚鐘舵��',
     width: 160,
   },
   {
     id: '16',
-    enCode: 'gender',
-    name: '鎬у埆',
-    width: 160,
-  },
-  {
-    id: '17',
-    enCode: 'age',
-    name: '骞撮緞',
-    width: 160,
-  },
-  {
-    id: '20',
-    enCode: 'premiumAmount',
-    name: '淇濊垂',
-    width: 160,
-  },
-  {
-    id: '21',
-    enCode: 'incDecAmount',
-    name: '澧炲噺璐圭敤',
-    width: 160,
-  },
-
-  {
-    id: '20',
-    enCode: 'createTime',
-    name: '瀵煎叆鏃ユ湡',
+    enCode: 'insuranceType',
+    name: '鐞嗚禂鏁伴噺',
     width: 160,
   },
 ]).filter(Boolean);

--
Gitblit v1.9.1