zlisen 4 lat temu
rodzic
commit
613299bfd5
50 zmienionych plików z 6363 dodań i 549 usunięć
  1. 70
    1
      config/routes.js
  2. BIN
      src/assets/logo.png
  3. BIN
      src/assets/poster1.png
  4. BIN
      src/assets/poster2.png
  5. BIN
      src/assets/touxiang.jpg
  6. BIN
      src/assets/xiaochengxu.png
  7. BIN
      src/assets/yinhao.png
  8. 39
    0
      src/components/ModalButton/ModalButton.jsx
  9. 9
    0
      src/components/ModalButton/index.jsx
  10. 4
    5
      src/pages/carouselFigure/advertisingList.jsx
  11. 5
    7
      src/pages/carouselFigure/carouselFigureList.jsx
  12. 75
    80
      src/pages/carouselFigure/customImg/edit.jsx
  13. 3
    3
      src/pages/carouselFigure/customImg/list.jsx
  14. 181
    188
      src/pages/carouselFigure/editAdvertising.jsx
  15. 256
    265
      src/pages/carouselFigure/editCarousel.jsx
  16. 323
    0
      src/pages/customer/Customer/PublicCustomer/AssistConsultant/AssistConsultant.jsx
  17. 98
    0
      src/pages/customer/Customer/PublicCustomer/AssistConsultant/Attribution.jsx
  18. 170
    0
      src/pages/customer/Customer/PublicCustomer/AssistConsultant/BatchAssistConsultant.jsx
  19. 77
    0
      src/pages/customer/Customer/PublicCustomer/AssistConsultant/ChangeStatus.jsx
  20. 140
    0
      src/pages/customer/Customer/PublicCustomer/AssistConsultant/IntegralRecord.jsx
  21. 285
    0
      src/pages/customer/Customer/PublicCustomer/AssistConsultant/Recommend.jsx
  22. 354
    0
      src/pages/news/list/NewsList.jsx
  23. 398
    0
      src/pages/news/list/editNewsList.jsx
  24. 119
    0
      src/pages/news/list/style.less
  25. 148
    0
      src/pages/news/type/NewsType.jsx
  26. 93
    0
      src/pages/news/type/editNews.jsx
  27. 56
    0
      src/pages/news/type/style.less
  28. 15
    0
      src/pages/staff/Organization/index.jsx
  29. 278
    0
      src/pages/staff/Role/Edit/index.jsx
  30. 148
    0
      src/pages/staff/Role/List/index.jsx
  31. 129
    0
      src/pages/staff/components/BatchAssistConsultant.jsx
  32. 58
    0
      src/pages/staff/components/BuildingSelection.jsx
  33. 115
    0
      src/pages/staff/components/CustomerChange.jsx
  34. 83
    0
      src/pages/staff/components/Tagss.jsx
  35. 140
    0
      src/pages/staff/components/attribution.jsx
  36. 24
    0
      src/pages/staff/components/style.less
  37. 149
    0
      src/pages/staff/list/RoleList.jsx
  38. 284
    0
      src/pages/staff/list/StaffList.jsx
  39. 280
    0
      src/pages/staff/list/addRole.jsx
  40. 64
    0
      src/pages/staff/list/channelList.less
  41. 159
    0
      src/pages/staff/list/distribution.jsx
  42. 203
    0
      src/pages/staff/list/editRole.jsx
  43. 324
    0
      src/pages/staff/list/editStaff.jsx
  44. 56
    0
      src/pages/staff/list/index.jsx
  45. 82
    0
      src/pages/staff/list/style.less
  46. 314
    0
      src/pages/staff/staff/Edit/index.jsx
  47. 125
    0
      src/pages/staff/staff/components/BatchAssistConsultant.jsx
  48. 58
    0
      src/pages/staff/staff/components/BuildingSelection.jsx
  49. 113
    0
      src/pages/staff/staff/components/CustomerChange.jsx
  50. 259
    0
      src/pages/staff/staff/list/index.jsx

+ 70
- 1
config/routes.js Wyświetl plik

@@ -138,8 +138,77 @@ export default [
138 138
               },
139 139
             ],
140 140
           },
141
+          {
142
+            path: '/staff',
143
+            name: '员工管理',
144
+            component: '../layouts/BlankLayout',
145
+            routes: [
146
+              {
147
+                path: '/staff/Staff/List',
148
+                name: '员工列表',
149
+                component: './staff/Staff/List',
150
+              },
151
+              {
152
+                path: '/staff/Staff/Edit',
153
+                name: '编辑员工',
154
+                hideInMenu: true,
155
+                component: './staff/Staff/Edit',
156
+              },
157
+              {
158
+                path: '/staff/Role/List',
159
+                name: '角色管理',
160
+                component: './staff/Role/List',
161
+              },
162
+              {
163
+                path: '/staff/Role/Edit',
164
+                name: '编辑角色',
165
+                hideInMenu: true,
166
+                component: './staff/Role/Edit',
167
+              },
168
+              {
169
+                path: '/staff/Organization/List',
170
+                name: '组织架构',
171
+                component: './staff/Organization',
172
+              },
173
+         
141 174
 
142
-
175
+              // {
176
+              //   path: '/staff/list/distribution',
177
+              //   name: '分配归属',
178
+              //   hideInMenu: true,
179
+              //   component: './staff/list/distribution',
180
+              // },
181
+            ],
182
+          },
183
+          {
184
+            path: '/news',
185
+            name: '资讯管理',
186
+            component: '../layouts/BlankLayout',
187
+            routes: [
188
+              {
189
+                path: '/news/type/NewsType',
190
+                name: '资讯类型',
191
+                component: './news/type/NewsType',
192
+              },
193
+              {
194
+                path: '/news/type/editNews',
195
+                name: '编辑资讯类型',
196
+                hideInMenu: true,
197
+                component: './news/type/editNews',
198
+              },
199
+              {
200
+                path: '/news/list/NewsList',
201
+                name: '资讯列表',
202
+                component: './news/list/NewsList',
203
+              },
204
+              {
205
+                path: '/news/list/editNewsList',
206
+                name: '编辑资讯',
207
+                hideInMenu: true,
208
+                component: './news/list/editNewsList',
209
+              },
210
+            ],
211
+          },
143 212
           {
144 213
             path: '/carouselFigure',
145 214
             name: '资源位管理',

BIN
src/assets/logo.png Wyświetl plik


BIN
src/assets/poster1.png Wyświetl plik


BIN
src/assets/poster2.png Wyświetl plik


BIN
src/assets/touxiang.jpg Wyświetl plik


BIN
src/assets/xiaochengxu.png Wyświetl plik


BIN
src/assets/yinhao.png Wyświetl plik


+ 39
- 0
src/components/ModalButton/ModalButton.jsx Wyświetl plik

@@ -0,0 +1,39 @@
1
+import React from 'react';
2
+import { Modal, Button, message } from 'antd';
3
+
4
+export default function ModalButton(props) {
5
+  const {
6
+    method = 'confirm',
7
+    title = '',
8
+    content = '',
9
+    modalConfigs = {},
10
+    onClick,
11
+    onCancel,
12
+    // 未选数据弹出提示
13
+    beforeCheck = '',
14
+    okText = '确认',
15
+    cancelText = '取消',
16
+    ...btnProps
17
+  } = props || {}
18
+
19
+  const handleClick = e => {
20
+    if (!!beforeCheck) { message.info(beforeCheck); return }
21
+    Modal[method]({
22
+      title,
23
+      content,
24
+      okText,
25
+      cancelText,
26
+      ...modalConfigs,
27
+      onOk() {
28
+        // eslint-disable-next-line no-unused-expressions
29
+        onClick && onClick(e);
30
+      },
31
+      onCancel() {
32
+        // eslint-disable-next-line no-unused-expressions
33
+        onCancel && onCancel();
34
+      },
35
+    })
36
+  }
37
+
38
+  return <Button {...btnProps} onClick={handleClick}>{props.children}</Button>
39
+}

+ 9
- 0
src/components/ModalButton/index.jsx Wyświetl plik

@@ -0,0 +1,9 @@
1
+import React from 'react';
2
+import ModalButton from './ModalButton';
3
+
4
+const ConfirmButton = props => <ModalButton {...props} method="confirm" />
5
+
6
+export {
7
+  ModalButton,
8
+  ConfirmButton,
9
+}

+ 4
- 5
src/pages/carouselFigure/advertisingList.jsx Wyświetl plik

@@ -1,5 +1,5 @@
1 1
 import React, { useState, useEffect } from 'react';
2
-import { Form, Button, Select, message, Table, Pagination, Modal, DatePicker } from 'antd';
2
+import { Form, Button, Select, message, Table, Pagination, Modal, Card } from 'antd';
3 3
 import router from 'umi/router';
4 4
 import moment from 'moment';
5 5
 import AuthButton from '@/components/AuthButton';
@@ -13,7 +13,6 @@ import request from '../../utils/request';
13 13
 import styles from '../style/GoodsList.less';
14 14
 
15 15
 const { Option } = Select;
16
-const { MonthPicker, RangePicker, WeekPicker } = DatePicker;
17 16
 
18 17
 const header = (props) => {
19 18
   const [data, setData] = useState({})
@@ -217,7 +216,7 @@ const header = (props) => {
217 216
   const { getFieldDecorator } = props.form
218 217
   return (
219 218
 
220
-    <>
219
+    <Card>
221 220
       <Form layout="inline" onSubmit={e => handleSubmit(e, props)}>
222 221
         <Form.Item>
223 222
           {getFieldDecorator('cityId')(
@@ -272,13 +271,13 @@ const header = (props) => {
272 271
         </Form.Item>
273 272
       </Form>
274 273
       <AuthButton name="admin.advert.post" noRight={null}>
275
-        <Button type="danger" className={styles.addBtn} onClick={toEdit()}>新增</Button>
274
+        <Button type='primary' onClick={toEdit()} style={{margin:'20px 0'}}>新增</Button>
276 275
       </AuthButton>
277 276
       <Table dataSource={data.records} columns={columns} pagination={false} rowKey="advertisingList" />
278 277
       <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '30px' }}>
279 278
         <Pagination showQuickJumper defaultCurrent={1} total={data.total} onChange={e => changePageNum(e, props)} current={data.current} />
280 279
       </div>
281
-    </>
280
+    </Card>
282 281
   )
283 282
 }
284 283
 const WrappedHeader = Form.create({ name: 'header' })(header);

+ 5
- 7
src/pages/carouselFigure/carouselFigureList.jsx Wyświetl plik

@@ -1,5 +1,5 @@
1 1
 import React, { useState, useEffect } from 'react';
2
-import { Form, Button, Select, message, Table, Pagination, Modal, DatePicker } from 'antd';
2
+import { Form, Button, Select, message, Table, Pagination, Modal, DatePicker, Card } from 'antd';
3 3
 import router from 'umi/router';
4 4
 import moment from 'moment';
5 5
 import AuthButton from '@/components/AuthButton';
@@ -13,11 +13,9 @@ import request from '../../utils/request';
13 13
 import styles from '../style/GoodsList.less';
14 14
 
15 15
 const { Option } = Select;
16
-const { MonthPicker, RangePicker, WeekPicker } = DatePicker;
17 16
 
18 17
 const header = (props) => {
19 18
   const [data, setData] = useState({})
20
-  //   const [page, changePage] = useState({})
21 19
 
22 20
   useEffect(() => {
23 21
     getList({ pageNum: 1, pageSize: 10, showType: 'banner' });
@@ -216,7 +214,7 @@ const header = (props) => {
216 214
   const { getFieldDecorator } = props.form
217 215
   return (
218 216
 
219
-    <>
217
+    <Card>
220 218
       <Form layout="inline" onSubmit={e => handleSubmit(e, props)}>
221 219
         <Form.Item>
222 220
           {getFieldDecorator('cityId')(
@@ -270,13 +268,13 @@ const header = (props) => {
270 268
         </Form.Item>
271 269
       </Form>
272 270
       <AuthButton name="admin.extendContent.post" noRight={null}>
273
-        <Button type="danger" className={styles.addBtn} onClick={toEditCarouse()}>新增</Button>
271
+        <Button type='primary' onClick={toEditCarouse()} style={{margin:'20px 0'}}>新增</Button>
274 272
       </AuthButton>
275
-      <Table dataSource={data.records} columns={columns} pagination={false} rowKey="carouseFigureList" />
273
+      <Table dataSource={data.records} columns={columns} pagination={false} rowKey="contentId" />
276 274
       <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '30px' }}>
277 275
         <Pagination showQuickJumper defaultCurrent={1} total={data.total} onChange={changePageNum} current={data.current} />
278 276
       </div>
279
-    </>
277
+    </Card>
280 278
   )
281 279
 }
282 280
 const WrappedHeader = Form.create({ name: 'header' })(header);

+ 75
- 80
src/pages/carouselFigure/customImg/edit.jsx Wyświetl plik

@@ -1,30 +1,23 @@
1 1
 import React, { useState, useEffect } from 'react';
2
-import { Input, Menu, Dropdown, Button, Icon, message, Table, Divider, Tag, Select, Form, Alert } from 'antd';
3
-import { FormattedMessage } from 'umi-plugin-react/locale';
4
-// import channels from '../../channel/channelList.less';
2
+import { Card, message, Form } from 'antd';
5 3
 import { connect } from 'dva';
6
-import BuildSelect from '../../../components/SelectButton/BuildSelect'
7 4
 import { createForm, FieldTypes } from '../../../components/XForm';
8
-import Wangedit from '../../../components/Wangedit/Wangedit'
9 5
 import router from 'umi/router';
10 6
 import apis from '../../../services/apis';
11
-import request from '../../../utils/request'
7
+import request from '../../../utils/request';
12 8
 
13
-const { TextArea } = Input;
14
-const { Option } = Select;
9
+let activityVisible = true;
10
+let helpTips = '';
15 11
 
16
-let activityVisible = true
17
-let helpTips = ''
18
-
19
-const setExtraData = (data) => {
20
-    activityVisible = data.imgType === 'index';
21
-  }
12
+const setExtraData = data => {
13
+  activityVisible = data.imgType === 'index';
14
+};
22 15
 
23 16
 const handleFormValueChange = (props, changedValues, allValues) => {
24
-    setExtraData(allValues)
25
-}
17
+  setExtraData(allValues);
18
+};
26 19
 
27
-const XForm = createForm({ onValuesChange: handleFormValueChange })
20
+const XForm = createForm({ onValuesChange: handleFormValueChange });
28 21
 
29 22
 const header = props => {
30 23
   const {
@@ -35,41 +28,43 @@ const header = props => {
35 28
     menu,
36 29
   } = props;
37 30
 
38
-  const imgId = props.location.query.imgId
39
-  const imgType = props.location.query.imgType
40
-
41
-  const [ data, setData ] = useState(imgType === 'index' ? 
42
-  {
43
-    'imgUrl':'https://estateagents.oss-cn-shanghai.aliyuncs.com/miniapp/upload/images/1574145199853-97feda7895c65be33aa234a7b81b37f.jpg',
44
-    'imgType':'index',
45
-    'imgDesc':'小程序首页分享配图',
46
-    'imgDocument': currentUser.orgName+' 精准获客平台'
47
-  } : 
48
-  {
49
-    'imgUrl':'http://njcj.oss-cn-shanghai.aliyuncs.com/icon.png',
50
-    'imgType':'indexNews',
51
-  }
52
-  )
31
+  const imgId = props.location.query.imgId;
32
+  const imgType = props.location.query.imgType;
33
+
34
+  const [data, setData] = useState(
35
+    imgType === 'index'
36
+      ? {
37
+          imgUrl:
38
+            'https://estateagents.oss-cn-shanghai.aliyuncs.com/miniapp/upload/images/1574145199853-97feda7895c65be33aa234a7b81b37f.jpg',
39
+          imgType: 'index',
40
+          imgDesc: '小程序首页分享配图',
41
+          imgDocument: currentUser.orgName + ' 精准获客平台',
42
+        }
43
+      : {
44
+          imgUrl: 'http://njcj.oss-cn-shanghai.aliyuncs.com/icon.png',
45
+          imgType: 'indexNews',
46
+        },
47
+  );
53 48
 
54
-  if(imgId){
49
+  if (imgId) {
55 50
     useEffect(() => {
56 51
       getData(imgId);
57
-    },[])
58
-
59
-  // 查询列表
60
-  const getData = (imgId) => {
61
-    request({ ...apis.carsuseFigure.getCustomImg, urlData: { id: imgId} }).then((data) => {
62
-        console.log(data)
63
-        if (data.imgType === 'index'){
64
-            activityVisible = true;
65
-            helpTips = '建议图片尺寸:750*600px,比例5:4,格式:jpg,用于:首页分享';
66
-        }else{
67
-            activityVisible = false;
68
-            helpTips = '建议尺寸:80*80px,比例1:1,格式:jpg,用于:首页资讯logo'
52
+    }, []);
53
+
54
+    // 查询列表
55
+    const getData = imgId => {
56
+      request({ ...apis.carsuseFigure.getCustomImg, urlData: { id: imgId } }).then(data => {
57
+        console.log(data);
58
+        if (data.imgType === 'index') {
59
+          activityVisible = true;
60
+          helpTips = '建议图片尺寸:750*600px,比例5:4,格式:jpg,用于:首页分享';
61
+        } else {
62
+          activityVisible = false;
63
+          helpTips = '建议尺寸:80*80px,比例1:1,格式:jpg,用于:首页资讯logo';
69 64
         }
70
-        setData(data)
71
-    })
72
-  }
65
+        setData(data);
66
+      });
67
+    };
73 68
   }
74 69
 
75 70
   const fields = [
@@ -79,16 +74,15 @@ const header = props => {
79 74
       type: FieldTypes.ImageUploader,
80 75
       value: data.imgUrl,
81 76
       help: helpTips,
82
-      rules: [
83
-        {required: true, message: '请选择图片'},
84
-      ]
77
+      rules: [{ required: true, message: '请选择图片' }],
85 78
     },
86 79
     {
87 80
       label: '类型',
88 81
       name: 'imgType',
89 82
       type: FieldTypes.Select,
90 83
       value: data.imgType,
91
-      dict: [{
84
+      dict: [
85
+        {
92 86
           label: '首页分享',
93 87
           value: 'index',
94 88
         },
@@ -97,52 +91,53 @@ const header = props => {
97 91
           value: 'indexNews',
98 92
         },
99 93
       ],
100
-      rules: [
101
-        { required: true, message: '请选择类型' },
102
-      ],
94
+      rules: [{ required: true, message: '请选择类型' }],
103 95
     },
104 96
     data.imgType === 'index' && {
105 97
       label: '分享文案',
106 98
       name: 'imgDocument',
107 99
       type: FieldTypes.Text,
108 100
       value: data.imgDocument,
109
-      rules: [
110
-        { required: true, message: '请输入分享文案' },
111
-      ],
101
+      rules: [{ required: true, message: '请输入分享文案' }],
112 102
     },
113
-  ]
103
+  ];
114 104
 
115 105
   const handleSubmit = values => {
116
-    
117 106
     if (imgId) {
118
-      values.imgId = imgId
119
-      request({ ...apis.carsuseFigure.updateCustomImg, data: values,}).then((data) => {
120
-        cancelPage()
121
-      }).catch((err) => {
122
-        message.info(err.msg || err.message)
123
-      })
124
-      }else{
125
-      request({ ...apis.carsuseFigure.addCustomImg, data: values,}).then((data) => {
126
-        cancelPage()
127
-      }).catch((err) => {
128
-        message.info(err.msg || err.message)
129
-      })
130
-      }
131
-  }
107
+      values.imgId = imgId;
108
+      request({ ...apis.carsuseFigure.updateCustomImg, data: values })
109
+        .then(data => {
110
+          cancelPage();
111
+        })
112
+        .catch(err => {
113
+          message.info(err.msg || err.message);
114
+        });
115
+    } else {
116
+      request({ ...apis.carsuseFigure.addCustomImg, data: values })
117
+        .then(data => {
118
+          cancelPage();
119
+        })
120
+        .catch(err => {
121
+          message.info(err.msg || err.message);
122
+        });
123
+    }
124
+  };
132 125
 
133 126
   const cancelPage = () => {
134 127
     router.push({
135
-        pathname: '/carouselFigure/customImg/list',
128
+      pathname: '/carouselFigure/customImg/list',
136 129
     });
137
-  }
130
+  };
138 131
 
139 132
   return (
140
-    <XForm onSubmit={handleSubmit} onCancel={cancelPage} fields={fields}></XForm>
141
-  )
142
-}
133
+    <Card>
134
+      <XForm onSubmit={handleSubmit} onCancel={cancelPage} fields={fields}></XForm>
135
+    </Card>
136
+  );
137
+};
143 138
 
144 139
 const WrappedNormalLoginForm = Form.create({ name: 'header' })(header);
145 140
 
146 141
 export default connect(({ user }) => ({
147 142
   currentUser: user.currentUser,
148
-}))(WrappedNormalLoginForm);
143
+}))(WrappedNormalLoginForm);

+ 3
- 3
src/pages/carouselFigure/customImg/list.jsx Wyświetl plik

@@ -1,5 +1,5 @@
1 1
 import React, { useState, useEffect } from 'react';
2
-import { Form, Table } from 'antd';
2
+import { Form, Table, Card } from 'antd';
3 3
 import router from 'umi/router';
4 4
 import AuthButton from '@/components/AuthButton';
5 5
 import withActions from '@/components/ActionList';
@@ -49,7 +49,7 @@ function header(props) {
49 49
   // const { getFieldDecorator } = props.form
50 50
   return (
51 51
 
52
-    <>
52
+    <Card>
53 53
       <Table dataSource={data}>
54 54
         <Column title="图片" dataIndex="imgUrl" key="imgUrl"
55 55
           render={(text, record) => (
@@ -73,7 +73,7 @@ function header(props) {
73 73
           ])}
74 74
         />
75 75
       </Table>,
76
-    </>
76
+    </Card>
77 77
   )
78 78
 }
79 79
 const WrappedHeader = Form.create({ name: 'header' })(header);

+ 181
- 188
src/pages/carouselFigure/editAdvertising.jsx Wyświetl plik

@@ -1,17 +1,14 @@
1 1
 import React, { useState, useEffect, useRef } from 'react';
2
-import { Modal, message } from 'antd';
3
-import { FormattedMessage } from 'umi-plugin-react/locale';
4
-import styles from '../style/GoodsList.less';
5
-import moment from 'moment';
2
+import { Card, message } from 'antd';
6 3
 import router from 'umi/router';
7
-import BuildSelect from '../../components/SelectButton/BuildSelect2'
8
-import CitySelect from '../../components/SelectButton/CitySelect2'
4
+import BuildSelect from '../../components/SelectButton/BuildSelect2';
5
+import CitySelect from '../../components/SelectButton/CitySelect2';
9 6
 import { FieldTypes, createForm } from '../../components/XForm';
10 7
 import Wangedit from '../../components/Wangedit/Wangedit';
11 8
 import SelectActivity from './SelectActivity';
12 9
 import SelectNews from './SelectNews';
13 10
 import apis from '../../services/apis';
14
-import request from '../../utils/request'
11
+import request from '../../utils/request';
15 12
 import SelectHelp from './SelectHelp';
16 13
 import SelectGroup from './SelectGroup';
17 14
 import SelectH5 from './SelectH5';
@@ -24,30 +21,30 @@ import LiveGroup from './LiveGroup';
24 21
  * @returns
25 22
  */
26 23
 const createEditor = () => {
27
-  let contentVisible = false
28
-  let activityVisible = false
29
-  let newsVisible = false
30
-  let helpVisible = false
31
-  let groupVisible = false
32
-  let salesBatchVisible = false
33
-  let liveVisible = false
34
-  let h5Visible = false
35
-  let buildingId = ''
36
-  let cityId = ''
37
-  let isHaveActive = false
38
-  let isCanChoose = true
39
-  let isHavePosition = false
40
-  let islet = true
24
+  let contentVisible = false;
25
+  let activityVisible = false;
26
+  let newsVisible = false;
27
+  let helpVisible = false;
28
+  let groupVisible = false;
29
+  let salesBatchVisible = false;
30
+  let liveVisible = false;
31
+  let h5Visible = false;
32
+  let buildingId = '';
33
+  let cityId = '';
34
+  let isHaveActive = false;
35
+  let isCanChoose = true;
36
+  let isHavePosition = false;
37
+  let islet = true;
41 38
 
42
-  const setExtraData = (data) => {
39
+  const setExtraData = data => {
43 40
     if (data.isHaveActive !== undefined) {
44
-      isHaveActive = data.isHaveActive
41
+      isHaveActive = data.isHaveActive;
45 42
       if (!isHaveActive) {
46 43
         // data.contentType=null
47
-        data.buildingId = null
44
+        data.buildingId = null;
48 45
       }
49 46
     }
50
-    islet = isHaveActive
47
+    islet = isHaveActive;
51 48
     if (data.showPosition == 'index') {
52 49
       isHavePosition = true;
53 50
     } else {
@@ -69,19 +66,24 @@ const createEditor = () => {
69 66
     liveVisible = data.contentType === 'live';
70 67
     h5Visible = data.contentType === 'h5';
71 68
 
72
-    cityId = data.cityId
69
+    cityId = data.cityId;
73 70
     // console.log(data.buildingId, ' data.buildingId')
74
-    buildingId = data.buildingId
75
-  }
71
+    buildingId = data.buildingId;
72
+  };
76 73
 
77 74
   const setExtraData1 = data => {
78
-    console.log(data, "data.buildingIddata.buildingId2")
79
-    islet = data.isHaveActive
75
+    console.log(data, 'data.buildingIddata.buildingId2');
76
+    islet = data.isHaveActive;
80 77
 
81
-    if ((data.contentType === 'h5' && data.buildingId == null) || data.contentType === '' || data.contentType === 'nothing' || (data.contentType === 'live' && data.buildingId == null)) {
82
-      isHaveActive = false
78
+    if (
79
+      (data.contentType === 'h5' && data.buildingId == null) ||
80
+      data.contentType === '' ||
81
+      data.contentType === 'nothing' ||
82
+      (data.contentType === 'live' && data.buildingId == null)
83
+    ) {
84
+      isHaveActive = false;
83 85
     } else {
84
-      isHaveActive = true
86
+      isHaveActive = true;
85 87
     }
86 88
     // if (!isHaveActivea && data.contentType === 'h5') {
87 89
     //   // data.contentType=null
@@ -110,44 +112,44 @@ const createEditor = () => {
110 112
     liveVisible = data.contentType === 'live';
111 113
     h5Visible = data.contentType === 'h5';
112 114
 
113
-    console.log(data.buildingId, ' data.buildingId')
114
-    buildingId = data.buildingId
115
-  }
115
+    console.log(data.buildingId, ' data.buildingId');
116
+    buildingId = data.buildingId;
117
+  };
116 118
 
117 119
   const handleFormValueChange = (props, changedValues, allValues) => {
118
-    setExtraData(allValues)
119
-  }
120
+    setExtraData(allValues);
121
+  };
120 122
 
121
-  const XForm = createForm({ onValuesChange: handleFormValueChange })
123
+  const XForm = createForm({ onValuesChange: handleFormValueChange });
122 124
 
123
-  return (props) => {
125
+  return props => {
124 126
     // const [tab, changeTab] = useState('basic')
125
-    const contentId = props.location.query.contentId
126
-    const [data, setData] = useState({})
127
+    const contentId = props.location.query.contentId;
128
+    const [data, setData] = useState({});
127 129
     const formRef = useRef(null);
128 130
 
129 131
     // 查询列表
130 132
     const getDetail = contentId => {
131
-      request({ ...apis.carsuseFigure.getExtendContent, urlData: { id: contentId } }).then((data) => {
132
-        setExtraData1(data)
133
-        setData(data)
134
-      })
135
-    }
133
+      request({ ...apis.carsuseFigure.getExtendContent, urlData: { id: contentId } }).then(data => {
134
+        setExtraData1(data);
135
+        setData(data);
136
+      });
137
+    };
136 138
     useEffect(() => {
137 139
       if (contentId) {
138
-        isCanChoose = false
140
+        isCanChoose = false;
139 141
         getDetail(contentId);
140 142
       } else {
141
-        isCanChoose = true
143
+        isCanChoose = true;
142 144
       }
143
-    }, [])
145
+    }, []);
144 146
 
145 147
     const cancelPage = () => {
146
-      isCanChoose = true
148
+      isCanChoose = true;
147 149
       router.push({
148 150
         pathname: '/carouselFigure/advertisingList',
149 151
       });
150
-    }
152
+    };
151 153
 
152 154
     const fields = [
153 155
       {
@@ -158,34 +160,32 @@ const createEditor = () => {
158 160
         hidden: () => !isCanChoose,
159 161
         props: {
160 162
           onChange: () => {
161
-            const type = formRef.current.props.form.getFieldValue('contentType')
162
-            if (formRef.current && (type !== 'live' && type !== 'h5')) {
163
-              console.log(formRef.current.props.form.getFieldValue('contentType'), '2222')
163
+            const type = formRef.current.props.form.getFieldValue('contentType');
164
+            if (formRef.current && type !== 'live' && type !== 'h5') {
165
+              console.log(formRef.current.props.form.getFieldValue('contentType'), '2222');
164 166
               formRef.current.props.form.resetFields(['contentType', []]);
165 167
             }
166 168
           },
167 169
         },
168
-        rules: [
169
-          { required: true, message: '是否城市活动' },
170
-        ],
170
+        rules: [{ required: true, message: '是否城市活动' }],
171 171
       },
172 172
       {
173 173
         label: '发布位置',
174 174
         name: 'showPosition',
175 175
         type: FieldTypes.Select,
176 176
         value: isHaveActive,
177
-        dict: [{
178
-          label: '首页',
179
-          value: 'index',
180
-        },
181
-        {
182
-          label: '项目',
183
-          value: 'building',
184
-        }],
185
-        value: data.showPosition,
186
-        rules: [
187
-          { required: true, message: '请选择发布位置' },
177
+        dict: [
178
+          {
179
+            label: '首页',
180
+            value: 'index',
181
+          },
182
+          {
183
+            label: '项目',
184
+            value: 'building',
185
+          },
188 186
         ],
187
+        value: data.showPosition,
188
+        rules: [{ required: true, message: '请选择发布位置' }],
189 189
       },
190 190
       {
191 191
         label: '所属项目',
@@ -193,9 +193,7 @@ const createEditor = () => {
193 193
         render: <BuildSelect />,
194 194
         value: data.buildingId,
195 195
         hidden: () => !isHaveActive && isHavePosition,
196
-        rules: [
197
-          { required: true, message: '请选择所属项目' },
198
-        ],
196
+        rules: [{ required: true, message: '请选择所属项目' }],
199 197
       },
200 198
       {
201 199
         label: '展示城市',
@@ -203,9 +201,7 @@ const createEditor = () => {
203 201
         render: <CitySelect />,
204 202
         hidden: () => !isHavePosition || isHaveActive,
205 203
         value: data.cityId,
206
-        rules: [
207
-          { required: true, message: '请选择展示城市' },
208
-        ],
204
+        rules: [{ required: true, message: '请选择展示城市' }],
209 205
       },
210 206
       {
211 207
         label: '开屏广告',
@@ -213,31 +209,29 @@ const createEditor = () => {
213 209
         type: FieldTypes.ImageUploader,
214 210
         value: data.image,
215 211
         help: '建议图片尺寸:640*960px,比例2:3,格式:jpg,用于开屏广告',
216
-        rules: [
217
-          { required: true, message: '请上传图片' },
218
-        ],
212
+        rules: [{ required: true, message: '请上传图片' }],
219 213
       },
220 214
       {
221 215
         label: '类型',
222 216
         name: 'contentType',
223 217
         type: FieldTypes.Select,
224 218
         hidden: () => isHaveActive,
225
-        dict: [{
226
-          label: 'H5活动详情',
227
-          value: 'h5',
228
-        },
229
-        {
230
-          label: '直播活动详情',
231
-          value: 'live',
232
-        },
233
-        {
234
-          label: '其它',
235
-          value: 'others',
236
-        }],
237
-        value: data.contentType,
238
-        rules: [
239
-          { required: true, message: '请选择类型' },
219
+        dict: [
220
+          {
221
+            label: 'H5活动详情',
222
+            value: 'h5',
223
+          },
224
+          {
225
+            label: '直播活动详情',
226
+            value: 'live',
227
+          },
228
+          {
229
+            label: '其它',
230
+            value: 'others',
231
+          },
240 232
         ],
233
+        value: data.contentType,
234
+        rules: [{ required: true, message: '请选择类型' }],
241 235
       },
242 236
       {
243 237
         label: '标题',
@@ -245,65 +239,61 @@ const createEditor = () => {
245 239
         type: FieldTypes.Text,
246 240
         hidden: true,
247 241
         value: data.title,
248
-        rules: [
249
-          { required: true, message: '请输入标题' },
250
-        ],
242
+        rules: [{ required: true, message: '请输入标题' }],
251 243
       },
252 244
       {
253 245
         label: '类型',
254 246
         name: 'contentType',
255 247
         hidden: () => !isHaveActive,
256 248
         type: FieldTypes.Select,
257
-        dict: [{
258
-          label: '报名活动详情',
259
-          value: 'activity'
260
-        },
261
-        {
262
-          label: '项目详情',
263
-          value: 'project'
264
-        },
265
-        {
266
-          label: '资讯详情',
267
-          value: 'news'
268
-        },
269
-        {
270
-          label: '拼团活动详情',
271
-          value: 'group'
272
-        },
273
-        {
274
-          label: '助力活动详情',
275
-          value: 'help'
276
-        },
277
-        {
278
-          label: 'H5活动详情',
279
-          value: 'h5',
280
-        },
281
-        {
282
-          label: '在线选房详情',
283
-          value: 'salesBatch',
284
-        },
285
-        {
286
-          label: '直播活动详情',
287
-          value: 'live',
288
-        },
289
-        {
290
-          label: '其它',
291
-          value: 'others',
292
-        }],
293
-        value: data.contentType,
294
-        rules: [
295
-          { required: true, message: '请选择类型' },
249
+        dict: [
250
+          {
251
+            label: '报名活动详情',
252
+            value: 'activity',
253
+          },
254
+          {
255
+            label: '项目详情',
256
+            value: 'project',
257
+          },
258
+          {
259
+            label: '资讯详情',
260
+            value: 'news',
261
+          },
262
+          {
263
+            label: '拼团活动详情',
264
+            value: 'group',
265
+          },
266
+          {
267
+            label: '助力活动详情',
268
+            value: 'help',
269
+          },
270
+          {
271
+            label: 'H5活动详情',
272
+            value: 'h5',
273
+          },
274
+          {
275
+            label: '在线选房详情',
276
+            value: 'salesBatch',
277
+          },
278
+          {
279
+            label: '直播活动详情',
280
+            value: 'live',
281
+          },
282
+          {
283
+            label: '其它',
284
+            value: 'others',
285
+          },
296 286
         ],
287
+        value: data.contentType,
288
+        rules: [{ required: true, message: '请选择类型' }],
297 289
       },
298 290
       {
299 291
         label: '发布H5活动',
300 292
         name: 'targetId',
301
-        render: <SelectH5 buildingId={() => islet ? buildingId : ''} />,
293
+        render: <SelectH5 buildingId={() => (islet ? buildingId : '')} />,
302 294
         hidden: () => !h5Visible,
303 295
         value: data.targetId,
304
-        rules: [
305
-          { required: true, message: '请选择发布H5' },
306
-        ],
296
+        rules: [{ required: true, message: '请选择发布H5' }],
307 297
       },
308 298
       {
309 299
         label: '发布活动',
@@ -311,9 +301,7 @@ const createEditor = () => {
311 301
         render: <SelectActivity buildingId={() => buildingId} />,
312 302
         hidden: () => !activityVisible,
313 303
         value: data.targetId,
314
-        rules: [
315
-          { required: true, message: '请选择发布活动' },
316
-        ],
304
+        rules: [{ required: true, message: '请选择发布活动' }],
317 305
       },
318 306
       {
319 307
         label: '发布资讯',
@@ -321,9 +309,7 @@ const createEditor = () => {
321 309
         render: <SelectNews buildingId={() => buildingId} />,
322 310
         hidden: () => !newsVisible,
323 311
         value: data.targetId,
324
-        rules: [
325
-          { required: true, message: '请选择发布资讯' },
326
-        ],
312
+        rules: [{ required: true, message: '请选择发布资讯' }],
327 313
       },
328 314
       {
329 315
         label: '发布内容',
@@ -331,9 +317,7 @@ const createEditor = () => {
331 317
         render: <Wangedit />,
332 318
         value: data.content,
333 319
         hidden: () => !contentVisible,
334
-        rules: [
335
-          { required: true, message: '请选择发布内容' },
336
-        ],
320
+        rules: [{ required: true, message: '请选择发布内容' }],
337 321
       },
338 322
       {
339 323
         label: '发布助力',
@@ -341,9 +325,7 @@ const createEditor = () => {
341 325
         render: <SelectHelp buildingId={() => buildingId} />,
342 326
         hidden: () => !helpVisible,
343 327
         value: data.targetId,
344
-        rules: [
345
-          { required: true, message: '请选择发布助力' },
346
-        ],
328
+        rules: [{ required: true, message: '请选择发布助力' }],
347 329
       },
348 330
       {
349 331
         label: '发布拼团',
@@ -351,9 +333,7 @@ const createEditor = () => {
351 333
         render: <SelectGroup buildingId={() => buildingId} />,
352 334
         hidden: () => !groupVisible,
353 335
         value: data.targetId,
354
-        rules: [
355
-          { required: true, message: '请选择发布拼团' },
356
-        ],
336
+        rules: [{ required: true, message: '请选择发布拼团' }],
357 337
       },
358 338
       {
359 339
         label: '发布销售批次',
@@ -361,66 +341,79 @@ const createEditor = () => {
361 341
         render: <SalesBatchGroup buildingId={() => buildingId} />,
362 342
         hidden: () => !salesBatchVisible,
363 343
         value: data.targetId,
364
-        rules: [
365
-          { required: true, message: '请选择发布销售批次' },
366
-        ],
344
+        rules: [{ required: true, message: '请选择发布销售批次' }],
367 345
       },
368 346
       {
369 347
         label: '发布直播活动',
370 348
         name: 'targetId',
371
-        render: <LiveGroup buildingId={() => islet ? buildingId : ''} />,
349
+        render: <LiveGroup buildingId={() => (islet ? buildingId : '')} />,
372 350
         hidden: () => !liveVisible,
373 351
         value: data.targetId,
374
-        rules: [
375
-          { required: true, message: '请选择发布直播活动' },
376
-        ],
352
+        rules: [{ required: true, message: '请选择发布直播活动' }],
377 353
       },
378 354
       {
379 355
         label: '状态',
380 356
         name: 'status',
381 357
         type: FieldTypes.Select,
382
-        dict: [{
383
-          label: "上架",
384
-          value: 1
385
-        },
386
-        {
387
-          label: "下架",
388
-          value: 0
389
-        },],
358
+        dict: [
359
+          {
360
+            label: '上架',
361
+            value: 1,
362
+          },
363
+          {
364
+            label: '下架',
365
+            value: 0,
366
+          },
367
+        ],
390 368
         value: data.status != null ? data.status : 1,
391 369
       },
392
-    ]
370
+    ];
393 371
 
394 372
     const handleSubmit = val => {
395
-      val.showType = 'screen'
373
+      val.showType = 'screen';
396 374
       if (!isHaveActive && val.targetId) {
397 375
         if (!val.contentType) {
398
-          val.contentType = 'h5'
376
+          val.contentType = 'h5';
399 377
         }
400 378
       }
401 379
       if (!isHaveActive && !val.targetId) {
402
-        val.contentType = ''
380
+        val.contentType = '';
403 381
       }
404 382
       if (contentId) {
405
-        request({ ...apis.carsuseFigure.updataExtendContent, urlData: { id: contentId }, data: val, }).then((data) => {
406
-          cancelPage()
407
-        }).catch((err) => {
408
-          message.info(err.msg || err.message)
383
+        request({
384
+          ...apis.carsuseFigure.updataExtendContent,
385
+          urlData: { id: contentId },
386
+          data: val,
409 387
         })
388
+          .then(data => {
389
+            cancelPage();
390
+          })
391
+          .catch(err => {
392
+            message.info(err.msg || err.message);
393
+          });
410 394
       } else {
411
-        request({ ...apis.carsuseFigure.addExtendContent, data: val, }).then((data) => {
412
-          cancelPage()
413
-        }).catch((err) => {
414
-          message.info(err.msg || err.message)
415
-        })
395
+        request({ ...apis.carsuseFigure.addExtendContent, data: val })
396
+          .then(data => {
397
+            cancelPage();
398
+          })
399
+          .catch(err => {
400
+            message.info(err.msg || err.message);
401
+          });
416 402
       }
417
-    }
418
-
403
+    };
419 404
 
420 405
     return (
421
-      <XForm wrappedComponentRef={formRef} onSubmit={handleSubmit} onCancel={cancelPage} onValuesChange={handleFormValueChange} fields={fields}></XForm>
406
+      <Card>
407
+        <XForm
408
+          wrappedComponentRef={formRef}
409
+          onSubmit={handleSubmit}
410
+          onCancel={cancelPage}
411
+          onValuesChange={handleFormValueChange}
412
+          fields={fields}
413
+        ></XForm>
414
+      </Card>
422 415
     );
423
-  }
424
-}
416
+  };
417
+};
425 418
 
426
-export default createEditor()
419
+export default createEditor();

+ 256
- 265
src/pages/carouselFigure/editCarousel.jsx Wyświetl plik

@@ -1,15 +1,13 @@
1 1
 import React, { useState, useEffect } from 'react';
2
-import { Form, Input, Button, Icon, Select, Tabs, Radio, DatePicker, message } from 'antd';
3
-import { FormattedMessage } from 'umi-plugin-react/locale';
4
-import moment from 'moment';
2
+import { Card, DatePicker, message } from 'antd';
3
+
5 4
 import router from 'umi/router';
6
-import styles from '../style/GoodsList.less';
7
-import BuildSelect from '../../components/SelectButton/BuildSelect2'
8
-import CitySelect from '../../components/SelectButton/CitySelect2'
5
+import BuildSelect from '../../components/SelectButton/BuildSelect2';
6
+import CitySelect from '../../components/SelectButton/CitySelect2';
9 7
 import { createForm, FieldTypes } from '../../components/XForm';
10
-import Wangedit from '../../components/Wangedit/Wangedit'
8
+import Wangedit from '../../components/Wangedit/Wangedit';
11 9
 import apis from '../../services/apis';
12
-import request from '../../utils/request'
10
+import request from '../../utils/request';
13 11
 import SelectHelp from './SelectHelp';
14 12
 import SelectGroup from './SelectGroup';
15 13
 import SalesBatchGroup from './SalesBatchGroup';
@@ -18,35 +16,34 @@ import SelectNews from './SelectNews';
18 16
 import SelectActivity from './SelectActivity';
19 17
 import SelectH5 from './SelectH5';
20 18
 
21
-const { MonthPicker, RangePicker, WeekPicker } = DatePicker;
22 19
 /**
23 20
  *
24 21
  *
25 22
  * @param {*} props
26 23
  * @returns
27 24
  */
28
- const Edit = props => {
29
-  let contentVisible = false
30
-  let activityVisible = false
31
-  let newsVisible = false
32
-  let helpVisible = false
33
-  let groupVisible = false
34
-  let salesBatchVisible = false
35
-  let liveVisible = false
36
-  let h5Visible = false
37
-  let buildingId = ''
38
-  let cityId=''
39
-  let locationType = false
40
-  let isHaveActive=false
41
-  let isCanChoose=true
25
+const Edit = props => {
26
+  let contentVisible = false;
27
+  let activityVisible = false;
28
+  let newsVisible = false;
29
+  let helpVisible = false;
30
+  let groupVisible = false;
31
+  let salesBatchVisible = false;
32
+  let liveVisible = false;
33
+  let h5Visible = false;
34
+  let buildingId = '';
35
+  let cityId = '';
36
+  let locationType = false;
37
+  let isHaveActive = false;
38
+  let isCanChoose = true;
42 39
 
43
-  const setExtraData = (data) => {
40
+  const setExtraData = data => {
44 41
     console.log(data, 'data');
45
-    if(data.isHaveActive!=undefined){
46
-      isHaveActive=data.isHaveActive
47
-      if(!isHaveActive) {
42
+    if (data.isHaveActive != undefined) {
43
+      isHaveActive = data.isHaveActive;
44
+      if (!isHaveActive) {
48 45
         // data.contentType=null
49
-        data.buildingId=null
46
+        data.buildingId = null;
50 47
       }
51 48
     }
52 49
 
@@ -59,18 +56,23 @@ const { MonthPicker, RangePicker, WeekPicker } = DatePicker;
59 56
     liveVisible = data.contentType === 'live';
60 57
     h5Visible = data.contentType === 'h5';
61 58
 
62
-    cityId=data.cityId
63
-    buildingId = data.buildingId
59
+    cityId = data.cityId;
60
+    buildingId = data.buildingId;
64 61
     locationType = data.showPosition === 'mall';
65 62
     console.log(locationType, 'locationType');
66
-  }
63
+  };
67 64
 
68
-  const setExtraData1 = (data) => {
69
-     if((data.contentType=='h5'  && data.buildingId == null) || data.contentType==''||data.contentType=='nothing' || (data.contentType=='live' && data.buildingId == null)){
70
-        isHaveActive=false
71
-     }else{
72
-        isHaveActive=true
73
-     }
65
+  const setExtraData1 = data => {
66
+    if (
67
+      (data.contentType == 'h5' && data.buildingId == null) ||
68
+      data.contentType == '' ||
69
+      data.contentType == 'nothing' ||
70
+      (data.contentType == 'live' && data.buildingId == null)
71
+    ) {
72
+      isHaveActive = false;
73
+    } else {
74
+      isHaveActive = true;
75
+    }
74 76
 
75 77
     contentVisible = data.contentType === 'other';
76 78
     activityVisible = data.contentType === 'activity';
@@ -79,141 +81,136 @@ const { MonthPicker, RangePicker, WeekPicker } = DatePicker;
79 81
     groupVisible = data.contentType === 'group';
80 82
     salesBatchVisible = data.contentType === 'salesBatch';
81 83
     liveVisible = data.contentType === 'live';
82
-    buildingId = data.buildingId
84
+    buildingId = data.buildingId;
83 85
     locationType = data.showPosition === 'mall';
84 86
     h5Visible = data.contentType === 'h5';
85 87
     console.log(locationType, 'locationType');
86
-  }
87
-
88
+  };
88 89
 
89 90
   const handleFormValueChange = (props, changedValues, allValues) => {
90
-      setExtraData(allValues)
91
-  }
91
+    setExtraData(allValues);
92
+  };
92 93
 
93
-  const XForm = createForm({ onValuesChange: handleFormValueChange })
94
+  const XForm = createForm({ onValuesChange: handleFormValueChange });
94 95
 
95 96
   return props => {
96
-    const [tab, changeTab] = useState('basic')
97
-    const { contentId } = props.location.query
98
-    const [data, setData] = useState({})
97
+    const [tab, changeTab] = useState('basic');
98
+    const { contentId } = props.location.query;
99
+    const [data, setData] = useState({});
99 100
 
100 101
     if (contentId) {
101
-      isCanChoose=false
102
+      isCanChoose = false;
102 103
       // eslint-disable-next-line react-hooks/rules-of-hooks
103 104
       useEffect(() => {
104 105
         getDetail(contentId);
105
-      }, [])
106
+      }, []);
106 107
 
107 108
       // 查询列表
108 109
       const getDetail = contentId => {
109
-        request({ ...apis.carsuseFigure.getExtendContent, urlData: { id: contentId } }).then(data => {
110
-            console.log(data)
111
-            setExtraData1(data)
112
-            setData(data)
113
-        })
114
-      }
115
-    }else{
116
-      isCanChoose=true
110
+        request({ ...apis.carsuseFigure.getExtendContent, urlData: { id: contentId } }).then(
111
+          data => {
112
+            console.log(data);
113
+            setExtraData1(data);
114
+            setData(data);
115
+          },
116
+        );
117
+      };
118
+    } else {
119
+      isCanChoose = true;
117 120
     }
118 121
 
119 122
     const cancelPage = () => {
120 123
       router.push({
121 124
         pathname: '/carouselFigure/carouselFigureList',
122 125
       });
123
-    }
126
+    };
124 127
 
125
-      const fields = [
126
-        {
127
-          label: '是否关联项目',
128
-          name: 'isHaveActive',
129
-          type: FieldTypes.Switch,
130
-          value:isHaveActive,
131
-          hidden: () => !isCanChoose,
132
-          rules: [
133
-            { required: true,message: '是否城市活动' },
134
-          ],
135
-        },
136
-        {
137
-          label: '所属项目',
138
-          name: 'buildingId',
139
-          render: <BuildSelect />,
140
-          hidden: () => !isHaveActive,
141
-          value: data.buildingId,
142
-          rules: [
143
-            { required: true, message: '请选择所属项目' },
144
-          ],
145
-        },
146
-        {
147
-          label: '展示城市',
148
-          name: 'cityId',
149
-          render: <CitySelect />,
150
-          hidden: () => isHaveActive,
151
-          value: data.cityId,
152
-          rules: [
153
-            { required: true, message: '请选择展示城市' },
154
-          ],
155
-        },
156
-        {
157
-          label: '发布位置',
158
-          name: 'showPosition',
159
-          type: FieldTypes.Select,
160
-          dict: [{
128
+    const fields = [
129
+      {
130
+        label: '是否关联项目',
131
+        name: 'isHaveActive',
132
+        type: FieldTypes.Switch,
133
+        value: isHaveActive,
134
+        hidden: () => !isCanChoose,
135
+        rules: [{ required: true, message: '是否城市活动' }],
136
+      },
137
+      {
138
+        label: '所属项目',
139
+        name: 'buildingId',
140
+        render: <BuildSelect />,
141
+        hidden: () => !isHaveActive,
142
+        value: data.buildingId,
143
+        rules: [{ required: true, message: '请选择所属项目' }],
144
+      },
145
+      {
146
+        label: '展示城市',
147
+        name: 'cityId',
148
+        render: <CitySelect />,
149
+        hidden: () => isHaveActive,
150
+        value: data.cityId,
151
+        rules: [{ required: true, message: '请选择展示城市' }],
152
+      },
153
+      {
154
+        label: '发布位置',
155
+        name: 'showPosition',
156
+        type: FieldTypes.Select,
157
+        dict: [
158
+          {
161 159
             label: '首页',
162 160
             value: 'index',
163 161
           },
164 162
           {
165 163
             label: '积分商城',
166 164
             value: 'mall',
167
-          }],
168
-          value: data.showPosition,
169
-          rules: [
170
-            { required: true, message: '请选择发布位置' },
171
-          ],
172
-        },
173
-        {
174
-          label: () => (locationType ? '积分商城轮播图' : '首页轮播图'),
175
-          name: 'image',
176
-          type: FieldTypes.ImageUploader,
177
-          value: data.image,
178
-          help: () => (locationType ? '建议图片尺寸:750*250px,比例3:1,格式:jpg,用于积分商城banner轮播' : '建议图片尺寸:750*464px,比例1.:0.618,格式:jpg,用于:首页顶部banner轮播'),
179
-          rules: [
180
-            { required: true, message: '请上传轮播图' },
181
-          ],
182
-        },
183
-        {
184
-          label: '类型',
185
-          name: 'contentType',
186
-          type: FieldTypes.Select,
187
-          hidden: () => isHaveActive,
188
-          dict: [{
165
+          },
166
+        ],
167
+        value: data.showPosition,
168
+        rules: [{ required: true, message: '请选择发布位置' }],
169
+      },
170
+      {
171
+        label: () => (locationType ? '积分商城轮播图' : '首页轮播图'),
172
+        name: 'image',
173
+        type: FieldTypes.ImageUploader,
174
+        value: data.image,
175
+        help: () =>
176
+          locationType
177
+            ? '建议图片尺寸:750*250px,比例3:1,格式:jpg,用于积分商城banner轮播'
178
+            : '建议图片尺寸:750*464px,比例1.:0.618,格式:jpg,用于:首页顶部banner轮播',
179
+        rules: [{ required: true, message: '请上传轮播图' }],
180
+      },
181
+      {
182
+        label: '类型',
183
+        name: 'contentType',
184
+        type: FieldTypes.Select,
185
+        hidden: () => isHaveActive,
186
+        dict: [
187
+          {
189 188
             label: 'h5',
190 189
             value: 'h5',
191 190
           },
192 191
           {
193 192
             label: '直播活动详情',
194 193
             value: 'live',
195
-          }],
196
-          value: data.contentType,
197
-          rules: [
198
-            { required: true, message: '请选择类型' },
199
-          ],
200
-        },
201
-        {
202
-          label: '标题',
203
-          name: 'title',
204
-          type: FieldTypes.Text,
205
-          value: data.title,
206
-          hidden: true,
207
-          rules: [
208
-            { required: true, message: '请输入标题' },
209
-          ],
210
-        },
211
-        {
212
-          label: '类型',
213
-          name: 'contentType',
214
-          type: FieldTypes.Select,
215
-          hidden: () => !isHaveActive,
216
-          dict: [{
194
+          },
195
+        ],
196
+        value: data.contentType,
197
+        rules: [{ required: true, message: '请选择类型' }],
198
+      },
199
+      {
200
+        label: '标题',
201
+        name: 'title',
202
+        type: FieldTypes.Text,
203
+        value: data.title,
204
+        hidden: true,
205
+        rules: [{ required: true, message: '请输入标题' }],
206
+      },
207
+      {
208
+        label: '类型',
209
+        name: 'contentType',
210
+        type: FieldTypes.Select,
211
+        hidden: () => !isHaveActive,
212
+        dict: [
213
+          {
217 214
             label: '常规活动',
218 215
             value: 'activity',
219 216
           },
@@ -248,146 +245,140 @@ const { MonthPicker, RangePicker, WeekPicker } = DatePicker;
248 245
           {
249 246
             label: '直播活动详情',
250 247
             value: 'live',
251
-          }],
252
-          value: data.contentType,
253
-          rules: [
254
-            { required: true, message: '请选择类型' },
255
-          ],
256
-        },
257
-        {
258
-          label: '发布活动',
259
-          name: 'targetId',
260
-          render: <SelectActivity buildingId={() => buildingId} />,
261
-          hidden: () => !activityVisible,
262
-          value: data.targetId,
263
-          rules: [
264
-            { required: true, message: '请选择发布活动' },
265
-          ],
266
-        },
267
-        {
268
-          label: '是否发布H5',
269
-          name: 'targetId',
270
-          render: <SelectH5 buildingId={() => buildingId}/>,
271
-          hidden: () => !h5Visible,
272
-          value: data.targetId,
273
-          rules: [
274
-            { required: false, message: '请选择发布H5' },
275
-          ],
276
-        },
277
-        {
278
-          label: '发布资讯',
279
-          name: 'targetId',
280
-          render: <SelectNews buildingId={() => buildingId} />,
281
-          hidden: () => !newsVisible,
282
-          value: data.targetId,
283
-          rules: [
284
-            { required: true, message: '请选择发布资讯' },
285
-          ],
286
-        },
287
-        {
288
-          label: '发布内容',
289
-          name: 'content',
290
-          render: <Wangedit />,
291
-          value: data.content,
292
-          hidden: () => !contentVisible,
293
-          rules: [
294
-            { required: true, message: '请输入发布内容' },
295
-          ],
296
-        },
297
-        {
298
-          label: '发布助力',
299
-          name: 'targetId',
300
-          render: <SelectHelp buildingId={() => buildingId} />,
301
-          hidden: () => !helpVisible,
302
-          value: data.targetId,
303
-          rules: [
304
-            { required: true, message: '请选择发布助力' },
305
-          ],
306
-        },
307
-        {
308
-          label: '发布拼团',
309
-          name: 'targetId',
310
-          render: <SelectGroup buildingId={() => buildingId} />,
311
-          hidden: () => !groupVisible,
312
-          value: data.targetId,
313
-          rules: [
314
-            { required: true, message: '请选择发布拼团' },
315
-          ],
316
-        },
317
-        {
318
-          label: '发布销售批次',
319
-          name: 'targetId',
320
-          render: <SalesBatchGroup buildingId={() => buildingId} />,
321
-          hidden: () => !salesBatchVisible,
322
-          value: data.targetId,
323
-          rules: [
324
-            { required: true, message: '请选择发布销售批次' },
325
-          ],
326
-        },
327
-        {
328
-          label: '发布直播活动',
329
-          name: 'targetId',
330
-          render: <LiveGroup buildingId={() => buildingId} />,
331
-          hidden: () => !liveVisible,
332
-          value: data.targetId, 
333
-          rules: [
334
-            { required: true, message: '请选择发布直播活动' },
335
-          ],
336
-        },
337
-        {
338
-          label: '状态',
339
-          name: 'status',
340
-          type: FieldTypes.Select,
341
-          dict: [{
248
+          },
249
+        ],
250
+        value: data.contentType,
251
+        rules: [{ required: true, message: '请选择类型' }],
252
+      },
253
+      {
254
+        label: '发布活动',
255
+        name: 'targetId',
256
+        render: <SelectActivity buildingId={() => buildingId} />,
257
+        hidden: () => !activityVisible,
258
+        value: data.targetId,
259
+        rules: [{ required: true, message: '请选择发布活动' }],
260
+      },
261
+      {
262
+        label: '是否发布H5',
263
+        name: 'targetId',
264
+        render: <SelectH5 buildingId={() => buildingId} />,
265
+        hidden: () => !h5Visible,
266
+        value: data.targetId,
267
+        rules: [{ required: false, message: '请选择发布H5' }],
268
+      },
269
+      {
270
+        label: '发布资讯',
271
+        name: 'targetId',
272
+        render: <SelectNews buildingId={() => buildingId} />,
273
+        hidden: () => !newsVisible,
274
+        value: data.targetId,
275
+        rules: [{ required: true, message: '请选择发布资讯' }],
276
+      },
277
+      {
278
+        label: '发布内容',
279
+        name: 'content',
280
+        render: <Wangedit />,
281
+        value: data.content,
282
+        hidden: () => !contentVisible,
283
+        rules: [{ required: true, message: '请输入发布内容' }],
284
+      },
285
+      {
286
+        label: '发布助力',
287
+        name: 'targetId',
288
+        render: <SelectHelp buildingId={() => buildingId} />,
289
+        hidden: () => !helpVisible,
290
+        value: data.targetId,
291
+        rules: [{ required: true, message: '请选择发布助力' }],
292
+      },
293
+      {
294
+        label: '发布拼团',
295
+        name: 'targetId',
296
+        render: <SelectGroup buildingId={() => buildingId} />,
297
+        hidden: () => !groupVisible,
298
+        value: data.targetId,
299
+        rules: [{ required: true, message: '请选择发布拼团' }],
300
+      },
301
+      {
302
+        label: '发布销售批次',
303
+        name: 'targetId',
304
+        render: <SalesBatchGroup buildingId={() => buildingId} />,
305
+        hidden: () => !salesBatchVisible,
306
+        value: data.targetId,
307
+        rules: [{ required: true, message: '请选择发布销售批次' }],
308
+      },
309
+      {
310
+        label: '发布直播活动',
311
+        name: 'targetId',
312
+        render: <LiveGroup buildingId={() => buildingId} />,
313
+        hidden: () => !liveVisible,
314
+        value: data.targetId,
315
+        rules: [{ required: true, message: '请选择发布直播活动' }],
316
+      },
317
+      {
318
+        label: '状态',
319
+        name: 'status',
320
+        type: FieldTypes.Select,
321
+        dict: [
322
+          {
342 323
             label: '上架',
343 324
             value: 1,
344 325
           },
345 326
           {
346 327
             label: '下架',
347 328
             value: 0,
348
-          }],
349
-          value: data.status != null ? data.status : 1,
350
-        },
351
-        {
352
-          label: '权重',
353
-          name: 'orderNo',
354
-          type: FieldTypes.Number,
355
-          value: data.orderNo,
356
-          help: "数值越大越靠前",
357
-        },
358
-      ]
329
+          },
330
+        ],
331
+        value: data.status != null ? data.status : 1,
332
+      },
333
+      {
334
+        label: '权重',
335
+        name: 'orderNo',
336
+        type: FieldTypes.Number,
337
+        value: data.orderNo,
338
+        help: '数值越大越靠前',
339
+      },
340
+    ];
359 341
 
360
-      const handleSubmit = val => {
361
-        console.log(val,"232323")
362
-        val.showType = 'banner'
363
-        if(!isHaveActive&&val.targetId) {
364
-          if(!val.contentType){
365
-            val.contentType='h5'
366
-          }
367
-        }
368
-        if(!isHaveActive&&!val.targetId){
369
-          val.contentType=''
342
+    const handleSubmit = val => {
343
+      console.log(val, '232323');
344
+      val.showType = 'banner';
345
+      if (!isHaveActive && val.targetId) {
346
+        if (!val.contentType) {
347
+          val.contentType = 'h5';
370 348
         }
371
-        if (contentId) {
372
-          request({ ...apis.carsuseFigure.updataExtendContent, urlData: { id: contentId }, data: val }).then(data => {
373
-            cancelPage()
374
-          }).catch(err => {
375
-            message.info(err.msg || err.message)
349
+      }
350
+      if (!isHaveActive && !val.targetId) {
351
+        val.contentType = '';
352
+      }
353
+      if (contentId) {
354
+        request({
355
+          ...apis.carsuseFigure.updataExtendContent,
356
+          urlData: { id: contentId },
357
+          data: val,
358
+        })
359
+          .then(data => {
360
+            cancelPage();
376 361
           })
377
-        } else {
378
-          request({ ...apis.carsuseFigure.addExtendContent, data: val }).then(data => {
379
-            cancelPage()
380
-          }).catch(err => {
381
-            message.info(err.msg || err.message)
362
+          .catch(err => {
363
+            message.info(err.msg || err.message);
364
+          });
365
+      } else {
366
+        request({ ...apis.carsuseFigure.addExtendContent, data: val })
367
+          .then(data => {
368
+            cancelPage();
382 369
           })
383
-        }
370
+          .catch(err => {
371
+            message.info(err.msg || err.message);
372
+          });
384 373
       }
374
+    };
385 375
 
386 376
     return (
387
-      <XForm onSubmit={handleSubmit} onCancel={cancelPage} fields={fields}></XForm>
377
+      <Card>
378
+        <XForm onSubmit={handleSubmit} onCancel={cancelPage} fields={fields}></XForm>
379
+      </Card>
388 380
     );
389
-  }
390
- }
391
-
381
+  };
382
+};
392 383
 
393
-export default Edit()
384
+export default Edit();

+ 323
- 0
src/pages/customer/Customer/PublicCustomer/AssistConsultant/AssistConsultant.jsx Wyświetl plik

@@ -0,0 +1,323 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Table, Modal, notification } from 'antd';
3
+import request from '@/utils/request';
4
+import apis from '@/services/apis';
5
+import BuildSelect from '../../../../../components/SelectButton/BuildSelect';
6
+
7
+/**
8
+ * 分配置业顾问
9
+ *
10
+ * @param {*} props
11
+ * @returns
12
+ */
13
+
14
+const AssistConsultant = props => {
15
+  const { visible, data } = props.modelProps || {};
16
+
17
+  const [tableData, setTableData] = useState({});
18
+  const [loading, setLoading] = useState(false);
19
+
20
+  const openNotificationWithIcon = (type, message) => {
21
+    notification[type]({
22
+      message,
23
+      description: '',
24
+    });
25
+  };
26
+
27
+  function getList(params) {
28
+    // 网路请求
29
+    setLoading(true);
30
+    request({
31
+      ...apis.customer.buildingConsultant,
32
+      params: { ...params },
33
+    })
34
+      .then(res => {
35
+        console.log(res, 'res');
36
+        setTableData(res);
37
+        setLoading(false);
38
+      })
39
+      .catch(err => {
40
+        openNotificationWithIcon('error', err);
41
+        setLoading(false);
42
+      });
43
+  }
44
+
45
+  useEffect(() => {
46
+    if (visible) {
47
+      getList({ pageNumber: 1, pageSize: 5 });
48
+    } else {
49
+      setTableData({});
50
+    }
51
+  }, [visible]);
52
+
53
+  // 分页
54
+  function onChange(pageNum) {
55
+    getList({ pageNumber: pageNum, pageSize: 5 });
56
+  }
57
+
58
+  function changBuilding(buildingId) {
59
+    if (buildingId) {
60
+      getList({ pageNumber: 1, pageSize: 5, buildingId: buildingId });
61
+    }
62
+  }
63
+
64
+  //   // 提交
65
+  function submitGm(record) {
66
+    // 网路请求
67
+    request({
68
+      ...apis.customer.consultantAssist,
69
+      urlData: { id: data.customerId },
70
+      data: { userId: record.userId, buildingId: data.buildingName || data.buildingId },
71
+    })
72
+      .then(res => {
73
+        // eslint-disable-next-line no-unused-expressions
74
+
75
+        openNotificationWithIcon('success', '操作成功');
76
+        props.handleCancel();
77
+      })
78
+      .catch(err => {
79
+        // eslint-disable-next-line no-unused-expressions
80
+      });
81
+  }
82
+
83
+  const columns = [
84
+    {
85
+      title: '姓名',
86
+      dataIndex: 'userName',
87
+      key: 'userName',
88
+    },
89
+    {
90
+      title: '电话',
91
+      dataIndex: 'phone',
92
+      key: 'phone',
93
+    },
94
+    {
95
+      title: '部门',
96
+      dataIndex: 'department',
97
+      key: 'department',
98
+    },
99
+    {
100
+      title: '岗位',
101
+      dataIndex: 'position',
102
+      key: 'position',
103
+    },
104
+    {
105
+      title: '操作',
106
+      dataIndex: 'personId',
107
+      key: 'personId',
108
+      // eslint-disable-next-line no-nested-ternary
109
+      render: (_, record) => (
110
+        <>
111
+          {
112
+            <Button type="danger" onClick={() => submitGm(record)}>
113
+              确定
114
+            </Button>
115
+          }
116
+        </>
117
+      ),
118
+    },
119
+  ];
120
+
121
+  return (
122
+    <>
123
+      <Modal
124
+        title={'分配置业顾问'}
125
+        width={800}
126
+        destroyOnClose="true"
127
+        footer={null}
128
+        visible={visible}
129
+        onCancel={() => props.onCancel()}
130
+      >
131
+        {/* <span>你正在为{this.props.visibleData.customerId.length}位公客分配置业顾问</span><br/><br/>
132
+            {this.props.visibleData.buildingId == null && <BuildSelect onChange={this.changBuilding.bind(this)} value={this.state.visibleData.buildingName} />} */}
133
+
134
+        {data && (
135
+          <>
136
+            {data.customerId?.length > 0 && (
137
+              <>
138
+                <span>你正在为{data.customerId.length}位公客分配置业顾问</span>
139
+                <br />
140
+                <br />
141
+              </>
142
+            )}
143
+            {data?.buildingId == null && (
144
+              <BuildSelect onChange={e => changBuilding(e)} value={data?.buildingName} />
145
+            )}
146
+            <Table
147
+              dataSource={tableData.records}
148
+              columns={columns}
149
+              loading={loading}
150
+              pagination={{
151
+                pageSize: tableData.pageSize,
152
+                total: tableData.total,
153
+                onChange: e => onChange(e),
154
+              }}
155
+            />
156
+          </>
157
+        )}
158
+      </Modal>
159
+    </>
160
+  );
161
+};
162
+
163
+export default AssistConsultant;
164
+
165
+// import React, { useState, useEffect } from 'react';
166
+// import { Form, Icon, Input, Button, DatePicker, Select, Card, Row, Col, Pagination, Alert, Table, Avatar, Radio, Modal, Descriptions, notification } from 'antd';
167
+// import moment from 'moment';
168
+// import request from '../../../../utils/request';
169
+// import apis from '../../../../services/apis';
170
+// import Styles from '../style.less';
171
+// import BuildSelect from '../../../../components/SelectButton/BuildSelect'
172
+
173
+// const { Option } = Select;
174
+// // eslint-disable-next-line @typescript-eslint/no-unused-vars
175
+// const { Meta } = Card;
176
+
177
+// /**
178
+//  * 分配置业顾问
179
+//  *
180
+//  * @param {*} props
181
+//  * @returns
182
+//  */
183
+// class ModalAttribution extends React.Component {
184
+//   constructor(props) {
185
+//     super(props);
186
+//     this.state = {
187
+//        dataSource: { records: [] },
188
+//        visibleData: { visible: false, customerId: '', buildingName: '' },
189
+//     }
190
+//   }
191
+
192
+//   // 挂载之后
193
+//   componentDidMount() {
194
+//     // this.getList({ pageNumber: 1, pageSize: 5 })
195
+//   }
196
+
197
+//   componentDidUpdate(preProps, preState) {
198
+//     console.log(this.props.visibleData)
199
+//     if (this.props.visibleData.visible !== preState.visibleData.visible) {
200
+//       this.getList({ pageNumber: 1, pageSize: 5, customerId: this.props.visibleData.customerId,buildingId:this.props.visibleData.buildingId })
201
+//       this.setState({ visibleData: this.props.visibleData });
202
+//     }
203
+//   }
204
+
205
+//   // 弹框确定按钮
206
+//   // eslint-disable-next-line react/sort-comp
207
+//   handleOk() {
208
+//     this.props.onCancel()
209
+//   }
210
+
211
+//   // 弹框取消按钮
212
+//   handleCancel() {
213
+//     this.props.onCancel()
214
+//   }
215
+
216
+//   changBuilding(buildingId){
217
+//     this.getUserList({ pageNumber: 1, pageSize: 5, buildingId: buildingId })
218
+//     this.setState({ visibleData: { visible: this.props.visibleData.visible, customerId: this.props.visibleData.customerId, buildingName: buildingId } });
219
+//   }
220
+
221
+//   getUserList(params){
222
+//     console.log('params: ', params)
223
+//     if (params.buildingId === '' || params.buildingId === null || params.buildingId === undefined) {
224
+//       return
225
+//     }
226
+//     // 网路请求
227
+//     request({ ...apis.customer.buildingConsultant, params: { ...params } }).then(res => {
228
+//       this.setState({ dataSource: res })
229
+//     }).catch(err => {
230
+
231
+//     })
232
+//   }
233
+
234
+//   getList(params) {
235
+//     // 网路请求
236
+//     request({ ...apis.customer.buildingConsultant, params: { ...params } }).then(res => {
237
+//       this.setState({ dataSource: res })
238
+//     }).catch(err => {
239
+
240
+//     })
241
+//   }
242
+
243
+//   openNotificationWithIcon = (type, message) => {
244
+//     notification[type]({
245
+//       message,
246
+//       description:
247
+//         '',
248
+//     });
249
+//   };
250
+
251
+//    // 分页
252
+//   onChange(pageNum) {
253
+//     this.getList({ pageNumber: pageNum, pageSize: 5, customerId: this.props.visibleData.customerId, buildingId: this.state.visibleData.buildingName ||this.props.visibleData.buildingId})
254
+//   }
255
+
256
+//   // 提交
257
+//   submitGm(record) {
258
+//     debugger
259
+//     // 网路请求
260
+//     request({ ...apis.customer.consultantAssist, urlData: { id: this.state.visibleData.customerId },
261
+//       data: { userId: record.userId,buildingId:this.state.visibleData.buildingName  || this.props.visibleData.buildingId } }).then(res => {
262
+//       // eslint-disable-next-line no-unused-expressions
263
+
264
+//       this.openNotificationWithIcon('success', '操作成功')
265
+//       this.handleCancel()
266
+//     }).catch(err => {
267
+//       // eslint-disable-next-line no-unused-expressions
268
+//     })
269
+//   }
270
+
271
+//   render() {
272
+//     const columns = [
273
+//       // {
274
+//       //   title: '编号',
275
+//       //   dataIndex: 'userId',
276
+//       //   key: 'userId',
277
+//       // },
278
+//       {
279
+//         title: '姓名',
280
+//         dataIndex: 'userName',
281
+//         key: 'userName',
282
+//       },
283
+//       {
284
+//         title: '电话',
285
+//         dataIndex: 'phone',
286
+//         key: 'phone',
287
+//       },
288
+//       {
289
+//         title: '部门',
290
+//         dataIndex: 'department',
291
+//         key: 'department',
292
+//       },
293
+//       {
294
+//         title: '岗位',
295
+//         dataIndex: 'position',
296
+//         key: 'position',
297
+//       },
298
+//       {
299
+//         title: '操作',
300
+//         dataIndex: 'personId',
301
+//         key: 'personId',
302
+//         // eslint-disable-next-line no-nested-ternary
303
+//         render: (_, record) => <>{ <Button type="danger" onClick={() => this.submitGm(record)}>确定</Button>}</>, },
304
+//     ]
305
+//     return (
306
+//       <>
307
+//         <Modal
308
+//             title="分配置业顾问"
309
+//             width={800}
310
+//             destroyOnClose="true"
311
+//             footer={null}
312
+//             visible={this.state.visibleData.visible}
313
+//             onCancel={(e) => this.handleCancel(e)}
314
+//           >
315
+//             {this.props.visibleData.buildingId == null && <BuildSelect  onChange={this.changBuilding.bind(this)} value={this.state.visibleData.buildingName} />}
316
+//             <Table rowKey="assistConsultant" dataSource={this.state.dataSource.records} columns={columns} pagination={{pageSize: 5, total: this.state.dataSource.total, onChange: e => this.onChange(e) }} />
317
+//           </Modal>
318
+//       </>
319
+//     );
320
+//   }
321
+// }
322
+
323
+// export default ModalAttribution

+ 98
- 0
src/pages/customer/Customer/PublicCustomer/AssistConsultant/Attribution.jsx Wyświetl plik

@@ -0,0 +1,98 @@
1
+import React from 'react';
2
+import { Button, Modal, notification } from 'antd';
3
+import request from '@/utils/request';
4
+import apis from '@/services/apis';
5
+import TableList from '@/components/TableList';
6
+
7
+const Attribution = props => {
8
+  console.log(props, 'props');
9
+
10
+  const { visible, data } = props.modelProps || {};
11
+
12
+  const openNotificationWithIcon = (type, message) => {
13
+    notification[type]({
14
+      message,
15
+      description: '',
16
+    });
17
+  };
18
+
19
+  // 提交
20
+  function submitGm(record) {
21
+    // 网路请求
22
+    request({
23
+      ...apis.customer.recommendEdit,
24
+      urlData: { id: data.customerId },
25
+      data: { customerId: data.customerId, realtyConsultant: record.userId },
26
+    })
27
+      .then(res => {
28
+        // eslint-disable-next-line no-unused-expressions
29
+        openNotificationWithIcon('success', '操作成功');
30
+        props.handleCancel();
31
+      })
32
+      .catch(err => {
33
+        // eslint-disable-next-line no-unused-expressions
34
+        openNotificationWithIcon('error', err);
35
+      });
36
+  }
37
+
38
+  const columns = [
39
+    {
40
+      title: '姓名',
41
+      dataIndex: 'userName',
42
+      key: 'userName',
43
+    },
44
+    {
45
+      title: '电话',
46
+      dataIndex: 'phone',
47
+      key: 'phone',
48
+    },
49
+    {
50
+      title: '部门',
51
+      dataIndex: 'department',
52
+      key: 'department',
53
+    },
54
+    {
55
+      title: '岗位',
56
+      dataIndex: 'position',
57
+      key: 'position',
58
+    },
59
+    {
60
+      title: '操作',
61
+      dataIndex: 'personId',
62
+      key: 'personId',
63
+      render: (_, record) => (
64
+        <>
65
+          {data.realtyConsultant != record.userId && (
66
+            <Button type="primary" onClick={() => submitGm(record)}>
67
+              确定
68
+            </Button>
69
+          )}
70
+        </>
71
+      ),
72
+    },
73
+  ];
74
+
75
+  return (
76
+    <>
77
+      <Modal
78
+        title="变更状态"
79
+        width={800}
80
+        destroyOnClose="true"
81
+        footer={null}
82
+        visible={visible}
83
+        onCancel={() => props.onCancel()}
84
+      >
85
+        {data && (
86
+          <TableList
87
+            rowKey="userId"
88
+            api={apis.customer.buildingConsultant}
89
+            params={{ buildingId: data.buildingId }}
90
+            columns={columns}
91
+          />
92
+        )}
93
+      </Modal>
94
+    </>
95
+  );
96
+};
97
+
98
+export default Attribution;

+ 170
- 0
src/pages/customer/Customer/PublicCustomer/AssistConsultant/BatchAssistConsultant.jsx Wyświetl plik

@@ -0,0 +1,170 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Form, Icon, Input, Button, DatePicker, Select, Card, Row, Col, Pagination, Alert, Table, Avatar, Radio, Modal, Descriptions, notification } from 'antd';
3
+import moment from 'moment';
4
+import request from '../../../../utils/request';
5
+import apis from '../../../../services/apis';
6
+import Styles from '../style.less';
7
+import BuildSelect from '../../../../components/SelectButton/BuildSelect'
8
+
9
+
10
+const { Option } = Select;
11
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
12
+const { Meta } = Card;
13
+
14
+/**
15
+ * 分配置业顾问
16
+ *
17
+ * @param {*} props
18
+ * @returns
19
+ */
20
+class ModalAttribution extends React.Component {
21
+  constructor(props) {
22
+    super(props);
23
+    console.log(props, 'props')
24
+    this.state = {
25
+       dataSource: { records: [] },
26
+       visibleData: { visible: false, customerId: [], buildingName: '' },
27
+    }
28
+  }
29
+
30
+  // 挂载之后
31
+  componentDidMount() {
32
+    // this.getList({ pageNumber: 1, pageSize: 5 })
33
+  }
34
+
35
+  componentDidUpdate(preProps, preState) {
36
+    console.log(this.props.visibleData)
37
+    if (this.props.visibleData.visible !== preState.visibleData.visible) {
38
+      this.getList({ pageNumber: 1, pageSize: 5,buildingId: this.props.visibleData.buildingId})
39
+      this.setState({ visibleData: this.props.visibleData });
40
+    }
41
+  }
42
+
43
+  // 弹框确定按钮
44
+  // eslint-disable-next-line react/sort-comp
45
+  handleOk() {
46
+    this.props.onCancel()
47
+  }
48
+
49
+  // 弹框取消按钮
50
+  handleCancel() {
51
+    this.props.onCancel()
52
+  }
53
+
54
+  changBuilding(buildingId){
55
+    this.getUserList({ pageNumber: 1, pageSize: 5, buildingId: buildingId })
56
+    this.setState({ visibleData: { visible: this.props.visibleData.visible, customerId: this.props.visibleData.customerId, buildingName: buildingId } });
57
+  }
58
+
59
+  getUserList(params){
60
+    console.log('params: ', params)
61
+    if (params.buildingId === '' || params.buildingId === null || params.buildingId === undefined) {
62
+      return
63
+    }
64
+    // 网路请求
65
+    request({ ...apis.customer.buildingConsultant, params: { ...params } }).then(res => {
66
+      this.setState({ dataSource: res })
67
+    }).catch(err => {
68
+      message.err(err)
69
+    })
70
+  }
71
+
72
+  getList(params) {
73
+    // 网路请求
74
+    console.log('params: ', params)
75
+    request({ ...apis.customer.buildingConsultant , params: { ...params }}).then(res => {
76
+      this.setState({ dataSource: res })
77
+    }).catch(err => {
78
+      
79
+    })
80
+  }
81
+
82
+  openNotificationWithIcon = (type, message) => {
83
+    notification[type]({
84
+      message,
85
+      description:
86
+        '',
87
+    });
88
+  };
89
+
90
+   // 分页
91
+  onChange(pageNum) {
92
+    this.getList({ pageNumber: pageNum, pageSize: 5, buildingId: this.state.visibleData.buildingName ||this.props.visibleData.buildingId})
93
+
94
+    // this.getUserList({ pageNumber: pageNum, pageSize: 5, buildingId: this.state.visibleData.buildingName })
95
+  }
96
+
97
+  // 提交
98
+  submitGm(record) {
99
+    // 网路请求
100
+    request({ ...apis.customer.batchConsultantAssist, data: { userId: record.userId
101
+      ,buildingId:this.state.visibleData.buildingName  || this.props.visibleData.buildingId
102
+      , customerIds: this.state.visibleData.customerId } }).then(res => {
103
+      // eslint-disable-next-line no-unused-expressions
104
+      debugger
105
+      if(res!= null && res.failNum > 0 ){
106
+        this.openNotificationWithIcon('success', '共'+res.totalNum+'条数据,失败操作'+res.failNum+'条')
107
+      }else{
108
+        this.openNotificationWithIcon('success', '操作成功')
109
+      }
110
+      this.handleCancel()
111
+    }).catch(err => {
112
+      // eslint-disable-next-line no-unused-expressions
113
+  
114
+    })
115
+  }
116
+
117
+  render() {
118
+    const columns = [
119
+      // {
120
+      //   title: '编号',
121
+      //   dataIndex: 'userId',
122
+      //   key: 'userId',
123
+      // },
124
+      {
125
+        title: '姓名',
126
+        dataIndex: 'userName',
127
+        key: 'userName',
128
+      },
129
+      {
130
+        title: '电话',
131
+        dataIndex: 'phone',
132
+        key: 'phone',
133
+      },
134
+      {
135
+        title: '部门',
136
+        dataIndex: 'department',
137
+        key: 'department',
138
+      },
139
+      {
140
+        title: '岗位',
141
+        dataIndex: 'position',
142
+        key: 'position',
143
+      },
144
+      {
145
+        title: '操作',
146
+        dataIndex: 'personId',
147
+        key: 'personId',
148
+        // eslint-disable-next-line no-nested-ternary
149
+        render: (_, record) => <>{ <Button type="danger" onClick={() => this.submitGm(record)}>确定</Button>}</>, },
150
+    ]
151
+    return (
152
+      <>
153
+        <Modal
154
+            title="分配置业顾问"
155
+            width={800}
156
+            destroyOnClose="true"
157
+            footer={null}
158
+            visible={this.state.visibleData.visible}
159
+            onCancel={(e) => this.handleCancel(e)}
160
+          >
161
+            <span>你正在为{this.props.visibleData.customerId.length}位公客分配置业顾问</span><br/><br/>
162
+            {this.props.visibleData.buildingId == null && <BuildSelect onChange={this.changBuilding.bind(this)} value={this.state.visibleData.buildingName} />}
163
+            <Table rowKey="BatchAssistConsultant" dataSource={this.state.dataSource.records} columns={columns} pagination={{pageSize: 5, total: this.state.dataSource.total, onChange: e => this.onChange(e) }} />
164
+          </Modal>
165
+      </>
166
+    );
167
+  }
168
+}
169
+
170
+export default ModalAttribution

+ 77
- 0
src/pages/customer/Customer/PublicCustomer/AssistConsultant/ChangeStatus.jsx Wyświetl plik

@@ -0,0 +1,77 @@
1
+import React, { useState, useEffect } from 'react';
2
+import {
3
+  Button,
4
+  Radio,
5
+  Modal,
6
+  notification,
7
+} from 'antd';
8
+import request from '@/utils/request';
9
+import apis from '@/services/apis';
10
+
11
+const ChangeStatus = props => {
12
+  console.log(props, 'props');
13
+
14
+  const [value, setValue] = useState();
15
+
16
+  const { visible, data } = props.modelProps || {};
17
+
18
+  useEffect(() => {
19
+    console.log(data, 'data');
20
+    setValue(data?.status);
21
+  }, [data]);
22
+
23
+  const openNotificationWithIcon = (type, message) => {
24
+    notification[type]({
25
+      message,
26
+      description: '',
27
+    });
28
+  };
29
+
30
+const  submitButton = () => {
31
+    // 网路请求
32
+    request({
33
+      ...apis.customer.recommendEdit,
34
+      urlData: { id: data.customerId },
35
+      data: { customerId: data.customerId, status: value },
36
+    })
37
+      .then(() => {
38
+        // eslint-disable-next-line no-unused-expressions
39
+        openNotificationWithIcon('success', '操作成功');
40
+        props.handleCancel()
41
+      })
42
+      .catch(err => {
43
+        // eslint-disable-next-line no-unused-expressions
44
+        openNotificationWithIcon('error', err);
45
+      });
46
+  };
47
+
48
+  return (
49
+    <>
50
+      <Modal
51
+        title="变更状态"
52
+        width={800}
53
+        destroyOnClose="true"
54
+        footer={null}
55
+        visible={visible}
56
+        // onOk={() => this.handleOk()}
57
+        onCancel={() => props.onCancel()}
58
+      >
59
+        {data && (
60
+          <>
61
+            <Radio.Group value={value} onChange={e => setValue(e.target.value)}>
62
+              <Radio value={1}>客户报备</Radio>
63
+              <Radio value={2}>客户到访</Radio>
64
+              <Radio value={3}>客户认购</Radio>
65
+              <Radio value={4}>客户签约</Radio>
66
+            </Radio.Group>
67
+            <Button type="primary" onClick={submitButton}>
68
+              确定
69
+            </Button>
70
+          </>
71
+        )}
72
+      </Modal>
73
+    </>
74
+  );
75
+};
76
+
77
+export default ChangeStatus;

+ 140
- 0
src/pages/customer/Customer/PublicCustomer/AssistConsultant/IntegralRecord.jsx Wyświetl plik

@@ -0,0 +1,140 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Select, Card, Modal, notification, Table } from 'antd';
3
+import moment from 'moment';
4
+import request from '@/utils/request';
5
+import apis from '@/services/apis';
6
+import Styles from '../../style.less';
7
+
8
+/**
9
+ * 积分记录
10
+ *
11
+ * @param {*} props
12
+ * @returns
13
+ */
14
+const IntegralRecord = props => {
15
+  const { visible, data } = props.modelProps || {};
16
+
17
+  const [tableData, setTableData] = useState({});
18
+  const [totalPoints, setTotalPoints] = useState();
19
+const [loading,setLoading] = useState(false)
20
+  function getList(params) {
21
+    const { personId } = data || {};
22
+    if (personId === '' || personId === undefined) {
23
+      return;
24
+    }
25
+
26
+    console.log(personId, 'customerId');
27
+    // 网路请求
28
+    setLoading(true);
29
+    request({
30
+      ...apis.customer.taPointsRecords,
31
+      urlData: { id: personId },
32
+      params: { ...params },
33
+    })
34
+      .then(res => {
35
+        console.log(res, 'res');
36
+        setTableData(res.result);
37
+        setTotalPoints(res.totalPoints);
38
+        setLoading(false);
39
+      })
40
+      .catch(err => {
41
+        this.openNotificationWithIcon('error', err);
42
+        setLoading(false);
43
+      });
44
+  }
45
+
46
+  useEffect(() => {
47
+    if (visible) {
48
+      getList({ pageNumber: 1, pageSize: 5 });
49
+    }else{
50
+      setTableData({})
51
+    }
52
+  }, [visible]);
53
+
54
+  // 分页
55
+  function onChange(pageNum) {
56
+    this.getList({ pageNumber: pageNum, pageSize: 5 });
57
+  }
58
+
59
+  // 积分类型
60
+  function showChangeType(str) {
61
+    switch (str) {
62
+      case 'goods':
63
+        return '兑换商品';
64
+      case 'checkin':
65
+        return '签到';
66
+      case 'share-poster':
67
+        return '分享';
68
+      case 'signup-agent':
69
+        return '授权手机号';
70
+      case 'activity_checkin':
71
+        return '活动签到';
72
+      case 'document_verify':
73
+        return '资料审核';
74
+      case 'recommend-customer':
75
+        return '推荐客户';
76
+      case 'group':
77
+        return '拼团';
78
+      case 'recommend-customer':
79
+        return '推荐客户';
80
+      default:
81
+        return '未知类型';
82
+    }
83
+  }
84
+
85
+
86
+
87
+  const columns = [
88
+    {
89
+      title: '序号',
90
+      dataIndex: 'index',
91
+      key: 'index',
92
+      render: (_text, _record, index) => <span>{index + 1}</span>,
93
+    },
94
+    {
95
+      title: '积分类型',
96
+      dataIndex: 'changeType',
97
+      key: 'changeType',
98
+      render: (_, record) => <span>{showChangeType(record.changeType)}</span>,
99
+    },
100
+    {
101
+      title: '积分变化',
102
+      dataIndex: 'pointsAmount',
103
+      key: 'pointsAmount',
104
+    },
105
+    {
106
+      title: '发生时间',
107
+      dataIndex: 'createDate',
108
+      key: 'createDate',
109
+      render: (createDate) => <span> {moment(createDate).format('YYYY-MM-DD')}</span>,
110
+    },
111
+  ];
112
+  return (
113
+    <>
114
+      <Modal
115
+        title={'当前可用积分:' + (totalPoints || 0)}
116
+        width={800}
117
+        destroyOnClose="true"
118
+        footer={null}
119
+        visible={visible}
120
+        // onOk={() => this.handleOk()}
121
+        onCancel={() => props.onCancel()}
122
+      >
123
+        {data && (
124
+          <Table
125
+            dataSource={tableData.records}
126
+            columns={columns}
127
+            loading={loading}
128
+            pagination={{
129
+              pageSize: tableData.pageSize,
130
+              total: tableData.total,
131
+              onChange: e => onChange(e),
132
+            }}
133
+          />
134
+        )}
135
+      </Modal>
136
+    </>
137
+  );
138
+};
139
+
140
+export default IntegralRecord;

+ 285
- 0
src/pages/customer/Customer/PublicCustomer/AssistConsultant/Recommend.jsx Wyświetl plik

@@ -0,0 +1,285 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Table, Modal, notification } from 'antd';
3
+import moment from 'moment';
4
+import request from '@/utils/request';
5
+import apis from '@/services/apis';
6
+
7
+/**
8
+ * 推荐客户
9
+ *
10
+ * @param {*} props
11
+ * @returns
12
+ */
13
+
14
+const Recommend = props => {
15
+  const { visible, data } = props.modelProps || {};
16
+
17
+  const [tableData, setTableData] = useState({});
18
+  const [loading, setLoading] = useState(false);
19
+
20
+  const openNotificationWithIcon = (type, message) => {
21
+    notification[type]({
22
+      message,
23
+      description: '',
24
+    });
25
+  };
26
+
27
+  function getList(params) {
28
+    const { personId } = data || {};
29
+    if (personId === '' || personId === undefined) {
30
+      return;
31
+    }
32
+    // 网路请求
33
+    setLoading(true);
34
+    request({
35
+      ...apis.customer.recommendClient,
36
+      urlData: { id: personId },
37
+      params: { ...params },
38
+    })
39
+      .then(res => {
40
+        console.log(res, 'res');
41
+        setTableData(res);
42
+        setLoading(false);
43
+      })
44
+      .catch(err => {
45
+        this.openNotificationWithIcon('error', err);
46
+        setLoading(false);
47
+      });
48
+  }
49
+
50
+  useEffect(() => {
51
+    if (visible) {
52
+      getList({ pageNumber: 1, pageSize: 5 });
53
+    } else {
54
+      setTableData({});
55
+    }
56
+  }, [visible]);
57
+
58
+  // 分页
59
+  function onChange(pageNum) {
60
+    this.getList({ pageNumber: pageNum, pageSize: 5 });
61
+  }
62
+
63
+  const columns = [
64
+    {
65
+      title: '头像',
66
+      dataIndex: 'picture',
67
+      key: 'picture',
68
+      // eslint-disable-next-line jsx-a11y/alt-text
69
+      render: text => <img src={text} width={50} height={50} />,
70
+    },
71
+    {
72
+      title: '用户名',
73
+      dataIndex: 'name',
74
+      key: 'name',
75
+    },
76
+    {
77
+      title: '电话',
78
+      dataIndex: 'phone',
79
+      key: 'phone',
80
+    },
81
+    {
82
+      title: '性别',
83
+      dataIndex: 'sex',
84
+      key: 'sex',
85
+      render: text => <span>{text === 1 ? '男' : '女'}</span>,
86
+    },
87
+    {
88
+      title: '意向项目',
89
+      dataIndex: 'intention',
90
+      key: 'intention',
91
+    },
92
+    {
93
+      title: '推荐时间',
94
+      dataIndex: 'createDate',
95
+      key: 'createDate',
96
+      render: (_, record) => (
97
+        <>
98
+          <span>
99
+            {record.createDate && moment(record.createDate).format('YYYY-MM-DD HH:mm:ss')}
100
+          </span>
101
+        </>
102
+      ),
103
+    },
104
+    {
105
+      title: '状态',
106
+      dataIndex: 'state',
107
+      key: 'state',
108
+      // eslint-disable-next-line consistent-return
109
+      render: (_, records) => {
110
+        if (records.verifyStatus === 0) {
111
+          return '未审核';
112
+        }
113
+        if (records.verifyStatus === 1) {
114
+          if (records.reportRecommendStatus === 1) {
115
+            return '报备';
116
+          }
117
+          if (records.reportRecommendStatus === 2) {
118
+            return '推荐';
119
+          }
120
+        }
121
+        if (records.verifyStatus === 2) {
122
+          return '审核不通过';
123
+        }
124
+      },
125
+    },
126
+  ];
127
+
128
+  return (
129
+    <>
130
+      <Modal
131
+        title={'推荐客户'}
132
+        width={800}
133
+        destroyOnClose="true"
134
+        footer={null}
135
+        visible={visible}
136
+        // onOk={() => this.handleOk()}
137
+        onCancel={() => props.onCancel()}
138
+      >
139
+        {data && (
140
+          <Table
141
+            dataSource={tableData.records}
142
+            columns={columns}
143
+            loading={loading}
144
+            pagination={{
145
+              pageSize: tableData.pageSize,
146
+              total: tableData.total,
147
+              onChange: e => onChange(e),
148
+            }}
149
+          />
150
+        )}
151
+      </Modal>
152
+    </>
153
+  );
154
+};
155
+
156
+export default Recommend;
157
+
158
+// class ModalRecommendRecord extends React.Component {
159
+//   constructor(props) {
160
+//     super(props);
161
+//     this.state = {
162
+//        dataSource: [],
163
+//        visibleData: { visible: false, customerId: '' },
164
+//     }
165
+//   }
166
+
167
+//   // 挂载之后
168
+//   componentDidMount() {
169
+//     this.getList({ pageNumber: 1, pageSize: 5 })
170
+//   }
171
+
172
+//   componentDidUpdate(preProps, preState) {
173
+//     // console.log('this.props.visibleData', this.props.visibleData)
174
+//     if (this.props.visibleData.customerId !== preState.visibleData.customerId) {
175
+//       this.getList({ pageNumber: 1, pageSize: 5 })
176
+//       this.setState({ visibleData: this.props.visibleData });
177
+//     }
178
+//   }
179
+
180
+//   // 弹框确定按钮
181
+//   // eslint-disable-next-line react/sort-comp
182
+//   handleOk() {
183
+//     this.props.onCancel()
184
+//   }
185
+
186
+//   // 弹框取消按钮
187
+//   handleCancel() {
188
+//     this.props.onCancel()
189
+//   }
190
+
191
+//   openNotificationWithIcon = (type, message) => {
192
+//     notification[type]({
193
+//       message,
194
+//       description:
195
+//         '',
196
+//     });
197
+//   }
198
+
199
+//   getList(params) {
200
+//     const { customerId } = this.state.visibleData
201
+//     if (customerId === '' || customerId === undefined) {
202
+//       return
203
+//     }
204
+//     console.log('customerId', customerId)
205
+//     // 网路请求
206
+//     // 网路请求
207
+//     request({ ...apis.customer.recommendClient, urlData: { id: customerId }, params: { ...params } }).then(res => {
208
+//       this.setState({ dataSource: res })
209
+//     }).catch(err => {
210
+//       this.openNotificationWithIcon('error', err)
211
+//     })
212
+//   }
213
+
214
+//    // 分页
215
+//   onChange(pageNum) {
216
+//     this.getList({ pageNumber: pageNum, pageSize: 5 })
217
+//   }
218
+
219
+//   render() {
220
+//     const columns = [
221
+//       {
222
+//         title: '头像',
223
+//         // eslint-disable-next-line jsx-a11y/alt-text
224
+//         render: (text, records) => <img src={records.picture} width={50} height={50} />,
225
+//       },
226
+//       {
227
+//         title: '用户名',
228
+//         dataIndex: 'name',
229
+//         key: 'name',
230
+//       },
231
+//       {
232
+//         title: '电话',
233
+//         dataIndex: 'phone',
234
+//         key: 'phone',
235
+//       },
236
+//       {
237
+//         title: '性别',
238
+//         dataIndex: 'sex',
239
+//         key: 'sex',
240
+//         render: (text, records) => <span>{records.sex === 1 ? '男' : '女'}</span>,
241
+//       },
242
+//       {
243
+//         title: '意向项目',
244
+//         dataIndex: 'intention',
245
+//         key: 'intention',
246
+//       },
247
+//       {
248
+//         title: '推荐时间',
249
+//         dataIndex: 'createDate',
250
+//         key: 'createDate',
251
+//         render: (_, record) => <><span>{ record.createDate && moment(record.createDate).format('YYYY-MM-DD HH:mm:ss') }</span></>,
252
+//       },
253
+//       {
254
+//         title: '状态',
255
+//         // eslint-disable-next-line consistent-return
256
+//         render: (text, records) => {
257
+//           if (records.verifyStatus === 0) { return '未审核' }
258
+//           if (records.verifyStatus === 1) {
259
+//             if (records.reportRecommendStatus === 1) { return '报备' }
260
+//             if (records.reportRecommendStatus === 2) { return '推荐' }
261
+//            }
262
+//           if (records.verifyStatus === 2) { return '审核不通过' }
263
+//         },
264
+//       },
265
+//     ]
266
+//     return (
267
+//       <>
268
+//         <Modal
269
+//             title="推荐客户"
270
+//             width={800}
271
+//             destroyOnClose="true"
272
+//             footer={null}
273
+//             visible={this.state.visibleData.visible}
274
+//             // onOk={() => this.handleOk()}
275
+//             onCancel={(e) => this.handleCancel(e)}
276
+//           >
277
+//             {console.log('this.state.dataSource11111111111', this.state.dataSource.total)}
278
+//             <Table dataSource={this.state.dataSource.records} rowKey="integralrecord" columns={columns} pagination={{ total: this.state.dataSource.total, pageSize: this.state.dataSource.size, onChange: e => this.onChange(e) }} />
279
+//           </Modal>
280
+//       </>
281
+//     );
282
+//   }
283
+// }
284
+
285
+// export default ModalRecommendRecord

+ 354
- 0
src/pages/news/list/NewsList.jsx Wyświetl plik

@@ -0,0 +1,354 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Form, Icon, Input, Button, DatePicker, Select, Modal, message, Card, Row, Col, Pagination, Alert } from 'antd';
3
+import moment from 'moment';
4
+import router from 'umi/router';
5
+import request from '../../../utils/request';
6
+import apis from '../../../services/apis';
7
+import Styles from './style.less';
8
+import styles from '../../style/GoodsList.less';
9
+import NewsTypeSelect from '../../../components/SelectButton/NewTypeSelect'
10
+import BuildSelect from '../../../components/SelectButton/BuildSelect'
11
+import SelectCity from '../../../components/SelectButton/CitySelect'
12
+import Prompt from 'umi/prompt';
13
+
14
+import AuthButton from '@/components/AuthButton';
15
+import EditIcon from '@/components/EditIcon';
16
+import Navigate from '@/components/Navigate';
17
+
18
+
19
+const { Option } = Select;
20
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
21
+const { Meta } = Card;
22
+
23
+const tempDate = [{ code: 's101' }]
24
+
25
+/**
26
+ *
27
+ *
28
+ * @param {*} props
29
+ * @returns
30
+ */
31
+function body(props) {
32
+  const { getFieldDecorator } = props.form
33
+
34
+  // eslint-disable-next-line react-hooks/rules-of-hooks
35
+  const [dataSource, setDataSource] = useState({ records: [] })
36
+  const [page, setPage] = useState(props.location.query.page || 1)
37
+
38
+
39
+  // eslint-disable-next-line react-hooks/rules-of-hooks
40
+  useEffect(() => {
41
+    if (localStorage.getItem("newsPageParams")) {
42
+      props.form.setFieldsValue(JSON.parse(localStorage.getItem("newsPageParams")));
43
+      // const { getFieldDecorator } = JSON.parse(localStorage.getItem("pageParams"))
44
+
45
+      getList(JSON.parse(localStorage.getItem("newsPageParams")))
46
+    } else {
47
+      localStorage.setItem("newsPageParams", JSON.stringify({ pageNum: 1, pageSize: 6 }));
48
+      getList({ pageNum: 1, pageSize: 6 })
49
+    }
50
+  }, [])
51
+
52
+  function getList(params) {
53
+    // 网路请求
54
+    request({ ...apis.news.getList, params: { ...params } }).then(res => {
55
+      setDataSource(res)
56
+    }).catch(err => {
57
+      // eslint-disable-next-line no-unused-expressions
58
+      <Alert
59
+        style={{
60
+          marginBottom: 24,
61
+        }}
62
+        message={err}
63
+        type="error"
64
+        showIcon
65
+      />
66
+    })
67
+  }
68
+
69
+  // 提交事件
70
+  function handleSubmit(e) {
71
+    e.preventDefault();
72
+    props.form.validateFields((err, values) => {
73
+      if (!err) {
74
+        console.log('提交数据: ', values)
75
+        const { startDate } = values
76
+        localStorage.setItem("newsPageParams", (JSON.stringify({ pageNum: 1, pageSize: 6, ...values })));
77
+        getList({ pageNum: 1, pageSize: 6, ...values })
78
+      }
79
+    });
80
+  }
81
+
82
+  // 跳转到编辑资讯列表
83
+  const toEditList = (id) => () => {
84
+    router.push({
85
+      pathname: '/news/list/editNewsList',
86
+      query: {
87
+        id
88
+      },
89
+    });
90
+  }
91
+
92
+
93
+
94
+  /**
95
+   *卡片
96
+   *
97
+   * @returns
98
+   */
99
+  function CartBody(props) {
100
+    const { data } = props
101
+    console.log(data);
102
+    const cancelPage = () => {
103
+      router.push({
104
+        pathname: '/news/list/NewsList',
105
+      });
106
+    }
107
+
108
+    //删除资讯
109
+    const changeNewsListStatus = (row, newsId) => () => {
110
+      Modal.confirm({
111
+        title: '资讯会被删除,小程序端和后台都无法再看到',
112
+        okText: '确认',
113
+        cancelText: '取消',
114
+        onOk() {
115
+          request({ ...apis.news.put, urlData: { id: newsId }, data: { ...row, status: -1 } }).then((data) => {
116
+            message.info('操作成功!')
117
+            getList(JSON.parse(localStorage.getItem("newsPageParams")));
118
+          }).catch((err) => {
119
+            console.log(err)
120
+            message.info(err.msg || err.message)
121
+          })
122
+        }
123
+      });
124
+    }
125
+
126
+    // 跳转到编辑资讯列表
127
+    const toEditList = (newsId) => () => {
128
+      router.push({
129
+        pathname: '/news/list/editNewsList',
130
+        query: {
131
+          newsId,
132
+        },
133
+      });
134
+    }
135
+
136
+    //   置顶
137
+    const topNews = (weightParam, newsId) => () => {
138
+      const weight = Math.abs(weightParam - 1)
139
+      request({ ...apis.news.weight, params: { newsId: newsId, weight } }).then((data) => {
140
+        console.log(data)
141
+        message.info('操作成功!')
142
+        getList(JSON.parse(localStorage.getItem("newsPageParams")))
143
+      }).catch((err) => {
144
+        console.log(err)
145
+        message.info(err.msg || err.message)
146
+      })
147
+    }
148
+
149
+    function cancelRelease(newsId, newsStatus, buildingId, newsTypeId) {
150
+      console.log("newsId" + newsId + "status" + newsStatus);
151
+      if (newsStatus === 1) {
152
+        Modal.confirm({
153
+          title: '资讯会在小程序端隐藏,后台可继续编辑重新发布',
154
+          okText: '确认',
155
+          cancelText: '取消',
156
+          onOk() {
157
+            request({ ...apis.news.cancel, data: { "newsStatus": newsStatus, "buildingId": buildingId, "newsTypeId": newsTypeId }, urlData: { id: newsId }, }).then((data) => {
158
+              message.info('操作成功!')
159
+              getList(JSON.parse(localStorage.getItem("newsPageParams")));
160
+            }).catch((err) => {
161
+              console.log(err)
162
+              message.info(err.msg || err.message)
163
+            })
164
+          },
165
+          onCancel() {
166
+            console.log('Cancel');
167
+          },
168
+        });
169
+      } else if (newsStatus === 0) {
170
+        Modal.confirm({
171
+          title: '确认发布该资讯?',
172
+          okText: '确认',
173
+          cancelText: '取消',
174
+          onOk() {
175
+            request({ ...apis.news.cancel, data: { "newsStatus": newsStatus, "buildingId": buildingId, "newsTypeId": newsTypeId }, urlData: { id: newsId }, }).then((data) => {
176
+              message.info('操作成功!')
177
+              getList(JSON.parse(localStorage.getItem("newsPageParams")));
178
+            }).catch((err) => {
179
+              console.log(err)
180
+              message.info(err.msg || err.message)
181
+            })
182
+          },
183
+          onCancel() {
184
+            console.log('Cancel');
185
+          },
186
+        });
187
+      }
188
+    }
189
+
190
+    return (
191
+      <Card
192
+        // hoverable
193
+        style={{ height: '230px', minWidth: '570px', borderRadius: '12px', margin: '10px', boxShadow: '0px 0px 16px 2px rgba(0,0,0,0.12)', position: 'relative' }}
194
+        cover={<img alt="example" src={data.newsImg} style={{ borderRadius: '12px 0 0 12px', width: '230px', height: '228px' }}></img>}
195
+        bodyStyle={{ padding: '10px 20px' }}
196
+      >
197
+        <AuthButton name="admin.taNews.top" noRight={null}>
198
+          <span style={{ position: 'absolute', right: '83px', top: '16px', fontSize: ' 0.106rem', zIndex: 1, color: '#FF7E48', cursor: 'pointer' }} onClick={topNews(data.weight, data.newsId)}>{data.weight === 1 ? '取消置顶' : '置顶'}</span>
199
+        </AuthButton>
200
+
201
+        <AuthButton name="admin.taNews.id.put" noRight={null}>
202
+          <span style={{ position: 'absolute', right: '10px', top: '16px', fontSize: ' 0.106rem', zIndex: 1, color: '#FF7E48', cursor: 'pointer' }} onClick={toEditList(data.newsId)}>
203
+            <EditIcon text="编辑" color='#ff925c' type="edit"></EditIcon>
204
+          </span>
205
+        </AuthButton>
206
+        <AuthButton name="admin.taNews.publish" noRight={null}>
207
+          {data.newsStatus === 0 ?
208
+            <span style={{ position: 'absolute', left: '250px', bottom: ' 10px', fontSize: ' 0.106rem', color: '#FF7E48', zIndex: 1, cursor: 'pointer' }} onClick={cancelRelease.bind(this, data.newsId, 1, data.buildingId, data.newsType.newsTypeId)}>
209
+              <EditIcon text="取消发布" color='#FF4A4A' type="cancel"></EditIcon>
210
+            </span> :
211
+            <span style={{ position: 'absolute', left: '250px', bottom: ' 10px', fontSize: ' 0.106rem', color: '#FF7E48', zIndex: 1, cursor: 'pointer' }} onClick={cancelRelease.bind(this, data.newsId, 0, data.buildingId, data.newsType.newsTypeId)}>
212
+              <EditIcon text="发布" color='#ff925c' type="publish"></EditIcon>
213
+            </span>
214
+          }
215
+        </AuthButton>
216
+        <AuthButton name="admin.taNews.id.delete" noRight={null}>
217
+          <span style={{ position: 'absolute', right: '20px', bottom: ' 10px', fontSize: ' 0.106rem', color: '#FF7E48', cursor: 'pointer', zIndex: 1 }} onClick={changeNewsListStatus(data, data.newsId)}>
218
+            <EditIcon text="删除" color='#FF4A4A' type="delete"></EditIcon>
219
+          </span>
220
+        </AuthButton>
221
+        <div style={{ position: 'absolute', left: '240px', top: '0px', padding: '16px 10px', width: '64%' }}>
222
+          <p style={{
223
+            fontSize: ' 0.106rem', color: '#333', fontWeight: '600', marginBottom: '10px', overflow: 'hidden',
224
+            textOverflow: 'ellipsis',
225
+            whiteSpace: 'nowrap',
226
+            width: '75%',
227
+          }}><Navigate to={`/news/list/editNewsList?newsId=${data.newsId}`}>{data.newsName}</Navigate></p>
228
+          <p style={{ fontSize: ' 0.106rem', color: '#555', marginBottom: '8px', display: 'flex' }}>
229
+            <span style={{ display: 'inline-block', width: '50%', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>资讯类型:{data.newsType.newsTypeName}</span>
230
+            <span>状态:{data.newsStatus == 0 ? "已发布" : "未发布"}</span>
231
+          </p>
232
+
233
+          <p style={{ fontSize: ' 0.106rem', color: '#555', marginBottom: '8px', display: 'flex', alignItems: 'center' }}>
234
+            <span style={{ display: 'inline-block', width: '50%', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>阅读数量:{data.pvNum}</span>
235
+            <span>转发数量:{data.shareNum}</span>
236
+          </p>
237
+
238
+          <p style={{ fontSize: ' 0.106rem', color: '#555', marginBottom: '8px', display: 'flex', alignItems: 'center' }}>
239
+            {/* <span style={{ display: 'inline-block', width: '50%', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>点赞数量:{data.favorNum}</span> */}
240
+            <span>收藏数量:{data.saveNum}</span>
241
+          </p>
242
+
243
+          <p style={{ fontSize: ' 0.106rem', color: '#999', marginBottom: '8px' }}>发布时间:{moment(data.createDate).format('YYYY-MM-DD HH:mm:ss')}</p>
244
+        </div>
245
+      </Card>
246
+    )
247
+  }
248
+
249
+
250
+  // Change 事件
251
+  function handleSelectChange(e) {
252
+    // eslint-disable-next-line no-console
253
+    console.log(e)
254
+  }
255
+
256
+  // 分页
257
+  function onChange(pageNumber) {
258
+    props.form.validateFields((err, values) => {
259
+      if (!err) {
260
+        localStorage.setItem("newsPageParams", JSON.stringify({ pageNum: pageNumber, pageSize: 6, ...values }));
261
+        // eslint-disable-next-line react-hooks/rules-of-hooks
262
+        getList({ pageNum: pageNumber, pageSize: 6, ...values })
263
+      }
264
+    });
265
+  }
266
+
267
+  //重置搜索
268
+  function handleReset() {
269
+    props.form.resetFields();
270
+    localStorage.setItem("newsPageParams", JSON.stringify({ pageNum: 1, pageSize: 6 }));
271
+    getList({ pageNum: 1, pageSize: 6 })
272
+  }
273
+
274
+  function getDate(value, dateString) {
275
+    // moment(value).format('YYYY-MM-DD HH:mm:ss')
276
+    console.log(value, dateString)
277
+  }
278
+
279
+  return (
280
+    <>
281
+      <Form layout="inline" onSubmit={e => handleSubmit(e, props)}>
282
+
283
+        <Form.Item>
284
+          {getFieldDecorator('cityId')(
285
+            <SelectCity />,
286
+          )}
287
+        </Form.Item>
288
+        <Form.Item>
289
+          {getFieldDecorator('buildingId')(
290
+            <BuildSelect />,
291
+          )}
292
+        </Form.Item>
293
+        <Form.Item>
294
+          {getFieldDecorator('title')(
295
+            <Input
296
+              prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
297
+              placeholder="请输入标题"
298
+            />,
299
+          )}
300
+        </Form.Item>
301
+        <Form.Item>
302
+          {getFieldDecorator('newsTypeId')(
303
+            <NewsTypeSelect />,
304
+          )}
305
+        </Form.Item>
306
+        <Form.Item>
307
+          {getFieldDecorator('newsStatus')(
308
+            <Select style={{ width: '180px' }} placeholder="状态">
309
+              <Option value="0">已发布</Option>
310
+              <Option value="1">未发布</Option>
311
+            </Select>,
312
+          )}
313
+        </Form.Item>
314
+        <Form.Item>
315
+          <AuthButton name="admin.news.search" noRight={null}>
316
+            <Button type="primary" htmlType="submit" >
317
+              搜索
318
+            </Button>
319
+          </AuthButton>
320
+          <Button style={{ marginLeft: 8 }} onClick={handleReset}>
321
+            重置
322
+            </Button>
323
+        </Form.Item>
324
+      </Form>
325
+      <AuthButton name="admin.taNews.post" noRight={null}>
326
+        <Button type="danger" style={{ padding: '0 40px', margin: '20px 0' }} onClick={toEditList()}>
327
+          新增
328
+        </Button>
329
+      </AuthButton>
330
+
331
+      {/* 卡片内容,显示楼盘项目  */}
332
+      <Row>
333
+        {
334
+          dataSource.records.map((item, index) => (
335
+            <Col span={12}>
336
+              <CartBody data={item} key={item.buildingId} />
337
+            </Col>
338
+          ))
339
+        }
340
+      </Row>
341
+      {/* 分页 */}
342
+      <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '30px' }}>
343
+        <Pagination showQuickJumper defaultCurrent={1} total={dataSource.total} pageSize={6} onChange={onChange} current={dataSource.current} />
344
+      </div>
345
+      <Prompt message={location =>
346
+        location.pathname.startsWith("/news/list")
347
+          ? true
348
+          : localStorage.removeItem("newsPageParams")} />
349
+    </>
350
+  );
351
+}
352
+const WrappedBody = Form.create({ name: 'body' })(body);
353
+
354
+export default WrappedBody

+ 398
- 0
src/pages/news/list/editNewsList.jsx Wyświetl plik

@@ -0,0 +1,398 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Input, Button, Radio, message } from 'antd';
3
+import apis from '../../../services/apis';
4
+import router from 'umi/router';
5
+import BuildSelect from '../../../components/SelectButton/BuildSelect2'
6
+import NewsTypeSelect from '../../../components/SelectButton/NewTypeSelect'
7
+import  { FieldTypes, createForm } from '../../../components/XForm';
8
+import Wangedit from '../../../components/Wangedit/Wangedit'
9
+import request from '../../../utils/request'
10
+import ImageUploader from '../../../components/XForm/ImageUpload';
11
+import logo from '../../../assets/logo.png';
12
+import yinhao from '../../../assets/yinhao.png'
13
+import touxiang from '../../../assets/touxiang.jpg';
14
+import poster1 from '../../../assets/poster1.png';
15
+import poster2 from '../../../assets/poster2.png';
16
+import xiaochengxu from '../../../assets/xiaochengxu.png'
17
+import Prompt from 'umi/prompt';
18
+
19
+const { TextArea } = Input;
20
+
21
+let detailVisible = false;
22
+let urlVisible = false;
23
+
24
+const setExtraData = (data) => {
25
+  detailVisible = data.newsDetailType == '1'
26
+  urlVisible = data.newsDetailType == '0'
27
+}
28
+
29
+const handleFormValueChange = (props, changedValues, allValues) => {
30
+    setExtraData(allValues)
31
+}
32
+
33
+const XForm = createForm({ onValuesChange: handleFormValueChange })
34
+
35
+const cancelPage = () =>{
36
+  router.push({
37
+    pathname: '/news/list/NewsList',
38
+  });
39
+}
40
+
41
+const Basic = (props) => {
42
+  const { data: dynamicData } = props
43
+  const [ changeBuildingId, setChangeBuildingIdData ] = useState('')
44
+
45
+  const handleBuildingChange = (e) => {
46
+    console.log(e)
47
+    setChangeBuildingIdData(e)
48
+  }
49
+
50
+  const fields = [
51
+    {
52
+      label: '意向项目',
53
+      name: 'buildingId',
54
+      render: <BuildSelect onChange={(e => handleBuildingChange(e))}/>,
55
+      value: dynamicData.buildingId,
56
+      rules: [
57
+        {required: true, message: '请选择所属项目'},
58
+      ]
59
+    },
60
+    {
61
+      label: '资讯列表图',
62
+      name: 'newsImg',
63
+      type: FieldTypes.ImageUploader,
64
+      value: dynamicData.newsImg,
65
+      help: '建议图片尺寸:320*240px,比例5:4,格式:jpg,用于资讯列表',
66
+      rules: [
67
+        {required: true, message: '请选择资讯列表'},
68
+      ]
69
+    },
70
+    {
71
+      label: '资讯标题',
72
+      name: 'newsName',
73
+      type: FieldTypes.Text,
74
+      value: dynamicData.newsName,
75
+      rules: [
76
+        {required: true, message: '请输入资讯标题'},
77
+      ]
78
+    },
79
+    {
80
+      label: '资讯类型',
81
+      name: 'newsTypeId',
82
+      render: <NewsTypeSelect buildingId={changeBuildingId || dynamicData.buildingId}/>,
83
+      value: dynamicData.newsTypeId,
84
+      rules: [
85
+        {required: true, message: '请选择资讯类型'},
86
+      ]
87
+    },
88
+    {
89
+      label: '资讯详情',
90
+      name: 'newsDetailType',
91
+      render: <Radio.Group> 
92
+              <Radio value={1}>自定义</Radio>
93
+              <Radio value={0}>公众号链接</Radio>
94
+              </Radio.Group>,
95
+      value: dynamicData.newsDetailType - 0,
96
+      rules: [
97
+        {required: true, message: '请选择资讯类型'},
98
+      ]
99
+    },
100
+    {
101
+      label: '详情内容',
102
+      name: 'newsDetail',
103
+      render: <Wangedit />,
104
+      hidden: () => !detailVisible,
105
+      value: dynamicData.newsDetail,
106
+      rules: [
107
+        {required: true, message: '请输入详情内容'},
108
+      ]
109
+    },
110
+    {
111
+      label: '公众号链接',
112
+      name: 'newsDetail',
113
+      type: FieldTypes.Text,
114
+      hidden: () => !urlVisible,
115
+      value: dynamicData.newsDetail,
116
+      help: "只能填写同一主体公众号的文章链接",
117
+      rules: [
118
+        {required: true, message: '请输入公众号链接'},
119
+      ]
120
+    },
121
+  ]
122
+
123
+  const handleSubmit = val => { 
124
+    console.log(dynamicData,'12312345')
125
+    let {...submitValue} = val
126
+    
127
+    if(dynamicData.newsId){
128
+      submitValue.newsId = dynamicData.newsId
129
+      request({ ...apis.news.put, urlData: {id: dynamicData.newsId}, data: { ...submitValue },}).then((data) => {
130
+        // cancelPage();
131
+        message.info("保存成功")
132
+        console.log(data,'data1')
133
+      }).catch((err) => {
134
+        message.info(err.msg || err.message)
135
+      })
136
+    }else{
137
+      request({ ...apis.news.post, data: { ...submitValue },}).then((data) => {
138
+        // cancelPage();
139
+        message.info("保存成功")
140
+        router.push({
141
+          pathname: '/news/list/editNewsList',
142
+          query: {
143
+            newsId:data.newsId
144
+          },
145
+        });
146
+        console.log(data,'data2')
147
+      }).catch((err) => {
148
+        message.info(err.msg || err.message)
149
+      })
150
+    }
151
+  }
152
+
153
+  const cancelPage = () =>{
154
+    router.push({
155
+      pathname: '/news/list/NewsList',
156
+    });
157
+  }
158
+  
159
+  return <XForm onSubmit={handleSubmit} onCancel={cancelPage}  fields={fields}></XForm>
160
+}
161
+
162
+/**
163
+ *
164
+ *
165
+ * @param {*} props
166
+ * @returns
167
+ */
168
+ const Edit = (props) => {
169
+  const [ tab, changeTab ] = useState('basic')
170
+  const newsId = props.location.query.newsId
171
+  const [ dynamicData, setDynamicData ] = useState({})
172
+
173
+    useEffect(() => {
174
+      if(newsId){
175
+        getDynamicData(newsId);
176
+      }
177
+    },[newsId])
178
+
179
+  // 查询列表
180
+  const getDynamicData = (newsId) => {
181
+    request({ ...apis.news.get, urlData: { id: newsId },}).then((data) => {
182
+      setDynamicData(data)
183
+      setExtraData(data)
184
+      // detailVisible = data.newsDetailType == '1'
185
+      // urlVisible = data.newsDetailType == '0'
186
+    }).catch((err) => {
187
+      console.log(err)
188
+      message.info(err.msg || err.message)
189
+    })
190
+    }
191
+
192
+  const Poster = (props) => {
193
+    const [inputValue, changeInput] = useState('')
194
+    const [textAreaValue, changeTextArea] = useState('')
195
+    const [imgValue, changeImg] = useState('')
196
+    const [posterId, setPosterId] = useState('')
197
+
198
+    if(newsId){
199
+      useEffect(() => {
200
+        request({ ...apis.activity.poster, params: {targetId: newsId,targetType: 'news'} }).then((data) => {
201
+          console.log(data,"2222")
202
+          if(data.length > 0){
203
+            setPosterId(data[0].posterId)
204
+            changeImg(data[0].posterImg)
205
+            changeTextArea(data[0].posterDescription)
206
+            changeInput(data[0].posterTitle)
207
+          }
208
+        }).catch((err) => {
209
+          message.info(err.msg || err.message)
210
+        })
211
+        getMiniappName()
212
+      }, [])
213
+    }else{
214
+      getMiniappName()
215
+    }
216
+
217
+    // 获取小程序名称
218
+  const [miniappName, setMiniappName] = useState('')
219
+  function getMiniappName() {
220
+
221
+    request({ ...apis.building.getMiniappName }).then(res => {
222
+    
223
+      setMiniappName(res)
224
+     
225
+    })
226
+  }
227
+    const submitPoster  = () => {
228
+       if(newsId){
229
+        if(posterId){
230
+          request({ ...apis.activity.updatePoster, urlData: {id: posterId}, data: {targetId: newsId,targetType: 'news',posterImg: imgValue,posterTitle: inputValue,posterDescription: textAreaValue},}).then((data) => {
231
+            message.info("保存成功")
232
+          }).catch((err) => {
233
+            message.info(err.msg || err.message)
234
+          })
235
+         }else{
236
+          request({ ...apis.activity.addPoster, data: {targetId: newsId,targetType: 'news',posterImg: imgValue,posterTitle: inputValue,posterDescription: textAreaValue},}).then((data) => {
237
+            setPosterId(data.posterId)
238
+            message.info("保存成功")
239
+          }).catch((err) => {
240
+            message.info(err.msg || err.message)
241
+          })
242
+         }
243
+       }else{
244
+        message.warn("请先保存基本信息数据")
245
+       }
246
+    }
247
+
248
+    return <div>
249
+      <div style={{ display: 'flex' }}>
250
+        <div style={{ width: '420px', height: '900px', display: 'inline-block', marginTop: '30px' }}>
251
+          <div style={{ width: '375px', height: '700px', backgroundColor: '#fff', boxShadow: '0px 0px 16px 6px rgba(0,0,0,0.15)', position: 'relative', margin: '0 auto' }}>
252
+            <img style={{ width: '100%', height: '300px' }} src={imgValue ? imgValue : poster1} alt="" />
253
+            <div style={{ display: 'flex', alignItems: 'center', marginTop: '-24px' }}>
254
+              <img style={{ width: '70px', height: '70px', border: '4px solid #fff', borderRadius: '35px', marginLeft: '16px' }} src={touxiang} alt="" />
255
+              <span style={{ color: '#222', fontWeight: '600', margin: '24px 10px 0 14px', fontSize: '17px' }}>喵喵</span>
256
+              <span style={{ color: '#999', marginTop: '25px', fontSize: '17px' }}>邀您阅读</span>
257
+              <span style={{ color: '#999', margin: '25px 0 0 60px', fontSize: '17px' }}>2019.09.21</span>
258
+            </div>
259
+            <p style={{
260
+              margin: '10px 20px', fontSize: '20px', color: '#222', fontWeight: '600',
261
+              display: '-webkit-box', lineClamp: '3', height: '60px',
262
+              WebkitLineClamp: '2',
263
+              WebkitBoxOrient: 'vertical',
264
+              overflow: 'hidden',
265
+              textOverflow: 'ellipsis'
266
+            }}>{inputValue ? inputValue : '海报标题'}</p>
267
+
268
+            <img src={yinhao} style={{ width: '30px', marginLeft: '20px' }} alt="" />
269
+            <p style={{
270
+              margin: '16px 20px 28px 20px', fontSize: '17px', color: '#999',
271
+              display: '-webkit-box', lineClamp: '3', height: '72px',
272
+              WebkitLineClamp: '3',
273
+              WebkitBoxOrient: 'vertical',
274
+              overflow: 'hidden',
275
+              textOverflow: 'ellipsis'
276
+            }}>{textAreaValue ? textAreaValue : '海报描述'}</p>
277
+               <div style={{ backgroundColor: '#f1f1f1', padding: '22px 30px', boxShadow: '0px 6px 12px -4px #dcdcdc',position:'relative' }}>
278
+            <p style={{margin:'0',fontSize:'18px',color:'#888'}}>长按识别小程序码</p>
279
+            <p style={{margin:'0',fontSize:'18px',color:'#888'}}>进入资讯查看详情</p>
280
+            <img style={{ width: '80px',position: 'absolute',right:'30px',top:'10px' }} src={xiaochengxu} alt="" />
281
+          </div>
282
+      
283
+          </div>
284
+          <p style={{ textAlign: 'center', fontSize: '19px', color: '#666', marginTop: '30px' }}>海报模板</p>
285
+        </div>
286
+
287
+        <div >
288
+          <div style={{ display: 'flex', width: '100%', margin: '60px 0' }}>
289
+            <p style={{ minWidth: '200px', color: '#222', textAlign: 'right', margin: '0 30px 0 0' }}>资讯海报图</p>
290
+            <ImageUploader value={imgValue} onChange={e => changeImg(e)} />
291
+          </div>
292
+          <p style={{ fontSize: '0.5vw', color: '#A9A9A9', marginLeft: '230px', marginBottom: '30px'}}>建议图片尺寸:640*670px,比例64:67,格式:jpg,用于资讯海报</p>
293
+          <div style={{ display: 'flex', alignItems: 'center', width: '100%', marginBottom: '60px' }}>
294
+            <p style={{ minWidth: '200px', color: '#222', textAlign: 'right', margin: '0 30px 0 0' }}>海报标题</p>
295
+            <Input style={{ width: '20vw' }} value={inputValue} placeholder="请输入海报标题" onChange={e => changeInput(e.target.value)} />
296
+          </div>
297
+          <div style={{ display: 'flex', margin: '10px 0 40px 0', width: '100%' }}>
298
+            <p style={{ minWidth: '200px', color: '#222', textAlign: 'right', margin: '0 30px 0 0' }}>海报描述</p>
299
+            <TextArea rows={5} maxLength={1024} value={textAreaValue} onChange={e => changeTextArea(e.target.value)} />
300
+          </div>
301
+
302
+        </div>
303
+      </div>
304
+      <Button type="primary" onClick={submitPoster} style={{ margin: '40px 40px 40px 30vw' }}> 确定</Button>
305
+      <Button onClick={cancelPage}>取消</Button>
306
+    </div>
307
+
308
+  }
309
+ 
310
+  const Share = (props) => {
311
+    const [inputValue, changeInput] = useState('')
312
+    const [imgValue, changeImg] = useState('')
313
+    const [shareContentId, setShareContentId] = useState('')
314
+    
315
+    if(newsId){
316
+      useEffect(() => {
317
+        request({ ...apis.activity.shareContent, params: {targetId: newsId,targetType: 'news'},}).then((data) => {
318
+          console.log(data,"2222")
319
+          if(data.length > 0){
320
+            setShareContentId(data[0].shareContentId)
321
+            changeImg(data[0].shareContentImg)
322
+            changeInput(data[0].shareContentTitle)
323
+          }
324
+        }).catch((err) => {
325
+          message.info(err.msg || err.message)
326
+        })
327
+      }, [])
328
+    }
329
+
330
+    const submitShare = () => {
331
+      if(newsId){
332
+        if(shareContentId){
333
+          request({ ...apis.activity.updateShareContent, urlData: {id: shareContentId},data: {targetId: newsId,shareContentType: 'news',shareContentImg: imgValue,shareContentTitle: inputValue},}).then((data) => {
334
+            message.info("保存成功")
335
+          }).catch((err) => {
336
+            message.info(err.msg || err.message)
337
+          })
338
+         }else{
339
+          request({ ...apis.activity.addShareContent, data: {targetId: newsId,shareContentType: 'news',shareContentImg: imgValue,shareContentTitle: inputValue},}).then((data) => {
340
+            setShareContentId(data.shareContentId)
341
+            message.info("保存成功")
342
+          }).catch((err) => {
343
+            message.info(err.msg || err.message)
344
+          })
345
+         }
346
+       }else{
347
+        message.warn("请先保存基本信息数据")
348
+       }
349
+    }
350
+
351
+    return <div style={{ padding: '20px' }}>
352
+      <div style={{ display: 'flex', margin: '10px 0 40px 0', width: '100%' }}>
353
+        <p style={{ minWidth: '200px', color: '#222', textAlign: 'right', margin: '0 30px 0 0' }}>分享模板</p>
354
+        <div>
355
+          <p style={{ display: 'flex', alignItems: 'center', fontSize: '14px', color: '#999', margin: '0', lineHeight: '0' }}><img src={logo} style={{ width: '22px', marginRight: '10px' }} />橙蕉互动</p>
356
+          <p style={{ fontSize: '16px', color: '#222', fontWeight: '600', margin: '0' }}>{inputValue ? inputValue : '置业V客厅 精准获客平台'}</p>
357
+          <img style={{ width: '200px', height: '160px' }} src={imgValue ? imgValue : poster2} alt="" />
358
+        </div>
359
+      </div>
360
+      <div style={{ display: 'flex', alignItems: 'center', width: '100%' }}>
361
+        <p style={{ minWidth: '200px', color: '#222', textAlign: 'right', margin: '0 30px 0 0' }}>分享标题</p>
362
+        <Input placeholder="请输入分享标题" value={inputValue} onChange={e => changeInput(e.target.value)} />
363
+      </div>
364
+      <div style={{ display: 'flex', width: '100%', marginTop: '40px' }}>
365
+        <p style={{ minWidth: '200px', color: '#222', textAlign: 'right', margin: '0 30px 0 0' }}>资讯分享好友图</p>
366
+        <ImageUploader value={imgValue} onChange={e => changeImg(e)} />
367
+      </div>
368
+      <p style={{ fontSize: '0.5vw', color: '#A9A9A9', marginLeft: '230px', marginTop: '20px' }}>建议图片尺寸:750*600px,比例5:4,格式:jpg,用于资讯分享好友</p>
369
+      <Button type="primary" htmlType="submit" onClick={submitShare} style={{ margin: '40px 40px 40px 220px' }}> 确定</Button>
370
+      <Button onClick={cancelPage}>取消</Button>
371
+    </div>
372
+  }
373
+
374
+  return (
375
+    <div>
376
+      <div>
377
+        <Radio.Group value={tab} buttonStyle="solid" onChange={e => changeTab(e.target.value)}>
378
+          <Radio.Button value="basic">基本信息</Radio.Button>
379
+          <Radio.Button value="poster">海报图片</Radio.Button>
380
+          <Radio.Button value="share">分享设置</Radio.Button>
381
+        </Radio.Group>
382
+      </div>
383
+      <div>
384
+        { tab === 'basic' && <Basic data={dynamicData} /> }
385
+        { tab === 'poster' && <Poster /> }
386
+        { tab === 'share' && <Share /> }
387
+      </div>
388
+      <Prompt message={location =>
389
+                          location.pathname.startsWith("/news/list")
390
+                            ? true
391
+                            : localStorage.removeItem("newsPageParams")} />
392
+    </div>
393
+  );
394
+ }
395
+
396
+
397
+
398
+export default Edit

+ 119
- 0
src/pages/news/list/style.less Wyświetl plik

@@ -0,0 +1,119 @@
1
+.SubmitButton {
2
+    background: #3a91d5;
3
+    border-radius: 7px;
4
+    border: 0px;
5
+  }
6
+  .SelectFrom {
7
+    width: 180px;
8
+    background: #ffffff;
9
+    border-radius: 7px;
10
+    border: 1px solid #dbdbdb;
11
+  }
12
+  .addButton {
13
+    background: #50be00;
14
+    border-radius: 4px;
15
+    border: 0px;
16
+    margin: 10px 0px;
17
+  }
18
+  .cardText {
19
+    color: #333;
20
+    display: flex;
21
+    align-items: center;
22
+    position: relative;
23
+    line-height: 1.5;
24
+    font-size: 0.106rem;
25
+    margin-bottom: 0.08rem;
26
+  
27
+  }
28
+  .cardItem{
29
+    color: #666;
30
+    display: flex;
31
+    align-items: center;  
32
+    line-height: 1.5;
33
+    font-size: 0.106rem;
34
+    margin-bottom: 0.08rem;
35
+  }
36
+  .ediText {
37
+    font-size: 0.106rem;
38
+    color: #ff925c;
39
+    line-height: 24px;
40
+    position: absolute;
41
+    right: 0;
42
+  }
43
+  .title{
44
+    display: inline-block;
45
+    width:  0.54rem;
46
+    justify-content: space-between;
47
+    text-align: justify;
48
+    text-align-last:justify
49
+  }
50
+  
51
+  .address { 
52
+    width: 400px;
53
+    height: 24px; 
54
+    text-overflow: ellipsis; 
55
+    white-space: nowrap;
56
+    overflow: hidden;
57
+  }
58
+
59
+  .SubmitButton {
60
+    background: rgba(239,39,58,1);
61
+    border-radius: 7px;
62
+    border: 0px;
63
+  }
64
+  .SelectFrom {
65
+    width: 180px;
66
+    background: #ffffff;
67
+    border-radius: 7px;
68
+    border: 1px solid #dbdbdb;
69
+  }
70
+  .addButton {
71
+    background: #50be00;
72
+    border-radius: 4px;
73
+    border: 0px;
74
+    margin: 10px 0px;
75
+  }
76
+  .cardText {
77
+    color: #333;
78
+    display: flex;
79
+    align-items: center;
80
+    position: relative;
81
+    line-height: 1.5;
82
+    font-size: 0.106rem;
83
+    margin-bottom: 0.08rem;
84
+  
85
+  }
86
+  .cardItem{
87
+    font-size: 0.106rem;
88
+    font-weight: 400;
89
+    color: #666;
90
+    line-height: 24px;
91
+    display: flex;
92
+    align-items: center;  
93
+  }
94
+  .ediText {
95
+    font-size:  0.106rem;
96
+    color: #ff925c;
97
+    line-height: 24px;
98
+    position: absolute;
99
+    right: 0;
100
+  }
101
+  .title{
102
+    display: inline-block;
103
+    width:  0.54rem;
104
+    justify-content: space-between;
105
+    text-align: justify;
106
+    text-align-last:justify
107
+  }
108
+  
109
+  .address { 
110
+    width: 400px;
111
+    height: 24px; 
112
+    text-overflow: ellipsis; 
113
+    white-space: nowrap;
114
+    overflow: hidden;
115
+  }
116
+  
117
+  
118
+  
119
+  

+ 148
- 0
src/pages/news/type/NewsType.jsx Wyświetl plik

@@ -0,0 +1,148 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Form, Button, message, Table, Pagination, Card } from 'antd';
3
+import router from 'umi/router';
4
+import AuthButton from '@/components/AuthButton';
5
+import withActions from '@/components/ActionList';
6
+import EditIcon from '@/components/EditIcon';
7
+import { ConfirmButton } from '@/components/ModalButton';
8
+import apis from '../../../services/apis';
9
+import request from '../../../utils/request'
10
+import BuildSelect from '../../../components/SelectButton/BuildSelect';
11
+import styles from '../../style/GoodsList.less';
12
+import Navigate from '@/components/Navigate';
13
+
14
+function NewsType(props) {
15
+  // 获取初始化数据
16
+  const [data, setData] = useState({})
17
+
18
+  useEffect(() => {
19
+    getList({ pageNum: 1, pageSize: 10 });
20
+  }, [])
21
+
22
+  // 查询列表
23
+  const getList = (params) => {
24
+    request({ ...apis.newsType.list, params: { ...params } }).then((data) => {
25
+      console.log(data)
26
+      setData(data)
27
+    })
28
+  }
29
+
30
+
31
+  // 提交事件
32
+  const handleSubmit = (e, props) => {
33
+    e.preventDefault();
34
+    props.form.validateFields((err, values) => {
35
+      if (!err) {
36
+        getList({ pageNum: 1, pageSize: 10, ...values })
37
+      }
38
+    });
39
+  }
40
+
41
+  const changePageNum = (pageNumber) => {
42
+    props.form.validateFields((err, values) => {
43
+      if (!err) {
44
+        getList({ pageNum: pageNumber, pageSize: 10, ...values })
45
+      }
46
+    });
47
+  }
48
+
49
+
50
+  // 跳转到编辑资讯
51
+  const toEditNews = (id) => () => {
52
+    router.push({
53
+      pathname: '/news/type/editNews',
54
+      query: {
55
+        id
56
+      },
57
+    });
58
+  }
59
+
60
+
61
+  const changeNewsStatus = (row, newsId) => () => {
62
+    request({ ...apis.newsType.put, urlData: { id: newsId }, data: { ...row, status: -1 } }).then((data) => {
63
+      message.info('操作成功!')
64
+      getList({ pageNum: 1, pageSize: 10 });
65
+    }).catch((err) => {
66
+      console.log(err)
67
+      message.info(err.msg || err.message)
68
+    })
69
+  }
70
+  /**
71
+   *
72
+   *
73
+   * @param {*} props
74
+   * @returns
75
+   */
76
+  const columns = [
77
+    {
78
+      title: '类型图',
79
+      dataIndex: 'newsTypeImg',
80
+      key: 'newsTypeImg',
81
+      align: 'center',
82
+      render: (text, record) => <img src={record.newsTypeImg} style={{ width: '165px', height: '104px' }} />,
83
+    },
84
+    {
85
+      title: '名称',
86
+      dataIndex: 'newsTypeName',
87
+      key: 'newsTypeName',
88
+      align: 'center',
89
+      render: (text, record) => <Navigate to={`/news/type/editNews?id=${record.newsTypeId}`}>{text}</Navigate>
90
+    },
91
+    {
92
+      title: '操作',
93
+      dataIndex: 'handle',
94
+      key: 'handle',
95
+      align: 'center',
96
+      render: withActions((x, row) => [
97
+        <AuthButton name="admin.taNewsType.id.delete" noRight={null}>
98
+          <ConfirmButton type="link" title="确认删除?" onClick={changeNewsStatus(row, row.newsTypeId)}>
99
+            <EditIcon text="删除" type="delete" />
100
+          </ConfirmButton>
101
+        </AuthButton>,
102
+        <AuthButton name="admin.taNewsType.id.put" noRight={null}>
103
+          <EditIcon text="编辑" type="edit" onClick={toEditNews(row.newsTypeId)} />
104
+        </AuthButton>,
105
+      ]),
106
+    },
107
+  ];
108
+
109
+  function handleReset() {
110
+    props.form.resetFields();
111
+    getList({ pageNum: 1, pageSize: 10 })
112
+  }
113
+
114
+  const { getFieldDecorator } = props.form
115
+  return (
116
+
117
+    <Card>
118
+      <Form layout="inline" onSubmit={e => handleSubmit(e, props)}>
119
+        <Form.Item>
120
+          {getFieldDecorator('buildingId')(
121
+            <BuildSelect />,
122
+          )}
123
+        </Form.Item>
124
+        <Form.Item>
125
+          <AuthButton name="admin.taNewsType.search" noRight={null}>
126
+            <Button type="primary" htmlType="submit" >
127
+              搜索
128
+              </Button>
129
+          </AuthButton>
130
+          <Button style={{ marginLeft: 8 }} onClick={handleReset}>
131
+            重置
132
+            </Button>
133
+        </Form.Item>
134
+      </Form>
135
+      <AuthButton name="admin.taNewsType.post" noRight={null}>
136
+        <Button type='primary' style={{margin:'20px 0'}} onClick={toEditNews()}>新增</Button>
137
+      </AuthButton>
138
+      <Table rowKey="newsType" dataSource={data.records} columns={columns} pagination={false} />
139
+      <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '30px' }}>
140
+        <Pagination showQuickJumper defaultCurrent={1} total={data.total} onChange={changePageNum} current={data.current} />
141
+      </div>
142
+    </Card>
143
+  )
144
+}
145
+
146
+const WrappedHeader = Form.create({ name: 'header' })(NewsType);
147
+
148
+export default WrappedHeader

+ 93
- 0
src/pages/news/type/editNews.jsx Wyświetl plik

@@ -0,0 +1,93 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Input, Menu, Dropdown, Button, Icon, message, Table, Divider, Tag, Select, Form, Alert } from 'antd';
3
+import { FormattedMessage } from 'umi-plugin-react/locale';
4
+import BuildSelect from '../../../components/SelectButton/BuildSelect'
5
+import XForm, { FieldTypes } from '../../../components/XForm';
6
+import router from 'umi/router';
7
+import apis from '../../../services/apis';
8
+import request from '../../../utils/request'
9
+
10
+const { TextArea } = Input;
11
+const { Option } = Select;
12
+
13
+const header = props => {
14
+  const newsId = props.location.query.id
15
+  console.log("newsId" + newsId);
16
+  const [ newsData, setNewsData ] = useState({})
17
+  if(newsId){
18
+    useEffect(() => {
19
+      getNewsData(newsId);
20
+    },[])
21
+
22
+  // 查询列表
23
+  const getNewsData = (newsId) => {
24
+    request({
25
+        ...apis.newsType.get,
26
+        urlData: { id: newsId }
27
+    }).then((data) => {
28
+        setNewsData(data)
29
+    }).catch((err) => {
30
+      message.error(err.msg || err.message)
31
+    })
32
+  }
33
+  }
34
+
35
+  const fields = [
36
+    {
37
+      label: '所属项目',
38
+      name: 'buildingId',
39
+      render: <BuildSelect />,
40
+      value: newsData.buildingId,
41
+      rules: [
42
+        {required: true, message: '请选择所属项目'},
43
+      ]
44
+    },
45
+    {
46
+      label: '类型图',
47
+      name: 'newsTypeImg',
48
+      type: FieldTypes.ImageUploader,
49
+      value: newsData.newsTypeImg,
50
+      help: '建议图片尺寸:660px*416px',
51
+    },
52
+    {
53
+      label: '名称',
54
+      name: 'newsTypeName',
55
+      type: FieldTypes.Text,
56
+      value: newsData.newsTypeName,
57
+      rules: [
58
+        {required: true, message: '请输入资讯名称'},
59
+      ]
60
+    },
61
+  ]
62
+
63
+   
64
+  const handleSubmit = (values) => {
65
+    if(newsId){
66
+        values.newsTypeId = newsId
67
+        request({ ...apis.newsType.put, urlData: { id: newsId }, data: { ...values }}).then((data) => {
68
+          cancelPage();
69
+        }).catch((err) => {
70
+          message.error(err.msg || err.message)
71
+        })
72
+      }else{
73
+        request({ ...apis.newsType.post, data: { ...values } }).then((data) => {
74
+          cancelPage();
75
+        }).catch((err) => {
76
+          message.error(err.msg || err.message)
77
+        })
78
+      }
79
+  }
80
+
81
+  const cancelPage = () => {
82
+    router.push({
83
+      pathname: '/news/type/NewsType',
84
+    });
85
+  }
86
+
87
+  return (
88
+    <XForm onSubmit={handleSubmit} onCancel={cancelPage} fields={fields}></XForm>
89
+  )
90
+}
91
+
92
+const WrappedNormalLoginForm = Form.create({ name: 'header' })(header);
93
+export default WrappedNormalLoginForm

+ 56
- 0
src/pages/news/type/style.less Wyświetl plik

@@ -0,0 +1,56 @@
1
+.searchBox {
2
+    font-size: 30px;
3
+    color: red;
4
+    display: flex;
5
+    display: flex;
6
+    justify-items: center;
7
+    align-items: center;
8
+    justify-content: space-between;
9
+    .searchItem {
10
+      min-width: 200px;
11
+      margin-right: 20px;
12
+      text-align: left;
13
+      .anticon-down {
14
+        float: right !important;
15
+      }
16
+    }
17
+  }
18
+  .addBtn {
19
+    padding: 0 30px;
20
+    height: 36px;
21
+    background-color: #50be00;
22
+    color: #fff;
23
+    margin: 30px 0;
24
+    border-color: #50be00;
25
+  }
26
+  .addBtn:focus {
27
+    color: #fff;
28
+    background-color: #50be00;
29
+    border-color: #50be00;
30
+  }
31
+  .searchBtn{
32
+   background-color: #3A91D5;
33
+   border-color: #3A91D5;
34
+  }
35
+  .searchBtn:focus {
36
+    color: #fff;
37
+    background-color: #3A91D5;
38
+    border-color: #3A91D5;
39
+  }
40
+  .touxiang {
41
+    width: 93px;
42
+    height: 93px;
43
+  }
44
+  .ant-table-column-title {
45
+    font-weight: 600;
46
+  }
47
+  .shoppingCart{
48
+    color: #dcdcdc;
49
+    margin-left: 6px;
50
+    font-size: 16px;
51
+  }
52
+  .edit{
53
+    color: #dcdcdc;
54
+    margin-left: 6px;
55
+    font-size: 15px;
56
+  }

+ 15
- 0
src/pages/staff/Organization/index.jsx Wyświetl plik

@@ -0,0 +1,15 @@
1
+import React from 'react';
2
+
3
+function Organization(props) {
4
+  
5
+
6
+
7
+  return (
8
+    <>
9
+     组织架构
10
+    </>
11
+  );
12
+}
13
+
14
+
15
+export default Organization

+ 278
- 0
src/pages/staff/Role/Edit/index.jsx Wyświetl plik

@@ -0,0 +1,278 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Checkbox, Input, Card, Form, Button, Row, Col, Spin, message } from 'antd';
3
+import { connect } from 'dva';
4
+import XForm, { FieldTypes } from '@/components/XForm';
5
+import request from '@/utils/request';
6
+import router from 'umi/router';
7
+import apis from '@/services/apis';
8
+
9
+const { TextArea } = Input;
10
+
11
+
12
+/**
13
+ *
14
+ *
15
+ * @param {*} props
16
+ * @returns
17
+ */
18
+const Poster = props => {
19
+  const userMenus = props.user.currentUser.menus;
20
+  const userBtns = props.user.currentUser.buttons;
21
+  console.log(userMenus)
22
+  // 获取当前所有菜单
23
+  const [data, setData] = useState({ data: [] })
24
+  const [buttonData, setButtonData] = useState([])
25
+
26
+  // 展示要显示的菜单和按钮----(编辑)
27
+  const [dataMenuId, setDataMenuId] = useState([])
28
+  const [dataButtonId, setDataButtonId] = useState([])
29
+
30
+  const [loading, setLoading] = useState(false);
31
+
32
+  useEffect(() => {
33
+    // 新增和编辑用一个页面
34
+    if (props.location.query) {
35
+      const { id } = props.location.query
36
+      if (id) {
37
+        buttonAndMenuList('', id)
38
+      }
39
+    }
40
+    // menuList({ pageNum: 1, pageSize: 100 })
41
+    buttonList({ pageNum: 1, pageSize: 100 })
42
+  }, [])
43
+  // 当前所有的菜单
44
+  function menuList(params) {
45
+    request({ ...apis.role.menuList, params: { ...params } }).then((data) => {
46
+      setData(data)
47
+  }).catch((err) => {
48
+      console.log(err)
49
+      message.info(err.msg || err.message)
50
+  })
51
+  }
52
+
53
+  // 所有按钮
54
+  function buttonList(params) {
55
+    request({ ...apis.role.buttonList, params: { ...params } }).then((data) => {
56
+      setButtonData(data)
57
+  }).catch((err) => {
58
+      console.log(err)
59
+  })
60
+  }
61
+
62
+
63
+  // 根据角色id查询当前的菜单及其按钮
64
+  function buttonAndMenuList(params, ids) {
65
+    setLoading(true)
66
+    request({ ...apis.role.buttonAndMenuList, urlData: { id: ids }, params: { ...params } }).then(data => {
67
+      setLoading(false)
68
+      props.form.setFieldsValue({ roleName: data.roleName })
69
+      console.log(data)
70
+      setData(data)
71
+
72
+      // 获取所有的权限Id
73
+      if (data.sysMenuList) {
74
+        setDataMenuId(data.sysMenuList.map(item => item && item.menuId))
75
+        // setDataButtonId((data.sysMenuList.map(item => item.sysButtonInMenu && item.sysButtonInMenu.map(btn => btn.btnId).join(',')).filter(f => f !== '').join(',').split(',')).map(a => parseInt(a) ) )
76
+        setDataButtonId(data.sysButtonInMenu.map(item => item && item.btnId))
77
+      }
78
+  }).catch((err) => {
79
+      console.log(err)
80
+      message.info(err.msg || err.message)
81
+  })
82
+  }
83
+
84
+  // const [menus, setMenus] = useState([]);
85
+  // 判断menus是否有值
86
+  const [menus, setMenus] = useState([]);
87
+  const [but, setBut] = useState([]);
88
+
89
+  const addMenus = m => setMenus([...menus, m])
90
+  const delMenus = m => setMenus(menus.filter(x => x.menuId !== m.menuId));
91
+
92
+  const handleMenuChange = m => e => {
93
+    // 如果是根菜单, 把子菜单挑出来
94
+    const isMenuRoot = m.parentCode === '-1'
95
+    const subMenus = isMenuRoot ? userMenus.filter(x => x.parentCode == m.menuId) : []
96
+    // 把子菜单与当前对象, 同时作为当前操作对象
97
+    const currentMenus = [ m, ...subMenus ]
98
+    // 先把选中列表中, 当前操作对象去掉
99
+    const leftCheckedMenusIds = dataMenuId.filter(x => !currentMenus.some(it => it.menuId == x))
100
+
101
+    // 当前选中菜单
102
+    const currentCheckedMenus = e.target.checked ? currentMenus : []
103
+
104
+    // 计算所有选中菜单
105
+    let checkedMenus = [
106
+      ...currentCheckedMenus,
107
+      ...userMenus.filter(x => leftCheckedMenusIds.some(it => it == x.menuId)),
108
+    ]
109
+
110
+    // 如果子菜单全部取消选择, 那么根菜单也取消选择
111
+    // 如果子菜单有一个选中, 那么根菜单也选中
112
+    if (!isMenuRoot) {
113
+      const children = checkedMenus.filter(x => x.menuRoot === m.menuRoot && x.menuId !== m.menuRoot)
114
+      if (!children || children.length < 1) {
115
+        checkedMenus = checkedMenus.filter(x => x.menuId !== m.menuRoot)
116
+      } else {
117
+        const hasRootMenu = checkedMenus.some(x => x.menuId === m.menuRoot)
118
+  
119
+        if (!hasRootMenu) {
120
+          const rootMenu = userMenus.filter(x => x.menuId === m.menuRoot)[0]
121
+          if (rootMenu) {
122
+            checkedMenus.push(rootMenu)
123
+          }
124
+        }
125
+      }
126
+    }
127
+
128
+    // 只要菜单选中, 所属按钮全部选中
129
+    // 菜单取消选择, 所有按钮全部取消选择
130
+    const currentMenuBtns = currentMenus.reduce((acc, it) => [...acc, ...userBtns.filter(x => x.menuId === it.menuId)], [])
131
+    const currentCheckedMenuBtns = currentCheckedMenus.reduce((acc, it) => [...acc, ...userBtns.filter(x => x.menuId === it.menuId)], [])
132
+    const checkedBtns = dataButtonId.filter(x => !currentMenuBtns.some(it => it.btnId === x)).map(x => userBtns.filter(it => x == it.btnId)[0]).concat(...currentCheckedMenuBtns)
133
+
134
+    setMenus(checkedMenus)
135
+    setDataMenuId(checkedMenus.map(x => x.menuId))
136
+    setDataButtonId(checkedBtns.map(x => x.btnId))
137
+    setBut(checkedBtns)
138
+  }
139
+
140
+  // 判断menus是否有值
141
+  const addBut = m => setBut([...but, m])
142
+  const delBut = m => setBut(but.filter(x => x.menuId !== m.menuId));
143
+  const handleButChange = m => e => {
144
+
145
+    // 如果有一个按钮选中, 那么对应的菜单也需要选中
146
+    // 如果没有一个兄弟节点选中, 不做任何处理
147
+    if (e.target.checked) {
148
+      const parentMenuId = dataMenuId.filter(x => x === m.menuId)[0]
149
+
150
+      if (!parentMenuId) {
151
+        const parentMenu = userMenus.filter(x => x.menuId === m.menuId)[0]
152
+        const parentMenuRoot = userMenus.filter(x => x.menuId === parentMenu.menuRoot)[0]
153
+
154
+        const checkedMenus = menus.concat(parentMenu).concat(parentMenuRoot)
155
+        setMenus(checkedMenus)
156
+        setDataMenuId(checkedMenus.map(x => x.menuId))
157
+      }
158
+    }
159
+
160
+    if (e.target.checked) {
161
+      setDataButtonId(dataButtonId.concat(m.btnId))
162
+      addBut(m)
163
+    } else {
164
+      setDataButtonId(dataButtonId.filter(item => item !== m.btnId));
165
+      delBut(m)
166
+    }
167
+  }
168
+  const gridStyle1 = {
169
+    width: '16%',
170
+    textAlign: 'left',
171
+    height: '72px',
172
+    padding:'24px'
173
+  };
174
+  const gridStyle2 = {
175
+    width: '84%',
176
+    textAlign: 'left',
177
+    height: '72px',
178
+  };
179
+
180
+  function toRoleList() {
181
+    router.push({
182
+      pathname: '/staff/RoleList',
183
+    });
184
+  }
185
+
186
+  function updateAuthMenu(data) {
187
+    setLoading(true)
188
+    request({ ...apis.role.updateAuthMenu, data: { ...data } }).then((data) => {
189
+      setLoading(false)
190
+      toRoleList()
191
+  }).catch((err) => {
192
+      console.log(err)
193
+  })
194
+  }
195
+
196
+
197
+  function handleSubmit(e) {
198
+    e.preventDefault();
199
+    props.form.validateFields((err, values) => {
200
+      if (values.roleName === undefined || values.roleName === '') {
201
+        message.error('请输入角色名称')
202
+        return
203
+      }
204
+
205
+      if (props.location.query.id !== undefined) {
206
+        console.log('menus', menus)
207
+      
208
+        const sumitMenu = userMenus.filter(item => dataMenuId.includes(item.menuId))
209
+        const sumitBtn = buttonData.filter(item => dataButtonId.includes(item.btnId))
210
+        updateAuthMenu({ sysMenu: sumitMenu, name: values.roleName, id: props.location.query.id, sysButton: sumitBtn })
211
+      } else {
212
+        updateAuthMenu({ sysMenu: menus, name: values.roleName, id: props.location.query.id, sysButton: but })
213
+        }
214
+    });
215
+  }
216
+  const { getFieldDecorator } = props.form;
217
+  
218
+  return (
219
+    <Card>
220
+      <div>
221
+      <Spin spinning={ loading } size="large">
222
+        <Form labelCol={{ span: 6 }} wrapperCol={{ span: 12 }} onSubmit={handleSubmit}>
223
+          <Form.Item label="角色名称">
224
+            {getFieldDecorator('roleName', {
225
+              rules: [{ required: true, message: '请输入角色名称' }],
226
+            })(<Input  />)}
227
+
228
+          </Form.Item>
229
+          {userMenus.map(item => (
230
+            (item.parentCode === '-1') &&
231
+            <Row >
232
+              <Col span={6}>
233
+              </Col>
234
+              <Col span={18}>
235
+
236
+                <Card title={<Checkbox checked={dataMenuId.includes(item.menuId)} onChange={handleMenuChange(item)}>{item.name}</Checkbox>} bordered style={{ width: '100%', alignItems: 'center',margin:'10px 0', boxShadow:'3px 3px 10px  rgba(0,0,0,0.15)',borderRadius:'8px'}} >
237
+                  {
238
+                    userMenus.map(menu => (
239
+
240
+                      (item.menuId === menu.menuRoot && item.menuId !== menu.menuId) &&
241
+                      <>
242
+                        <Card.Grid style={gridStyle1} >
243
+                          <Checkbox checked={dataMenuId.includes(menu.menuId)} onChange={handleMenuChange(menu)}>{menu.name}</Checkbox>
244
+                        </Card.Grid>
245
+                        <Card.Grid style={gridStyle2}>
246
+                          {buttonData.length > 0 && buttonData.map(btn => (
247
+                            <>
248
+                              {
249
+                                btn.menuId === menu.menuId &&
250
+                                <Checkbox checked={dataButtonId.includes(btn.btnId)} onChange={handleButChange(btn)}>{btn.name}</Checkbox>
251
+                              }
252
+                            </>
253
+                          ))}
254
+                        </Card.Grid>
255
+                      </>
256
+                    ))
257
+                  }
258
+                </Card>
259
+              </Col>
260
+
261
+            </Row>
262
+          ))}
263
+          <Form.Item wrapperCol={{ span: 15, offset: 7 }} style={{ marginTop: '10px' }}>
264
+            <Button type="primary" htmlType="submit">
265
+              保存
266
+          </Button>
267
+            <Button onClick = {toRoleList}>
268
+              取消
269
+          </Button>
270
+          </Form.Item>
271
+        </Form>
272
+        </Spin>
273
+      </div>
274
+    </Card>
275
+  )
276
+}
277
+const WrappedNormalLoginForm = Form.create({ name: 'Poster' })(Poster);
278
+export default connect(({ user }) => ({ user }))(WrappedNormalLoginForm);

+ 148
- 0
src/pages/staff/Role/List/index.jsx Wyświetl plik

@@ -0,0 +1,148 @@
1
+
2
+import React, { useState, useEffect } from 'react';
3
+import { Button, message, Table, Modal, Card } from 'antd';
4
+import withActions from '@/components/ActionList';
5
+import EditIcon from '@/components/EditIcon';
6
+import router from 'umi/router';
7
+import request from '@/utils/request'
8
+import apis from '@/services/apis';
9
+import AuthButton from '@/components/AuthButton';
10
+
11
+
12
+const header = props => {
13
+  // function confirm(id) {
14
+  //   Modal.confirm({
15
+  //     title: '确认停用该角色?',
16
+  //     okText: '确认',
17
+  //     cancelText: '取消',
18
+  //     onOk() {
19
+  //     },
20
+  //     onCancel() {
21
+  //       console.log('Cancel');
22
+  //     },
23
+  //   });
24
+  // }
25
+
26
+  function addRole(roleId) {
27
+    router.push({
28
+      pathname: '/staff/Role/Edit',
29
+    });
30
+  }
31
+
32
+  function toEditRole(roleId) {
33
+    router.push({
34
+      pathname: '/staff/Role/Edit',
35
+      query: {
36
+        id: roleId,
37
+      },
38
+    });
39
+  }
40
+  const [data, setData] = useState({ data: [] })
41
+  // 初始化角色
42
+  useEffect(() => {
43
+    localStorage.removeItem('value');
44
+    getRoleList({ pageNum: 1, pageSize: 100 })
45
+  }, [])
46
+
47
+  //  function getRoleList(params) {
48
+  //    request({
49
+  //      url: '/api/admin/taRole',
50
+  //      method: 'GET',
51
+  //      params: { ...params },
52
+  //  // eslint-disable-next-line no-shadow
53
+  //  }).then(data => {
54
+  //      console.log(data)
55
+  //      setData(data)
56
+  //  })
57
+  //  }
58
+
59
+  function getRoleList(params) {
60
+    request({ ...apis.role.getRoleList, params: { ...params } }).then((data) => {
61
+      setData(data)
62
+    }).catch((err) => {
63
+      console.log(err)
64
+      message.info(err.msg || err.message)
65
+    })
66
+  }
67
+
68
+
69
+  function stop(ids, status) {
70
+    Modal.confirm({
71
+      title: "删除后角色对应账号权限也会被自动停用,请谨慎操作",
72
+      okText: '确认',
73
+      cancelText: '取消',
74
+      onOk() {
75
+        request({ ...apis.role.stop, urlData: { id: ids } }).then((data) => {
76
+          getRoleList({ pageNum: 1, pageSize: 100 })
77
+        }).catch((err) => {
78
+          console.log(err)
79
+          message.info(err.msg || err.message)
80
+        })
81
+      }
82
+    });
83
+  }
84
+
85
+  const dataSource = [
86
+    {
87
+      name: '置业顾问',
88
+      status: '1',
89
+    },
90
+    {
91
+      name: '置业经理',
92
+      status: '1',
93
+    },
94
+  ];
95
+
96
+  const columns = [
97
+    // {
98
+    //   title: '商品图片',
99
+    //   dataIndex: 'img',
100
+    //   key: 'img',
101
+    //   align: 'center',
102
+
103
+    //   render: (text, record) => <img src={record.img} className={channels.touxiang} />,
104
+    // },
105
+    {
106
+      title: '角色名称',
107
+      dataIndex: 'roleName',
108
+      key: 'roleName',
109
+      align: 'center',
110
+    },
111
+
112
+    {
113
+      title: '操作  ',
114
+      dataIndex: 'status',
115
+      key: 'status',
116
+      align: 'center',
117
+
118
+      render: withActions((text, record) => {
119
+        return record.isAdmin ? [] :
120
+          [
121
+            record.status === 1 ?
122
+            <AuthButton name="admin.role.publish" noRight={null}>
123
+              <EditIcon type="delete" text="删除" onClick={() => stop(record.roleId, record.status)} />
124
+            </AuthButton> : null,
125
+
126
+            <AuthButton name="admin.role.put" noRight={null}>
127
+              <EditIcon text="编辑" type="edit" onClick={() => toEditRole(record.roleId)} />
128
+            </AuthButton>,
129
+          ]
130
+      }),
131
+    },
132
+  ];
133
+
134
+
135
+  return (
136
+    <Card>
137
+      <AuthButton name="admin.role.add" noRight={null}>
138
+        <Button type="primary"  onClick={addRole}>新增</Button>
139
+      </AuthButton>
140
+      <div style={{marginTop:'20px'}}>
141
+
142
+        <Table rowKey="roleList" dataSource={data.records} columns={columns} />
143
+      </div>
144
+    </Card>
145
+
146
+  )
147
+}
148
+export default header

+ 129
- 0
src/pages/staff/components/BatchAssistConsultant.jsx Wyświetl plik

@@ -0,0 +1,129 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Form, Icon, Input, Button, DatePicker, Select, Card, Row, Col, Pagination, Alert, Table, Avatar, Radio, Modal, Descriptions, notification } from 'antd';
3
+import moment from 'moment';
4
+import request from '../../../utils/request';
5
+import apis from '../../../services/apis';
6
+
7
+
8
+const { Option } = Select;
9
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
10
+const { Meta } = Card;
11
+
12
+/**
13
+ * 分配置业顾问
14
+ *
15
+ * @param {*} props
16
+ * @returns
17
+ */
18
+class ModalAttribution extends React.Component {
19
+  constructor(props) {
20
+    super(props);
21
+    // console.log(props, 'props')
22
+    this.state = {
23
+      dataSource: { records: [] },
24
+      visibleData: { visible: false, buildingId: '' },
25
+    }
26
+  }
27
+
28
+  // 挂载之后
29
+  componentDidMount() {
30
+    // this.getList({ pageNumber: 1, pageSize: 5 })
31
+  }
32
+
33
+  componentDidUpdate(preProps, preState) {
34
+    if (this.props.visible !== preState.visibleData.visible) {
35
+      this.getUserList({ pageNumber: 1, pageSize: 5, buildingId: this.props.buildingId })
36
+      this.setState({ visibleData: { visible: this.props.visible, buildingId: this.props.buildingId } });
37
+    }
38
+  }
39
+
40
+  // 弹框取消按钮
41
+  handleCancel() {
42
+    this.props.onCancel()
43
+  }
44
+
45
+  getUserList(params) {
46
+    console.log('params: ', params)
47
+    if (params.buildingId === '' || params.buildingId === null || params.buildingId === undefined) {
48
+      return
49
+    }
50
+    // 网路请求
51
+    request({ ...apis.customer.buildingConsultant, params: { ...params } }).then(res => {
52
+      this.setState({ dataSource: res })
53
+    }).catch(err => {
54
+
55
+    })
56
+  }
57
+
58
+  openNotificationWithIcon = (type, message) => {
59
+    notification[type]({
60
+      message,
61
+      description:
62
+        '',
63
+    });
64
+  };
65
+
66
+  // 分页
67
+  onChange(pageNum) {
68
+
69
+    this.getUserList({ pageNumber: pageNum, pageSize: 5, buildingId: this.state.visibleData.buildingId })
70
+  }
71
+
72
+  // 提交
73
+  submitGm(record) {
74
+    this.props.onCancel(record)
75
+  }
76
+
77
+  render() {
78
+    const columns = [
79
+      {
80
+        title: '姓名',
81
+        dataIndex: 'userName',
82
+        key: 'userName',
83
+        width: 120,
84
+      },
85
+      {
86
+        title: '电话',
87
+        dataIndex: 'phone',
88
+        key: 'phone',
89
+        width: 150,
90
+      },
91
+      {
92
+        title: '部门',
93
+        dataIndex: 'department',
94
+        key: 'department',
95
+        width: 130,
96
+      },
97
+      {
98
+        title: '岗位',
99
+        dataIndex: 'position',
100
+        key: 'position',
101
+        width: 120,
102
+      },
103
+      {
104
+        title: '操作',
105
+        dataIndex: 'personId',
106
+        key: 'personId',
107
+        width: 80,
108
+        // eslint-disable-next-line no-nested-ternary
109
+        render: (_, record) => <>{record.userId !== this.props.userId ? <Button type="danger" onClick={() => this.submitGm(record)}>确定</Button> : ''}</>,
110
+      },
111
+    ]
112
+    return (
113
+      <>
114
+        <Modal
115
+          title="分配置业顾问"
116
+          width={600}
117
+          destroyOnClose="true"
118
+          footer={null}
119
+          visible={this.state.visibleData.visible}
120
+          onCancel={(e) => this.handleCancel(e)}
121
+        >
122
+          <Table rowKey="userId" dataSource={this.state.dataSource.records} columns={columns} pagination={{ pageSize: 5, total: this.state.dataSource.total, onChange: e => this.onChange(e) }} />
123
+        </Modal>
124
+      </>
125
+    );
126
+  }
127
+}
128
+
129
+export default ModalAttribution

+ 58
- 0
src/pages/staff/components/BuildingSelection.jsx Wyświetl plik

@@ -0,0 +1,58 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Input, Menu, Dropdown, Button, Icon, message, Table, Tooltip, Tabs, Radio, Divider, Tag, Select, Form, Alert, Modal } from 'antd';
3
+import request from '../../../utils/request';
4
+import apis from '../../../services/apis';
5
+import CustomerChange from './CustomerChange'
6
+import BuildSelect from '@/components/SelectButton/BuildSelect'
7
+
8
+let building = null
9
+const BuildingSelection = (props) => {
10
+    const [visible, setVisible] = useState(false) 
11
+    const { userData } = props;
12
+
13
+     //授权项目改变
14
+  const consultantBuildingChange =(e) => {
15
+    building = e
16
+    if(userData.isConsultant && props.value !== e){
17
+      request({ ...apis.staff.check, params: { userId: userData.userId, personId: userData.consultantPersonId, buildingId: userData.buildingId } }).then(res => {
18
+        if(res.length > 0){
19
+          Modal.confirm({
20
+            title: '此置业顾问下有私客,是否转移私客?',
21
+            okText: '确认',
22
+            cancelText: '取消',
23
+            onOk () {
24
+              setVisible(true)
25
+            },
26
+          });
27
+        }else{
28
+            props.onChange(e)
29
+        }
30
+     })
31
+    }else{
32
+        props.onChange(e)
33
+    }
34
+  }
35
+
36
+   //迁移私客成功回调
37
+   const moveSuccess = (e) => {
38
+       if(e === 'success'){
39
+        props.onChange(building)
40
+       }
41
+       setVisible(false)
42
+  }
43
+
44
+     return (<>
45
+        <BuildSelect value={props.value} onChange={consultantBuildingChange} />
46
+        <Modal
47
+              visible={visible}
48
+              title="分配归属"
49
+              onCancel={() => setVisible(false)}
50
+              footer={null}
51
+              width={900}
52
+            >
53
+                <CustomerChange userId={userData.userId} consultantPersonId={userData.consultantPersonId} buildingId={userData.buildingId} onSuccess={moveSuccess} />
54
+            </Modal>
55
+     </>)
56
+  }
57
+  
58
+  export default BuildingSelection;

+ 115
- 0
src/pages/staff/components/CustomerChange.jsx Wyświetl plik

@@ -0,0 +1,115 @@
1
+import React, { Component, useState, useEffect } from 'react';
2
+import request from '../../../utils/request';
3
+import apis from '../../../services/apis';
4
+import moment from 'moment';
5
+import router from 'umi/router';
6
+import { Table, Select, Row, Col, Menu, Dropdown, Button, Icon, message } from 'antd';
7
+import BatchAssistConsultant from './BatchAssistConsultant'
8
+
9
+const CustomerChange = (props) => {
10
+  const [data, setData] = useState([])
11
+  const [consultantVisible, setConsultantVisible] = useState(false)
12
+  const [selectIds, setSelectIds] = useState([])
13
+
14
+  const rowSelection = {
15
+    selectedRowKeys: selectIds,
16
+    onChange: (selectedRowKeys, selectedRows) => {
17
+      console.log('selectedRowKeys:', selectedRowKeys, 'selectedRows: ', selectedRows);
18
+      setSelectIds(selectedRowKeys)
19
+    },
20
+  };
21
+
22
+  const batchAssistConsultant = () => {
23
+    if (selectIds.length < 1) {
24
+      message.info("请至少选择一条数据");
25
+      return
26
+    }
27
+    setConsultantVisible(true)
28
+  }
29
+
30
+  const consulatanChange = (e) => {
31
+    if (e) {
32
+      data.map(x => {
33
+        selectIds.map(y => {
34
+          if (x.customerId === y) {
35
+            x.realtyConsultant = e.userId
36
+            x.moveUserId = e.userId
37
+            x.moveUserName = e.userName
38
+          }
39
+        })
40
+      })
41
+    }
42
+    setConsultantVisible(false)
43
+    setSelectIds([])
44
+  }
45
+
46
+  //批量保存
47
+  const batchSaveConsultant = () => {
48
+    const unMoveData = data.filter(x => !x.moveUserId)
49
+    if (unMoveData.length > 0) {
50
+      message.info("存在未分配归属客户");
51
+      return
52
+    }
53
+    request({ ...apis.staff.move, data }).then(data => {
54
+      message.info('操作成功')
55
+      props.onSuccess('success')
56
+    })
57
+  }
58
+
59
+  //取消按钮
60
+  const cancelConsultant = () => {
61
+    props.onSuccess('cancel')
62
+  }
63
+
64
+
65
+  const columns = [
66
+    {
67
+      title: '用户名',
68
+      dataIndex: 'name',
69
+      key: 'name',
70
+      align: 'center',
71
+    },
72
+    {
73
+      title: '手机号',
74
+      dataIndex: 'phone',
75
+      key: 'phone',
76
+      align: 'center',
77
+    },
78
+    {
79
+      title: '客户状态',
80
+      dataIndex: 'reportRecommendStatus',
81
+      key: 'reportRecommendStatus',
82
+      align: 'center',
83
+      render: (text, records) => {
84
+        if (records.status === 1) { return '报备' }
85
+        if (records.status === 2) { return '到访' }
86
+        if (records.status === 3) { return '认购' }
87
+        if (records.status === 4) { return '签约' }
88
+      },
89
+    },
90
+    {
91
+      title: '调整后归属',
92
+      dataIndex: 'moveUserName',
93
+      key: 'moveUserName',
94
+      align: 'center',
95
+    }
96
+  ];
97
+
98
+  useEffect(() => {
99
+    request({ ...apis.staff.check, params: { userId: props.userId, personId: props.consultantPersonId, buildingId: props.buildingId } }).then(data => {
100
+      setData(data)
101
+    })
102
+  }, [props.userId])
103
+
104
+  return (
105
+    <div>
106
+      <Button type="primary" onClick={() => batchAssistConsultant()} style={{ float: 'right', margin: '20px 0', marginLeft: '20px', zIndex: 1 }}>分配置业顾问</Button>
107
+      <Table rowSelection={rowSelection} dataSource={data} columns={columns} rowKey="customerId" pagination={false} scroll={{ y: 500 }} />
108
+      <BatchAssistConsultant visible={consultantVisible} userId={props.userId} buildingId={props.buildingId} onCancel={consulatanChange} />
109
+      <div style={{ textAlign: 'center', marginTop: '16px' }}><Button type="primary" onClick={() => batchSaveConsultant()}>保存</Button>
110
+        <Button style={{ marginLeft: '10px' }} onClick={() => cancelConsultant()}>取消</Button></div>
111
+    </div>
112
+  )
113
+}
114
+
115
+export default CustomerChange;

+ 83
- 0
src/pages/staff/components/Tagss.jsx Wyświetl plik

@@ -0,0 +1,83 @@
1
+import React from 'react';
2
+import { Tag, Input, Tooltip, Icon } from 'antd';
3
+import Styles from './style.less';
4
+
5
+ class Tagss extends React.Component {
6
+  state = {
7
+    tags: [ 'Tag 2', 'Tag 3'],
8
+    inputVisible: false,
9
+    inputValue: '',
10
+  };
11
+
12
+  handleClose = removedTag => {
13
+    const tags = this.state.tags.filter(tag => tag !== removedTag);
14
+    console.log(tags);
15
+    this.setState({ tags });
16
+  };
17
+
18
+  showInput = () => {
19
+    this.setState({ inputVisible: true }, () => this.input.focus());
20
+  };
21
+
22
+  handleInputChange = e => {
23
+    this.setState({ inputValue: e.target.value });
24
+  };
25
+
26
+  handleInputConfirm = () => {
27
+    const { inputValue } = this.state;
28
+    let { tags } = this.state;
29
+    if (inputValue && tags.indexOf(inputValue) === -1) {
30
+      tags = [...tags, inputValue];
31
+    }
32
+    console.log(tags);
33
+    this.setState({
34
+      tags,
35
+      inputVisible: false,
36
+      inputValue: '',
37
+    });
38
+  };
39
+
40
+  saveInputRef = input => (this.input = input);
41
+
42
+  render() {
43
+    const { tags, inputVisible, inputValue } = this.state;
44
+    return (
45
+      <div>
46
+        {tags.map((tag, index) => {
47
+          const isLongTag = tag.length > 20;
48
+          const tagElem = (
49
+            <Tag className = {Styles.tagss} key={tag} closable = {true} onClose={() => this.handleClose(tag)}>
50
+              {isLongTag ? `${tag.slice(0, 20)}...` : tag}
51
+            </Tag>
52
+          );
53
+          return isLongTag ? (
54
+            <Tooltip title={tag} key={tag}>
55
+              {tagElem}
56
+            </Tooltip>
57
+          ) : (
58
+            tagElem
59
+          );
60
+        })}
61
+        {inputVisible && (
62
+          <Input className = {Styles.tagss}
63
+            ref={this.saveInputRef}
64
+            // type="text"
65
+            // size="small"
66
+            // style={{ width: 78 }}
67
+            value={inputValue}
68
+            onChange={this.handleInputChange}
69
+            onBlur={this.handleInputConfirm}
70
+            onPressEnter={this.handleInputConfirm}
71
+          />
72
+        )}
73
+        {!inputVisible && (
74
+          <Tag className = {Styles.tagss} onClick={this.showInput} >
75
+            <Icon type="plus" /> 新建
76
+          </Tag>
77
+        )}
78
+      </div>
79
+    );
80
+  }
81
+}
82
+
83
+export default Tagss;

+ 140
- 0
src/pages/staff/components/attribution.jsx Wyświetl plik

@@ -0,0 +1,140 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Form, Icon, Input, Button, DatePicker, Select, Card, Row, Col, Pagination, Alert, Table, Avatar, Radio, Modal, Descriptions, notification } from 'antd';
3
+import moment from 'moment';
4
+import request from '../../../utils/request';
5
+import apis from '../../../services/apis';
6
+
7
+
8
+const { Option } = Select;
9
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
10
+const { Meta } = Card;
11
+
12
+/**
13
+ * 调整归属
14
+ *
15
+ * @param {*} props
16
+ * @returns
17
+ */
18
+class ModalAttribution extends React.Component {
19
+  constructor(props) {
20
+    super(props);
21
+    this.state = {
22
+       dataSource: { records: [] },
23
+       visibleData: { visible: false, realtyConsultant: '', buildingId: '', userId: '' },
24
+    }
25
+  }
26
+
27
+  // 挂载之后
28
+  componentDidMount() {
29
+    // this.getList({ pageNumber: 1, pageSize: 5 })
30
+  }
31
+
32
+  componentDidUpdate(preProps, preState) {
33
+    if (this.props.visibleData.visible !== preState.visibleData.visible) {
34
+      this.getList({ pageNumber: 1, pageSize: 5, buildingId: this.props.visibleData.buildingId })
35
+      // eslint-disable-next-line react/no-did-update-set-state
36
+      this.setState({ visibleData: this.props.visibleData });
37
+    }
38
+  }
39
+
40
+  // 弹框确定按钮
41
+  // eslint-disable-next-line react/sort-comp
42
+  handleOk() {
43
+    this.props.onCancel()
44
+  }
45
+
46
+  // 弹框取消按钮
47
+  handleCancel() {
48
+    this.props.onCancel()
49
+  }
50
+
51
+  getList(params) {
52
+    if (params.buildingId === '' || params.buildingId === null || params.buildingId === undefined) {
53
+      return
54
+    }
55
+
56
+    // 网路请求
57
+    request({ ...apis.customer.buildingConsultant, params: { ...params } }).then(res => {
58
+      const records = res.records.filter(f => f.userId !== this.state.visibleData.userId)
59
+      this.setState({ dataSource: { ...res, records, total: res.total - 1 } })
60
+    }).catch(() => {
61
+      // eslint-disable-next-line no-unused-expressions
62
+
63
+    })
64
+  }
65
+
66
+  openNotificationWithIcon = (type, message) => {
67
+    notification[type]({
68
+      message,
69
+      description:
70
+        '',
71
+    });
72
+  };
73
+
74
+   // 分页
75
+  onChange(pageNum) {
76
+    this.getList({ pageNumber: pageNum, pageSize: 5, buildingId: this.props.visibleData.buildingId })
77
+  }
78
+
79
+  // 提交
80
+  submitGm(record) {
81
+
82
+    console.log('传递之前:', record)
83
+    this.handleCancel()
84
+    this.props.onSuccess({ realtyConsultant: record.userId, name: record.userName })
85
+  }
86
+
87
+  render() {
88
+    const columns = [
89
+      // {
90
+      //   title: '编号',
91
+      //   dataIndex: 'personId',
92
+      //   key: 'personId',
93
+      // },
94
+      {
95
+        title: '姓名',
96
+        dataIndex: 'userName',
97
+        key: 'userName',
98
+      },
99
+      {
100
+        title: '电话',
101
+        dataIndex: 'phone',
102
+        key: 'phone',
103
+      },
104
+      {
105
+        title: '部门',
106
+        dataIndex: 'department',
107
+        key: 'department',
108
+      },
109
+      {
110
+        title: '岗位',
111
+        dataIndex: 'position',
112
+        key: 'position',
113
+      },
114
+      {
115
+        title: '操作',
116
+        dataIndex: 'personId',
117
+        key: 'personId',
118
+        // eslint-disable-next-line no-nested-ternary
119
+        render: (_, record) => <>{ this.props.visibleData.realtyConsultant !== record.userId && <Button type="danger" onClick={() => this.submitGm(record)}>确定</Button>}</>,
120
+      },
121
+    ]
122
+    return (
123
+      <>
124
+        <Modal
125
+            title="选择置业顾问"
126
+            width={800}
127
+            destroyOnClose="true"
128
+            footer={null}
129
+            visible={this.state.visibleData.visible}
130
+            // onOk={() => this.handleOk()}
131
+            onCancel={(e) => this.handleCancel(e)}
132
+          >
133
+            <Table rowKey="attribution" dataSource={this.state.dataSource.records} columns={columns} pagination={{ total: this.state.dataSource.total, onChange: e => this.onChange(e) }} />
134
+          </Modal>
135
+      </>
136
+    );
137
+  }
138
+}
139
+
140
+export default ModalAttribution

+ 24
- 0
src/pages/staff/components/style.less Wyświetl plik

@@ -0,0 +1,24 @@
1
+.tagss{
2
+  width: 150px;
3
+  height: 32px;
4
+  
5
+font-size:14px;
6
+
7
+font-weight:400;
8
+color:rgba(153,153,153,1);
9
+
10
+
11
+padding: 4px 11px;
12
+
13
+color: rgba(0, 0, 0, 0.65);
14
+
15
+
16
+
17
+line-height: 1.5;
18
+
19
+background-color: #fff;
20
+
21
+
22
+
23
+border: 1px solid #d9d9d9;
24
+}

+ 149
- 0
src/pages/staff/list/RoleList.jsx Wyświetl plik

@@ -0,0 +1,149 @@
1
+
2
+import React, { useState, useEffect } from 'react';
3
+import { Button, message, Table, Modal } from 'antd';
4
+import withActions from '@/components/ActionList';
5
+import EditIcon from '@/components/EditIcon';
6
+import router from 'umi/router';
7
+import request from '../../../utils/request'
8
+import Styles from './style.less';
9
+import apis from '../../../services/apis';
10
+import AuthButton from '../../../components/AuthButton';
11
+import styles from '../../style/GoodsList.less';
12
+
13
+const header = props => {
14
+  // function confirm(id) {
15
+  //   Modal.confirm({
16
+  //     title: '确认停用该角色?',
17
+  //     okText: '确认',
18
+  //     cancelText: '取消',
19
+  //     onOk() {
20
+  //     },
21
+  //     onCancel() {
22
+  //       console.log('Cancel');
23
+  //     },
24
+  //   });
25
+  // }
26
+
27
+  function addRole(roleId) {
28
+    router.push({
29
+      pathname: '/staff/list/addRole',
30
+    });
31
+  }
32
+
33
+  function toEditRole(roleId) {
34
+    router.push({
35
+      pathname: '/staff/list/addRole',
36
+      query: {
37
+        id: roleId,
38
+      },
39
+    });
40
+  }
41
+  const [data, setData] = useState({ data: [] })
42
+  // 初始化角色
43
+  useEffect(() => {
44
+    localStorage.removeItem('value');
45
+    getRoleList({ pageNum: 1, pageSize: 100 })
46
+  }, [])
47
+
48
+  //  function getRoleList(params) {
49
+  //    request({
50
+  //      url: '/api/admin/taRole',
51
+  //      method: 'GET',
52
+  //      params: { ...params },
53
+  //  // eslint-disable-next-line no-shadow
54
+  //  }).then(data => {
55
+  //      console.log(data)
56
+  //      setData(data)
57
+  //  })
58
+  //  }
59
+
60
+  function getRoleList(params) {
61
+    request({ ...apis.role.getRoleList, params: { ...params } }).then((data) => {
62
+      setData(data)
63
+    }).catch((err) => {
64
+      console.log(err)
65
+      message.info(err.msg || err.message)
66
+    })
67
+  }
68
+
69
+
70
+  function stop(ids, status) {
71
+    Modal.confirm({
72
+      title: "删除后角色对应账号权限也会被自动停用,请谨慎操作",
73
+      okText: '确认',
74
+      cancelText: '取消',
75
+      onOk() {
76
+        request({ ...apis.role.stop, urlData: { id: ids } }).then((data) => {
77
+          getRoleList({ pageNum: 1, pageSize: 100 })
78
+        }).catch((err) => {
79
+          console.log(err)
80
+          message.info(err.msg || err.message)
81
+        })
82
+      }
83
+    });
84
+  }
85
+
86
+  const dataSource = [
87
+    {
88
+      name: '置业顾问',
89
+      status: '1',
90
+    },
91
+    {
92
+      name: '置业经理',
93
+      status: '1',
94
+    },
95
+  ];
96
+
97
+  const columns = [
98
+    // {
99
+    //   title: '商品图片',
100
+    //   dataIndex: 'img',
101
+    //   key: 'img',
102
+    //   align: 'center',
103
+
104
+    //   render: (text, record) => <img src={record.img} className={channels.touxiang} />,
105
+    // },
106
+    {
107
+      title: '角色名称',
108
+      dataIndex: 'roleName',
109
+      key: 'roleName',
110
+      align: 'center',
111
+    },
112
+
113
+    {
114
+      title: '操作  ',
115
+      dataIndex: 'status',
116
+      key: 'status',
117
+      align: 'center',
118
+
119
+      render: withActions((text, record) => {
120
+        return record.isAdmin ? [] :
121
+          [
122
+            record.status === 1 ?
123
+            <AuthButton name="admin.role.publish" noRight={null}>
124
+              <EditIcon type="delete" text="删除" onClick={() => stop(record.roleId, record.status)} />
125
+            </AuthButton> : null,
126
+
127
+            <AuthButton name="admin.role.put" noRight={null}>
128
+              <EditIcon text="编辑" type="edit" onClick={() => toEditRole(record.roleId)} />
129
+            </AuthButton>,
130
+          ]
131
+      }),
132
+    },
133
+  ];
134
+
135
+
136
+  return (
137
+    <>
138
+      <AuthButton name="admin.role.add" noRight={null}>
139
+        <Button type="danger" className={styles.addBtn} onClick={addRole}>新增</Button>
140
+      </AuthButton>
141
+      <div className={Styles.roletext}>
142
+
143
+        <Table rowKey="roleList" dataSource={data.records} columns={columns} />
144
+      </div>
145
+    </>
146
+
147
+  )
148
+}
149
+export default header

+ 284
- 0
src/pages/staff/list/StaffList.jsx Wyświetl plik

@@ -0,0 +1,284 @@
1
+
2
+import React, { useState, useEffect } from 'react';
3
+import { Form, Input, Button, Icon, Select, message, Table, Divider, Row, Col, Tag, Pagination, Modal, DatePicker, Card, Avatar } from 'antd';
4
+import { FormattedMessage } from 'umi-plugin-react/locale';
5
+import styles from '../../style/GoodsList.less';
6
+import router from 'umi/router';
7
+import AuthButton from '../../../components/AuthButton';
8
+import apis from '../../../services/apis';
9
+import request from '../../../utils/request'
10
+import Styles from './style.less';
11
+import BuildingSelect from '@/components/SelectButton/BuildSelect';
12
+import CustomerChange from '../components/CustomerChange'
13
+import EditIcon from '@/components/EditIcon';
14
+
15
+const { Meta } = Card;
16
+const { Option } = Select;
17
+const { MonthPicker, RangePicker, WeekPicker } = DatePicker;
18
+
19
+// 跳转到编辑商品
20
+const toEditStaff = userId => () => {
21
+  router.push({
22
+    pathname: '/staff/editStaff',
23
+    query: {
24
+      userId,
25
+    },
26
+  });
27
+}
28
+
29
+
30
+/**
31
+ *卡片
32
+ *
33
+ * @returns
34
+ */
35
+const CartBody = props => {
36
+  const { data } = props
37
+  const [visible, setVisible] = useState(false)
38
+  // console.log("data11:", data)
39
+
40
+  const confirm = data => () => {
41
+    // console.log(data, "11111")
42
+    if (data.status === 1) {
43
+      if (data.isConsultant) {
44
+        request({ ...apis.staff.check, params: { userId: data.userId, personId: data.consultantPersonId, buildingId: data.buildingId } }).then(res => {
45
+          if (res.length > 0) {
46
+            Modal.confirm({
47
+              title: '此置业顾问下有私客,是否转移私客?',
48
+              okText: '确认',
49
+              cancelText: '取消',
50
+              onOk() {
51
+                setVisible(true)
52
+              },
53
+            });
54
+          } else {
55
+            const titleMessahe = data.isConsultant ? '停用后此员工无法继续登录后台(若为置业顾问停用后在小程序端将成为普通用户)确认进行停用操作?' : '停用后此员工无法继续登录后台,确认进行停用操作?';
56
+            Modal.confirm({
57
+              title: titleMessahe,
58
+              okText: '确认',
59
+              cancelText: '取消',
60
+              onOk() {
61
+                request({ ...apis.staff.change, urlData: { id: data.userId, type: 'off' } }).then(res => {
62
+                  message.info('操作成功')
63
+                  props.onFresh()
64
+                })
65
+              },
66
+            });
67
+          }
68
+        })
69
+      } else {
70
+        const titleMessahe = data.isConsultant ? '停用后此员工无法继续登录后台(若为置业顾问停用后在小程序端将成为普通用户)确认进行停用操作?' : '停用后此员工无法继续登录后台,确认进行停用操作?';
71
+        Modal.confirm({
72
+          title: titleMessahe,
73
+          okText: '确认',
74
+          cancelText: '取消',
75
+          onOk() {
76
+            request({ ...apis.staff.change, urlData: { id: data.userId, type: 'off' } }).then(res => {
77
+              message.info('操作成功')
78
+              props.onFresh()
79
+            })
80
+          },
81
+        });
82
+      }
83
+    } else {
84
+      Modal.confirm({
85
+        title: '确认启用该角色?',
86
+        okText: '确认',
87
+        cancelText: '取消',
88
+        onOk() {
89
+          request({ ...apis.staff.change, urlData: { id: data.userId, type: 'on' } }).then(res => {
90
+            message.info('操作成功')
91
+            props.onFresh()
92
+          })
93
+        },
94
+      });
95
+    }
96
+  }
97
+
98
+  //迁移私客成功回调
99
+  const moveSuccess = (e) => {
100
+    setVisible(false)
101
+    if (e === 'success') {
102
+      confirm(data)()
103
+    }
104
+  }
105
+
106
+ 
107
+  return (
108
+    <div>
109
+      <Card className={Styles.card}>
110
+        <div>
111
+          <Avatar src={data.photo} style={{ width: '0.48rem', height: '0.48rem' }} />
112
+          <AuthButton name="admin.user.put" noRight={null}>
113
+            <Button type="link" style={{ color: '#FF925C', fontSize: '0.106rem', position: 'absolute', top: '40px', left: '0.56rem' }} onClick={toEditStaff(data.userId)}>
114
+              <EditIcon text="编辑" color='#ff925c' type="edit"></EditIcon>
115
+            </Button>
116
+          </AuthButton>
117
+          {/* <Button type="link" style={{ fontSize: ' 0.106rem', color: '#cacaca', position: 'absolute', top: '40px', right: '0' }} onClick={() => departure(data)}>
118
+            离职
119
+                  <Icon type="exclamation-circle" style={{ color: '#C0C4CC', marginLeft: '0.04rem' }} />
120
+          </Button> */}
121
+          <AuthButton name="admin.user.publish" noRight={null}>
122
+            <Button type="link" style={{ fontSize: ' 0.106rem', color: '#cacaca', position: 'absolute', top: '40px', right: '0' }} onClick={confirm(data)}>
123
+              {data.status === 1 ? <EditIcon text="停用" color='#FF4A4A' type="stop"></EditIcon> : <EditIcon text="启用" color='#ff925c' type="start"></EditIcon>}
124
+
125
+            </Button>
126
+          </AuthButton>
127
+        </div>
128
+        <div>
129
+
130
+          <span>
131
+            {
132
+              data.taTagsList.map((item, index) => <Tag className={Styles.cardTag} color={item.tagColor}>{item.tagName}</Tag>)
133
+            }
134
+          </span>
135
+
136
+          <p className={Styles.cardText} >姓名 : {data.userName}
137
+          </p>
138
+          {/* <p className={Styles.statusText} > 状态 : {data.status === 1 ? '启用' : '停用'} </p> */}
139
+          <p className={Styles.statusText} > 绑定状态 : {data.miniStatus === 1 ? '已绑定' : '未绑定'} </p>
140
+          <p className={Styles.phoneText} >
141
+            电话 : {data.phone}
142
+          </p>
143
+        </div>
144
+
145
+      </Card>
146
+      <Modal
147
+        visible={visible}
148
+        title="分配归属"
149
+        onCancel={() => setVisible(false)}
150
+        footer={null}
151
+        width={900}
152
+      >
153
+        <CustomerChange userId={data.userId} consultantPersonId={data.consultantPersonId} buildingId={data.buildingId} onSuccess={moveSuccess} />
154
+      </Modal>
155
+    </div>
156
+  )
157
+}
158
+
159
+const header = props => {
160
+  const [tempData, setTempData] = useState({ records: [] })
161
+  useEffect(() => {
162
+    getList({ pageNum: 1, pageSize: 8 });
163
+  }, [])
164
+
165
+  const getList = params => {
166
+    request({ ...apis.staff.taUser, params: { ...params } }).then(data => {
167
+      console.log(data, 'listData')
168
+      setTempData(data)
169
+    })
170
+  }
171
+
172
+  // 分页
173
+  const onChange = pageNumber => {
174
+    getList({ pageNum: pageNumber, pageSize: 8, ...props.form.getFieldsValue() });
175
+  }
176
+
177
+  // 提交事件
178
+  const handleSubmit = (e, props) => {
179
+    e.preventDefault();
180
+    props.form.validateFields((err, values) => {
181
+      if (!err) {
182
+        console.log('提交数据: ', values)
183
+        getList({ pageNum: 1, pageSize: 8, ...values })
184
+      }
185
+    });
186
+  }
187
+
188
+  // 重置搜索
189
+  function handleReset() {
190
+    props.form.resetFields();
191
+    getList({ pageNum: 1, pageSize: 8 });
192
+  }
193
+
194
+  const { getFieldDecorator } = props.form
195
+  return (
196
+
197
+    <>
198
+      <Form layout="inline" onSubmit={e => handleSubmit(e, props)}>
199
+        <Form.Item>
200
+          {getFieldDecorator('buildingId')(
201
+            <BuildingSelect />
202
+          )}
203
+        </Form.Item>
204
+        <Form.Item>
205
+          {getFieldDecorator('userName')(
206
+            <Input
207
+              prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
208
+              placeholder="姓名"
209
+            />,
210
+          )}
211
+        </Form.Item>
212
+        <Form.Item>
213
+          {getFieldDecorator('phone')(
214
+            <Input
215
+              prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
216
+              placeholder="电话"
217
+            />,
218
+          )}
219
+        </Form.Item>
220
+
221
+        <Form.Item>
222
+
223
+          {getFieldDecorator('status')(
224
+            <Select style={{ width: '180px' }} placeholder="状态" >
225
+              <Option value="1">启用</Option>
226
+              <Option value="9">停用</Option>
227
+            </Select>,
228
+          )}
229
+        </Form.Item>
230
+
231
+        <Form.Item>
232
+
233
+          {getFieldDecorator('isConsultant')(
234
+            <Select style={{ width: '180px' }} placeholder="是否置业顾问" >
235
+              <Option value="0">非置业顾问</Option>
236
+              <Option value="1">置业顾问</Option>
237
+            </Select>,
238
+          )}
239
+        </Form.Item>
240
+
241
+        <Form.Item>
242
+
243
+          {getFieldDecorator('miniStatus')(
244
+            <Select style={{ width: '180px' }} placeholder="是否绑定" >
245
+              <Option value="0">未绑定</Option>
246
+              <Option value="1">已绑定</Option>
247
+            </Select>,
248
+          )}
249
+        </Form.Item>
250
+
251
+        <Form.Item>
252
+          <AuthButton name="admin.user.search" noRight={null}>
253
+            <Button type="primary" htmlType="submit" className={styles.searchBtn}>
254
+              搜索
255
+          </Button>
256
+          </AuthButton>
257
+          <Button style={{ marginLeft: 8 }} onClick={handleReset}>
258
+            重置
259
+            </Button>
260
+        </Form.Item>
261
+      </Form>
262
+      <AuthButton name="admin.user.add" noRight={null}>
263
+        <Button type="danger" style={{ margin: '20px 0', padding: '2px 36px' }} onClick={toEditStaff()}>新增</Button>
264
+      </AuthButton>
265
+      <Row style={{ padding: ' 0 10px' }}>
266
+        {
267
+          tempData.records.filter(f => f.isAdmin != 1).map((item, index) => (
268
+            <Col span={6}>
269
+              <CartBody data={item} onFresh={() => getList({ pageNum: 1, pageSize: 8 })} key={item.userId} />
270
+            </Col>
271
+          ))
272
+        }
273
+      </Row>
274
+
275
+      {/* 分页  */}
276
+      <div style={{ display: 'flex', justifyContent: 'flex-end' }}>
277
+        <Pagination showQuickJumper defaultCurrent={1} pageSize={8} total={tempData.total} onChange={onChange} current={tempData.current} />
278
+      </div>
279
+    </>
280
+  )
281
+}
282
+const WrappedHeader = Form.create({ name: 'header' })(header);
283
+
284
+export default WrappedHeader

+ 280
- 0
src/pages/staff/list/addRole.jsx Wyświetl plik

@@ -0,0 +1,280 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Checkbox, Input, Card, Form, Button, Row, Col, Spin, message } from 'antd';
3
+import { connect } from 'dva';
4
+import XForm, { FieldTypes } from '../../../components/XForm';
5
+import request from '../../../utils/request';
6
+import channels from './channelList.less';
7
+import { resolve, join } from 'path';
8
+import router from 'umi/router';
9
+import apis from '../../../services/apis';
10
+
11
+const { TextArea } = Input;
12
+
13
+
14
+/**
15
+ *
16
+ *
17
+ * @param {*} props
18
+ * @returns
19
+ */
20
+const Poster = props => {
21
+  const userMenus = props.user.currentUser.menus;
22
+  const userBtns = props.user.currentUser.buttons;
23
+  console.log(userMenus)
24
+  // 获取当前所有菜单
25
+  const [data, setData] = useState({ data: [] })
26
+  const [buttonData, setButtonData] = useState([])
27
+
28
+  // 展示要显示的菜单和按钮----(编辑)
29
+  const [dataMenuId, setDataMenuId] = useState([])
30
+  const [dataButtonId, setDataButtonId] = useState([])
31
+
32
+  const [loading, setLoading] = useState(false);
33
+
34
+  useEffect(() => {
35
+    // 新增和编辑用一个页面
36
+    if (props.location.query) {
37
+      const { id } = props.location.query
38
+      if (id) {
39
+        buttonAndMenuList('', id)
40
+      }
41
+    }
42
+    // menuList({ pageNum: 1, pageSize: 100 })
43
+    buttonList({ pageNum: 1, pageSize: 100 })
44
+  }, [])
45
+  // 当前所有的菜单
46
+  function menuList(params) {
47
+    request({ ...apis.role.menuList, params: { ...params } }).then((data) => {
48
+      setData(data)
49
+  }).catch((err) => {
50
+      console.log(err)
51
+      message.info(err.msg || err.message)
52
+  })
53
+  }
54
+
55
+  // 所有按钮
56
+  function buttonList(params) {
57
+    request({ ...apis.role.buttonList, params: { ...params } }).then((data) => {
58
+      setButtonData(data)
59
+  }).catch((err) => {
60
+      console.log(err)
61
+  })
62
+  }
63
+
64
+
65
+  // 根据角色id查询当前的菜单及其按钮
66
+  function buttonAndMenuList(params, ids) {
67
+    setLoading(true)
68
+    request({ ...apis.role.buttonAndMenuList, urlData: { id: ids }, params: { ...params } }).then(data => {
69
+      setLoading(false)
70
+      props.form.setFieldsValue({ roleName: data.roleName })
71
+      console.log(data)
72
+      setData(data)
73
+
74
+      // 获取所有的权限Id
75
+      if (data.sysMenuList) {
76
+        setDataMenuId(data.sysMenuList.map(item => item && item.menuId))
77
+        // setDataButtonId((data.sysMenuList.map(item => item.sysButtonInMenu && item.sysButtonInMenu.map(btn => btn.btnId).join(',')).filter(f => f !== '').join(',').split(',')).map(a => parseInt(a) ) )
78
+        setDataButtonId(data.sysButtonInMenu.map(item => item && item.btnId))
79
+      }
80
+  }).catch((err) => {
81
+      console.log(err)
82
+      message.info(err.msg || err.message)
83
+  })
84
+  }
85
+
86
+  // const [menus, setMenus] = useState([]);
87
+  // 判断menus是否有值
88
+  const [menus, setMenus] = useState([]);
89
+  const [but, setBut] = useState([]);
90
+
91
+  const addMenus = m => setMenus([...menus, m])
92
+  const delMenus = m => setMenus(menus.filter(x => x.menuId !== m.menuId));
93
+
94
+  const handleMenuChange = m => e => {
95
+    // 如果是根菜单, 把子菜单挑出来
96
+    const isMenuRoot = m.parentCode === '-1'
97
+    const subMenus = isMenuRoot ? userMenus.filter(x => x.parentCode == m.menuId) : []
98
+    // 把子菜单与当前对象, 同时作为当前操作对象
99
+    const currentMenus = [ m, ...subMenus ]
100
+    // 先把选中列表中, 当前操作对象去掉
101
+    const leftCheckedMenusIds = dataMenuId.filter(x => !currentMenus.some(it => it.menuId == x))
102
+
103
+    // 当前选中菜单
104
+    const currentCheckedMenus = e.target.checked ? currentMenus : []
105
+
106
+    // 计算所有选中菜单
107
+    let checkedMenus = [
108
+      ...currentCheckedMenus,
109
+      ...userMenus.filter(x => leftCheckedMenusIds.some(it => it == x.menuId)),
110
+    ]
111
+
112
+    // 如果子菜单全部取消选择, 那么根菜单也取消选择
113
+    // 如果子菜单有一个选中, 那么根菜单也选中
114
+    if (!isMenuRoot) {
115
+      const children = checkedMenus.filter(x => x.menuRoot === m.menuRoot && x.menuId !== m.menuRoot)
116
+      if (!children || children.length < 1) {
117
+        checkedMenus = checkedMenus.filter(x => x.menuId !== m.menuRoot)
118
+      } else {
119
+        const hasRootMenu = checkedMenus.some(x => x.menuId === m.menuRoot)
120
+  
121
+        if (!hasRootMenu) {
122
+          const rootMenu = userMenus.filter(x => x.menuId === m.menuRoot)[0]
123
+          if (rootMenu) {
124
+            checkedMenus.push(rootMenu)
125
+          }
126
+        }
127
+      }
128
+    }
129
+
130
+    // 只要菜单选中, 所属按钮全部选中
131
+    // 菜单取消选择, 所有按钮全部取消选择
132
+    const currentMenuBtns = currentMenus.reduce((acc, it) => [...acc, ...userBtns.filter(x => x.menuId === it.menuId)], [])
133
+    const currentCheckedMenuBtns = currentCheckedMenus.reduce((acc, it) => [...acc, ...userBtns.filter(x => x.menuId === it.menuId)], [])
134
+    const checkedBtns = dataButtonId.filter(x => !currentMenuBtns.some(it => it.btnId === x)).map(x => userBtns.filter(it => x == it.btnId)[0]).concat(...currentCheckedMenuBtns)
135
+
136
+    setMenus(checkedMenus)
137
+    setDataMenuId(checkedMenus.map(x => x.menuId))
138
+    setDataButtonId(checkedBtns.map(x => x.btnId))
139
+    setBut(checkedBtns)
140
+  }
141
+
142
+  // 判断menus是否有值
143
+  const addBut = m => setBut([...but, m])
144
+  const delBut = m => setBut(but.filter(x => x.menuId !== m.menuId));
145
+  const handleButChange = m => e => {
146
+
147
+    // 如果有一个按钮选中, 那么对应的菜单也需要选中
148
+    // 如果没有一个兄弟节点选中, 不做任何处理
149
+    if (e.target.checked) {
150
+      const parentMenuId = dataMenuId.filter(x => x === m.menuId)[0]
151
+
152
+      if (!parentMenuId) {
153
+        const parentMenu = userMenus.filter(x => x.menuId === m.menuId)[0]
154
+        const parentMenuRoot = userMenus.filter(x => x.menuId === parentMenu.menuRoot)[0]
155
+
156
+        const checkedMenus = menus.concat(parentMenu).concat(parentMenuRoot)
157
+        setMenus(checkedMenus)
158
+        setDataMenuId(checkedMenus.map(x => x.menuId))
159
+      }
160
+    }
161
+
162
+    if (e.target.checked) {
163
+      setDataButtonId(dataButtonId.concat(m.btnId))
164
+      addBut(m)
165
+    } else {
166
+      setDataButtonId(dataButtonId.filter(item => item !== m.btnId));
167
+      delBut(m)
168
+    }
169
+  }
170
+  const gridStyle1 = {
171
+    width: '16%',
172
+    textAlign: 'left',
173
+    height: '72px',
174
+    padding:'24px'
175
+  };
176
+  const gridStyle2 = {
177
+    width: '84%',
178
+    textAlign: 'left',
179
+    height: '72px',
180
+  };
181
+
182
+  function toRoleList() {
183
+    router.push({
184
+      pathname: '/staff/RoleList',
185
+    });
186
+  }
187
+
188
+  function updateAuthMenu(data) {
189
+    setLoading(true)
190
+    request({ ...apis.role.updateAuthMenu, data: { ...data } }).then((data) => {
191
+      setLoading(false)
192
+      toRoleList()
193
+  }).catch((err) => {
194
+      console.log(err)
195
+  })
196
+  }
197
+
198
+
199
+  function handleSubmit(e) {
200
+    e.preventDefault();
201
+    props.form.validateFields((err, values) => {
202
+      if (values.roleName === undefined || values.roleName === '') {
203
+        message.error('请输入角色名称')
204
+        return
205
+      }
206
+
207
+      if (props.location.query.id !== undefined) {
208
+        console.log('menus', menus)
209
+      
210
+        const sumitMenu = userMenus.filter(item => dataMenuId.includes(item.menuId))
211
+        const sumitBtn = buttonData.filter(item => dataButtonId.includes(item.btnId))
212
+        updateAuthMenu({ sysMenu: sumitMenu, name: values.roleName, id: props.location.query.id, sysButton: sumitBtn })
213
+      } else {
214
+        updateAuthMenu({ sysMenu: menus, name: values.roleName, id: props.location.query.id, sysButton: but })
215
+        }
216
+    });
217
+  }
218
+  const { getFieldDecorator } = props.form;
219
+  
220
+  return (
221
+    <>
222
+      <div>
223
+      <Spin spinning={ loading } size="large">
224
+        <Form labelCol={{ span: 6 }} wrapperCol={{ span: 12 }} onSubmit={handleSubmit}>
225
+          <Form.Item label="角色名称">
226
+            {getFieldDecorator('roleName', {
227
+              rules: [{ required: true, message: '请输入角色名称' }],
228
+            })(<Input className={channels.inpuit} />)}
229
+
230
+          </Form.Item>
231
+          {userMenus.map(item => (
232
+            (item.parentCode === '-1') &&
233
+            <Row >
234
+              <Col span={6}>
235
+              </Col>
236
+              <Col span={18}>
237
+
238
+                <Card title={<Checkbox checked={dataMenuId.includes(item.menuId)} onChange={handleMenuChange(item)}>{item.name}</Checkbox>} bordered style={{ width: '100%', alignItems: 'center',margin:'10px 0', boxShadow:'3px 3px 10px  rgba(0,0,0,0.15)',borderRadius:'8px'}} >
239
+                  {
240
+                    userMenus.map(menu => (
241
+
242
+                      (item.menuId === menu.menuRoot && item.menuId !== menu.menuId) &&
243
+                      <>
244
+                        <Card.Grid style={gridStyle1} >
245
+                          <Checkbox checked={dataMenuId.includes(menu.menuId)} onChange={handleMenuChange(menu)}>{menu.name}</Checkbox>
246
+                        </Card.Grid>
247
+                        <Card.Grid style={gridStyle2}>
248
+                          {buttonData.length > 0 && buttonData.map(btn => (
249
+                            <>
250
+                              {
251
+                                btn.menuId === menu.menuId &&
252
+                                <Checkbox checked={dataButtonId.includes(btn.btnId)} onChange={handleButChange(btn)}>{btn.name}</Checkbox>
253
+                              }
254
+                            </>
255
+                          ))}
256
+                        </Card.Grid>
257
+                      </>
258
+                    ))
259
+                  }
260
+                </Card>
261
+              </Col>
262
+
263
+            </Row>
264
+          ))}
265
+          <Form.Item wrapperCol={{ span: 15, offset: 7 }} style={{ marginTop: '10px' }}>
266
+            <Button type="primary" htmlType="submit">
267
+              保存
268
+          </Button>
269
+            <Button className={channels.formButton} onClick = {toRoleList}>
270
+              取消
271
+          </Button>
272
+          </Form.Item>
273
+        </Form>
274
+        </Spin>
275
+      </div>
276
+    </>
277
+  )
278
+}
279
+const WrappedNormalLoginForm = Form.create({ name: 'Poster' })(Poster);
280
+export default connect(({ user }) => ({ user }))(WrappedNormalLoginForm);

+ 64
- 0
src/pages/staff/list/channelList.less Wyświetl plik

@@ -0,0 +1,64 @@
1
+.searchBox {
2
+  font-size: 20px;
3
+  color: red;
4
+  display: flex;
5
+  display: flex;
6
+  align-items: center;
7
+  justify-content: space-between;
8
+  .searchItem {
9
+    min-width: 20px;
10
+    margin-right: 20px;
11
+    text-align: left;
12
+    .anticon-down {
13
+      float: right !important;
14
+    }
15
+  }
16
+}
17
+.addBtn {
18
+  padding: 0 30px;
19
+  height: 36px;
20
+  background-color: #50be00;
21
+  color: #fff;
22
+  margin: 30px 0;
23
+}
24
+.touxiang {
25
+  width: 93px;
26
+  height: 93px;
27
+}
28
+.ant-table-column-title {
29
+  font-weight: 600;
30
+}
31
+
32
+.about {
33
+  padding: 0 30px;
34
+  height: 36px;
35
+  background-color: #00bfff;
36
+  color: #fff;
37
+  margin: 30px 0;
38
+}
39
+
40
+.selectName {
41
+  font-size: 17px;
42
+  padding: 0 10px;
43
+  height: 36px;
44
+  color: rgb(10, 10, 10);
45
+  margin: 30px 0;
46
+}
47
+
48
+.inpuit {
49
+  width:50%;
50
+}
51
+
52
+.inpuitTxt {
53
+  width:70%;
54
+}
55
+
56
+
57
+.formButton{
58
+  margin-left: 12% 
59
+}
60
+
61
+.divInput{
62
+  float: 'left'; 
63
+  width: 500
64
+}

+ 159
- 0
src/pages/staff/list/distribution.jsx Wyświetl plik

@@ -0,0 +1,159 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Button, Table, message, Modal } from 'antd';
3
+
4
+import apis from '../../../services/apis';
5
+import request from '../../../utils/request';
6
+import ModalAttribution from '../components/attribution';
7
+import { router } from 'umi';
8
+
9
+function body(props) {
10
+    console.log('props.localtion.query: ', props.location.query)
11
+
12
+    const { id } = props.location.query
13
+    
14
+
15
+    // eslint-disable-next-line react-hooks/rules-of-hooks
16
+    const [dataSource, setDataSource] = useState({ records: [], current: 1, size: 10, total: 0 })
17
+    // eslint-disable-next-line react-hooks/rules-of-hooks
18
+    const [consultant, setConsultant] = useState({ consultantUserId: '', consultantName: '' })
19
+
20
+    // eslint-disable-next-line react-hooks/rules-of-hooks
21
+    const [selectedRowIndex, setSelectedRowIndex] = useState([])
22
+
23
+    // eslint-disable-next-line react-hooks/rules-of-hooks
24
+    const [customerIdList, setCustomerIdList] = useState([])
25
+
26
+    // eslint-disable-next-line react-hooks/rules-of-hooks
27
+    const [visibleData, setVisibleData] = useState({ visible: false, realtyConsultant: '', buildingId: '', userId: '' })
28
+
29
+    // eslint-disable-next-line react-hooks/rules-of-hooks
30
+    const [userData, setUserData] = useState({})
31
+
32
+    // eslint-disable-next-line react-hooks/rules-of-hooks
33
+    useEffect(() => {
34
+        if (id) {
35
+            getList({ pageNumber: 1, pageSize: 99999, userId: id })
36
+            getUserData(id)
37
+        }
38
+    }, [])
39
+
40
+    function getList(params) {
41
+        // 网路请求
42
+        request({ ...apis.customer.byUserIdSelectCustomer, urlData: { id: params.userId }, params: { ...params } }).then(res => {
43
+          setDataSource(res)
44
+        }).catch(() => {
45
+
46
+        })
47
+    }
48
+
49
+     // 查询列表
50
+    function getUserData(userId) {
51
+        request({ ...apis.staff.getTaUser, urlData: { id: userId } }).then((data) => {
52
+            setUserData(data)
53
+        })
54
+    }
55
+
56
+    function onShow() {
57
+        setVisibleData({ visible: true, realtyConsultant: '', buildingId: userData.buildingId, userId: userData.userId })
58
+    }
59
+
60
+    function onCancel() {
61
+        setVisibleData({ visible: false, realtyConsultant: '', buildingId: '', userId: '' })
62
+    }
63
+
64
+    function onSuccess({ realtyConsultant, name }) {
65
+        setConsultant({ consultantUserId: realtyConsultant, consultantName: name })
66
+    }
67
+
68
+    function onSubmit() {
69
+        if (customerIdList.length !== dataSource.total) {
70
+            message.error('存在未分配归属客户')
71
+            return
72
+        }
73
+
74
+        if (consultant.consultantId === '') {
75
+            message.error('请选择分配归属的置业顾问')
76
+            return
77
+        }
78
+
79
+        Modal.confirm({
80
+            title: '确认保存后,当前员工下的客户数据将转移',
81
+            content: '同时删除此员工所有数据,确认进行保存操作?',
82
+            okText: '确认',
83
+            cancelText: '取消',
84
+            onOk () {
85
+                request({ ...apis.staff.departure, urlData: { id: userData.userId }, params: { customerIdList, consultantUserId: consultant.consultantUserId } }).then(() => {
86
+                    message.info('操作成功')
87
+                    props.onFresh()
88
+                    router.go(-1)
89
+                }).catch(() => {
90
+          
91
+                })
92
+            },
93
+          });
94
+    }
95
+
96
+    const rowSelection = {
97
+        selectedRowKeys: selectedRowIndex,
98
+        hideDefaultSelections: true,
99
+        onChange: (selectedRowKeys, selectedRows) => {
100
+          console.log('selectedRowKeys: ', selectedRowKeys, 'selectedRows: ', selectedRows, selectedRowKeys);
101
+          setSelectedRowIndex(selectedRowKeys)
102
+          setCustomerIdList(selectedRows.map(p => p.customerId))
103
+        },
104
+    };
105
+
106
+    const columns = [
107
+        {
108
+          title: '用户名',
109
+          dataIndex: 'name',
110
+          key: 'name',
111
+          align: 'center',
112
+        },
113
+        {
114
+          title: '手机号',
115
+          dataIndex: 'phone',
116
+          align: 'center',
117
+          key: 'phone',
118
+        },
119
+        {
120
+            title: '状态',
121
+            dataIndex: 'reportRecommendStatus',
122
+            key: 'reportRecommendStatus',
123
+            align: 'center',
124
+            // eslint-disable-next-line no-nested-ternary
125
+            render: (text, records) => {
126
+              if (records.status === 1) { return '报备' }
127
+              if (records.status === 2) { return '到访' }
128
+              if (records.status === 3) { return '认筹' }
129
+              if (records.status === 4) { return '签约' }
130
+            },
131
+          },
132
+        {
133
+            title: '调整后归属',
134
+            dataIndex: 'consultantName',
135
+            key: 'consultantName',
136
+            align: 'center',
137
+            render: (text, records, index) => {
138
+                return selectedRowIndex.includes(index) ? consultant.consultantName : ''
139
+            },
140
+        },
141
+      ];
142
+
143
+    return (
144
+        <>
145
+            <Button type="primary" onClick={() => onShow()}>分配归属</Button>
146
+            <Table rowSelection={rowSelection} dataSource={dataSource.records} columns={columns} pagination={{ pageSize: dataSource.size, current: dataSource.current, total: dataSource.total }} />
147
+            <div style={{ display: 'flex', justifyContent: 'center', marginTop: '20px' }}>
148
+                <Button type="primary" onClick={() => onSubmit()}>保存</Button>
149
+                &nbsp;&nbsp;&nbsp;&nbsp;
150
+                <Button onClick={() => router.go(-1)}>取消</Button>
151
+            </div>
152
+
153
+            {/* 选择只顾问弹框 */}
154
+            <ModalAttribution visibleData={visibleData} onCancel={() => onCancel()} onSuccess={e => onSuccess(e)}/>
155
+        </>
156
+    )
157
+}
158
+
159
+export default body

+ 203
- 0
src/pages/staff/list/editRole.jsx Wyświetl plik

@@ -0,0 +1,203 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Checkbox, Input, Card } from 'antd';
3
+import { connect } from 'dva';
4
+import XForm, { FieldTypes } from '../../../components/XForm';
5
+import request from '../../../utils/request';
6
+import channels from './channelList.less';
7
+import { resolve } from 'path';
8
+
9
+const { TextArea } = Input;
10
+
11
+
12
+/**
13
+ *
14
+ *
15
+ * @param {*} props
16
+ * @returns
17
+ */
18
+const Edit = props => {
19
+  console.log('props,props', props.user.currentUser)
20
+  const userMenus = props.user.currentUser.menus;
21
+  const userBtns = props.user.currentUser.buttons;
22
+
23
+  const [data, setData] = useState({ data: [] })
24
+ // 获取当前所有菜单
25
+  useEffect(() => {
26
+    localStorage.removeItem('value');
27
+    menuList({ pageNum: 1, pageSize: 100 })
28
+  }, [])
29
+
30
+  function menuList(params) {
31
+    request({
32
+      url: '/api/admin/menuList',
33
+      method: 'GET',
34
+      params: { ...params },
35
+  // eslint-disable-next-line no-shadow
36
+  }).then(data => {
37
+      console.log(data)
38
+      setData(data)
39
+  })
40
+  }
41
+
42
+  // function SuBmenu(params) {
43
+  //  return Array.from(userMenus).map(Item =>
44
+  //  <Checkbox value={ Item.menuId }> { Item.name }</Checkbox>)
45
+  // }
46
+  // const [tab, changeTab] = useState('basic')
47
+
48
+  const Permission = [
49
+    '项目管理',
50
+    '员工管理',
51
+    '客户管理',
52
+    '系统管理',
53
+    '渠道管理',
54
+    '轮播图管理',
55
+    '资讯管理',
56
+    '活动管理',
57
+    '积分商城',
58
+    '首页数据',
59
+  ]
60
+
61
+  const Poster = props => {
62
+    const [menus, setMenus] = useState([]);
63
+// 判断menus是否有值
64
+    const addMenus = m => setMenus([...menus, m]);
65
+    const delMenus = m => setMenus(menus.filter(x => x.menuId !== m.menuId));
66
+    const handleMenuChange = m => e => {
67
+      console.log('e', m)
68
+      if (e.target.checked) {
69
+        addMenus(m)
70
+      } else {
71
+        delMenus(m)
72
+      }
73
+      console.log('menus', menus)
74
+    }
75
+
76
+    const [but, setBut] = useState([]);
77
+    // 判断menus是否有值
78
+        const addBut = m => setBut([...but, m]);
79
+        const delBut = m => setBut(but.filter(x => x.menuId !== m.menuId));
80
+        const handleButChange = m => e => {
81
+          console.log('e', m)
82
+          if (e.target.checked) {
83
+            addBut(m)
84
+          } else {
85
+            delBut(m)
86
+          }
87
+          // console.log('menus', menus)
88
+
89
+          console.log('menus', menus)
90
+          console.log('but', but)
91
+        }
92
+
93
+
94
+    const dataSource = [
95
+      {
96
+        name: '员工管理',
97
+        per: [
98
+          '111111',
99
+          '22222',
100
+          '33333',
101
+        ],
102
+      },
103
+      {
104
+        name: '角色管理',
105
+        per: [
106
+          '444',
107
+          '555',
108
+          '666',
109
+        ],
110
+      },
111
+    ];
112
+
113
+
114
+    const gridStyle1 = {
115
+      width: '20%',
116
+      textAlign: 'left',
117
+    };
118
+    const gridStyle2 = {
119
+      width: '80%',
120
+      textAlign: 'left',
121
+      height: '69px',
122
+    };
123
+
124
+    return (
125
+    <>
126
+      <div style={{}}>
127
+        {/* { console.log('userMenus', userMenus) }
128
+        { console.log('userBtns', userBtns) } */}
129
+        {userMenus.map(item => (
130
+          (item.parentCode === '-1') &&
131
+          <Card title={<Checkbox onChange={handleMenuChange(item)}>{item.name}</Checkbox>} bordered style={{ width: '100%' }}>
132
+              {
133
+                   userMenus.map(menu => (
134
+
135
+                    (item.menuId === menu.menuRoot && item.menuId !== menu.menuId) &&
136
+                    <>
137
+                      <Card.Grid style={gridStyle1} >
138
+                          <Checkbox onChange={handleMenuChange(menu)}>{menu.name}</Checkbox>
139
+                      </Card.Grid>
140
+                      <Card.Grid style={gridStyle2}>
141
+                        {userBtns.map(btn => (
142
+                          <>
143
+                            {
144
+                              btn.menuId === menu.menuId &&
145
+                              <Checkbox onChange={handleButChange(btn)}>{btn.name}</Checkbox>
146
+                            }
147
+                          </>
148
+                        ))}
149
+                      </Card.Grid>
150
+                   </>
151
+                   ))
152
+              }
153
+          </Card>
154
+        ))}
155
+      </div>
156
+    </>
157
+    )
158
+  }
159
+
160
+  const fields = [
161
+    {
162
+      label: '角色名称',
163
+      name: 'roleName',
164
+      type: FieldTypes.Text,
165
+      // placeholder: '名称',
166
+      value: ''
167
+    },
168
+    {
169
+      label: '简介',
170
+      name: 'roleIntroduction',
171
+      render: <TextArea className={channels.inpuitTxt} ></TextArea>,
172
+      value: ''
173
+
174
+    },
175
+
176
+    {
177
+      label: '菜单权限',
178
+      name: 'rolePermission',
179
+      render:
180
+        <>
181
+          <div>
182
+            <Poster/>
183
+          </div>
184
+        </>,
185
+    },
186
+
187
+  ]
188
+
189
+  const handleSubmit = val => {
190
+    window.console.log('submit data --->', val)
191
+    request({
192
+      url: '/api/admin/menuList',
193
+      method: 'POST',
194
+      params: { ...params },
195
+  // eslint-disable-next-line no-shadow
196
+  }).then(data => {
197
+      console.log(data)
198
+      setData(data)
199
+  })
200
+  }
201
+  return <XForm onSubmit={handleSubmit} fields={fields}></XForm>
202
+}
203
+export default connect(({ user }) => ({ user }))(Edit);

+ 324
- 0
src/pages/staff/list/editStaff.jsx Wyświetl plik

@@ -0,0 +1,324 @@
1
+import React, { useState, useEffect } from 'react';
2
+
3
+import { Input, Menu, Dropdown, Button, Icon, message, Table, Tooltip, Tabs, Radio, Divider, Tag, Select, Form, Alert, Modal } from 'antd';
4
+import { FormattedMessage } from 'umi-plugin-react/locale';
5
+import BuildSelect from '../../../components/SelectButton/BuildSelect'
6
+import router from 'umi/router';
7
+import styles from '../../style/GoodsList.less';
8
+import { FieldTypes, createForm } from '../../../components/XForm';
9
+import Wangedit from '../../../components/Wangedit/Wangedit'
10
+import channels from './channelList.less';
11
+import Tagss from '../components/Tagss.jsx';
12
+import apis from '../../../services/apis';
13
+import request from '../../../utils/request'
14
+import BuildingSelection from '../components/BuildingSelection'
15
+
16
+const { TextArea } = Input;
17
+const { Option } = Select;
18
+let consultantChecked = false;
19
+
20
+const setExtraData = (data) => {
21
+  consultantChecked = data.isConsultant
22
+}
23
+
24
+const handleFormValueChange = (props, changedValues, allValues) => {
25
+    setExtraData(allValues)
26
+}
27
+
28
+const XForm = createForm({ onValuesChange: handleFormValueChange })
29
+
30
+/**
31
+ *
32
+ *
33
+ * @param {*} props
34
+ * @returns
35
+ */
36
+const Edit = (props) => {
37
+  const userId = props.location.query.userId
38
+  const [userData, setUserData] = useState({})
39
+  const [tagData, setTagData] = useState([])
40
+  const [roleData, setRoleData] = useState([])
41
+  const [buildData, setBuildData] = useState([])
42
+  const [visible, setVisible] = useState(false)
43
+
44
+  const getTagList = () => {
45
+    request({ ...apis.staff.taTags, params: { pageNum: 1, pageSize: 999 } }).then((data) => {
46
+      setTagData(data.records)
47
+    })
48
+  }
49
+
50
+  const getRoleList = () => {
51
+    request({ ...apis.role.getRoleList, params: { pageNum: 1, pageSize: 999 } }).then((data) => {
52
+      console.log(data)
53
+      setRoleData(data.records)
54
+    })
55
+  }
56
+
57
+  //获取项目列表
58
+  const getBuildList = e => {
59
+    request({ ...apis.building.buildingSelect, params: { pageNum: 1, pageSize: 999 } }).then(data => {
60
+        setBuildData(data)
61
+    })
62
+  }
63
+
64
+  // 查询列表
65
+  const getUserData = (userId) => {
66
+    request({ ...apis.staff.getTaUser, urlData: { id: userId } }).then((data) => {
67
+      consultantChecked = data.isConsultant
68
+      setUserData(data)
69
+    })
70
+  }
71
+
72
+  if(userData.buildingIds && buildData.length > 0 && !consultantChecked){
73
+      const newBuildings = userData.buildingIds.filter(x => buildData.filter(it => it.buildingId === x)[0])
74
+      userData.buildingIds = newBuildings
75
+  }
76
+
77
+  if(userData.roleIds && roleData.length > 0){
78
+    const newRoleIds = userData.roleIds.filter(x => roleData.filter(it => it.roleId === x)[0])
79
+      userData.roleIds = newRoleIds
80
+  }
81
+
82
+  useEffect(() => {
83
+    getTagList();
84
+    getRoleList();
85
+    getBuildList();
86
+    if (userId) {
87
+      getUserData(userId);
88
+    }
89
+  }, [])
90
+
91
+  const tagsChange = (value) => {
92
+    console.log(`selected ${value}`);
93
+  }
94
+
95
+  const handleSubmit = val => {
96
+    if (userId) {
97
+      request({ ...apis.staff.updateTaUser, urlData: { id: userId }, data: val, }).then((data) => {
98
+        console.log(data, "tauser")
99
+        message.info("保存成功")
100
+        router.go(-1)
101
+      }).catch(error => {
102
+        // message.info(error.message)
103
+      })
104
+    } else {
105
+      request({ ...apis.staff.addTaUser, data: val, }).then((data) => {
106
+        console.log(data, "tauser")
107
+        message.info("保存成功")
108
+        router.go(-1)
109
+      }).catch(error => {
110
+        // message.info(error.message)
111
+      })
112
+    }
113
+  }
114
+
115
+  const photoBeforeUpload = (file) => {
116
+    // const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
117
+    // if (!isJpgOrPng) {
118
+    //   message.error('请上传 JPG/PNG 格式的图片!');
119
+    // }
120
+    console.log(file.size, file.size / 1024)
121
+    const isLt100k = (file.size / 1024) < 100;
122
+    if (!isLt100k) {
123
+      message.error('请上传小于100k的图片!');
124
+    }
125
+    return isLt100k;
126
+  }
127
+
128
+  //授权项目改变
129
+  const consultantBuildingChange =(e) => {
130
+    if(userData.isConsultant){
131
+      request({ ...apis.staff.check, params: { userId: userData.userId, personId: userData.consultantPersonId, buildingId: userData.buildingId } }).then(res => {
132
+        if(res.length > 0){
133
+          Modal.confirm({
134
+            title: '此置业顾问下有私客,是否转移私客?',
135
+            okText: '确认',
136
+            cancelText: '取消',
137
+            onOk () {
138
+              setVisible(true)
139
+            },
140
+          });
141
+        }
142
+     })
143
+    }
144
+  }
145
+
146
+   //迁移私客成功回调
147
+   const moveSuccess = (e) => {
148
+    setVisible(false)
149
+  }
150
+
151
+  const fields = [
152
+    {
153
+      label: '姓名',
154
+      name: 'userName',
155
+      type: FieldTypes.Text,
156
+      value: userData.userName,
157
+      rules: [
158
+        { required: true, message: '请输入姓名' },
159
+      ]
160
+    },
161
+    {
162
+      label: '公司',
163
+      name: 'orgName',
164
+      type: FieldTypes.Text,
165
+      placeholder: '请输入公司名称',
166
+      value: userData.orgName,
167
+      rules: [
168
+        { required: true, message: '请输入公司名称' },
169
+      ]
170
+    },
171
+    {
172
+      label: '部门',
173
+      name: 'department',
174
+      type: FieldTypes.Text,
175
+      placeholder: '请输入部门',
176
+      value: userData.department,
177
+      rules: [
178
+        { required: true, message: '请输入部门' },
179
+      ]
180
+    },
181
+    {
182
+      label: '职位',
183
+      name: 'position',
184
+      type: FieldTypes.Text,
185
+      placeholder: '请输入职位',
186
+      value: userData.position,
187
+      rules: [
188
+        { required: true, message: '请输入职位' },
189
+      ]
190
+    },
191
+    {
192
+      label: '是否置业顾问',
193
+      name: 'isConsultant',
194
+      type: FieldTypes.Switch,
195
+      value: userData.isConsultant,
196
+      props: {disabled: userData.isConsultant},
197
+    },
198
+    {
199
+      label: '电话',
200
+      name: 'phone',
201
+      type: FieldTypes.Text,
202
+      placeholder: '请输入电话号码',
203
+      value: userData.phone,
204
+      rules: [
205
+        {
206
+            required: true,
207
+            pattern: new RegExp('^1[0-9]{10}$'),
208
+            message: '请输入正确的电话号码',
209
+        },
210
+      ]
211
+    },
212
+    {
213
+      label: '登录名',
214
+      name: 'loginName',
215
+      type: FieldTypes.Text,
216
+      placeholder: '请输入登录名',
217
+      value: userData.loginName,
218
+      // hidden: () => consultantChecked,
219
+      help: '默认密码:123456',
220
+    },
221
+    {
222
+      label: '角色',
223
+      name: 'roleIds',
224
+      render: <Select
225
+        mode="multiple"
226
+        style={{ width: '100%' }}
227
+        placeholder="请选择标签"
228
+        onChange={tagsChange} >
229
+        {roleData.map(item => (
230
+          <Select.Option key={item.roleId} value={item.roleId}>
231
+            {item.roleName}
232
+          </Select.Option>
233
+        ))}
234
+      </Select>,
235
+      value: userData.roleIds,
236
+    },
237
+    {
238
+      label: '授权项目',
239
+      name: 'buildingId',
240
+      render: <BuildingSelection userData={userData} />,
241
+      value: userData.buildingId,
242
+      hidden: () => !consultantChecked,
243
+      rules: [
244
+        { required: true, message: '请选择授权项目' },
245
+      ]
246
+    },
247
+    {
248
+      label: '授权项目',
249
+      name: 'buildingIds',
250
+      render: <Select
251
+        mode="multiple"
252
+        showSearch
253
+        style={{ width: '100%' }}
254
+        placeholder="请选择授权项目"
255
+        filterOption={(input, option) =>
256
+          option.props.children && option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
257
+        }
258
+        >
259
+        {buildData.map(item => (
260
+          <Select.Option key={item.buildingId} value={item.buildingId}>
261
+            {item.buildingName}
262
+          </Select.Option>
263
+        ))}
264
+      </Select>,
265
+      value: userData.buildingIds,
266
+      hidden: () => consultantChecked,
267
+      rules: [
268
+        { required: true, message: '请选择授权项目' },
269
+      ]
270
+    },
271
+    {
272
+      label: '置业顾问头像',
273
+      name: 'photo',
274
+      type: FieldTypes.ImageUploader,
275
+      extra: '建议图片尺寸:320*320px,比例1:1,格式:jpg,用于置业顾问头像,限制大小:100k',
276
+      value: userData.photo,
277
+      beforeUpload: (e) => photoBeforeUpload(e),
278
+      rules: [
279
+        { required: true, message: '请选择头像' },
280
+      ]
281
+    },
282
+    {
283
+      label: '简介',
284
+      name: 'description',
285
+      render: <TextArea className={channels.inpuitTxt} ></TextArea>,
286
+      value: userData.description
287
+
288
+    },
289
+    {
290
+      label: '状态',
291
+      name: 'status',
292
+      render: <Radio.Group initialValue="1" buttonStyle="solid">
293
+        <Radio.Button value="9">禁用</Radio.Button>
294
+        <Radio.Button value="1">启用</Radio.Button>
295
+      </Radio.Group>,
296
+      value: userData.status != null ? userData.status.toString() : "1"
297
+    },
298
+    {
299
+      label: '权重',
300
+      name: 'weight',
301
+      type: FieldTypes.Number,
302
+      render: <Input type="number" style={{ width: 150}} />,
303
+      value: userData.weight,
304
+      help: '数字越大越靠前',
305
+    },
306
+  ]
307
+
308
+  console.log('--------->', fields)
309
+
310
+  return <div>
311
+            <XForm onChange={console.log} onSubmit={handleSubmit} fields={fields.filter(Boolean)} onCancel={() => router.go(-1)}></XForm>
312
+            {/* <Modal
313
+              visible={visible}
314
+              title="分配归属"
315
+              onCancel={() => setVisible(false)}
316
+              footer={null}
317
+              width={900}
318
+            >
319
+                <CustomerChange userId={userData.userId} consultantPersonId={userData.consultantPersonId} buildingId={userData.buildingId} onSuccess={moveSuccess} />
320
+            </Modal> */}
321
+        </div>
322
+}
323
+
324
+export default Edit

+ 56
- 0
src/pages/staff/list/index.jsx Wyświetl plik

@@ -0,0 +1,56 @@
1
+import React, { useMemo, useRef, useCallback, useState } from 'react'
2
+import {Button} from 'antd'
3
+import apis from '@/services/apis'
4
+import AuthButton from '@/components/AuthButton';
5
+// import QueryTable from '@/components/QueryTable'
6
+import TableList from '@/components/TableList'
7
+import getTableColumns from './tableColumns'
8
+import { router } from 'umi';
9
+
10
+export default (props) => {
11
+  const ref = useRef()
12
+  const [page, setPage] = useState({current: 1, pageSize: 10})
13
+  const toEdit = useCallback((row) => {
14
+    //
15
+    router.push({
16
+      pathname: '/building/Developers/Edit',
17
+      query: {
18
+        id: row?.id || undefined,
19
+      },
20
+    });
21
+  }, [])
22
+
23
+  const onDelete = useCallback((row) => {
24
+
25
+  }, [])
26
+
27
+
28
+  const tableColumns = useMemo(() => {
29
+    return getTableColumns({
30
+      page,
31
+      onEdit:(e)=>toEdit(e),
32
+      onDelete,
33
+    })
34
+  }, [page])
35
+
36
+  const actionRender = () => {
37
+    return (
38
+      <AuthButton name="admin.tdBuildingType.add" noRight={null}>
39
+        <Button type="primary" icon="plus" onClick={() => toEdit()} >
40
+          新增
41
+        </Button>
42
+      </AuthButton>
43
+    );
44
+  };
45
+
46
+  return (
47
+    <>
48
+      <TableList
49
+        rowKey="buildingId"
50
+        api={apis.building.getList}
51
+        columns={tableColumns}
52
+        actionRender={actionRender}
53
+      />
54
+    </>
55
+  )
56
+}

+ 82
- 0
src/pages/staff/list/style.less Wyświetl plik

@@ -0,0 +1,82 @@
1
+.SubmitButton {
2
+  background: #3a91d5;
3
+  border-radius: 7px;
4
+  border: 0px;
5
+}
6
+
7
+.SelectFrom {
8
+  width: 180px;
9
+  background: #ffffff;
10
+  border-radius: 7px;
11
+  border: 1px solid #dbdbdb;
12
+}
13
+
14
+
15
+.card {
16
+  min-width: 240px;
17
+  margin-right: 0.1rem;
18
+  height: 1.4rem;
19
+  background: rgba(255, 255, 255, 1);
20
+  box-shadow: 0px 0px 16px 2px rgba(0, 0, 0, 0.12);
21
+  border-radius: 12px;
22
+  margin-bottom: 40px;
23
+  position: relative;
24
+  padding: 0.1rem;
25
+  
26
+}
27
+
28
+.cardText {
29
+  font-size: 0.12rem;
30
+  color: rgba(102, 102, 102, 1);
31
+  position: absolute;
32
+  bottom:0.28rem;
33
+}
34
+.statusText {
35
+  font-size: 0.12rem;
36
+  color: rgba(102, 102, 102, 1);
37
+  position: absolute;
38
+  bottom:0.28rem;
39
+  right: 20px;
40
+}
41
+.phoneText{
42
+  font-size: 0.12rem;
43
+  color: rgba(102, 102, 102, 1);
44
+  position: absolute;
45
+  bottom:0.05rem;
46
+}
47
+
48
+.cardItem {
49
+  color: #666;
50
+  display: flex;
51
+  align-items: center;
52
+  line-height: 1.5;
53
+  font-size: 0.106rem;
54
+  margin-bottom: 0.08rem;
55
+}
56
+
57
+
58
+.cardTag {
59
+  font-size: 10px;
60
+  border-radius: 4px;
61
+  color: #ffffff;
62
+  line-height: 16px;
63
+  margin-top: 10px;
64
+  padding: 1px 3px;
65
+
66
+}
67
+
68
+.title {
69
+  display: inline-block;
70
+  width:  0.54rem;
71
+  justify-content: space-between;
72
+  text-align: justify;
73
+  text-align-last: justify;
74
+}
75
+
76
+
77
+.roletext {
78
+  font-size: 20px;
79
+  font-weight: 400;
80
+  color: rgba(51, 51, 51, 1);
81
+  line-height: 28px;
82
+}

+ 314
- 0
src/pages/staff/staff/Edit/index.jsx Wyświetl plik

@@ -0,0 +1,314 @@
1
+import React, { useState, useEffect } from 'react';
2
+
3
+import { Input, Card, message, Radio, Select, Modal } from 'antd';
4
+import { FormattedMessage } from 'umi-plugin-react/locale';
5
+import BuildSelect from '@/components/SelectButton/BuildSelect'
6
+import router from 'umi/router';
7
+import { FieldTypes, createForm } from '@/components/XForm';
8
+import Wangedit from '@/components/Wangedit/Wangedit'
9
+// import channels from './channelList.less';
10
+// import Tagss from '../components/Tagss.jsx';
11
+import apis from '@/services/apis';
12
+import request from '@/utils/request'
13
+import BuildingSelection from '../components/BuildingSelection'
14
+
15
+const { TextArea } = Input;
16
+const { Option } = Select;
17
+let consultantChecked = false;
18
+
19
+const setExtraData = (data) => {
20
+  consultantChecked = data.isConsultant
21
+}
22
+
23
+const handleFormValueChange = (props, changedValues, allValues) => {
24
+    setExtraData(allValues)
25
+}
26
+
27
+const XForm = createForm({ onValuesChange: handleFormValueChange })
28
+
29
+/**
30
+ *
31
+ *
32
+ * @param {*} props
33
+ * @returns
34
+ */
35
+const StaffEdit = (props) => {
36
+  const userId = props.location.query.userId
37
+  const [userData, setUserData] = useState({})
38
+  const [tagData, setTagData] = useState([])
39
+  const [roleData, setRoleData] = useState([])
40
+  const [buildData, setBuildData] = useState([])
41
+  const [visible, setVisible] = useState(false)
42
+
43
+  const getTagList = () => {
44
+    request({ ...apis.staff.taTags, params: { pageNum: 1, pageSize: 999 } }).then((data) => {
45
+      setTagData(data.records)
46
+    })
47
+  }
48
+
49
+  const getRoleList = () => {
50
+    request({ ...apis.role.getRoleList, params: { pageNum: 1, pageSize: 999 } }).then((data) => {
51
+      console.log(data)
52
+      setRoleData(data.records)
53
+    })
54
+  }
55
+
56
+  //获取项目列表
57
+  const getBuildList = e => {
58
+    request({ ...apis.building.buildingSelect, params: { pageNum: 1, pageSize: 999 } }).then(data => {
59
+        setBuildData(data)
60
+    })
61
+  }
62
+
63
+  // 查询列表
64
+  const getUserData = (userId) => {
65
+    request({ ...apis.staff.getTaUser, urlData: { id: userId } }).then((data) => {
66
+      consultantChecked = data.isConsultant
67
+      setUserData(data)
68
+    })
69
+  }
70
+
71
+  if(userData.buildingIds && buildData.length > 0 && !consultantChecked){
72
+      const newBuildings = userData.buildingIds.filter(x => buildData.filter(it => it.buildingId === x)[0])
73
+      userData.buildingIds = newBuildings
74
+  }
75
+
76
+  if(userData.roleIds && roleData.length > 0){
77
+    const newRoleIds = userData.roleIds.filter(x => roleData.filter(it => it.roleId === x)[0])
78
+      userData.roleIds = newRoleIds
79
+  }
80
+
81
+  useEffect(() => {
82
+    getTagList();
83
+    getRoleList();
84
+    getBuildList();
85
+    if (userId) {
86
+      getUserData(userId);
87
+    }
88
+  }, [])
89
+
90
+  const tagsChange = (value) => {
91
+    console.log(`selected ${value}`);
92
+  }
93
+
94
+  const handleSubmit = val => {
95
+    if (userId) {
96
+      request({ ...apis.staff.updateTaUser, urlData: { id: userId }, data: val, }).then((data) => {
97
+        console.log(data, "tauser")
98
+        message.info("保存成功")
99
+        router.go(-1)
100
+      }).catch(error => {
101
+        // message.info(error.message)
102
+      })
103
+    } else {
104
+      request({ ...apis.staff.addTaUser, data: val, }).then((data) => {
105
+        console.log(data, "tauser")
106
+        message.info("保存成功")
107
+        router.go(-1)
108
+      }).catch(error => {
109
+        // message.info(error.message)
110
+      })
111
+    }
112
+  }
113
+
114
+  const photoBeforeUpload = (file) => {
115
+    // const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
116
+    // if (!isJpgOrPng) {
117
+    //   message.error('请上传 JPG/PNG 格式的图片!');
118
+    // }
119
+    console.log(file.size, file.size / 1024)
120
+    const isLt100k = (file.size / 1024) < 100;
121
+    if (!isLt100k) {
122
+      message.error('请上传小于100k的图片!');
123
+    }
124
+    return isLt100k;
125
+  }
126
+
127
+  //授权项目改变
128
+  const consultantBuildingChange =(e) => {
129
+    if(userData.isConsultant){
130
+      request({ ...apis.staff.check, params: { userId: userData.userId, personId: userData.consultantPersonId, buildingId: userData.buildingId } }).then(res => {
131
+        if(res.length > 0){
132
+          Modal.confirm({
133
+            title: '此置业顾问下有私客,是否转移私客?',
134
+            okText: '确认',
135
+            cancelText: '取消',
136
+            onOk () {
137
+              setVisible(true)
138
+            },
139
+          });
140
+        }
141
+     })
142
+    }
143
+  }
144
+
145
+   //迁移私客成功回调
146
+   const moveSuccess = (e) => {
147
+    setVisible(false)
148
+  }
149
+
150
+  const fields = [
151
+    {
152
+      label: '姓名',
153
+      name: 'userName',
154
+      type: FieldTypes.Text,
155
+      value: userData.userName,
156
+      rules: [
157
+        { required: true, message: '请输入姓名' },
158
+      ]
159
+    },
160
+    {
161
+      label: '公司',
162
+      name: 'orgName',
163
+      type: FieldTypes.Text,
164
+      placeholder: '请输入公司名称',
165
+      value: userData.orgName,
166
+      rules: [
167
+        { required: true, message: '请输入公司名称' },
168
+      ]
169
+    },
170
+    {
171
+      label: '部门',
172
+      name: 'department',
173
+      type: FieldTypes.Text,
174
+      placeholder: '请输入部门',
175
+      value: userData.department,
176
+      rules: [
177
+        { required: true, message: '请输入部门' },
178
+      ]
179
+    },
180
+    {
181
+      label: '职位',
182
+      name: 'position',
183
+      type: FieldTypes.Text,
184
+      placeholder: '请输入职位',
185
+      value: userData.position,
186
+      rules: [
187
+        { required: true, message: '请输入职位' },
188
+      ]
189
+    },
190
+    {
191
+      label: '是否置业顾问',
192
+      name: 'isConsultant',
193
+      type: FieldTypes.Switch,
194
+      value: userData.isConsultant,
195
+      props: {disabled: userData.isConsultant},
196
+    },
197
+    {
198
+      label: '电话',
199
+      name: 'phone',
200
+      type: FieldTypes.Text,
201
+      placeholder: '请输入电话号码',
202
+      value: userData.phone,
203
+      rules: [
204
+        {
205
+            required: true,
206
+            pattern: new RegExp('^1[0-9]{10}$'),
207
+            message: '请输入正确的电话号码',
208
+        },
209
+      ]
210
+    },
211
+    {
212
+      label: '登录名',
213
+      name: 'loginName',
214
+      type: FieldTypes.Text,
215
+      placeholder: '请输入登录名',
216
+      value: userData.loginName,
217
+      // hidden: () => consultantChecked,
218
+      help: '默认密码:123456',
219
+    },
220
+    {
221
+      label: '角色',
222
+      name: 'roleIds',
223
+      render: <Select
224
+        mode="multiple"
225
+        style={{ width: '100%' }}
226
+        placeholder="请选择标签"
227
+        onChange={tagsChange} >
228
+        {roleData.map(item => (
229
+          <Select.Option key={item.roleId} value={item.roleId}>
230
+            {item.roleName}
231
+          </Select.Option>
232
+        ))}
233
+      </Select>,
234
+      value: userData.roleIds,
235
+    },
236
+    {
237
+      label: '授权项目',
238
+      name: 'buildingId',
239
+      render: <BuildingSelection userData={userData} />,
240
+      value: userData.buildingId,
241
+      hidden: () => !consultantChecked,
242
+      rules: [
243
+        { required: true, message: '请选择授权项目' },
244
+      ]
245
+    },
246
+    {
247
+      label: '授权项目',
248
+      name: 'buildingIds',
249
+      render: <Select
250
+        mode="multiple"
251
+        showSearch
252
+        style={{ width: '100%' }}
253
+        placeholder="请选择授权项目"
254
+        filterOption={(input, option) =>
255
+          option.props.children && option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
256
+        }
257
+        >
258
+        {buildData.map(item => (
259
+          <Select.Option key={item.buildingId} value={item.buildingId}>
260
+            {item.buildingName}
261
+          </Select.Option>
262
+        ))}
263
+      </Select>,
264
+      value: userData.buildingIds,
265
+      hidden: () => consultantChecked,
266
+      rules: [
267
+        { required: true, message: '请选择授权项目' },
268
+      ]
269
+    },
270
+    {
271
+      label: '置业顾问头像',
272
+      name: 'photo',
273
+      type: FieldTypes.ImageUploader,
274
+      extra: '建议图片尺寸:320*320px,比例1:1,格式:jpg,用于置业顾问头像,限制大小:100k',
275
+      value: userData.photo,
276
+      beforeUpload: (e) => photoBeforeUpload(e),
277
+      rules: [
278
+        { required: true, message: '请选择头像' },
279
+      ]
280
+    },
281
+    {
282
+      label: '简介',
283
+      name: 'description',
284
+      render: <TextArea  ></TextArea>,
285
+      value: userData.description
286
+      // className={channels.inpuitTxt}
287
+    },
288
+    {
289
+      label: '状态',
290
+      name: 'status',
291
+      render: <Radio.Group initialValue="1" buttonStyle="solid">
292
+        <Radio.Button value="9">禁用</Radio.Button>
293
+        <Radio.Button value="1">启用</Radio.Button>
294
+      </Radio.Group>,
295
+      value: userData.status != null ? userData.status.toString() : "1"
296
+    },
297
+    {
298
+      label: '权重',
299
+      name: 'weight',
300
+      type: FieldTypes.Number,
301
+      render: <Input type="number" style={{ width: 150}} />,
302
+      value: userData.weight,
303
+      help: '数字越大越靠前',
304
+    },
305
+  ]
306
+
307
+
308
+  return <Card>
309
+            <XForm onChange={console.log} onSubmit={handleSubmit} fields={fields.filter(Boolean)} onCancel={() => router.go(-1)}></XForm>
310
+
311
+        </Card>
312
+}
313
+
314
+export default StaffEdit

+ 125
- 0
src/pages/staff/staff/components/BatchAssistConsultant.jsx Wyświetl plik

@@ -0,0 +1,125 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Form, Icon, Input, Button, DatePicker, Select, Card, Row, Col, Pagination, Alert, Table, Avatar, Radio, Modal, Descriptions, notification } from 'antd';
3
+import moment from 'moment';
4
+import apis from '@/services/apis';
5
+import request from '@/utils/request';
6
+
7
+
8
+/**
9
+ * 分配置业顾问
10
+ *
11
+ * @param {*} props
12
+ * @returns
13
+ */
14
+class ModalAttribution extends React.Component {
15
+  constructor(props) {
16
+    super(props);
17
+    // console.log(props, 'props')
18
+    this.state = {
19
+      dataSource: { records: [] },
20
+      visibleData: { visible: false, buildingId: '' },
21
+    }
22
+  }
23
+
24
+  // 挂载之后
25
+  componentDidMount() {
26
+    // this.getList({ pageNumber: 1, pageSize: 5 })
27
+  }
28
+
29
+  componentDidUpdate(preProps, preState) {
30
+    if (this.props.visible !== preState.visibleData.visible) {
31
+      this.getUserList({ pageNumber: 1, pageSize: 5, buildingId: this.props.buildingId })
32
+      this.setState({ visibleData: { visible: this.props.visible, buildingId: this.props.buildingId } });
33
+    }
34
+  }
35
+
36
+  // 弹框取消按钮
37
+  handleCancel() {
38
+    this.props.onCancel()
39
+  }
40
+
41
+  getUserList(params) {
42
+    console.log('params: ', params)
43
+    if (params.buildingId === '' || params.buildingId === null || params.buildingId === undefined) {
44
+      return
45
+    }
46
+    // 网路请求
47
+    request({ ...apis.customer.buildingConsultant, params: { ...params } }).then(res => {
48
+      this.setState({ dataSource: res })
49
+    }).catch(err => {
50
+
51
+    })
52
+  }
53
+
54
+  openNotificationWithIcon = (type, message) => {
55
+    notification[type]({
56
+      message,
57
+      description:
58
+        '',
59
+    });
60
+  };
61
+
62
+  // 分页
63
+  onChange(pageNum) {
64
+
65
+    this.getUserList({ pageNumber: pageNum, pageSize: 5, buildingId: this.state.visibleData.buildingId })
66
+  }
67
+
68
+  // 提交
69
+  submitGm(record) {
70
+    this.props.onCancel(record)
71
+  }
72
+
73
+  render() {
74
+    const columns = [
75
+      {
76
+        title: '姓名',
77
+        dataIndex: 'userName',
78
+        key: 'userName',
79
+        width: 120,
80
+      },
81
+      {
82
+        title: '电话',
83
+        dataIndex: 'phone',
84
+        key: 'phone',
85
+        width: 150,
86
+      },
87
+      {
88
+        title: '部门',
89
+        dataIndex: 'department',
90
+        key: 'department',
91
+        width: 130,
92
+      },
93
+      {
94
+        title: '岗位',
95
+        dataIndex: 'position',
96
+        key: 'position',
97
+        width: 120,
98
+      },
99
+      {
100
+        title: '操作',
101
+        dataIndex: 'personId',
102
+        key: 'personId',
103
+        width: 80,
104
+        // eslint-disable-next-line no-nested-ternary
105
+        render: (_, record) => <>{record.userId !== this.props.userId ? <Button type="danger" onClick={() => this.submitGm(record)}>确定</Button> : ''}</>,
106
+      },
107
+    ]
108
+    return (
109
+      <>
110
+        <Modal
111
+          title="分配置业顾问"
112
+          width={600}
113
+          destroyOnClose="true"
114
+          footer={null}
115
+          visible={this.state.visibleData.visible}
116
+          onCancel={(e) => this.handleCancel(e)}
117
+        >
118
+          <Table rowKey="userId" dataSource={this.state.dataSource.records} columns={columns} pagination={{ pageSize: 5, total: this.state.dataSource.total, onChange: e => this.onChange(e) }} />
119
+        </Modal>
120
+      </>
121
+    );
122
+  }
123
+}
124
+
125
+export default ModalAttribution

+ 58
- 0
src/pages/staff/staff/components/BuildingSelection.jsx Wyświetl plik

@@ -0,0 +1,58 @@
1
+import React, { useState } from 'react';
2
+import {  Modal } from 'antd';
3
+import apis from '@/services/apis';
4
+import request from '@/utils/request';
5
+import CustomerChange from './CustomerChange'
6
+import BuildSelect from '@/components/SelectButton/BuildSelect'
7
+
8
+let building = null
9
+const BuildingSelection = (props) => {
10
+    const [visible, setVisible] = useState(false) 
11
+    const { userData } = props;
12
+
13
+     //授权项目改变
14
+  const consultantBuildingChange =(e) => {
15
+    building = e
16
+    if(userData.isConsultant && props.value !== e){
17
+      request({ ...apis.staff.check, params: { userId: userData.userId, personId: userData.consultantPersonId, buildingId: userData.buildingId } }).then(res => {
18
+        if(res.length > 0){
19
+          Modal.confirm({
20
+            title: '此置业顾问下有私客,是否转移私客?',
21
+            okText: '确认',
22
+            cancelText: '取消',
23
+            onOk () {
24
+              setVisible(true)
25
+            },
26
+          });
27
+        }else{
28
+            props.onChange(e)
29
+        }
30
+     })
31
+    }else{
32
+        props.onChange(e)
33
+    }
34
+  }
35
+
36
+   //迁移私客成功回调
37
+   const moveSuccess = (e) => {
38
+       if(e === 'success'){
39
+        props.onChange(building)
40
+       }
41
+       setVisible(false)
42
+  }
43
+
44
+     return (<>
45
+        <BuildSelect value={props.value} onChange={consultantBuildingChange} />
46
+        <Modal
47
+              visible={visible}
48
+              title="分配归属"
49
+              onCancel={() => setVisible(false)}
50
+              footer={null}
51
+              width={900}
52
+            >
53
+                <CustomerChange userId={userData.userId} consultantPersonId={userData.consultantPersonId} buildingId={userData.buildingId} onSuccess={moveSuccess} />
54
+            </Modal>
55
+     </>)
56
+  }
57
+  
58
+  export default BuildingSelection;

+ 113
- 0
src/pages/staff/staff/components/CustomerChange.jsx Wyświetl plik

@@ -0,0 +1,113 @@
1
+import React, {  useState, useEffect } from 'react';
2
+import apis from '@/services/apis';
3
+import request from '@/utils/request';
4
+import { Table, Button,  message } from 'antd';
5
+import BatchAssistConsultant from './BatchAssistConsultant'
6
+
7
+const CustomerChange = (props) => {
8
+  const [data, setData] = useState([])
9
+  const [consultantVisible, setConsultantVisible] = useState(false)
10
+  const [selectIds, setSelectIds] = useState([])
11
+
12
+  const rowSelection = {
13
+    selectedRowKeys: selectIds,
14
+    onChange: (selectedRowKeys, selectedRows) => {
15
+      console.log('selectedRowKeys:', selectedRowKeys, 'selectedRows: ', selectedRows);
16
+      setSelectIds(selectedRowKeys)
17
+    },
18
+  };
19
+
20
+  const batchAssistConsultant = () => {
21
+    if (selectIds.length < 1) {
22
+      message.info("请至少选择一条数据");
23
+      return
24
+    }
25
+    setConsultantVisible(true)
26
+  }
27
+
28
+  const consulatanChange = (e) => {
29
+    if (e) {
30
+      data.map(x => {
31
+        selectIds.map(y => {
32
+          if (x.customerId === y) {
33
+            x.realtyConsultant = e.userId
34
+            x.moveUserId = e.userId
35
+            x.moveUserName = e.userName
36
+          }
37
+        })
38
+      })
39
+    }
40
+    setConsultantVisible(false)
41
+    setSelectIds([])
42
+  }
43
+
44
+  //批量保存
45
+  const batchSaveConsultant = () => {
46
+    const unMoveData = data.filter(x => !x.moveUserId)
47
+    if (unMoveData.length > 0) {
48
+      message.info("存在未分配归属客户");
49
+      return
50
+    }
51
+    request({ ...apis.staff.move, data }).then(data => {
52
+      message.info('操作成功')
53
+      props.onSuccess('success')
54
+    })
55
+  }
56
+
57
+  //取消按钮
58
+  const cancelConsultant = () => {
59
+    props.onSuccess('cancel')
60
+  }
61
+
62
+
63
+  const columns = [
64
+    {
65
+      title: '用户名',
66
+      dataIndex: 'name',
67
+      key: 'name',
68
+      align: 'center',
69
+    },
70
+    {
71
+      title: '手机号',
72
+      dataIndex: 'phone',
73
+      key: 'phone',
74
+      align: 'center',
75
+    },
76
+    {
77
+      title: '客户状态',
78
+      dataIndex: 'reportRecommendStatus',
79
+      key: 'reportRecommendStatus',
80
+      align: 'center',
81
+      render: (text, records) => {
82
+        if (records.status === 1) { return '报备' }
83
+        if (records.status === 2) { return '到访' }
84
+        if (records.status === 3) { return '认购' }
85
+        if (records.status === 4) { return '签约' }
86
+      },
87
+    },
88
+    {
89
+      title: '调整后归属',
90
+      dataIndex: 'moveUserName',
91
+      key: 'moveUserName',
92
+      align: 'center',
93
+    }
94
+  ];
95
+
96
+  useEffect(() => {
97
+    request({ ...apis.staff.check, params: { userId: props.userId, personId: props.consultantPersonId, buildingId: props.buildingId } }).then(data => {
98
+      setData(data)
99
+    })
100
+  }, [props.userId])
101
+
102
+  return (
103
+    <div>
104
+      <Button type="primary" onClick={() => batchAssistConsultant()} style={{ float: 'right', margin: '20px 0', marginLeft: '20px', zIndex: 1 }}>分配置业顾问</Button>
105
+      <Table rowSelection={rowSelection} dataSource={data} columns={columns} rowKey="customerId" pagination={false} scroll={{ y: 500 }} />
106
+      <BatchAssistConsultant visible={consultantVisible} userId={props.userId} buildingId={props.buildingId} onCancel={consulatanChange} />
107
+      <div style={{ textAlign: 'center', marginTop: '16px' }}><Button type="primary" onClick={() => batchSaveConsultant()}>保存</Button>
108
+        <Button style={{ marginLeft: '10px' }} onClick={() => cancelConsultant()}>取消</Button></div>
109
+    </div>
110
+  )
111
+}
112
+
113
+export default CustomerChange;

+ 259
- 0
src/pages/staff/staff/list/index.jsx Wyświetl plik

@@ -0,0 +1,259 @@
1
+import React, { useMemo, useRef, useCallback, useState } from 'react';
2
+import { Button, Modal, message } from 'antd';
3
+import moment from 'moment';
4
+import apis from '@/services/apis';
5
+import request from '@/utils/request';
6
+import AuthButton from '@/components/AuthButton';
7
+import QueryTable from '@/components/QueryTable';
8
+import BuildingSelect from '@/components/SelectButton/BuildSelect';
9
+import OperButton from '@/components/OperButton';
10
+import withActions from '@/components/ActionList';
11
+import { router } from 'umi';
12
+
13
+export default props => {
14
+  const ref = useRef();
15
+  const [visible, setVisible] = useState(false);
16
+  const [data, setData] = useState(false);
17
+
18
+
19
+  const toEdit = useCallback(row => {
20
+    //跳转到编辑商品
21
+    router.push({
22
+      pathname: '/staff/Staff/Edit',
23
+      query: {
24
+        userId: row?.userId || undefined,
25
+      },
26
+    });
27
+  }, []);
28
+
29
+
30
+  //迁移私客成功回调
31
+  const moveSuccess = e => {
32
+    setVisible(false);
33
+    if (e === 'success') {
34
+      confirm(data)();
35
+      setData()
36
+    }
37
+  };
38
+
39
+  const confirm = data => () => {
40
+    // console.log(data, "11111")
41
+    if (data.status === 1) {
42
+      if (data.isConsultant) {
43
+        request({
44
+          ...apis.staff.check,
45
+          params: {
46
+            userId: data.userId,
47
+            personId: data.consultantPersonId,
48
+            buildingId: data.buildingId,
49
+          },
50
+        }).then(res => {
51
+          if (res.length > 0) {
52
+            Modal.confirm({
53
+              title: '此置业顾问下有私客,是否转移私客?',
54
+              okText: '确认',
55
+              cancelText: '取消',
56
+              onOk() {
57
+                setVisible(true);
58
+                setData(data);
59
+              },
60
+            });
61
+          } else {
62
+            const titleMessahe = data.isConsultant
63
+              ? '停用后此员工无法继续登录后台(若为置业顾问停用后在小程序端将成为普通用户)确认进行停用操作?'
64
+              : '停用后此员工无法继续登录后台,确认进行停用操作?';
65
+            Modal.confirm({
66
+              title: titleMessahe,
67
+              okText: '确认',
68
+              cancelText: '取消',
69
+              onOk() {
70
+                request({ ...apis.staff.change, urlData: { id: data.userId, type: 'off' } }).then(
71
+                  res => {
72
+                    message.info('操作成功');
73
+                    ref.current.reload();
74
+                  },
75
+                );
76
+              },
77
+            });
78
+          }
79
+        });
80
+      } else {
81
+        const titleMessahe = data.isConsultant
82
+          ? '停用后此员工无法继续登录后台(若为置业顾问停用后在小程序端将成为普通用户)确认进行停用操作?'
83
+          : '停用后此员工无法继续登录后台,确认进行停用操作?';
84
+        Modal.confirm({
85
+          title: titleMessahe,
86
+          okText: '确认',
87
+          cancelText: '取消',
88
+          onOk() {
89
+            request({ ...apis.staff.change, urlData: { id: data.userId, type: 'off' } }).then(
90
+              res => {
91
+                message.info('操作成功');
92
+                ref.current.reload();
93
+              },
94
+            );
95
+          },
96
+        });
97
+      }
98
+    } else {
99
+      Modal.confirm({
100
+        title: '确认启用该角色?',
101
+        okText: '确认',
102
+        cancelText: '取消',
103
+        onOk() {
104
+          request({ ...apis.staff.change, urlData: { id: data.userId, type: 'on' } }).then(res => {
105
+            message.info('操作成功');
106
+            ref.current.reload();
107
+          });
108
+        },
109
+      });
110
+    }
111
+  };
112
+
113
+  const searchFields = [
114
+    {
115
+      name: 'buildingId',
116
+      label: '所属项目',
117
+      placeholder: '请选择项目',
118
+      render: () => <BuildingSelect style={{ width: 160 }} />,
119
+    },
120
+    {
121
+      name: 'code',
122
+      label: '工号',
123
+      placeholder: '请输入工号',
124
+    },
125
+    {
126
+      name: 'userName',
127
+      label: '姓名',
128
+      placeholder: '请输入姓名',
129
+    },
130
+    {
131
+      name: 'isConsultant',
132
+      label: '类型',
133
+      placeholder: '请选择类型',
134
+      type: 'select',
135
+      options: [
136
+        { label: '全部', value: '' },
137
+        { label: '非置业顾问', value: 0 },
138
+        { label: '置业顾问', value: 1 },
139
+      ],
140
+    },
141
+    {
142
+      name: 'status',
143
+      label: '状态',
144
+      placeholder: '请选择状态',
145
+      type: 'select',
146
+      options: [
147
+        { label: '全部', value: '' },
148
+        { label: '启用', value: 1 },
149
+        { label: '禁用', value: 9 },
150
+      ],
151
+    },
152
+  ];
153
+
154
+  const tableColumns = [
155
+    {
156
+      title: '工号',
157
+      key: 'code',
158
+      dataIndex: 'code',
159
+      align: 'center',
160
+    },
161
+    {
162
+      title: '姓名',
163
+      dataIndex: 'userName',
164
+      key: 'userName',
165
+      align: 'center',
166
+    },
167
+    {
168
+      title: '电话',
169
+      dataIndex: 'phone',
170
+      key: 'phone',
171
+      align: 'center',
172
+    },
173
+    {
174
+      title: '类型',
175
+      dataIndex: 'isConsultant',
176
+      key: 'isConsultant',
177
+      align: 'center',
178
+      render: text => (text === 1 ? '置业顾问' : '非置业顾问'),
179
+    },
180
+    {
181
+      title: '绑定状态',
182
+      dataIndex: 'miniStatus',
183
+      key: 'miniStatus',
184
+      align: 'center',
185
+      render: text => (text === 1 ? '已绑定' : '未绑定'),
186
+    },
187
+    {
188
+      title: '创建时间',
189
+      dataIndex: 'createDate',
190
+      key: 'createDate',
191
+      align: 'center',
192
+      render: t => moment(t).format('YYYY-MM-DD HH:mm'),
193
+    },
194
+    {
195
+      title: '状态',
196
+      dataIndex: 'status',
197
+      key: 'status',
198
+      align: 'center',
199
+      render: text => (text === 1 ? '启用' : '停用'),
200
+    },
201
+
202
+    {
203
+      title: '操作',
204
+      key: 'options',
205
+      align: 'center',
206
+      render: withActions(
207
+        (_, row) => [
208
+          <AuthButton name="admin.building.public" noRight={null}>
209
+            <OperButton onClick={confirm(row)}>{row.status === 1 ? '停用' : '启用'}</OperButton>
210
+          </AuthButton>,
211
+          <AuthButton name="admin.building.delete" noRight={null}>
212
+               <OperButton onClick={() => toEdit(row)}>编辑</OperButton>
213
+          </AuthButton>,
214
+        ],
215
+        { noMargin: true },
216
+      ),
217
+    },
218
+  ];
219
+
220
+  const actionRender = () => {
221
+    return (
222
+      <AuthButton name="admin.tdBuildingType.add" noRight={null}>
223
+        <Button type="primary" icon="plus" onClick={() => toEdit()}>
224
+          新增
225
+        </Button>
226
+      </AuthButton>
227
+    );
228
+  };
229
+
230
+  return (
231
+    <>
232
+      <QueryTable
233
+        ref={ref}
234
+        rowKey="buildingId"
235
+        api={apis.staff.taUser}
236
+        columns={tableColumns}
237
+        searchFields={searchFields}
238
+        actionRender={actionRender}
239
+      />
240
+
241
+      <Modal
242
+        visible={visible}
243
+        title="分配归属"
244
+        onCancel={() => setVisible(false)}
245
+        footer={null}
246
+        width={900}
247
+      >
248
+        {data && (
249
+          <CustomerChange
250
+            userId={data.userId}
251
+            consultantPersonId={data.consultantPersonId}
252
+            buildingId={data.buildingId}
253
+            onSuccess={moveSuccess}
254
+          />
255
+        )}
256
+      </Modal>
257
+    </>
258
+  );
259
+};