fangmingyue 1 年之前
父節點
當前提交
e2572ff6e1
共有 5 個檔案被更改,包括 250 行新增40 行删除
  1. 95
    11
      src/pages/member/Edit.jsx
  2. 16
    13
      src/pages/member/components/MemberCardInfo.jsx
  3. 110
    0
      src/pages/query/index.jsx
  4. 12
    2
      src/routes/routes.jsx
  5. 17
    14
      src/utils/request.js

+ 95
- 11
src/pages/member/Edit.jsx 查看文件

@@ -1,17 +1,37 @@
1 1
 import { getTaMemberId } from "@/services/taMember";
2 2
 import { Card } from "antd";
3
-import React, { useEffect, useState } from "react";
3
+import React, { useEffect, useState, useRef } from "react";
4 4
 import { useSearchParams } from "react-router-dom";
5 5
 import Page from "@/components/Page";
6
+import { ProTable } from '@ant-design/pro-components';
6 7
 import MemberInfo from "./components/MemberInfo";
7 8
 import MemberCardInfo from "./components/MemberCardInfo";
9
+import moment from "moment";
10
+import {
11
+  BILL_CONSUME,
12
+  BILL_REFUND,
13
+  BILL_RECHARGE,
14
+  BILL_WITHDRAW,
15
+} from "@/utils/biz";
16
+import { getTaOrder } from "@/services/taOrder";
17
+import { getSysUser } from "@/services/sysUser";
18
+import { queryTable, queryDict } from "@/utils/request";
8 19
 import "./index.less";
9 20
 // import Pages from "./components/Pages";
10 21
 export default (props) => {
22
+
23
+  const actionRef = React.useRef();
24
+
11 25
   const [params] = useSearchParams();
12 26
   const [activeTabKey, setActiveTabKey] = useState("tab1");
13 27
   const [memberList, setMemberList] = useState();
28
+  const [memberCardId, setMemberCardId] = useState();
14 29
   const id = params.get("id");
30
+  const tab = params.get("tab");
31
+
32
+  const TaOrderList = queryTable(getTaOrder);
33
+
34
+  const TaSysUserList = queryDict(getSysUser, { labelKey: "userName", valueKey: "userId" });
15 35
 
16 36
   useEffect(() => {
17 37
     if (id) {
@@ -21,23 +41,87 @@ export default (props) => {
21 41
     }
22 42
   }, []);
23 43
 
44
+  useEffect(() => {
45
+    if (tab) {
46
+      setActiveTabKey(tab);
47
+    }
48
+  }, [tab]);
49
+
50
+  const tabList = [
51
+    {
52
+      key: "tab1",
53
+      tab: "会员信息",
54
+    },
55
+    {
56
+      key: "tab2",
57
+      tab: "会员卡信息",
58
+    },
59
+  ];
60
+
61
+  const contentList = {
62
+    tab1: <MemberInfo memberList={memberList} />,
63
+    tab2: <MemberCardInfo memberId={id} setMemberCardId={setMemberCardId} />,
64
+  };
65
+
66
+  const columns = [
67
+    {
68
+      title: '会员名称',
69
+      dataIndex: "memberName",
70
+    },
71
+    {
72
+      title: "消费类型",
73
+      dataIndex: "billType",
74
+      render: (it) =>
75
+        it == BILL_CONSUME
76
+          ? "消费"
77
+          : it == BILL_REFUND
78
+            ? "退款"
79
+            : it == BILL_RECHARGE
80
+              ? "充值-开卡"
81
+              : it == BILL_WITHDRAW
82
+                ? "提现"
83
+                : "未知",
84
+    },
85
+    {
86
+      title: "消费时间",
87
+      dataIndex: "createdAt",
88
+      render: (it) => moment(it).format("YYYY-MM-DD HH:mm:ss"),
89
+    },
90
+    {
91
+      title: '操作人',
92
+      dataIndex: "createdBy",
93
+      valueType: "select",
94
+      request: TaSysUserList,
95
+    },
96
+  ];
97
+
98
+
24 99
   return (
25 100
     <Page back>
26 101
       <Card
27
-        title="会员信息"
28 102
         className="scorll"
103
+        tabList={tabList}
104
+        activeTabKey={activeTabKey}
105
+        onTabChange={setActiveTabKey}
29 106
         style={{ width: "100%", overflowY: "scroll", maxHeight: "700px", marginBottom: "24px" }}
30 107
       >
31
-        <MemberInfo memberList={memberList} />
32
-      </Card>
33
-
34
-      <Card
35
-        title="会员卡信息"
36
-        className="scorll"
37
-        style={{ width: "100%", overflowY: "scroll" }}
38
-      >
39
-        <MemberCardInfo memberId={id} />
108
+        {contentList[activeTabKey]}
40 109
       </Card>
110
+      {
111
+        memberCardId && (
112
+          <Card title="消费记录" style={{ marginTop: '24px' }}>
113
+            <ProTable
114
+              actionRef={actionRef}
115
+              rowKey="cardId"
116
+              columns={columns}
117
+              params={{ memberCardId: memberCardId }}
118
+              options={false}
119
+              search={false}
120
+              request={TaOrderList}
121
+            />
122
+          </Card>
123
+        )
124
+      }
41 125
     </Page>
42 126
   );
43 127
 };

+ 16
- 13
src/pages/member/components/MemberCardInfo.jsx 查看文件

@@ -2,21 +2,30 @@ import React, { useEffect, useState } from "react";
2 2
 import { Button, Card, Switch, Table } from "antd";
3 3
 import { ProTable } from "@ant-design/pro-components";
4 4
 import { getTaMemberCard } from "@/services/taMemberCard";
5
-import { queryTable } from "@/utils/request";
5
+import { getTaPackage } from "@/services/taPackage";
6
+import { getTaOrder } from "@/services/taOrder";
7
+import { queryTable, queryDict } from "@/utils/request";
6 8
 import moment from "moment";
7 9
 import MemberOrderModal from "./MemberOrderModal";
8 10
 
11
+const PackageNameList = queryDict(getTaPackage, { labelKey: "packageName", valueKey: "packageId" });
12
+
9 13
 export default (props) => {
10
-  const { memberId } = props;
14
+  const { memberId, setMemberCardId } = props;
11 15
   const actionRef = React.useRef();
12 16
 
13 17
   const TaMemberCardList = queryTable(() =>
14 18
     getTaMemberCard({ memberId: memberId })
15 19
   );
16
-  const [id, setId] = useState();
17
-  const [open, setOpen] = useState(false);
18 20
 
19 21
   const columns = [
22
+    {
23
+      title: "套餐名称",
24
+      dataIndex: "packageId",
25
+      valueType: 'select',
26
+      request: PackageNameList,
27
+      ellipsis: true,
28
+    },
20 29
     {
21 30
       title: "开卡人姓名",
22 31
       dataIndex: "memberName",
@@ -57,7 +66,7 @@ export default (props) => {
57 66
           style={{ padding: 0 }}
58 67
           type="link"
59 68
           key={1}
60
-          onClick={() => onClickOpen(record)}
69
+          onClick={() => onClick(record)}
61 70
         >
62 71
           消费记录
63 72
         </Button>,
@@ -65,13 +74,8 @@ export default (props) => {
65 74
     },
66 75
   ];
67 76
 
68
-  const onClickOpen = (val) => {
69
-    setId(val?.cardId);
70
-    setOpen(true);
71
-  };
72
-
73
-  const onCancel = () => {
74
-    setOpen(false);
77
+  const onClick = (val) => {
78
+    setMemberCardId(val?.cardId);
75 79
   };
76 80
 
77 81
   return (
@@ -84,7 +88,6 @@ export default (props) => {
84 88
         search={false}
85 89
         request={TaMemberCardList}
86 90
       />
87
-      <MemberOrderModal open={open} onCancel={onCancel} id={id} />
88 91
     </>
89 92
   );
90 93
 };

+ 110
- 0
src/pages/query/index.jsx 查看文件

@@ -0,0 +1,110 @@
1
+import React, { useRef } from "react";
2
+import List from "@/components/Page/List";
3
+import { getTaOrder } from "@/services/taOrder";
4
+import { getTaMemberCard } from "@/services/taMemberCard";
5
+import moment from "moment";
6
+import Page from '@/components/Page';
7
+import { ProTable } from '@ant-design/pro-components';
8
+import { queryTable, queryDict } from "@/utils/request";
9
+import { getSysUser } from "@/services/sysUser";
10
+import {
11
+  BILL_CONSUME,
12
+  BILL_REFUND,
13
+  BILL_RECHARGE,
14
+  BILL_WITHDRAW,
15
+} from "@/utils/biz";
16
+
17
+const TaOrderList = queryTable(getTaOrder);
18
+
19
+const TaSysUserList = queryDict(getSysUser, { labelKey: "userName", valueKey: "userId" });
20
+export default (props) => {
21
+  const actionRef = useRef();
22
+
23
+  const columns = [
24
+    {
25
+      title: "会员名称",
26
+      dataIndex: "memberName",
27
+    },
28
+    {
29
+      title: '套餐名称',
30
+      dataIndex: "packageName",
31
+      search: false
32
+    },
33
+    {
34
+      title: "消费类型",
35
+      dataIndex: "billType",
36
+      valueType: "select",
37
+      valueEnum: {
38
+        'consume': '消费',
39
+        'refund': '退款',
40
+        'recharge': '充值-开卡',
41
+        'withdraw': '提现',
42
+      }
43
+    },
44
+    {
45
+      title: "总费用",
46
+      dataIndex: "totalCharge",
47
+      search: false
48
+    },
49
+    {
50
+      title: "数量",
51
+      dataIndex: "totalAmount",
52
+      search: false
53
+    },
54
+    {
55
+      title: "单价",
56
+      dataIndex: "unitCharge",
57
+      search: false
58
+    },
59
+    {
60
+      title: "原始价格",
61
+      dataIndex: "fullCharge",
62
+      search: false
63
+    },
64
+    {
65
+      title: "下单日期",
66
+      dataIndex: "orderDate",
67
+      render: (it) => (it == '-' ? '-' : moment(it).format("YYYY-MM-DD HH:mm:ss")),
68
+      search: false
69
+    },
70
+    {
71
+      title: "下单人名称",
72
+      dataIndex: "personName",
73
+      search: false
74
+    },
75
+    // {
76
+    //   title: "是否退单",
77
+    //   dataIndex: "isRefund",
78
+    //   valueEnum: {
79
+    //     1: '是',
80
+    //     2: '否',
81
+    //   },
82
+    //   search: false
83
+    // },
84
+    {
85
+      title: "操作时间",
86
+      dataIndex: "createdAt",
87
+      render: (it) => (it == '-' ? '-' : moment(it).format("YYYY-MM-DD HH:mm:ss")),
88
+      search: false
89
+    },
90
+    {
91
+      title: "操作人",
92
+      dataIndex: "createdBy",
93
+      valueType: "select",
94
+      request: TaSysUserList,
95
+      search: false,
96
+    },
97
+  ]
98
+
99
+  return (
100
+    <Page>
101
+      <ProTable
102
+        cardBordered
103
+        rowKey="orderId"
104
+        columns={columns}
105
+        actionRef={actionRef}
106
+        request={TaOrderList}
107
+      />
108
+    </Page>
109
+  )
110
+}

+ 12
- 2
src/routes/routes.jsx 查看文件

@@ -15,6 +15,7 @@ import {
15 15
   BorderInnerOutlined,
16 16
   HeatMapOutlined,
17 17
   MediumOutlined,
18
+  LaptopOutlined
18 19
 } from "@ant-design/icons";
19 20
 import { Outlet, Navigate } from "react-router-dom";
20 21
 import AuthLayout from "@/layouts/AuthLayout";
@@ -29,6 +30,7 @@ import ProjectContactEdit from "@/pages/projectContact/Edit";
29 30
 import ProjectDeploy from "@/pages/projectDeploy";
30 31
 import ProjectDeployEdit from "@/pages/project/components/ProjectDeployEdit";
31 32
 import ProjectNode from "@/pages/projectNode";
33
+import Query from "@/pages/query";
32 34
 
33 35
 import Role from "@/pages/role";
34 36
 import Dept from "@/pages/dept";
@@ -146,6 +148,14 @@ export const authRoutes = [
146 148
           hideInMenu: true,
147 149
         },
148 150
       },
151
+      {
152
+        path: "query",
153
+        element: <Query />,
154
+        meta: {
155
+          title: "查询统计",
156
+          icon: <LaptopOutlined />,
157
+        },
158
+      }
149 159
     ],
150 160
   },
151 161
   {
@@ -307,7 +317,7 @@ export const defaultRoutes = [
307 317
   },
308 318
 ];
309 319
 
310
-export function mergeAuthRoutes(r1, r2) {
320
+export function mergeAuthRoutes (r1, r2) {
311 321
   const r = r1.slice();
312 322
   const children = r1[0].children.slice();
313 323
   r[0].children = children.concat(r2);
@@ -316,7 +326,7 @@ export function mergeAuthRoutes(r1, r2) {
316 326
 
317 327
 // 全部路由
318 328
 export const routes = mergeAuthRoutes(defaultRoutes, authRoutes);
319
-function getPath(parent = "/", current = "") {
329
+function getPath (parent = "/", current = "") {
320 330
   if (current.indexOf("/") === 0 || current.indexOf("http") === 0)
321 331
     return current;
322 332
   return `${parent}/${current}`.replace(/\/\//g, "/");

+ 17
- 14
src/utils/request.js 查看文件

@@ -4,7 +4,7 @@ import { message } from "antd";
4 4
 import { getToken, setToken } from "./token";
5 5
 
6 6
 const instance = axios.create({
7
-  baseURL:  import.meta.env.VITE_SERVER_BASE,
7
+  baseURL: import.meta.env.VITE_SERVER_BASE,
8 8
   timeout: 10000,
9 9
   // withCredentials: true, // 跨域
10 10
 });
@@ -21,7 +21,7 @@ instance.interceptors.request.use(
21 21
       params = {},
22 22
     } = config;
23 23
 
24
-      const token = getToken();
24
+    const token = getToken();
25 25
     let noTip = silent;
26 26
     if (noTip === undefined) {
27 27
       noTip = method.toLocaleLowerCase() === "get" ? true : false;
@@ -35,7 +35,7 @@ instance.interceptors.request.use(
35 35
       headers: {
36 36
         ...headers,
37 37
         Authorization: token || "",
38
-        "x-client-type":"pc.admin",
38
+        "x-client-type": "pc.admin",
39 39
         // "Content-Type": "application/json;charset=utf-8"
40 40
       },
41 41
       responseType: download ? "blob" : responseType,
@@ -95,7 +95,7 @@ instance.interceptors.response.use(
95 95
 
96 96
 export default instance;
97 97
 
98
-export function queryTable(apiRequest) {
98
+export function queryTable (apiRequest) {
99 99
   return function (params) {
100 100
     const { pageSize } = params;
101 101
     return apiRequest({
@@ -118,13 +118,13 @@ export function queryTable(apiRequest) {
118 118
   };
119 119
 }
120 120
 
121
-function getValueOfType(value, type) {
121
+function getValueOfType (value, type) {
122 122
   if (type == "string") return `${value}`;
123 123
   if (type == "int" || type == "integer") return value - 0;
124 124
   return value;
125 125
 }
126 126
 
127
-export function queryDict(
127
+export function queryDict (
128 128
   apiRequest,
129 129
   { labelKey = "name", valueKey = "id", valueType }
130 130
 ) {
@@ -136,11 +136,14 @@ export function queryDict(
136 136
       ...(leftParams || {}),
137 137
     })
138 138
       .then((res) => {
139
-        return res?.records?.map((x) => ({
140
-          label: x[labelKey],
141
-          value: getValueOfType(x[valueKey], valueType),
142
-          ...x,
143
-        }));
139
+        return res?.records?.map((x) => (
140
+          console.log('xiaofang-->x', x),
141
+          // console.log('xiaofang-->', x[labelKey]),
142
+          {
143
+            label: x[labelKey],
144
+            value: getValueOfType(x[valueKey], valueType),
145
+            ...x,
146
+          }));
144 147
       })
145 148
       .catch((err) => {
146 149
         return {
@@ -149,7 +152,7 @@ export function queryDict(
149 152
       });
150 153
   };
151 154
 }
152
-export function restful(url) {
155
+export function restful (url) {
153 156
   const list = (params) => instance.get(url, { params });
154 157
   const get = (id) => instance.get(`${url}/${id}`);
155 158
   const add = (data) => instance.post(url, data);
@@ -159,7 +162,7 @@ export function restful(url) {
159 162
   return [list, get, add, update, del];
160 163
 }
161 164
 
162
-export function useRequest(fn) {
165
+export function useRequest (fn) {
163 166
   const [loading, setLoading] = React.useState(false);
164 167
 
165 168
   const p = (...args) =>
@@ -179,7 +182,7 @@ export function useRequest(fn) {
179 182
   return [loading, p];
180 183
 }
181 184
 
182
-function downloadBlob(response) {
185
+function downloadBlob (response) {
183 186
   let fileName = "未知文件";
184 187
   const contentType = response.headers["content-type"];
185 188
   const contentDisposition = response.headers["content-disposition"];