Browse Source

Merge branch 'v2' of http://git.ycjcjy.com/yunzhi/crm_pc into v2

fangmingyue 1 year ago
parent
commit
2b2fb8390a

+ 1
- 0
.env View File

1
+VITE_SERVER_BASE=/api

+ 1
- 0
.env.production View File

1
+VITE_SERVER_BASE=http://api.crm2.njyunzhi.com/api/admin

+ 5
- 4
src/components/Upload/UploadImage.jsx View File

40
     if (info.file.status === 'done') {
40
     if (info.file.status === 'done') {
41
       setLoading(false);
41
       setLoading(false);
42
       const { url, fileType } = info.file.response;
42
       const { url, fileType } = info.file.response;
43
-      console.log(url)
44
-      onChange(url);
43
+      onChange(info.file.response.res);
45
     }
44
     }
46
   };
45
   };
47
 
46
 
48
   const previewUrl = getRealPath ? getRealPath(value) : value;
47
   const previewUrl = getRealPath ? getRealPath(value) : value;
49
-console.log(value)
48
+// console.log(value)
49
+// console.log(previewUrl)
50
+console.log("propsprops",props)
50
   return (
51
   return (
51
     <Upload
52
     <Upload
52
       listType="picture-card"
53
       listType="picture-card"
55
       beforeUpload={beforeUpload}
56
       beforeUpload={beforeUpload}
56
       onChange={handleChange}
57
       onChange={handleChange}
57
     >
58
     >
58
-      {value ? <img src={value} alt="avatar" style={{ width: '100%', height: '100%' }} /> : <UploadButton loading={loading} />}
59
+      {value ? <img src={previewUrl} alt="avatar" style={{ width: '100%', height: '100%' }} /> : <UploadButton loading={loading} />}
59
     </Upload>
60
     </Upload>
60
   );
61
   );
61
 }
62
 }

+ 6
- 14
src/components/Upload/request.js View File

1
-import request from '@/utils/request';
2
 
1
 
3
-const upload = (file, fileType = 'image') => {
4
-  const formData = new FormData();
5
-  formData.append("file", file);
6
-  formData.append("fileType", fileType);
7
-  return request('/upload', {
8
-    method: 'post',
9
-    data: formData,
10
-    headers: {
11
-      'Content-Type': 'multipart/form-data',
12
-    }
13
-  });
14
-}
2
+import { uploadFile as upload } from "@/store/oss";
3
+
4
+
15
 
5
 
16
 /**
6
 /**
17
  * 上传文件
7
  * 上传文件
19
  */
9
  */
20
 export function uploadFile(params) {
10
 export function uploadFile(params) {
21
   const { file, onSuccess, onError } = params;
11
   const { file, onSuccess, onError } = params;
12
+  console.log(upload)
22
   upload(file).then((res) => {
13
   upload(file).then((res) => {
23
-    onSuccess(res, file)
14
+    console.log("resresres",res)
15
+   onSuccess({res}, file);
24
   }).catch((e) => {
16
   }).catch((e) => {
25
     onError(e)
17
     onError(e)
26
   });
18
   });

+ 24
- 18
src/pages/member/components/MemberCardInfo.jsx View File

1
 import React, { useEffect, useState } from "react";
1
 import React, { useEffect, useState } from "react";
2
 import { Button, Card, Switch, Table } from "antd";
2
 import { Button, Card, Switch, Table } from "antd";
3
-import { ProTable } from '@ant-design/pro-components';
3
+import { ProTable } from "@ant-design/pro-components";
4
 import { getTaMemberCard } from "@/services/taMemberCard";
4
 import { getTaMemberCard } from "@/services/taMemberCard";
5
-import { queryTable } from '@/utils/request'
5
+import { queryTable } from "@/utils/request";
6
 import moment from "moment";
6
 import moment from "moment";
7
 import MemberOrderModal from "./MemberOrderModal";
7
 import MemberOrderModal from "./MemberOrderModal";
8
 
8
 
9
-
10
 export default (props) => {
9
 export default (props) => {
11
-  const { memberId } = props
10
+  const { memberId } = props;
12
   const actionRef = React.useRef();
11
   const actionRef = React.useRef();
13
 
12
 
14
-  const TaMemberCardList = queryTable(() => getTaMemberCard({ memberId: memberId }))
13
+  const TaMemberCardList = queryTable(() =>
14
+    getTaMemberCard({ memberId: memberId })
15
+  );
15
   const [id, setId] = useState();
16
   const [id, setId] = useState();
16
   const [open, setOpen] = useState(false);
17
   const [open, setOpen] = useState(false);
17
 
18
 
35
     {
36
     {
36
       title: "开卡日期",
37
       title: "开卡日期",
37
       dataIndex: "bizDate",
38
       dataIndex: "bizDate",
38
-      render: (it) => moment(it).format("YYYY-MM-DD HH:mm:ss")
39
+      render: (it) => (it ? moment(it).format("YYYY-MM-DD HH:mm:ss") : ""),
39
     },
40
     },
40
     {
41
     {
41
       title: "总时长",
42
       title: "总时长",
42
-      dataIndex: "totalTime"
43
+      dataIndex: "totalTime",
43
     },
44
     },
44
     {
45
     {
45
       title: "截止日期",
46
       title: "截止日期",
46
       dataIndex: "expireTime",
47
       dataIndex: "expireTime",
47
-      render: (it) => moment(it).format("YYYY-MM-DD HH:mm:ss")
48
+      render: (it) => (it ? moment(it).format("YYYY-MM-DD HH:mm:ss") : ""),
48
     },
49
     },
49
-    {
50
-      title: '操作',
51
-      valueType: 'option',
52
-      key: 'option',
50
+    { 
51
+      title: "操作",
52
+      valueType: "option",
53
+      key: "option",
53
       ellipsis: true,
54
       ellipsis: true,
54
       render: (_, record) => [
55
       render: (_, record) => [
55
-        <Button style={{ padding: 0 }} type="link" key={1} onClick={() => onClickOpen(record)}>
56
+        <Button
57
+          style={{ padding: 0 }}
58
+          type="link"
59
+          key={1}
60
+          onClick={() => onClickOpen(record)}
61
+        >
56
           消费记录
62
           消费记录
57
-        </Button>
58
-      ]
59
-    }
60
-  ]
63
+        </Button>,
64
+      ],
65
+    },
66
+  ];
61
 
67
 
62
   const onClickOpen = (val) => {
68
   const onClickOpen = (val) => {
63
-    setId(val?.cardId)
69
+    setId(val?.cardId);
64
     setOpen(true);
70
     setOpen(true);
65
   };
71
   };
66
 
72
 

+ 27
- 22
src/pages/member/components/MemberOrderModal.jsx View File

1
 import React, { useEffect, useState } from "react";
1
 import React, { useEffect, useState } from "react";
2
 import { Button } from "antd";
2
 import { Button } from "antd";
3
-import {
4
-  ModalForm,
5
-  ProTable
6
-} from '@ant-design/pro-components';
3
+import { ModalForm, ProTable } from "@ant-design/pro-components";
7
 import moment from "moment";
4
 import moment from "moment";
8
 import { getTaOrder } from "@/services/taOrder";
5
 import { getTaOrder } from "@/services/taOrder";
9
-import { queryTable } from '@/utils/request'
6
+import { queryTable } from "@/utils/request";
10
 
7
 
8
+import {
9
+  BILL_CONSUME,
10
+  BILL_REFUND,
11
+  BILL_RECHARGE,
12
+  BILL_WITHDRAW,
13
+} from "@/utils/biz";
11
 export default (props) => {
14
 export default (props) => {
12
   const { open, onCancel, id } = props;
15
   const { open, onCancel, id } = props;
13
 
16
 
14
   const actionRef = React.useRef();
17
   const actionRef = React.useRef();
15
-  const TaTaOrderList = queryTable(() => getTaOrder({ memberCardId: id }))
18
+  const TaTaOrderList = queryTable(() => getTaOrder({ memberCardId: id }));
16
 
19
 
17
   const columns = [
20
   const columns = [
18
     {
21
     {
19
       title: "消费类型",
22
       title: "消费类型",
20
       dataIndex: "billType",
23
       dataIndex: "billType",
21
-      render: (it) => it == 'consume' ? '消费' : it == 'refund' ? '退款' : it == 'recharge' ? '开卡' : it == 'withdraw' ? '提现' : '未知'
24
+      render: (it) =>
25
+        it == BILL_CONSUME
26
+          ? "消费"
27
+          : it == BILL_REFUND
28
+          ? "退款"
29
+          : it == BILL_RECHARGE
30
+          ? "充值-开卡"
31
+          : it == BILL_WITHDRAW
32
+          ? "提现"
33
+          : "未知",
22
     },
34
     },
23
     {
35
     {
24
       title: "消费时间",
36
       title: "消费时间",
25
       dataIndex: "createdAt",
37
       dataIndex: "createdAt",
26
-      render: (it) => moment(it).format("YYYY-MM-DD HH:mm:ss")
38
+      render: (it) => moment(it).format("YYYY-MM-DD HH:mm:ss"),
27
     },
39
     },
28
-  ]
40
+  ];
29
 
41
 
30
   return (
42
   return (
31
     <ModalForm
43
     <ModalForm
33
       open={open}
45
       open={open}
34
       modalProps={{
46
       modalProps={{
35
         destroyOnClose: true,
47
         destroyOnClose: true,
36
-        onCancel: onCancel
48
+        onCancel: onCancel,
37
       }}
49
       }}
38
       submitter={{
50
       submitter={{
39
         // 完全自定义整个区域
51
         // 完全自定义整个区域
40
         render: (props, doms) => {
52
         render: (props, doms) => {
41
           return [
53
           return [
42
-            <Button
43
-              onClick={onCancel}
44
-            >
45
-              取消
46
-            </Button>,
47
-            <Button
48
-              type="primary"
49
-              onClick={onCancel}
50
-            >
54
+            <Button onClick={onCancel}>取消</Button>,
55
+            <Button type="primary" onClick={onCancel}>
51
               确定
56
               确定
52
             </Button>,
57
             </Button>,
53
           ];
58
           ];
54
-        }
59
+        },
55
       }}
60
       }}
56
     >
61
     >
57
       <ProTable
62
       <ProTable
63
         request={TaTaOrderList}
68
         request={TaTaOrderList}
64
       />
69
       />
65
     </ModalForm>
70
     </ModalForm>
66
-  )
67
-}
71
+  );
72
+};

+ 24
- 8
src/pages/member/index.jsx View File

11
   const [isModalOpen, setIsModalOpen] = React.useState(false);
11
   const [isModalOpen, setIsModalOpen] = React.useState(false);
12
   const [modalTitle, setModalTitle] = React.useState("");
12
   const [modalTitle, setModalTitle] = React.useState("");
13
   const [modalObj, setModalObj] = React.useState({});
13
   const [modalObj, setModalObj] = React.useState({});
14
-
14
+  const today = moment().format("YYYY-MM-DDTHH:mm:ss");
15
+  const newToday = moment(today);
15
   const columns = [
16
   const columns = [
16
     {
17
     {
17
       title: "注册日期",
18
       title: "注册日期",
76
   const onWrite = (id) => {
77
   const onWrite = (id) => {
77
     // putTaMemberCardIdWrite().then((res) => {});
78
     // putTaMemberCardIdWrite().then((res) => {});
78
   };
79
   };
79
-const actionRef=useRef()
80
+  const actionRef = useRef();
80
 
81
 
81
-const reload=()=>{
82
-  return actionRef?.current?.reload()
83
-}
82
+  const reload = () => {
83
+    return actionRef?.current?.reload();
84
+  };
84
 
85
 
85
   return (
86
   return (
86
     <>
87
     <>
90
         // onEdit={(record) => navigate(`/member/edit?id=${record.memberId}`)}
91
         // onEdit={(record) => navigate(`/member/edit?id=${record.memberId}`)}
91
         columnOptionRender={(_, record) => {
92
         columnOptionRender={(_, record) => {
92
           const dataNum = record.taMemberCardList.reduce((total, item) => {
93
           const dataNum = record.taMemberCardList.reduce((total, item) => {
93
-            return (total += item.leftAmount);
94
+            if (!item.expireTime) {
95
+              return (total += item.leftAmount);
96
+            } else {
97
+              const endTime = moment(item.expireTime);
98
+              const expireNum = endTime.diff(newToday, "minutes");
99
+              console.log(expireNum)
100
+              if (expireNum >= 5) {
101
+                return true;
102
+              }else{
103
+                return false
104
+              }
105
+            }
94
           }, 0);
106
           }, 0);
107
+          console.log(dataNum)
108
+          console.log(record)
95
           return [
109
           return [
96
             <Button
110
             <Button
97
               key="A2"
111
               key="A2"
98
               style={{ padding: 0 }}
112
               style={{ padding: 0 }}
99
               type="link"
113
               type="link"
100
-              onClick={() => navigate(`/custom/member/edit?id=${record.memberId}`)}
114
+              onClick={() =>
115
+                navigate(`/custom/member/edit?id=${record.memberId}`)
116
+              }
101
             >
117
             >
102
               详情
118
               详情
103
             </Button>,
119
             </Button>,
134
         modalTitle={modalTitle}
150
         modalTitle={modalTitle}
135
         modalObj={modalObj}
151
         modalObj={modalObj}
136
         reload={reload}
152
         reload={reload}
137
-      /> 
153
+      />
138
     </>
154
     </>
139
   );
155
   );
140
 };
156
 };

+ 7
- 4
src/pages/package/components/ModalPackageItem.jsx View File

31
         .then(() => {
31
         .then(() => {
32
           setOpen(false);
32
           setOpen(false);
33
           ref?.current?.reload();
33
           ref?.current?.reload();
34
+          formRef.current?.resetFields();
34
         })
35
         })
35
         .catch((e) => ref?.current?.reload());
36
         .catch((e) => ref?.current?.reload());
36
     } else {
37
     } else {
39
         .then(() => {
40
         .then(() => {
40
           setOpen(false);
41
           setOpen(false);
41
           ref?.current?.reload();
42
           ref?.current?.reload();
43
+          formRef.current?.resetFields();
42
         })
44
         })
43
         .catch((e) => ref?.current?.reload());
45
         .catch((e) => ref?.current?.reload());
44
     }
46
     }
45
   };
47
   };
46
 
48
 
47
   useEffect(() => {
49
   useEffect(() => {
48
-    formRef.current?.resetFields();
49
-
50
     if (curd != "new" && curd) {
50
     if (curd != "new" && curd) {
51
       formRef.current?.setFieldsValue(curd);
51
       formRef.current?.setFieldsValue(curd);
52
     }
52
     }
65
       })
65
       })
66
       .catch((err) => {});
66
       .catch((err) => {});
67
   }, []);
67
   }, []);
68
-
68
+  const onCancel = () => {
69
+    setOpen(false);
70
+    formRef.current?.resetFields();
71
+  };
69
   return (
72
   return (
70
     <Modal
73
     <Modal
71
       title="套餐内容维护"
74
       title="套餐内容维护"
72
       open={open}
75
       open={open}
73
       footer={null}
76
       footer={null}
74
       maskClosable={false}
77
       maskClosable={false}
75
-      onCancel={() => setOpen(false)}
78
+      onCancel={onCancel}
76
     >
79
     >
77
       <ProForm
80
       <ProForm
78
         {...formItemLayout}
81
         {...formItemLayout}

+ 9
- 9
src/pages/package/components/Package.jsx View File

34
     }
34
     }
35
   };
35
   };
36
 
36
 
37
-  const onChange = (file) => {
38
-    console.log('file', file);
39
-  };
37
+  // const onChange = (file) => {
38
+  //   console.log('file', file);
39
+  // };
40
   return (
40
   return (
41
     <ProForm
41
     <ProForm
42
       formRef={formRef}
42
       formRef={formRef}
55
             <Col offset={1}>
55
             <Col offset={1}>
56
               <Button onClick={() => navigate(-1)}>返回</Button>
56
               <Button onClick={() => navigate(-1)}>返回</Button>
57
             </Col>
57
             </Col>
58
-          </Row>
58
+          </Row>,
59
           // doms.find((dom) => dom.props?.children === "提交"),
59
           // doms.find((dom) => dom.props?.children === "提交"),
60
           // <Button onClick={() => navigate(-1)}>返回</Button>,
60
           // <Button onClick={() => navigate(-1)}>返回</Button>,
61
         ],
61
         ],
64
       <ProFormText name="packageName" label="套餐名称" />
64
       <ProFormText name="packageName" label="套餐名称" />
65
       <ProFormText name="packageType" label="套餐类型" />
65
       <ProFormText name="packageType" label="套餐类型" />
66
       <ProForm.Item name="thumb" label="套餐图片">
66
       <ProForm.Item name="thumb" label="套餐图片">
67
-        <UploadImage onChange={onChange} />
67
+        <UploadImage />
68
       </ProForm.Item>
68
       </ProForm.Item>
69
       <ProFormMoney name="charge" label="套餐价格" />
69
       <ProFormMoney name="charge" label="套餐价格" />
70
       {/* <ProFormText name="limitType" label="是否限制型消费" /> */}
70
       {/* <ProFormText name="limitType" label="是否限制型消费" /> */}
84
         name="limitType"
84
         name="limitType"
85
         label="是否限制型消费"
85
         label="是否限制型消费"
86
         options={[
86
         options={[
87
-          { label: '是', value: 1 },
88
-          { label: '否', value: 0 },
87
+          { label: "是", value: 1 },
88
+          { label: "否", value: 0 },
89
         ]}
89
         ]}
90
       />
90
       />
91
       {/* <ProFormSelect
91
       {/* <ProFormSelect
106
         name="status"
106
         name="status"
107
         label="套餐状态"
107
         label="套餐状态"
108
         options={[
108
         options={[
109
-          { label: '上架', value: 1 },
110
-          { label: '下架', value: 0 },
109
+          { label: "上架", value: 1 },
110
+          { label: "下架", value: 0 },
111
         ]}
111
         ]}
112
       />
112
       />
113
     </ProForm>
113
     </ProForm>

+ 3
- 0
src/services/ossPolicy.js View File

1
+import request from "@/utils/request";
2
+
3
+export const getPolicy = () => request("/upload/policy");

+ 58
- 0
src/store/oss.js View File

1
+import axios from "axios";
2
+import { getPolicy as getOssPolicy } from "@/services/ossPolicy";
3
+
4
+let oss;
5
+let expire = 0;
6
+
7
+const resetPolicy = () => {
8
+  return getOssPolicy().then((res) => {
9
+    oss = res;
10
+    expire = res.expire;
11
+
12
+    return oss;
13
+  });
14
+}
15
+
16
+const getOssAsync = () => {
17
+  const current = (new Date()).getTime() / 1000;
18
+  // 3s 缓冲
19
+  if (expire <= current + 3) {
20
+    // 说明快到期了
21
+    return resetPolicy();
22
+  } else {
23
+    return Promise.resolve(oss);
24
+  }
25
+}
26
+
27
+const request = axios.create();
28
+const uploadFile = file => {
29
+  return getOssAsync().then(oss => {
30
+    const formData = new FormData();
31
+    const fileName= (new Date).getTime() + '_' + file.name;
32
+
33
+    formData.append("OSSAccessKeyId", oss.accessId);
34
+    formData.append("signature", oss.signature);
35
+    formData.append("policy", oss.policy);
36
+    formData.append("key", oss.dir + fileName);
37
+    formData.append("success_action_status", 200);
38
+    formData.append("file", file);
39
+  
40
+    return request(oss.host, {
41
+      method: "post",
42
+      data: formData,
43
+      headers: {
44
+        "Content-Type": "multipart/form-data",
45
+      },
46
+    }).then(res => {
47
+      console.log(res);
48
+
49
+      if (res.status == 200) {
50
+        return `${oss.customDomain}/${oss.dir}${fileName}`;
51
+      }
52
+    });
53
+  });
54
+}
55
+
56
+export {
57
+  uploadFile,
58
+}

+ 34
- 0
src/utils/biz.js View File

1
+// 消费
2
+export const BILL_CONSUME = "consume";
3
+// 退款
4
+export const BILL_REFUND = "refund";
5
+// 充值-开卡
6
+export const BILL_RECHARGE = "recharge";
7
+// 提现
8
+export const BILL_WITHDRAW = "withdraw";
9
+
10
+export const BILL_TYPE = {
11
+  [BILL_CONSUME]: "消费",
12
+  [BILL_REFUND]: "退款",
13
+  [BILL_RECHARGE]: "开卡",
14
+  [BILL_WITHDRAW]: "提现",
15
+};
16
+
17
+export const BILL_TYPE_OPTIONS = [
18
+  {value: "",text: "全部"},
19
+  {value: BILL_CONSUME,text: "消费"},
20
+  { value: BILL_REFUND, text: "退款" },
21
+  { value: BILL_RECHARGE, text: "开卡" },
22
+  { value: BILL_WITHDRAW, text: "提现" },
23
+];
24
+
25
+// export const ORDER_STATUS_OPTIONS = [
26
+//   {value: BILL_CONSUME,text: "消费"},
27
+//   { value: BILL_REFUND, text: "退款" },
28
+//   { value: BILL_RECHARGE, text: "开卡" },
29
+//   { value: BILL_WITHDRAW, text: "提现" },
30
+// ];
31
+
32
+
33
+// 计次卡
34
+export const CARD_TYPE_OF_ORDER = "order";

+ 1
- 1
src/utils/request.js View File

7
   baseURL: process.env.NODE_ENV == "development" ? "/api/admin" : SERVER_BASE,
7
   baseURL: process.env.NODE_ENV == "development" ? "/api/admin" : SERVER_BASE,
8
   timeout: 10000,
8
   timeout: 10000,
9
 });
9
 });
10
-
10
+console.log(process.env.NODE_ENV)
11
 // 添加请求拦截器
11
 // 添加请求拦截器
12
 instance.interceptors.request.use(
12
 instance.interceptors.request.use(
13
   function (config) {
13
   function (config) {

+ 1
- 1
vite.config.js View File

5
 
5
 
6
 // https://vitejs.dev/config/
6
 // https://vitejs.dev/config/
7
 export default defineConfig({
7
 export default defineConfig({
8
-  base: '',
8
+  base: '/admin/',
9
   server: {
9
   server: {
10
     port: 3009,
10
     port: 3009,
11
     host: "0.0.0.0",
11
     host: "0.0.0.0",