Yansen 2 vuotta sitten
vanhempi
commit
bb8b085c11

+ 34
- 23
src/components/Wangeditor/index.jsx Näytä tiedosto

@@ -5,7 +5,16 @@ import { Editor, Toolbar } from "@wangeditor/editor-for-react";
5 5
 // 工具栏配置参考
6 6
 // https://www.cnblogs.com/-roc/p/16400965.html
7 7
 
8
+const defaultStyle = {
9
+  border: "1px solid #ccc",
10
+  zIndex: 100,
11
+  marginTop: "15px"
12
+}
13
+
8 14
 function MyEditor(props) {
15
+
16
+  const style = React.useMemo(() => ({ ...defaultStyle, ...(props.style || {}) }), [props.style])
17
+
9 18
   const {
10 19
     value = "",
11 20
     onChange = (e) => {
@@ -22,19 +31,23 @@ function MyEditor(props) {
22 31
   const [editor, setEditor] = useState(null); // 存储 editor 实例
23 32
   const [html, setHtml] = useState("");
24 33
  
25
-  // 模拟 ajax 请求,异步设置 html
26
-  useEffect(() => {
27
-    setHtml(value || "");
28
-  }, [value]);
34
+  // // 模拟 ajax 请求,异步设置 html
35
+  // useEffect(() => {
36
+  //   setHtml(value || "");
37
+  // }, [value]);
29 38
 
30 39
   // 及时销毁 editor
31 40
   useEffect(() => {
41
+    if (editor) {
42
+      setHtml(value || "");
43
+    }
44
+
32 45
     return () => {
33 46
       if (editor == null) return;
34 47
       editor.destroy();
35 48
       setEditor(null);
36 49
     };
37
-  }, [editor]);
50
+  }, [editor, value]);
38 51
 
39 52
   function insertText() {
40 53
     if (editor == null) return;
@@ -47,24 +60,22 @@ function MyEditor(props) {
47 60
   }
48 61
 
49 62
   return !readonly ? (
50
-    <>
51
-      <div style={{ border: "1px solid #ccc", zIndex: 100, marginTop: "15px" }}>
52
-        <Toolbar
53
-          editor={editor}
54
-          defaultConfig={toolbarConfig}
55
-          mode="default"
56
-          style={{ borderBottom: "1px solid #ccc" }}
57
-        />
58
-        <Editor
59
-          defaultConfig={editorConfig}
60
-          value={html}
61
-          onCreated={setEditor}
62
-          onChange={(editor) => onChange(editor.getHtml())}
63
-          mode="default"
64
-          style={{ height: "500px" }}
65
-        />
66
-      </div>
67
-    </>
63
+    <div className={props.className} style={style}>
64
+      <Toolbar
65
+        editor={editor}
66
+        defaultConfig={toolbarConfig}
67
+        mode="default"
68
+        style={{ borderBottom: "1px solid #ccc" }}
69
+      />
70
+      <Editor
71
+        defaultConfig={editorConfig}
72
+        value={html}
73
+        onCreated={setEditor}
74
+        onChange={(editor) => onChange(editor.getHtml())}
75
+        mode="default"
76
+        style={{ height: "500px" }}
77
+      />
78
+    </div>
68 79
   ) : (
69 80
     <div dangerouslySetInnerHTML={{ __html: value }}></div>
70 81
   );

+ 27
- 0
src/pages/dish/edit/Detail.jsx Näytä tiedosto

@@ -0,0 +1,27 @@
1
+import React from 'react';
2
+import { Row, Col, Divider, Typography, Image } from 'antd';
3
+
4
+const { Title, Paragraph } = Typography;
5
+
6
+export default (props) => {
7
+
8
+  const { dish = {} } = props;
9
+
10
+  return (
11
+    <Row gutter={24}>
12
+      <Col span={12}>
13
+        <Typography>
14
+          {/* <Title level={3}>
15
+            五花肉
16
+          </Title> */}
17
+          <Paragraph>
18
+            <div dangerouslySetInnerHTML={{ __html: dish.content }}  style={{ fontSize: '16px', lineHeight: '2em' }} />
19
+          </Paragraph>
20
+        </Typography>
21
+      </Col>
22
+      <Col span={12}>
23
+        <Image src={dish.thumb} />
24
+      </Col>
25
+    </Row>
26
+  )
27
+}

+ 49
- 0
src/pages/dish/edit/Edit.jsx Näytä tiedosto

@@ -0,0 +1,49 @@
1
+import { getStoreList, getStoreTypeList } from '@/services/stock';
2
+import { Alert, Row, Col } from 'antd';
3
+import { useEffect, useState, useMemo } from 'react';
4
+import Form from './Form';
5
+
6
+export default (props) => {
7
+  const { dish, onFinish } = props;
8
+
9
+  const [ingredientsList, setIngredientsList] = useState([]);
10
+  const [storeList, setStoreList] = useState([]);
11
+  const [storeTypeList, setStoreTypeList] = useState([]);
12
+  
13
+  const foodDict = useMemo(() => storeList.map(x => ({ label: x.name, value: x.id, })), [storeList]);
14
+  const Nutrition = useMemo(() => {
15
+    if (!ingredientsList.length
16
+      || !storeList.length
17
+      || !storeTypeList.length
18
+      ) return [];
19
+
20
+    return ingredientsList.map(x => storeList.filter(y => y.id === x)[0])
21
+      .map(x => storeTypeList.filter(y => y.id === x.typeId)[0].nutrition)
22
+      .map((it, inx) => (<p key={inx}>{it}</p>));
23
+  }, [ingredientsList, storeList, storeTypeList]);
24
+  
25
+  useEffect(() => {
26
+    getStoreList({ isDish: 1, pageSize: 9999 }).then((res) => {
27
+      setStoreList(res?.records || []);
28
+    });
29
+    getStoreTypeList({ isFood: 1, pageSize: 9999 }).then((res) => {
30
+      setStoreTypeList(res?.records || []);
31
+    });
32
+  }, []);
33
+
34
+  useEffect(() => {
35
+    const { ingredientsIdList } = dish || {};
36
+    setIngredientsList(ingredientsIdList || [])
37
+  }, [dish]);
38
+
39
+  return (
40
+    <Row gutter={48}>
41
+      <Col span={12}>
42
+        <Form dish={dish} onFinish={onFinish} foodDict={foodDict} onIngredientsChange={setIngredientsList} />         
43
+      </Col>
44
+      <Col span={12}>
45
+        <Alert message="营养元素" description={Nutrition} type="info" />
46
+      </Col>
47
+    </Row>
48
+  );
49
+};

+ 88
- 0
src/pages/dish/edit/Form.jsx Näytä tiedosto

@@ -0,0 +1,88 @@
1
+import { addDish } from '@/services/dish';
2
+import { ProForm, ProFormSelect, ProFormText, ProFormMoney } from '@ant-design/pro-components';
3
+import { useNavigate, useSearchParams } from 'react-router-dom';
4
+import { Row, Col, Space } from 'antd';
5
+import { useEffect, useRef, useState, useMemo } from 'react';
6
+import UploadFile from '@/components/UploadFile';
7
+import Wangeditor from "@/components/Wangeditor";
8
+import { floatMultiply, floatDivide } from "@/utils/float";
9
+
10
+export default (props) => {
11
+  const [searchParams] = useSearchParams();
12
+  const id = searchParams.get('id');
13
+  const navigate = useNavigate();
14
+
15
+  const formRef = useRef();
16
+
17
+  useEffect(() => {
18
+    if (props.dish) {
19
+      formRef.current.setFieldsValue({ ...props.dish, price: floatDivide(props.dish.price, 100) });
20
+    }
21
+  }, [props.dish]);
22
+
23
+  const onFinish = async (values) => {
24
+    addDish({ ...values, price: floatMultiply(values.price, 100), id }).then((res) => {
25
+      props.onFinish(res);
26
+    });
27
+
28
+    return false;
29
+  };
30
+
31
+  return (
32
+    <ProForm
33
+      formRef={formRef}
34
+      layout={'horizontal'}
35
+      labelCol={{ span: 4 }}
36
+      wrapperCol={{ span: 20 }}
37
+      onFinish={onFinish}
38
+      initialValues={{ type: '1', state: '1' }}
39
+      submitter={{
40
+        searchConfig: {
41
+          resetText: '返回',
42
+        },
43
+        onReset: () => navigate(-1),
44
+        render: (props, doms) => {
45
+          return (
46
+            <Row>
47
+              <Col span={8} offset={8}>
48
+                <Space>{doms}</Space>
49
+              </Col>
50
+            </Row>
51
+          );
52
+        },
53
+      }}
54
+    >
55
+      <ProFormText
56
+        name="name"
57
+        label="名称"
58
+        placeholder="请输入菜肴名称"
59
+        rules={[{ required: true, message: '请输入菜肴名称' }]}
60
+      />
61
+      <ProFormText
62
+        name="unit"
63
+        label="单位"
64
+        placeholder="请输入菜肴单位"
65
+        rules={[{ required: true, message: '请输入菜肴单位' }]}
66
+      />
67
+      <ProFormMoney
68
+        name="price"
69
+        label="价格"
70
+        rules={[{ required: true, message: '请输入菜肴价格' }]}
71
+      />
72
+      <ProFormSelect
73
+        mode="multiple"
74
+        name="ingredientsIdList"
75
+        label="食材"
76
+        placeholder="请选择包含食材"
77
+        options={props.foodDict}
78
+        onChange={props.onIngredientsChange}
79
+      />
80
+      <ProForm.Item name="thumb" label="图片">
81
+        <UploadFile preview={true} />
82
+      </ProForm.Item>
83
+      <ProForm.Item name="content" label="做法">
84
+        <Wangeditor></Wangeditor>
85
+      </ProForm.Item>
86
+    </ProForm>
87
+  );
88
+};

+ 19
- 95
src/pages/dish/edit/index.jsx Näytä tiedosto

@@ -1,115 +1,39 @@
1
-import { addDish, getDishById } from '@/services/dish';
2
-import { getStoreList } from '@/services/stock';
3
-import { PageContainer, ProForm, ProFormSelect, ProFormText, ProFormMoney, ProFormDigit } from '@ant-design/pro-components';
1
+import { getDishById } from '@/services/dish';
2
+import { PageContainer } from '@ant-design/pro-components';
4 3
 import { useNavigate, useSearchParams } from 'react-router-dom';
5
-import { Card, Col, message, Row, Space } from 'antd';
6
-import { useEffect, useRef, useState } from 'react';
7
-import { floatMultiply, floatDivide } from "@/utils/float";
4
+import { Alert, Card, Row, Col, message, Space, Button } from 'antd';
5
+import { useEffect, useRef, useState, useMemo } from 'react';
6
+import Detail from './Detail';
7
+import Edit from './Edit';
8 8
 
9 9
 export default (props) => {
10 10
   const [searchParams] = useSearchParams();
11 11
   const id = searchParams.get('id');
12
-  const [foodDict, setFoodDict] = useState([]);
12
+  const [dish, setDish] = useState();
13
+  const [isPreivw, setIsPreview] = useState(!!id);
13 14
   const navigate = useNavigate();
14
-
15
-  const formRef = useRef();
16
-  useEffect(() => {
17
-    getStoreList({ isDish: 1, pageSize: 9999 }).then((res) => {
18
-      setFoodDict(
19
-        res?.records?.map((x) => ({
20
-          label: x.name,
21
-          value: x.id,
22
-        })),
23
-      );
24
-    });
25
-  }, [id]);
26
-
15
+  
27 16
   useEffect(() => {
28 17
     if (id) {
29 18
       getDishById(id).then((res) => {
30
-        formRef.current.setFieldsValue({ ...res, price: floatDivide(res.price, 100) });
19
+        setDish(res);
31 20
       });
32 21
     }
33 22
   }, [id]);
34 23
 
35
-  const onFinish = async (values) => {
36
-    console.log(values, '===');
37
-
38
-    addDish({ ...values, price: floatMultiply(values.price, 100), id }).then((res) => {
39
-      // message.success('添加成功');
40
-      navigate(-1);
41
-    });
42
-
43
-    return false;
24
+  const onFinish = (values) => {
25
+    setDish(values);
26
+    // navigate(-1);
44 27
   };
45 28
 
46 29
   return (
47 30
     <PageContainer>
48
-      <Card>
49
-        <ProForm
50
-          formRef={formRef}
51
-          layout={'horizontal'}
52
-          labelCol={{ span: 8 }}
53
-          wrapperCol={{ span: 16 }}
54
-          onFinish={onFinish}
55
-          initialValues={{ type: '1', state: '1' }}
56
-          submitter={{
57
-            searchConfig: {
58
-              resetText: '返回',
59
-            },
60
-            onReset: () => navigate(-1),
61
-            render: (props, doms) => {
62
-              return (
63
-                <Row>
64
-                  <Col span={8} offset={8}>
65
-                    <Space>{doms}</Space>
66
-                  </Col>
67
-                </Row>
68
-              );
69
-            },
70
-          }}
71
-        >
72
-          <ProFormText
73
-            name="name"
74
-            label="菜肴名称"
75
-            placeholder="请输入菜肴名称"
76
-            rules={[{ required: true, message: '请输入菜肴名称' }]}
77
-            width={460}
78
-          />
79
-          <ProFormText
80
-            name="unit"
81
-            label="菜肴单位"
82
-            placeholder="请输入菜肴单位"
83
-            rules={[{ required: true, message: '请输入菜肴单位' }]}
84
-            width={460}
85
-          />
86
-          <ProFormMoney
87
-            name="price"
88
-            label="价格"
89
-            rules={[{ required: true, message: '请输入菜肴价格' }]}
90
-            width={460}
91
-          />
92
-          <ProFormSelect
93
-            mode="multiple"
94
-            name="ingredientsIdList"
95
-            label="包含食材"
96
-            placeholder="请选择包含食材"
97
-            rules={[{ required: true, message: '请选择包含食材' }]}
98
-            width={460}
99
-            options={foodDict}
100
-          />
101
-          <ProFormDigit
102
-            label="元素"
103
-            name="calorie"
104
-            min={0}
105
-            width={460}
106
-            placeholder="卡路里"
107
-            fieldProps={{
108
-              addonAfter: '卡',
109
-              precision: '4'
110
-            }}
111
-          />
112
-        </ProForm>
31
+      <Card
32
+        title={(dish || {}).name}
33
+        extra={<Button type='link' disabled={!id} onClick={() => setIsPreview(!isPreivw)}>{ isPreivw ? '编辑' : '图文' }</Button>}>
34
+        {
35
+          isPreivw ? <Detail dish={dish} /> : <Edit dish={dish} onFinish={onFinish} />
36
+        }
113 37
       </Card>
114 38
     </PageContainer>
115 39
   );

+ 7
- 7
src/pages/guaranteeTask/Edit/DishList.jsx Näytä tiedosto

@@ -19,12 +19,12 @@ export default (props) => {
19 19
   const packageRef = useRef();
20 20
   const dishRef = useRef();
21 21
 
22
-  const calorie = useMemo(() => {
23
-    return list.reduce((acc, it) => {
24
-      const dish = dishRef.current.filterItem(it.dishId) || {};
25
-      return acc + dish.calorie || 0;
26
-    }, 0);
27
-  }, [list]);
22
+  // const calorie = useMemo(() => {
23
+  //   return list.reduce((acc, it) => {
24
+  //     const dish = dishRef.current.filterItem(it.dishId) || {};
25
+  //     return acc + dish.calorie || 0;
26
+  //   }, 0);
27
+  // }, [list]);
28 28
 
29 29
   const handlePackageSubmit = ({item, amount}) => {
30 30
     packageRef.current = item;
@@ -144,7 +144,7 @@ export default (props) => {
144 144
       </Col>
145 145
       <Col span={16}>
146 146
         <Card
147
-          title={`已选菜肴 共计${calorie}卡`}
147
+          title="已选菜肴"
148 148
           loading={loading}
149 149
           extra={<Button disabled={!dataSource} type='primary' loading={loading} onClick={onSubmit}>保存</Button>}
150 150
         >

+ 87
- 55
src/pages/package/DishList.jsx Näytä tiedosto

@@ -1,15 +1,23 @@
1
-import React, { useEffect, useState, useRef } from 'react';
2
-import { Button, List, Popconfirm, Select } from 'antd';
1
+import React, { useEffect, useState, useRef, forwardRef, useImperativeHandle } from 'react';
2
+import { Button, Modal, List, Popconfirm, Form, Select, message } from 'antd';
3 3
 import classNames from 'classnames';
4
+import useBool from '@/utils/hooks/useBool';
4 5
 import { getPackageDetailList, addPackageDetail, deletePackageDetail } from '@/services/package';
5 6
 import { getDishList } from '@/services/dish';
6 7
 
7 8
 const { Option } = Select;
9
+const defaultKind = 2;
8 10
 
9
-const Header = props => {
11
+const AddDish = props => {
10 12
   const { onChange } = props;
11 13
   const [data, setData] = useState([]);
12
-  const [value, setValue] = useState();
14
+  const [form] = Form.useForm();
15
+
16
+  const onFinish = (values) => {
17
+    const it = data.filter(x => x.id === values.dishId)[0] || {};
18
+    const dishKind = values.dishKind || defaultKind;
19
+    onChange({...it, dishKind});
20
+  };
13 21
 
14 22
   const handleSearch = (newValue) => {
15 23
     if (newValue) {
@@ -21,17 +29,10 @@ const Header = props => {
21 29
     }
22 30
   };
23 31
 
24
-  const handleChange = (newValue) => {
25
-    setValue(newValue);
26
-    if (newValue) {
27
-      onChange(data.filter(x => x.id === newValue)[0]);
28
-    }
29
-  };
30
-
31 32
   const options = data.map(d => <Option key={d.id} value={d.id}>{d.name}</Option>);
32 33
 
33 34
   const initList = () => {
34
-    getDishList({ pageNum: 1, pageSize: 10 }).then(res => {
35
+    getDishList({ pageNum: 1, pageSize: 20 }).then(res => {
35 36
       setData(res.records || []);
36 37
     });
37 38
   }
@@ -41,32 +42,48 @@ const Header = props => {
41 42
   }, [])
42 43
 
43 44
   return (
44
-    <Select
45
-      style={{ width: '100%' }}
46
-      allowClear
47
-      showSearch
48
-      value={value}
49
-      placeholder='请选择菜肴'
50
-      defaultActiveFirstOption={false}
51
-      showArrow={false}
52
-      filterOption={false}
53
-      onSearch={handleSearch}
54
-      onChange={handleChange}
55
-      notFoundContent={null}
56
-      onClear={initList}
57
-    >
58
-      {options}
59
-    </Select>
45
+    <Form form={form} layout="vertical" onFinish={onFinish}>
46
+      <Form.Item name="dishId" label="选择菜肴" rules={[{ required: true, message: '请选择菜肴' }]}>
47
+        <Select
48
+          allowClear
49
+          showSearch
50
+          placeholder='请选择菜肴, 可输入汉字搜索'
51
+          defaultActiveFirstOption={false}
52
+          showArrow={false}
53
+          filterOption={false}
54
+          onSearch={handleSearch}
55
+          // onChange={handleChange}
56
+          notFoundContent={null}
57
+          onClear={initList}
58
+        >
59
+          {options}
60
+        </Select>
61
+      </Form.Item>
62
+      <Form.Item name="dishKind" label="菜肴类型">
63
+        <Select allowClear defaultValue={defaultKind}>
64
+          <Select.Option value={1}>主食</Select.Option>
65
+          <Select.Option value={2}>菜肴</Select.Option>
66
+        </Select>
67
+      </Form.Item>
68
+      <Form.Item>
69
+        <Button type='primary' htmlType='sumbit'>确定</Button>
70
+      </Form.Item>
71
+    </Form>
60 72
   );
61 73
 }
62 74
 
75
+const kindDict = {
76
+  '1': '主食',
77
+  '2': '菜肴',
78
+}
63 79
 
64
-export default (props) => {
80
+export default forwardRef((props, ref) => {
65 81
   const { current, setCurrent } = props;
66 82
 
67 83
   const packageId = (current || {}).id;
68 84
 
69 85
   const [loading, setLoading] = useState(false);
86
+  const [open, setVisible, hide ] = useBool();
70 87
   const [list, setList] = useState([]);
71 88
   const [detail, setDetail] = useState({});
72 89
   const listRef = useRef();
@@ -74,10 +91,11 @@ export default (props) => {
74 91
 
75 92
   const onAdd = item => {
76 93
     setLoading(true);
77
-    addPackageDetail({ packageId, dishId: item.id }).then(res => {
94
+    addPackageDetail({ ...item, packageId, dishId: item.id }).then(res => {
78 95
       setLoading(false);
79 96
       const newList = listRef.current.concat(res);
80 97
       setList(newList);
98
+      hide();
81 99
     }).catch(() => {
82 100
       setLoading(false);
83 101
     });
@@ -108,30 +126,44 @@ export default (props) => {
108 126
 
109 127
   }, [packageId]);
110 128
 
129
+  useImperativeHandle(ref, () => ({
130
+    new: () => setVisible(),
131
+  }));
132
+
111 133
   return (
112
-    <List
113
-      style={{ minHeight: '300px' }}
114
-      header={<Header onChange={onAdd} />}
115
-      bordered
116
-      loading={loading}
117
-      dataSource={list}
118
-      renderItem={item => (
119
-        <List.Item
120
-          className={classNames({ active: detail.id === item.id })}
121
-          onClick={() => setDetail(item)}
122
-          actions={[
123
-            <Popconfirm
124
-              key="delete"
125
-              title="确认删除?"
126
-              onConfirm={() => onDelete(item)}
127
-              >
128
-              <a href="#">删除</a>
129
-            </Popconfirm>
130
-          ]}
131
-        >
132
-          {item.name}
133
-        </List.Item>
134
-      )}
135
-    />
134
+    <>
135
+      <List
136
+        style={{ minHeight: '300px' }}
137
+        loading={loading}
138
+        dataSource={list}
139
+        renderItem={item => (
140
+          <List.Item
141
+            className={classNames({ active: detail.id === item.id })}
142
+            onClick={() => setDetail(item)}
143
+            actions={[
144
+              <Popconfirm
145
+                key="delete"
146
+                title="确认删除?"
147
+                onConfirm={() => onDelete(item)}
148
+                >
149
+                <a href="#">删除</a>
150
+              </Popconfirm>
151
+            ]}
152
+          >
153
+            {`【${kindDict[`${item.dishKind}`]}】${item.name}`}
154
+          </List.Item>
155
+        )}
156
+      />
157
+      <Modal
158
+        title="添加菜肴"
159
+        open={open}
160
+        onCancel={hide}
161
+        maskClosable={false}
162
+        footer={null}
163
+        destroyOnClose
164
+      >
165
+        <AddDish onChange={onAdd} />
166
+      </Modal>
167
+    </>
136 168
   );
137
-}
169
+})

+ 36
- 18
src/pages/package/List.jsx Näytä tiedosto

@@ -1,12 +1,15 @@
1
-import React, { useState, useEffect, useRef } from 'react';
2
-import { Row, Col, Button, List, Popconfirm, Input } from 'antd';
1
+import React, { useState, useEffect, useRef, forwardRef, useImperativeHandle } from 'react';
2
+import { Modal, Button, List, Popconfirm, Input } from 'antd';
3 3
 import classNames from 'classnames';
4
+import BasicForm from './BasicForm';
4 5
 import { getPackageList, deletePackage } from '@/services/package';
6
+import useBool from '@/utils/hooks/useBool';
5 7
 
6
-export default (props) => {
8
+export default forwardRef((props, ref) => {
7 9
   const { current, setCurrent } = props;
8
-  const [loading, setLoading] = useState(false);
9
-  const [hasMore, setHasMore] = useState(true);
10
+  const [loading, startLoading, stopLoading] = useBool();
11
+  const [open, setVisible, hide] = useBool();
12
+  const [hasMore, setHasMore] = useState(false);
10 13
   const [filter, setFilter] = useState({ pageNum: 1, pageSize: 10, total: 0 });
11 14
   const [list, setList] = useState([]);
12 15
   const listRef = useRef();
@@ -40,10 +43,15 @@ export default (props) => {
40 43
     })
41 44
   }
42 45
 
46
+  const onEdit = (val = {}) => {
47
+    setCurrent(val);
48
+    setVisible();
49
+  }
50
+
43 51
   const onDelete = (item) => {
44
-    setLoading(true);
52
+    startLoading();
45 53
     deletePackage(item.id).then(res => {
46
-      setLoading(false);
54
+      stopLoading();
47 55
 
48 56
       const newList = listRef.current.filter(x => x.id !== item.id);
49 57
       setList(newList);
@@ -51,14 +59,19 @@ export default (props) => {
51 59
         setCurrent(newList[0] || {});
52 60
       }
53 61
     }).catch(() => {
54
-      setLoading(false);
62
+      stopLoading();
55 63
     });
56 64
   };
57 65
 
66
+  const handleForm = (val) => {
67
+    setCurrent(val);
68
+    hide()
69
+  }
70
+
58 71
   useEffect(() => {
59
-    setLoading(true);
72
+    startLoading();
60 73
     getPackageList(filter).then(res => {
61
-      setLoading(false);
74
+      stopLoading();
62 75
 
63 76
       const { records = [], current, total, pages } = res
64 77
 
@@ -71,7 +84,7 @@ export default (props) => {
71 84
 
72 85
       setHasMore(current < pages)
73 86
     }).catch(() => {
74
-      setLoading(false);
87
+      stopLoading();
75 88
     });
76 89
   }, [filter]);
77 90
 
@@ -95,16 +108,16 @@ export default (props) => {
95 108
     setList(newList);
96 109
   }, [current])
97 110
 
111
+  useImperativeHandle(ref, () => ({
112
+    new: () => onEdit(),
113
+  }));
114
+
98 115
   return (
116
+    <>
99 117
     <List
100 118
       style={{ minHeight: '600px' }}
101 119
       bordered
102
-      header={
103
-        <Input.Group compact>
104
-          <Input.Search allowClear placeholder="请输入筛选名称" onSearch={onSearch} style={{ width: 'calc(100% - 60px)' }} />
105
-          <Button type='link' onClick={() => setCurrent({})} >新增</Button>
106
-        </Input.Group>
107
-      }
120
+      header={<Input.Search allowClear placeholder="请输入筛选名称" onSearch={onSearch} />}
108 121
       dataSource={list}
109 122
       loading={loading}
110 123
       loadMore={loadMore}
@@ -113,6 +126,7 @@ export default (props) => {
113 126
           className={classNames({ active: current.id === item.id })}
114 127
           onClick={() => setCurrent(item)}
115 128
           actions={[
129
+            <Button key="edit" type='link' onClick={() => onEdit(item)}>编辑</Button>,
116 130
             <Popconfirm
117 131
               key="delete"
118 132
               title="确认删除?"
@@ -126,5 +140,9 @@ export default (props) => {
126 140
         </List.Item>
127 141
       )}
128 142
     />
143
+    <Modal open={open} title="套餐维护" footer={null} onCancel={hide} maskClosable={false} >
144
+      <BasicForm current={current} onChange={handleForm}></BasicForm>
145
+    </Modal>
146
+    </>
129 147
   )
130
-}
148
+})

+ 20
- 18
src/pages/package/index.jsx Näytä tiedosto

@@ -1,6 +1,6 @@
1
-import React, { useState } from 'react';
1
+import React from 'react';
2 2
 import { PageContainer } from '@ant-design/pro-components';
3
-import { Row, Col, Card } from 'antd';
3
+import { Button, Row, Col, Card } from 'antd';
4 4
 import List from './List';
5 5
 import BasicForm from './BasicForm';
6 6
 import DishList from './DishList';
@@ -8,23 +8,25 @@ import DishList from './DishList';
8 8
 import './style.less';
9 9
 
10 10
 export default (props) => {
11
-  const [current, setCurrent] = useState({});
11
+  const [current, setCurrent] = React.useState({});
12
+  const pkgRef = React.useRef();
13
+  const dishRef = React.useRef();
14
+
15
+  const onAdd = () => pkgRef.current.new();
16
+  const onDishAdd = () => dishRef.current.new();
12 17
 
13 18
   return (
14
-    <PageContainer>
15
-      <Card>
16
-        <Row gutter={100}>
17
-          <Col span={8}>
18
-            <List current={current} setCurrent={setCurrent}/>
19
-          </Col>
20
-          <Col span={8}>
21
-            <BasicForm current={current} onChange={it => setCurrent(it)} />
22
-            <div style={{ marginTop: '24px' }}>
23
-              <DishList current={current} />
24
-            </div>
25
-          </Col>
26
-        </Row>
27
-      </Card>
28
-    </PageContainer>
19
+    <Row gutter={24}>
20
+      <Col span={12}>
21
+        <Card title="套餐列表" extra={<Button type='primary' onClick={onAdd}>新增</Button>}>
22
+          <List ref={pkgRef} current={current} setCurrent={setCurrent}/>
23
+        </Card>
24
+      </Col>
25
+      <Col span={12}>
26
+        <Card title={`${current.name || '套餐'} 明细`} extra={<Button onClick={onDishAdd}>新增</Button>}>
27
+          <DishList current={current} ref={dishRef} />
28
+        </Card>
29
+      </Col>
30
+    </Row>
29 31
   )
30 32
 }

+ 14
- 5
src/pages/stockClassification/edit/index.jsx Näytä tiedosto

@@ -1,9 +1,11 @@
1 1
 import { addStoreType, getStoreTypeById, updataStoreType } from '@/services/stock';
2
-import { PageContainer, ProForm, ProFormSelect, ProFormText } from '@ant-design/pro-components';
2
+import { PageContainer, ProForm, ProFormSelect, ProFormText, ProFormTextArea } from '@ant-design/pro-components';
3 3
 import { useNavigate, useSearchParams } from 'react-router-dom';
4 4
 import { Card, Col, message, Row, Space } from 'antd';
5 5
 import { useEffect, useRef } from 'react';
6 6
 
7
+const width = 540;
8
+
7 9
 export default (props) => {
8 10
   const [searchParams, setSearchParams] = useSearchParams();
9 11
   const id = searchParams.get('id');
@@ -44,7 +46,7 @@ export default (props) => {
44 46
         <ProForm
45 47
           formRef={formRef}
46 48
           layout={'horizontal'}
47
-          labelCol={{ span: 8 }}
49
+          labelCol={{ span: 4 }}
48 50
           wrapperCol={{ span: 16 }}
49 51
           onFinish={onFinish}
50 52
           submitter={{
@@ -67,7 +69,7 @@ export default (props) => {
67 69
             name="name"
68 70
             label="分类名称"
69 71
             placeholder="请输入名称"
70
-            width={460}
72
+            width={width}
71 73
             allowClear={false}
72 74
             rules={[{ required: true, message: '请输入名称' }]}
73 75
           />
@@ -79,7 +81,7 @@ export default (props) => {
79 81
               { label: '否', value: 0 },
80 82
             ]}
81 83
             placeholder="请选择"
82
-            width={460}
84
+            width={width}
83 85
             allowClear={false}
84 86
             rules={[{ required: true, message: '请选择是否食材' }]}
85 87
           />
@@ -91,10 +93,17 @@ export default (props) => {
91 93
               { label: '否', value: 0 },
92 94
             ]}
93 95
             placeholder="请选择"
94
-            width={460}
96
+            width={width}
95 97
             allowClear={false}
96 98
             rules={[{ required: true, message: '请选择是否设备' }]}
97 99
           />
100
+          <ProFormTextArea
101
+            name="nutrition"
102
+            label="营养元素"
103
+            placeholder="请输入名称"
104
+            width={width}
105
+            allowClear={true}
106
+          />
98 107
         </ProForm>
99 108
       </Card>
100 109
     </PageContainer>