Просмотр исходного кода

```
feat(government): 新增积分充值统计与失败记录功能

新增获取积分充值统计列表和失败记录列表的 API 接口,并在政府积分管理页面中展示相关数据。
补充了对应的类型定义 `PointsRechargeVO` 和 `PointsFailureRecordVO`,并调整了表格列配置及导入记录弹窗逻辑。
```

zhangtao 3 недель назад
Родитель
Сommit
ebfd9cffad

+ 25 - 0
src/service/api/government/points/index.ts

@@ -30,3 +30,28 @@ export function fetchImportPoints(params: File) {
     }
   });
 }
+
+/** 获取积分充值统计列表
+ *
+ * @param params
+ * @returns
+ */
+export function fetchGetPointsOutList(params: any) {
+  return request<Api.government.PointsRechargeVO[]>({
+    url: '/platform/pointsRecharge/statisticsList',
+    method: 'get',
+    params
+  });
+}
+
+/**
+ *  获取积分充值失败列表
+ * @param params
+ * @returns
+ */
+export function fetchGetFailPointsList() {
+  return request<Api.government.PointsFailureRecordVO[]>({
+    url: '/platform/pointsFailureRecord/groupByCode',
+    method: 'get'
+  });
+}

+ 51 - 0
src/typings/api.d.ts

@@ -599,5 +599,56 @@ declare namespace Api {
       userPhone?: string;
       [property: string]: any;
     }
+
+    /**
+     * 充值积分记录统计列表
+     *
+     * PointsRechargeVO
+     */
+    interface PointsRechargeVO {
+      /**
+       * 渠道(企业)名称
+       */
+      channelName?: string;
+      /**
+       * 操作时间
+       */
+      createTime?: string;
+      /**
+       * 总充值积分
+       */
+      totalPoints?: number;
+      /**
+       * 总充值人数
+       */
+      totalUserCount?: number;
+      [property: string]: any;
+    }
+    /**
+     * 积分任务执行失败记录列表
+     */
+    interface PointsFailureRecordVO {
+      /**
+       * 操作人
+       */
+      createBy?: string;
+      /**
+       * 时间
+       */
+      createTime?: string;
+      /**
+       * 失败状态数量
+       */
+      failureStatus?: number;
+      /**
+       * 任务名称
+       */
+      name?: string;
+      /**
+       * 成功状态数量
+       */
+      successStatus?: number;
+      [property: string]: any;
+    }
   }
 }

+ 6 - 6
src/views/government/government-list/index.vue

@@ -7,32 +7,32 @@ import { useModalFrom } from '@/components/zt/ModalForm/hooks/useModalForm';
 
 const columns: NaiveUI.TableColumn<InternalRowData>[] = [
   {
-    key: 'name',
+    key: '1',
     title: '企业编号',
     align: 'center'
   },
   {
-    key: 'name',
+    key: '2',
     title: '企业名称',
     align: 'center'
   },
   {
-    key: 'name',
+    key: '3',
     title: '总员工数',
     align: 'center'
   },
   {
-    key: 'name',
+    key: '4',
     title: '正常员工数',
     align: 'center'
   },
   {
-    key: 'name',
+    key: '5',
     title: '状态',
     align: 'center'
   },
   {
-    key: 'name',
+    key: '6',
     title: '创建时间',
     align: 'center'
   }

+ 118 - 8
src/views/government/points/index.vue

@@ -1,10 +1,16 @@
 <script setup lang="tsx">
 import { ref } from 'vue';
-import { fetchGetPointsList, fetchImportPoints } from '@/service/api/government/points';
+import {
+  fetchGetFailPointsList,
+  fetchGetPointsList,
+  fetchGetPointsOutList,
+  fetchImportPoints
+} from '@/service/api/government/points';
 import { useTable } from '@/components/zt/Table/hooks/useTable';
 import { useModal } from '@/components/zt/Modal/hooks/useModal';
 import type { ModalMethods } from '@/components/zt/Modal/types';
 import type { FormSchema } from '@/components/zt/Form/types/form';
+import SVGIcon from '@/components/custom/svg-icon.vue';
 const importTemplateRef = ref<ModalMethods>();
 const ModalColumns: NaiveUI.TableColumn<Api.government.PointsRecharge>[] = [
   {
@@ -38,6 +44,28 @@ const ModalColumns: NaiveUI.TableColumn<Api.government.PointsRecharge>[] = [
     align: 'center'
   }
 ];
+const outColumns: NaiveUI.TableColumn<Api.government.PointsRechargeVO>[] = [
+  {
+    key: 'channelName',
+    title: '所属企业',
+    align: 'center'
+  },
+  {
+    key: 'totalPoints',
+    title: '总充值积分',
+    align: 'center'
+  },
+  {
+    key: 'totalUserCount',
+    title: '总充值人次',
+    align: 'center'
+  },
+  {
+    key: 'createTime',
+    title: '操作时间',
+    align: 'center'
+  }
+];
 const searchSchemas: FormSchema[] = [
   {
     field: 'channelName',
@@ -50,10 +78,77 @@ const searchSchemas: FormSchema[] = [
     component: 'NInput'
   }
 ];
-
-const [registerTable] = useTable({
+const failColumns: NaiveUI.TableColumn<Api.government.PointsFailureRecordVO>[] = [
+  {
+    key: 'index',
+    title: '序号',
+    align: 'center',
+    render(_, rowIndex) {
+      return rowIndex + 1;
+    }
+  },
+  {
+    key: 'name',
+    title: '任务名称',
+    align: 'center'
+  },
+  {
+    key: 'createTime',
+    title: '时间',
+    align: 'center',
+    render(row) {
+      return (
+        <div>
+          <div>创建时间:{row.createTime}</div>
+          <div>完成时间:{row.createTime}</div>
+        </div>
+      );
+    }
+  },
+  {
+    key: 'totalUserCount',
+    title: '操作人',
+    align: 'center',
+    render(row) {
+      return (
+        <div>
+          <div>{row.createByRole}</div>
+          <div>({row.createByName})</div>
+        </div>
+      );
+    }
+  },
+  {
+    key: 'successStatus',
+    title: '状态',
+    align: 'center',
+    width: 240,
+    render(row) {
+      return (
+        <div class={'flex items-center'}>
+          共{Number(row.successStatus) + Number(row.failureStatus)}条,成功:{row.successStatus},
+          <span class={'flex items-center text-red-500'}>
+            失败:
+            {row.failureStatus}
+            {row.failureStatus != 0 && (
+              <div onClick={() => hanleExportFailure(row.code)}>
+                <SVGIcon
+                  icon={'tdesign:download'}
+                  class={'ml-1 cursor-pointer text-20px'}
+                  style={'color:var(--n-color)'}
+                ></SVGIcon>
+              </div>
+            )}
+          </span>
+        </div>
+      );
+    }
+  }
+];
+const failData = ref<Api.government.PointsFailureRecordVO[]>([]);
+const [registerTable, { refresh }] = useTable({
   searchFormConfig: {
-    schemas: searchSchemas,
+    schemas: searchSchemas.slice(0, 1),
     inline: false,
     size: 'small',
     labelPlacement: 'left',
@@ -87,6 +182,11 @@ const [registerModal, { openModal }] = useModal({
   showFooter: false,
   width: 1200
 });
+const [registerModalFail, { openModal: openModalFail }] = useModal({
+  title: '导入记录',
+  height: 400,
+  showFooter: false
+});
 async function handleSubmitImport(file: File) {
   const { error } = await fetchImportPoints(file);
   if (!error) {
@@ -99,16 +199,24 @@ async function handleSubmitImport(file: File) {
 function handleOpenPoints() {
   importTemplateRef.value?.openModal();
 }
+async function openImportModal() {
+  openModalFail();
+  const { data } = await fetchGetFailPointsList();
+  failData.value = data as Api.government.PointsFailureRecordVO[];
+}
+function hanleExportFailure(code: string) {
+  window.open(`${import.meta.env.VITE_SERVICE_BASE_URL}/platform/pointsFailureRecord/export?code=${code}`, '_blank');
+}
 </script>
 
 <template>
   <LayoutTable>
-    <ZTable :show-table-action="false" :columns="ModalColumns" :api="fetchGetPointsList" @register="registerTable">
+    <ZTable :show-table-action="false" :columns="outColumns" :api="fetchGetPointsOutList" @register="registerTable">
       <template #prefix>
         <NButton size="small" @click="openModal">充值积分</NButton>
       </template>
     </ZTable>
-    <BasicModal @register="registerModal">
+    <BasicModal @register="registerModal" @after-leave="refresh">
       <LayoutTable>
         <ZTable
           :show-table-action="false"
@@ -118,12 +226,14 @@ function handleOpenPoints() {
         >
           <template #prefix>
             <NButton size="small" @click="handleOpenPoints">导入积分</NButton>
-            <NButton size="small">导入记录</NButton>
+            <NButton size="small" @click="openImportModal">导入记录</NButton>
           </template>
         </ZTable>
       </LayoutTable>
     </BasicModal>
-
+    <BasicModal @register="registerModalFail">
+      <NDataTable :columns="failColumns" :data="failData" size="small" remote class="sm:h-full" />
+    </BasicModal>
     <ZImportTemplate
       ref="importTemplateRef"
       url="/platform/pointsRecharge/exportTemplate"