lisenzhou hace 2 años
padre
commit
a02046f0d6

+ 4145
- 8
package-lock.json
La diferencia del archivo ha sido suprimido porque es demasiado grande
Ver fichero


+ 1
- 0
package.json Ver fichero

@@ -11,6 +11,7 @@
11 11
   "dependencies": {
12 12
     "@ant-design/icons": "^4.7.0",
13 13
     "@ant-design/pro-components": "^2.3.13",
14
+    "@wangeditor/editor-for-react": "^1.0.5",
14 15
     "@zjxpcyc/react-tiny-store": "^2.0.1",
15 16
     "antd": "^4.23.4",
16 17
     "axios": "^1.1.2",

+ 78
- 0
src/components/Wangeditor/index.jsx Ver fichero

@@ -0,0 +1,78 @@
1
+import React, { useState, useEffect } from "react";
2
+import "@wangeditor/editor/dist/css/style.css";
3
+import { Editor, Toolbar } from "@wangeditor/editor-for-react";
4
+
5
+function MyEditor(props) {
6
+  const {
7
+    value,
8
+    onChange = (e) => {
9
+      setHtml(e);
10
+    },
11
+    toolbarConfig = {
12
+      excludeKeys: [
13
+        "insertImage",
14
+        "viewImageLink",
15
+        "editImage",
16
+        "uploadImage",
17
+        "uploadVideo",
18
+      ],
19
+    },
20
+    editorConfig = {
21
+      placeholder: "请输入内容...",
22
+    },
23
+    readonly = false,
24
+  } = props;
25
+  const [editor, setEditor] = useState(null); // 存储 editor 实例
26
+  const [html, setHtml] = useState("");
27
+  console.log(props, "MyEditor");
28
+  // 模拟 ajax 请求,异步设置 html
29
+  useEffect(() => {
30
+    console.log(editor     );
31
+
32
+    setHtml(value);
33
+  }, [value]);
34
+
35
+  // 及时销毁 editor
36
+  useEffect(() => {
37
+    return () => {
38
+      if (editor == null) return;
39
+      editor.destroy();
40
+      setEditor(null);
41
+    };
42
+  }, [editor]);
43
+
44
+  function insertText() {
45
+    if (editor == null) return;
46
+    editor.insertText(" hello ");
47
+  }
48
+
49
+  function printHtml() {
50
+    if (editor == null) return;
51
+    console.log(editor.getHtml());
52
+  }
53
+
54
+  return !readonly ? (
55
+    <>
56
+      <div style={{ border: "1px solid #ccc", zIndex: 100, marginTop: "15px" }}>
57
+        <Toolbar
58
+          editor={editor}
59
+          defaultConfig={toolbarConfig}
60
+          mode="default"
61
+          style={{ borderBottom: "1px solid #ccc" }}
62
+        />
63
+        <Editor
64
+          defaultConfig={editorConfig}
65
+          value={html}
66
+          onCreated={setEditor}
67
+          onChange={(editor) => onChange(editor.getHtml())}
68
+          mode="default"
69
+          style={{ height: "500px" }}
70
+        />
71
+      </div>
72
+    </>
73
+  ) : (
74
+    <div dangerouslySetInnerHTML={{ __html: value }}></div>
75
+  );
76
+}
77
+
78
+export default MyEditor;

+ 123
- 0
src/pages/cms/emergencyPlan/edit/index.jsx Ver fichero

@@ -0,0 +1,123 @@
1
+import { savePosts, getPostsDetail, updatePosts } from "@/services/posts";
2
+import { getStoreList } from "@/services/stock";
3
+import {
4
+  PageContainer,
5
+  ProForm,
6
+  ProFormSelect,
7
+  ProFormText,
8
+} from "@ant-design/pro-components";
9
+import { useNavigate, useSearchParams } from "react-router-dom";
10
+import { Card, Col, message, Row, Space } from "antd";
11
+import { useEffect, useRef, useState } from "react";
12
+import Wangeditor from "@/components/Wangeditor";
13
+
14
+export default (props) => {
15
+  const [searchParams] = useSearchParams();
16
+  const id = searchParams.get("id");
17
+  // const [foodDict, setFoodDict] = useState([]);
18
+  const navigate = useNavigate();
19
+
20
+  const formRef = useRef();
21
+  // useEffect(() => {
22
+  //   getStoreList({ isDish: 1, pageSize: 9999 }).then((res) => {
23
+  //     setFoodDict(
24
+  //       res?.records?.map((x) => ({
25
+  //         label: x.name,
26
+  //         value: x.id,
27
+  //       }))
28
+  //     );
29
+  //   });
30
+  // }, [id]);
31
+
32
+  useEffect(() => {
33
+    if (id) {
34
+      getPostsDetail(id).then((res) => {
35
+        formRef.current.setFieldsValue(res);
36
+      });
37
+    }
38
+  }, [id]);
39
+
40
+  const onFinish = async (values) => {
41
+    console.log(values, "===");
42
+
43
+    if (id) {
44
+      updatePosts(id, { ...values, status: Number(values.status) }).then(
45
+        (res) => {
46
+          navigate(-1);
47
+        }
48
+      );
49
+    } else {
50
+      savePosts({ ...values, status: Number(values.status) }).then((res) => {
51
+        navigate(-1);
52
+      });
53
+    }
54
+
55
+    return false;
56
+  };
57
+
58
+  return (
59
+    <PageContainer>
60
+      <Card>
61
+        <ProForm
62
+          //  readonly
63
+          formRef={formRef}
64
+          layout={"horizontal"}
65
+          labelCol={{ span: 8 }}
66
+          wrapperCol={{ span: 12 }}
67
+          onFinish={onFinish}
68
+          initialValues={{ status: 0 }}
69
+          submitter={{
70
+            searchConfig: {
71
+              resetText: "返回",
72
+            },
73
+            onReset: () => navigate(-1),
74
+            render: (props, doms) => {
75
+              return (
76
+                <Row>
77
+                  <Col span={8} offset={8}>
78
+                    <Space>{doms}</Space>
79
+                  </Col>
80
+                </Row>
81
+              );
82
+            },
83
+          }}
84
+        >
85
+          <ProFormText
86
+            name="title"
87
+            label="内容名称"
88
+            placeholder="请输入内容名称"
89
+            rules={[{ required: true, message: "请输入内容名称" }]}
90
+            width={460}
91
+          />
92
+
93
+          <ProForm.Item
94
+            name="detail"
95
+            label="发布详情"
96
+            placeholder="请输入发布详情"
97
+            rules={[{ required: true, message: "请输入发布详情" }]}
98
+          >
99
+            <Wangeditor></Wangeditor>
100
+          </ProForm.Item>
101
+
102
+          <ProFormSelect
103
+            name="status"
104
+            label="状态"
105
+            placeholder="请选择"
106
+            rules={[{ required: true, message: "请选择状态" }]}
107
+            width={460}
108
+            options={[
109
+              {
110
+                value: 0,
111
+                label: "未发布",
112
+              },
113
+              {
114
+                value: 1,
115
+                label: "已发布",
116
+              },
117
+            ]}
118
+          />
119
+        </ProForm>
120
+      </Card>
121
+    </PageContainer>
122
+  );
123
+};

+ 113
- 0
src/pages/cms/emergencyPlan/list/index.jsx Ver fichero

@@ -0,0 +1,113 @@
1
+import { getPostsList } from "@/services/posts";
2
+import { queryTable } from "@/utils/request";
3
+import { PageContainer, ProTable } from "@ant-design/pro-components";
4
+import { useNavigate } from "react-router-dom";
5
+import { Button, message, Popconfirm } from "antd";
6
+import { useRef, useState, useEffect } from "react";
7
+import { floatMultiply, floatDivide } from "@/utils";
8
+
9
+// type plan 采购计划  bill 采购账单  inStore  采购入库
10
+const StockList = (props) => {
11
+  const { type } = props;
12
+  const [showDetail, setShowDetail] = useState(false);
13
+  const [activeKey, setActiveKey] = useState("");
14
+  const actionRef = useRef();
15
+  const navigate = useNavigate();
16
+  // console.log(props, "props");
17
+
18
+  useEffect(() => {
19
+    actionRef.current.reload();
20
+  }, [type]);
21
+  const handleDelete = (id) => {
22
+    if (id) {
23
+      deletePurchase(id).then((res) => {
24
+        actionRef.current.reload();
25
+      });
26
+    }
27
+  };
28
+
29
+  const columns = [
30
+    {
31
+      title: "内容名称",
32
+      dataIndex: "title",
33
+    },
34
+
35
+    {
36
+      title: "发布内容",
37
+      dataIndex: "detail",
38
+      search: false,
39
+      width:'50%'
40
+    },
41
+    {
42
+      title: "状态",
43
+      dataIndex: "status",
44
+      valueType: 'select',
45
+      valueEnum:{
46
+        0: { text: '未发布', status: 'Error' },
47
+        1: { text: '已发布', status: 'Processing' }, 
48
+      },
49
+    
50
+    //   const valueEnum = {
51
+    //     all: { text: '全部', status: 'Default' },
52
+    //     running: { text: '运行中', status: 'Processing' },
53
+    //     online: { text: '已上线', status: 'Success' },
54
+    //     error: { text: '异常', status: 'Error' },
55
+    //   };
56
+    },
57
+
58
+    {
59
+      title: "操作",
60
+      valueType: "option",
61
+      width: 200,
62
+      render: (_, record) => [
63
+        <Button
64
+          key={2}
65
+          style={{ padding: 0 }}
66
+          type="link"
67
+          onClick={() => {
68
+            navigate(`/cms/emergency-plan/edit?id=${record.id}`);
69
+          }}
70
+        >
71
+          修改
72
+        </Button>,
73
+        <Popconfirm
74
+          key={3}
75
+          title="您是否确认删除 ?"
76
+          onConfirm={() => handleDelete(record.id)}
77
+          okText="确定"
78
+          cancelText="取消"
79
+        >
80
+          {/* manualPush */}
81
+          <Button style={{ padding: 0 }} type="link">
82
+            删除
83
+          </Button>
84
+        </Popconfirm>,
85
+      ],
86
+    },
87
+  ];
88
+
89
+  return (
90
+    <PageContainer>
91
+      <ProTable
92
+        actionRef={actionRef}
93
+        rowKey="id"
94
+        toolBarRender={() => [
95
+          <Button
96
+            key="2"
97
+            type="primary"
98
+            onClick={() => {
99
+              navigate("/cms/emergency-plan/edit");
100
+            }}
101
+          >
102
+            新增
103
+          </Button>,
104
+        ]}
105
+        // search={false}
106
+        request={queryTable(getPostsList)}
107
+        columns={columns}
108
+      />
109
+    </PageContainer>
110
+  );
111
+};
112
+
113
+export default StockList;

+ 213
- 0
src/pages/purchase/bill/edit/index.jsx Ver fichero

@@ -0,0 +1,213 @@
1
+import {
2
+  savePurchase,
3
+  updatePurchase,
4
+  getPurchaseDetail,
5
+} from "@/services/purchase";
6
+import { getStoreList } from "@/services/stock";
7
+import {
8
+  PageContainer,
9
+  ProForm,
10
+  ProFormSelect,
11
+  ProFormText,
12
+  ProFormDigit,
13
+} from "@ant-design/pro-components";
14
+import { useNavigate, useSearchParams } from "react-router-dom";
15
+import { Card, Col, message, Row, Space, Form, Button } from "antd";
16
+import { useEffect, useRef, useState } from "react";
17
+import { MinusCircleOutlined, PlusOutlined } from "@ant-design/icons";
18
+import { floatMultiply, floatDivide } from "@/utils";
19
+
20
+export default (props) => {
21
+  const [searchParams] = useSearchParams();
22
+  const id = searchParams.get("id");
23
+  const [storeList, setStoreList] = useState([]);
24
+  const [isCompleted, setIsCompleted] = useState(false);
25
+  const navigate = useNavigate();
26
+  
27
+  const formRef = useRef();
28
+  useEffect(() => {
29
+    getStoreList({ pageSize: 9999 }).then((res) => {
30
+      setStoreList(
31
+        res?.records?.map((x) => ({
32
+          label: x.name,
33
+          value: x.id,
34
+        }))
35
+      );
36
+    });
37
+  }, []);
38
+
39
+  useEffect(() => {
40
+    if (id) {
41
+      getPurchaseDetail(id).then((res) => {
42
+        setIsCompleted(res.isCompleted)
43
+        formRef.current.setFieldsValue({
44
+          ...res,
45
+          itemsList: res.itemsList?.map((x) => ({
46
+            ...x,
47
+            planUnitPrice: floatDivide(x.planUnitPrice, 100),
48
+            actUnitPrice: floatDivide(x.actUnitPrice, 100),
49
+          })),
50
+        });
51
+      });
52
+    }
53
+  }, [id]);
54
+
55
+  const onFinish = async (values) => {
56
+    console.log(values, "===");
57
+
58
+    let data = {
59
+      id: id ? Number(id) : null,
60
+      ...values,
61
+      itemsList: values.itemsList?.map((x) => ({
62
+        ...x,
63
+        planUnitPrice: floatMultiply(x.planUnitPrice, 100),
64
+        actUnitPrice: floatMultiply(x.actUnitPrice, 100),
65
+      })),
66
+    };
67
+
68
+    savePurchase(data).then((res) => {
69
+      // message.success("添加成功");
70
+      navigate(-1);
71
+    });
72
+
73
+    return false;
74
+  };
75
+
76
+  const onBillFinish = ({ form }) => {
77
+    form.validateFields().then((res) => {
78
+      console.log(res, "===--");
79
+      onFinish({ ...res, isCompleted: true });
80
+    });
81
+  };
82
+
83
+  return (
84
+    <PageContainer>
85
+      <Card>
86
+        <ProForm
87
+          formRef={formRef}
88
+          layout={"horizontal"}
89
+          labelCol={{ span: 2 }}
90
+          wrapperCol={{ span: 8 }}
91
+          onFinish={onFinish}
92
+          submitter={{
93
+            searchConfig: {
94
+              resetText: "返回",
95
+            },
96
+            onReset: () => navigate(-1),
97
+            render: (props, doms) => {
98
+              console.log(props, doms, "renderprops");
99
+              return (
100
+                <Row>
101
+                  <Col span={8} offset={2}>
102
+                    <Space>
103
+                      {doms?.map((x, index) => {
104
+                        if (index === 1 && isCompleted) {
105
+                          return null;
106
+                        }
107
+                        return x;
108
+                      })}
109
+                      {id&&!isCompleted && (
110
+                        <Button
111
+                          type="primary"
112
+                          onClick={() => onBillFinish(props)}
113
+                        >
114
+                          采购完成
115
+                        </Button>
116
+                      )}
117
+                    </Space>
118
+                  </Col>
119
+                </Row>
120
+              );
121
+            },
122
+          }}
123
+        >
124
+          <ProFormText
125
+            name="title"
126
+            label="采购计划"
127
+            placeholder="请输入采购计划"
128
+            disabled
129
+            width={480}
130
+          />
131
+          <ProFormText
132
+            name="planDate"
133
+            label="计划时间"
134
+            placeholder="请输入计划时间"
135
+            disabled
136
+            width={480}
137
+          />
138
+          <Form.Item
139
+            label="采购清单"
140
+            labelCol={{ span: 2 }}
141
+            wrapperCol={{ span: 22 }}
142
+          >
143
+            <Form.List name="itemsList">
144
+              {(fields, { add, remove }) => (
145
+                <>
146
+                  {fields.map(({ key, name, ...restField }) => (
147
+                    <Space
148
+                      key={key}
149
+                      style={{ display: "flex" }}
150
+                      align="baseline"
151
+                    >
152
+                      <ProFormSelect
153
+                        {...restField}
154
+                        name={[name, "storeId"]}
155
+                        label="库存名称"
156
+                        placeholder="请选择库存名称"
157
+                        disabled
158
+                        options={storeList}
159
+                      />
160
+
161
+                      <ProFormDigit
162
+                        {...restField}
163
+                        name={[name, "planAmount"]}
164
+                        label="计划数量"
165
+                        placeholder="请输入计划数量"
166
+                        disabled
167
+                        width={100}
168
+                        fieldProps={{
169
+                          precision: 10,
170
+                          formatter: (value) => value,
171
+                        }}
172
+                      />
173
+                      <ProFormDigit
174
+                        {...restField}
175
+                        name={[name, "planUnitPrice"]}
176
+                        label="预估单价"
177
+                        placeholder="请输入预估单价"
178
+                        disabled
179
+                        fieldProps={{ precision: 2, prefix: "¥" }}
180
+                        width={100}
181
+                      />
182
+                      <ProFormDigit
183
+                        {...restField}
184
+                        name={[name, "actAmount"]}
185
+                        label="采购数量"
186
+                        placeholder="请输入采购数量"
187
+                        rules={[{ required: true, message: "请输入采购数量" }]}
188
+                        width={100}
189
+                        fieldProps={{
190
+                          precision: 10,
191
+                          formatter: (value) => value,
192
+                        }}
193
+                      />
194
+                      <ProFormDigit
195
+                        {...restField}
196
+                        name={[name, "actUnitPrice"]}
197
+                        label="采购单价"
198
+                        placeholder="请输入采购单价"
199
+                        rules={[{ required: true, message: "请输入采购单价" }]}
200
+                        fieldProps={{ precision: 2, prefix: "¥" }}
201
+                        width={100}
202
+                      />
203
+                    </Space>
204
+                  ))}
205
+                </>
206
+              )}
207
+            </Form.List>
208
+          </Form.Item>
209
+        </ProForm>
210
+      </Card>
211
+    </PageContainer>
212
+  );
213
+};

+ 197
- 0
src/pages/purchase/inStore/edit/index.jsx Ver fichero

@@ -0,0 +1,197 @@
1
+import {
2
+  savePurchaseInStore,
3
+  getPurchaseDetail,
4
+} from "@/services/purchase";
5
+import { getStoreList } from "@/services/stock";
6
+import {
7
+  PageContainer,
8
+  ProForm,
9
+  ProFormSelect,
10
+  ProFormText,
11
+  ProFormDigit,
12
+} from "@ant-design/pro-components";
13
+import { useNavigate, useSearchParams } from "react-router-dom";
14
+import { Card, Col, message, Row, Space, Form, Button } from "antd";
15
+import { useEffect, useRef, useState } from "react";
16
+import { MinusCircleOutlined, PlusOutlined } from "@ant-design/icons";
17
+import { floatMultiply, floatDivide } from "@/utils";
18
+
19
+export default (props) => {
20
+  const [searchParams] = useSearchParams();
21
+  const id = searchParams.get("id");
22
+  const [storeList, setStoreList] = useState([]);
23
+  const [isInStore, setIsInStore] = useState(false);
24
+  const navigate = useNavigate();
25
+  
26
+  const formRef = useRef();
27
+  useEffect(() => {
28
+    getStoreList({ pageSize: 9999 }).then((res) => {
29
+      setStoreList(
30
+        res?.records?.map((x) => ({
31
+          label: x.name,
32
+          value: x.id,
33
+        }))
34
+      );
35
+    });
36
+  }, []);
37
+
38
+  useEffect(() => {
39
+    if (id) {
40
+      getPurchaseDetail(id).then((res) => {
41
+        setIsInStore(res.isInStore)
42
+        formRef.current.setFieldsValue({
43
+          ...res,
44
+          itemsList: res.itemsList?.map((x) => ({
45
+            ...x,
46
+            planUnitPrice: x.planUnitPrice
47
+              ? floatDivide(x.planUnitPrice, 100)
48
+              : null,
49
+            actUnitPrice: x.actUnitPrice
50
+              ? floatDivide(x.actUnitPrice, 100)
51
+              : null,
52
+          })),
53
+        });
54
+      });
55
+    }
56
+  }, [id]);
57
+
58
+  const onFinish = async (values) => {
59
+    console.log(values, "===");
60
+
61
+
62
+
63
+    savePurchaseInStore(Number(id)).then((res) => {
64
+      // message.success("添加成功");
65
+      navigate(-1);
66
+    });
67
+
68
+    return false;
69
+  };
70
+
71
+
72
+
73
+  return (
74
+    <PageContainer>
75
+      <Card>
76
+        <ProForm
77
+        
78
+          formRef={formRef}
79
+          layout={"horizontal"}
80
+          labelCol={{ span: 2 }}
81
+          wrapperCol={{ span: 8 }}
82
+          onFinish={onFinish}
83
+          submitter={{
84
+            searchConfig: {
85
+              resetText: "返回",
86
+              submitText:'入库'
87
+            },
88
+            onReset: () => navigate(-1),
89
+            render: (props, doms) => {
90
+              console.log(props, doms, "renderprops");
91
+              return (
92
+                <Row>
93
+                  <Col span={8} offset={2}>
94
+                    <Space>
95
+                      {doms?.map((x, index) => {
96
+                        if (index === 1 && isInStore) {
97
+                          return null;
98
+                        }
99
+                        return x;
100
+                      })}
101
+                    </Space>
102
+                  </Col>
103
+                </Row>
104
+              );
105
+            },
106
+          }}
107
+        >
108
+          <ProFormText
109
+            name="title"
110
+            label="采购计划"
111
+            placeholder="请输入采购计划"
112
+            disabled
113
+            width={480}
114
+          />
115
+          <ProFormText
116
+            name="planDate"
117
+            label="计划时间"
118
+            placeholder="请输入计划时间"
119
+            disabled
120
+            width={480}
121
+          />
122
+          <Form.Item
123
+            label="采购清单"
124
+            labelCol={{ span: 2 }}
125
+            wrapperCol={{ span: 22 }}
126
+          >
127
+            <Form.List name="itemsList">
128
+              {(fields, { add, remove }) => (
129
+                <>
130
+                  {fields.map(({ key, name, ...restField }) => (
131
+                    <Space
132
+                      key={key}
133
+                      style={{ display: "flex" }}
134
+                      align="baseline"
135
+                    >
136
+                      <ProFormSelect
137
+                        {...restField}
138
+                        name={[name, "storeId"]}
139
+                        label="库存名称"
140
+                        placeholder="请选择库存名称"
141
+                        disabled
142
+                        options={storeList}
143
+                      />
144
+
145
+                      <ProFormDigit
146
+                        {...restField}
147
+                        name={[name, "planAmount"]}
148
+                        label="计划数量"
149
+                        placeholder="请输入计划数量"
150
+                        disabled
151
+                        width={100}
152
+                        fieldProps={{
153
+                          precision: 10,
154
+                          formatter: (value) => value,
155
+                        }}
156
+                      />
157
+                      <ProFormDigit
158
+                        {...restField}
159
+                        name={[name, "planUnitPrice"]}
160
+                        label="预估单价"
161
+                        placeholder="请输入预估单价"
162
+                        disabled
163
+                        fieldProps={{ precision: 2, prefix: "¥" }}
164
+                        width={100}
165
+                      />
166
+                      <ProFormDigit
167
+                        {...restField}
168
+                        name={[name, "actAmount"]}
169
+                        label="采购数量"
170
+                        placeholder="请输入采购数量"
171
+                        disabled
172
+                        width={100}
173
+                        fieldProps={{
174
+                          precision: 10,
175
+                          formatter: (value) => value,
176
+                        }}
177
+                      />
178
+                      <ProFormDigit
179
+                        {...restField}
180
+                        name={[name, "actUnitPrice"]}
181
+                        label="采购单价"
182
+                        placeholder="请输入采购单价"
183
+                        disabled
184
+                        fieldProps={{ precision: 2, prefix: "¥" }}
185
+                        width={100}
186
+                      />
187
+                    </Space>
188
+                  ))}
189
+                </>
190
+              )}
191
+            </Form.List>
192
+          </Form.Item>
193
+        </ProForm>
194
+      </Card>
195
+    </PageContainer>
196
+  );
197
+};

+ 190
- 0
src/pages/purchase/plan/edit/index.jsx Ver fichero

@@ -0,0 +1,190 @@
1
+import {
2
+  savePurchase,
3
+  updatePurchase,
4
+  getPurchaseDetail,
5
+} from "@/services/purchase";
6
+import { getStoreList } from "@/services/stock";
7
+import {
8
+  PageContainer,
9
+  ProForm,
10
+  ProFormSelect,
11
+  ProFormText,
12
+  ProFormDigit,
13
+} from "@ant-design/pro-components";
14
+import { useNavigate, useSearchParams } from "react-router-dom";
15
+import { Card, Col, message, Row, Space, Form, Button } from "antd";
16
+import { useEffect, useRef, useState } from "react";
17
+import { MinusCircleOutlined, PlusOutlined } from "@ant-design/icons";
18
+import { floatMultiply, floatDivide } from "@/utils";
19
+
20
+export default (props) => {
21
+  const [searchParams] = useSearchParams();
22
+  const id = searchParams.get("id");
23
+  const [storeList, setStoreList] = useState([]);
24
+  const [isCompleted, setIsCompleted] = useState(false);
25
+
26
+  const navigate = useNavigate();
27
+
28
+  const formRef = useRef();
29
+  useEffect(() => {
30
+    getStoreList({ pageSize: 9999 }).then((res) => {
31
+      setStoreList(
32
+        res?.records?.map((x) => ({
33
+          label: x.name,
34
+          value: x.id,
35
+        }))
36
+      );
37
+    });
38
+  }, []);
39
+
40
+  useEffect(() => {
41
+    if (id) {
42
+      getPurchaseDetail(id).then((res) => {
43
+        setIsCompleted(res.isCompleted);
44
+        formRef.current.setFieldsValue({
45
+          ...res,
46
+          itemsList: res.itemsList?.map((x) => ({
47
+            ...x,
48
+            planUnitPrice: x.planUnitPrice
49
+              ? floatDivide(x.planUnitPrice, 100)
50
+              : null,
51
+          })),
52
+        });
53
+      });
54
+    }
55
+  }, [id]);
56
+
57
+  const onFinish = async (values) => {
58
+    let data = {
59
+      id: id ? Number(id) : null,
60
+      ...values,
61
+      itemsList: values.itemsList?.map((x) => ({
62
+        ...x,
63
+        planUnitPrice: floatMultiply(x.planUnitPrice, 100),
64
+      })),
65
+    };
66
+
67
+    savePurchase(data).then((res) => {
68
+      // message.success("添加成功");
69
+      navigate(-1);
70
+    });
71
+
72
+    return false;
73
+  };
74
+
75
+  return (
76
+    <PageContainer>
77
+      <Card>
78
+        <ProForm
79
+          formRef={formRef}
80
+          layout={"horizontal"}
81
+          labelCol={{ span: 2 }}
82
+          wrapperCol={{ span: 8 }}
83
+          onFinish={onFinish}
84
+          initialValues={{ type: "1", state: "1" }}
85
+          submitter={{
86
+            searchConfig: {
87
+              resetText: "返回",
88
+            },
89
+            onReset: () => navigate(-1),
90
+            render: (props, doms) => {
91
+              console.log(props, doms, "propsprops");
92
+              console.log(props?.form?.getFieldsValue(), "propsprops");
93
+              return (
94
+                <Row>
95
+                  <Col span={8} offset={2}>
96
+                    <Space>
97
+                      {doms?.map((x, index) => {
98
+                        if (index === 1 && isCompleted) {
99
+                          return null;
100
+                        }
101
+                        return x;
102
+                      })}
103
+                    </Space>
104
+                  </Col>
105
+                </Row>
106
+              );
107
+            },
108
+          }}
109
+        >
110
+          <ProFormText
111
+            name="title"
112
+            label="采购计划"
113
+            placeholder="请输入采购计划"
114
+            rules={[{ required: true, message: "请输入采购计划" }]}
115
+            width={480}
116
+          />
117
+          <ProFormText
118
+            name="planDate"
119
+            label="计划时间"
120
+            placeholder="请输入计划时间"
121
+            rules={[{ required: true, message: "请输入计划时间" }]}
122
+            width={480}
123
+          />
124
+          <Form.Item
125
+            label="采购清单"
126
+            labelCol={{ span: 2 }}
127
+            wrapperCol={{ span: 22 }}
128
+          >
129
+            <Form.List name="itemsList">
130
+              {(fields, { add, remove }) => (
131
+                <>
132
+                  {fields.map(({ key, name, ...restField }) => (
133
+                    <Space
134
+                      key={key}
135
+                      style={{ display: "flex" }}
136
+                      align="baseline"
137
+                    >
138
+                      <ProFormSelect
139
+                        {...restField}
140
+                        name={[name, "storeId"]}
141
+                        label="库存名称"
142
+                        placeholder="请选择库存名称"
143
+                        rules={[{ required: true, message: "请输入选择名称" }]}
144
+                        options={storeList}
145
+                      />
146
+
147
+                      <ProFormDigit
148
+                        {...restField}
149
+                        name={[name, "planAmount"]}
150
+                        label="计划数量"
151
+                        placeholder="请输入计划数量"
152
+                        rules={[{ required: true, message: "请输入计划数量" }]}
153
+                        // width={150}
154
+                        fieldProps={{
155
+                          precision: 10,
156
+                          formatter: (value) => value,
157
+                        }}
158
+                      />
159
+                      <ProFormDigit
160
+                        {...restField}
161
+                        name={[name, "planUnitPrice"]}
162
+                        label="预估单价"
163
+                        placeholder="请输入预估单价"
164
+                        rules={[{ required: true, message: "请输入预估单价" }]}
165
+                        fieldProps={{ precision: 2, prefix: "¥" }}
166
+                        // width={150}
167
+                      />
168
+                      <MinusCircleOutlined onClick={() => remove(name)} />
169
+                    </Space>
170
+                  ))}
171
+                  <Form.Item>
172
+                    <Button
173
+                      type="dashed"
174
+                      onClick={() => add()}
175
+                      // block
176
+                      // style={{width:100}}
177
+                      icon={<PlusOutlined />}
178
+                    >
179
+                      添加
180
+                    </Button>
181
+                  </Form.Item>
182
+                </>
183
+              )}
184
+            </Form.List>
185
+          </Form.Item>
186
+        </ProForm>
187
+      </Card>
188
+    </PageContainer>
189
+  );
190
+};

+ 160
- 0
src/pages/purchase/plan/list/index.jsx Ver fichero

@@ -0,0 +1,160 @@
1
+import {
2
+  getPurchaseList,
3
+  getPurchaseDetail,
4
+  savePurchase,
5
+  updatePurchase,
6
+  deletePurchase,
7
+} from "@/services/purchase";
8
+import { queryTable } from "@/utils/request";
9
+import { PageContainer, ProTable } from "@ant-design/pro-components";
10
+import { useNavigate } from "react-router-dom";
11
+import { Button, message, Popconfirm } from "antd";
12
+import { useRef, useState, useEffect } from "react";
13
+import { floatMultiply, floatDivide } from "@/utils";
14
+
15
+// type plan 采购计划  bill 采购账单  inStore  采购入库
16
+const StockList = (props) => {
17
+  const { type } = props;
18
+  const [showDetail, setShowDetail] = useState(false);
19
+  const [activeKey, setActiveKey] = useState("");
20
+  const actionRef = useRef();
21
+  const navigate = useNavigate();
22
+  // console.log(props, "props");
23
+
24
+  useEffect(() => {
25
+    actionRef.current.reload();
26
+  }, [type]);
27
+  const handleDelete = (id) => {
28
+    if (id) {
29
+      deletePurchase(id).then((res) => {
30
+        actionRef.current.reload();
31
+      });
32
+    }
33
+  };
34
+
35
+  const columns = [
36
+    {
37
+      title: "采购计划",
38
+      dataIndex: "title",
39
+    },
40
+
41
+    {
42
+      title: "计划时间",
43
+      dataIndex: "planDate",
44
+    },
45
+    {
46
+      title: "采购项目",
47
+      dataIndex: "items",
48
+      search: false,
49
+    },
50
+
51
+    {
52
+      title: "是否入库",
53
+      dataIndex: "isInStore",
54
+      valueEnum: {
55
+        false: { text: "否", status: "Error" },
56
+        true: { text: "是", status: "Success" },
57
+      },
58
+      search: false,
59
+    },
60
+
61
+    {
62
+      title: "是否采购完成",
63
+      dataIndex: "isCompleted",
64
+      valueEnum: {
65
+        false: { text: "否", status: "Error" },
66
+        true: { text: "是", status: "Success" },
67
+      },
68
+      search: false,
69
+    },
70
+
71
+    {
72
+      title: "操作",
73
+      valueType: "option",
74
+      width: 200,
75
+      render: (_, record) => [
76
+        type === "plan" ? (
77
+          <Button
78
+            key={2}
79
+            style={{ padding: 0 }}
80
+            type="link"
81
+            onClick={() => {
82
+              navigate(`/purchase/plan/edit?id=${record.id}`);
83
+            }}
84
+          >
85
+            修改
86
+          </Button>
87
+        ) : null,
88
+
89
+        type === "bill" ? (
90
+          <Button
91
+            key={4}
92
+            style={{ padding: 0 }}
93
+            type="link"
94
+            onClick={() => {
95
+              navigate(`/purchase/bill/edit?id=${record.id}`);
96
+            }}
97
+          >
98
+            采购
99
+          </Button>
100
+        ) : null,
101
+
102
+        type === "inStore" ? (
103
+          <Button
104
+            key={5}
105
+            style={{ padding: 0 }}
106
+            type="link"
107
+            onClick={() => {
108
+              navigate(`/purchase/inStore/edit?id=${record.id}`);
109
+            }}
110
+          >
111
+            入库
112
+          </Button>
113
+        ) : null,
114
+
115
+        type === "plan" ? (
116
+          <Popconfirm
117
+            key={3}
118
+            title="您是否确认删除 ?"
119
+            onConfirm={() => handleDelete(record.id)}
120
+            okText="确定"
121
+            cancelText="取消"
122
+          >
123
+            {/* manualPush */}
124
+            <Button style={{ padding: 0 }} type="link">
125
+              删除
126
+            </Button>
127
+          </Popconfirm>
128
+        ) : null,
129
+      ],
130
+    },
131
+  ];
132
+
133
+  return (
134
+    <PageContainer>
135
+      <ProTable
136
+        actionRef={actionRef}
137
+        rowKey="id"
138
+        params={type === "inStore"? {isCompleted:true}:{}}
139
+        toolBarRender={() => [
140
+          type === "plan" ? (
141
+            <Button
142
+              key="2"
143
+              type="primary"
144
+              onClick={() => {
145
+                navigate("/purchase/plan/edit");
146
+              }}
147
+            >
148
+              新增
149
+            </Button>
150
+          ) : null,
151
+        ]}
152
+        // search={false}
153
+        request={queryTable(getPurchaseList)}
154
+        columns={columns}
155
+      />
156
+    </PageContainer>
157
+  );
158
+};
159
+
160
+export default StockList;

+ 2
- 2
src/pages/stock/list/index.jsx Ver fichero

@@ -93,7 +93,7 @@ const StockList = (props) => {
93 93
           style={{ padding: 0 }}
94 94
           type="link"
95 95
           onClick={() => {
96
-            navigate(`/stock/edit?id=${record.id}`);
96
+            navigate(`/stock/add?id=${record.id}`);
97 97
           }}
98 98
         >
99 99
           修改
@@ -126,7 +126,7 @@ const StockList = (props) => {
126 126
             key="2"
127 127
             type="primary"
128 128
             onClick={() => {
129
-              navigate('/stock/edit');
129
+              navigate('/stock/add');
130 130
             }}
131 131
           >
132 132
             新增

+ 1
- 1
src/pages/stock/outAndIn/index.jsx Ver fichero

@@ -18,7 +18,7 @@ const OutAndIn = (props) => {
18 18
         amount: tabKey === 'out' ? -values.amount : values.amount,
19 19
         optType: tabKey,
20 20
       }).then((res) => {
21
-        message.success('操作成功');
21
+        
22 22
 
23 23
         onSuccess();
24 24
       });

+ 171
- 99
src/routes/routes.jsx Ver fichero

@@ -6,31 +6,37 @@ import {
6 6
   MenuFoldOutlined,
7 7
   MenuUnfoldOutlined,
8 8
   PieChartOutlined,
9
-} from '@ant-design/icons';
10
-import { Navigate } from 'react-router-dom';
11
-import AuthLayout from '@/layouts/AuthLayout';
12
-import Container from '@/layouts/Container';
13
-import Login from '@/pages/login';
14
-import Page404 from '@/pages/404';
15
-import Home from '@/pages/sample/home';
16
-import BasicForm from '@/pages/sample/form';
17
-import BasicTable from '@/pages/sample/table';
18
-import GuaranteeTaskList from '@/pages/guaranteeTask';
19
-import GuaranteeTaskEdit from '@/pages/guaranteeTask/Edit';
20
-import GuaranteeTaskPrint from '@/pages/guaranteeTask/print';
21
-import DishList from '@/pages/dish/list';
22
-import DishEdit from '@/pages/dish/edit';
23
-import PackageList from '@/pages/package/List';
24
-import StockList from '@/pages/stock/list';
25
-import StockEdit from '@/pages/stock/edit';
26
-import StockInOut from '@/pages/stock/outAndIn';
27
-import StockLog from '@/pages/stock/stockLog';
28
-import StockClassificationList from '@/pages/stockClassification/list';
29
-import StockClassificationEdit from '@/pages/stockClassification/edit';
30
-import RotationChartList from '@/pages/rotationChart/list';
31
-import RotationChartEdit from '@/pages/rotationChart/edit';
32
-import RotationChartIntroduction from '@/pages/rotationChart/introduction';
33
-import Roles from '@/pages/roles/index';
9
+} from "@ant-design/icons";
10
+import { Navigate } from "react-router-dom";
11
+import AuthLayout from "@/layouts/AuthLayout";
12
+import Container from "@/layouts/Container";
13
+import Login from "@/pages/login";
14
+import Page404 from "@/pages/404";
15
+import Home from "@/pages/sample/home";
16
+import BasicForm from "@/pages/sample/form";
17
+import BasicTable from "@/pages/sample/table";
18
+import GuaranteeTaskList from "@/pages/guaranteeTask";
19
+import GuaranteeTaskEdit from "@/pages/guaranteeTask/Edit";
20
+import GuaranteeTaskPrint from "@/pages/guaranteeTask/print";
21
+import EmergencyPlanList from "@/pages/cms/emergencyPlan/list";
22
+import EmergencyPlanEdit from "@/pages/cms/emergencyPlan/edit";
23
+import DishList from "@/pages/dish/list";
24
+import DishEdit from "@/pages/dish/edit";
25
+import PackageList from "@/pages/package/List";
26
+import StockList from "@/pages/stock/list";
27
+import StockEdit from "@/pages/stock/edit";
28
+import StockInOut from "@/pages/stock/outAndIn";
29
+import StockLog from "@/pages/stock/stockLog";
30
+import StockClassificationList from "@/pages/stockClassification/list";
31
+import StockClassificationEdit from "@/pages/stockClassification/edit";
32
+import RotationChartList from "@/pages/rotationChart/list";
33
+import RotationChartEdit from "@/pages/rotationChart/edit";
34
+import RotationChartIntroduction from "@/pages/rotationChart/introduction";
35
+import Roles from "@/pages/roles/index";
36
+import PurchasePlanList from "@/pages/purchase/plan/list";
37
+import PurchasePlanEdit from "@/pages/purchase/plan/edit";
38
+import PurchaseBillEdit from "@/pages/purchase/bill/edit";
39
+import PurchaseInStoreEdit from "@/pages/purchase/inStore/edit";
34 40
 
35 41
 /**
36 42
  * meta 用来扩展自定义数据数据
@@ -44,7 +50,7 @@ import Roles from '@/pages/roles/index';
44 50
 
45 51
 export default [
46 52
   {
47
-    path: '/',
53
+    path: "/",
48 54
     element: <AuthLayout />,
49 55
     children: [
50 56
       {
@@ -52,245 +58,311 @@ export default [
52 58
         element: <Home />,
53 59
       },
54 60
       {
55
-        path: 'home',
61
+        path: "home",
56 62
         element: <Home />,
57 63
         meta: {
58
-          title: '首页',
64
+          title: "首页",
59 65
           icon: <DesktopOutlined />,
60 66
         },
61 67
       },
62 68
       {
63
-        path: 'task',
69
+        path: "task",
64 70
         element: <Container />,
65 71
         meta: {
66
-          title: '军供任务',
72
+          title: "军供任务",
67 73
           icon: <AppstoreOutlined />,
68 74
         },
69 75
         children: [
70 76
           {
71 77
             index: true,
72
-            element: <Navigate to='guaranteeTask' replace />,
78
+            element: <Navigate to="guaranteeTask" replace />,
73 79
           },
74 80
           {
75
-            path: 'guaranteeTask',
81
+            path: "guaranteeTask",
76 82
             element: <GuaranteeTaskList />,
77 83
             meta: {
78
-              title: '军供通报',
84
+              title: "军供通报",
79 85
             },
80 86
           },
81 87
           {
82
-            path: 'guaranteeTask/edit',
88
+            path: "guaranteeTask/edit",
83 89
             element: <GuaranteeTaskEdit />,
84 90
             meta: {
85
-              title: '任务配置',
91
+              title: "任务配置",
86 92
             },
87 93
           },
88 94
           {
89
-            path: 'guaranteeTask/print',
95
+            path: "guaranteeTask/print",
90 96
             element: <GuaranteeTaskPrint />,
91 97
             meta: {
92 98
               hideInMenu: true,
93 99
               noLayout: true,
94
-              target: '_blank',
95
-              title: '任务执行',
100
+              target: "_blank",
101
+              title: "任务执行",
96 102
             },
97
-          }
98
-        ]
103
+          },
104
+        ],
99 105
       },
100 106
       {
101
-        path: 'material',
107
+        path: "material",
102 108
         element: <Container />,
103 109
         meta: {
104
-          title: '物资管理',
110
+          title: "物资管理",
105 111
           icon: <AppstoreOutlined />,
106 112
         },
107 113
         children: [
108 114
           {
109 115
             index: true,
110
-            element: <Navigate to='dish/list' replace />,
116
+            element: <Navigate to="dish/list" replace />,
111 117
           },
112 118
           {
113
-            path: 'dish/list',
119
+            path: "dish/list",
114 120
             element: <DishList />,
115 121
             meta: {
116
-              title: '菜肴管理',
122
+              title: "菜肴管理",
117 123
             },
118 124
           },
119 125
           {
120
-            path: 'dish/edit',
126
+            path: "dish/edit",
121 127
             element: <DishEdit />,
122 128
             meta: {
123 129
               hideInMenu: true,
124
-              title: '菜肴维护',
130
+              title: "菜肴维护",
125 131
             },
126 132
           },
127 133
           {
128
-            path: 'package/list',
134
+            path: "package/list",
129 135
             element: <PackageList />,
130 136
             meta: {
131
-              title: '套餐管理',
137
+              title: "套餐管理",
132 138
             },
133 139
           },
134
-        ]
140
+        ],
135 141
       },
136 142
       {
137
-        path: 'stock',
143
+        path: "stock",
138 144
         element: <Container />,
139 145
         meta: {
140
-          title: '库存管理',
146
+          title: "库存管理",
141 147
           icon: <AppstoreOutlined />,
142 148
         },
143 149
         children: [
144 150
           {
145 151
             index: true,
146
-            element: <Navigate to='list' replace />,
152
+            element: <Navigate to="list" replace />,
147 153
           },
148 154
           {
149
-            path: 'list',
155
+            path: "list",
150 156
             element: <StockList />,
151 157
             meta: {
152
-              title: '库存列表',
158
+              title: "库存列表",
153 159
             },
154 160
           },
155 161
           {
156
-            path: 'add',
162
+            path: "add",
157 163
             element: <StockEdit />,
158 164
             meta: {
159
-              title: '库存维护',
165
+              title: "库存维护",
160 166
             },
161 167
           },
162 168
         ],
163 169
       },
164 170
       {
165
-        path: 'cms',
171
+        path: "cms",
166 172
         element: <Container />,
167 173
         meta: {
168
-          title: '公告文件',
174
+          title: "公告文件",
169 175
         },
170 176
         children: [
171 177
           {
172 178
             index: true,
173
-            element: <Navigate to='rotationChart/list' replace />,
179
+            element: <Navigate to="rotationChart/list" replace />,
174 180
           },
175 181
           {
176
-            path: 'station',
182
+            path: "station",
177 183
             element: null,
178 184
             meta: {
179
-              title: '本站信息',
185
+              title: "本站信息",
180 186
             },
181 187
           },
182 188
           {
183
-            path: 'rotationChart/list',
189
+            path: "rotationChart/list",
184 190
             element: <RotationChartList />,
185 191
             meta: {
186
-              title: '公告内容',
192
+              title: "公告内容",
187 193
             },
188 194
           },
189 195
           {
190
-            path: 'rotationChart/edit',
196
+            path: "rotationChart/edit",
191 197
             element: <RotationChartEdit />,
192 198
             meta: {
193
-              title: '公告维护',
199
+              title: "公告维护",
194 200
             },
195 201
           },
196 202
           {
197
-            path: 'rotationChart/introduction',
203
+            path: "rotationChart/introduction",
198 204
             element: <RotationChartIntroduction />,
199 205
             meta: {
200
-              title: '本站信息简介',
206
+              title: "本站信息简介",
201 207
             },
202 208
           },
203 209
           {
204
-            path: 'regulation',
210
+            path: "regulation",
205 211
             element: null,
206 212
             meta: {
207
-              title: '规章制度',
213
+              title: "规章制度",
208 214
             },
209 215
           },
210 216
           {
211
-            path: 'emergency-plan',
212
-            element: null,
217
+            path: "emergency-plan",
218
+            element: <EmergencyPlanList />,
213 219
             meta: {
214
-              title: '应急预案',
220
+              title: "应急预案",
215 221
             },
216 222
           },
217 223
           {
218
-            path: 'files',
224
+            path: "emergency-plan/edit",
225
+            element: <EmergencyPlanEdit />,
226
+            meta: {
227
+              title: "应急预案维护",
228
+              hideInMenu: true,
229
+            },
230
+          },
231
+          {
232
+            path: "files",
219 233
             element: null,
220 234
             meta: {
221
-              title: '文件管理',
235
+              title: "文件管理",
222 236
             },
223 237
           },
224 238
         ],
225 239
       },
226 240
       {
227
-        path: 'static',
241
+        path: "static",
228 242
         element: <Container />,
229 243
         meta: {
230
-          title: '数据分析',
244
+          title: "数据分析",
231 245
         },
232 246
       },
233 247
       {
234
-        path: 'system',
248
+        path: "system",
235 249
         element: <Container />,
236 250
         meta: {
237
-          title: '系统管理',
251
+          title: "系统管理",
238 252
         },
239 253
         children: [
240 254
           {
241 255
             index: true,
242
-            element: <Navigate to='stockClassification/list' replace />,
256
+            element: <Navigate to="stockClassification/list" replace />,
243 257
           },
244 258
           {
245
-            path: 'stockClassification/list',
259
+            path: "stockClassification/list",
246 260
             element: <StockClassificationList />,
247 261
             meta: {
248
-              title: '库存分类管理',
262
+              title: "库存分类管理",
249 263
             },
250 264
           },
251 265
           {
252
-            path: 'stockClassification/edit',
266
+            path: "stockClassification/edit",
253 267
             element: <StockClassificationEdit />,
254 268
             meta: {
255
-              title: '库存分类维护',
269
+              title: "库存分类维护",
256 270
               hideInMenu: true,
257 271
             },
258 272
           },
259 273
           {
260
-            path: 'log',
274
+            path: "log",
261 275
             element: <StockLog />,
262 276
             meta: {
263
-              title: '库存操作日志',
277
+              title: "库存操作日志",
264 278
             },
265 279
           },
266 280
           {
267
-            path: 'roles',
281
+            path: "roles",
268 282
             element: <Roles />,
269 283
             meta: {
270
-              title: '系统角色管理',
284
+              title: "系统角色管理",
271 285
             },
272 286
           },
273 287
           {
274
-            path: 'user',
288
+            path: "user",
275 289
             element: null,
276 290
             meta: {
277
-              title: '系统用户管理',
291
+              title: "系统用户管理",
278 292
             },
279
-          }
293
+          },
280 294
         ],
281 295
       },
282 296
       {
283
-        path: '*',
284
-        element: <Page404 />
285
-      }
297
+        path: "purchase",
298
+        element: <Container />,
299
+        meta: {
300
+          title: "采购管理",
301
+        },
302
+        children: [
303
+          {
304
+            index: true,
305
+            element: <Navigate to="plan/list" replace />,
306
+          },
307
+          {
308
+            path: "plan/list",
309
+            element: <PurchasePlanList type="plan" />,
310
+            meta: {
311
+              title: "采购计划",
312
+            },
313
+          },
314
+          {
315
+            path: "plan/edit",
316
+            element: <PurchasePlanEdit />,
317
+            meta: {
318
+              title: "采购计划维护",
319
+              hideInMenu: true,
320
+            },
321
+          },
322
+          {
323
+            path: "bill/list",
324
+            element: <PurchasePlanList type="bill" />,
325
+            meta: {
326
+              title: "采购账单",
327
+            },
328
+          },
329
+          {
330
+            path: "bill/edit",
331
+            element: <PurchaseBillEdit />,
332
+            meta: {
333
+              title: "采购账单维护",
334
+              hideInMenu: true,
335
+            },
336
+          },
337
+          {
338
+            path: "inStore/list",
339
+            element: <PurchasePlanList type="inStore" />,
340
+            meta: {
341
+              title: "采购入库",
342
+            },
343
+          },
344
+          {
345
+            path: "inStore/edit",
346
+            element: <PurchaseInStoreEdit  />,
347
+            meta: {
348
+              title: "采购入库维护",
349
+              hideInMenu: true,
350
+            },
351
+          },
352
+        ],
353
+      },
354
+      {
355
+        path: "*",
356
+        element: <Page404 />,
357
+      },
286 358
     ],
287 359
   },
288 360
   {
289
-    path: '/login',
361
+    path: "/login",
290 362
     element: <Login />,
291 363
   },
292 364
   {
293
-    path: '*',
294
-    element: <Page404 />
295
-  }
296
-]
365
+    path: "*",
366
+    element: <Page404 />,
367
+  },
368
+];

+ 10
- 0
src/services/posts.js Ver fichero

@@ -0,0 +1,10 @@
1
+import { restful } from "@/utils/request";
2
+
3
+/**
4
+ * 构造 Service
5
+ * @returns
6
+ */
7
+const [getPostsList, getPostsDetail, savePosts, updatePosts, deletePosts] =
8
+  restful("/posts");
9
+
10
+export { getPostsList, getPostsDetail, savePosts, updatePosts, deletePosts };

+ 43
- 0
src/services/purchase.js Ver fichero

@@ -0,0 +1,43 @@
1
+import request, { restful } from "@/utils/request";
2
+
3
+/**
4
+ * 构造 Service
5
+ * @returns
6
+ */
7
+const [
8
+  getPurchaseList,
9
+  getPurchaseDetail,
10
+  savePurchase,
11
+  updatePurchase,
12
+  deletePurchase,
13
+] = restful("/purchase");
14
+
15
+/**
16
+ * 新增
17
+ *  @param {*} id
18
+ * @param {*} data
19
+ * @returns
20
+ */
21
+  const savePurchaseInStore = (id) => request(`/purchase/${id}/in-store`, { method: 'put'});
22
+
23
+//  const [
24
+//   getResourceList,
25
+//   getResourceDetail,
26
+//   saveResource,
27
+//   updateResource,
28
+//   deleteResource,
29
+//  ] = restful('/resources');
30
+
31
+export {
32
+  getPurchaseList,
33
+  getPurchaseDetail,
34
+  savePurchase,
35
+  updatePurchase,
36
+  deletePurchase,
37
+  savePurchaseInStore,
38
+  //   getResourceList,
39
+  //   getResourceDetail,
40
+  //   saveResource,
41
+  //   updateResource,
42
+  //   deleteResource,
43
+};

+ 2
- 2
src/services/stock.js Ver fichero

@@ -6,7 +6,7 @@ import request from '@/utils/request';
6 6
  * @param {*} params
7 7
  * @returns
8 8
  */
9
-export const getStoreList = (params) => request('/store', { params });
9
+export const getStoreList = (params) => request('/store', { params,successTip:false });
10 10
 
11 11
 /**
12 12
  * 新增
@@ -51,7 +51,7 @@ export const storeExport = (params) => request('/store/export',  { download: tru
51 51
  * @param {*} params
52 52
  * @returns
53 53
  */
54
-export const getStoreTypeList = (params) => request('/storeType', { params });
54
+export const getStoreTypeList = (params) => request('/storeType', { params,successTip:false });
55 55
 
56 56
 /**
57 57
  * 新增

+ 1
- 1
src/services/user.js Ver fichero

@@ -8,7 +8,7 @@ import request from '@/utils/request';
8 8
  * @param {*} 
9 9
  * @returns
10 10
  */
11
- export const queryCurrentUser = () => request('/users/current', { silent: true });
11
+ export const queryCurrentUser = () => request('/users/current', { silent: true,successTip:false });
12 12
 
13 13
  /**
14 14
   * 登录

+ 75
- 0
src/utils/index.jsx Ver fichero

@@ -0,0 +1,75 @@
1
+let toNonExponential = (num) => {
2
+  var m = num.toExponential().match(/\d(?:\.(\d*))?e([+-]\d+)/);
3
+  return num.toFixed(Math.max(0, (m[1] || "").length - m[2]));
4
+};
5
+
6
+/**
7
+ * 乘法 - js运算精度丢失问题
8
+ * @param arg1  数1
9
+ * @param arg2  数2
10
+ * 0.0023 * 100 ==> 0.22999999999999998
11
+ * {{ 0.0023 | multiply(100) }} ==> 0.23
12
+ */
13
+export const floatMultiply = (arg1, arg2) => {
14
+  console.log("==222==");
15
+  arg1 = Number(arg1);
16
+  arg2 = Number(arg2);
17
+  if ((!arg1 && arg1 !== 0) || (!arg2 && arg2 !== 0)) {
18
+    return null;
19
+  }
20
+  arg1 = toNonExponential(arg1);
21
+  arg2 = toNonExponential(arg2);
22
+  let n1, n2;
23
+  let r1, r2; // 小数位数
24
+  try {
25
+    r1 = arg1.toString().split(".")[1].length;
26
+  } catch (e) {
27
+    r1 = 0;
28
+  }
29
+  try {
30
+    r2 = arg2.toString().split(".")[1].length;
31
+  } catch (e) {
32
+    r2 = 0;
33
+  }
34
+  n1 = Number(arg1.toString().replace(".", ""));
35
+  n2 = Number(arg2.toString().replace(".", ""));
36
+  return (n1 * n2) / Math.pow(10, r1 + r2);
37
+};
38
+
39
+/**
40
+ * 除法 - js运算精度丢失问题
41
+ * @param arg1  数1
42
+ * @param arg2  数2
43
+ * 0.0023 / 0.00001 ==> 229.99999999999997
44
+ * {{ 0.0023 | divide(0.00001) }} ==> 230
45
+ */
46
+ export const floatDivide = (arg1, arg2) => {
47
+    arg1 = Number(arg1);
48
+    arg2 = Number(arg2);
49
+    if (!arg2) {
50
+        return null;
51
+    }
52
+    if (!arg1 && arg1!==0) {
53
+        return null;
54
+    }else if(arg1===0) {
55
+        return 0;
56
+    }
57
+    arg1 = toNonExponential(arg1);
58
+    arg2 = toNonExponential(arg2);
59
+    let n1, n2;
60
+    let r1, r2; // 小数位数
61
+    try {
62
+        r1 = arg1.toString().split(".")[1].length;
63
+    } catch (e) {
64
+        r1 = 0;
65
+    }
66
+    try {
67
+        r2 = arg2.toString().split(".")[1].length;
68
+    } catch (e) {
69
+        r2 = 0;
70
+    }
71
+    n1 = Number(arg1.toString().replace(".", ""));
72
+    n2 = Number(arg2.toString().replace(".", ""));
73
+    return floatMultiply((n1 / n2), Math.pow(10, r2 - r1));
74
+    // return (n1 / n2) * Math.pow(10, r2 - r1);   // 直接乘法还是会出现精度问题
75
+}

+ 2
- 2
src/utils/request.js Ver fichero

@@ -3,7 +3,7 @@ import { message } from 'antd';
3 3
 
4 4
 const instance = axios.create({
5 5
   baseURL: import.meta.env.VITE_SERVER_BASE,
6
-  timeout: 1000,
6
+  timeout: 10000,
7 7
 });
8 8
 
9 9
 
@@ -118,7 +118,7 @@ export function queryDict(apiRequest) {
118 118
 
119 119
 export function restful(url) {
120 120
   const list = params => instance.get(url, { params, successTip: false });
121
-  const get = id => instance.get(`${url}/${id}`);
121
+  const get = id => instance.get(`${url}/${id}`,{ successTip: false });
122 122
   const add = data => instance.post(url, data);
123 123
   const update = (id, data) => instance.put(`${url}/${id}`, data);
124 124
   const del = id => instance.delete(`${url}/${id}`);

+ 1
- 1
vite.config.js Ver fichero

@@ -9,7 +9,7 @@ export default defineConfig({
9 9
     proxy: {
10 10
       '/api/': {
11 11
         // 要代理的地址
12
-        target: 'http://127.0.0.1:8087',
12
+        target: 'http://192.168.89.147:8087',
13 13
         // 配置了这个可以从 http 代理到 https
14 14
         // 依赖 origin 的功能可能需要这个,比如 cookie
15 15
         changeOrigin: true,