From 6aea79cf8115867a976e50868801f50955be65c1 Mon Sep 17 00:00:00 2001
From: wupengfei <834520024@qq.com>
Date: 星期五, 19 九月 2025 10:45:10 +0800
Subject: [PATCH] fix: bug

---
 src/views/ServiceChargeManage/ServiceChargeDetail.vue |  445 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 430 insertions(+), 15 deletions(-)

diff --git a/src/views/ServiceChargeManage/ServiceChargeDetail.vue b/src/views/ServiceChargeManage/ServiceChargeDetail.vue
index 5d19a9e..9fbb7c8 100644
--- a/src/views/ServiceChargeManage/ServiceChargeDetail.vue
+++ b/src/views/ServiceChargeManage/ServiceChargeDetail.vue
@@ -1,46 +1,461 @@
 <template>
   <LoadingLayout :loading="isLoading">
-    <AppScrollContainer>
-      <ChunkCell title="缁撶畻鍗曡鎯�"> </ChunkCell>
-      <ChunkCell title="缁撶畻娴佺▼"> </ChunkCell>
-      <ChunkCell title="缁撶畻鍚嶅崟"> </ChunkCell>
-    </AppScrollContainer>
+    <AppContainer>
+      <ChunkCell title="缁撶畻鍗曡鎯�">
+        <ProForm :model="form" ref="formRef" label-width="120px" :is-read="true">
+          <ProFormCol>
+            <ProFormColItem :span="8">
+              <ProFormItemV2 label="鎵�灞炰换鍔�:" prop="name">
+                <ProFormText v-model="form.name"> </ProFormText>
+              </ProFormItemV2>
+            </ProFormColItem>
+            <ProFormColItem :span="8">
+              <ProFormItemV2 label="浠诲姟缂栧彿:" prop="code">
+                <ProFormText v-model="form.code"> </ProFormText>
+              </ProFormItemV2>
+            </ProFormColItem>
+          </ProFormCol>
+          <!-- <ProFormCol>
+            <ProFormColItem :span="8">
+              <ProFormItemV2 label="缁撶畻鍗曞悕绉�:" prop="settlementOrderName">
+                <ProFormText v-model="form.settlementOrderName"> </ProFormText>
+              </ProFormItemV2>
+            </ProFormColItem>
+            <ProFormColItem :span="8">
+              <ProFormItemV2 label="涓婁紶鏃堕棿:" prop="settlementOrderTime">
+                <ProFormDatePicker
+                  v-model="form.settlementOrderTime"
+                  type="date"
+                  format="YYYY-MM-DD HH:mm"
+                ></ProFormDatePicker>
+              </ProFormItemV2>
+            </ProFormColItem>
+          </ProFormCol> -->
+          <ProFormCol>
+            <ProFormColItem :span="8">
+              <ProFormItemV2 label="缁撶畻閲戦:" prop="settlementAmount">
+                <ProFormInputNumber v-model="form.settlementAmount" format-value="money">
+                </ProFormInputNumber>
+              </ProFormItemV2>
+            </ProFormColItem>
+            <ProFormColItem :span="8">
+              <ProFormItemV2 label="瀹炲彂閲戦:" prop="actualSettlementAmount">
+                <ProFormInputNumber v-model="form.actualSettlementAmount" format-value="money">
+                </ProFormInputNumber>
+              </ProFormItemV2>
+            </ProFormColItem>
+          </ProFormCol>
+        </ProForm>
+      </ChunkCell>
+      <ChunkCell title="缁撶畻鍚嶅崟" style="flex: 1" class="settlement-user-list-chunk">
+        <ProTableQueryFilterBar @on-reset="reset">
+          <template #query>
+            <QueryFilterItem>
+              <SearchInput
+                v-model="extraParamState.keywords"
+                style="width: 300px"
+                placeholder="濮撳悕/鎵嬫満/韬唤璇佸彿/瀹㈡埛"
+                @on-click-search="getList"
+              >
+              </SearchInput>
+            </QueryFilterItem>
+          </template>
+          <template #btn v-if="isSettlement">
+            <BlFileUpload
+              v-model:file-url="form.settlementUrl"
+              ref="uploadRef"
+              :showTip="false"
+              :show-file-list="false"
+              class="pro-table-operation-btn upload-style-btn"
+              :on-success="(event) => handleUploadSuccess(event)"
+              :limitFileSize="null"
+              :limit="1"
+              accept="xlsx,xls"
+            >
+              <el-button text type="primary" class="pro-table-operation-btn">瀵煎叆</el-button>
+            </BlFileUpload>
+            <el-button type="primary" link @click="handleExport()">瀵煎嚭</el-button>
+          </template>
+        </ProTableQueryFilterBar>
+        <ProTableV2
+          v-bind="proTableProps"
+          :columns="SettlementListColumns"
+          :operationBtns="operationBtns"
+          :auto-height="false"
+          ref="proTable"
+          :tableProps="{
+            maxHeight: '250px',
+          }"
+        >
+        </ProTableV2>
+        <div class="chuck-add-or-edit-actions">
+          <el-button class="chuck-add-or-edit-actions" @click="handleBack">鍙栨秷</el-button>
+          <el-button
+            v-if="isSettlement"
+            class="chuck-add-or-edit-actions"
+            type="primary"
+            @click="handleSubmit()"
+            >缁撶畻</el-button
+          >
+        </div>
+      </ChunkCell>
+    </AppContainer>
+    <EditAccountInfoDialog v-bind="dialogProps"></EditAccountInfoDialog>
+    <SettleDetailDialog v-bind="dialogSettleProps" />
   </LoadingLayout>
 </template>
 <script setup lang="ts">
-import { LoadingLayout, AppScrollContainer, ChunkCell } from '@bole-core/components';
-import {} from '@/constants';
-import * as flexTaskServices from '@/services/api/FlexTask';
+import {
+  LoadingLayout,
+  AppContainer,
+  ChunkCell,
+  ProForm,
+  ProFormItemV2,
+  ProFormText,
+  ProFormCol,
+  ProFormColItem,
+  ProFormDatePicker,
+  ProFormInputNumber,
+  useTable,
+  ProTableV2,
+  defineOperationBtns,
+  SearchInput,
+  QueryFilterItem,
+  ProTableQueryFilterBar,
+  useFormDialog,
+  XLSXUtils,
+  BlFileUpload,
+  UploadUserFile,
+} from '@bole-core/components';
+import { SettlementListColumns } from './constants';
 import { useQuery } from '@tanstack/vue-query';
+import * as taskServices from '@/services/api/task';
+import * as taskUserServices from '@/services/api/taskUser';
+import EditAccountInfoDialog from './components/EditAccountInfoDialog.vue';
+import SettleDetailDialog from './components/SettleDetailDialog.vue';
+import { Message } from '@bole-core/core';
+import { SettlementReceiveStatusText } from '@/constants';
+import {
+  downloadFile,
+  downloadFileByUrl,
+  paginateList,
+  setOssFileName,
+  setOSSLink,
+  toThousand,
+} from '@/utils';
+import _ from 'lodash';
 
 defineOptions({
   name: 'ServiceChargeDetail',
 });
 
+const { closeViewPush } = useRouteView();
+const eventContext = useGlobalEventContext();
+const operationBtns = defineOperationBtns([
+  {
+    data: {
+      enCode: 'editBtn',
+      name: '缂栬緫',
+    },
+    emits: {
+      onClick: (role) => openDialog(role),
+    },
+    extraProps: {
+      hide: () => !isSettlement.value,
+    },
+  },
+]);
 const route = useRoute();
 const id = (route.params.id as string) ?? '';
+const settlement = (route.query.settlement as string) ?? '';
+const isSettlement = computed(() => !!settlement);
 
-const state = reactive({
-  loading: true,
+const form = reactive({
+  name: '',
+  settlementAmount: 0,
+  actualSettlementAmount: 0,
+  code: '',
+  settlementOrderName: '',
+  settlementOrderTime: '',
+  settlementTaskUsers: [] as API.GetSettlementTaskUsersQueryResultItem[],
+
+  settlementUrl: [] as UploadUserFile[],
 });
 
-const { isLoading } = useQuery({
-  queryKey: ['flexTaskServices/getFlexTaskDetail', id],
+const BaseState = {
+  loading: true,
+};
+
+const state = reactive({ ...BaseState });
+
+const { isLoading, refetch } = useQuery({
+  queryKey: ['taskUserServices/getSettlementTaskUsers', id],
   queryFn: async () => {
-    return await flexTaskServices.getFlexTaskDetail(
+    return await taskUserServices.getSettlementTaskUsers(
       { id: id },
       {
         showLoading: false,
       }
     );
   },
-  onSuccess(data) {},
+  placeholderData: () => ({} as API.GetSettlementTaskUsersQueryResult),
+  onSuccess(res) {
+    form.settlementTaskUsers = res?.data ?? [];
+    if (res?.detail) {
+      form.name = res?.detail?.name;
+      form.settlementAmount = res?.detail?.settlementAmount ?? 0;
+      form.actualSettlementAmount = res?.detail?.actualSettlementAmount ?? 0;
+      form.code = res?.detail?.code;
+      // form.settlementOrderName = setOssFileName(res?.detail?.settlementOrderName);
+      // form.settlementOrderTime = res?.detail?.settlementOrderTime ?? '';
+    }
+    // if (res?.errors?.length > 0) {
+    //   Message.tipMessage('瀛樺湪瀵煎叆閿欒鐨勬暟鎹紝鏄惁瀵煎嚭锛�').then(() => {
+    //     XLSXUtils.exportToXLSX({
+    //       workbookDataList: res.errors,
+    //       fileName: '缁撶畻瀵煎叆-閿欒鏁版嵁',
+    //       workbookHeaderMap: {
+    //         name: '濮撳悕',
+    //         identity: '韬唤璇佸彿',
+    //         taskName: '浠诲姟鍚嶇О',
+    //         settlementAmount: '缁撶畻閲戦',
+    //         actualSettlementAmount: '瀹炲彂閲戦',
+    //         receiveAccount: '鏀舵璐︽埛',
+    //         bank: '鎵�灞為摱琛�',
+    //         bankBranch: '寮�鎴锋敮琛屽悕绉�',
+    //         errorMessage: '閿欒淇℃伅',
+    //       },
+    //     });
+    //   });
+    // }
+    getList();
+  },
   enabled: !!id,
 });
 
-onMounted(() => {});
+const {
+  getDataSource: getList,
+  proTableProps,
+  paginationState,
+  extraParamState,
+  reset,
+} = useTable(
+  async ({ pageIndex, pageSize }, extraParamState) => {
+    try {
+      let list = [...form.settlementTaskUsers];
+      if (extraParamState.keywords) {
+        list = list?.filter((item) => {
+          return (
+            item.name.includes(extraParamState.keywords) ||
+            item.contactPhoneNumber.includes(extraParamState.keywords) ||
+            item.identity.includes(extraParamState.keywords)
+          );
+        });
+      }
+
+      return Promise.resolve({
+        pageModel: {
+          rows: pageSize,
+          page: pageIndex,
+          totalCount: list.length,
+        },
+        data: paginateList(list, pageIndex, pageSize),
+      });
+    } catch (error) {
+      console.log('error: ', error);
+    }
+  },
+  {
+    defaultExtraParams: {
+      keywords: '',
+      orderInput: [{ property: 'id', order: EnumPagedListOrder.Desc }],
+    },
+    queryKey: ['taskUserServices/getSettlementTaskUsers'],
+    columnsRenderProps: {
+      settlementTime: { type: 'date' },
+      settlementAmount: { type: 'money' },
+      actualSettlementAmount: { type: 'money' },
+      settlementReceiveStatus: { type: 'enum', valueEnum: SettlementReceiveStatusText },
+    },
+  }
+);
+
+const { dialogProps, handleAdd, handleEdit, editForm } = useFormDialog({
+  onConfirm: handleAddOrEdit,
+  defaultFormParams: {
+    id: '',
+    settlementAmount: null as number,
+    actualSettlementAmount: null as number,
+    receiveAccount: '',
+    bank: '',
+    // bankBranch: '',
+  },
+});
+
+function openDialog(row?: API.GetSettlementTaskUsersQueryResultItem) {
+  if (row) {
+    handleEdit({
+      id: row?.id,
+      settlementAmount: row?.settlementAmount ?? null,
+      actualSettlementAmount: row?.actualSettlementAmount ?? null,
+      receiveAccount: row?.receiveAccount ?? '',
+      bank: row?.bank ?? '',
+      // bankBranch: row?.bankBranch ?? '',
+    });
+  }
+}
+
+async function handleAddOrEdit() {
+  try {
+    let params: API.EditTaskSettlementOrderRosterCommand = {
+      id: editForm.id,
+      settlementAmount: editForm.settlementAmount,
+      actualSettlementAmount: editForm.actualSettlementAmount,
+      receiveAccount: editForm.receiveAccount,
+      bank: editForm.bank,
+      // bankBranch: editForm.bankBranch,
+    };
+    let res = await taskServices.editTaskSettlementOrderRoster(params);
+    if (res) {
+      Message.successMessage('鎿嶄綔鎴愬姛');
+      refetch();
+      getList(paginationState.pageIndex);
+    }
+  } catch (error) {}
+}
+
+function handleUploadSuccess(response: UploadUserFile & { file: File & { uid: number } }) {
+  if (response.path) {
+    importTaskSettlementOrderRosters(response.path);
+  }
+}
+
+async function importTaskSettlementOrderRosters(url: string) {
+  try {
+    let params: API.ImportTaskSettlementOrderRostersCommand = {
+      id: id,
+      url: url,
+    };
+    let res = await taskServices.importTaskSettlementOrderRosters(params);
+    if (res) {
+      Message.successMessage('鎿嶄綔鎴愬姛');
+      refetch();
+      getList(paginationState.pageIndex);
+      if (res?.errors?.length > 0) {
+        Message.tipMessage('瀛樺湪瀵煎叆閿欒鐨勬暟鎹紝鏄惁瀵煎嚭锛�').then(() => {
+          XLSXUtils.exportToXLSX({
+            workbookDataList: res.errors,
+            fileName: '缁撶畻瀵煎叆-閿欒鏁版嵁',
+            workbookHeaderMap: {
+              name: '濮撳悕',
+              identity: '韬唤璇佸彿',
+              contactPhoneNumber: '鎵嬫満鍙�',
+              bank: '鎵�灞為摱琛�',
+              bankBranch: '鎵�灞炴敮琛�',
+              receiveAccount: '鏀舵璐︽埛',
+              settlementAmount: '缁撶畻閲戦',
+              actualSettlementAmount: '瀹炲彂閲戦',
+              errorMessage: '閿欒淇℃伅',
+            },
+          });
+        });
+      }
+    }
+  } catch (error) {
+  } finally {
+    form.settlementUrl = [] as UploadUserFile[];
+  }
+}
+
+function handleSubmit() {
+  handleSettleEdit({
+    id: id,
+    name: form.name,
+    code: form.code,
+    settlementUserCount: form.settlementTaskUsers.length,
+    actualSettlementAmount: form.actualSettlementAmount,
+  });
+}
+
+const {
+  dialogProps: dialogSettleProps,
+  handleEdit: handleSettleEdit,
+  editForm: settleEditForm,
+} = useFormDialog({
+  onConfirm: handleSettle,
+  defaultFormParams: {
+    id: '',
+    name: '',
+    code: '',
+    settlementUserCount: 0,
+    actualSettlementAmount: 0,
+  },
+});
+
+async function handleSettle() {
+  sureTaskSettlementOrder();
+}
+
+async function sureTaskSettlementOrder() {
+  try {
+    let params: API.SureTaskSettlementCommand = {
+      taskInfoId: id,
+    };
+    let res = await taskServices.sureTaskSettlement(params);
+    if (res) {
+      Message.successMessage('鎿嶄綔鎴愬姛');
+      eventContext.emit('sureTaskSettlementOrder');
+      handleBack();
+    }
+  } catch (error) {}
+}
+
+const handleExport = _.debounce(
+  async () => {
+    if (paginationState.total === 0) {
+      Message.warnMessage('娌℃湁鏁版嵁鍙互瀵煎嚭鍝');
+      return;
+    }
+    try {
+      let params: API.ExportTaskSettlementOrderRostersCommand = {
+        id: id,
+      };
+      let res = await taskServices.exportTaskSettlementOrderRosters(params);
+      if (res) {
+        downloadFileByUrl(setOSSLink(res), `${form.name}-${form.code}`);
+      }
+    } catch (error) {}
+  },
+  1000,
+  { leading: true, trailing: false }
+);
+
+function handleBack() {
+  closeViewPush(route, {
+    name: 'ServiceChargeManageList',
+  });
+}
 </script>
 
 <style lang="scss" scoped>
 @use '@/style/common.scss' as *;
+
+.step-wrapper {
+  margin: 0 auto;
+  padding: 24px 0;
+}
+
+.settlement-user-list-chunk {
+  :deep() {
+    .no-data img {
+      width: 280px;
+    }
+  }
+}
+</style>
+<style lang="scss">
+.text-over-tooltip-content {
+  max-width: 600px;
+  word-break: break-all;
+}
 </style>

--
Gitblit v1.9.1