Sfoglia il codice sorgente

Merge branch 'master' of http://git.ycjcjy.com/civilized_city/pc-admin

fangmingyue 2 anni fa
parent
commit
53ce508e5e

+ 198
- 0
src/pages/check/components/QuForm.jsx Vedi File

1
+import React from 'react';
2
+import {
3
+  DrawerForm,
4
+  ProFormText,
5
+  ProFormSelect,
6
+  ProFormDigit,
7
+  ProFormList
8
+} from '@ant-design/pro-components';
9
+import { Form, Row, Col } from 'antd';
10
+import WangEditor from '@/components/Wangeditor';
11
+import { postTaCheckItemQu } from '@/service/tdlocquestion';
12
+
13
+export default (props) => {
14
+  const {open, onOpenChange, quInfo, itemId, onChange} = props;
15
+  const [form] = Form.useForm();
16
+  
17
+  const onFinish = async (values) => {
18
+    const data = {
19
+      ...(quInfo || {}),
20
+      ...values,
21
+      itemId,
22
+    }
23
+
24
+    const res = await postTaCheckItemQu(data).then(x => x);
25
+
26
+    onChange(res);
27
+    return true;
28
+  }
29
+
30
+  React.useEffect(() => {
31
+    if (quInfo) {
32
+      form.setFieldsValue(quInfo);
33
+    } else {
34
+      form.resetFields();
35
+    }
36
+  }, [quInfo]);
37
+
38
+  return (
39
+    <DrawerForm
40
+      title="问题维护"
41
+      open={open}
42
+      width={800}
43
+      form={form}
44
+      destroyOnClose
45
+      onFinish={onFinish}
46
+      onOpenChange={onOpenChange}
47
+    >
48
+      <Row gutter={24}>
49
+        <Col span={6}>
50
+          <ProFormText
51
+            name="sortNo"
52
+            label="序号"
53
+            placeholder="请填写"
54
+            rules={[
55
+              {
56
+                required: true,
57
+                message: '请填写序号',
58
+              },
59
+            ]}
60
+          />
61
+        </Col>
62
+        <Col span={18}>
63
+          <ProFormText
64
+            name="title"
65
+            label="题干描述"
66
+            placeholder="请填写"
67
+            rules={[
68
+              {
69
+                required: true,
70
+                message: '请填写题干',
71
+              },
72
+            ]}
73
+          />
74
+        </Col>
75
+      </Row>
76
+      <Row gutter={24}>
77
+        <Col span={12}>
78
+          <ProFormSelect
79
+            name="quType"
80
+            label="问题类型"
81
+            fieldProps={{
82
+              style: { width: '100%' }
83
+            }}
84
+            valueEnum={{
85
+              radio: '单选',
86
+              fill: '填空'
87
+            }}
88
+            rules={[
89
+              {
90
+                required: true,
91
+                message: '请选择问题类型',
92
+              },
93
+            ]}
94
+          />
95
+        </Col>
96
+        <Col span={12}>
97
+          <ProFormSelect
98
+            name="computeType"
99
+            label="计分方式"
100
+            fieldProps={{
101
+              style: { width: '100%' }
102
+            }}
103
+            valueEnum={{
104
+              '+': '得分',
105
+              '-': '扣分'
106
+            }}
107
+            rules={[
108
+              {
109
+                required: true,
110
+                message: '请选择计分方式',
111
+              },
112
+            ]}
113
+          />
114
+        </Col>
115
+      </Row>
116
+      <Row gutter={24}>
117
+        <Col span={12}>
118
+          <ProFormDigit
119
+            name="maxScore"
120
+            label="最 高 分"
121
+            min={0}
122
+            fieldProps={{ precision: 2 }}
123
+            rules={[
124
+              {
125
+                required: true,
126
+                message: '请设置最高分',
127
+              },
128
+            ]}
129
+          />
130
+        </Col>
131
+        <Col span={12}>
132
+          <ProFormDigit
133
+            name="anScore"
134
+            label="单项计分"
135
+            min={0}
136
+            fieldProps={{ precision: 2 }}
137
+            rules={[
138
+              {
139
+                required: true,
140
+                message: '请设置单项计分',
141
+              },
142
+            ]}
143
+          />
144
+        </Col>
145
+      </Row>
146
+      <Form.Item name="stand" label="评分标准">
147
+        <WangEditor
148
+          height="200px"
149
+          toolbarConfig={{
150
+            toolbarKeys: [
151
+              'headerSelect',
152
+              'blockquote',
153
+              '|',
154
+              'bold',
155
+              'underline',
156
+              'italic',
157
+              'color',
158
+              'fontSize',
159
+              '|',
160
+              'bulletedList',
161
+              'numberedList',
162
+            ]
163
+          }}
164
+        />
165
+      </Form.Item>
166
+      <ProFormList
167
+        name="answerList"
168
+        label="选项列表"
169
+        copyIconProps={false}
170
+      >
171
+        <Row gutter={24} style={{width: '730px'}}>
172
+          <Col span={6}>
173
+            <ProFormText
174
+              name="answerCode"
175
+              label="选项"
176
+              help="类似 A, B, C, D"
177
+            />
178
+          </Col>
179
+          <Col span={6}>
180
+            <ProFormDigit
181
+              name="score"
182
+              label="计分"
183
+              min={0}
184
+              fieldProps={{ precision: 2 }}
185
+            />
186
+          </Col>
187
+          <Col span={12}>
188
+            <ProFormText
189
+              name="answer"
190
+              label="答案"
191
+              placeholder="具体选项内容"
192
+            />
193
+          </Col>
194
+        </Row>
195
+      </ProFormList>
196
+    </DrawerForm>
197
+  )
198
+}

+ 44
- 164
src/pages/check/components/QuManage.jsx Vedi File

1
 import React from 'react';
1
 import React from 'react';
2
-import { Button, Form, Row, Col, Card, Input, Modal, List } from 'antd';
3
-import {
4
-  DrawerForm,
5
-  ProFormGroup,
6
-  ProFormText,
7
-  ProFormSelect,
8
-  ProFormDigit,
9
-  ProFormList
10
-} from '@ant-design/pro-components';
11
-import WangEditor from '@/components/Wangeditor';
2
+import { Button, Form, Row, Col, Card, List, Popconfirm } from 'antd';
3
+import QuForm from './QuForm';
12
 import { postTaCheckItemQu, getTaCheckItemQu } from '@/service/tdlocquestion';
4
 import { postTaCheckItemQu, getTaCheckItemQu } from '@/service/tdlocquestion';
13
-import { getTaCheckItemAn } from '@/service/tacheckiteman';
5
+import { deleteTaCheckItemQu } from '@/service/tacheckitemqu';
6
+import { message } from 'antd';
14
 
7
 
15
 const QuItem = (props) => {
8
 const QuItem = (props) => {
16
-   const { qu, onEdit } = props;
9
+  const { qu, onEdit, onDelete } = props;
17
 
10
 
18
-   const quTitle = `${qu?.sortNo}. [${qu?.quType == 'fill' ? '填空' : '选择'}] ${qu?.title} (分值: ${qu?.computeType} ${qu?.anScore}/${qu?.maxScore})`
11
+  const quTitle = `${qu?.sortNo}. [${qu?.quType == 'fill' ? '填空' : '选择'}] ${qu?.title} (分值: ${qu?.computeType} ${qu?.anScore}/${qu?.maxScore})`
19
 
12
 
20
   return (
13
   return (
21
-    <Card title={quTitle} extra={<Button type='link' onClick={onEdit}>修改</Button>} style={{marginTop: '24px'}}>
14
+    <Card
15
+      title={quTitle} 
16
+      style={{marginTop: '24px'}}
17
+      extra={(
18
+        <>
19
+          <Button type='link' onClick={onEdit}>修改</Button>
20
+          <Popconfirm
21
+            title="确认进行删除操作?"
22
+            onConfirm={onDelete}
23
+          >
24
+            <Button type='link' danger >删除</Button>
25
+          </Popconfirm>
26
+        </>
27
+      )} 
28
+    >
22
       <Card.Meta
29
       <Card.Meta
23
         title={
30
         title={
24
           qu?.quType != 'fill' ?
31
           qu?.quType != 'fill' ?
56
   const [open, setOpen] = React.useState(false);
63
   const [open, setOpen] = React.useState(false);
57
   const [quInfo, setQuInfo] = React.useState(false);
64
   const [quInfo, setQuInfo] = React.useState(false);
58
   const [list, setList] = React.useState([]);
65
   const [list, setList] = React.useState([]);
59
-  // const [anList, setAnList] = React.useState([]);
60
-  const [form] = Form.useForm();
61
-
62
-  const onFinish = async (values) => {
63
-    const data = { ...(quInfo || {}), ...values, itemId }
64
-    const res = await postTaCheckItemQu(data);
65
 
66
 
67
+  const onFinish = (res) => {
66
     let found = false;
68
     let found = false;
67
     const newList = list.map(item => {
69
     const newList = list.map(item => {
68
       if (item.quId === res.quId) {
70
       if (item.quId === res.quId) {
78
     }
80
     }
79
 
81
 
80
     setList(list);
82
     setList(list);
81
-    onChange(res);
82
-
83
-    return true;
84
   }
83
   }
85
 
84
 
86
   const onEditQu = (qu) => {
85
   const onEditQu = (qu) => {
88
     setOpen(true);
87
     setOpen(true);
89
   }
88
   }
90
 
89
 
91
-  React.useEffect(() => {
92
-    if (quInfo) {
93
-      form.setFieldsValue(quInfo);
90
+  const onDeleteQu = (qu) => {
91
+    if (qu?.quId) {
92
+      deleteTaCheckItemQu(qu.quId).then(() => {
93
+        setList(list.filter(x => x.quId !== qu.quId));
94
+      })
95
+    } else {
96
+      setList(list.filter(x => x.quId !== qu.quId));
94
     }
97
     }
95
-  }, [quInfo]);
98
+  }
96
 
99
 
97
   React.useEffect(() => {
100
   React.useEffect(() => {
98
     if (itemId) {
101
     if (itemId) {
103
   }, [itemId]);
106
   }, [itemId]);
104
 
107
 
105
   React.useImperativeHandle(ref, () => ({
108
   React.useImperativeHandle(ref, () => ({
106
-    add: () => setOpen(true),
109
+    add: () => {
110
+      setQuInfo();
111
+      setOpen(true);
112
+    },
107
   }), []);
113
   }), []);
108
 
114
 
109
   return (
115
   return (
110
-    <div>
111
-      <DrawerForm title="问题维护" open={open} width={800} form={form} onFinish={onFinish} onOpenChange={setOpen}>
112
-        <ProFormText
113
-          name="title"
114
-          label="题干描述"
115
-          placeholder="请填写"
116
-          rules={[
117
-            {
118
-              required: true,
119
-              message: '请填写题干',
120
-            },
121
-          ]}
122
-        />
123
-        <Row gutter={24}>
124
-          <Col span={12}>
125
-            <ProFormSelect
126
-              name="quType"
127
-              label="问题类型"
128
-              fieldProps={{
129
-                style: { width: '100%' }
130
-              }}
131
-              valueEnum={{
132
-                radio: '单选',
133
-                fill: '填空'
134
-              }}
135
-              rules={[
136
-                {
137
-                  required: true,
138
-                  message: '请选择问题类型',
139
-                },
140
-              ]}
141
-            />
142
-          </Col>
143
-          <Col span={12}>
144
-            <ProFormSelect
145
-              name="computeType"
146
-              label="计分方式"
147
-              fieldProps={{
148
-                style: { width: '100%' }
149
-              }}
150
-              valueEnum={{
151
-                '+': '得分',
152
-                '-': '扣分'
153
-              }}
154
-              rules={[
155
-                {
156
-                  required: true,
157
-                  message: '请选择计分方式',
158
-                },
159
-              ]}
160
-            />
161
-          </Col>
162
-        </Row>
163
-        <Row gutter={24}>
164
-          <Col span={12}>
165
-            <ProFormDigit
166
-              name="maxScore"
167
-              label="最 高 分"
168
-              min={0}
169
-              fieldProps={{ precision: 2 }}
170
-              rules={[
171
-                {
172
-                  required: true,
173
-                  message: '请设置最高分',
174
-                },
175
-              ]}
176
-            />
177
-          </Col>
178
-          <Col span={12}>
179
-            <ProFormDigit
180
-              name="anScore"
181
-              label="单项计分"
182
-              min={0}
183
-              fieldProps={{ precision: 2 }}
184
-              rules={[
185
-                {
186
-                  required: true,
187
-                  message: '请设置单项计分',
188
-                },
189
-              ]}
190
-            />
191
-          </Col>
192
-        </Row>
193
-        <Form.Item name="stand" label="评分标准">
194
-          <WangEditor
195
-            height="200px"
196
-            toolbarConfig={{
197
-              toolbarKeys: [
198
-                'headerSelect',
199
-                'blockquote',
200
-                '|',
201
-                'bold',
202
-                'underline',
203
-                'italic',
204
-                'color',
205
-                'fontSize',
206
-                '|',
207
-                'bulletedList',
208
-                'numberedList',
209
-              ]
210
-            }}
211
-          />
212
-        </Form.Item>
213
-        <ProFormList
214
-          name="answerList"
215
-          label="选项列表"
216
-          copyIconProps={false}
217
-        >
218
-          <Row gutter={24} style={{width: '730px'}}>
219
-            <Col span={6}>
220
-              <ProFormText
221
-                name="answerCode"
222
-                label="选项"
223
-                help="类似 A, B, C, D"
224
-              />
225
-            </Col>
226
-            <Col span={6}>
227
-              <ProFormDigit
228
-                name="score"
229
-                label="计分"
230
-                min={0}
231
-                fieldProps={{ precision: 2 }}
232
-              />
233
-            </Col>
234
-            <Col span={12}>
235
-              <ProFormText
236
-                name="answer"
237
-                label="答案"
238
-                placeholder="具体选项内容"
239
-              />
240
-            </Col>
241
-          </Row>
242
-        </ProFormList>
243
-      </DrawerForm>
116
+    <>
117
+      <QuForm itemId={itemId} quInfo={quInfo} open={open} onOpenChange={setOpen} onChange={onFinish} />
244
       <List
118
       <List
245
         itemLayout="horizontal"
119
         itemLayout="horizontal"
246
         dataSource={list}
120
         dataSource={list}
247
-        renderItem={(item) => <QuItem qu={item} onEdit={() => onEditQu(item)}/>}
121
+        renderItem={(item) => (
122
+          <QuItem
123
+            qu={item}
124
+            onEdit={() => onEditQu(item)}
125
+            onDelete={() => onDeleteQu(item)}
126
+          />
127
+        )}
248
       />
128
       />
249
-    </div>
129
+    </>
250
   )
130
   )
251
 });
131
 });

+ 0
- 2
src/pages/locType/edit/index.jsx Vedi File

46
     }
46
     }
47
   }, [id]);
47
   }, [id]);
48
 
48
 
49
-  console.log('id', id);
50
-
51
   const onFinish = (values) => {
49
   const onFinish = (values) => {
52
     startSubmit();
50
     startSubmit();
53
     console.log('locType修改id', id);
51
     console.log('locType修改id', id);

+ 0
- 18
src/pages/locType/list/index.jsx Vedi File

32
   };
32
   };
33
 
33
 
34
   const columns = [
34
   const columns = [
35
-    {
36
-      title: "分类ID",
37
-      dataIndex: "typeId",
38
-    },
39
     {
35
     {
40
       title: "分类名称",
36
       title: "分类名称",
41
       dataIndex: "name",
37
       dataIndex: "name",
44
       title: "分类描述",
40
       title: "分类描述",
45
       dataIndex: "desc",
41
       dataIndex: "desc",
46
     },
42
     },
47
-    {
48
-      title: "排序",
49
-      dataIndex: "sortNo",
50
-    },
51
     {
43
     {
52
       title: "状态",
44
       title: "状态",
53
       dataIndex: "status",
45
       dataIndex: "status",
67
       valueType: "option",
59
       valueType: "option",
68
       width: 200,
60
       width: 200,
69
       render: (_, record) => [
61
       render: (_, record) => [
70
-        // <Button
71
-        //   key={1}
72
-        //   style={{ padding: 0 }}
73
-        //   type="link"
74
-        //   onClick={() => {
75
-        //     updateStatus(record);
76
-        //   }}
77
-        // >
78
-        //   {record.status === 1 ? "禁用" : "启用"}
79
-        // </Button>,
80
         <Button
62
         <Button
81
           key={2}
63
           key={2}
82
           style={{ padding: 0 }}
64
           style={{ padding: 0 }}

+ 4
- 3
src/pages/login/style.less Vedi File

22
   .login-card {
22
   .login-card {
23
     width: 900px;
23
     width: 900px;
24
     height: 600px;
24
     height: 600px;
25
-    border-radius: 4px;
25
+    border-radius: 8px;
26
     overflow: hidden;
26
     overflow: hidden;
27
+    backdrop-filter: blur(6px);
27
     box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.2);
28
     box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.2);
28
     
29
     
29
     display: grid;
30
     display: grid;
31
   }
32
   }
32
 
33
 
33
   .login-card-left {
34
   .login-card-left {
34
-    background: rgba(255, 255, 255, 0.9);
35
+    background: rgba(255, 255, 255, 0.45);
35
   }
36
   }
36
   .login-card-right {
37
   .login-card-right {
37
-    background: #EFF6FA;
38
+    // background: #EFF6FA;
38
   }
39
   }
39
 
40
 
40
   .login-form-box {
41
   .login-form-box {

+ 98
- 0
src/pages/org/components/Form.jsx Vedi File

1
+import React from 'react';
2
+import { Button, Card, Form, Input, Select } from 'antd';
3
+import useBool from '@/utils/hooks/useBool';
4
+import { postSysOrg, putSysOrg, getSysOrgById } from "@/service/sysorg";
5
+import { formItemLayout, tailFormItemLayout } from '@/utils/form';
6
+
7
+export default (props) => {
8
+  const { org, list, parentId, onChange } = props;
9
+
10
+  const [submiting, startSubmit, cancelSubmit] = useBool();
11
+  const [form] = Form.useForm();
12
+  
13
+  const onFinish = (values) => {
14
+    startSubmit();
15
+    if (org?.orgId) {
16
+      // 修改
17
+      putSysOrg(org.orgId, values).then((res) => {
18
+        cancelSubmit();
19
+        onChange(res);
20
+      }).catch(() => {
21
+        cancelSubmit();
22
+      });
23
+    } else {
24
+      // 新增
25
+      postSysOrg(values).then((res) => {
26
+        cancelSubmit();
27
+        onChange(res);
28
+      }).catch(() => {
29
+        cancelSubmit();
30
+      });
31
+    }
32
+  }
33
+
34
+  React.useEffect(() => {
35
+    if (org) {
36
+      form.setFieldsValue(org);
37
+    } else {
38
+      form.resetFields();
39
+      form.setFieldValue('orgPId', parentId);
40
+    }
41
+
42
+    console.log(org, parentId);
43
+  }, [org, parentId]);
44
+
45
+  return (
46
+    <Form onFinish={onFinish} form={form} {...formItemLayout} style={{width: '800px'}}>
47
+      <Form.Item
48
+        name="name"
49
+        label="机构名称"
50
+        rules={[
51
+          {required: true, message: '请填写机构名称'}
52
+        ]}
53
+      >
54
+        <Input />
55
+      </Form.Item>
56
+      <Form.Item
57
+        name="orgPId"
58
+        label="上级单位"
59
+      >
60
+        <Select>
61
+          {
62
+            (list || []).map(x => (
63
+              <Select.Option key={x.orgId}>
64
+                {x.name}
65
+              </Select.Option>
66
+            ))
67
+          }
68
+        </Select>
69
+      </Form.Item>
70
+
71
+      <Form.Item
72
+        name="sortNo"
73
+        label="排序"
74
+      >
75
+        <Input />
76
+      </Form.Item>
77
+
78
+
79
+      <Form.Item
80
+        name="status"
81
+        label="状态"
82
+      >
83
+        <Select
84
+          style={{ width: '100%' }}
85
+          placeholder="请选择状态"
86
+        >
87
+          <Option value={0}>不正常</Option>
88
+          <Option value={1}>正常</Option>
89
+        </Select>
90
+      </Form.Item>
91
+      <Form.Item {...tailFormItemLayout}>
92
+        <Button loading={submiting} type="primary" htmlType="submit">
93
+          保存
94
+        </Button>
95
+      </Form.Item>
96
+    </Form>
97
+  )
98
+}

+ 0
- 131
src/pages/org/edit/index.jsx Vedi File

1
-import React, { useEffect, useState } from 'react';
2
-import { Button, Card, Form, Input, Select } from 'antd';
3
-import useBool from '@/utils/hooks/useBool';
4
-import { postSysOrg, putSysOrg, getSysOrgById } from "@/service/sysorg";
5
-import { useSearchParams, useNavigate } from 'react-router-dom';
6
-
7
-const formItemLayout = {
8
-  labelCol: {
9
-    xs: { span: 24 },
10
-    sm: { span: 8 },
11
-  },
12
-  wrapperCol: {
13
-    xs: { span: 24 },
14
-    sm: { span: 16 },
15
-  },
16
-};
17
-const tailFormItemLayout = {
18
-  wrapperCol: {
19
-    xs: {
20
-      span: 24,
21
-      offset: 0,
22
-    },
23
-    sm: {
24
-      span: 16,
25
-      offset: 8,
26
-    },
27
-  },
28
-};
29
-
30
-const { Option } = Select;
31
-
32
-export default (props) => {
33
-
34
-  const [loading, startLoading, cancelLoading] = useBool();
35
-  const [submiting, startSubmit, cancelSubmit] = useBool();
36
-  const [form] = Form.useForm();
37
-  const navigate = useNavigate();
38
-  const [searchParams, setSearchParams] = useSearchParams();
39
-  const id = searchParams.get("id");
40
-
41
-  useEffect(() => {
42
-    if (id) {
43
-      getSysOrgById(id).then((res) => {
44
-        form.setFieldsValue(res);
45
-        // setDate(res);
46
-      });
47
-    }
48
-  }, [id]);
49
-
50
-  const onFinish = (values) => {
51
-    startSubmit();
52
-    if (id) {
53
-      // 修改
54
-      putSysOrg(id, values).then((res) => {
55
-        navigate(-1);
56
-      }).catch(() => {
57
-        cancelSubmit();
58
-      });
59
-    } else {
60
-      // 新增
61
-      postSysOrg(values).then((res) => {
62
-        navigate(-1);
63
-      }).catch(() => {
64
-        cancelSubmit();
65
-      });
66
-    }
67
-  }
68
-
69
-
70
-  return (
71
-    <Card loading={loading}>
72
-      <Form onFinish={onFinish} form={form} {...formItemLayout} scrollToFirstError style={{ maxWidth: '1000px' }}>
73
-        <Form.Item
74
-          name="orgCode"
75
-          label="机构编码"
76
-        >
77
-          <Input />
78
-        </Form.Item>
79
-        <Form.Item
80
-          name="name"
81
-          label="机构名称"
82
-        >
83
-          <Input />
84
-        </Form.Item>
85
-        <Form.Item
86
-          name="orgPId"
87
-          label="上级单位"
88
-        >
89
-          <Input />
90
-        </Form.Item>
91
-
92
-        <Form.Item
93
-          name="sortNo"
94
-          label="排序"
95
-        >
96
-          <Input />
97
-        </Form.Item>
98
-
99
-
100
-        <Form.Item
101
-          name="status"
102
-          label="状态"
103
-        >
104
-          <Select
105
-            style={{ width: '100%' }}
106
-            placeholder="请选择状态"
107
-          >
108
-            <Option key={0}>不正常</Option>
109
-            <Option key={1}>正常</Option>
110
-          </Select>
111
-        </Form.Item>
112
-        <Form.Item
113
-          name="createUser"
114
-          label="创建人"
115
-        >
116
-          <Input />
117
-        </Form.Item>
118
-        <Form.Item {...tailFormItemLayout}>
119
-          <Button loading={submiting} type="primary" htmlType="submit">
120
-            保存
121
-          </Button>
122
-          <Button style={{ marginLeft: '2em' }} onClick={() => navigate(-1)}>
123
-            返回
124
-          </Button>
125
-        </Form.Item>
126
-      </Form>
127
-    </Card>
128
-  )
129
-}
130
-
131
-

+ 116
- 0
src/pages/org/index.jsx Vedi File

1
+import React from 'react';
2
+import {
3
+  PlusOutlined,
4
+  DeleteOutlined,
5
+} from '@ant-design/icons';
6
+import { Button, Card, Row, Col, Tree, Tooltip, Popconfirm } from "antd";
7
+import Page from '@/components/Page';
8
+import { getSysOrg, deleteSysOrg } from "@/service/sysorg";
9
+import { arr2Tree } from '@/utils/array';
10
+import useBool from '@/utils/hooks/useBool';
11
+import Form from './components/Form';
12
+
13
+export default (props) => {
14
+
15
+  const [loading, startLoading, stopLoading] = useBool();
16
+  const [list, setList] = React.useState([]);
17
+  const [current, setCurrernt] = React.useState();
18
+  const [parentId, setParentId] = React.useState('-1');
19
+
20
+  const [parentList, treeData] = React.useMemo(() => {
21
+    const plist = [{orgId: '-1', name: '根节点'}].concat(list);
22
+    const [tree] = arr2Tree((list || []).map(x => ({
23
+      title: x.name,
24
+      key: x.orgId,
25
+      parentId: x.orgPId,
26
+      raw: x,
27
+    })));
28
+
29
+    return [plist, tree];
30
+  }, [list])
31
+
32
+  const changeCurrent = (org) => {
33
+    setCurrernt(org);
34
+    setParentId(org?.orgPId || '-1');
35
+  }
36
+
37
+  const onSelect = (selectedKeys, e) => {
38
+    changeCurrent(e.node.raw)
39
+  }
40
+
41
+  const onClick = (org) => {
42
+    changeCurrent(org);
43
+  }
44
+
45
+  const onAdd = (parent = '-1') => {
46
+    setParentId(parent);
47
+    setCurrernt();
48
+  }
49
+
50
+  const onDelete = (org) => {
51
+    deleteSysOrg(org.orgId).then(() => {
52
+      setList(list.filter(x => x.orgId !== org.orgId))
53
+    });
54
+  }
55
+
56
+  const queryList = React.useCallback(() => {
57
+    getSysOrg({pageSize: 500}).then(res => {
58
+      setList(res.records || []);
59
+      changeCurrent();
60
+    });
61
+  }, []);
62
+
63
+  const onFormChange = () => {
64
+    // 重新查一次数据
65
+    queryList();
66
+  }
67
+
68
+  React.useEffect(() => {
69
+    queryList();
70
+  }, []);
71
+
72
+  return (
73
+    <Page>
74
+      <Row gutter={24}>
75
+        <Col span={8}>
76
+          <Card
77
+            title="单位"
78
+            onSelect={onSelect}
79
+            extra={<Button type='link' onClick={() => onAdd()}>新增</Button>}
80
+          >
81
+            <Tree
82
+              blockNode
83
+              treeData={treeData}
84
+              // onSelect={onSelect}
85
+              titleRender={(node) => (
86
+                <div style={{display: 'flex'}} onClick={e => e.stopPropagation()}>
87
+                  <div style={{lineHeight: '32px', flex: 1}} onClick={() => onClick(node.raw)}>
88
+                    {node.title}
89
+                  </div>
90
+                  <div style={{width: '80px', flex: 'none'}}>
91
+                    <Tooltip title="新增子节点">
92
+                      <Button type='link' icon={<PlusOutlined />} onClick={() => onAdd(node.raw.orgId)}></Button>
93
+                    </Tooltip>
94
+                    <Tooltip title="删除节点">
95
+                      <Popconfirm
96
+                        title="确认进行删除操作?"
97
+                        onConfirm={() => onDelete(node.raw)}
98
+                      >
99
+                        <Button type='link' danger icon={<DeleteOutlined />}></Button>
100
+                      </Popconfirm>
101
+                    </Tooltip>
102
+                  </div>
103
+                </div>
104
+              )}
105
+            />
106
+          </Card>
107
+        </Col>
108
+        <Col span={16}>
109
+          <Card>
110
+            <Form org={current} parentId={parentId} list={parentList} onChange={onFormChange} />
111
+          </Card>
112
+        </Col>
113
+      </Row>
114
+    </Page>
115
+  )
116
+}

+ 0
- 137
src/pages/org/list/index.jsx Vedi File

1
-import React from "react";
2
-import { useNavigate } from "react-router-dom";
3
-import { queryTable } from "@/utils/request";
4
-import { ProTable } from "@ant-design/pro-components";
5
-import { Button, message, Popconfirm } from "antd";
6
-import { getSysOrg, deleteSysOrg } from "@/service/sysorg";
7
-
8
-const querySysOrgList = queryTable(getSysOrg);
9
-
10
-export default (props) => {
11
-  const actionRef = React.useRef();
12
-  const navigate = useNavigate();
13
-
14
-  // const updateStatus = (user) => {
15
-  //   const status = user.status === 1 ? 0 : 1;
16
-  //   const hide = message.loading("请稍候...", 0);
17
-  //   updateUserStatus(user.id, status)
18
-  //     .then((res) => {
19
-  //       hide();
20
-  //       actionRef.current.reload();
21
-  //     })
22
-  //     .catch(() => {
23
-  //       hide();
24
-  //     });
25
-  // };
26
-  const handleDelete = (id) => {
27
-    if (id) {
28
-      deleteSysOrg(id).then((res) => {
29
-        actionRef.current.reload();
30
-      });
31
-    }
32
-  };
33
-
34
-  const columns = [
35
-    {
36
-      title: "机构ID",
37
-      dataIndex: "orgId",
38
-    },
39
-    {
40
-      title: "机构编码",
41
-      dataIndex: "orgCode",
42
-    },
43
-    {
44
-      title: "机构名称",
45
-      dataIndex: "name",
46
-    },
47
-    {
48
-      title: "上级单位",
49
-      dataIndex: "orgPId",
50
-    },
51
-
52
-    {
53
-      title: "排序",
54
-      dataIndex: "sortNo",
55
-    },
56
-
57
-    {
58
-      title: "状态",
59
-      dataIndex: "status",
60
-      valueEnum: {
61
-        1: {
62
-          text: "正常",
63
-          status: "Processing",
64
-        },
65
-        0: {
66
-          text: "禁用",
67
-          status: "Error",
68
-        },
69
-      },
70
-    },
71
-    {
72
-      title: "创建人",
73
-      dataIndex: "createUser",
74
-    },
75
-    {
76
-      title: "操作",
77
-      valueType: "option",
78
-      width: 200,
79
-      render: (_, record) => [
80
-        // <Button
81
-        //   key={1}
82
-        //   style={{ padding: 0 }}
83
-        //   type="link"
84
-        //   onClick={() => {
85
-        //     updateStatus(record);
86
-        //   }}
87
-        // >
88
-        //   {record.status === 1 ? "禁用" : "启用"}
89
-        // </Button>,
90
-        <Button
91
-          key={2}
92
-          style={{ padding: 0 }}
93
-          type="link"
94
-          onClick={() => {
95
-            console.log(record, "]]");
96
-            navigate(`/system/org/edit?id=${record.orgId}`);
97
-          }}
98
-        >
99
-          编辑
100
-        </Button>,
101
-        <Popconfirm
102
-          key={3}
103
-          title="您是否确认删除 ?"
104
-          onConfirm={() => handleDelete(record.orgId)}
105
-          okText="确定"
106
-          cancelText="取消"
107
-        >
108
-          {/* manualPush */}
109
-          <Button style={{ padding: 0 }} type="link">
110
-            删除
111
-          </Button>
112
-        </Popconfirm>,
113
-      ],
114
-    },
115
-  ];
116
-
117
-  return (
118
-    <ProTable
119
-      actionRef={actionRef}
120
-      rowKey="orgId"
121
-      search={false}
122
-      toolBarRender={() => [
123
-        <Button
124
-          key="1"
125
-          type="primary"
126
-          onClick={() => {
127
-            navigate("/system/org/edit");
128
-          }}
129
-        >
130
-          新增
131
-        </Button>,
132
-      ]}
133
-      request={querySysOrgList}
134
-      columns={columns}
135
-    />
136
-  );
137
-};

+ 20
- 42
src/pages/position/edit/index.jsx Vedi File

2
 import { Button, Card, Form, Input, Select } from 'antd';
2
 import { Button, Card, Form, Input, Select } from 'antd';
3
 import useBool from '@/utils/hooks/useBool';
3
 import useBool from '@/utils/hooks/useBool';
4
 import { getSysPosition, postSysPosition, putSysPosition, getSysPositionById } from "@/service/sysposition";
4
 import { getSysPosition, postSysPosition, putSysPosition, getSysPositionById } from "@/service/sysposition";
5
+import { getSysOrg } from '@/service/sysorg';
5
 import { useSearchParams, useNavigate } from 'react-router-dom';
6
 import { useSearchParams, useNavigate } from 'react-router-dom';
6
-
7
-const formItemLayout = {
8
-  labelCol: {
9
-    xs: { span: 24 },
10
-    sm: { span: 8 },
11
-  },
12
-  wrapperCol: {
13
-    xs: { span: 24 },
14
-    sm: { span: 16 },
15
-  },
16
-};
17
-const tailFormItemLayout = {
18
-  wrapperCol: {
19
-    xs: {
20
-      span: 24,
21
-      offset: 0,
22
-    },
23
-    sm: {
24
-      span: 16,
25
-      offset: 8,
26
-    },
27
-  },
28
-};
7
+import { formItemLayout, tailFormItemLayout } from '@/utils/form';
29
 
8
 
30
 const { Option } = Select;
9
 const { Option } = Select;
31
 export default (props) => {
10
 export default (props) => {
37
   const actionRef = useRef();
16
   const actionRef = useRef();
38
   const [searchParams, setSearchParams] = useSearchParams();
17
   const [searchParams, setSearchParams] = useSearchParams();
39
   const id = searchParams.get("id");
18
   const id = searchParams.get("id");
40
-  const [sysPositionList, setSysPositionList] = useState([]);
19
+  const [positionList, setPositionList] = useState([]);
20
+  const [orgList, setOrgList] = useState([]);
41
 
21
 
42
   useEffect(() => {
22
   useEffect(() => {
43
     if (id) {
23
     if (id) {
49
 
29
 
50
   useEffect(() => {
30
   useEffect(() => {
51
     getSysPosition({ pageSize: 999 }).then((res) => {
31
     getSysPosition({ pageSize: 999 }).then((res) => {
52
-      console.log('res', res.records);
53
-      setSysPositionList(res.records);
32
+      setPositionList(res.records || []);
33
+    })
34
+    getSysOrg({ pageSize: 999 }).then((res) => {
35
+      setOrgList(res.records || []);
54
     })
36
     })
55
   }, [])
37
   }, [])
56
 
38
 
75
     }
57
     }
76
   }
58
   }
77
 
59
 
78
-
79
-  console.log('tiantian', sysPositionList);
80
-
81
-
82
   return (
60
   return (
83
     <Card loading={loading}>
61
     <Card loading={loading}>
84
       <Form onFinish={onFinish} form={form} {...formItemLayout} scrollToFirstError style={{ maxWidth: '1000px' }}>
62
       <Form onFinish={onFinish} form={form} {...formItemLayout} scrollToFirstError style={{ maxWidth: '1000px' }}>
92
           name="positionPId"
70
           name="positionPId"
93
           label="上级岗位"
71
           label="上级岗位"
94
         >
72
         >
95
-          <Input />
73
+          <Select allowClear>
74
+            {positionList.map((item) => (
75
+              <Option value={item.positionId} key={item.positionId}>
76
+                {item.name}
77
+              </Option>
78
+            ))}
79
+          </Select>
96
         </Form.Item>
80
         </Form.Item>
97
         <Form.Item
81
         <Form.Item
98
           name="orgId"
82
           name="orgId"
99
           label="所属单位"
83
           label="所属单位"
100
         >
84
         >
101
           <Select allowClear>
85
           <Select allowClear>
102
-            {sysPositionList.map((item) => (
103
-              <Option value={item.positionId} key={item.positionId}>
104
-                {item.orgId}
86
+            {orgList.map((item) => (
87
+              <Option value={item.orgId} key={item.orgId}>
88
+                {item.name}
105
               </Option>
89
               </Option>
106
             ))}
90
             ))}
107
           </Select>
91
           </Select>
120
             style={{ width: '100%' }}
104
             style={{ width: '100%' }}
121
             placeholder="请选择状态"
105
             placeholder="请选择状态"
122
           >
106
           >
123
-            <Option key={0}>不正常</Option>
124
-            <Option key={1}>正常</Option>
107
+            <Option value={0}>不正常</Option>
108
+            <Option value={1}>正常</Option>
125
           </Select>
109
           </Select>
126
         </Form.Item>
110
         </Form.Item>
127
-        <Form.Item
128
-          name="createUser"
129
-          label="创建人"
130
-        >
131
-          <Input />
132
-        </Form.Item>
133
         <Form.Item {...tailFormItemLayout}>
111
         <Form.Item {...tailFormItemLayout}>
134
           <Button loading={submiting} type="primary" htmlType="submit">
112
           <Button loading={submiting} type="primary" htmlType="submit">
135
             保存
113
             保存

+ 5
- 13
src/pages/position/list/index.jsx Vedi File

1
 import React from "react";
1
 import React from "react";
2
 import { useNavigate } from "react-router-dom";
2
 import { useNavigate } from "react-router-dom";
3
-import { queryTable } from "@/utils/request";
3
+import { queryTable, queryDict } from "@/utils/request";
4
 import { ProTable } from "@ant-design/pro-components";
4
 import { ProTable } from "@ant-design/pro-components";
5
 import { Button, message, Popconfirm } from "antd";
5
 import { Button, message, Popconfirm } from "antd";
6
 import { getSysPosition, deleteSysPosition } from "@/service/sysposition";
6
 import { getSysPosition, deleteSysPosition } from "@/service/sysposition";
7
+import { getSysOrg } from "@/service/sysorg";
7
 
8
 
8
 const querySysPositionList = queryTable(getSysPosition);
9
 const querySysPositionList = queryTable(getSysPosition);
10
+const queryOrg = queryDict(getSysOrg, {labelKey: 'name', valueKey: 'orgId'})
9
 
11
 
10
 export default (props) => {
12
 export default (props) => {
11
   const actionRef = React.useRef();
13
   const actionRef = React.useRef();
32
   };
34
   };
33
 
35
 
34
   const columns = [
36
   const columns = [
35
-    {
36
-      title: "岗位ID",
37
-      dataIndex: "positionId",
38
-    },
39
     {
37
     {
40
       title: "岗位名称",
38
       title: "岗位名称",
41
       dataIndex: "name",
39
       dataIndex: "name",
42
     },
40
     },
43
-    {
44
-      title: "上级岗位",
45
-      dataIndex: "positionPId",
46
-    },
47
     {
41
     {
48
       title: "所属单位",
42
       title: "所属单位",
49
       dataIndex: "orgId",
43
       dataIndex: "orgId",
44
+      valueType: 'select',
45
+      request: queryOrg,
50
     },
46
     },
51
 
47
 
52
     {
48
     {
67
         },
63
         },
68
       },
64
       },
69
     },
65
     },
70
-    {
71
-      title: "创建人",
72
-      dataIndex: "createUser",
73
-    },
74
     {
66
     {
75
       title: "操作",
67
       title: "操作",
76
       valueType: "option",
68
       valueType: "option",

+ 29
- 26
src/pages/user/Edit.jsx Vedi File

5
 import { postSysUser, getSysUserById } from '@/service/sysuser';
5
 import { postSysUser, getSysUserById } from '@/service/sysuser';
6
 import { useSearchParams, useNavigate } from 'react-router-dom';
6
 import { useSearchParams, useNavigate } from 'react-router-dom';
7
 import Page from '@/components/Page';
7
 import Page from '@/components/Page';
8
+import {formItemLayout, tailFormItemLayout} from '@/utils/form';
9
+import { getSysOrg } from '@/service/sysorg';
10
+import { getSysPosition } from '@/service/sysposition';
8
 import Account from './Account';
11
 import Account from './Account';
9
 
12
 
10
-const formItemLayout = {
11
-  labelCol: {
12
-    xs: { span: 24 },
13
-    sm: { span: 8 },
14
-  },
15
-  wrapperCol: {
16
-    xs: { span: 24 },
17
-    sm: { span: 16 },
18
-  },
19
-};
20
-const tailFormItemLayout = {
21
-  wrapperCol: {
22
-    xs: {
23
-      span: 24,
24
-      offset: 0,
25
-    },
26
-    sm: {
27
-      span: 16,
28
-      offset: 8,
29
-    },
30
-  },
31
-};
32
-
33
 const { Option } = Select;
13
 const { Option } = Select;
34
 
14
 
35
 export default (props) => {
15
 export default (props) => {
37
   const [submiting, startSubmit, cancelSubmit] = useBool();
17
   const [submiting, startSubmit, cancelSubmit] = useBool();
38
   const [open, setShow, setHidden] = useBool(false);
18
   const [open, setShow, setHidden] = useBool(false);
39
   const [roleList, setRoleList] = React.useState([]);
19
   const [roleList, setRoleList] = React.useState([]);
20
+  const [orgList, setOrgList] = React.useState([]);
21
+  const [org, setOrg] = React.useState();
22
+  const [posList, setPosList] = React.useState([]);
40
   const [searchParams] = useSearchParams();
23
   const [searchParams] = useSearchParams();
41
   const [form] = Form.useForm();
24
   const [form] = Form.useForm();
42
   const [user, setUser] = React.useState();
25
   const [user, setUser] = React.useState();
61
   }
44
   }
62
 
45
 
63
   React.useEffect(() => {
46
   React.useEffect(() => {
64
-    getSysRole({ pageSize: 500 }).then(res => setRoleList(res.records));
47
+    getSysRole({ pageSize: 500 }).then(res => setRoleList(res.records || []));
48
+    getSysOrg({ pageSize: 500 }).then(res => setOrgList(res.records || []));
65
   }, []);
49
   }, []);
50
+
51
+  React.useEffect(() => {
52
+    if (org) {
53
+      getSysPosition({orgId: org, pageSize: 500}).then(res => setPosList(res.records || []));
54
+    }
55
+  }, [org])
66
   
56
   
67
   React.useEffect(() => {
57
   React.useEffect(() => {
68
     if (id) {
58
     if (id) {
69
       startLoading();
59
       startLoading();
70
       getSysUserById(id).then(res => {
60
       getSysUserById(id).then(res => {
61
+        setOrg(res.orgId);
71
         setUser(res);
62
         setUser(res);
72
         form.setFieldsValue({
63
         form.setFieldsValue({
73
           ...res,
64
           ...res,
114
             name="orgId"
105
             name="orgId"
115
             label="单位"
106
             label="单位"
116
           >
107
           >
117
-            <Input />
108
+            <Select onChange={setOrg}>
109
+              {
110
+                orgList.map(x => (
111
+                  <Option key={x.orgId}>{x.name}</Option>
112
+                ))
113
+              }
114
+            </Select>
118
           </Form.Item>
115
           </Form.Item>
119
           <Form.Item
116
           <Form.Item
120
             name="positionId"
117
             name="positionId"
121
             label="岗位"
118
             label="岗位"
122
           >
119
           >
123
-            <Input />
120
+            <Select>
121
+              {
122
+                posList.map(x => (
123
+                  <Option key={x.positionId}>{x.name}</Option>
124
+                ))
125
+              }
126
+            </Select>
124
           </Form.Item>
127
           </Form.Item>
125
           <Form.Item
128
           <Form.Item
126
             name="rolesList"
129
             name="rolesList"

+ 9
- 1
src/pages/user/index.jsx Vedi File

1
 import React from "react";
1
 import React from "react";
2
 import { useNavigate } from "react-router-dom";
2
 import { useNavigate } from "react-router-dom";
3
-import { queryTable } from "@/utils/request";
3
+import { queryTable, queryDict } from "@/utils/request";
4
 import { ProTable } from "@ant-design/pro-components";
4
 import { ProTable } from "@ant-design/pro-components";
5
 import Page from "@/components/Page";
5
 import Page from "@/components/Page";
6
 import { Button, message, Popconfirm } from "antd";
6
 import { Button, message, Popconfirm } from "antd";
7
 import { getSysUser, updateUserStatus, deleteSysUser } from "@/service/sysuser";
7
 import { getSysUser, updateUserStatus, deleteSysUser } from "@/service/sysuser";
8
+import { getSysOrg } from "@/service/sysorg";
9
+import { getSysPosition } from "@/service/sysposition";
8
 
10
 
9
 const queryUserList = queryTable(getSysUser);
11
 const queryUserList = queryTable(getSysUser);
12
+const queryOrg = queryDict(getSysOrg, {labelKey: 'name', valueKey: 'orgId'});
13
+const queryPosition = queryDict(getSysPosition, {labelKey: 'name', valueKey: 'positionId'})
10
 
14
 
11
 export default (props) => {
15
 export default (props) => {
12
   const actionRef = React.useRef();
16
   const actionRef = React.useRef();
36
     {
40
     {
37
       title: "单位",
41
       title: "单位",
38
       dataIndex: "orgId",
42
       dataIndex: "orgId",
43
+      valueType: 'select',
44
+      request: queryOrg,
39
     },
45
     },
40
     {
46
     {
41
       title: "姓名",
47
       title: "姓名",
48
     {
54
     {
49
       title: "岗位",
55
       title: "岗位",
50
       dataIndex: "positionId",
56
       dataIndex: "positionId",
57
+      valueType: 'select',
58
+      request: queryPosition,
51
     },
59
     },
52
     {
60
     {
53
       title: "状态",
61
       title: "状态",

+ 3
- 13
src/routes/routes.jsx Vedi File

17
 import UserEdit from '@/pages/user/Edit';
17
 import UserEdit from '@/pages/user/Edit';
18
 import CheckList from '@/pages/check';
18
 import CheckList from '@/pages/check';
19
 import CheckEdit from '@/pages/check/Edit';
19
 import CheckEdit from '@/pages/check/Edit';
20
+import OrgList from "@/pages/org/index";
20
 
21
 
21
 import Index from '@/pages/index';
22
 import Index from '@/pages/index';
22
 import Home from "@/pages/sample/home";
23
 import Home from "@/pages/sample/home";
23
 import BasicForm from '@/pages/sample/form';
24
 import BasicForm from '@/pages/sample/form';
24
 import BasicTable from '@/pages/sample/table';
25
 import BasicTable from '@/pages/sample/table';
25
-import OrgList from "@/pages/org/list";
26
-import OrgEdit from "@/pages/org/edit";
26
+
27
 import PositionList from "@/pages/position/list";
27
 import PositionList from "@/pages/position/list";
28
 import PositionEdit from "@/pages/position/edit";
28
 import PositionEdit from "@/pages/position/edit";
29
 import LocTypeList from "@/pages/locType/list";
29
 import LocTypeList from "@/pages/locType/list";
88
         },
88
         },
89
       },
89
       },
90
       {
90
       {
91
-        path: "org/list",
91
+        path: "org",
92
         element: <OrgList />,
92
         element: <OrgList />,
93
         meta: {
93
         meta: {
94
           title: '机构管理',
94
           title: '机构管理',
96
           // permission: 'form',
96
           // permission: 'form',
97
         },
97
         },
98
       },
98
       },
99
-      {
100
-        path: "org/edit",
101
-        element: <OrgEdit />,
102
-        meta: {
103
-          hideInMenu: true,
104
-          title: '机构管理编辑',
105
-          // icon: <AppstoreOutlined />,
106
-          // permission: 'form',
107
-        },
108
-      },
109
       {
99
       {
110
         path: "position/list",
100
         path: "position/list",
111
         element: <PositionList />,
101
         element: <PositionList />,

+ 1
- 1
src/utils/hooks/useBool.js Vedi File

1
 import React from "react";
1
 import React from "react";
2
 
2
 
3
-export default function useLoading(initial = false) {
3
+export default function useBool(initial = false) {
4
   const [loading, setLoading] = React.useState(initial);
4
   const [loading, setLoading] = React.useState(initial);
5
   const loadingRef = React.useRef();
5
   const loadingRef = React.useRef();
6
   loadingRef.current = loading;
6
   loadingRef.current = loading;

+ 2
- 2
src/utils/request.js Vedi File

103
   };
103
   };
104
 }
104
 }
105
 
105
 
106
-export function queryDict (apiRequest) {
107
-  return function (params, labelKey = 'name', valueKey = 'id') {
106
+export function queryDict (apiRequest, {labelKey = 'name', valueKey = 'id'}) {
107
+  return function (params) {
108
     const { current, pageSize, ...leftParams } = params || {};
108
     const { current, pageSize, ...leftParams } = params || {};
109
     return apiRequest({
109
     return apiRequest({
110
       pageSize: 9999,
110
       pageSize: 9999,

+ 1
- 1
vite.config.js Vedi File

8
     port: 3000,
8
     port: 3000,
9
     proxy: {
9
     proxy: {
10
       '/api': {
10
       '/api': {
11
-        target: 'http://192.168.89.147:9087',
11
+        target: 'http://localhost:9087',
12
         changeOrigin: true,
12
         changeOrigin: true,
13
       },
13
       },
14
     }
14
     }