Przeglądaj źródła

Merge branch 'master' of http://git.ycjcjy.com/nanyang/machinery-admin

[baozhangchao] 3 lat temu
rodzic
commit
c061bdfcc6

+ 1
- 1
config/proxy.js Wyświetl plik

@@ -11,7 +11,7 @@ export default {
11 11
     // localhost:8000/api/** -> https://preview.pro.ant.design/api/**
12 12
     '/api/': {
13 13
       // 要代理的地址
14
-      target: 'https://preview.pro.ant.design',
14
+      target: 'http://192.168.89.147:7080',
15 15
       // 配置了这个可以从 http 代理到 https
16 16
       // 依赖 origin 的功能可能需要这个,比如 cookie
17 17
       changeOrigin: true,

+ 60
- 45
config/routes.js Wyświetl plik

@@ -62,7 +62,48 @@ export default [
62 62
       },
63 63
     ],
64 64
   },
65
-
65
+  {
66
+    path: '/ContentManagementSystem',
67
+    name: 'CMS管理',
68
+    icon: 'MediumOutlined',
69
+    component: '../layouts/BasicLayout',
70
+    routes: [
71
+      {
72
+        path: '/ContentManagementSystem/InformationClassification',
73
+        name: '资讯分类',
74
+        component: './ContentManagementSystem/InformationClassification',
75
+      },
76
+      {
77
+        path: '/ContentManagementSystem/InformationClassification/InformationClassificationEdit',
78
+        name: '资讯分类编辑',
79
+        component:
80
+          './ContentManagementSystem/InformationClassification/InformationClassificationEdit',
81
+        hideInMenu: true,
82
+      },
83
+      {
84
+        path: '/ContentManagementSystem/InformationList',
85
+        name: '资讯列表',
86
+        component: './ContentManagementSystem/InformationList',
87
+      },
88
+      {
89
+        path: '/ContentManagementSystem/InformationList/InformationListEdit',
90
+        name: '资讯列表编辑',
91
+        component: './ContentManagementSystem/InformationList/InformationListEdit',
92
+        hideInMenu: true,
93
+      },
94
+      {
95
+        path: '/ContentManagementSystem/BannerClassification',
96
+        name: 'Banner资讯',
97
+        component: './ContentManagementSystem/BannerClassification',
98
+      },
99
+      {
100
+        path: '/ContentManagementSystem/BannerClassification/BannerClassificationEdit',
101
+        name: 'Banner资讯编辑',
102
+        component: './ContentManagementSystem/BannerClassification/BannerClassificationEdit',
103
+        hideInMenu: true,
104
+      },
105
+    ],
106
+  },
66 107
   {
67 108
     path: '/Machinery',
68 109
     name: '农机管理',
@@ -78,7 +119,7 @@ export default [
78 119
         path: '/Machinery/Cooperative/edit.jsx',
79 120
         name: '合作社编辑',
80 121
         component: './Machinery/Cooperative/edit.jsx',
81
-        // hideInMenu: true,
122
+        hideInMenu: true,
82 123
       },
83 124
       {
84 125
         path: '/Machinery/Employees',
@@ -91,6 +132,22 @@ export default [
91 132
         component: './Machinery/Employees/edit.jsx',
92 133
         hideInMenu: true,
93 134
       },
135
+      {
136
+        path: '/Machinery/MachineryType',
137
+        name: '农机分类列表',
138
+        component: './Machinery/MachineryType',
139
+      },
140
+      {
141
+        path: '/Machinery/Machinery',
142
+        name: '农机列表',
143
+        component: './Machinery/Machinery',
144
+      },
145
+      {
146
+        path: '/Machinery/Machinery/edit.jsx',
147
+        name: '农机编辑',
148
+        component: './Machinery/Machinery/edit.jsx',
149
+        hideInMenu: true,
150
+      },
94 151
     ],
95 152
   },
96 153
   {
@@ -207,7 +264,7 @@ export default [
207 264
         path: '/GPSDevice/GPS/GPSEdit',
208 265
         name: '新增设备',
209 266
         component: './GPSDevice/GPS/GPSEdit',
210
-        hideInMenu: true
267
+        hideInMenu: true,
211 268
       },
212 269
     ],
213 270
   },
@@ -229,7 +286,6 @@ export default [
229 286
         icon: 'smile',
230 287
         component: './SystemManagement/Administrator/AdminEdit',
231 288
         hideInMenu: true,
232
-
233 289
       },
234 290
       {
235 291
         path: '/SystemManagement/UserRights',
@@ -255,48 +311,7 @@ export default [
255 311
       },
256 312
     ],
257 313
   },
258
-  {
259
-    path: '/ContentManagementSystem',
260
-    name: 'CMS管理',
261
-    icon: 'MediumOutlined',
262
-    component: '../layouts/BasicLayout',
263
-    routes: [
264
-      {
265
-        path: '/ContentManagementSystem/InformationClassification',
266
-        name: '资讯分类',
267
-        component: './ContentManagementSystem/InformationClassification',
268
-      },
269
-      {
270
-        path: '/ContentManagementSystem/InformationClassification/InformationClassificationEdit',
271
-        name: '资讯分类编辑',
272
-        component: './ContentManagementSystem/InformationClassification/InformationClassificationEdit',
273
-        hideInMenu: true
274
-      },
275
-      {
276
-        path: '/ContentManagementSystem/InformationList',
277
-        name: '资讯列表',
278
-        component: './ContentManagementSystem/InformationList',
279
-      },
280
-      {
281
-        path: '/ContentManagementSystem/InformationList/InformationListEdit',
282
-        name: '资讯列表编辑',
283
-        component: './ContentManagementSystem/InformationList/InformationListEdit',
284
-        hideInMenu: true
285 314
 
286
-      },
287
-      {
288
-        path: '/ContentManagementSystem/BannerClassification',
289
-        name: 'Banner资讯',
290
-        component: './ContentManagementSystem/BannerClassification',
291
-      }, {
292
-        path: '/ContentManagementSystem/BannerClassification/BannerClassificationEdit',
293
-        name: 'Banner资讯编辑',
294
-        component: './ContentManagementSystem/BannerClassification/BannerClassificationEdit',
295
-        hideInMenu: true
296
-
297
-      },
298
-    ],
299
-  },
300 315
   {
301 316
     path: '/',
302 317
     redirect: '/welcome',

+ 3
- 0
package.json Wyświetl plik

@@ -46,6 +46,7 @@
46 46
     "not ie <= 10"
47 47
   ],
48 48
   "dependencies": {
49
+    "@amap/amap-jsapi-loader": "^1.0.1",
49 50
     "@ant-design/icons": "^4.7.0",
50 51
     "@ant-design/pro-card": "^1.18.34",
51 52
     "@ant-design/pro-descriptions": "^1.10.0",
@@ -54,9 +55,11 @@
54 55
     "@ant-design/pro-list": "^1.21.32",
55 56
     "@ant-design/pro-table": "^2.61.0",
56 57
     "@umijs/route-utils": "^2.0.0",
58
+    "ali-oss": "^6.17.1",
57 59
     "antd": "^4.17.0",
58 60
     "classnames": "^2.3.0",
59 61
     "lodash": "^4.17.0",
62
+    "md5": "^2.3.0",
60 63
     "moment": "^2.29.1",
61 64
     "omit.js": "^2.0.2",
62 65
     "rc-menu": "^9.1.0",

+ 10
- 26
src/app.jsx Wyświetl plik

@@ -1,10 +1,9 @@
1
-import { SettingDrawer } from '@ant-design/pro-layout';
2 1
 import { PageLoading } from '@ant-design/pro-layout';
3 2
 import { history, Link } from 'umi';
4 3
 import RightContent from '@/components/RightContent';
5 4
 import Footer from '@/components/Footer';
6
-import { currentUser as queryCurrentUser } from './services/ant-design-pro/api';
7
-import defaultSettings from '../config/defaultSettings';
5
+import { currentUser as queryCurrentUser } from './services/user';
6
+import { requestConfig } from '@/utils/request';
8 7
 const isDev = process.env.NODE_ENV === 'development';
9 8
 const loginPath = '/user/login';
10 9
 /** 获取用户信息比较慢的时候会展示一个 loading */
@@ -19,8 +18,8 @@ export const initialStateConfig = {
19 18
 export async function getInitialState() {
20 19
   const fetchUserInfo = async () => {
21 20
     try {
22
-      const msg = await queryCurrentUser();
23
-      return msg.data;
21
+      const { user } = await queryCurrentUser();
22
+      return user;
24 23
     } catch (error) {
25 24
       history.push(loginPath);
26 25
     }
@@ -33,20 +32,21 @@ export async function getInitialState() {
33 32
     return {
34 33
       fetchUserInfo,
35 34
       currentUser,
36
-      settings: defaultSettings,
35
+      settings: {},
37 36
     };
38 37
   }
39 38
 
40 39
   return {
41 40
     fetchUserInfo,
42
-    settings: defaultSettings,
41
+    settings: {},
43 42
   };
44 43
 } // ProLayout 支持的api https://procomponents.ant.design/components/layout
45 44
 
46
-export const layout = ({ initialState, setInitialState }) => {
45
+export const layout = ({ initialState }) => {
47 46
   return {
48 47
     rightContentRender: () => <RightContent />,
49 48
     disableContentMargin: false,
49
+
50 50
     footerRender: () => <Footer />,
51 51
     onPageChange: () => {
52 52
       const { location } = history; // 如果没有登录,重定向到 login
@@ -58,24 +58,8 @@ export const layout = ({ initialState, setInitialState }) => {
58 58
     menuHeaderRender: undefined,
59 59
     // 自定义 403 页面
60 60
     // unAccessible: <div>unAccessible</div>,
61
-    // 增加一个 loading 的状态
62
-    childrenRender: (children, props) => {
63
-      // if (initialState?.loading) return <PageLoading />;
64
-      return (
65
-        <>
66
-          {children}
67
-          {!props.location?.pathname?.includes('/login') && (
68
-            <SettingDrawer
69
-              enableDarkTheme
70
-              settings={initialState?.settings}
71
-              onSettingChange={(settings) => {
72
-                setInitialState((preInitialState) => ({ ...preInitialState, settings }));
73
-              }}
74
-            />
75
-          )}
76
-        </>
77
-      );
78
-    },
79 61
     ...initialState?.settings,
80 62
   };
81 63
 };
64
+
65
+export const request = requestConfig;

+ 45
- 43
src/components/ExtendContent/List.jsx Wyświetl plik

@@ -1,64 +1,63 @@
1
-import { useEffect, useState, forwardRef, useImperativeHandle, useRef } from "react";
1
+import { useEffect, useState, forwardRef, useImperativeHandle, useRef } from 'react';
2 2
 import { Table, Space, Button, Popconfirm } from 'antd';
3 3
 import { getList, remove } from '@/services/extendContent';
4 4
 
5 5
 export default forwardRef((props, ref) => {
6 6
   const { targetType, targetId, onEdit } = props;
7 7
 
8
-  const [loading, setLoading] = useState(false)
9
-  const [list, setList] = useState([])
8
+  const [loading, setLoading] = useState(false);
9
+  const [list, setList] = useState([]);
10 10
   const refs = useRef();
11 11
 
12
-
13 12
   const tableList = () => {
14
-    setLoading(true)
13
+    setLoading(true);
15 14
     getList({
16 15
       pageSize: 9999,
17 16
       targetId,
18 17
       targetType,
19
-    }).then((res) => {
20
-      setList(res.records || [])
21
-      setLoading(false)
22
-    }).catch(() => setLoading(false))
23
-  }
24
-
25
-  refs.current = tableList
26
-
18
+    })
19
+      .then((res) => {
20
+        setList(res.records || []);
21
+        setLoading(false);
22
+      })
23
+      .catch(() => setLoading(false));
24
+  };
27 25
 
26
+  refs.current = tableList;
28 27
 
29 28
   // 父组件调用 updateList 来修改 list
30 29
   useImperativeHandle(ref, () => ({
31 30
     reload: refs.current,
32 31
     setLoading,
33
-  }))
32
+  }));
34 33
 
35 34
   const handleEdit = (record) => {
36
-    onEdit(record)
37
-
38
-  }
35
+    onEdit(record);
36
+  };
39 37
   //删除
40 38
   const handleDelete = (record) => {
41
-    setLoading(true)
42
-    remove(record.extId).then(() => {
43
-      setList(list.filter(x => x.extId !== record.extId))
44
-      setLoading(false)
45
-      // refs.current.reload();
46
-
47
-    }).catch(() => setLoading(false))
48
-  }
39
+    setLoading(true);
40
+    remove(record.extId)
41
+      .then(() => {
42
+        setList(list.filter((x) => x.extId !== record.extId));
43
+        setLoading(false);
44
+        // refs.current.reload();
45
+      })
46
+      .catch(() => setLoading(false));
47
+  };
49 48
 
50 49
   const columns = [
51 50
     {
52 51
       title: '序号',
53 52
       key: 'index',
54 53
       dataIndex: 'index',
55
-      render: (t, record, index) => `${index + 1}`
54
+      render: (t, record, index) => `${index + 1}`,
56 55
     },
57 56
     {
58 57
       title: '权重',
59 58
       key: 'sort',
60 59
       dataIndex: 'sort',
61
-      render: (t, record) => `${record.sort}`
60
+      render: (t, record) => `${record.sort}`,
62 61
     },
63 62
     {
64 63
       title: '内容',
@@ -68,12 +67,9 @@ export default forwardRef((props, ref) => {
68 67
       render: (t, record) => {
69 68
         if (record.contentType === 'text') return t;
70 69
         if (record.contentType === 'image') {
71
-          return <img style={{ width: '110px' }} src={t} alt="" />
72
-        }
73
-        if (record.contentType === 'video') {
74
-          return <video style={{ width: '110px' }} src={t} />
70
+          return <img style={{ width: '110px' }} src={t} alt="" />;
75 71
         }
76
-      }
72
+      },
77 73
     },
78 74
     {
79 75
       title: '操作',
@@ -81,25 +77,31 @@ export default forwardRef((props, ref) => {
81 77
       render: (_, record) => {
82 78
         return (
83 79
           <Space>
84
-            <Button type="link" onClick={() => handleEdit(record)}>编辑</Button>
80
+            <Button type="link" onClick={() => handleEdit(record)}>
81
+              编辑
82
+            </Button>
85 83
             {/* <Button type="link" onClick={() => handleEdit(record)}>插入</Button> */}
86 84
             <Popconfirm title="确定进行当前操作 ?" onConfirm={() => handleDelete(record)}>
87 85
               <Button type="link">删除</Button>
88 86
             </Popconfirm>
89 87
           </Space>
90
-        )
91
-      }
88
+        );
89
+      },
92 90
     },
93
-  ]
94
-
91
+  ];
95 92
 
96 93
   useEffect(() => {
97 94
     if (targetType) {
98
-      refs.current()
95
+      refs.current();
99 96
     }
100
-  }, [targetType])
97
+  }, [targetType]);
101 98
   return (
102
-
103
-    <Table loading={loading} rowKey="extId" columns={columns} dataSource={list} pagination={false} />
104
-  )
105
-})
99
+    <Table
100
+      loading={loading}
101
+      rowKey="extId"
102
+      columns={columns}
103
+      dataSource={list}
104
+      pagination={false}
105
+    />
106
+  );
107
+});

+ 52
- 37
src/components/ExtendContent/ModalButton.jsx Wyświetl plik

@@ -1,53 +1,68 @@
1
-import { useEffect, useImperativeHandle, useState, forwardRef } from "react"
2
-import { Button } from 'antd'
3
-import ModalText from './ModalText'
4
-import ModalImage from './Modalimage'
5
-import ModalVideo from './ModalVideo'
6
-import { parseGeoJson } from "echarts"
1
+import { useEffect, useImperativeHandle, useState, forwardRef } from 'react';
2
+import { Button } from 'antd';
3
+import ModalText from './ModalText';
4
+import ModalImage from './Modalimage';
7 5
 
8 6
 export default forwardRef((props, ref) => {
9
-  const { contentType, record, onChange, onClose, ...btnProps } = props
10
-
11
-  const [visible, setVisible] = useState(false)
12
-  const [content, setContent] = useState()
13
-  const [sortVale, setSortVale] = useState()
7
+  const { contentType, record, onChange, onClose, ...btnProps } = props;
14 8
 
9
+  const [visible, setVisible] = useState(false);
10
+  const [content, setContent] = useState();
11
+  const [sortVale, setSortVale] = useState();
15 12
 
16 13
   const handleClose = () => {
17
-    setContent()
18
-    setSortVale()
19
-    setVisible(false)
20
-    onClose()
21
-  }
14
+    setContent();
15
+    setSortVale();
16
+    setVisible(false);
17
+    onClose();
18
+  };
22 19
 
23 20
   const handleChange = (val, e) => {
24
-    onChange({
25
-      ...record || {},
26
-      content: val,
27
-      sort: e - 0,
28
-      contentType,
29
-    }, handleClose)
30
-  }
21
+    onChange(
22
+      {
23
+        ...(record || {}),
24
+        content: val,
25
+        sort: e - 0,
26
+        contentType,
27
+      },
28
+      handleClose,
29
+    );
30
+  };
31 31
 
32 32
   useImperativeHandle(ref, () => ({
33 33
     toggle: () => {
34
-      setVisible(!visible)
35
-    }
36
-  }))
34
+      setVisible(!visible);
35
+    },
36
+  }));
37 37
 
38 38
   useEffect(() => {
39
-    setContent(record?.content)
40
-    setSortVale(record?.sort)
41
-  }, [record, visible])
42
-
43
-
39
+    setContent(record?.content);
40
+    setSortVale(record?.sort);
41
+  }, [record, visible]);
44 42
 
45 43
   return (
46 44
     <>
47
-      <Button onClick={() => setVisible(true)} {...btnProps}>{props.children}</Button>
48
-      {contentType === 'text' && <ModalText sortVale={sortVale} visible={visible} value={content} onChange={handleChange} onCancel={handleClose} />}
49
-      {contentType === 'image' && <ModalImage sortVale={sortVale} visible={visible} value={content} onChange={handleChange} onCancel={handleClose} />}
50
-      {contentType === 'video' && <ModalVideo sortVale={sortVale} visible={visible} value={content} onChange={handleChange} onCancel={handleClose} />}
45
+      <Button onClick={() => setVisible(true)} {...btnProps}>
46
+        {props.children}
47
+      </Button>
48
+      {contentType === 'text' && (
49
+        <ModalText
50
+          sortVale={sortVale}
51
+          visible={visible}
52
+          value={content}
53
+          onChange={handleChange}
54
+          onCancel={handleClose}
55
+        />
56
+      )}
57
+      {contentType === 'image' && (
58
+        <ModalImage
59
+          sortVale={sortVale}
60
+          visible={visible}
61
+          value={content}
62
+          onChange={handleChange}
63
+          onCancel={handleClose}
64
+        />
65
+      )}
51 66
     </>
52
-  )
53
-})
67
+  );
68
+});

+ 0
- 43
src/components/ExtendContent/ModalVideo.jsx Wyświetl plik

@@ -1,43 +0,0 @@
1
-
2
-import { useEffect, useState } from 'react'
3
-import { UploadVideo } from '@/components/Upload'
4
-import { Input, Modal, Form, Button } from 'antd'
5
-
6
-
7
-const FormItem = Form.Item
8
-export default (props) => {
9
-  const { value, visible, onChange, onCancel, sortVale } = props
10
-
11
-  const [video, setVideo] = useState()
12
-  const [sort, setSort] = useState()
13
-
14
-  const Submit = (e) => {
15
-    setSort(e.target.value)
16
-  }
17
-  const handleOk = () => {
18
-    onChange(video, sort)
19
-  }
20
-  useEffect(() => {
21
-    setVideo(value)
22
-    setSort(sortVale)
23
-
24
-  }, [value, visible, sortVale])
25
-  const setld=()=>{
26
-
27
-  }
28
-  return (
29
-    <Modal title="请上传视频" visible={visible} onOk={handleOk} onCancel={onCancel} destroyOnClose={true}>
30
-
31
-      <Form onFinish={Submit} >
32
-        <FormItem label="内容" rules={[{ required: true, message: '请输入内容' }]} >
33
-          <UploadVideo value={video} onChange={setVideo}  poster='' setPoster={setld} setld={setld}/>
34
-
35
-        </FormItem>
36
-        <FormItem label="权重" rules={[{ required: true, message: '请设置权重' }]}>
37
-          <Input min={0} placeholder="请输入权重" type='number' value={sort} onChange={Submit} style={{ width: '350px' }} />
38
-        </FormItem>
39
-      </Form>
40
-    </Modal>
41
-
42
-  )
43
-}

+ 54
- 41
src/components/ExtendContent/index.jsx Wyświetl plik

@@ -1,58 +1,51 @@
1 1
 import { Button, message, Space } from 'antd';
2 2
 import { PlusOutlined } from '@ant-design/icons';
3
-import { useRef, useState, } from 'react';
3
+import { useRef, useState } from 'react';
4 4
 import ModalButton from './ModalButton';
5
-import List from './List'
6
-import { save, update } from '@/services/extendContent'
7
-
8
-
5
+import List from './List';
6
+import { save, update } from '@/services/extendContent';
9 7
 
10 8
 export default (props) => {
11
-  const { onCancel, targetId, targetType } = props
12
-
13
-  const [record, setRecord] = useState()
14
-  const listRef = useRef()
15
-  const textBtnRef = useRef()
16
-  const imageBtnRef = useRef()
17
-  const videoBtnRef = useRef()
18
-
9
+  const { onCancel, targetId, targetType } = props;
19 10
 
11
+  const [record, setRecord] = useState();
12
+  const listRef = useRef();
13
+  const textBtnRef = useRef();
14
+  const imageBtnRef = useRef();
15
+  const videoBtnRef = useRef();
20 16
 
21 17
   const handleChange = (row, next) => {
22 18
     const data = {
23 19
       ...(row || {}),
24 20
       targetId,
25 21
       targetType,
26
-    }
22
+    };
27 23
 
28 24
     if (data.extId) {
29 25
       // 编辑提交
30 26
 
31
-      update(data.extId, data,).then(() => {
32
-        listRef.current.reload()
33
-        next()
34
-
35
-        message.success('更新数据成功')
36
-
37
-      })
27
+      update(data.extId, data).then(() => {
28
+        listRef.current.reload();
29
+        next();
38 30
 
31
+        message.success('更新数据成功');
32
+      });
39 33
     } else if (data.content) {
40 34
       // 新增提交
41
-      listRef.current.setLoading(true)
35
+      listRef.current.setLoading(true);
42 36
       save(data).then((res) => {
43
-        listRef.current.reload()
44
-        next()
37
+        listRef.current.reload();
38
+        next();
45 39
 
46
-        message.success('保存数据成功')
47
-      })
40
+        message.success('保存数据成功');
41
+      });
42
+    } else {
43
+      next();
48 44
     }
49
-    else {
50
-      next()
51
-    }
52
-  }
45
+  };
53 46
 
54 47
   const handleEdit = (row) => {
55
-    setRecord(row)
48
+    setRecord(row);
56 49
     switch (row.contentType) {
57 50
       case 'text':
58 51
         textBtnRef.current.toggle();
@@ -66,22 +59,42 @@ export default (props) => {
66 59
       default:
67 60
         break;
68 61
     }
69
-  }
70
-
62
+  };
71 63
 
72 64
   const handleClose = () => {
73
-    setRecord()
74
-  }
65
+    setRecord();
66
+  };
75 67
 
76 68
   return (
77 69
     <div>
78 70
       <Space size="large" style={{ marginBottom: '18px' }}>
79
-        <ModalButton ref={textBtnRef} type="dashed" icon={<PlusOutlined />} record={record} contentType="text" onChange={handleChange} onClose={handleClose}>文字</ModalButton>
80
-        <ModalButton ref={imageBtnRef} type="dashed" icon={<PlusOutlined />} record={record} contentType="image" onChange={handleChange} onClose={handleClose}>图片</ModalButton>
81
-        <ModalButton ref={videoBtnRef} type="dashed" icon={<PlusOutlined />} record={record} contentType="video" onChange={handleChange} onClose={handleClose}>视频</ModalButton>
71
+        <ModalButton
72
+          ref={textBtnRef}
73
+          type="dashed"
74
+          icon={<PlusOutlined />}
75
+          record={record}
76
+          contentType="text"
77
+          onChange={handleChange}
78
+          onClose={handleClose}
79
+        >
80
+          文字
81
+        </ModalButton>
82
+        <ModalButton
83
+          ref={imageBtnRef}
84
+          type="dashed"
85
+          icon={<PlusOutlined />}
86
+          record={record}
87
+          contentType="image"
88
+          onChange={handleChange}
89
+          onClose={handleClose}
90
+        >
91
+          图片
92
+        </ModalButton>
82 93
       </Space>
83 94
       <List ref={listRef} targetType={targetType} onEdit={handleEdit} targetId={targetId} />
84
-      <Button onClick={onCancel} style={{ marginTop: '2em', float: 'right' }}>返回</Button>
95
+      {/* <Button onClick={onCancel} style={{ marginTop: '2em', float: 'right' }}>
96
+        返回
97
+      </Button> */}
85 98
     </div>
86
-  )
87
-}
99
+  );
100
+};

+ 42
- 29
src/components/RightContent/AvatarDropdown.jsx Wyświetl plik

@@ -1,32 +1,34 @@
1
-import React, { useCallback } from 'react';
2
-import { LogoutOutlined, SettingOutlined, UserOutlined } from '@ant-design/icons';
3
-import { Avatar, Menu, Spin } from 'antd';
1
+import React, { useState, useCallback } from 'react';
2
+import { LogoutOutlined, KeyOutlined } from '@ant-design/icons';
3
+import { Avatar, Menu, message, Spin } from 'antd';
4 4
 import { history, useModel } from 'umi';
5 5
 import { stringify } from 'querystring';
6 6
 import HeaderDropdown from '../HeaderDropdown';
7
+import ChangePassword from './ChangePassword';
7 8
 import styles from './index.less';
8
-import { outLogin } from '@/services/ant-design-pro/api';
9 9
 
10 10
 /**
11 11
  * 退出登录,并且将当前的 url 保存
12 12
  */
13 13
 const loginOut = async () => {
14
-  await outLogin();
15
-  const { query = {}, search, pathname } = history.location;
14
+  localStorage.removeItem('token');
15
+  const { query = {}, pathname } = history.location;
16 16
   const { redirect } = query; // Note: There may be security issues, please note
17 17
 
18 18
   if (window.location.pathname !== '/user/login' && !redirect) {
19 19
     history.replace({
20 20
       pathname: '/user/login',
21 21
       search: stringify({
22
-        redirect: pathname + search,
22
+        redirect: pathname,
23 23
       }),
24 24
     });
25 25
   }
26 26
 };
27 27
 
28 28
 const AvatarDropdown = ({ menu }) => {
29
+  const [showPasswordModal, setShowPasswordModal] = useState(false);
29 30
   const { initialState, setInitialState } = useModel('@@initialState');
31
+
30 32
   const onMenuClick = useCallback(
31 33
     (event) => {
32 34
       const { key } = event;
@@ -37,10 +39,22 @@ const AvatarDropdown = ({ menu }) => {
37 39
         return;
38 40
       }
39 41
 
40
-      history.push(`/account/${key}`);
42
+      if (key === 'changepassword') {
43
+        setShowPasswordModal(true);
44
+        return;
45
+      }
41 46
     },
42 47
     [setInitialState],
43 48
   );
49
+
50
+  const handleChangeSuccessful = () => {
51
+    message.success('密码修改成功');
52
+    setShowPasswordModal(false);
53
+    setInitialState((s) => ({ ...s, currentUser: undefined }));
54
+    loginOut();
55
+    return;
56
+  };
57
+
44 58
   const loading = (
45 59
     <span className={`${styles.action} ${styles.account}`}>
46 60
       <Spin
@@ -59,39 +73,38 @@ const AvatarDropdown = ({ menu }) => {
59 73
 
60 74
   const { currentUser } = initialState;
61 75
 
62
-  if (!currentUser || !currentUser.name) {
76
+  if (!currentUser || !currentUser.userName) {
63 77
     return loading;
64 78
   }
65 79
 
66 80
   const menuHeaderDropdown = (
67 81
     <Menu className={styles.menu} selectedKeys={[]} onClick={onMenuClick}>
68
-      {menu && (
69
-        <Menu.Item key="center">
70
-          <UserOutlined />
71
-          个人中心
72
-        </Menu.Item>
73
-      )}
74
-      {menu && (
75
-        <Menu.Item key="settings">
76
-          <SettingOutlined />
77
-          个人设置
78
-        </Menu.Item>
79
-      )}
80
-      {menu && <Menu.Divider />}
81
-
82
+      <Menu.Item key="changepassword">
83
+        <KeyOutlined />
84
+        修改密码
85
+      </Menu.Item>
86
+      <Menu.Divider />
82 87
       <Menu.Item key="logout">
83 88
         <LogoutOutlined />
84 89
         退出登录
85 90
       </Menu.Item>
86 91
     </Menu>
87 92
   );
93
+
88 94
   return (
89
-    <HeaderDropdown overlay={menuHeaderDropdown}>
90
-      <span className={`${styles.action} ${styles.account}`}>
91
-        <Avatar size="small" className={styles.avatar} src={currentUser.avatar} alt="avatar" />
92
-        <span className={`${styles.name} anticon`}>{currentUser.name}</span>
93
-      </span>
94
-    </HeaderDropdown>
95
+    <>
96
+      <HeaderDropdown overlay={menuHeaderDropdown}>
97
+        <span className={`${styles.action} ${styles.account}`}>
98
+          {/* <Avatar size="small" className={styles.avatar} src={currentUser.avatar} alt="avatar" /> */}
99
+          <span className={`${styles.name} anticon`}>{currentUser.userName}</span>
100
+        </span>
101
+      </HeaderDropdown>
102
+      <ChangePassword
103
+        visible={showPasswordModal}
104
+        onCancel={() => setShowPasswordModal(false)}
105
+        onSuccess={handleChangeSuccessful}
106
+      />
107
+    </>
95 108
   );
96 109
 };
97 110
 

+ 87
- 0
src/components/RightContent/ChangePassword.jsx Wyświetl plik

@@ -0,0 +1,87 @@
1
+import React, { useState } from 'react';
2
+import { Form, Input, Button, Modal } from 'antd';
3
+import md5 from 'md5';
4
+import { changePassword } from '@/services/user'
5
+
6
+const layout = {
7
+  labelCol: { span: 6 },
8
+  wrapperCol: { span: 14 },
9
+};
10
+const tailLayout = {
11
+  wrapperCol: { offset: 6, span: 14 },
12
+};
13
+
14
+export default (props) => {
15
+  const { visible, onSuccess, onCancel } = props
16
+
17
+  const [loading, setLoading] = useState(false)
18
+
19
+  const handleFinish = (values) => {
20
+    const data = {
21
+      originPassword: md5(values.originPassword),
22
+      newPassword: md5(values.newPassword)
23
+    }
24
+
25
+    setLoading(true)
26
+    changePassword(data).then(() => {
27
+      setLoading(false)
28
+      if (onSuccess) {
29
+        onSuccess()
30
+      }
31
+    }).catch((err) => {
32
+      setLoading(false)
33
+    })
34
+  }
35
+
36
+  const handleCancel = () => {
37
+    if (onCancel) {
38
+      onCancel()
39
+    }
40
+  }
41
+
42
+  return (
43
+    <Modal visible={visible} title="修改密码" footer={null} onCancel={handleCancel}>
44
+      <Form {...layout} onFinish={handleFinish}>
45
+        <Form.Item
46
+          name="originPassword"
47
+          label="原密码"
48
+          rules={[{ required: true, message: '请填写原密码!' }]}
49
+        >
50
+          <Input.Password placeholder="请填写原密码" />
51
+        </Form.Item>
52
+        <Form.Item
53
+          name="newPassword"
54
+          label="新密码"
55
+          rules={[{ required: true, message: '请填写新密码!' }]}
56
+        >
57
+          <Input.Password placeholder="请填写新密码" />
58
+        </Form.Item>
59
+        <Form.Item
60
+          name="newPassword2"
61
+          label="确认密码"
62
+          rules={[
63
+            { required: true, message: '请填写新密码!' },
64
+            ({ getFieldValue }) => ({
65
+              validator(_, value) {
66
+                if (!value || getFieldValue('newPassword') === value) {
67
+                  return Promise.resolve();
68
+                }
69
+                return Promise.reject(new Error('两次输入密码不一致!'));
70
+              },
71
+            })
72
+          ]}
73
+        >
74
+          <Input.Password placeholder="确认密码需要与新密码保持一致" />
75
+        </Form.Item>
76
+        <Form.Item {...tailLayout}>
77
+          <Button loading={loading} type="primary" htmlType="submit">
78
+            提交
79
+          </Button>
80
+          <Button htmlType="button" onClick={handleCancel} style={{ marginLeft: '4em' }}>
81
+            取消
82
+          </Button>
83
+        </Form.Item>
84
+      </Form>
85
+    </Modal>
86
+  )
87
+}

+ 1
- 37
src/components/RightContent/index.jsx Wyświetl plik

@@ -1,9 +1,7 @@
1 1
 import { Space } from 'antd';
2
-import { QuestionCircleOutlined } from '@ant-design/icons';
3 2
 import React from 'react';
4
-import { useModel, SelectLang } from 'umi';
3
+import { useModel } from 'umi';
5 4
 import Avatar from './AvatarDropdown';
6
-import HeaderSearch from '../HeaderSearch';
7 5
 import styles from './index.less';
8 6
 
9 7
 const GlobalHeaderRight = () => {
@@ -22,41 +20,7 @@ const GlobalHeaderRight = () => {
22 20
 
23 21
   return (
24 22
     <Space className={className}>
25
-      <HeaderSearch
26
-        className={`${styles.action} ${styles.search}`}
27
-        placeholder="站内搜索"
28
-        defaultValue="umi ui"
29
-        options={[
30
-          {
31
-            label: <a href="https://umijs.org/zh/guide/umi-ui.html">umi ui</a>,
32
-            value: 'umi ui',
33
-          },
34
-          {
35
-            label: <a href="next.ant.design">Ant Design</a>,
36
-            value: 'Ant Design',
37
-          },
38
-          {
39
-            label: <a href="https://protable.ant.design/">Pro Table</a>,
40
-            value: 'Pro Table',
41
-          },
42
-          {
43
-            label: <a href="https://prolayout.ant.design/">Pro Layout</a>,
44
-            value: 'Pro Layout',
45
-          },
46
-        ]} // onSearch={value => {
47
-        //   console.log('input', value);
48
-        // }}
49
-      />
50
-      <span
51
-        className={styles.action}
52
-        onClick={() => {
53
-          window.open('https://pro.ant.design/docs/getting-started');
54
-        }}
55
-      >
56
-        <QuestionCircleOutlined />
57
-      </span>
58 23
       <Avatar />
59
-      <SelectLang className={styles.action} />
60 24
     </Space>
61 25
   );
62 26
 };

+ 2
- 2
src/components/RightContent/index.less Wyświetl plik

@@ -1,4 +1,4 @@
1
-@import (reference) '~antd/es/style/themes/index';
1
+@import '~antd/es/style/themes/default.less';
2 2
 
3 3
 @pro-header-hover-bg: rgba(0, 0, 0, 0.025);
4 4
 
@@ -18,7 +18,7 @@
18 18
   margin-left: auto;
19 19
   overflow: hidden;
20 20
   .action {
21
-    display: flex;
21
+    display: ;
22 22
     align-items: center;
23 23
     height: 48px;
24 24
     padding: 0 12px;

+ 0
- 95
src/components/Upload/UploadVideo.jsx Wyświetl plik

@@ -1,95 +0,0 @@
1
-import React, { useState, useRef } from 'react';
2
-import { Button } from 'antd'
3
-import Upload from './Upload';
4
-import { uplodeNoteImage } from '@/services/note'
5
-import styles from './style.less';
6
-import { useEffect } from 'react';
7
-
8
-function beforeUpload(file) {
9
-  const isMp4 = file.type === 'video/mp4';
10
-  if (!isMp4) {
11
-    message.error('请上传 MP4 视频!');
12
-  }
13
-
14
-  return isMp4;
15
-}
16
-
17
-export default (props) => {
18
-  //onPoster 改变主图事件   isScreenshot判断父组件是否需要截屏按钮
19
-  const { value, onChange, onPoster, isScreenshot } = props;
20
-  const [loading, setLoading] = useState(false);//上传按钮loading框
21
-  const [capturing, setCapturing] = useState(false);//截屏按钮loading框
22
-  const [video, setVideo] = useState()//当前上传的视频
23
-  const [isVideoReady, setIsVideoReady] = useState(false)//判断视频是否加载成功
24
-  
25
-  const canvasRef = useRef()
26
-  const videoRef = useRef()
27
-
28
-  useEffect(() => {
29
-    setVideo(value)//父组件的视频获取成功时改变当前页面的视频
30
-  }, [value])
31
-
32
-  const handleChange = info => {
33
-    if (info.file.status === 'uploading') {
34
-      setLoading(true);
35
-      return;
36
-    }
37
-    if (info.file.status === 'error') {
38
-      setLoading(false);
39
-      return;
40
-    }
41
-    if (info.file.status === 'done') {
42
-      onChange(info.file.response);
43
-      setLoading(false);
44
-    }
45
-  };
46
-
47
-  //开始截图
48
-  const handelScreenshot = () => {
49
-    const ctx = canvasRef.current.getContext("2d");  
50
-    ctx.drawImage(videoRef.current, 0, 0);    
51
-    const image = canvasRef.current.toDataURL("image/png", 0.9)
52
-    setCapturing(true)
53
-    uplodeNoteImage({ base64: image }).then((res) => {
54
-      onPoster(res)
55
-      setCapturing(false)
56
-    })
57
-  }
58
-
59
-  //视频加载成功事件
60
-  const handleVideoReady = (e) => {
61
-    setIsVideoReady(true)
62
-    canvasRef.current.width = e.target.videoWidth;
63
-    canvasRef.current.height = e.target.videoHeight;
64
-  }
65
-
66
-  return (
67
-    <div className={styles['video-uploader']}>
68
-      <Upload
69
-        className="image-uploader"
70
-        showUploadList={false}
71
-        beforeUpload={beforeUpload}
72
-        onChange={handleChange}
73
-      >
74
-        <div style={{ maxWidth: '1px', maxHeight: '1px', overflow: 'hidden' }}>
75
-          <canvas ref={canvasRef}></canvas>
76
-        </div>
77
-        <Button loading={loading}>
78
-          点击上传视频 (MP4)
79
-        </Button>
80
-
81
-      </Upload>
82
-      {
83
-        isScreenshot && (
84
-          // disabled={!isVideoReady} 当视频准备成功时截屏按钮可以点击  否则不能点击
85
-          <Button loading={capturing} style={{ marginLeft: '1em' }} onClick={handelScreenshot} disabled={!isVideoReady}>截屏</Button>
86
-        )
87
-      }
88
-      {
89
-        !!video && (
90
-          <video ref={videoRef} width="320" height='500' crossOrigin='anonymous' controls src={video} onCanPlay={handleVideoReady}></video>
91
-        )
92
-      }
93
-    </div>
94
-  );
95
-}

+ 1
- 7
src/components/Upload/index.jsx Wyświetl plik

@@ -1,11 +1,5 @@
1 1
 import Upload from './Upload';
2 2
 import UploadImage from './UploadImage';
3 3
 import UploadImageList from './UploadImageList';
4
-import UploadVideo from './UploadVideo';
5 4
 
6
-export {
7
-  Upload,
8
-  UploadImage,
9
-  UploadImageList,
10
-  UploadVideo,
11
-}
5
+export { Upload, UploadImage, UploadImageList };

+ 21
- 7
src/pages/Machinery/Cooperative/edit.jsx Wyświetl plik

@@ -2,6 +2,8 @@ import { Form, Input, Card, InputNumber, Select, message, Button } from 'antd';
2 2
 import { history } from 'umi';
3 3
 import ProCard from '@ant-design/pro-card';
4 4
 import { useState, useEffect } from 'react';
5
+import POI from '@/components/POI/POI';
6
+
5 7
 // import { getTagList } from '@/services/tag';
6 8
 // import { addAttaList, gettaTouristForm, EditaddAttaList } from '@/services/AttaList'
7 9
 
@@ -20,13 +22,17 @@ export default (props) => {
20 22
   const [listForm, setListForm] = useState({});
21 23
   const [loading, setLoading] = useState(false);
22 24
   const [imageList, setImageList] = useState([]);
23
-
25
+  //地址--占位
26
+  const [newLocName, setLocName] = useState('');
27
+  const [newAddress, setAddress] = useState('');
24 28
   const Submit = (data) => {
25 29
     const typeList = (data.typeList || []).map((x) => {
26 30
       return { ...x, targetId: id, targetType: 'tourist' };
27 31
     });
28
-    setLoading(true);
29
-
32
+    // setLoading(true);
33
+    console.log(data);
34
+    console.log(newLocName);
35
+    console.log(newAddress);
30 36
     // if (id) {
31 37
     //   EditaddAttaList(id, { ...listForm, ...data, imageList, typeList }).then(() => {
32 38
     //     setLoading(false);
@@ -50,10 +56,6 @@ export default (props) => {
50 56
     // }
51 57
   };
52 58
 
53
-  //地址--占位
54
-  const [newLocName, setLocName] = useState('');
55
-  const [newAddress, setAddress] = useState('');
56
-
57 59
   const selectTagList = (params) => {
58 60
     // return getTagList({
59 61
     // }).then((res) => {
@@ -126,6 +128,18 @@ export default (props) => {
126 128
             >
127 129
               <Input placeholder="请输入联系方式" rows={4} style={{ width: '350px' }} />
128 130
             </FormItem>
131
+            <FormItem
132
+              label="定位经纬"
133
+              name="locaton"
134
+              rules={[{ required: true, message: '请定位' }]}
135
+            >
136
+              <POI
137
+                placeholder="定位"
138
+                setLocName={setLocName}
139
+                setAddress={setAddress}
140
+                roomBoole={true}
141
+              />
142
+            </FormItem>
129 143
             <FormItem
130 144
               label="地址"
131 145
               name="address"

+ 2
- 2
src/pages/Machinery/Cooperative/index.jsx Wyświetl plik

@@ -13,11 +13,11 @@ const formatterTime = (val) => {
13 13
 
14 14
 export default (props) => {
15 15
   const actions = () => [
16
-    <Button key="add" type="primary" icon={<PlusOutlined />} onClick={() => gotoDetail()}>
16
+    <Button key="add" type="primary" icon={<PlusOutlined />} onClick={() => gotoEdit()}>
17 17
       新增合作社
18 18
     </Button>,
19 19
   ];
20
-  const gotoDetail = (id) => {
20
+  const gotoEdit = (id) => {
21 21
     const queryStr = id ? `?id=${id}` : '';
22 22
     history.push(`./Cooperative/edit.jsx${queryStr}`);
23 23
   };

+ 5
- 1
src/pages/Machinery/Employees/edit.jsx Wyświetl plik

@@ -118,7 +118,11 @@ export default (props) => {
118 118
                 </Option>
119 119
               </Select>
120 120
             </FormItem>
121
-            <FormItem label="角色" name="role" rules={[{ required: true, message: '请选择角色' }]}>
121
+            <FormItem
122
+              label="身份"
123
+              name="identity"
124
+              rules={[{ required: true, message: '请选择身份' }]}
125
+            >
122 126
               <Select style={{ width: '350px' }}>
123 127
                 <Option value="6" key="6">
124 128
                   农机手

+ 19
- 3
src/pages/Machinery/Employees/index.jsx Wyświetl plik

@@ -1,6 +1,7 @@
1 1
 import React from 'react';
2 2
 import { history, Link } from 'umi';
3 3
 import { Button, Popconfirm, message, Tooltip } from 'antd';
4
+import { PlusOutlined } from '@ant-design/icons';
4 5
 // import { getPersonList, exportPersonList } from '@/services/person';
5 6
 import { PageHeaderWrapper } from '@ant-design/pro-layout';
6 7
 import moment from 'moment';
@@ -11,6 +12,15 @@ const formatterTime = (val) => {
11 12
 };
12 13
 
13 14
 export default (props) => {
15
+  const actions = () => [
16
+    <Button key="add" type="primary" icon={<PlusOutlined />} onClick={() => gotoEdit()}>
17
+      新增员工
18
+    </Button>,
19
+  ];
20
+  const gotoEdit = (id) => {
21
+    const queryStr = id ? `?id=${id}` : '';
22
+    history.push(`./Employees/edit.jsx${queryStr}`);
23
+  };
14 24
   const columns = [
15 25
     {
16 26
       title: '姓名',
@@ -28,9 +38,14 @@ export default (props) => {
28 38
       key: 'title',
29 39
     },
30 40
     {
31
-      title: '角色',
32
-      dataIndex: 'role',
33
-      key: 'role',
41
+      title: '身份',
42
+      dataIndex: 'identity',
43
+      key: 'identity',
44
+    },
45
+    {
46
+      title: '工作状态',
47
+      dataIndex: 'status',
48
+      key: 'status',
34 49
     },
35 50
     {
36 51
       title: '注册时间',
@@ -62,6 +77,7 @@ export default (props) => {
62 77
       <PageTable
63 78
         // request={getPersonList}
64 79
         // expfunc={exportPersonList}
80
+        toolBarRender={actions}
65 81
         columns={columns}
66 82
         rowKey="employeesId"
67 83
         options={false}

+ 167
- 0
src/pages/Machinery/Machinery/edit.jsx Wyświetl plik

@@ -0,0 +1,167 @@
1
+import { Form, Input, Card, InputNumber, Select, message, Button } from 'antd';
2
+import { history } from 'umi';
3
+import ProCard from '@ant-design/pro-card';
4
+import { useState, useEffect } from 'react';
5
+// import { getTagList } from '@/services/tag';
6
+// import { addAttaList, gettaTouristForm, EditaddAttaList } from '@/services/AttaList'
7
+
8
+const { TextArea } = Input;
9
+const { Option } = Select;
10
+const formItemLayout = { labelCol: { span: 6 }, wrapperCol: { span: 14 } };
11
+
12
+const goBack = () => {
13
+  history.goBack();
14
+};
15
+const FormItem = Form.Item;
16
+export default (props) => {
17
+  const { location } = props;
18
+  const { id } = location.query;
19
+  const [form] = Form.useForm();
20
+  const [listForm, setListForm] = useState({});
21
+  const [loading, setLoading] = useState(false);
22
+  const [imageList, setImageList] = useState([]);
23
+
24
+  const Submit = (data) => {
25
+    const typeList = (data.typeList || []).map((x) => {
26
+      return { ...x, targetId: id, targetType: 'tourist' };
27
+    });
28
+    setLoading(true);
29
+
30
+    // if (id) {
31
+    //   EditaddAttaList(id, { ...listForm, ...data, imageList, typeList }).then(() => {
32
+    //     setLoading(false);
33
+    //     message.success('数据更新成功');
34
+    //     goBack();
35
+    //   })
36
+    //     .catch(err => {
37
+    //       setLoading(false);
38
+    //       message.error(err.message || err);
39
+    //     });
40
+    // } else {
41
+    //   addAttaList({ ...data, imageList, typeList }).then((res) => {
42
+    //     setLoading(false);
43
+    //     message.success('数据保存成功');
44
+    //     history.replace(`/Attractions/Edit?id=${res.touristId}`)
45
+    //   })
46
+    //     .catch(err => {
47
+    //       setLoading(false);
48
+    //       message.error(err.message || err);
49
+    //     });
50
+    // }
51
+  };
52
+
53
+  //地址--占位
54
+  const [newLocName, setLocName] = useState('');
55
+  const [newAddress, setAddress] = useState('');
56
+
57
+  const selectTagList = (params) => {
58
+    // return getTagList({
59
+    // }).then((res) => {
60
+    // }).catch((err) => {
61
+    //   return {
62
+    //     success: false,
63
+    //   }
64
+    // })
65
+  };
66
+
67
+  const imageInput = (image) => {
68
+    return {
69
+      uid: image.imageId,
70
+      url: image.url,
71
+    };
72
+  };
73
+
74
+  const imageOutput = (image) => {
75
+    return {
76
+      imageId: image?.raw?.imageId,
77
+      shopId: id,
78
+      url: image.url,
79
+    };
80
+  };
81
+  useEffect(() => {
82
+    selectTagList();
83
+    // if (id) {
84
+    //   gettaTouristForm(id).then((res) => {
85
+    //     setListForm(res)
86
+    //     form.setFieldsValue(res)
87
+    //     setImageList(res?.imageList || [])
88
+    //   })
89
+    // }
90
+  }, [id]);
91
+
92
+  return (
93
+    <Card>
94
+      <ProCard tabs={{ type: 'card' }}>
95
+        <ProCard.TabPane key={1} tab="农机编辑">
96
+          <Form {...formItemLayout} onFinish={Submit} form={form}>
97
+            <FormItem
98
+              label="农机名"
99
+              name="name"
100
+              rules={[{ required: true, message: '请输入农机名' }]}
101
+            >
102
+              <Input placeholder="请输入农机名" style={{ width: '350px' }} />
103
+            </FormItem>
104
+            <FormItem
105
+              label="农机类型"
106
+              name="typeId"
107
+              rules={[{ required: true, message: '请选择农机类型' }]}
108
+            >
109
+              <Select style={{ width: '350px' }}>
110
+                <Option value="6" key="6">
111
+                  {6}
112
+                </Option>
113
+                <Option value="7" key="7">
114
+                  {7}
115
+                </Option>
116
+              </Select>
117
+            </FormItem>
118
+            <FormItem
119
+              label="农机归属"
120
+              name="regionId"
121
+              rules={[{ required: true, message: '请选择农机归属' }]}
122
+            >
123
+              <Select style={{ width: '350px' }}>
124
+                <Option value="6" key="6">
125
+                  {6}
126
+                </Option>
127
+                <Option value="7" key="7">
128
+                  {7}
129
+                </Option>
130
+              </Select>
131
+            </FormItem>
132
+            <FormItem label="价格" name="price" rules={[{ required: true, message: '请输入价格' }]}>
133
+              <Input placeholder="请输入价格" style={{ width: '350px' }} />
134
+            </FormItem>
135
+            <FormItem
136
+              label="押金"
137
+              name="deposit"
138
+              rules={[{ required: true, message: '请输入押金' }]}
139
+            >
140
+              <Input placeholder="请输入押金" style={{ width: '350px' }} />
141
+            </FormItem>
142
+            <FormItem
143
+              label="人工费"
144
+              name="laborCost"
145
+              rules={[{ required: true, message: '请输入人工费' }]}
146
+            >
147
+              <Input placeholder="请输入人工费" style={{ width: '350px' }} />
148
+            </FormItem>
149
+            <FormItem label=" " colon={false}>
150
+              <Button type="default" onClick={() => goBack()}>
151
+                返回
152
+              </Button>
153
+              <Button
154
+                type="primary"
155
+                loading={loading}
156
+                htmlType="submit"
157
+                style={{ marginLeft: '4em' }}
158
+              >
159
+                保存
160
+              </Button>
161
+            </FormItem>
162
+          </Form>
163
+        </ProCard.TabPane>
164
+      </ProCard>
165
+    </Card>
166
+  );
167
+};

+ 98
- 0
src/pages/Machinery/Machinery/index.jsx Wyświetl plik

@@ -0,0 +1,98 @@
1
+import React from 'react';
2
+import { history, Link } from 'umi';
3
+import { Button, Popconfirm, message, Tooltip } from 'antd';
4
+import { PlusOutlined } from '@ant-design/icons';
5
+// import { getPersonList, exportPersonList } from '@/services/person';
6
+import { PageHeaderWrapper } from '@ant-design/pro-layout';
7
+import moment from 'moment';
8
+import PageTable from '@/components/PageTable';
9
+
10
+const formatterTime = (val) => {
11
+  return val ? moment(val).format('YYYY-MM-DD HH:mm:ss') : '';
12
+};
13
+
14
+export default (props) => {
15
+  const actions = () => [
16
+    <Button key="add" type="primary" icon={<PlusOutlined />} onClick={() => gotoEdit()}>
17
+      新增农机
18
+    </Button>,
19
+  ];
20
+  const gotoEdit = (id) => {
21
+    const queryStr = id ? `?id=${id}` : '';
22
+    history.push(`./machinery/edit.jsx${queryStr}`);
23
+  };
24
+  const columns = [
25
+    {
26
+      title: '名称',
27
+      dataIndex: 'name',
28
+      key: 'name',
29
+    },
30
+    {
31
+      title: '农机类型',
32
+      dataIndex: 'typeName',
33
+      key: 'typeName',
34
+    },
35
+    {
36
+      title: '农机归属',
37
+      dataIndex: 'regionName',
38
+      key: 'regionName',
39
+    },
40
+    {
41
+      title: '农机价格',
42
+      dataIndex: 'price',
43
+      key: 'price',
44
+    },
45
+    {
46
+      title: '人工费',
47
+      dataIndex: 'laborCost',
48
+      key: 'laborCost',
49
+    },
50
+    {
51
+      title: '押金',
52
+      dataIndex: 'deposit',
53
+      key: 'deposit',
54
+    },
55
+    {
56
+      title: '工作状态',
57
+      dataIndex: 'jobStatus',
58
+      key: 'jobStatus',
59
+    },
60
+    {
61
+      title: '状态',
62
+      dataIndex: 'status',
63
+      key: 'status',
64
+    },
65
+    {
66
+      title: '操作',
67
+      valueType: 'option',
68
+      render: (_, record) => [
69
+        <Link key={1} to={`./machinery/edit.jsx`}>
70
+          编辑
71
+        </Link>,
72
+        <Popconfirm
73
+          key={2}
74
+          title="您是否确认删除 ?"
75
+          onConfirm={() => handleDelete(record.cooperativeId)}
76
+          okText="确定"
77
+          cancelText="取消"
78
+        >
79
+          <a href="#">删除</a>
80
+        </Popconfirm>,
81
+      ],
82
+    },
83
+  ];
84
+  const handleDelete = () => {};
85
+  return (
86
+    <PageHeaderWrapper>
87
+      <PageTable
88
+        // request={getPersonList}
89
+        // expfunc={exportPersonList}
90
+        toolBarRender={actions}
91
+        columns={columns}
92
+        rowKey="machineryId"
93
+        options={false}
94
+        scroll={{ x: 1000 }}
95
+      />
96
+    </PageHeaderWrapper>
97
+  );
98
+};

+ 133
- 0
src/pages/Machinery/MachineryType/index.jsx Wyświetl plik

@@ -0,0 +1,133 @@
1
+import React from 'react';
2
+import { history, Link } from 'umi';
3
+import { Button, Popconfirm, Modal, Form, Input, message, Space, Tooltip } from 'antd';
4
+import { PlusOutlined } from '@ant-design/icons';
5
+// import { getPersonList, exportPersonList } from '@/services/person';
6
+import { PageHeaderWrapper } from '@ant-design/pro-layout';
7
+import { useRef, useState, useEffect } from 'react';
8
+import moment from 'moment';
9
+import PageTable from '@/components/PageTable';
10
+
11
+const formatterTime = (val) => {
12
+  return val ? moment(val).format('YYYY-MM-DD HH:mm:ss') : '';
13
+};
14
+const FormItem = Form.Item;
15
+export default (props) => {
16
+  const formItemLayout = { labelCol: { span: 6 }, wrapperCol: { span: 14 } };
17
+  const [loading, setLoading] = useState(false);
18
+  const [form] = Form.useForm();
19
+  const actionRef = useRef();
20
+  const [name, setName] = useState();
21
+  const [selectModal, setSelectModal] = useState(false);
22
+  const [machineryTypeList, setMachineryTypeList] = useState([]);
23
+
24
+  const handleName = (val) => {
25
+    setName(val);
26
+  };
27
+  const changeWeight = (record) => {
28
+    setSelectModal(true);
29
+
30
+    // setWeight(record.weight || 0)
31
+    // setEditDetail(record)
32
+  };
33
+  const actions = () => [
34
+    <Button key="add" type="primary" icon={<PlusOutlined />} onClick={selectModalOpen}>
35
+      新增农机分类
36
+    </Button>,
37
+  ];
38
+  const columns = [
39
+    {
40
+      title: '分类名',
41
+      dataIndex: 'name',
42
+      key: 'name',
43
+    },
44
+    {
45
+      title: '操作',
46
+      key: 'option',
47
+      render: (_, record) => {
48
+        return (
49
+          <Space>
50
+            <Button key={1} onClick={() => changeWeight(record)} type="link">
51
+              编辑
52
+            </Button>
53
+            <Popconfirm
54
+              key={2}
55
+              title="您是否确认删除 ?"
56
+              onConfirm={() => handleDelete(record.cooperativeId)}
57
+              okText="确定"
58
+              cancelText="取消"
59
+            >
60
+              <a href="#">删除</a>
61
+            </Popconfirm>
62
+          </Space>
63
+        );
64
+      },
65
+      search: false,
66
+    },
67
+  ];
68
+  const handleDelete = () => {};
69
+
70
+  const Submit = () => {
71
+    setLoading(true);
72
+    editRecommend({ ...editdetail, weight }, editdetail.serialNo).then(() => {
73
+      message.success(`修改成功`);
74
+      setLoading(false);
75
+      onCancel();
76
+      setName();
77
+      actionRef.current.reload();
78
+    });
79
+  };
80
+  const selectModalOpen = () => {
81
+    setSelectModal(true);
82
+  };
83
+  const onCancel = () => {
84
+    form.resetFields();
85
+    setSelectModal(false);
86
+  };
87
+  useEffect(() => {
88
+    form.setFieldsValue({ targetName: '' });
89
+    // setPackageList();
90
+    // getResource({ pageSize: 100 }).then((res) => {
91
+    //   setMachineryTypeList(res.records || []);
92
+    // });
93
+  }, []);
94
+  return (
95
+    <PageHeaderWrapper>
96
+      <Modal
97
+        title="套餐权重修改"
98
+        visible={selectModal}
99
+        onCancel={onCancel}
100
+        destroyOnClose={true}
101
+        footer={null}
102
+      >
103
+        <Form {...formItemLayout} onFinish={Submit} form={form}>
104
+          <FormItem label="权重" name="name" initialValue={name}>
105
+            <Input onChange={handleName} style={{ width: '100%' }} placeholder="请输入分类名" />
106
+          </FormItem>
107
+          <FormItem label=" " colon={false}>
108
+            <Button type="default" onClick={onCancel}>
109
+              取消
110
+            </Button>
111
+            <Button
112
+              type="primary"
113
+              loading={loading}
114
+              htmlType="Submit"
115
+              style={{ marginLeft: '4em' }}
116
+            >
117
+              修改
118
+            </Button>
119
+          </FormItem>
120
+        </Form>
121
+      </Modal>
122
+      <PageTable
123
+        // request={getPersonList}
124
+        // expfunc={exportPersonList}
125
+        toolBarRender={actions}
126
+        columns={columns}
127
+        rowKey="typeId"
128
+        options={false}
129
+        scroll={{ x: 1000 }}
130
+      />
131
+    </PageHeaderWrapper>
132
+  );
133
+};

+ 39
- 27
src/pages/PlatformMessageManagement/MessageEdit/index.jsx Wyświetl plik

@@ -1,18 +1,18 @@
1
-import { Input, Card, Select, Button, message } from "antd"
2
-import { useEffect, useState } from 'react'
3
-import { Form } from "antd";
1
+import { Input, Card, Select, Button, message } from 'antd';
2
+import { useEffect, useState } from 'react';
3
+import { Form } from 'antd';
4 4
 import { history } from 'umi';
5
-import ProCard from '@ant-design/pro-card'
5
+import ExtendContent from '@/components/ExtendContent';
6
+import ProCard from '@ant-design/pro-card';
6 7
 
7 8
 const { Option } = Select;
8 9
 const goBack = () => {
9
-  history.goBack()
10
-}
11
-const FormItem = Form.Item
10
+  history.goBack();
11
+};
12
+const FormItem = Form.Item;
12 13
 export default (props) => {
13
-
14
-  const [form] = Form.useForm()
15
-  const [loading, setLoading] = useState(false)
14
+  const [form] = Form.useForm();
15
+  const [loading, setLoading] = useState(false);
16 16
 
17 17
   const formItemLayout = {
18 18
     //布局
@@ -20,24 +20,19 @@ export default (props) => {
20 20
     wrapperCol: { span: 14 },
21 21
   };
22 22
 
23
-  const Submit = values => {
24
-    console.log("🚀 ~ file: index.jsx ~ line 21 ~ values", values)
25
-
23
+  const Submit = (values) => {
24
+    console.log('🚀 ~ file: index.jsx ~ line 21 ~ values', values);
26 25
   };
27 26
 
28 27
   return (
29
-    <Card >
30
-      <ProCard tabs={{ type: 'card' }} style={{ marginTop: '16px' }}
31
-      >
28
+    <Card>
29
+      <ProCard tabs={{ type: 'card' }} style={{ marginTop: '16px' }}>
32 30
         <ProCard.TabPane key={1} tab="基本信息">
33
-          <Form {...formItemLayout} onFinish={Submit} form={form} >
34
-            <FormItem label="农机手" name="shopName" rules={[{ required: true, message: '请输入' }]}>
35
-              <Input placeholder="请输入" style={{ width: '350px' }} />
36
-            </FormItem>
37
-            <FormItem label="农户" name="title" rules={[{ required: true, message: '请输入' }]}>
31
+          <Form {...formItemLayout} onFinish={Submit} form={form}>
32
+            <FormItem label="标题" name="title" rules={[{ required: true, message: '请输入' }]}>
38 33
               <Input placeholder="请输入" style={{ width: '350px' }} />
39 34
             </FormItem>
40
-            <FormItem label="推送方式" name="phone" rules={[{ required: true, message: '请输入' }]} >
35
+            <FormItem label="推送方式" name="phone" rules={[{ required: true, message: '请输入' }]}>
41 36
               <Select
42 37
                 placeholder="请选择方式"
43 38
                 // onChange={onGenderChange}
@@ -49,13 +44,30 @@ export default (props) => {
49 44
                 <Option value="other">短信推送</Option>
50 45
               </Select>
51 46
             </FormItem>
52
-            <FormItem label=" " colon={false} >
53
-              <Button type='default' onClick={() => goBack()} >返回</Button>
54
-              <Button type='primary' loading={loading} htmlType="Submit" style={{ marginLeft: '4em' }}>保存</Button>
47
+
48
+            <FormItem label="图文信息" colon={false}>
49
+              <ExtendContent
50
+                targetType="tourist"
51
+                targetId={'66'}
52
+                onCancel={() => history.goBack()}
53
+              />
54
+            </FormItem>
55
+            <FormItem label=" " colon={false}>
56
+              <Button type="default" onClick={() => goBack()}>
57
+                返回
58
+              </Button>
59
+              <Button
60
+                type="primary"
61
+                loading={loading}
62
+                htmlType="Submit"
63
+                style={{ marginLeft: '4em' }}
64
+              >
65
+                保存
66
+              </Button>
55 67
             </FormItem>
56 68
           </Form>
57 69
         </ProCard.TabPane>
58 70
       </ProCard>
59 71
     </Card>
60
-  )
61
-}
72
+  );
73
+};

+ 3
- 4
src/pages/PlatformMessageManagement/MessageManageList/index.jsx Wyświetl plik

@@ -14,11 +14,10 @@ export default (props) => {
14 14
       pushPerson: '农机手',
15 15
       status: 'APP内消息中心推送',
16 16
     },
17
-
18 17
   ];
19 18
   const gotoDetail = (id) => {
20
-    history.push(`./MessageEdit`)
21
-  }
19
+    history.push(`./MessageEdit`);
20
+  };
22 21
 
23 22
   const actions = () => [
24 23
     <Button key="add" type="primary" icon={<PlusOutlined />} onClick={() => gotoDetail()}>
@@ -96,7 +95,7 @@ export default (props) => {
96 95
       width: '300px',
97 96
       render: (_, record) => [
98 97
         <Link key={2} to={`./MessageEdit`}>
99
-          查看
98
+          编辑
100 99
         </Link>,
101 100
         <Popconfirm
102 101
           key={3}

+ 91
- 252
src/pages/user/Login/index.jsx Wyświetl plik

@@ -1,284 +1,123 @@
1
-import {
2
-  AlipayCircleOutlined,
3
-  LockOutlined,
4
-  MobileOutlined,
5
-  TaobaoCircleOutlined,
6
-  UserOutlined,
7
-  WeiboCircleOutlined,
8
-} from '@ant-design/icons';
1
+import { LockOutlined, UserOutlined } from '@ant-design/icons';
9 2
 import { Alert, message, Tabs } from 'antd';
10 3
 import React, { useState } from 'react';
11
-import { ProFormCaptcha, ProFormCheckbox, ProFormText, LoginForm } from '@ant-design/pro-form';
12
-import { useIntl, history, FormattedMessage, SelectLang, useModel } from 'umi';
4
+import md5 from 'md5';
5
+import ProForm, { ProFormText } from '@ant-design/pro-form';
6
+import { useIntl, Link, history, FormattedMessage, SelectLang, useModel } from 'umi';
13 7
 import Footer from '@/components/Footer';
14
-import { login } from '@/services/ant-design-pro/api';
15
-import { getFakeCaptcha } from '@/services/ant-design-pro/login';
8
+import { login } from '@/services/login';
16 9
 import styles from './index.less';
17 10
 
18
-const LoginMessage = ({ content }) => (
19
-  <Alert
20
-    style={{
21
-      marginBottom: 24,
22
-    }}
23
-    message={content}
24
-    type="error"
25
-    showIcon
26
-  />
27
-);
28
-
29 11
 const Login = () => {
30
-  const [userLoginState, setUserLoginState] = useState({});
31
-  const [type, setType] = useState('account');
12
+  const [submitting, setSubmitting] = useState(false);
32 13
   const { initialState, setInitialState } = useModel('@@initialState');
33 14
   const intl = useIntl();
34 15
 
35
-  const fetchUserInfo = async () => {
36
-    const userInfo = await initialState?.fetchUserInfo?.();
37
-
38
-    if (userInfo) {
39
-      await setInitialState((s) => ({ ...s, currentUser: userInfo }));
40
-    }
41
-  };
42
-
43 16
   const handleSubmit = async (values) => {
17
+    setSubmitting(true);
18
+
44 19
     try {
45 20
       // 登录
46
-      const msg = await login({ ...values, type });
21
+      const { user } = await login({ ...values, password: md5(values.password) });
47 22
 
48
-      if (msg.status === 'ok') {
49
-        const defaultLoginSuccessMessage = intl.formatMessage({
50
-          id: 'pages.login.success',
51
-          defaultMessage: '登录成功!',
52
-        });
53
-        message.success(defaultLoginSuccessMessage);
54
-        await fetchUserInfo();
55
-        /** 此方法会跳转到 redirect 参数所在的位置 */
23
+      await setInitialState((s) => ({ ...s, currentUser: user }));
56 24
 
57
-        if (!history) return;
58
-        const { query } = history.location;
59
-        const { redirect } = query;
60
-        history.push(redirect || '/');
61
-        return;
62
-      }
25
+      message.success('登录成功!');
26
+      /** 此方法会跳转到 redirect 参数所在的位置 */
63 27
 
64
-      console.log(msg); // 如果失败去设置用户错误信息
65
-
66
-      setUserLoginState(msg);
28
+      if (!history) return;
29
+      const { query } = history.location;
30
+      const { redirect } = query;
31
+      history.push(redirect || '/');
32
+      return;
67 33
     } catch (error) {
68
-      const defaultLoginFailureMessage = intl.formatMessage({
69
-        id: 'pages.login.failure',
70
-        defaultMessage: '登录失败,请重试!',
71
-      });
72
-      message.error(defaultLoginFailureMessage);
34
+      console.error(error);
73 35
     }
36
+
37
+    setSubmitting(false);
74 38
   };
75 39
 
76
-  const { status, type: loginType } = userLoginState;
77 40
   return (
78 41
     <div className={styles.container}>
79 42
       <div className={styles.lang} data-lang>
80 43
         {SelectLang && <SelectLang />}
81 44
       </div>
82 45
       <div className={styles.content}>
83
-        <LoginForm
84
-          logo={<img alt="logo" src="/logo.svg" />}
85
-          title="Ant Design"
86
-          subTitle={intl.formatMessage({
87
-            id: 'pages.layouts.userLayout.title',
88
-          })}
89
-          initialValues={{
90
-            autoLogin: true,
91
-          }}
92
-          actions={[
93
-            <FormattedMessage
94
-              key="loginWith"
95
-              id="pages.login.loginWith"
96
-              defaultMessage="其他登录方式"
97
-            />,
98
-            <AlipayCircleOutlined key="AlipayCircleOutlined" className={styles.icon} />,
99
-            <TaobaoCircleOutlined key="TaobaoCircleOutlined" className={styles.icon} />,
100
-            <WeiboCircleOutlined key="WeiboCircleOutlined" className={styles.icon} />,
101
-          ]}
102
-          onFinish={async (values) => {
103
-            await handleSubmit(values);
104
-          }}
105
-        >
106
-          <Tabs activeKey={type} onChange={setType}>
107
-            <Tabs.TabPane
108
-              key="account"
109
-              tab={intl.formatMessage({
110
-                id: 'pages.login.accountLogin.tab',
111
-                defaultMessage: '账户密码登录',
112
-              })}
113
-            />
114
-            <Tabs.TabPane
115
-              key="mobile"
116
-              tab={intl.formatMessage({
117
-                id: 'pages.login.phoneLogin.tab',
118
-                defaultMessage: '手机号登录',
119
-              })}
120
-            />
121
-          </Tabs>
122
-
123
-          {status === 'error' && loginType === 'account' && (
124
-            <LoginMessage
125
-              content={intl.formatMessage({
126
-                id: 'pages.login.accountLogin.errorMessage',
127
-                defaultMessage: '账户或密码错误(admin/ant.design)',
128
-              })}
129
-            />
130
-          )}
131
-          {type === 'account' && (
132
-            <>
133
-              <ProFormText
134
-                name="username"
135
-                fieldProps={{
136
-                  size: 'large',
137
-                  prefix: <UserOutlined className={styles.prefixIcon} />,
138
-                }}
139
-                placeholder={intl.formatMessage({
140
-                  id: 'pages.login.username.placeholder',
141
-                  defaultMessage: '用户名: admin or user',
142
-                })}
143
-                rules={[
144
-                  {
145
-                    required: true,
146
-                    message: (
147
-                      <FormattedMessage
148
-                        id="pages.login.username.required"
149
-                        defaultMessage="请输入用户名!"
150
-                      />
151
-                    ),
152
-                  },
153
-                ]}
154
-              />
155
-              <ProFormText.Password
156
-                name="password"
157
-                fieldProps={{
158
-                  size: 'large',
159
-                  prefix: <LockOutlined className={styles.prefixIcon} />,
160
-                }}
161
-                placeholder={intl.formatMessage({
162
-                  id: 'pages.login.password.placeholder',
163
-                  defaultMessage: '密码: ant.design',
164
-                })}
165
-                rules={[
166
-                  {
167
-                    required: true,
168
-                    message: (
169
-                      <FormattedMessage
170
-                        id="pages.login.password.required"
171
-                        defaultMessage="请输入密码!"
172
-                      />
173
-                    ),
174
-                  },
175
-                ]}
176
-              />
177
-            </>
178
-          )}
179
-
180
-          {status === 'error' && loginType === 'mobile' && <LoginMessage content="验证码错误" />}
181
-          {type === 'mobile' && (
182
-            <>
183
-              <ProFormText
184
-                fieldProps={{
185
-                  size: 'large',
186
-                  prefix: <MobileOutlined className={styles.prefixIcon} />,
187
-                }}
188
-                name="mobile"
189
-                placeholder={intl.formatMessage({
190
-                  id: 'pages.login.phoneNumber.placeholder',
191
-                  defaultMessage: '手机号',
192
-                })}
193
-                rules={[
194
-                  {
195
-                    required: true,
196
-                    message: (
197
-                      <FormattedMessage
198
-                        id="pages.login.phoneNumber.required"
199
-                        defaultMessage="请输入手机号!"
200
-                      />
201
-                    ),
202
-                  },
203
-                  {
204
-                    pattern: /^1\d{10}$/,
205
-                    message: (
206
-                      <FormattedMessage
207
-                        id="pages.login.phoneNumber.invalid"
208
-                        defaultMessage="手机号格式错误!"
209
-                      />
210
-                    ),
211
-                  },
212
-                ]}
213
-              />
214
-              <ProFormCaptcha
215
-                fieldProps={{
216
-                  size: 'large',
217
-                  prefix: <LockOutlined className={styles.prefixIcon} />,
218
-                }}
219
-                captchaProps={{
220
-                  size: 'large',
221
-                }}
222
-                placeholder={intl.formatMessage({
223
-                  id: 'pages.login.captcha.placeholder',
224
-                  defaultMessage: '请输入验证码',
225
-                })}
226
-                captchaTextRender={(timing, count) => {
227
-                  if (timing) {
228
-                    return `${count} ${intl.formatMessage({
229
-                      id: 'pages.getCaptchaSecondText',
230
-                      defaultMessage: '获取验证码',
231
-                    })}`;
232
-                  }
233
-
234
-                  return intl.formatMessage({
235
-                    id: 'pages.login.phoneLogin.getVerificationCode',
236
-                    defaultMessage: '获取验证码',
237
-                  });
238
-                }}
239
-                name="captcha"
240
-                rules={[
241
-                  {
242
-                    required: true,
243
-                    message: (
244
-                      <FormattedMessage
245
-                        id="pages.login.captcha.required"
246
-                        defaultMessage="请输入验证码!"
247
-                      />
248
-                    ),
249
-                  },
250
-                ]}
251
-                onGetCaptcha={async (phone) => {
252
-                  const result = await getFakeCaptcha({
253
-                    phone,
254
-                  });
255
-
256
-                  if (result === false) {
257
-                    return;
258
-                  }
46
+        <div className={styles.top}>
47
+          <div className={styles.header}>
48
+            <Link to="/">
49
+              {/* <img alt="logo" className={styles.logo} src="/logo.svg" /> */}
50
+              <span className={styles.title}>南阳智慧农机系统</span>
51
+            </Link>
52
+          </div>
53
+          <div className={styles.desc}>我们是一群被打了鸡血的小伙伴</div>
54
+        </div>
259 55
 
260
-                  message.success('获取验证码成功!验证码为:1234');
261
-                }}
262
-              />
263
-            </>
264
-          )}
265
-          <div
266
-            style={{
267
-              marginBottom: 24,
56
+        <div className={styles.main}>
57
+          <ProForm
58
+            initialValues={{
59
+              autoLogin: true,
60
+            }}
61
+            submitter={{
62
+              searchConfig: {
63
+                submitText: intl.formatMessage({
64
+                  id: 'pages.login.submit',
65
+                  defaultMessage: '登录',
66
+                }),
67
+              },
68
+              render: (_, dom) => dom.pop(),
69
+              submitButtonProps: {
70
+                loading: submitting,
71
+                size: 'large',
72
+                style: {
73
+                  width: '100%',
74
+                },
75
+              },
76
+            }}
77
+            onFinish={async (values) => {
78
+              handleSubmit(values);
268 79
             }}
269 80
           >
270
-            <ProFormCheckbox noStyle name="autoLogin">
271
-              <FormattedMessage id="pages.login.rememberMe" defaultMessage="自动登录" />
272
-            </ProFormCheckbox>
273
-            <a
274
-              style={{
275
-                float: 'right',
81
+            <ProFormText
82
+              name="userName"
83
+              fieldProps={{
84
+                size: 'large',
85
+                prefix: <UserOutlined className={styles.prefixIcon} />,
276 86
               }}
277
-            >
278
-              <FormattedMessage id="pages.login.forgotPassword" defaultMessage="忘记密码" />
279
-            </a>
280
-          </div>
281
-        </LoginForm>
87
+              placeholder="用户名"
88
+              rules={[
89
+                {
90
+                  required: true,
91
+                  message: (
92
+                    <FormattedMessage
93
+                      id="pages.login.username.required"
94
+                      defaultMessage="请输入用户名!"
95
+                    />
96
+                  ),
97
+                },
98
+              ]}
99
+            />
100
+            <ProFormText.Password
101
+              name="password"
102
+              fieldProps={{
103
+                size: 'large',
104
+                prefix: <LockOutlined className={styles.prefixIcon} />,
105
+              }}
106
+              placeholder="密码"
107
+              rules={[
108
+                {
109
+                  required: true,
110
+                  message: (
111
+                    <FormattedMessage
112
+                      id="pages.login.password.required"
113
+                      defaultMessage="请输入密码!"
114
+                    />
115
+                  ),
116
+                },
117
+              ]}
118
+            />
119
+          </ProForm>
120
+        </div>
282 121
       </div>
283 122
       <Footer />
284 123
     </div>

+ 73
- 9
src/pages/user/Login/index.less Wyświetl plik

@@ -1,4 +1,4 @@
1
-@import (reference) '~antd/es/style/themes/index';
1
+@import '~antd/es/style/themes/default.less';
2 2
 
3 3
 .container {
4 4
   display: flex;
@@ -36,15 +36,79 @@
36 36
   }
37 37
 }
38 38
 
39
-.icon {
40
-  margin-left: 8px;
41
-  color: rgba(0, 0, 0, 0.2);
42
-  font-size: 24px;
43
-  vertical-align: middle;
44
-  cursor: pointer;
45
-  transition: color 0.3s;
39
+.top {
40
+  text-align: center;
41
+}
42
+
43
+.header {
44
+  height: 44px;
45
+  line-height: 44px;
46
+  a {
47
+    text-decoration: none;
48
+  }
49
+}
50
+
51
+.logo {
52
+  height: 44px;
53
+  margin-right: 16px;
54
+  vertical-align: top;
55
+}
56
+
57
+.title {
58
+  position: relative;
59
+  top: 2px;
60
+  color: @heading-color;
61
+  font-weight: 600;
62
+  font-size: 33px;
63
+  font-family: Avenir, 'Helvetica Neue', Arial, Helvetica, sans-serif;
64
+}
65
+
66
+.desc {
67
+  margin-top: 12px;
68
+  margin-bottom: 40px;
69
+  color: @text-color-secondary;
70
+  font-size: @font-size-base;
71
+}
72
+
73
+.main {
74
+  width: 328px;
75
+  margin: 0 auto;
76
+  @media screen and (max-width: @screen-sm) {
77
+    width: 95%;
78
+    max-width: 328px;
79
+  }
80
+
81
+  :global {
82
+    .@{ant-prefix}-tabs-nav-list {
83
+      margin: auto;
84
+      font-size: 16px;
85
+    }
86
+  }
87
+
88
+  .icon {
89
+    margin-left: 16px;
90
+    color: rgba(0, 0, 0, 0.2);
91
+    font-size: 24px;
92
+    vertical-align: middle;
93
+    cursor: pointer;
94
+    transition: color 0.3s;
95
+
96
+    &:hover {
97
+      color: @primary-color;
98
+    }
99
+  }
100
+
101
+  .other {
102
+    margin-top: 24px;
103
+    line-height: 22px;
104
+    text-align: left;
105
+    .register {
106
+      float: right;
107
+    }
108
+  }
46 109
 
47
-  &:hover {
110
+  .prefixIcon {
48 111
     color: @primary-color;
112
+    font-size: @font-size-base;
49 113
   }
50 114
 }

+ 37
- 0
src/services/extendContent.js Wyświetl plik

@@ -0,0 +1,37 @@
1
+import request from '@/utils/request'
2
+
3
+/**
4
+ * 保存扩展内容
5
+ * @param {*} data 
6
+ * @returns 
7
+ */
8
+export const save = (data) => request('/taExtendContent', { method: 'post', data })
9
+
10
+/**
11
+ * 修改扩展内容
12
+ * @param {*} data 
13
+ * @returns 
14
+ */
15
+export const update = (id, data) => request(`/taExtendContent/${id}`, { method: 'put', data })
16
+
17
+/**
18
+ * 查询扩展内容列表 
19
+ * @param {*} params 
20
+ * @returns 
21
+ */
22
+export const getList = (params) => request('/taExtendContent', { params })
23
+
24
+
25
+/**
26
+ * 删除扩展内容
27
+ * @param {*} data 
28
+ * @returns 
29
+ */
30
+ export const remove = (id) => request(`/taExtendContent/${id}`, { method: 'delete'})
31
+ 
32
+/**
33
+ * 查询扩展内容详情
34
+ * @param {*} params 
35
+ * @returns 
36
+ */
37
+export const getDetail = (id) => request(`/taExtendContent/${id}`)

+ 3
- 0
src/services/login.js Wyświetl plik

@@ -0,0 +1,3 @@
1
+import request from '@/utils/request';
2
+
3
+export const login = (data) => request('/login', { method: 'post', data });

+ 61
- 0
src/services/oss.js Wyświetl plik

@@ -0,0 +1,61 @@
1
+import OSS from 'ali-oss';
2
+import request from '@/utils/request';
3
+
4
+let client;
5
+let stsInfo;
6
+
7
+/**
8
+ * 获取 OSS-STS 临时凭证
9
+ * @returns
10
+ */
11
+export const getSTSToken = () => request('/oss-sts');
12
+
13
+/**
14
+ * 获取 OSS 客户端
15
+ * @returns
16
+ */
17
+export function getOSSClient() {
18
+  if (client) {
19
+    return Promise.resolve(client);
20
+  }
21
+
22
+  return getSTSToken().then((sts) => {
23
+    stsInfo = sts;
24
+
25
+    client = new OSS({
26
+      accessKeyId: sts.accessKeyId,
27
+      accessKeySecret: sts.accessKeySecret,
28
+      stsToken: sts.stsToken,
29
+      bucket: sts.bucket,
30
+      endpoint: sts.endpoint,
31
+      refreshSTSTokenInterval: 25 * 60 * 1000, // 每25min刷新一次
32
+      refreshSTSToken: () => {
33
+        return getSTSToken().then((res) => {
34
+          return {
35
+            accessKeyId: res.accessKeyId,
36
+            accessKeySecret: res.accessKeySecret,
37
+            stsToken: res.stsToken,
38
+          };
39
+        });
40
+      },
41
+    });
42
+
43
+    return client;
44
+  });
45
+}
46
+
47
+/**
48
+ * 上传文件到 OSS
49
+ * @param {*} file
50
+ * @returns
51
+ */
52
+export function upload(file) {
53
+  return getOSSClient().then(() => {
54
+    const data = new FormData();
55
+    data.append('file', file);
56
+    const now = new Date();
57
+    const fileName = `${stsInfo.path}/${now.valueOf()}-${file.name}`;
58
+
59
+    return client.put(fileName, file).then((res) => res.url);
60
+  });
61
+}

+ 5
- 0
src/services/user.js Wyświetl plik

@@ -0,0 +1,5 @@
1
+import request from '@/utils/request';
2
+
3
+export const currentUser = () => request('/currentUser');
4
+
5
+export const changePassword = (data) => request('/change-password', { data, method: 'PUT' });

+ 2
- 1
src/utils/request.js Wyświetl plik

@@ -5,7 +5,8 @@ function requestInterceptor(url, options) {
5 5
   const headers = options.headers || {};
6 6
   const token = localStorage.getItem('token')
7 7
     ? { 'X-Authorization-JWT': localStorage.getItem('token') }
8
-    : {};
8
+    : // ? { 'Authorization': localStorage.getItem('token') }
9
+      {};
9 10
   const prefix =
10 11
     process.env.NODE_ENV === 'production' ? 'http://sgl-v2.njyunzhi.com/api/admin' : '/api/admin';
11 12
 

+ 17
- 0
src/utils/upload.js Wyświetl plik

@@ -0,0 +1,17 @@
1
+import { upload } from '@/services/oss'
2
+
3
+/**
4
+ * 获取 OSS 客户端
5
+ * @returns 
6
+ */
7
+export function uploadFile({ file, onSuccess, onError }) {
8
+  upload(file).then((url) => {
9
+    onSuccess(url, file)
10
+  }).catch((e) => {
11
+    onError(e)
12
+  });
13
+
14
+  return {
15
+    abort: () => {},
16
+  };
17
+}