Jelajahi Sumber

```
feat: 添加对账中心路由和功能模块

- 新增对账中心路由配置,包括积分核对和积分详情页面
- 更新路由映射和类型定义文件
- 在订单管理相关页面添加渠道筛选功能
- 在正常订单页面新增渠道列显示
- 在售后订单详情页面添加退款方式显示逻辑
- 在充值记录页面更新标题为"充值订单"

refactor: 优化字典选择组件支持额外选项

- 为字典选择组件添加extraOptions属性
- 实现额外选项与字典选项的合并逻辑

fix: 修复商品列表API注释错误

- 修正fetchList函数的JSDoc注释描述

chore: 调整测试环境服务基础URL配置

- 注释或修改部分测试环境的服务地址配置
```

wenjie 15 jam lalu
induk
melakukan
e7f4b6d621

+ 5 - 0
.claude/settings.json

@@ -0,0 +1,5 @@
+{
+  "enabledPlugins": {
+    "superpowers@claude-plugins-official": true
+  }
+}

+ 3 - 3
.env.test

@@ -1,16 +1,16 @@
 # backend service base url, test environment
 
 # VITE_SERVICE_BASE_URL=https://522d2ea1.r39.cpolar.top #王
-VITE_SERVICE_BASE_URL=http://89561bkaq794.vicp.fun:53846 #张
+# VITE_SERVICE_BASE_URL=http://89561bkaq794.vicp.fun:53846 #张
  #VITE_SERVICE_BASE_URL=https://25740642.r3.cpolar.top #田
-# VITE_SERVICE_BASE_URL=https://425f86e6.r24.cpolar.top #邓
+# VITE_SERVICE_BASE_URL=https://749885d7.r16.cpolar.top #邓
 # VITE_SERVICE_BASE_URL=http://74949mkfh190.vicp.fun #付
 # VITE_SERVICE_BASE_URL=https://smqjh.api.zswlgz.com
 # VITE_SERVICE_BASE_URL=https://735a1bda.r24.cpolar.top #黄
 # VITE_SERVICE_BASE_URL=http://192.168.0.11:8081 #wzq
 # VITE_SERVICE_BASE_URL=http://89561bkaq794.vicp.fun:53846
 
-# VITE_SERVICE_BASE_URL=http://47.109.84.152:8081#打包测试本地服务器
+VITE_SERVICE_BASE_URL=http://47.109.84.152:8081#打包测试本地服务器
 # VITE_SERVICE_BASE_URL=https://smqjh.api.zswlgz.com #服务器
 
 # other backend service base url, test environment

+ 4 - 0
src/components/zt/dict-select/index.ts

@@ -6,5 +6,9 @@ export interface disctSelectProps {
    * 禁用的标签
    */
   disabledLables?: string[];
+  /**
+   * 额外的选项,会追加到字典选项之后
+   */
+  extraOptions?: { label: string; value: string | number; disabled?: boolean; [key: string]: any }[];
   [key: string]: any;
 }

+ 5 - 1
src/components/zt/dict-select/index.vue

@@ -16,13 +16,17 @@ const value = defineModel<string | string[] | null>('value', { required: false }
 const attrs: SelectProps = useAttrs();
 const { options } = useDict(props.dictCode, props.immediate);
 const newOptions = computed(() => {
-  return options.value.map(item => {
+  const dictOptions = options.value.map(item => {
     return {
       label: item.label,
       value: item.value,
       disabled: Boolean(props.disabledLables?.includes(item.label))
     };
   });
+  if (props.extraOptions?.length) {
+    return [...dictOptions, ...props.extraOptions];
+  }
+  return dictOptions;
 });
 </script>
 

+ 4 - 1
src/locales/langs/en-us.ts

@@ -306,7 +306,10 @@ const local: App.I18n.Schema = {
     'h5-manage': '',
     'h5-manage_channel-manage': '',
     'h5-manage_edit-channel': '',
-    'h5-manage_user-list': ''
+    'h5-manage_user-list': '',
+    'reconciliation-center': '',
+    'reconciliation-center_points-checking': '',
+    'reconciliation-center_points-details': ''
   },
   page: {
     login: {

+ 4 - 1
src/locales/langs/zh-cn.ts

@@ -303,7 +303,10 @@ const local: App.I18n.Schema = {
     'h5-manage': '',
     'h5-manage_channel-manage': '',
     'h5-manage_edit-channel': '',
-    'h5-manage_user-list': ''
+    'h5-manage_user-list': '',
+    'reconciliation-center': '',
+    'reconciliation-center_points-checking': '',
+    'reconciliation-center_points-details': ''
   },
   page: {
     login: {

+ 2 - 0
src/router/elegant/imports.ts

@@ -65,6 +65,8 @@ export const views: Record<LastLevelRouteKey, RouteComponent | (() => Promise<Ro
   "order-manage_order-detail": () => import("@/views/order-manage/order-detail/index.vue"),
   "order-manage_ponits-details": () => import("@/views/order-manage/ponits-details/index.vue"),
   "order-manage_recharge-records": () => import("@/views/order-manage/recharge-records/index.vue"),
+  "reconciliation-center_points-checking": () => import("@/views/reconciliation-center/points-checking/index.vue"),
+  "reconciliation-center_points-details": () => import("@/views/reconciliation-center/points-details/index.vue"),
   "tenant_tenant-change": () => import("@/views/tenant/tenant-change/index.vue"),
   "tenant_tenant-package": () => import("@/views/tenant/tenant-package/index.vue"),
   tenant_tenant: () => import("@/views/tenant/tenant/index.vue"),

+ 29 - 0
src/router/elegant/routes.ts

@@ -598,6 +598,35 @@ export const generatedRoutes: GeneratedRoute[] = [
       }
     ]
   },
+  {
+    name: 'reconciliation-center',
+    path: '/reconciliation-center',
+    component: 'layout.base',
+    meta: {
+      title: 'reconciliation-center',
+      i18nKey: 'route.reconciliation-center'
+    },
+    children: [
+      {
+        name: 'reconciliation-center_points-checking',
+        path: '/reconciliation-center/points-checking',
+        component: 'view.reconciliation-center_points-checking',
+        meta: {
+          title: 'reconciliation-center_points-checking',
+          i18nKey: 'route.reconciliation-center_points-checking'
+        }
+      },
+      {
+        name: 'reconciliation-center_points-details',
+        path: '/reconciliation-center/points-details',
+        component: 'view.reconciliation-center_points-details',
+        meta: {
+          title: 'reconciliation-center_points-details',
+          i18nKey: 'route.reconciliation-center_points-details'
+        }
+      }
+    ]
+  },
   {
     name: 'tenant',
     path: '/tenant',

+ 3 - 0
src/router/elegant/transform.ts

@@ -239,6 +239,9 @@ const routeMap: RouteMap = {
   "order-manage_order-detail": "/order-manage/order-detail",
   "order-manage_ponits-details": "/order-manage/ponits-details",
   "order-manage_recharge-records": "/order-manage/recharge-records",
+  "reconciliation-center": "/reconciliation-center",
+  "reconciliation-center_points-checking": "/reconciliation-center/points-checking",
+  "reconciliation-center_points-details": "/reconciliation-center/points-details",
   "tenant": "/tenant",
   "tenant_tenant": "/tenant/tenant",
   "tenant_tenant-change": "/tenant/tenant-change",

+ 1 - 12
src/service/api/government/claim-records/index.ts

@@ -1,6 +1,6 @@
 import { request } from '@/service/request';
 /**
- * 分页获取商品
+ * 分页获取
  * @param params
  * @returns
  */
@@ -12,17 +12,6 @@ export function fetchList(data: any) {
   });
 }
 
-/**
- * 获取全部渠道商
- * @returns
- */
-export function fetchGetAllChannelList() {
-  return request<Api.goods.Channel[]>({
-    url: '/smqjh-system/api/v1/channel/listAll',
-    method: 'get'
-  });
-}
-
 /**
  * 获取一级渠道商
  * @returns

+ 24 - 0
src/service/api/reconciliation-center/points-checking/index.ts

@@ -0,0 +1,24 @@
+import { request } from '@/service/request';
+/**
+ * 分页获取商品
+ * @param params
+ * @returns
+ */
+export function fetchList(data: any) {
+  return request({
+    url: '/smqjh-system/api/v1/pointsReconciliation/page',
+    method: 'post',
+    data
+  });
+}
+
+/**
+ * 获取企业
+ * @returns
+ */
+export function fetchGetChannelList() {
+  return request<Api.goods.Channel[]>({
+    url: '/smqjh-system/api/v1/pointsReconciliation/getSelectChannel',
+    method: 'get'
+  });
+}

+ 47 - 0
src/service/api/reconciliation-center/points-details/index.ts

@@ -0,0 +1,47 @@
+import { request } from '@/service/request';
+/**
+ * 分页获取
+ * @param params
+ * @returns
+ */
+export function fetchList(data: any) {
+  return request({
+    url: '/smqjh-system/api/v1/pointsReconciliation/getPointsRecordLog',
+    method: 'post',
+    data
+  });
+}
+
+/**
+ * 获取企业
+ * @returns
+ */
+export function fetchGetChannelList() {
+  return request<Api.goods.Channel[]>({
+    url: '/smqjh-system/api/v1/pointsReconciliation/getSelectChannel',
+    method: 'get'
+  });
+}
+
+/**
+ * 冲正
+ * @returns
+ */
+export function fetchReversal(data: any) {
+  return request({
+    url: '/smqjh-system/api/v1/pointsReconciliation/savePointsRecord',
+    method: 'post',
+    data
+  });
+}
+
+/**
+ * 获取详情
+ * @returns
+ */
+export function fetchDetail(id: string) {
+  return request({
+    url: `/smqjh-system/api/v1/pointsReconciliation/getAdjustPointsRecord/${id}`,
+    method: 'get'
+  });
+}

+ 6 - 0
src/typings/elegant-router.d.ts

@@ -93,6 +93,9 @@ declare module "@elegant-router/types" {
     "order-manage_order-detail": "/order-manage/order-detail";
     "order-manage_ponits-details": "/order-manage/ponits-details";
     "order-manage_recharge-records": "/order-manage/recharge-records";
+    "reconciliation-center": "/reconciliation-center";
+    "reconciliation-center_points-checking": "/reconciliation-center/points-checking";
+    "reconciliation-center_points-details": "/reconciliation-center/points-details";
     "tenant": "/tenant";
     "tenant_tenant": "/tenant/tenant";
     "tenant_tenant-change": "/tenant/tenant-change";
@@ -168,6 +171,7 @@ declare module "@elegant-router/types" {
     | "member-center"
     | "operation"
     | "order-manage"
+    | "reconciliation-center"
     | "tenant"
     | "user-center"
     | "user-management"
@@ -240,6 +244,8 @@ declare module "@elegant-router/types" {
     | "order-manage_order-detail"
     | "order-manage_ponits-details"
     | "order-manage_recharge-records"
+    | "reconciliation-center_points-checking"
+    | "reconciliation-center_points-details"
     | "tenant_tenant-change"
     | "tenant_tenant-package"
     | "tenant_tenant"

+ 6 - 0
src/views/djk-manage/normal-order/index.vue

@@ -27,6 +27,12 @@ const columns: NaiveUI.TableColumn<Api.delivery.deliveryOrder>[] = [
     title: '订单编号',
     align: 'center'
   },
+  {
+    key: 'accessName',
+    title: '渠道',
+    align: 'center',
+    width: 120
+  },
   {
     key: 'consigneeMobile',
     title: '客户手机号',

+ 17 - 1
src/views/djk-manage/normal-order/normal-order.ts

@@ -2,6 +2,7 @@ import { h } from 'vue';
 import { NFlex, NImage, NTag } from 'naive-ui';
 // import { fetchGetAllStoreList } from '@/service/api/goods/desk-category';
 import { fetchGetStoreList } from '@/service/api/xsb-manage/store-info';
+import { fetchChannelList } from '@/service/api/h5-manage/channel-manage';
 // import { fetchGetDictDataList } from '@/service/api/system-manage';
 // import { useAuth } from '@/hooks/business/auth';
 import type { FormSchema } from '@/components/zt/Form/types/form';
@@ -15,7 +16,10 @@ export const SearchForm: FormSchema[] = [
       api: fetchGetStoreList,
       resultFeild: 'data.list',
       labelFeild: 'shopName',
-      valueFeild: 'shopId'
+      valueFeild: 'shopId',
+      params: {
+        hbStationNo: 'DJK'
+      }
     }
   },
   {
@@ -64,6 +68,18 @@ export const SearchForm: FormSchema[] = [
       type: 'datetimerange',
       defaultTime: ['00:00:00', '23:59:59']
     }
+  },
+  {
+    field: 'accessIds',
+    label: '渠道',
+    component: 'ApiSelect',
+    componentProps: {
+      api: fetchChannelList,
+      multiple: true,
+      resultFeild: 'data.list',
+      labelFeild: 'accessName',
+      valueFeild: 'accessId'
+    }
   }
   // {
   //   field: 'userAttrType',

+ 4 - 1
src/views/goods-center/health-goods/index.vue

@@ -100,7 +100,10 @@ const [registerTable, { refresh }] = useTable({
           api: fetchGetStoreList,
           resultFeild: 'data.list',
           labelFeild: 'shopName',
-          valueFeild: 'shopId'
+          valueFeild: 'shopId',
+          params: {
+            hbStationNo: 'DJK'
+          }
         }
       },
       {

+ 6 - 0
src/views/order-manage/after-sales-order-detail/index.vue

@@ -148,6 +148,12 @@ function handleDetail(orderNumber: string) {
           <div>售后方式:{{ orderInfo.refundType == 1 ? '整单退款' : '部分退款' }}</div>
           <div>退款原因:{{ orderInfo.buyerReason }} {{ orderInfo.buyerDesc }}</div>
           <div>退款件数:{{ orderInfo.goodsNum }}</div>
+          <div v-if="orderInfo.refundGoodsType != null">
+            退款方式:{{ orderInfo.refundGoodsType == 1 ? '自行配送' : '快递寄送' }}
+          </div>
+          <div v-if="orderInfo.refundGoodsType == 0 && orderInfo.trackingNumber">
+            快递单号:{{ orderInfo.trackingNumber }}
+          </div>
           <div class="py-20px font-semibold">02 退款商品&费用</div>
           <NDataTable :columns="refundOrderColumns" :data="orderInfo.orderRefundSkuVoList" :bordered="false" />
 

+ 20 - 2
src/views/order-manage/recharge-records/index.vue

@@ -3,6 +3,7 @@ import { computed } from 'vue';
 // import dayjs from 'dayjs';
 // import { fetchGetStoreList } from '@/service/api/xsb-manage/store-info';
 import { fetchList } from '@/service/api/order-manage/recharge-records';
+import { fetchChannelList } from '@/service/api/h5-manage/channel-manage';
 import { commonExport } from '@/utils/common';
 import { useTable } from '@/components/zt/Table/hooks/useTable';
 
@@ -17,6 +18,12 @@ const columns: NaiveUI.TableColumn<Api.goods.ShopSku>[] = [
     title: '用户手机号',
     align: 'center'
   },
+  {
+    key: 'accessName',
+    title: '渠道',
+    align: 'center',
+    width: 120
+  },
   {
     key: 'actualTotal',
     title: '充值金额',
@@ -98,7 +105,18 @@ const [registerTable, { getTableData, getSeachForm, setTableLoading }] = useTabl
           ]
         }
       },
-
+      {
+        field: 'accessIds',
+        label: '渠道',
+        component: 'ApiSelect',
+        componentProps: {
+          api: fetchChannelList,
+          multiple: true,
+          resultFeild: 'data.list',
+          labelFeild: 'accessName',
+          valueFeild: 'accessId'
+        }
+      },
       {
         label: '更新时间',
         component: 'NDatePicker',
@@ -116,7 +134,7 @@ const [registerTable, { getTableData, getSeachForm, setTableLoading }] = useTabl
   },
   tableConfig: {
     keyField: 'skuId',
-    title: '积分明细',
+    title: '充值订单',
     showAddButton: false,
     fieldMapToTime: [['createTime', ['startTime', 'endTime']]]
   }

+ 182 - 0
src/views/reconciliation-center/points-checking/index.vue

@@ -0,0 +1,182 @@
+<script setup lang="tsx">
+import { computed } from 'vue';
+import { useRouter } from 'vue-router';
+import { NButton } from 'naive-ui';
+// import dayjs from 'dayjs';
+// import { fetchGetStoreList } from '@/service/api/xsb-manage/store-info';
+import { fetchGetChannelList, fetchList } from '@/service/api/reconciliation-center/points-checking';
+import { commonExport } from '@/utils/common';
+import { useTable } from '@/components/zt/Table/hooks/useTable';
+const router = useRouter();
+
+const columns: NaiveUI.TableColumn<Api.goods.ShopSku>[] = [
+  {
+    key: 'transactionDate',
+    title: '交易日',
+    align: 'left',
+    width: 150
+  },
+  {
+    key: 'enterpriseName',
+    title: '企业',
+    align: 'center',
+    width: 200
+  },
+  {
+    key: 'openingPoints',
+    title: '期初积分',
+    align: 'center',
+    render: row => {
+      return (
+        <div class={'flex items-center justify-center'}>
+          {row.openingPoints}
+          {row.isFirst ? <div class={'ml-2 rounded-4px bg-black text-12px text-white'}>初始</div> : ''}
+        </div>
+      );
+    }
+  },
+  {
+    key: 'rechargePoints',
+    title: '充值积分',
+    align: 'center'
+  },
+  {
+    key: 'consumePoints',
+    title: '消费积分',
+    align: 'center'
+  },
+
+  {
+    key: 'exchangePoints',
+    title: '兑换',
+    align: 'center'
+  },
+  {
+    key: 'returnPoints',
+    title: '返还',
+    align: 'center'
+  },
+  {
+    key: 'expirePoints',
+    title: '过期积分',
+    align: 'center'
+  },
+  {
+    key: 'adjustPoints',
+    title: '冲正',
+    align: 'center'
+  },
+  {
+    key: 'expectedClosingPoints',
+    title: '期末应有积分',
+    align: 'center'
+  },
+  {
+    key: 'actualBalancePoints',
+    title: '实际余额积分',
+    align: 'center'
+  },
+  {
+    key: 'status',
+    title: '状态',
+    align: 'center',
+    render(row) {
+      return <div style={row.status == 1 ? 'color: white' : 'color: green'}>{row.status == 1 ? '异常' : '正常'}</div>;
+    }
+  }
+];
+
+const rowClassName = (row: any) => {
+  if (row.status == 1) {
+    return 'hight-light';
+  }
+  return '';
+};
+
+const [registerTable, { getTableData, getSeachForm, setTableLoading }] = useTable({
+  searchFormConfig: {
+    schemas: [
+      {
+        label: '企业',
+        component: 'ApiSelect',
+        field: 'enterpriseId',
+        componentProps: {
+          api: fetchGetChannelList,
+          resultFeild: 'data',
+          labelFeild: 'channelName',
+          valueFeild: 'channelId'
+        }
+      },
+      {
+        label: '交易日',
+        component: 'NDatePicker',
+        field: 'transactionDate',
+        componentProps: {
+          type: 'date',
+          valueFormat: 'yyyy-MM-dd'
+        }
+      }
+    ],
+    inline: false,
+    size: 'small',
+    labelPlacement: 'left',
+    isFull: false
+  },
+  tableConfig: {
+    keyField: 'skuId',
+    title: '积分对账',
+    showAddButton: false,
+    scrollX: 1800,
+    rowClassName
+  }
+});
+
+const tableData = computed(() => {
+  return getTableData();
+});
+
+function handle(row: any) {
+  console.log(row);
+  router.push({
+    path: '/reconciliation-center/points-details',
+    query: {
+      transactionDate: row.transactionDate,
+      channelId: row.enterpriseId,
+      mode: 'reversal'
+    }
+  });
+}
+
+async function handleExport() {
+  setTableLoading(true);
+  try {
+    await commonExport('/smqjh-system/app-api/v1/claim/export', getSeachForm(), '积分对账列表.xlsx');
+  } finally {
+    setTableLoading(false);
+  }
+}
+</script>
+
+<template>
+  <LayoutTable>
+    <ZTable :columns="columns" :api="fetchList" @register="registerTable">
+      <template v-if="false" #prefix="{ loading }">
+        <NSpace>
+          <NButton size="small" :disabled="tableData.length == 0" :loading="loading" @click="handleExport">
+            导出全部
+          </NButton>
+        </NSpace>
+      </template>
+
+      <template #op="{ row }">
+        <NButton size="small" ghost type="primary" @click="handle(row)">去处理</NButton>
+      </template>
+    </ZTable>
+  </LayoutTable>
+</template>
+
+<style scoped>
+:deep(.hight-light td) {
+  background-color: rgba(252, 4, 4, 0.6);
+}
+</style>

+ 289 - 0
src/views/reconciliation-center/points-details/index.vue

@@ -0,0 +1,289 @@
+<script setup lang="tsx">
+import { computed, onMounted, ref } from 'vue';
+import { useRoute } from 'vue-router';
+import { NButton } from 'naive-ui';
+// import dayjs from 'dayjs';
+// import { fetchGetStoreList } from '@/service/api/xsb-manage/store-info';
+import {
+  fetchDetail,
+  fetchGetChannelList,
+  fetchList,
+  fetchReversal
+} from '@/service/api/reconciliation-center/points-details';
+import { useAuth } from '@/hooks/business/auth';
+import { commonExport } from '@/utils/common';
+import { useTable } from '@/components/zt/Table/hooks/useTable';
+import { useModalFrom } from '@/components/zt/ModalForm/hooks/useModalForm';
+import { useModal } from '@/components/zt/Modal/hooks/useModal';
+const route = useRoute();
+const detailData = ref<any>(null);
+const columns: NaiveUI.TableColumn<Api.goods.ShopSku>[] = [
+  {
+    key: 'updateTime',
+    title: '更新时间',
+    align: 'center',
+    width: 200
+  },
+  {
+    key: 'realName',
+    title: '姓名',
+    align: 'center'
+  },
+  {
+    key: 'mobile',
+    title: '用户手机号',
+    align: 'center'
+  },
+  {
+    key: 'channelName',
+    title: '企业',
+    align: 'center'
+  },
+  {
+    key: 'businessScene',
+    title: '业务场景',
+    align: 'center'
+  },
+  {
+    key: 'pointsActionType',
+    title: '类型',
+    align: 'center'
+  },
+  {
+    key: 'variablePoints',
+    title: '变动积分',
+    align: 'center'
+  },
+  {
+    key: 'currentlyAvailablePoints',
+    title: '变动后积分',
+    align: 'center'
+  },
+  {
+    key: 'orderNumber',
+    title: '关联订单',
+    align: 'center'
+  }
+];
+
+const [registerTable, { refresh, getTableData, setFieldsValue, getSeachForm, setTableLoading }] = useTable({
+  searchFormConfig: {
+    schemas: [
+      {
+        label: '手机号',
+        component: 'NInput',
+        field: 'mobile'
+      },
+
+      {
+        field: 'businessScene',
+        label: '业务场景',
+        component: 'dictSelect',
+        componentProps: {
+          dictCode: 'sys_business_type',
+          immediate: true,
+          extraOptions: [
+            {
+              label: '充值',
+              value: 'CZ'
+            },
+            {
+              label: '过期',
+              value: 'GQ'
+            }
+          ]
+        }
+      },
+
+      {
+        label: '更新时间',
+        component: 'NDatePicker',
+        field: 'createTime',
+        componentProps: {
+          type: 'datetimerange',
+          defaultTime: ['00:00:00', '23:59:59']
+        }
+      },
+      {
+        label: '企业',
+        component: 'ApiSelect',
+        field: 'channelId',
+        componentProps: {
+          api: fetchGetChannelList,
+          resultFeild: 'data',
+          labelFeild: 'channelName',
+          valueFeild: 'channelId'
+        }
+      }
+    ],
+    inline: false,
+    size: 'small',
+    labelPlacement: 'left',
+    isFull: false
+  },
+  tableConfig: {
+    keyField: 'skuId',
+    title: '积分明细',
+    showAddButton: false,
+    scrollX: 1800,
+    fieldMapToTime: [['createTime', ['startTime', 'endTime']]]
+  }
+});
+
+const [registerModal, { openModal, setModalLoading }] = useModal({
+  title: '查看',
+  width: 500,
+  height: 400,
+  isShowHeaderText: false
+});
+
+const [
+  registerModalForm,
+  {
+    openModal: openModalForm,
+    setFieldsValue: setModalFormValue,
+    getFieldsValue: getModalFormValue,
+    closeModal: closeModalForm,
+    setSubLoading
+  }
+] = useModalFrom({
+  modalConfig: {
+    title: '优惠券',
+    isShowHeaderText: true
+  },
+  formConfig: {
+    schemas: [
+      {
+        field: 'id',
+        label: 'ID',
+        show: false,
+        component: 'NInput'
+      },
+      {
+        field: 'type',
+        label: '差额冲正',
+        component: 'NRadioGroup',
+        required: true,
+        componentProps: {
+          options: [
+            {
+              label: '增加',
+              value: 0
+            },
+            {
+              label: '扣除',
+              value: 1
+            }
+          ]
+        },
+        defaultValue: 0
+      },
+      {
+        field: 'variablePoints',
+        component: 'NInput',
+        label: '积分数量',
+        required: true,
+        componentProps: {
+          placeholder: '请输入积分数量'
+        }
+      },
+      {
+        field: 'remark',
+        component: 'NInput',
+        label: '备注',
+        required: true,
+        componentProps: {
+          type: 'textarea',
+          rows: 3
+        }
+      }
+    ],
+    labelWidth: 120,
+    layout: 'horizontal',
+    gridProps: {
+      cols: '1',
+      itemResponsive: true
+    }
+  }
+});
+
+const tableData = computed(() => {
+  return getTableData();
+});
+
+function handle(row: any) {
+  console.log(row);
+  openModalForm();
+  setModalFormValue({
+    id: row.id
+  });
+}
+
+async function handleDetail(row: any) {
+  openModal();
+  setModalLoading(true);
+  const { data, error } = await fetchDetail(row.id);
+  if (!error) {
+    setModalLoading(false);
+    detailData.value = data;
+  }
+}
+async function handleExport() {
+  setTableLoading(true);
+  try {
+    await commonExport('/smqjh-system/app-api/v1/claim/export', getSeachForm(), '积分明细列表.xlsx');
+  } finally {
+    setTableLoading(false);
+  }
+}
+
+async function handleSubmit() {
+  const form = await getModalFormValue();
+  setSubLoading(false);
+  const { error } = await fetchReversal(form);
+  if (error) {
+    return;
+  }
+  closeModalForm();
+  refresh();
+}
+
+onMounted(async () => {
+  if (route.query.transactionDate) {
+    await setFieldsValue({
+      channelId: Number(route.query.channelId),
+      createTime: [`${route.query.transactionDate} 00:00:00`, `${route.query.transactionDate} 23:59:59`]
+    });
+  }
+  refresh();
+});
+</script>
+
+<template>
+  <LayoutTable>
+    <ZTable :columns="columns" :api="fetchList" :immediate="false" @register="registerTable">
+      <template #prefix="{ loading }">
+        <NSpace>
+          <NButton size="small" :disabled="tableData.length == 0" :loading="loading" @click="handleExport">
+            导出全部
+          </NButton>
+        </NSpace>
+      </template>
+      <template v-if="useAuth().hasAuth('points-details:reversal') && route.query.mode == 'reversal'" #op="{ row }">
+        <NButton v-if="row.isAdjust" size="small" ghost type="primary" @click="handleDetail(row)">查看</NButton>
+        <NButton v-else size="small" ghost type="primary" @click="handle(row)">冲正</NButton>
+      </template>
+    </ZTable>
+    <BasicModal @register="registerModal">
+      <div class="text-14px font-600">处理结果</div>
+      <div>处理方式:{{ detailData?.type === 0 ? '增加' : '扣除' }}{{ detailData?.variablePoints || 0 }}</div>
+      <div>备注:{{ detailData?.remark }}</div>
+
+      <div>处理人:{{ detailData?.username }}</div>
+      <div>处理时间:{{ detailData?.updateTime }}</div>
+    </BasicModal>
+    <BasicModelForm @register-modal-form="registerModalForm" @submit-form="handleSubmit"></BasicModelForm>
+  </LayoutTable>
+</template>
+
+<style scoped></style>