Преглед изворни кода

Merge branch 'dev' of http://git.ycjcjy.com/jgz/admin into dev

Yansen пре 2 година
родитељ
комит
0ee563c5ea

+ 0
- 2351
package-lock.json
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 1
- 0
package.json Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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;

+ 38
- 0
src/pages/cms/emergencyPlan/detail/index.jsx Прегледај датотеку

@@ -0,0 +1,38 @@
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, Typography, message, Row, Button, Space } from "antd";
11
+import { useEffect, useRef, useState } from "react";
12
+import Wangeditor from "@/components/Wangeditor";
13
+const { Title } = Typography;
14
+export default (props) => {
15
+  const [searchParams] = useSearchParams();
16
+  const id = searchParams.get("id");
17
+  const [data, setData] = useState({});
18
+  const navigate = useNavigate();
19
+
20
+  const formRef = useRef();
21
+
22
+  useEffect(() => {
23
+    if (id) {
24
+      getPostsDetail(id).then((res) => {
25
+        setData(res);
26
+      });
27
+    }
28
+  }, [id]);
29
+
30
+  return (
31
+    <Card extra={<Button onClick={()=>navigate(-1)}> 返回</Button>}>
32
+      <Title level={2} style={{ marginBottom: "2em" }}>
33
+        {data.title}
34
+      </Title>
35
+      <div dangerouslySetInnerHTML={{ __html: data?.detail }}></div>
36
+    </Card>
37
+  );
38
+};

+ 152
- 0
src/pages/cms/emergencyPlan/edit/index.jsx Прегледај датотеку

@@ -0,0 +1,152 @@
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 UploadFile from "@/components/UploadFile";
13
+import Wangeditor from "@/components/Wangeditor";
14
+
15
+export default (props) => {
16
+  const [searchParams] = useSearchParams();
17
+  const id = searchParams.get("id");
18
+  // const [foodDict, setFoodDict] = useState([]);
19
+  const navigate = useNavigate();
20
+
21
+  const formRef = useRef();
22
+  // useEffect(() => {
23
+  //   getStoreList({ isDish: 1, pageSize: 9999 }).then((res) => {
24
+  //     setFoodDict(
25
+  //       res?.records?.map((x) => ({
26
+  //         label: x.name,
27
+  //         value: x.id,
28
+  //       }))
29
+  //     );
30
+  //   });
31
+  // }, [id]);
32
+
33
+  useEffect(() => {
34
+    if (id) {
35
+      getPostsDetail(id).then((res) => {
36
+        formRef.current.setFieldsValue(res);
37
+      });
38
+    }
39
+  }, [id]);
40
+
41
+  const onFinish = async (values) => {
42
+    console.log(values, "===");
43
+
44
+    if (id) {
45
+      updatePosts(id, { ...values, status: Number(values.status) }).then(
46
+        (res) => {
47
+          navigate(-1);
48
+        }
49
+      );
50
+    } else {
51
+      savePosts({ ...values, status: Number(values.status) }).then((res) => {
52
+        navigate(-1);
53
+      });
54
+    }
55
+
56
+    return false;
57
+  };
58
+
59
+  return (
60
+    <PageContainer>
61
+      <Card>
62
+        <ProForm
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
+          <ProForm.Item
102
+            name="file"
103
+            label="文件"
104
+   
105
+           
106
+          >
107
+            <UploadFile
108
+              preview={(value) => {
109
+                return (
110
+                  <div style={{ marginTop: "2em" }}>
111
+                    <a
112
+                      href={value}
113
+                      target="_blank"
114
+                      rel="noopener noreferrer"
115
+                      key="link"
116
+                    >
117
+                      {value}
118
+                    </a>
119
+                  </div>
120
+                );
121
+              }}
122
+            ></UploadFile>
123
+          </ProForm.Item>
124
+
125
+          <ProFormSelect
126
+            name="status"
127
+            label="状态"
128
+            placeholder="请选择"
129
+            rules={[{ required: true, message: "请选择状态" }]}
130
+            width={460}
131
+            options={[
132
+              {
133
+                value: 0,
134
+                label: "未发布",
135
+              },
136
+              {
137
+                value: 1,
138
+                label: "已发布",
139
+              },
140
+            ]}
141
+          />
142
+          <ProFormText
143
+            name="createPerson"
144
+            label="发布人"
145
+            placeholder="请输入发布人"
146
+            width={460}
147
+          />
148
+        </ProForm>
149
+      </Card>
150
+    </PageContainer>
151
+  );
152
+};

+ 136
- 0
src/pages/cms/emergencyPlan/list/index.jsx Прегледај датотеку

@@ -0,0 +1,136 @@
1
+import { getPostsList, deletePosts, updatePosts } 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
+const regex = /(<([^>]+)>)/gi;
10
+
11
+const EmergencyPlanList = (props) => {
12
+  const { type } = props;
13
+
14
+  const actionRef = useRef();
15
+  const navigate = useNavigate();
16
+
17
+  const updata = (row) => {
18
+    if (row.id) {
19
+      updatePosts(row.id, { status: row.status === 1 ? 0 : 1 }).then((res) => {
20
+        actionRef.current.reload();
21
+      });
22
+    }
23
+  };
24
+
25
+  const handleDelete = (id) => {
26
+    if (id) {
27
+      deletePosts(id).then((res) => {
28
+        actionRef.current.reload();
29
+      });
30
+    }
31
+  };
32
+
33
+  const columns = [
34
+    {
35
+      title: "内容名称",
36
+      dataIndex: "title",
37
+    },
38
+
39
+    {
40
+      title: "发布内容",
41
+      dataIndex: "detail",
42
+      search: false,
43
+      ellipsis: true,
44
+      width: "50%",
45
+      renderText: (text) => text.replace(regex, ""),
46
+    },
47
+    {
48
+      title: "状态",
49
+      dataIndex: "status",
50
+      valueType: "select",
51
+      valueEnum: {
52
+        0: { text: "未发布", status: "Error" },
53
+        1: { text: "已发布", status: "Processing" },
54
+      },
55
+    },
56
+    {
57
+      title: "发布人",
58
+      dataIndex: "createPerson",
59
+      search: false,
60
+    },
61
+    {
62
+      title: "操作",
63
+      valueType: "option",
64
+      width: 200,
65
+      render: (_, record) => [
66
+        <Button
67
+          key={3}
68
+          style={{ padding: 0 }}
69
+          type="link"
70
+          onClick={() => {
71
+            updata(record);
72
+          }}
73
+        >
74
+          {record.status === 1 ? "下架" : "发布"}
75
+        </Button>,
76
+        <Button
77
+          key={1}
78
+          style={{ padding: 0 }}
79
+          type="link"
80
+          onClick={() => {
81
+            navigate(`/cms/emergency-plan/detail?id=${record.id}`);
82
+          }}
83
+        >
84
+          详情
85
+        </Button>,
86
+        <Button
87
+          key={2}
88
+          style={{ padding: 0 }}
89
+          type="link"
90
+          onClick={() => {
91
+            navigate(`/cms/emergency-plan/edit?id=${record.id}`);
92
+          }}
93
+        >
94
+          修改
95
+        </Button>,
96
+        <Popconfirm
97
+          key={3}
98
+          title="您是否确认删除 ?"
99
+          onConfirm={() => handleDelete(record.id)}
100
+          okText="确定"
101
+          cancelText="取消"
102
+        >
103
+          {/* manualPush */}
104
+          <Button style={{ padding: 0 }} type="link">
105
+            删除
106
+          </Button>
107
+        </Popconfirm>,
108
+      ],
109
+    },
110
+  ];
111
+
112
+  return (
113
+    <PageContainer>
114
+      <ProTable
115
+        actionRef={actionRef}
116
+        rowKey="id"
117
+        toolBarRender={() => [
118
+          <Button
119
+            key="2"
120
+            type="primary"
121
+            onClick={() => {
122
+              navigate("/cms/emergency-plan/edit");
123
+            }}
124
+          >
125
+            新增
126
+          </Button>,
127
+        ]}
128
+        // search={false}
129
+        request={queryTable(getPostsList)}
130
+        columns={columns}
131
+      />
132
+    </PageContainer>
133
+  );
134
+};
135
+
136
+export default EmergencyPlanList;

+ 55
- 0
src/pages/cms/files/list/addFiles.jsx Прегледај датотеку

@@ -0,0 +1,55 @@
1
+import { PlusOutlined } from '@ant-design/icons';
2
+import {
3
+  ModalForm,
4
+  ProForm,
5
+  ProFormDateRangePicker,
6
+  ProFormSelect,
7
+  ProFormText,
8
+} from '@ant-design/pro-components';
9
+import { Button, Form, message } from 'antd';
10
+
11
+
12
+
13
+export default () => {
14
+  const [form] = Form.useForm();
15
+
16
+
17
+  const onFinish = ()=>{
18
+
19
+  }
20
+
21
+  return (
22
+    <ModalForm
23
+      title="新建表单"
24
+      trigger={
25
+        <Button type="primary">
26
+          <PlusOutlined />
27
+          新建表单
28
+        </Button>
29
+      }
30
+      form={form}
31
+      autoFocusFirstInput
32
+      modalProps={{
33
+        destroyOnClose: true,
34
+        onCancel: () => console.log('run'),
35
+      }}
36
+      submitTimeout={2000}
37
+      onFinish={async (values) => {
38
+        await waitTime(2000);
39
+        console.log(values.name);
40
+        message.success('提交成功');
41
+        return true;
42
+      }}
43
+    >
44
+    
45
+        <ProFormText
46
+          width="md"
47
+          name="name"
48
+          label="文件名称"
49
+
50
+          placeholder="请输入名称"
51
+        />
52
+
53
+    </ModalForm>
54
+  );
55
+};

+ 164
- 0
src/pages/cms/files/list/index.jsx Прегледај датотеку

@@ -0,0 +1,164 @@
1
+import { getPostsList, deletePosts, updatePosts } from "@/services/posts";
2
+import { queryTable } from "@/utils/request";
3
+import { PageContainer, ProTable, ProList } 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
+import AddFiles from './addFiles'
9
+
10
+const FilesList = (props) => {
11
+
12
+  const [showDetail, setShowDetail] = useState(false);
13
+  const [activeKey, setActiveKey] = useState("");
14
+  const actionRef = useRef();
15
+  const navigate = useNavigate();
16
+
17
+
18
+  const updata = (row) => {
19
+    if (row.id) {
20
+      updatePosts(row.id, { status: row.status === 1 ? 0 : 1 }).then((res) => {
21
+        actionRef.current.reload();
22
+      });
23
+    }
24
+  };
25
+
26
+  const handleDelete = (id) => {
27
+    if (id) {
28
+      deletePosts(id).then((res) => {
29
+        actionRef.current.reload();
30
+      });
31
+    }
32
+  };
33
+
34
+  const columns = [
35
+    {
36
+      title: "内容名称",
37
+      dataIndex: "title",
38
+    },
39
+
40
+    {
41
+      title: "状态",
42
+      dataIndex: "status",
43
+      valueType: "select",
44
+      valueEnum: {
45
+        0: { text: "未发布", status: "Error" },
46
+        1: { text: "已发布", status: "Processing" },
47
+      },
48
+    },
49
+    {
50
+      title: "发布人",
51
+      dataIndex: "createPerson",
52
+      search: false,
53
+    },
54
+    {
55
+      title: "操作",
56
+      valueType: "option",
57
+      width: 200,
58
+      render: (_, record) => [
59
+        <Button
60
+          key={3}
61
+          style={{ padding: 0 }}
62
+          type="link"
63
+          onClick={() => {
64
+            updata(record);
65
+          }}
66
+        >
67
+          {record.status === 1 ? "下架" : "发布"}
68
+        </Button>,
69
+        <Button
70
+          key={1}
71
+          style={{ padding: 0 }}
72
+          type="link"
73
+          onClick={() => {
74
+            navigate(`/cms/emergency-plan/detail?id=${record.id}`);
75
+          }}
76
+        >
77
+          详情
78
+        </Button>,
79
+        <Button
80
+          key={2}
81
+          style={{ padding: 0 }}
82
+          type="link"
83
+          onClick={() => {
84
+            navigate(`/cms/emergency-plan/edit?id=${record.id}`);
85
+          }}
86
+        >
87
+          修改
88
+        </Button>,
89
+        <Popconfirm
90
+          key={3}
91
+          title="您是否确认删除 ?"
92
+          onConfirm={() => handleDelete(record.id)}
93
+          okText="确定"
94
+          cancelText="取消"
95
+        >
96
+          {/* manualPush */}
97
+          <Button style={{ padding: 0 }} type="link">
98
+            删除
99
+          </Button>
100
+        </Popconfirm>,
101
+      ],
102
+    },
103
+  ];
104
+
105
+  return (
106
+    <PageContainer>
107
+      <ProList
108
+        toolBarRender={() => {
109
+          return [
110
+           <AddFiles />,
111
+          ];
112
+        }}
113
+        search={{}}
114
+        rowKey="id"
115
+        // headerTitle="基础列表"
116
+        pagination={{
117
+          pageSize: 5,
118
+        }}
119
+        showActions="hover"
120
+        metas={{
121
+          title: {
122
+            dataIndex: "fileName",
123
+            title: "文件名称",
124
+          },
125
+          description: {
126
+            dataIndex: "title",
127
+            search: false,
128
+          },
129
+          actions: {
130
+            render: (text, row) => [
131
+              <a
132
+                href={row.url}
133
+                target="_blank"
134
+                rel="noopener noreferrer"
135
+                key="link"
136
+              >
137
+                链路
138
+              </a>,
139
+              <a
140
+                href={row.url}
141
+                target="_blank"
142
+                rel="noopener noreferrer"
143
+                key="warning"
144
+              >
145
+                报警
146
+              </a>,
147
+              <a
148
+                href={row.url}
149
+                target="_blank"
150
+                rel="noopener noreferrer"
151
+                key="view"
152
+              >
153
+                查看
154
+              </a>,
155
+            ],
156
+            search: false,
157
+          },
158
+        }}
159
+      />
160
+    </PageContainer>
161
+  );
162
+};
163
+
164
+export default FilesList;

+ 213
- 0
src/pages/purchase/bill/edit/index.jsx Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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
       });

+ 48
- 0
src/regulation/index.jsx Прегледај датотеку

@@ -0,0 +1,48 @@
1
+import { PageContainer, ProTable } from '@ant-design/pro-components';
2
+import { useRef, useState } from 'react';
3
+import { useNavigate } from 'react-router-dom';
4
+import { queryTable } from '@/utils/request';
5
+
6
+const RegulationList = (props) => {
7
+const actionRef = useRef();
8
+const navigate = useNavigate();
9
+
10
+const columns = [
11
+    {
12
+      title: 'id',
13
+      dataIndex: 'id',
14
+    },
15
+    {
16
+      title: '标题',
17
+      dataIndex: 'title',
18
+    },
19
+
20
+    {
21
+      title: '内容',
22
+      dataIndex: 'content',
23
+    },
24
+
25
+    {
26
+      title: '发布人',
27
+      dataIndex: 'faburen',
28
+    },
29
+    {
30
+      title: '发布时间',
31
+      dataIndex: 'fabutime',
32
+    },
33
+  ];
34
+
35
+  return (
36
+    <PageContainer>
37
+      <ProTable
38
+        search={false}
39
+        actionRef={actionRef}
40
+        rowKey="id"
41
+        // request={queryTable(getBannerList)}
42
+        columns={columns}
43
+      />
44
+    </PageContainer>
45
+  );
46
+}
47
+
48
+export default RegulationList;

+ 92
- 7
src/routes/routes.jsx Прегледај датотеку

@@ -31,8 +31,17 @@ import RotationChartList from '@/pages/rotationChart/list';
31 31
 import RotationChartEdit from '@/pages/rotationChart/edit';
32 32
 import RotationChartIntroduction from '@/pages/rotationChart/introduction';
33 33
 import Roles from '@/pages/roles/index';
34
+import RegulationList from '@/regulation';
34 35
 import UserList from '@/pages/user';
35 36
 import UserEdit from '@/pages/user/Edit';
37
+import PurchasePlanList from "@/pages/purchase/plan/list";
38
+import PurchasePlanEdit from "@/pages/purchase/plan/edit";
39
+import PurchaseBillEdit from "@/pages/purchase/bill/edit";
40
+import PurchaseInStoreEdit from "@/pages/purchase/inStore/edit";
41
+import EmergencyPlanList from "@/pages/cms/emergencyPlan/list";
42
+import EmergencyPlanEdit from "@/pages/cms/emergencyPlan/edit";
43
+import EmergencyPlanDetail from "@/pages/cms/emergencyPlan/detail";
44
+import FilesList from "@/pages/cms/files/list";
36 45
 
37 46
 /**
38 47
  * meta 用来扩展自定义数据数据
@@ -173,7 +182,7 @@ export const authRoutes = [
173 182
         },
174 183
       },
175 184
       {
176
-        path: 'rotationChart/edit',
185
+        path: 'rotationChart/add',
177 186
         element: <RotationChartEdit />,
178 187
         meta: {
179 188
           title: '公告维护',
@@ -194,19 +203,37 @@ export const authRoutes = [
194 203
         },
195 204
       },
196 205
       {
197
-        path: 'emergency-plan',
198
-        element: null,
206
+        path: "emergency-plan",
207
+        element: <EmergencyPlanList />,
199 208
         meta: {
200
-          title: '应急预案',
209
+          title: "应急预案",
201 210
         },
202 211
       },
203 212
       {
204
-        path: 'files',
205
-        element: null,
213
+        path: "emergency-plan/edit",
214
+        element: <EmergencyPlanEdit />,
215
+        meta: {
216
+          title: "应急预案维护",
217
+          hideInMenu: true,
218
+        },
219
+      },
220
+      {
221
+        path: "emergency-plan/detail",
222
+        element: <EmergencyPlanDetail />,
223
+        meta: {
224
+          title: "应急预案详情",
225
+          hideInMenu: true,
226
+        },
227
+      },
228
+
229
+      {
230
+        path: "files",
231
+        element: <FilesList />,
206 232
         meta: {
207
-          title: '文件管理',
233
+          title: "文件管理",
208 234
         },
209 235
       },
236
+     
210 237
     ],
211 238
   },
212 239
   {
@@ -273,6 +300,64 @@ export const authRoutes = [
273 300
       }
274 301
     ],
275 302
   },
303
+  {
304
+    path: "purchase",
305
+    element: <Container />,
306
+    meta: {
307
+      title: "采购管理",
308
+    },
309
+    children: [
310
+      {
311
+        index: true,
312
+        element: <Navigate to="plan/list" replace />,
313
+      },
314
+      {
315
+        path: "plan/list",
316
+        element: <PurchasePlanList type="plan" />,
317
+        meta: {
318
+          title: "采购计划",
319
+        },
320
+      },
321
+      {
322
+        path: "plan/edit",
323
+        element: <PurchasePlanEdit />,
324
+        meta: {
325
+          title: "采购计划维护",
326
+          hideInMenu: true,
327
+        },
328
+      },
329
+      {
330
+        path: "bill/list",
331
+        element: <PurchasePlanList type="bill" />,
332
+        meta: {
333
+          title: "采购账单",
334
+        },
335
+      },
336
+      {
337
+        path: "bill/edit",
338
+        element: <PurchaseBillEdit />,
339
+        meta: {
340
+          title: "采购账单维护",
341
+          hideInMenu: true,
342
+        },
343
+      },
344
+      {
345
+        path: "inStore/list",
346
+        element: <PurchasePlanList type="inStore" />,
347
+        meta: {
348
+          title: "采购入库",
349
+        },
350
+      },
351
+      {
352
+        path: "inStore/edit",
353
+        element: <PurchaseInStoreEdit  />,
354
+        meta: {
355
+          title: "采购入库维护",
356
+          hideInMenu: true,
357
+        },
358
+      },
359
+    ],
360
+  },
276 361
 ]
277 362
 
278 363
 export const defaultRoutes = [

+ 10
- 0
src/services/posts.js Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -8,7 +8,7 @@ import request, { restful } 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 Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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,