dingxin пре 5 година
родитељ
комит
7956700b66
32 измењених фајлова са 1072 додато и 382 уклоњено
  1. 1
    1
      config/config.js
  2. 2
    0
      package.json
  3. 25
    0
      src/components/AuthButton/index.jsx
  4. 16
    10
      src/components/EchartsTest/EChart.jsx
  5. 42
    28
      src/components/XForm/ImageListUpload.jsx
  6. 25
    14
      src/components/XForm/ImageUpload.jsx
  7. 22
    1
      src/global.less
  8. 7
    10
      src/layouts/BasicLayout.jsx
  9. 11
    4
      src/models/login.js
  10. 11
    5
      src/models/user.js
  11. 1
    1
      src/pages/activity/ActivityList.jsx
  12. 9
    4
      src/pages/building/list/add/components/base.jsx
  13. 262
    0
      src/pages/building/list/add/components/buildingProjectType.jsx
  14. 19
    23
      src/pages/building/list/add/components/tags.jsx
  15. 59
    55
      src/pages/building/list/index.jsx
  16. 2
    2
      src/pages/building/type/index.jsx
  17. 1
    1
      src/pages/carouselFigure/advertisingList.jsx
  18. 1
    1
      src/pages/carouselFigure/carouselFigureList.jsx
  19. 1
    1
      src/pages/channel/brokerList.jsx
  20. 2
    2
      src/pages/customer/customerlist/index.jsx
  21. 1
    1
      src/pages/customer/report/index.jsx
  22. 180
    0
      src/pages/indexEcharts/components/UserSource.jsx
  23. 27
    0
      src/pages/indexEcharts/index.jsx
  24. 77
    0
      src/pages/indexEcharts/userSource.jsx
  25. 1
    1
      src/pages/integralMall/GoodsList.jsx
  26. 1
    1
      src/pages/integralMall/exchangeRecords.jsx
  27. 1
    1
      src/pages/news/list/NewsList.jsx
  28. 60
    159
      src/pages/staff/list/StaffList.jsx
  29. 107
    48
      src/pages/staff/list/editStaff.jsx
  30. 0
    1
      src/pages/staff/list/style.less
  31. 65
    2
      src/services/apis.js
  32. 33
    5
      src/utils/upload.js

+ 1
- 1
config/config.js Прегледај датотеку

@@ -479,7 +479,7 @@ export default {
479 479
 
480 480
   proxy: {
481 481
     '/api/': {
482
-      target: 'http://192.168.0.84:8080/',
482
+      target: 'http://192.168.0.11:8080/',
483 483
       changeOrigin: true,
484 484
       // pathRewrite: { '^/server': '' },
485 485
     },

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

@@ -45,6 +45,7 @@
45 45
     "@antv/data-set": "^0.10.2",
46 46
     "antd": "^3.20.0",
47 47
     "classnames": "^2.2.6",
48
+    "dayjs": "^1.8.16",
48 49
     "dva": "^2.4.1",
49 50
     "echarts": "^4.3.0",
50 51
     "lodash": "^4.17.11",
@@ -68,6 +69,7 @@
68 69
     "@ant-design/colors": "^3.1.0",
69 70
     "@ant-design/pro-cli": "^1.0.0",
70 71
     "@types/classnames": "^2.2.7",
72
+    "@types/echarts": "^4.1.14",
71 73
     "@types/express": "^4.17.0",
72 74
     "@types/history": "^4.7.2",
73 75
     "@types/jest": "^24.0.13",

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

@@ -0,0 +1,25 @@
1
+import React from 'react';
2
+
3
+let allBtns = [];
4
+let current = [];
5
+
6
+const AuthButton = ({ children, name, noRight }) => {
7
+  const btn = allBtns.filter(x => x.code === name)[0]
8
+
9
+  // 没维护的按钮, 或者不需要权限的按钮直接通过
10
+  if (!btn || !btn.roles || !btn.roles.length) {
11
+    return <>{children}</>
12
+  }
13
+
14
+  const hasRight = btn.roles.some(x => current.some(y => x === y))
15
+  return hasRight ? <>{children}</> : <>{noRight}</>
16
+}
17
+
18
+const setAllBtnAuth = x => allBtns = x;
19
+const setUserBtnAuth = x => current = x;
20
+
21
+export default AuthButton;
22
+export {
23
+  setAllBtnAuth,
24
+  setUserBtnAuth,
25
+};

+ 16
- 10
src/components/EchartsTest/EChart.jsx Прегледај датотеку

@@ -3,17 +3,20 @@ import React, { Component } from 'react';
3 3
 // 引入 ECharts 主模块
4 4
 import echarts from 'echarts/lib/echarts';
5 5
 // 引入柱状图
6
-import  'echarts/lib/chart/bar';
6
+import 'echarts/lib/chart/bar';
7
+import 'echarts/lib/chart/pie';
7 8
 // 引入提示框和标题组件
8 9
 import 'echarts/lib/component/tooltip';
10
+import 'echarts/lib/component/legend';
9 11
 import 'echarts/lib/component/title';
10 12
 
13
+
11 14
 class EchartsTest extends Component {
12
-    chartRef = undefined
15
+    chartRef = React.createRef();
13 16
     chart = undefined
14 17
     defaultChartOption = {}
15 18
 
16
-    componentDidMount() {
19
+    componentDidMount () {
17 20
         this.chart = echarts.init(this.chartRef.current)
18 21
 
19 22
         // 绘制图表
@@ -23,25 +26,28 @@ class EchartsTest extends Component {
23 26
         });
24 27
     }
25 28
 
26
-    componentDidUpdate(preProps) {
29
+    componentDidUpdate (preProps) {
27 30
         if (preProps.options != this.props.options) {
28
-            this.chart.setOption({
31
+            const options = {
29 32
                 ...this.defaultChartOption,
30 33
                 ...this.props.options || {},
31
-            });
34
+            }
35
+
36
+            console.log(options)
37
+
38
+            this.chart.setOption(options);
32 39
         }
33 40
     }
34 41
 
35
-    handleDom = ref => this.chartRef = ref
36
-
37
-    render() {
42
+    render () {
38 43
         const style = {
39 44
             width: '600px',
45
+            height: '400px',
40 46
             ...this.props.style || {}
41 47
         }
42 48
 
43 49
         return (
44
-            <div ref={this.handleDom} style={style}></div>
50
+            <div ref={this.chartRef} style={style}></div>
45 51
         );
46 52
     }
47 53
 }

+ 42
- 28
src/components/XForm/ImageListUpload.jsx Прегледај датотеку

@@ -3,65 +3,79 @@ import { Upload, Icon, Modal } from 'antd';
3 3
 import './style.less';
4 4
 import { uploaderProps } from '../../utils/upload';
5 5
 
6
-function getBase64(file) {
7
-  return new Promise((resolve, reject) => {
8
-    const reader = new FileReader();
9
-    reader.readAsDataURL(file);
10
-    reader.onload = () => resolve(reader.result);
11
-    reader.onerror = error => reject(error);
12
-  });
13
-}
14
-
15 6
 class ImageListUpload extends React.Component {
16 7
   state = {
17 8
     previewVisible: false,
18 9
     previewImage: '',
19
-    fileList: [],
10
+    loadding: false,
20 11
   };
21 12
 
13
+  getFileList = () => {
14
+    return (this.props.value || []).map((img, inx) => ({ uid: inx, url: img, status: 'done' }))
15
+  }
16
+
22 17
   handleCancel = () => this.setState({ previewVisible: false });
23 18
 
24 19
   handlePreview = async file => {
25
-    if (!file.url && !file.preview) {
26
-      file.preview = await getBase64(file.originFileObj);
27
-    }
28
-
29 20
     this.setState({
30
-      previewImage: file.url || file.preview,
21
+      previewImage: file.url ,
31 22
       previewVisible: true,
32 23
     });
33 24
   };
34 25
 
35
-  handleChange = ({ fileList }) => {
36
-    this.setState({ fileList })
37
-    if (typeof this.props.onChange === 'function') {
38
-      // return item.response.url
39
-      const images = fileList.filter(item => item.status === 'done')
40
-      this.props.onChange(images.map(item => item.response.url))
26
+  handleChange = (e) => {
27
+    if (e.file.status === "uploading") {
28
+      this.setState({ loading: true });
29
+      return;
30
+    }
31
+
32
+    if (e.file.state === 'removed') {
33
+      const fileList = (this.props.value || []).filter(x => x != e.file.url);
34
+      this.props.onChange(fileList);
41 35
     }
36
+
37
+    // if (e.file.status === "done") {
38
+    //   this.setState({
39
+    //     loading: false,
40
+    //   })
41
+
42
+    //   if (e.file.response && e.file.response.url) {
43
+    //     if (typeof this.props.onChange === 'function') {
44
+    //       const fileList = this.getFileList()
45
+    //       this.props.onChange([...fileList || [], e.file.response.url]);
46
+    //     }
47
+    //   }
48
+    // }
42 49
   };
43 50
 
44
-  render() {
45
-    const { previewVisible, previewImage, fileList } = this.state;
51
+  handleUploadSucess = (url) => {
52
+    this.setState({ loading: false });
53
+    if (typeof this.props.onChange === 'function') {
54
+      const fileList = this.props.value || [];
55
+      this.props.onChange([...fileList, url]);
56
+    }
57
+  }
46 58
 
47
-    const { value } = this.props
59
+  render() {
60
+    const { previewVisible, previewImage } = this.state;
61
+    const fileList = this.getFileList();
48 62
 
49 63
     const uploadButton = (
50 64
       <div>
51
-        <Icon type="plus" />
52
-        <div className="ant-upload-text">Upload</div>
65
+        <Icon style={{ fontSize: '2em', color: '#aaa' }} type={this.state.loading ? "loading" : "plus"}  />
53 66
       </div>
54 67
     );
55 68
     return (
56 69
       <div className="clearfix">
57 70
         <Upload
58 71
           listType="picture-card"
59
-          fileList={fileList || value}
72
+          fileList={fileList}
60 73
           onPreview={this.handlePreview}
61 74
           onChange={this.handleChange}
62 75
           { ...uploaderProps }
76
+          onSuccess={this.handleUploadSucess}
63 77
         >
64
-          {fileList.length >= 8 ? null : uploadButton}
78
+          {(fileList || images).length >= 8 ? null : uploadButton}
65 79
         </Upload>
66 80
         <Modal visible={previewVisible} footer={null} onCancel={this.handleCancel}>
67 81
           <img alt="example" style={{ width: '100%' }} src={previewImage} />

+ 25
- 14
src/components/XForm/ImageUpload.jsx Прегледај датотеку

@@ -16,24 +16,35 @@ class ImageUpload extends React.Component {
16 16
       this.setState({ loading: true });
17 17
       return;
18 18
     }
19
+    
20
+    if (e.file.state === 'removed') {
21
+      this.props.onChange();
22
+    }
19 23
 
20
-    if (info.file.status === "done") {
21
-      this.setState({
22
-        loading: false,
23
-      })
24
+    // if (info.file.status === "done") {
25
+    //   this.setState({
26
+    //     loading: false,
27
+    //   })
24 28
 
25
-      if (info.file.response && info.file.response.url) {
26
-        this.setState({
27
-          imageUrl: info.file.response.thumbUrl,
28
-        });
29
+    //   if (info.file.response && info.file.response.url) {
30
+    //     this.setState({
31
+    //       imageUrl: info.file.response.thumbUrl,
32
+    //     });
29 33
 
30
-        if (typeof this.props.onChange === 'function') {
31
-          this.props.onChange(info.file.response.url);
32
-        }
33
-      }
34
-    }
34
+    //     if (typeof this.props.onChange === 'function') {
35
+    //       this.props.onChange(info.file.response.url);
36
+    //     }
37
+    //   }
38
+    // }
35 39
   };
36 40
 
41
+  handleUploadSucess = (url) => {
42
+    this.setState({ loading: false });
43
+    if (typeof this.props.onChange === 'function') {
44
+      this.props.onChange(url);
45
+    }
46
+  }
47
+
37 48
   render() {
38 49
     const uploadButton = (
39 50
       <div>
@@ -50,8 +61,8 @@ class ImageUpload extends React.Component {
50 61
         showUploadList={false}
51 62
         beforeUpload={this.props.beforeUpload}
52 63
         onChange={this.handleChange}
53
-
54 64
         {...uploaderProps}
65
+        onSuccess={this.handleUploadSucess}
55 66
       >
56 67
         {(this.state.imageUrl || value) ? (
57 68
           <img src={this.state.imageUrl || value} alt="avatar" style={{ width: "100%" }} />

+ 22
- 1
src/global.less Прегледај датотеку

@@ -23,6 +23,7 @@ body {
23 23
   text-rendering: optimizeLegibility;
24 24
   -webkit-font-smoothing: antialiased;
25 25
   -moz-osx-font-smoothing: grayscale;
26
+  font-size: 16px;
26 27
 }
27 28
 
28 29
 ul,
@@ -70,6 +71,23 @@ ol {
70 71
 }
71 72
  
72 73
 .ant-layout{
74
+  .ant-menu-vertical .ant-menu-item,
75
+.ant-menu-vertical-left .ant-menu-item,
76
+.ant-menu-vertical-right .ant-menu-item,
77
+.ant-menu-inline .ant-menu-item,
78
+.ant-menu-vertical .ant-menu-submenu-title,
79
+.ant-menu-vertical-left .ant-menu-submenu-title,
80
+.ant-menu-vertical-right .ant-menu-submenu-title,
81
+.ant-menu-inline .ant-menu-submenu-title,
82
+.ant-input ,.ant-btn{
83
+  font-size: 16px;
84
+}
85
+.ant-breadcrumb{
86
+  font-size: 16px;
87
+  .anticon {
88
+    font-size: 16px;
89
+  }
90
+} 
73 91
   .ant-pro-global-header-trigger{
74 92
     display: none;
75 93
   }
@@ -92,8 +110,11 @@ ol {
92 110
   .ant-menu-inline > .ant-menu-item{
93 111
     height: 45px;
94 112
     line-height: 45px;
95
-    font-size: 16px;
113
+    
96 114
     margin: 0;
115
+    .ant-menu-submenu-title{
116
+      font-size: 16px!important;
117
+    }
97 118
   }
98 119
   .ant-menu.ant-pro-sider-menu{
99 120
     padding: 0!important;

+ 7
- 10
src/layouts/BasicLayout.jsx Прегледај датотеку

@@ -9,8 +9,9 @@ import Link from 'umi/link';
9 9
 import Redirect from 'umi/redirect';
10 10
 import { connect } from 'dva';
11 11
 import { formatMessage } from 'umi-plugin-react/locale';
12
-import Authorized from '@/utils/Authorized';
12
+// import Authorized from '@/utils/Authorized';
13 13
 import RightContent from '@/components/GlobalHeader/RightContent';
14
+import RenderAuthorize from '@/components/Authorized';
14 15
 import { isAntDesignPro } from '@/utils/utils';
15 16
 import logo from '../assets/logo.png';
16 17
   
@@ -33,12 +34,9 @@ const footerRender = () => {
33 34
 
34 35
 const BasicLayout = props => {
35 36
   const { dispatch, children, settings } = props;
36
-  /**
37
-   * constructor
38
-   */
39
-
37
+  
40 38
   useEffect(() => {
41
-    if (dispatch) {
39
+    if (dispatch && !props.user.currentUser.userId) {
42 40
       dispatch({
43 41
         type: 'user/fetchCurrent',
44 42
       });
@@ -47,9 +45,8 @@ const BasicLayout = props => {
47 45
       });
48 46
     }
49 47
   }, []);
50
-  /**
51
-   * init variables
52
-   */
48
+  
49
+  const Authorized = RenderAuthorize(props.user.currentUser.roles)
53 50
 
54 51
   const handleMenuCollapse = payload => {
55 52
     if (dispatch) {
@@ -61,7 +58,7 @@ const BasicLayout = props => {
61 58
   };
62 59
 
63 60
   const findAuthority = (path) => {
64
-    return ((props.user.menuList || []).filter(x => x.code === path)[0] || {}).roles || []
61
+    return ((props.user.menuList || []).filter(x => x.code === path)[0] || {}).roles
65 62
   }
66 63
   
67 64
   /**

+ 11
- 4
src/models/login.js Прегледај датотеку

@@ -1,8 +1,13 @@
1 1
 import { routerRedux } from 'dva/router';
2 2
 import { stringify } from 'querystring';
3
-import { fakeAccountLogin, getFakeCaptcha } from '@/services/login';
3
+// import { fakeAccountLogin, getFakeCaptcha } from '@/services/login';
4 4
 import { setAuthority } from '@/utils/authority';
5 5
 import { getPageQuery } from '@/utils/utils';
6
+import { fetch, apis } from '@/utils/request';
7
+
8
+const signin = fetch(apis.user.signin);
9
+const signout = fetch(apis.user.signout);
10
+
6 11
 const Model = {
7 12
   namespace: 'login',
8 13
   state: {
@@ -10,7 +15,7 @@ const Model = {
10 15
   },
11 16
   effects: {
12 17
     *login({ payload }, { call, put }) {
13
-      const response = yield call(fakeAccountLogin, payload);
18
+      const response = yield call(signin, { data: payload });
14 19
       yield put({
15 20
         type: 'changeLoginStatus',
16 21
         payload: response,
@@ -42,9 +47,11 @@ const Model = {
42 47
       yield call(getFakeCaptcha, payload);
43 48
     },
44 49
 
45
-    *logout(_, { put }) {
50
+    *logout(_, { put, call }) {
46 51
       const { redirect } = getPageQuery(); // redirect
47 52
 
53
+      yield call(signout, { logout: true });
54
+
48 55
       if (window.location.pathname !== '/user/login' && !redirect) {
49 56
         yield put(
50 57
           routerRedux.replace({
@@ -59,7 +66,7 @@ const Model = {
59 66
   },
60 67
   reducers: {
61 68
     changeLoginStatus(state, { payload }) {
62
-      setAuthority((payload.user.roles || []).map(x => x.roleId));
69
+      // setAuthority((payload.user.roles || []).map(x => x.roleId));
63 70
       return { ...state, status: 'ok', type: payload.type };
64 71
     },
65 72
   },

+ 11
- 5
src/models/user.js Прегледај датотеку

@@ -1,11 +1,14 @@
1
-import request from '../utils/request';
2
-import apis from '../services/apis';
1
+import { fetch, apis } from '@/utils/request';
2
+import { setAllBtnAuth, setUserBtnAuth } from '@/components/AuthButton';
3
+
4
+const getCurrentUser = fetch(apis.user.current)
3 5
 
4 6
 const UserModel = {
5 7
   namespace: 'user',
6 8
   state: {
7 9
     currentUser: {},
8 10
     menuList: [],
11
+    buttonList: [],
9 12
   },
10 13
   effects: {
11 14
     // *fetch(_, { call, put }) {
@@ -17,7 +20,7 @@ const UserModel = {
17 20
     // },
18 21
 
19 22
     *fetchCurrent(_, { call, put }) {
20
-      const response = yield call(request, apis.user.current);
23
+      const response = yield call(getCurrentUser);
21 24
 
22 25
       yield put({
23 26
         type: 'saveCurrentUser',
@@ -27,10 +30,13 @@ const UserModel = {
27 30
   },
28 31
   reducers: {
29 32
     saveCurrentUser(state, { payload }) {
30
-      const { taUser = {} , menuList = [] } = payload || {}
33
+      const { taUser = {} , menuList = [], buttonList = [] } = payload || {}
31 34
       const currentUser = { ...taUser, roles: (taUser.roles || []).map(x => x.roleId) }
32 35
 
33
-      return { ...state, currentUser, menuList };
36
+      setAllBtnAuth(buttonList)
37
+      setUserBtnAuth(currentUser.roles)
38
+
39
+      return { ...state, currentUser, menuList, buttonList };
34 40
     },
35 41
     changeNotifyCount(
36 42
       state = {

+ 1
- 1
src/pages/activity/ActivityList.jsx Прегледај датотеку

@@ -250,7 +250,7 @@ const handleSubmit = (e, props) => {
250 250
           </Button>
251 251
         </Form.Item>
252 252
       </Form>
253
-      <Button type="primary" className={styles.addBtn} onClick={toEditGoods()}>新增</Button>
253
+      <Button type="danger" className={styles.addBtn} onClick={toEditGoods()}>新增</Button>
254 254
       <Table dataSource={data.list} columns={columns} pagination={false}/>
255 255
       <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '30px' }}>
256 256
         <Pagination showQuickJumper defaultCurrent={1} total={data.total} onChange={changePageNum} />

+ 9
- 4
src/pages/building/list/add/components/base.jsx Прегледај датотеку

@@ -9,6 +9,7 @@ import ImageUpload from '../../../../../components/XForm/ImageUpload'
9 9
 import ImageListUpload from '../../../../../components/XForm/ImageListUpload'
10 10
 import Wangedit from '../../../../../components/Wangedit/Wangedit'
11 11
 import TagGroup from './tags'
12
+import BudildingProjectType from './buildingProjectType'
12 13
 
13 14
 const { Option } = Select
14 15
 const { TabPane } = Tabs;
@@ -55,6 +56,7 @@ function AddBuilding(props) {
55 56
     request({ url: tempUrl, method }).then(res => {
56 57
       res.openingDate = moment(res.openingDate)
57 58
       res.receivedDate = moment(res.receivedDate)
59
+      res.avatarImage = res.buildingImg.map(item => item.url)
58 60
       props.form.setFieldsValue(res)
59 61
     })
60 62
   }
@@ -71,11 +73,11 @@ function AddBuilding(props) {
71 73
   function addBuilding(data) {
72 74
     data.openingDate = moment(data.openingDate, 'yyyy-MM-dd HH:mm:ss')
73 75
     data.receivedDate = moment(data.receivedDate, 'yyyy-MM-dd HH:mm:ss')
74
-    data.buildingProjectType = []
75 76
     // 项目主图
76 77
     data.img = data.avatarImage && data.avatarImage.map((item, index) => ({ imgType: 'banner', url: item, orderNo: index + 1 }))
77 78
 
78
-    request({ ...apis.building.addBuilding, data: { ...data } }).then(() => {
79
+    const api = data.buildingId === undefined ? apis.building.addBuilding : apis.building.updateBuilding
80
+    request({ ...api, data: { ...data } }).then(() => {
79 81
       openNotificationWithIcon('success', '操作成功')
80 82
     }).catch(err => {
81 83
       openNotificationWithIcon('error', err.message)
@@ -84,6 +86,9 @@ function AddBuilding(props) {
84 86
 
85 87
   return (
86 88
         <Form {...formItemLayout} onSubmit={handleSubmit}>
89
+          <Form.Item label="项目Id" hasFeedback style={{ display: 'none' }}>
90
+            {getFieldDecorator('buildingId')(<Input disabled />)}
91
+          </Form.Item>
87 92
           <Form.Item label="楼盘编号" hasFeedback>
88 93
             {getFieldDecorator('code')(<Input />)}
89 94
           </Form.Item>
@@ -93,8 +98,8 @@ function AddBuilding(props) {
93 98
           <Form.Item label="别名" hasFeedback>
94 99
             {getFieldDecorator('name')(<Input />)}
95 100
           </Form.Item>
96
-          <Form.Item label="项目类型" hasFeedback>
97
-            {getFieldDecorator('buildingProjectType')(<Input />)}
101
+          <Form.Item label="项目类型">
102
+            {getFieldDecorator('buildingProjectType')(<BudildingProjectType />)}
98 103
           </Form.Item>
99 104
           <Form.Item label="均价" hasFeedback>
100 105
             {getFieldDecorator('price')(<Input />)}

+ 262
- 0
src/pages/building/list/add/components/buildingProjectType.jsx Прегледај датотеку

@@ -0,0 +1,262 @@
1
+import React, { useEffect, useState } from 'react'
2
+import { Button, Radio, Icon, Form, Input, Row, Col, Modal, notification, Checkbox } from 'antd';
3
+import { render } from 'react-dom';
4
+import request from '../../../../../utils/request';
5
+import apis from '../../../../../services/apis';
6
+
7
+
8
+const formItemLayout = {
9
+  labelCol: {
10
+    xs: { span: 24 },
11
+    sm: { span: 3 },
12
+  },
13
+  wrapperCol: {
14
+    xs: { span: 24 },
15
+    sm: { span: 16 },
16
+  },
17
+};
18
+
19
+/**
20
+ * 项目类型 form 表单子组件
21
+ *
22
+ * @param {*} props
23
+ */
24
+class TypeForm extends React.Component {
25
+
26
+  componentDidMount() {
27
+    this.props.form.setFieldsValue(this.props.type)
28
+  }
29
+
30
+  onChange(e, name) {
31
+    // console.log(e.target.value)
32
+    this.props.form.validateFieldsAndScroll((err, values) => {
33
+      if (!err) {
34
+        // console.log('Received values of form: ', values);
35
+        values[name] = e.target.value
36
+        values.buildingTypeName = this.props.type.buildingTypeName
37
+        console.log('values: ', values)
38
+        this.props.onSuccess(values)
39
+      }
40
+    });
41
+  }
42
+
43
+  close() {
44
+    this.props.onClose(this.props.form.getFieldsValue(['buildingTypeId']))
45
+  }
46
+
47
+  render() {
48
+    const { getFieldDecorator } = this.props.form;
49
+
50
+    // this.props.form.setFieldsValue(this.props.type)
51
+
52
+    return (
53
+      <>
54
+        <div>
55
+          <Row>
56
+            <Col span={8}>{ this.props.type.buildingTypeName || ''}</Col>
57
+            <Col span={1}>
58
+              <Button type="link" icon="close" onClick={() => this.close()} />
59
+            </Col>
60
+          </Row>
61
+          <Row>
62
+            <Col span={12}>
63
+              <Form {...formItemLayout}>
64
+                <Form.Item label="类型编号" style={{ display: 'none' }}>
65
+                  {getFieldDecorator('buildingTypeId')(<Input disabled />)}
66
+                </Form.Item>
67
+                <Form.Item label="状态" style={{ display: 'none' }}>
68
+                  {getFieldDecorator('status')(<Input disabled />)}
69
+                </Form.Item>
70
+                <Form.Item label="价格">
71
+                  {getFieldDecorator('price')(<Input type="number" placeholder="元/㎡" onChange={e => this.onChange(e, 'price')}/>)}
72
+                </Form.Item>
73
+                <Form.Item label="装修标准">
74
+                  {getFieldDecorator('decoration')(<Input onChange={e => this.onChange(e, 'decoration')}/>)}
75
+                </Form.Item>
76
+                <Form.Item label="产权年限">
77
+                  {getFieldDecorator('rightsYear')(<Input onChange={e => this.onChange(e, 'rightsYear')}/>)}
78
+                </Form.Item>
79
+              </Form>
80
+            </Col>
81
+          </Row>
82
+        </div>
83
+      </>
84
+    )
85
+  }
86
+}
87
+
88
+const WrappedTypeForm = Form.create({ name: 'TypeForm' })(TypeForm);
89
+
90
+/**
91
+ *项目类型组件
92
+ *
93
+ * @param {*} props
94
+ */
95
+class ProjectTypeBody extends React.Component {
96
+
97
+  constructor(props) {
98
+    super(props)
99
+    this.state = {
100
+      one: false,
101
+      projectType: [],
102
+      defaultCheckboxValue: [], // 多选框默认选中的值
103
+      visible: false,
104
+      data: [],
105
+      // data: [{ buildingTypeId: '1', buildingTypeName: '公寓', price: '10', decoration: '全包', rightsYear: '10', status: '1' }, { buildingTypeId: '2', buildingTypeName: '住宅', price: '10', decoration: '全包', rightsYear: '10', status: '1' }, { buildingTypeId: '3', buildingTypeName: '太平房', price: '10', decoration: '全包', rightsYear: '10', status: '1' }],
106
+    }
107
+  }
108
+
109
+  componentDidMount() {
110
+    this.getList({ pageNum: 1, pageSize: 999 })
111
+  }
112
+
113
+  componentDidUpdate(prevProps) {
114
+    // 典型用法(不要忘记比较 props):
115
+    if (this.props.value !== prevProps.data && !this.state.one) {
116
+      this.setValue()
117
+      this.setState({ one: true })
118
+    }
119
+  }
120
+
121
+  onSuccess = (values, item) => {
122
+    console.log('values: ', values)
123
+    console.log('data: ', this.state.data, 'item: ', item)
124
+    const newData = this.getNewProjectType(values)
125
+    console.log('newData: ', newData)
126
+    this.setState({ data: newData })
127
+    if (typeof this.props.onChange === 'function') {
128
+      this.props.onChange(newData)
129
+    }
130
+  }
131
+
132
+  onCheckboxChange = checkedValues => {
133
+      const checked = (`${checkedValues}` || '').split(',')
134
+      const { projectType } = this.state
135
+      const buildingType = projectType.filter(item => checked.includes(`${item.buildingTypeId}`))
136
+
137
+      // 这里会把值替换掉
138
+
139
+      const tempDate = buildingType.map(item => ({ buildingTypeId: item.buildingTypeId, buildingTypeName: item.buildingTypeName, price: '', decoration: '', rightsYear: '', status: '1' }))
140
+      const updateProjectDate = this.updateProjectType(checkedValues)
141
+      console.log('updateProjectDate: ', updateProjectDate)
142
+      this.setState({ data: updateProjectDate })
143
+  }
144
+
145
+  onClose = e => {
146
+    const { data } = this.state
147
+    const buildingType = data.filter(item => e.buildingTypeId !== item.buildingTypeId)
148
+    console.log('buildingType: ', buildingType)
149
+    this.setState({ data: buildingType })
150
+    this.setState({ defaultCheckboxValue: buildingType.map(item => item.buildingTypeId) })
151
+  }
152
+
153
+  getNewProjectType = values => {
154
+    const data = []
155
+    this.state.data.map(item => {
156
+      console.log('item: ', item)
157
+      if (item.buildingTypeId === values.buildingTypeId) {
158
+        data.push(values)
159
+      } else {
160
+        data.push(item)
161
+      }
162
+    })
163
+
164
+    return data
165
+  }
166
+
167
+  updateProjectType = values => {
168
+    const data = []
169
+    this.state.data.map(item => {
170
+      values.map(va => {
171
+        if (item.buildingTypeId === va.buildingTypeId) {
172
+          data.push(va)
173
+        } else {
174
+          data.push(item)
175
+        }
176
+      })
177
+    })
178
+
179
+    return data
180
+  }
181
+
182
+  getList = params => {
183
+    request({ ...apis.buildingType.getList, params: { ...params } }).then(res => {
184
+      this.setState({ projectType: res.records })
185
+    }).catch(err => {
186
+      this.openNotificationWithIcon('error', err.message)
187
+    })
188
+  }
189
+
190
+  setValue = () => {
191
+    let tempData = []
192
+    let tempCheckboxValue = []
193
+    const { value } = this.props
194
+    // console.log('value: ', value)
195
+    if (value !== undefined && value !== null) {
196
+      tempData = value
197
+      tempCheckboxValue = tempData.map(item => item.buildingTypeId)
198
+      this.setState({ defaultCheckboxValue: tempCheckboxValue })
199
+      this.setState({ data: tempData }, () => {
200
+        console.log("state: ", this.state.data)
201
+      })
202
+
203
+      console.log("tempData: ", tempData, "tempCheckboxValue: ", tempCheckboxValue, "value: ", value)
204
+    }
205
+  }
206
+
207
+  openNotificationWithIcon = (type, message) => {
208
+    notification[type]({
209
+      message,
210
+      description: '',
211
+    })
212
+  }
213
+
214
+  handleOk = e => {
215
+    this.setState({
216
+      visible: false,
217
+    });
218
+  };
219
+
220
+  handleCancel = e => {
221
+    this.setState({
222
+      visible: false,
223
+    });
224
+  };
225
+
226
+  showMadel = () => {
227
+    this.setState({ visible: true })
228
+    this.getList({ pageNum: 1, pageSize: 999 })
229
+  }
230
+
231
+  render () {
232
+
233
+    // let tempData = []
234
+    // let tempCheckboxValue = []
235
+    // const { value } = this.props
236
+    // if (value !== undefined && value !== null) {
237
+    //   tempData = value
238
+    // } else {
239
+    //   tempData = this.state.data
240
+    // }
241
+
242
+    // tempCheckboxValue = tempData.map(item => item.buildingTypeId)
243
+    return (
244
+      <>
245
+        <Button type="primary" icon="plus" size="large" onClick={() => this.showMadel()} />
246
+        <Modal
247
+          title="项目类型"
248
+          visible={this.state.visible}
249
+          onOk={this.handleOk}
250
+          onCancel={this.handleCancel}
251
+        >
252
+          <Checkbox.Group options={this.state.projectType.map(item => ({ label: item.buildingTypeName, value: item.buildingTypeId }))} defaultValue={this.state.defaultCheckboxValue} onChange={e => this.onCheckboxChange(e)} />
253
+        </Modal>
254
+        {
255
+          this.state.data.map(item => <WrappedTypeForm type={item} key={item.id} onSuccess={(e) => this.onSuccess(e, item)} onClose={(e) => this.onClose(e)} />)
256
+        }
257
+      </>
258
+    )
259
+  }
260
+}
261
+
262
+export default ProjectTypeBody

+ 19
- 23
src/pages/building/list/add/components/tags.jsx Прегледај датотеку

@@ -3,15 +3,23 @@ import { Tag, Input, Tooltip, Icon } from 'antd';
3 3
 
4 4
 class EditableTagGroup extends React.Component {
5 5
   state = {
6
-    tags: [],
7 6
     inputVisible: false,
8 7
     inputValue: '',
9 8
   };
10 9
 
10
+  // 每次取值,都从 this.props.value 获取最新值
11
+  getTags = () => (this.props.value || '').split(',')
12
+
13
+  toggleOnChange = tags => {
14
+    if (typeof this.props.onChange === 'function') {
15
+      this.props.onChange(tags.join(','))
16
+    }
17
+  }
18
+
11 19
   handleClose = removedTag => {
12
-    const tags = this.state.tags.filter(tag => tag !== removedTag);
13
-    console.log(tags);
14
-    this.setState({ tags });
20
+    const tags = this.getTags().filter(tag => tag !== removedTag);
21
+    // this.setState({ tags });
22
+    this.toggleOnChange(tags)
15 23
   };
16 24
 
17 25
   showInput = () => {
@@ -24,39 +32,27 @@ class EditableTagGroup extends React.Component {
24 32
 
25 33
   handleInputConfirm = () => {
26 34
     const { inputValue } = this.state;
27
-    let { tags } = this.state;
35
+
36
+    const tags = this.getTags()
28 37
     if (inputValue && tags.indexOf(inputValue) === -1) {
29
-      tags = [...tags, inputValue];
38
+      // 如果有新的值,就把这个值追加到 tags 原本值的后面,在通过onChange事件传递出去
39
+      this.toggleOnChange(tags.concat(inputValue))
30 40
     }
31
-    console.log(tags);
41
+
32 42
     this.setState({
33
-      tags,
34 43
       inputVisible: false,
35 44
       inputValue: '',
36 45
     });
37
-
38
-    if (typeof this.props.onChange === 'function') {
39
-      const tempTags = tags.join(',')
40
-      this.props.onChange(tempTags);
41
-    }
42 46
   };
43 47
 
44 48
   saveInputRef = input => (this.input = input);
45 49
 
46 50
   render() {
47
-    const { tags, inputVisible, inputValue } = this.state;
48
-
49
-    const { value } = this.props
50
-    let data = []
51
-    if (value !== undefined && value !== null) {
52
-      data = value.split(',')
53
-    } else {
54
-      data = tags
55
-    }
51
+    const { inputVisible, inputValue } = this.state;
56 52
 
57 53
     return (
58 54
       <div>
59
-        {data.map((tag, index) => {
55
+        {this.getTags().map((tag, index) => {
60 56
           const isLongTag = tag.length > 20;
61 57
           const tagElem = (
62 58
             <Tag key={tag} closable onClose={() => this.handleClose(tag)}>

+ 59
- 55
src/pages/building/list/index.jsx Прегледај датотеку

@@ -5,6 +5,7 @@ import request from '../../../utils/request';
5 5
 import apis from '../../../services/apis';
6 6
 import Styles from './style.less';
7 7
 import { router } from 'umi';
8
+import AuthButton from '@/components/AuthButton';
8 9
 
9 10
 
10 11
 const { Option } = Select;
@@ -100,56 +101,56 @@ function CartBody(props) {
100 101
   }
101 102
 
102 103
   return (
103
-          <Card
104
-            hoverable
105
-            style={{ minWidth: '400px', borderRadius: '12px', margin: '10px', boxShadow: '0px 0px 16px 2px rgba(0,0,0,0.12)' }}
106
-            cover={<img alt="example" src={ data.poster } style={{ borderRadius: '12px 12px 0 0', width: '100%', height: '14vw' }}></img>}
107
-            bodyStyle={{ padding: '10px 20px' }}
108
-          >
109
-            <p className={Styles.cardText}>
110
-              <span className={Styles.title}>楼盘编号</span>
111
-              <span >:{ data.code }</span>
112
-              <span className={Styles.ediText} onClick={() => toEdi(data)}>
113
-                编辑
104
+    <Card
105
+      hoverable
106
+      style={{ minWidth: '400px', borderRadius: '12px', margin: '10px', boxShadow: '0px 0px 16px 2px rgba(0,0,0,0.12)' }}
107
+      cover={<img alt="example" src={data.poster} style={{ borderRadius: '12px 12px 0 0', width: '100%', height: '14vw' }}></img>}
108
+      bodyStyle={{ padding: '10px 20px' }}
109
+    >
110
+      <p className={Styles.cardText}>
111
+        <span className={Styles.title}>楼盘编号</span>
112
+        <span >:{data.code}</span>
113
+        <span className={Styles.ediText} onClick={() => toEdi(data)}>
114
+          编辑
114 115
                 <Icon type="form" style={{ color: '#C0C4CC', marginLeft: '10px' }} />
115
-              </span>
116
-            </p>
117
-            <p className={Styles.cardText}>
118
-              <span className={Styles.title}>楼盘名称</span>
119
-              <span >:{ data.name }</span>
120
-            </p>
121
-            <p className={Styles.cardItem}>
122
-              <span className={Styles.title}>均价</span>
123
-              <span >
124
-                :约<span style={{ color: '#FF0707', fontSize: '20px' }}> { data.price } </span>元/m
125 116
         </span>
126
-            </p>
127
-            <p className={Styles.cardItem}>
128
-              <span className={Styles.title}>项目地址</span>
129
-              <span className={ Styles.address }>:{ data.address }</span>
130
-            </p>
131
-            <p className={Styles.cardItem}>
132
-              <span className={Styles.title}>发布状态</span>
133
-              <span >:{ data.status === 1 ? '已发布' : '未发布' }</span>
134
-            </p>
135
-            <p className={Styles.cardItem}>
136
-              <span className={Styles.title}>录入时间</span>
137
-              <span >:{ data.createDate }</span>
138
-            </p>
139
-            <p style={{ margin: '15px 0', position: 'relative', fontSize: '18px' }}>
140
-              <span style={{ color: '#1990FF' }} onClick={() => pulicAndUnPulic(data)}>
141
-                {/* 已发布的时候,需要显示取消发布的字样 */}
142
-                { data.status === 1 ? '取消发布' : '发布' }
143
-                <Icon type="close-circle" style={{ color: '#C0C4CC', marginLeft: '8px' }} />
144
-              </span>
145
-              <span style={{
146
-                color: '#FF4A4A', position: 'absolute', right: '0',
147
-              }} onClick={() => deleteBuilding(data)}>
148
-                删除
117
+      </p>
118
+      <p className={Styles.cardText}>
119
+        <span className={Styles.title}>楼盘名称</span>
120
+        <span >:{data.name}</span>
121
+      </p>
122
+      <p className={Styles.cardItem}>
123
+        <span className={Styles.title}>均价</span>
124
+        <span >
125
+          :约<span style={{ color: '#FF0707', fontSize: '20px' }}> {data.price} </span>元/m
126
+        </span>
127
+      </p>
128
+      <p className={Styles.cardItem}>
129
+        <span className={Styles.title}>项目地址</span>
130
+        <span className={Styles.address}>:{data.address}</span>
131
+      </p>
132
+      <p className={Styles.cardItem}>
133
+        <span className={Styles.title}>发布状态</span>
134
+        <span >:{data.status === 1 ? '已发布' : '未发布'}</span>
135
+      </p>
136
+      <p className={Styles.cardItem}>
137
+        <span className={Styles.title}>录入时间</span>
138
+        <span >:{data.createDate}</span>
139
+      </p>
140
+      <p style={{ margin: '15px 0', position: 'relative', fontSize: '18px' }}>
141
+        <span style={{ color: '#FF4A4A' }} onClick={() => pulicAndUnPulic(data)}>
142
+          {/* 已发布的时候,需要显示取消发布的字样 */}
143
+          {data.status === 1 ? '取消发布' : '发布'}
144
+          <Icon type={data.status === 1 ? 'close-circle' : 'form'} style={{ color: '#C0C4CC', marginLeft: '8px' }} />
145
+        </span>
146
+        <span style={{
147
+          color: '#FF4A4A', position: 'absolute', right: '0',
148
+        }} onClick={() => deleteBuilding(data)}>
149
+          删除
149 150
                 <Icon type="rest" style={{ color: '#C0C4CC', marginLeft: '8px' }} />
150
-              </span>
151
-            </p>
152
-          </Card>
151
+        </span>
152
+      </p>
153
+    </Card>
153 154
   )
154 155
 }
155 156
 
@@ -209,7 +210,7 @@ function body(props) {
209 210
   // 分页
210 211
   function onChange(pageNumber) {
211 212
     // eslint-disable-next-line react-hooks/rules-of-hooks
212
-      getList({ pageNum: pageNumber, pageSize: 9 })
213
+    getList({ pageNum: pageNumber, pageSize: 9 })
213 214
   }
214 215
 
215 216
   function getDate(value, dateString) {
@@ -285,18 +286,21 @@ function body(props) {
285 286
           </Button>
286 287
         </Form.Item>
287 288
       </Form>
288
-      <Button type="danger" className={Styles.addButton} onClick={() => toAdd()}>
289
-        新增楼盘
290
-      </Button>
289
+
290
+      <AuthButton name="building.add" noRight={null}>
291
+        <Button type="danger" className={Styles.addButton} onClick={() => toAdd()}>
292
+          新增楼盘
293
+        </Button>
294
+      </AuthButton>
291 295
 
292 296
       {/* 卡片内容,显示楼盘项目  */}
293 297
       <Row style={{ padding: ' 0 10px' }}>
294 298
         {
295 299
           dataSource.records.map((item, _) => (
296
-              <Col span={8}>
297
-                <CartBody data={item} key={item.buildingId} onSuccess={getList}/>
298
-              </Col>
299
-            ))
300
+            <Col span={8}>
301
+              <CartBody data={item} key={item.buildingId} onSuccess={getList} />
302
+            </Col>
303
+          ))
300 304
         }
301 305
       </Row>
302 306
       {/* 分页 */}

+ 2
- 2
src/pages/building/type/index.jsx Прегледај датотеку

@@ -96,8 +96,8 @@ function body() {
96 96
 
97 97
   return (
98 98
     <>
99
-      <Button type="primary" className={Styles.addButton} onClick={() => toEdi()}>新增类型</Button>
100
-      <Table dataSource={data.records} columns={columns} pagination={false}/>
99
+      <Button type="danger" onClick={() => toEdi()}>新增类型</Button>
100
+      <Table style={{marginTop:'30px'}} dataSource={data.records} columns={columns} pagination={false}/>
101 101
       {/* 分页 */}
102 102
       <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '30px' }}>
103 103
         <Pagination showQuickJumper defaultCurrent={1} total={data.total} onChange={onChange} />

+ 1
- 1
src/pages/carouselFigure/advertisingList.jsx Прегледај датотеку

@@ -217,7 +217,7 @@ const handleSubmit = (e, props) => {
217 217
           </Button>
218 218
         </Form.Item>
219 219
       </Form>
220
-      <Button type="primary" className={styles.addBtn} onClick={toEdit()}>新增</Button>
220
+      <Button type="danger" className={styles.addBtn} onClick={toEdit()}>新增</Button>
221 221
       <Table dataSource={data.records} columns={columns} pagination={false}/>
222 222
       <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '30px' }}>
223 223
         <Pagination showQuickJumper defaultCurrent={1} total={data.total} onChange={changePageNum} />

+ 1
- 1
src/pages/carouselFigure/carouselFigureList.jsx Прегледај датотеку

@@ -217,7 +217,7 @@ const handleSubmit = (e, props) => {
217 217
           </Button>
218 218
         </Form.Item>
219 219
       </Form>
220
-      <Button type="primary" className={styles.addBtn} onClick={toEditCarouse()}>新增</Button>
220
+      <Button type="danger" className={styles.addBtn} onClick={toEditCarouse()}>新增</Button>
221 221
       <Table dataSource={data.records} columns={columns} pagination={false}/>
222 222
       <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '30px' }}>
223 223
         <Pagination showQuickJumper defaultCurrent={1} total={data.total} onChange={changePageNum} />

+ 1
- 1
src/pages/channel/brokerList.jsx Прегледај датотеку

@@ -166,7 +166,7 @@ return (
166 166
       {/* <Button onClick={() => refurbishList() }>重置</Button> */}
167 167
     </div>
168 168
     </div>
169
-    <Table dataSource={data.list} columns={columns} pagination={{ pageSize: 10, total: data.total, onChange }} />
169
+    <Table style={{marginTop:'40px'}} dataSource={data.list} columns={columns} pagination={{ pageSize: 10, total: data.total, onChange }} />
170 170
   </>
171 171
 )
172 172
 }

+ 2
- 2
src/pages/customer/customerlist/index.jsx Прегледај датотеку

@@ -248,8 +248,8 @@ function body(props) {
248 248
           )}
249 249
         </Form.Item>
250 250
         <Form.Item>
251
-          <Button type="danger" htmlType="submit" >
252
-            搜索
251
+          <Button type="primary" htmlType="submit" >
252
+            查询
253 253
           </Button>
254 254
         </Form.Item>
255 255
       </Form>

+ 1
- 1
src/pages/customer/report/index.jsx Прегледај датотеку

@@ -159,7 +159,7 @@ function body(props) {
159 159
           </Button>
160 160
         </Form.Item>
161 161
       </Form>
162
-      <Table dataSource={dataSource.records} columns={columns} pagination={{ total: dataSource.total, onChange }} />
162
+      <Table style={{marginTop:'40px'}} dataSource={dataSource.records} columns={columns} pagination={{ total: dataSource.total, onChange }} />
163 163
     </>
164 164
   );
165 165
 }

+ 180
- 0
src/pages/indexEcharts/components/UserSource.jsx Прегледај датотеку

@@ -0,0 +1,180 @@
1
+import React, { Component, useState, useEffect } from 'react';
2
+
3
+import EChart from '../../../components/EchartsTest/EChart';
4
+import request from '../../../utils/request';
5
+import apis from '../../../services/apis';
6
+import dayjs from 'dayjs';
7
+import router from 'umi/router';
8
+import {Table, Select, Row, Col, Menu, Dropdown, Button, Icon, message } from 'antd';
9
+// import UserSource from './mmm';
10
+
11
+
12
+const UserSource = (props) => {
13
+
14
+  const [data, setData] = useState({ records: [] })
15
+  //柱图
16
+
17
+  useEffect(() => {
18
+    userResource()
19
+  }, [])
20
+
21
+  function userResource () {
22
+    request({
23
+      ...apis.indexEcharts.userResource,
24
+      params: { pageNum: 1, pageSize: 9999 }
25
+    }).then((data) => {
26
+      // console.log(data , '3333')
27
+      setData(data)
28
+    })
29
+  }
30
+
31
+  function toEdit () {
32
+    router.push({
33
+      pathname: '/indexEcharts/userSource',
34
+      // query: {
35
+      //   a: 'b',
36
+      // },
37
+    });
38
+  }
39
+
40
+  const dataset = data || {};
41
+  const source = dataset.columnar || [];
42
+
43
+  // const source = this.dataset.columnar || [];
44
+  const subtitle = '最近7天';
45
+  const baroptions = {
46
+    color: ['#286DD0', '#8565CE', '#6A96F8', '#F5749E', '#8B7FE2'],
47
+    xAxis: { type: 'category' },
48
+    legend: {
49
+      left: '20%',
50
+      data: ['所有用户', '注册用户'],
51
+    },
52
+
53
+    tooltip: {},
54
+
55
+    yAxis: {},
56
+    series: [
57
+      { type: 'bar', name: '所有用户', datasetIndex: 0 },
58
+      { type: 'bar', name: '注册用户' },
59
+    ],
60
+    dataset: {
61
+      id: 'bar',
62
+      dimensions: ['fromName', 'userCount', 'registered'],
63
+      source: source,
64
+    },
65
+
66
+  }
67
+  const { person_estate_agent = 0, person_null = 0, person_realty_consultant = 0 } = dataset.pie || {};
68
+  const pieoptions = {
69
+    // xAxis: {},
70
+    color: ['#286DD0', '#8565CE', '#6A96F8', '#F5749E', '#8B7FE2'],
71
+    legend: {
72
+      // left: '70%',
73
+      data: ['来源置业顾问', '来源全民经纪人', '自主进入'],
74
+    },
75
+    tooltip: {},
76
+    // yAxis: {},
77
+
78
+    series: [
79
+      {
80
+        type: 'pie',
81
+        // datasetIndex: 1,
82
+        center: ['50%', '50%'],
83
+        radius: [0, '50%'],
84
+      },
85
+    ],
86
+    dataset: {
87
+      id: 'pie',
88
+      source: [
89
+        { form: '来源置业顾问', value: person_realty_consultant },
90
+        { form: '来源全民经纪人', value: person_estate_agent },
91
+        { form: '自主进入', value: person_null },
92
+      ]
93
+    },
94
+
95
+
96
+
97
+
98
+
99
+  }
100
+  function handleSelectChange (e) {
101
+    // eslint-disable-next-line no-console
102
+    console.log(e)
103
+  }
104
+
105
+  //表格
106
+  const dataSource = [
107
+    {
108
+      name: '置业顾问',
109
+      status: '1',//显示停用
110
+    },
111
+    {
112
+      name: '置业经理',
113
+      status: '1',//停用
114
+    },
115
+  ];
116
+
117
+  const columns = [
118
+    // {
119
+    //   title: '商品图片',
120
+    //   dataIndex: 'img',
121
+    //   key: 'img',
122
+    //   align: 'center',
123
+  
124
+    //   render: (text, record) => <img src={record.img} className={channels.touxiang} />,
125
+    // },
126
+    {
127
+      title: '角色名称',
128
+      dataIndex: 'name',
129
+      key: 'name',
130
+      align: 'center',
131
+      render: text => <a>{text}</a>,
132
+    },
133
+  
134
+    {
135
+      title: '操作  ',
136
+      dataIndex: 'status',
137
+      key: 'status',
138
+      align: 'center',
139
+  
140
+      render: () => <>11</>
141
+       
142
+    },
143
+  ];
144
+
145
+  const style = {
146
+    width: '100%',
147
+    height: '400px',
148
+
149
+  }
150
+  const styles = {
151
+    width: '100%',
152
+    height: '400px',
153
+
154
+  }
155
+
156
+
157
+  return (
158
+    <>
159
+      <div>
160
+        <h3>用户来源 <small>{subtitle}</small></h3>
161
+        <Row>
162
+          <Col span={16}>
163
+            <EChart options={baroptions} style={style} /></Col>
164
+          <Col span={8}>
165
+            <EChart options={pieoptions} style={styles} /></Col>
166
+        </Row>
167
+      </div>
168
+      <Select style={{ width: '180px' }} placeholder="所有用户" onChange={handleSelectChange}>
169
+        <Option value={0}>所有用户</Option>
170
+        <Option value={1}>注册用户</Option>
171
+      </Select>
172
+
173
+
174
+      <Table dataSource={dataSource} columns={columns} />
175
+
176
+    </>
177
+  )
178
+}
179
+
180
+export default UserSource;

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

@@ -0,0 +1,27 @@
1
+
2
+import React, { useState, useEffect }  from 'react';
3
+import { Form, Input, Button, Icon, Select, message, Table, Divider, Row, Col, Tag, Pagination, Modal, DatePicker } from 'antd';
4
+
5
+// import styles from '../../style/GoodsList.less';
6
+import router from 'umi/router';
7
+
8
+import request from '../../utils/request'
9
+import apis from '../../services/apis';
10
+// import Styles from './style.less';/
11
+import UserSource from './components/UserSource.jsx';
12
+
13
+
14
+const header = (props) => {
15
+
16
+
17
+  return (
18
+
19
+    <>
20
+    {/* <div>2222</div> */}
21
+     <UserSource  ></UserSource>
22
+    </>
23
+  )
24
+}
25
+
26
+
27
+export default  header

+ 77
- 0
src/pages/indexEcharts/userSource.jsx Прегледај датотеку

@@ -0,0 +1,77 @@
1
+import dayjs from 'dayjs';
2
+import React from 'react';
3
+import {Radio, DatePicker,  Form, Input, Button, Icon, Select, message, Table, Divider, Tag, Pagination, Modal, Breadcrumb } from 'antd';
4
+
5
+import UserSource from './components/UserSource.jsx';
6
+// import XForm, { FieldTypes } from '../../components/XForm';
7
+import moment from 'moment';
8
+
9
+
10
+const header = props => {
11
+  const { RangePicker } = DatePicker;
12
+  function onChange(dates, dateStrings) {
13
+    console.log('From: ', dates[0], ', to: ', dates[1]);
14
+    console.log('From: ', dateStrings[0], ', to: ', dateStrings[1]);
15
+  }
16
+
17
+
18
+  const handleSubmit = (e, props) => {
19
+    e.preventDefault();
20
+    // props.form.validateFields((err, values) => {
21
+    //   if (!err) {
22
+    //     getList({ pageNum: 1, pageSize: 10, ...values })
23
+    //   }
24
+    // });
25
+  }
26
+
27
+
28
+  function getDataOf(days){      
29
+    // const endDate = new Date()
30
+    // const startDate = dayjs().subtract(days, 'day').toDate()
31
+
32
+    // this.$refs.chart.getData({ startDate, endDate })
33
+  }
34
+
35
+  function onChange(e) {
36
+    console.log(`radio checked:${e.target.value}`);
37
+  }
38
+
39
+  return (<>
40
+  {/* <el-button type="text" @click="() => getDataOf(7)">最近7天</el-button>
41
+      <el-button type="text" @click="() => getDataOf(30)">最近1月</el-button>
42
+      <el-date-picker
43
+        v-model="dateRange"
44
+        type="daterange"
45
+        start-placeholder="开始日期"
46
+        end-placeholder="结束日期"
47
+        style="margin-left: 16px">
48
+      </el-date-picker>
49
+      <el-button type="primary" icon="el-icon-search" style="margin-left: 32px" @click="search">查询</el-button>
50
+    </div>
51
+    <user-source ref="chart" mode="all"></user-source> */}
52
+  <Radio.Group onChange={onChange} defaultValue="a">
53
+        <Radio.Button value="a" onClick={getDataOf(7)}>最近7天</Radio.Button>
54
+        <Radio.Button value="b" onClick={getDataOf(30)}>最近1月</Radio.Button>
55
+      </Radio.Group>
56
+      <RangePicker
57
+      ranges={{
58
+        Today: [moment(), moment()],
59
+        'This Month': [moment().startOf('month'), moment().endOf('month')],
60
+      }}
61
+      showTime
62
+      format="YYYY/MM/DD HH:mm:ss"
63
+      // onChange={onChange}
64
+    />
65
+     <Button type="primary" htmlType="submit" >
66
+            查询
67
+          </Button>
68
+  <div>
69
+    
70
+
71
+    <UserSource ></UserSource>
72
+  </div>
73
+  </>
74
+  )
75
+}
76
+
77
+export default header

+ 1
- 1
src/pages/integralMall/GoodsList.jsx Прегледај датотеку

@@ -184,7 +184,7 @@ function header(props) {
184 184
           </Button>
185 185
         </Form.Item>
186 186
       </Form>
187
-      <Button type="primary" className={styles.addBtn} onClick={toEditGoods()}>新增</Button>
187
+      <Button type="danger" className={styles.addBtn} onClick={toEditGoods()}>新增</Button>
188 188
       <Table dataSource={data.records} columns={columns} pagination={false} />
189 189
       <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '30px' }}>
190 190
         <Pagination showQuickJumper defaultCurrent={1} total={data.total} onChange={changePageNum} />

+ 1
- 1
src/pages/integralMall/exchangeRecords.jsx Прегледај датотеку

@@ -190,7 +190,7 @@ function record(props) {
190 190
           </Form.Item>
191 191
         </div>
192 192
       </Form>
193
-      <Table dataSource={data.records} columns={columns} pagination={false} />
193
+      <Table style={{marginTop:'40px'}} dataSource={data.records} columns={columns} pagination={false} />
194 194
       <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '30px' }}>
195 195
         <Pagination showQuickJumper defaultCurrent={1} total={data.total} onChange={changePageNum} />
196 196
       </div>

+ 1
- 1
src/pages/news/list/NewsList.jsx Прегледај датотеку

@@ -178,7 +178,7 @@ function body(props) {
178 178
           </span> :
179 179
           <span style={{ position: 'absolute', left: '280px', bottom: '18px', fontSize: '18px', color: '#FF7E48' }} onClick={cancelRelease.bind(this, data.newsId, 0, data.buildingId, data.newsType.newsTypeId)}>
180 180
             发布
181
-              <Icon type="close-circle" style={{ color: '#C0C4CC', marginLeft: '8px' }} />
181
+              <Icon type="form" style={{ color: '#C0C4CC', marginLeft: '8px' }} />
182 182
           </span>
183 183
         }
184 184
 

+ 60
- 159
src/pages/staff/list/StaffList.jsx Прегледај датотеку

@@ -11,125 +11,45 @@ import Styles from './style.less';
11 11
 const { Meta } = Card;
12 12
 const { Option } = Select;
13 13
 const { MonthPicker, RangePicker, WeekPicker } = DatePicker;
14
-//标签颜色
15
-const colors = {
16
-  金牌顾问: '#E34B59',
17
-  销售冠军: '#E8747E',
18
-  优选顾问: '#EEC37E',
19
-  人气顾问: '#FDDA9F',
20
-}
21
-// 提交事件
22
-function handleSubmit (e, props) {
23
-  e.preventDefault();
24
-  props.form.validateFields((err, values) => {
25
-    if (!err) {
26
-      console.log('提交数据: ', values)
27
-    }
28
-  });
29
-}
30
-// Change 事件
31
-function handleSelectChange (props) {
32
-  console.log(props)
33
-}
34 14
 
35
-// 分页
36
-function onChange (pageNumber) {
37
-  console.log('Page: ', pageNumber);
38
-}
39 15
 // 跳转到编辑商品
40
-function toEditStaff () {
16
+const toEditStaff = (userId) => () => {
41 17
   router.push({
42 18
     pathname: '/staff/editStaff',
43
-    // query: {
44
-    //   a: 'b',
45
-    // },
46
-  });
47
-}
48
-function confirm () {
49
-  Modal.confirm({
50
-    title: '确认停用该角色?',
51
-    okText: '确认',
52
-    cancelText: '取消',
53
-    onOk () {
54
-      console.log('OK');
55
-    },
56
-    onCancel () {
57
-      console.log('Cancel');
19
+    query: {
20
+      userId
58 21
     },
59 22
   });
60
-
61 23
 }
62
-/**
63
- *
64
- *
65
- * 
66
- */
67
-
68
-// 假数据
69
-const tempData = [
70
-  {
71
-    name: '吴媛',
72
-    status: '1',// 启用
73
-    tel: '133 333 222',
74
-    avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
75
-    labels: ['金牌顾问', '销售冠军'],
76
-  },
77
-  {
78
-    name: '吴媛',
79
-    status: '1',// 启用
80
-    tel: '133 333 333',
81
-    avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
82
-    labels: ['金牌顾问', '销售冠军'],
83
-  },
84
-  {
85
-    name: '吴媛',
86
-    status: '1',// 启用
87
-    tel: '133 333 444',
88
-    avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
89
-    labels: ['金牌顾问', '销售冠军'],
90
-  },
91
-  {
92
-    name: '吴媛',
93
-    status: '1',// 启用
94
-    tel: '133 333 555',
95
-    avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
96
-    labels: ['金牌顾问', '销售冠军'],
97
-  },
98
-  {
99
-    name: '吴媛',
100
-    status: '0',
101
-    tel: '133 333 555',
102
-    avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
103
-    labels: ['金牌顾问', '销售冠军'],
104
-  },
105
-  {
106
-    name: '吴媛',
107
-    status: '1',// 启用
108
-    tel: '133 333 555',
109
-    avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
110
-    labels: ['金牌顾问'],
111
-  },
112
-
113
-
114
-
115
-]
116
-
117 24
 
118 25
 /**
119 26
  *卡片
120 27
  *
121 28
  * @returns
122 29
  */
123
-function CartBody (props) {
30
+const CartBody = (props) => {
124 31
   const { data } = props
125
-
32
+    
33
+  const confirm = () => {
34
+    Modal.confirm({
35
+      title: '确认停用该角色?',
36
+      okText: '确认',
37
+      cancelText: '取消',
38
+      onOk () {
39
+        console.log('OK');
40
+      },
41
+      onCancel () {
42
+        console.log('Cancel');
43
+      },
44
+    });
45
+  }
126 46
   return (
127 47
 
128 48
     <Card className={Styles.card}>
129 49
       <div>
130 50
 
131 51
         <Avatar src={data.avatar} style={{ width: 94, height: 94 }} />
132
-        <span className={Styles.ediText} style={{ marginLeft: '20px' }} onClick={toEditStaff}>
52
+        <span className={Styles.ediText} style={{ marginLeft: '20px' }} onClick={toEditStaff(data.userId)}>
133 53
           编辑
134 54
                 <Icon type="form" style={{ color: '#C0C4CC', marginLeft: '10px' }} />
135 55
         </span>
@@ -143,29 +63,20 @@ function CartBody (props) {
143 63
 
144 64
         <span>
145 65
           {
146
-            data.labels.map((item, index) => {
147
-              const color = colors[item];
148
-              console.log(color, '------');
149
-              return <Tag className={Styles.cardTag}  color = {color}>{item}</Tag>
66
+            data.taTagsList.map((item, index) => {
67
+              return <Tag className={Styles.cardTag} color={item.tagColor}>{item.tagName}</Tag>
150 68
             })
151 69
           }
152 70
         </span>
153
-        {/* {
154
-           data.label.map((item, index) => (
155
-              
156
-                <Tag className={Styles.cardTag}>{item}</Tag>
157
-          
158
-            ))
159
-            } */}
160 71
 
161 72
         <p className={Styles.cardText} style={{ width: '300px' }}>
162
-          <span>姓名:{data.name}</span>
73
+          <span>姓名:{data.userName}</span>
163 74
 
164 75
           <span style={{ float: "right" }}>状态:{data.status === '1' ? '启用' : '停用'}</span>
165 76
 
166 77
         </p>
167 78
         <p className={Styles.cardText} style={{ width: '300px' }}>
168
-          <span>电话:{data.tel}</span>
79
+          <span>电话:{data.phone}</span>
169 80
         </p>
170 81
       </div>
171 82
 
@@ -175,29 +86,37 @@ function CartBody (props) {
175 86
 
176 87
 
177 88
 const header = (props) => {
178
-  const [data, setData] = useState({})
179
-  //   const [page, changePage] = useState({})
180
-
181
-  // useEffect(() => {
182
-  //   request({
183
-  //       url: '/api/admin/iBuildingDynamicList',
184
-  //       method: 'GET',
185
-  //       params: {pageNum: 1,pageSize: 10},
186
-  //   }).then((data) => {
187
-  //       console.log(data)
188
-  //       setData(data)
189
-  //   })
190
-  // })
191
-
192
-  // const getList = (e) => {
193
-  //   request({
194
-  //       url: '/api/xxx',
195
-  //       method: 'GET',
196
-  //       params: {},
197
-  //   }).then((data) => {
198
-  //       setData(data)
199
-  //   })
200
-  // }
89
+  const [tempData,setTempData] = useState([])
90
+  useEffect(() => {
91
+    getList({ pageNum: 1, pageSize: 10 });
92
+  },[])
93
+
94
+  const getList = (params) => {
95
+    request({
96
+      url: '/api/admin/taUser',
97
+      method: 'GET',
98
+      params: { ...params },
99
+    }).then((data) => {
100
+        console.log(data,"listData")
101
+        setTempData(data.records)
102
+    })
103
+  }
104
+
105
+  // 分页
106
+  const onChange = (pageNumber) => {
107
+    getList({ pageNum: pageNumber, pageSize: 10 });
108
+  }
109
+
110
+  // 提交事件
111
+const handleSubmit = (e, props) => {
112
+  e.preventDefault();
113
+  props.form.validateFields((err, values) => {
114
+    if (!err) {
115
+      console.log('提交数据: ', values)
116
+      getList({ pageNum: 1, pageSize: 10, ...values })
117
+    }
118
+  });
119
+}
201 120
 
202 121
   const { getFieldDecorator } = props.form
203 122
   return (
@@ -205,7 +124,7 @@ const header = (props) => {
205 124
     <>
206 125
       <Form layout="inline" onSubmit={e => handleSubmit(e, props)}>
207 126
         <Form.Item>
208
-          {getFieldDecorator('name')(
127
+          {getFieldDecorator('userName')(
209 128
             <Input
210 129
               prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
211 130
               placeholder="姓名"
@@ -213,7 +132,7 @@ const header = (props) => {
213 132
           )}
214 133
         </Form.Item>
215 134
         <Form.Item>
216
-          {getFieldDecorator('tel')(
135
+          {getFieldDecorator('phone')(
217 136
             <Input
218 137
               prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
219 138
               placeholder="电话"
@@ -223,30 +142,13 @@ const header = (props) => {
223 142
 
224 143
         <Form.Item>
225 144
 
226
-          {getFieldDecorator('goodState')(
227
-            <Select style={{ width: '180px' }} placeholder="状态" onChange={handleSelectChange}>
145
+          {getFieldDecorator('status')(
146
+            <Select style={{ width: '180px' }} placeholder="状态" >
228 147
               <Option value="1">启用</Option>
229 148
               <Option value="0">停用</Option>
230 149
             </Select>,
231 150
           )}
232 151
         </Form.Item>
233
-        <Form.Item>
234
-          {getFieldDecorator('isMain')(
235
-            <Select style={{ width: '180px' }} placeholder="请选择" onChange={handleSelectChange}>
236
-              <Option value="1">职业顾问</Option>
237
-              <Option value="0">其他</Option>
238
-            </Select>,
239
-          )}
240
-        </Form.Item>
241
-        <Form.Item>
242
-          {getFieldDecorator('name')(
243
-            <Input
244
-              prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
245
-              placeholder="标签"
246
-            />,
247
-          )}
248
-        </Form.Item>
249
-
250 152
 
251 153
         <Form.Item>
252 154
           <Button type="primary" htmlType="submit" className={styles.searchBtn}>
@@ -254,7 +156,7 @@ const header = (props) => {
254 156
           </Button>
255 157
         </Form.Item>
256 158
       </Form>
257
-      <Button type="danger" className={styles.addBtn} onClick={toEditStaff}>新增</Button>
159
+      <Button type="danger" className={styles.addBtn} onClick={toEditStaff()}>新增</Button>
258 160
 
259 161
       <Row style={{ padding: ' 0 10px' }}>
260 162
         {
@@ -266,10 +168,9 @@ const header = (props) => {
266 168
         }
267 169
       </Row>
268 170
 
269
-      {/* <Table dataSource={data.records} columns={columns} /> */}
270 171
       {/* 分页  */}
271 172
       <div style={{ display: 'flex', justifyContent: 'flex-end' }}>
272
-        <Pagination showQuickJumper defaultCurrent={1} total={500} onChange={onChange} />
173
+        <Pagination showQuickJumper defaultCurrent={1} total={tempData.total} onChange={onChange} />
273 174
       </div>
274 175
     </>
275 176
   )

+ 107
- 48
src/pages/staff/list/editStaff.jsx Прегледај датотеку

@@ -1,15 +1,18 @@
1
-import React, { useState } from 'react';
1
+import React, { useState, useEffect } from 'react';
2 2
 
3 3
 import { Input, Menu, Dropdown, Button, Icon, message, Table, Tooltip, Tabs, Radio, Divider, Tag, Select, Form, Alert } from 'antd';
4 4
 import { FormattedMessage } from 'umi-plugin-react/locale';
5
+import BuildSelect from '../../../components/SelectButton/BuildSelect'
6
+import router from 'umi/router';
5 7
 import styles from '../../style/GoodsList.less';
6 8
 import XForm, { FieldTypes } from '../../../components/XForm';
7 9
 import Wangedit from '../../../components/Wangedit/Wangedit'
8 10
 import channels from './channelList.less';
9
-
10 11
 import Tagss from '../components/Tagss.jsx';
12
+import request from '../../../utils/request'
11 13
 
12 14
 const { TextArea } = Input;
15
+const { Option } = Select;
13 16
 
14 17
 
15 18
 /**
@@ -19,109 +22,165 @@ const { TextArea } = Input;
19 22
  * @returns
20 23
  */
21 24
 const Edit = (props) => {
25
+  const userId = props.location.query.userId
26
+  const [userData, setUserData] = useState({})
27
+  const [tagData, setTagData] = useState([])
28
+
29
+  console.log(userData,"user----》")
30
+
31
+  const getTagList = () => {
32
+    request({
33
+      url: '/api/admin/taTags',
34
+      method: 'GET',
35
+      params: {pageNum:1,pageSize:999}
36
+    }).then((data) => {
37
+      setTagData(data.records)
38
+    })
39
+  }
40
+
41
+  // 查询列表
42
+  const getUserData = (userId) => {
43
+    request({
44
+      url: '/api/admin/taUser/'+userId,
45
+      method: 'GET',
46
+    }).then((data) => {
47
+      console.log(data,"tauser")
48
+      setUserData(data)
49
+    })
50
+  }
51
+
52
+  useEffect(() => {
53
+    getTagList();
54
+    if (userId) {
55
+      getUserData(userId);
56
+    }
57
+  }, [])
58
+
59
+  const tagsChange = (value) => {
60
+    console.log(`selected ${value}`);
61
+  }
62
+
63
+  const handleSubmit = val => {
64
+    window.console.log('submit data --->', val)
65
+    if(userId){
66
+      request({
67
+        url: '/api/admin/taUser/' + userId,
68
+        method: 'PUT',
69
+        data: val,
70
+      }).then((data) => {
71
+        console.log(data,"tauser")
72
+        message.info("保存成功")
73
+        router.go(-1)
74
+      })
75
+    }else{
76
+      request({
77
+        url: '/api/admin/taUser',
78
+        method: 'POST',
79
+        data: val,
80
+      }).then((data) => {
81
+        console.log(data,"tauser")
82
+        message.info("保存成功")
83
+        router.go(-1)
84
+      })
85
+    }
86
+  }
22 87
 
23 88
   const fields = [
24 89
     {
25 90
       label: '名称',
26
-      name: 'staffName',
91
+      name: 'userName',
27 92
       type: FieldTypes.Text,
28
-      // placeholder: '名称',
29
-      value: ''
93
+      value: userData.userName
30 94
     },
31 95
     {
32 96
       label: '公司',
33
-      name: 'staffCompany',
97
+      name: 'orgName',
34 98
       type: FieldTypes.Text,
35 99
       placeholder: '请输入公司名称',
36
-      value: ''
100
+      value: userData.orgName
37 101
     },
38 102
     {
39 103
       label: '部门',
40
-      name: 'staffDepartment',
104
+      name: 'department',
41 105
       type: FieldTypes.Text,
42 106
       placeholder: '请输入部门',
43
-      value: ''
107
+      value: userData.department
44 108
     },
45 109
     {
46 110
       label: '职位',
47
-      name: 'staffPosition',
111
+      name: 'position',
48 112
       type: FieldTypes.Text,
49 113
       placeholder: '请输入职位',
50
-      value: ''
114
+      value: userData.position
51 115
     },
52 116
     {
53 117
       label: '电话',
54
-      name: 'staffTel',
118
+      name: 'phone',
55 119
       type: FieldTypes.Text,
56 120
       placeholder: '请输入电话号码',
57
-      value: ''
58
-      // rules: [
59
-      //   { message: '请输入电话号码'}
60
-      // ]
121
+      value: userData.phone,
61 122
     },
62 123
     {
63 124
       label: '标签',
64
-      name: 'staffTag',
65
-      render: 
66
-      <Tagss/>
67
-     
68
-   
125
+      name: 'taTags',
126
+      render: <Select
127
+                mode="multiple"
128
+                style={{ width: '100%' }}
129
+                placeholder="请选择标签"
130
+                onChange={tagsChange} >
131
+                  {tagData.map(item => (
132
+                    <Select.Option key={item.tagId} value={item.tagId}>
133
+                      {item.tagName}
134
+                    </Select.Option>
135
+                  ))}
136
+              </Select>,
137
+      value: userData.taTags,
69 138
     },
70 139
     {
71 140
       label: '地址',
72
-      name: 'staffAddress',
141
+      name: 'address',
73 142
       type: FieldTypes.Text,
74 143
       placeholder: '请输入地址',
75
-      value: ''
144
+      value: userData.address
76 145
 
77 146
     },
78 147
     {
79 148
       label: '授权项目',
80
-      name: 'staffProject',
81
-      type: FieldTypes.Select,
82
-      placeholder: '请选择',
83
-      value: ''
149
+      name: 'buildingId',
150
+      render: <BuildSelect />,
151
+      value: userData.buildingId,
152
+      rules: [
153
+        { required: true, message: '请选择所属项目' },
154
+      ],
84 155
     },
85
-
86
-    // {
87
-    //   label: '授权项目',
88
-    //   name: 'staffProject',
89
-    //   type: FieldTypes.Text,
90
-    //   placeholder: '请选择'
91
-    // },
92
-
93 156
     {
94 157
       label: '图片',
95
-      name: 'staffImage',
158
+      name: 'photo',
96 159
       type: FieldTypes.ImageUploader,
97 160
       extra: '建议图片大小 640 * 640',
98
-      value: ''
161
+      value: userData.photo
99 162
     },
100 163
 
101 164
 
102 165
     {
103 166
       label: '简介',
104
-      name: 'staffIntroduction',
167
+      name: 'description',
105 168
       render: <TextArea className={channels.inpuitTxt} ></TextArea>,
106
-      value: ''
169
+      value: userData.description
107 170
 
108 171
     },
109 172
     {
110 173
       label: '状态',
111
-      name: 'staffstate',
174
+      name: 'status',
112 175
       render: <Radio.Group>
113
-        <Radio.Button style={{background:'#f0f0f0'}} value="a">禁用</Radio.Button>
114
-        <Radio.Button style={{background:'#f0f0f0',color:'#ff7e48'}} value="b">启用</Radio.Button>
176
+        <Radio.Button style={{background:'#f0f0f0'}} value="0">禁用</Radio.Button>
177
+        <Radio.Button style={{background:'#f0f0f0',color:'#ff7e48'}} value="1">启用</Radio.Button>
115 178
       </Radio.Group>,
116
-      value: 'b'
179
+      value: null != userData.status ? userData.status : '1'
117 180
     },
118
-
119 181
   ]
120 182
 
121
-  const handleSubmit = val => {
122
-    window.console.log('submit data --->', val)
123
-  }
124
-  return <XForm onSubmit={handleSubmit} fields={fields} push={8}></XForm>
183
+  return <XForm onSubmit={handleSubmit} fields={fields}></XForm>
125 184
 
126 185
 
127 186
 

+ 0
- 1
src/pages/staff/list/style.less Прегледај датотеку

@@ -61,7 +61,6 @@
61 61
 }
62 62
 
63 63
 .cardTag {
64
-  width: 48px;
65 64
   height: 18px;
66 65
   font-size: 10px;
67 66
   // background: #fdce22;

+ 65
- 2
src/services/apis.js Прегледај датотеку

@@ -2,10 +2,14 @@ const prefix = '/api/admin'
2 2
 
3 3
 export default {
4 4
   image: {
5
-    upload: {
5
+    uploadForAnt: {
6 6
       url: `${prefix}/antd/image`,
7 7
       method: 'POST',
8
-    }
8
+    },
9
+    upload: {
10
+      url: `${prefix}/image`,
11
+      method: 'POST',
12
+    },
9 13
   },
10 14
   user: {
11 15
     current: {
@@ -16,6 +20,10 @@ export default {
16 20
       method: 'POST',
17 21
       url: `${prefix}/taUser/signin`,
18 22
     },
23
+    signout: {
24
+      method: 'POST',
25
+      url: `${prefix}/taUser/signout`,
26
+    },
19 27
   },
20 28
   building: {
21 29
     getList: {
@@ -30,6 +38,10 @@ export default {
30 38
       method: 'POST',
31 39
       url: `${prefix}/building/add`,
32 40
     },
41
+    updateBuilding: {
42
+      method: 'PUT',
43
+      url: `${prefix}/building/update`,
44
+    },
33 45
     buildingGetById: {
34 46
       method: 'GET',
35 47
       url: `${prefix}/buildingSelectId/id`,
@@ -141,4 +153,55 @@ export default {
141 153
       url: `${prefix}/customer/recommend/get/id`,
142 154
     },
143 155
   },
156
+  indexEcharts: {
157
+    userResource: {
158
+      method: 'GET',
159
+      url: `${prefix}/selectUserResource`
160
+    },
161
+
162
+  }
163
+  // indexEcharts:{
164
+  //   list:{
165
+  //     method:'get',
166
+  //     url: `${commPrefix}/indexStatistical`
167
+  //   },
168
+  //   userResource: {
169
+  //       method:'get',
170
+  //       url: `${commPrefix}/selectUserResource`
171
+  //   },
172
+  //   userConversion: {
173
+  //     method:'get',
174
+  //     url: `${commPrefix}/selectConversion`
175
+  //   },
176
+  //   userActive: {
177
+  //     method:'get',
178
+  //     url: `${commPrefix}/selectActiveUserCount`
179
+  //   },
180
+  //   newUser: {
181
+  //     method:'get',
182
+  //     url: `${commPrefix}/selectNewsUserCount`
183
+  //   },
184
+  //   userBehavior: {
185
+  //     summary: {
186
+  //       method:'get',
187
+  //       url: `${commPrefix}/selectUserBehavior`
188
+  //     },
189
+  //     profile: {
190
+  //       method:'get',
191
+  //       url: `${commPrefix}/selectEventAll`
192
+  //     },
193
+  //   },
194
+  //   intentionUsers: {
195
+  //     method:'get',
196
+  //     url: `${commPrefix}/selectIntentionUser`
197
+  //   },
198
+  //   userSex: {
199
+  //     method:'get',
200
+  //     url: `${commPrefix}/selectSexUser`
201
+  //   },
202
+  //   userCity: {
203
+  //     method:'get',
204
+  //     url: `${commPrefix}/selectCityUser`
205
+  //   },
206
+  // },
144 207
 }

+ 33
- 5
src/utils/upload.js Прегледај датотеку

@@ -1,11 +1,39 @@
1
-import apis from '../services/apis';
1
+import { fetch, apis } from './request';
2
+import mixStr from './mixStr';
3
+
4
+const getToken = () => mixStr(window.localStorage.getItem('test-foobar'))
5
+
6
+const uploadImage = fetch(apis.image.upload)
2 7
 
3 8
 const uploaderProps = {
4 9
   name: 'file',
5
-  action: apis.image.upload.url,
6
-  headers: {
7
-    Authorization: `Bearer ${window.localStorage.getItem('x-token')}`
8
-  }
10
+  // action: apis.image.uploadForAnt.url,
11
+  accept: '.png, .jpg, .jpeg, .gif',
12
+  // headers: {
13
+  //   Authorization: `Bearer ${getToken()}`
14
+  // },
15
+  customRequest({
16
+    action,
17
+    file,
18
+    headers,
19
+    onError,
20
+    onProgress,
21
+    onSuccess,
22
+    withCredentials,
23
+  }) {
24
+    const data = new FormData()
25
+    data.append('file', file)
26
+
27
+    uploadImage({ data }).then((img) => {
28
+      onSuccess(img, file);
29
+    }).catch(onError);
30
+
31
+    return {
32
+      abort() {
33
+        console.log('upload progress is aborted.');
34
+      },
35
+    };
36
+  },
9 37
 }
10 38
 
11 39
 export { uploaderProps }