Selaa lähdekoodia

feat(user-info): 完善用户信息列表及详情支持企业筛选与金额字段展示

- 新增用户余额和累计消费的显示与格式化,支持排序功能
- 用户列表新增所属企业筛选,后台接口增加firmId参数支持
- 更新用户信息接口与VO,增加当前余额和累计消费字段
- 优化数据查询SQL,支持按余额和累计消费排序
- 页面删除新增功能、调整详情弹窗显示内容
- 调整表头和表格列配置,优化操作按钮样式与宽度
- 代码重构及样式调整,提高金额显示的可读性
SheepHy 2 päivää sitten
vanhempi
commit
f31aac6173
2 muutettua tiedostoa jossa 132 lisäystä ja 146 poistoa
  1. 25 19
      src/api/userManage/user-info-api.ts
  2. 107 127
      src/views/userManage/user-info/index.vue

+ 25 - 19
src/api/userManage/user-info-api.ts

@@ -68,38 +68,44 @@ export default UserInfoAPI;
 
 /** 个人用户信息分页查询参数 */
 export interface UserInfoPageQuery extends PageQuery {
-    /** 所属集团编号 */
-    ecId?: number;
     /** 手机号 */
     phone?: string;
-    /** 所属第三方(无则为自营) */
-    groupId?: number;
+    /** 所属企业ID */
+    firmId?: number;
+    /** 排序字段 */
+    sortField?: string;
+    /** 排序方式: ascending/descending */
+    sortOrder?: string;
 }
 
 /** 个人用户信息表单对象 */
 export interface UserInfoForm {
-    /** 所属集团编号 */
-    ecId?:  number;
+    /** 主键 */
+    id?: number;
+    /** 昵称 */
+    nickName?: string;
     /** 手机号 */
-    phone?:  string;
-    /** 积分 */
-    integralNum?:  number;
-    /** 所属第三方(无则为自营) */
-    groupId?:  number;
-    /** 创建时间 */
-    createTime?:  Date;
+    phone?: string;
+    /** 微信openid */
+    openid?: string;
 }
 
 /** 个人用户信息分页对象 */
 export interface UserInfoPageVO {
-    /** 所属集团编号 */
-    ecId?: number;
+    /** 主键ID */
+    id?: number;
+    /** 昵称 */
+    nickName?: string;
+    /** 所属企业 */
+    firmName?: string;
     /** 手机号 */
     phone?: string;
-    /** 积分 */
-    integralNum?: number;
-    /** 所属第三方(无则为自营) */
-    groupId?: number;
+    /** 微信openid */
+    openid?: string;
+    /** 当前余额 */
+    balance?: number;
+    /** 累计消费 */
+    totalConsumption?: number;
     /** 创建时间 */
     createTime?: Date;
 }

+ 107 - 127
src/views/userManage/user-info/index.vue

@@ -18,16 +18,17 @@
       @toolbar-click="handleToolbarClick"
       @operate-click="handleOperateClick"
       @filter-change="handleFilterChange"
-    ></page-content>
+      @sort-change="handleSortChange"
+    >
+      <template #balance="scope">
+        <span class="money-text primary">¥ {{ formatMoney(scope.row.balance) }}</span>
+      </template>
+      <template #totalConsumption="scope">
+        <span class="money-text warning">¥ {{ formatMoney(scope.row.totalConsumption) }}</span>
+      </template>
+    </page-content>
 
-    <!-- 新增 -->
-    <page-modal
-      ref="addModalRef"
-      :modal-config="addModalConfig"
-      @submit-click="handleSubmitClick"
-    ></page-modal>
-
-    <!-- 编辑 -->
+    <!-- 详情 -->
     <page-modal
       ref="editModalRef"
       :modal-config="editModalConfig"
@@ -40,6 +41,7 @@
 defineOptions({ name: "UserInfo" });
 
 import UserInfoAPI, { UserInfoForm, UserInfoPageQuery } from "@/api/userManage/user-info-api";
+import UserFirmAPI from "@/api/toBManage/user-firm-api";
 import type { IObject, IModalConfig, IContentConfig, ISearchConfig } from "@/components/CURD/types";
 import usePage from "@/components/CURD/usePage";
 
@@ -47,7 +49,6 @@ import usePage from "@/components/CURD/usePage";
 const {
   searchRef,
   contentRef,
-  addModalRef,
   editModalRef,
   handleQueryClick,
   handleResetClick,
@@ -59,20 +60,19 @@ const {
   handleFilterChange,
 } = usePage();
 
+// 金额格式化函数
+const formatMoney = (value: number | undefined | null): string => {
+  if (value === null || value === undefined) return "0.00";
+  return Math.abs(value).toLocaleString("zh-CN", {
+    minimumFractionDigits: 2,
+    maximumFractionDigits: 2,
+  });
+};
+
 // 搜索配置
 const searchConfig: ISearchConfig = reactive({
   permPrefix: "business:user-info",
   formItems: [
-    {
-      type: "input",
-      label: "所属集团编号",
-      prop: "ecId",
-      attrs: {
-        placeholder: "所属集团编号",
-        clearable: true,
-        style: { width: "200px" },
-      },
-    },
     {
       type: "input",
       label: "手机号",
@@ -84,14 +84,29 @@ const searchConfig: ISearchConfig = reactive({
       },
     },
     {
-      type: "input",
-      label: "所属第三方", //(无则为自营)
-      prop: "groupId",
+      type: "select",
+      label: "所属企业",
+      prop: "firmId",
       attrs: {
-        placeholder: "所属第三方",
+        placeholder: "请选择企业",
         clearable: true,
+        filterable: true,
         style: { width: "200px" },
       },
+      options: [],
+      async initFn(formItem) {
+        try {
+          const response = await UserFirmAPI.getFirmList();
+          if (Array.isArray(response)) {
+            formItem.options = response.map((item: any) => ({
+              label: item.name,
+              value: item.id,
+            }));
+          }
+        } catch (error) {
+          console.error("Failed to fetch firm list:", error);
+        }
+      },
     },
   ],
 });
@@ -108,8 +123,6 @@ const contentConfig: IContentConfig<UserInfoPageQuery> = reactive({
   pk: "id",
   // 列表查询接口
   indexAction: UserInfoAPI.getPage,
-  // 删除接口
-  deleteAction: UserInfoAPI.deleteByIds,
   // 数据解析函数
   parseData(res: any) {
     return {
@@ -128,16 +141,30 @@ const contentConfig: IContentConfig<UserInfoPageQuery> = reactive({
   defaultToolbar: ["refresh", "filter"],
   // 表格列配置
   cols: [
-    { type: "selection", width: 55, align: "center" },
-    { label: "所属集团编号", prop: "ecId" },
+    { type: "selection", width: 50, align: "center" },
+    { label: "用户ID", prop: "id", width: 100 },
     { label: "手机号", prop: "phone" },
-    { label: "积分", prop: "integralNum" },
-    { label: "所属第三方", prop: "groupId" }, //(无则为自营)
+    { label: "昵称", prop: "nickName" },
+    { label: "所属企业", prop: "firmName" },
+    {
+      label: "当前余额",
+      prop: "balance",
+      sortable: "custom",
+      templet: "custom",
+      slotName: "balance",
+    },
+    {
+      label: "累计消费",
+      prop: "totalConsumption",
+      sortable: "custom",
+      templet: "custom",
+      slotName: "totalConsumption",
+    },
     { label: "创建时间", prop: "createTime" },
     {
       label: "操作",
       prop: "operation",
-      width: 220,
+      width: 100,
       templet: "tool",
       operat: [
         {
@@ -145,7 +172,9 @@ const contentConfig: IContentConfig<UserInfoPageQuery> = reactive({
           text: "详情",
           attrs: {
             type: "primary",
-            icon: "el-icon-view",
+            icon: "view",
+            link: true,
+            size: "small",
           },
         },
       ],
@@ -153,97 +182,24 @@ const contentConfig: IContentConfig<UserInfoPageQuery> = reactive({
   ],
 });
 
-// 新增配置
-const addModalConfig: IModalConfig<UserInfoForm> = reactive({
-  // 权限前缀
-  permPrefix: "business:user-info",
-  // 主键
-  pk: "id",
-  // 弹窗配置
-  dialog: {
-    title: "新增",
-    width: 800,
-    draggable: true,
-  },
-  form: {
-    labelWidth: 100,
-  },
-  // 表单项配置
-  formItems: [
-    {
-      type: "input",
-      attrs: {
-        placeholder: "所属集团编号",
-      },
-      label: "所属集团编号",
-      prop: "ecId",
-    },
-    {
-      type: "input",
-      attrs: {
-        placeholder: "手机号",
-      },
-      label: "手机号",
-      prop: "phone",
-    },
-    {
-      type: "input",
-      attrs: {
-        placeholder: "积分",
-      },
-      label: "积分",
-      prop: "integralNum",
-    },
-    {
-      type: "input",
-      attrs: {
-        placeholder: "所属第三方(无则为自营)",
-      },
-      label: "所属第三方(无则为自营)",
-      prop: "groupId",
-    },
-    {
-      type: "input",
-      attrs: {
-        placeholder: "创建时间",
-      },
-      label: "创建时间",
-      prop: "createTime",
-    },
-  ],
-  // 提交函数
-  formAction: (data: UserInfoForm) => {
-    if (data.id) {
-      // 编辑
-      return UserInfoAPI.update(data.id as string, data);
-    } else {
-      // 新增
-      return UserInfoAPI.create(data);
-    }
-  },
-});
-
-// 编辑配置
+// 详情配置
 const editModalConfig: IModalConfig<UserInfoForm> = reactive({
   permPrefix: "business:user-info",
   component: "drawer",
   drawer: {
-    title: "编辑",
+    title: "用户详情",
     size: 500,
   },
   pk: "id",
-  formAction(data: any) {
-    return UserInfoAPI.update(data.id as string, data);
-  },
   formItems: [
     {
       type: "input",
       attrs: {
-        placeholder: "所属集团编号",
+        placeholder: "用户ID",
         disabled: true,
       },
-      label: "所属集团编号",
-      prop: "ecId",
+      label: "用户ID",
+      prop: "id",
     },
     {
       type: "input",
@@ -257,31 +213,22 @@ const editModalConfig: IModalConfig<UserInfoForm> = reactive({
     {
       type: "input",
       attrs: {
-        placeholder: "积分",
+        placeholder: "昵称",
         disabled: true,
       },
-      label: "积分",
-      prop: "integralNum",
+      label: "昵称",
+      prop: "nickName",
     },
     {
       type: "input",
       attrs: {
-        placeholder: "所属第三方", //(无则为自营)
+        placeholder: "微信openid",
         disabled: true,
       },
-      label: "所属第三方", //(无则为自营)
-      prop: "groupId",
+      label: "微信openid",
+      prop: "openid",
     },
-    {
-      type: "input",
-      attrs: {
-        placeholder: "创建时间",
-        disabled: true,
-      },
-      label: "创建时间",
-      prop: "createTime",
-    },
-  ], // 复用新增的表单项
+  ],
 });
 
 // 处理操作按钮点击
@@ -293,8 +240,41 @@ const handleOperateClick = (data: IObject) => {
   }
 };
 
-// 处理工具栏按钮点击(删除等)
+// 处理工具栏按钮点击
 const handleToolbarClick = (name: string) => {
   console.log(name);
 };
+
+// 排序参数
+const sortParams = reactive({
+  sortField: "",
+  sortOrder: "",
+});
+
+// 处理排序变化
+const handleSortChange = (data: { prop: string; order: string | null }) => {
+  sortParams.sortField = data.prop || "";
+  sortParams.sortOrder = data.order || "";
+  // 带着排序参数重新查询
+  contentRef.value?.fetchPageData({ ...sortParams });
+};
 </script>
+
+<style scoped>
+.money-text {
+  font-weight: bold;
+  font-size: 13px;
+}
+.money-text.primary {
+  color: #409eff;
+}
+.money-text.success {
+  color: #67c23a;
+}
+.money-text.danger {
+  color: #f56c6c;
+}
+.money-text.warning {
+  color: #e6a23c;
+}
+</style>