zhoulisen 5 gadus atpakaļ
vecāks
revīzija
ed8f892ce8

+ 36
- 0
config/routes.js Parādīt failu

@@ -39,6 +39,30 @@ export default [
39 39
             hideInMenu: true,
40 40
             component: './channel/edit',
41 41
           },
42
+          {
43
+            path: '/contact',
44
+            name: '联系人管理',
45
+            component: '../layouts/BlankLayout',
46
+            routes: [
47
+              {
48
+                path: '/contact/contact/list',
49
+                name: '联系人',
50
+                component: './contact/contact/list',
51
+              },
52
+              {
53
+                path: '/contact/contact/add',
54
+                name: '新增',
55
+                hideInMenu: true,
56
+                component: './contact/contact/add',
57
+              },
58
+              {
59
+                path: '/contact/contact/detail',
60
+                name: '详情',
61
+                hideInMenu: true,
62
+                component: './contact/contact/detail',
63
+              },
64
+            ],
65
+          },
42 66
           {
43 67
             path: '/sample',
44 68
             name: 'H5样例管理',
@@ -49,11 +73,23 @@ export default [
49 73
                 name: 'H5样例',
50 74
                 component: './sample/h5/index',
51 75
               },
76
+              {
77
+                path: '/sample/h5/edit',
78
+                name: 'H5样例编辑',
79
+                hideInMenu: true,
80
+                component: './sample/h5/edit',
81
+              },
52 82
               {
53 83
                 path: '/sample/demand/list',
54 84
                 name: 'H5需求单',
55 85
                 component: './sample/demand/index',
56 86
               },
87
+              {
88
+                path: '/sample/demand/edit',
89
+                name: 'H5需求单详情',
90
+                hideInMenu: true,
91
+                component: './sample/demand/edit',
92
+              },
57 93
             ],
58 94
           },
59 95
           {

+ 2
- 1
package.json Parādīt failu

@@ -61,7 +61,8 @@
61 61
     "umi": "^2.8.7",
62 62
     "umi-plugin-pro-block": "^1.3.2",
63 63
     "umi-plugin-react": "^1.9.5",
64
-    "umi-request": "^1.0.8"
64
+    "umi-request": "^1.0.8",
65
+    "wangeditor": "^3.1.1"
65 66
   },
66 67
   "devDependencies": {
67 68
     "@ant-design/colors": "^3.1.0",

+ 108
- 0
src/components/Wangedit/Wangedit.jsx Parādīt failu

@@ -0,0 +1,108 @@
1
+import React from 'react';
2
+import E from 'wangeditor';
3
+import { fetch, apis } from '../../utils/request';
4
+
5
+/**
6
+ * @param {*} props
7
+ * @returns
8
+ */
9
+class Wangedit extends React.Component {
10
+  constructor(props, context) {
11
+    super(props, context);
12
+    this.state = {
13
+      html: undefined,
14
+      contenteditable: props.contenteditable == false ? false : true
15
+    }
16
+    this.editor = undefined;
17
+  }
18
+
19
+  render() {
20
+    return (
21
+      <div ref="editorElem" style={{ textAlign: 'left' }}>
22
+      </div>
23
+    );
24
+  }
25
+
26
+  componentDidMount() {
27
+    const elem = this.refs.editorElem
28
+    this.editor = new E(elem)
29
+    // 使用 onchange 函数监听内容的变化
30
+    this.editor.customConfig.onchange = html => {
31
+      this.setState({ html })
32
+
33
+      if (typeof this.props.onChange === 'function') {
34
+        this.props.onChange(html)
35
+      }
36
+    }
37
+    this.editor.customConfig.zIndex = 100
38
+    this.editor.customConfig.uploadImgMaxLength = 1
39
+    this.editor.customConfig.customUploadImg = function (files, insert) {
40
+      if (!files.length) return
41
+      
42
+      const data = new FormData()
43
+      data.append('file', files[0])
44
+
45
+      fetch(apis.image.upload)({data}).then(insert)
46
+    }
47
+    this.editor.customConfig.menus = [
48
+      'head',  // 标题
49
+      'bold',  // 粗体
50
+      'fontSize',  // 字号
51
+      'fontName',  // 字体
52
+      'italic',  // 斜体
53
+      'underline',  // 下划线
54
+      'strikeThrough',  // 删除线
55
+      'foreColor',  // 文字颜色
56
+      'backColor',  // 背景颜色
57
+      'list',  // 列表
58
+      'justify',  // 对齐方式
59
+      'quote',  // 引用
60
+      'image',  // 插入图片
61
+      'undo',  // 撤销
62
+      'redo'  // 重复
63
+    ]
64
+    
65
+    // 过滤 word 字符
66
+    this.editor.customConfig.pasteFilterStyle = false
67
+    this.editor.customConfig.pasteTextHandle = function(content) {
68
+      const regs = [
69
+        /<!--\[if [\s\S]*?endif\]-->/ig,
70
+        /<[a-zA-Z0-9]+\:[^>]+>[^>]*<\/[a-zA-Z0-9]+\:[^>]+>/ig,
71
+        /<[a-zA-Z0-9]+\:[^>]+\/>/ig,
72
+        /<style>[\s\S]*?<\/style>/ig,
73
+      ]
74
+
75
+      return regs.reduce((acc, reg) => {
76
+        return acc.replace(reg, '')
77
+      }, content)
78
+    }
79
+
80
+    this.editor.create()
81
+    this.editor.$textElem.attr('contenteditable',this.state.contenteditable);
82
+    this.editor.customConfig.uploadImgShowBase64 = true
83
+    this.editor.txt.html(this.props.value)
84
+  }
85
+
86
+  componentDidUpdate(props, state) {
87
+    if (this.props.value && !state.html) {
88
+      if (this.editor) {
89
+        this.editor.txt.html(this.props.value)
90
+      }
91
+    }
92
+  }
93
+
94
+  /**
95
+   *增加这个 shouldComponentUpdate 生命函数
96
+    处理自动聚焦到富文本上
97
+   *
98
+   * @param {*} nextProps
99
+   * @returns
100
+   * @memberof Wangedit
101
+   */
102
+  shouldComponentUpdate(nextProps) {
103
+    return nextProps.value !== this.editor.txt.html()
104
+  }
105
+}
106
+
107
+export default Wangedit
108
+

+ 205
- 0
src/pages/contact/contact/add.jsx Parādīt failu

@@ -0,0 +1,205 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Input, Modal, Menu, Dropdown, Button, Icon, message, Table, Divider, Tag, Select, Form, Alert } from 'antd';
3
+import { FormattedMessage } from 'umi-plugin-react/locale';
4
+import XForm, { FieldTypes } from '../../../components/XForm';
5
+import router from 'umi/router';
6
+import apis from '../../../services/apis';
7
+import request from '../../../utils/request';
8
+import moment from 'moment';
9
+
10
+
11
+
12
+const header = props => {
13
+
14
+    const [data, setData] = useState({})
15
+
16
+    const [datas, setDatas] = useState([])//表格数据
17
+    const [visible, setVisible] = useState()
18
+    const [formsdate, setFormsDate] = useState({})
19
+    //   const [page, changePage] = useState({})
20
+    useEffect(() => {
21
+
22
+        setVisible(false)
23
+
24
+    }, [])
25
+    const ModalData = props => {
26
+
27
+        const data = [];
28
+        return (
29
+            <>
30
+                <div>
31
+                </div>
32
+            </>
33
+        )
34
+    }
35
+
36
+    const onSelectBusiness = (e) => {
37
+        console.log('11111')
38
+
39
+    }
40
+
41
+    const fields = [
42
+        {
43
+            label: '姓名',
44
+            name: 'contactName',
45
+            type: FieldTypes.Text,
46
+            value: data.contactName,
47
+            rules: [
48
+                { required: true, message: '请输入通知标题' },
49
+                { max: 6, message: '通知标题名称不超过6个字符' }
50
+            ]
51
+        },
52
+        {
53
+            label: '性别',
54
+            name: 'sex',
55
+            type: FieldTypes.Select,
56
+            value: data.sex,
57
+            dict: [{
58
+                name: '男',
59
+                value: '1',
60
+            },
61
+            {
62
+                name: '女',
63
+                value: '2',
64
+            }],
65
+            rules: [
66
+                { required: false, message: '请选择性别' }
67
+            ]
68
+        },
69
+        {
70
+            label: '头像',
71
+            name: 'avatar',
72
+            type: FieldTypes.ImageUploader,
73
+            value: data.avatar,
74
+            rules: [
75
+                { required: false, message: '请选择头像' },
76
+            ],
77
+            help: '建议尺寸:Npx*Npx,比例:1:1,格式:jpg,大小:不超过300KB,用于客户查看',
78
+        },
79
+        {
80
+            label: '对外头衔',
81
+            name: 'appellation',
82
+            type: FieldTypes.Text,
83
+            value: data.appellation,
84
+            rules: [
85
+                { required: false, message: '请输入对外头衔' },
86
+                { max: 20, message: '对外头衔不能超过20个字符' }
87
+            ]
88
+        },
89
+        {
90
+            label: '固话',
91
+            name: 'telephone',
92
+            type: FieldTypes.Text,
93
+            value: data.telephone,
94
+            rules: [
95
+                { required: false, message: '请输入固话' },
96
+                { max: 20, message: '固话内容不能超过20个字符' }
97
+            ]
98
+        },
99
+        {
100
+            label: '手机号',
101
+            name: 'phone',
102
+            type: FieldTypes.Text,
103
+            value: data.phone,
104
+            rules: [
105
+                { required: true, message: '请输入手机号' },
106
+                // { max: 20, message: '' }
107
+            ]
108
+        },
109
+        {
110
+            label: '微信号',
111
+            name: 'wxCardImg',
112
+            type: FieldTypes.ImageUploader,
113
+            value: data.wxCardImg,
114
+            rules: [
115
+                { required: false, message: '请上传微信号' },
116
+            ],
117
+            help: '联系人的微信二维码名片,请到手机端微信-我-顶部微信号中保存后上传',
118
+        },
119
+        {
120
+            label: '邮箱',
121
+            name: 'mail',
122
+            type: FieldTypes.Text,
123
+            value: data.mail,
124
+            rules: [
125
+                { required: false, message: '请输入邮箱' },
126
+                { max: 20, message: '邮箱不能超过20个字符' }
127
+            ]
128
+        },
129
+        {
130
+            label: '联系地址*',
131
+            name: 'address',
132
+            type: FieldTypes.Text,
133
+            value: data.address,
134
+            rules: [
135
+                { required: false, message: '请输入联系地址' },
136
+                { max: 40, message: '邮箱不能超过40个字符' }
137
+            ]
138
+        },
139
+        {
140
+            label: '内部岗位*',
141
+            name: 'job',
142
+            type: FieldTypes.Text,
143
+            value: data.job,
144
+            rules: [
145
+                { required: false, message: '请输入内部岗位' },
146
+                { max: 20, message: '内部岗位不能超过20个字符' }
147
+            ]
148
+        },
149
+        {
150
+            label: '权重',
151
+            name: 'orderNo',
152
+            type: FieldTypes.Number,
153
+            value: data.orderNo,
154
+
155
+            help: '用于列表排序,越大越靠前'
156
+        },
157
+    ]
158
+
159
+    const handleSubmit = (values) => {
160
+        console.log | ("开始提交 联系人")
161
+        let submitValues = values;
162
+        props.form.validateFields((err, values) => {
163
+            console.log(values)
164
+            if (!err) {
165
+                request({ ...apis.contact.taContactAdd, data: { ...submitValues }, }).then((data) => {
166
+                    //   message.info("保存成功,请上传房源")
167
+                    router.push({
168
+                        pathname: '/contact/contact/list',
169
+                        query: {
170
+                            //   salesBatchId: data.salesBatchId,
171
+                            //   buildingId: data.buildingId,
172
+                        },
173
+                    });
174
+                }).catch((err) => {
175
+                    message.info(err.msg || err.message)
176
+                })
177
+            }
178
+        });
179
+    }
180
+    //model
181
+    const handleShowModel = val => {
182
+        setVisible(true);
183
+    }
184
+
185
+    const handleCancel = val => {
186
+        setVisible(false);
187
+    }
188
+
189
+    const cancelPage = () => {
190
+        router.push({
191
+            pathname: '/contact/pathname',
192
+        });
193
+    }
194
+
195
+    return (
196
+        <>
197
+            <div>
198
+                <XForm onSubmit={handleSubmit} onCancel={cancelPage} fields={fields}></XForm>
199
+            </div>
200
+        </>
201
+    )
202
+}
203
+
204
+const WrappedNormalLoginForm = Form.create({ name: 'header' })(header);
205
+export default WrappedNormalLoginForm

+ 211
- 0
src/pages/contact/contact/detail.jsx Parādīt failu

@@ -0,0 +1,211 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Input, Modal, Menu, Dropdown, Button, Icon, message, Table, Divider, Tag, Select, Form, Alert } from 'antd';
3
+import { FormattedMessage } from 'umi-plugin-react/locale';
4
+import XForm, { FieldTypes } from '../../../components/XForm';
5
+import router from 'umi/router';
6
+import apis from '../../../services/apis';
7
+import request from '../../../utils/request';
8
+import moment from 'moment';
9
+
10
+
11
+
12
+const header = props => {
13
+    const [data, setData] = useState({})
14
+    const contactId = props.location.query.id
15
+    if (contactId) {
16
+        useEffect(() => {
17
+            getData(contactId);
18
+        }, [])
19
+
20
+        // 查询列表
21
+        const getData = (contactId) => {
22
+            request({
23
+                ...apis.contact.taContactGet,
24
+                urlData: { id: contactId }
25
+            }).then((data) => {
26
+                setData(data)
27
+            }).catch((err) => {
28
+                message.error(err.msg || err.message)
29
+            })
30
+        }
31
+    }
32
+
33
+    const [datas, setDatas] = useState([])//表格数据
34
+    const [visible, setVisible] = useState()
35
+    const [formsdate, setFormsDate] = useState({})
36
+    //   const [page, changePage] = useState({})
37
+    useEffect(() => {
38
+
39
+        setVisible(false)
40
+
41
+    }, [])
42
+    const ModalData = props => {
43
+
44
+        const data = [];
45
+        return (
46
+            <>
47
+                <div>
48
+                </div>
49
+            </>
50
+        )
51
+    }
52
+
53
+    const onSelectBusiness = (e) => {
54
+        console.log('11111')
55
+
56
+    }
57
+
58
+    const fields = [
59
+        {
60
+            label: '姓名',
61
+            name: 'contactName',
62
+            type: FieldTypes.Text,
63
+            value: data.contactName,
64
+            rules: [
65
+                { required: true, message: '请输入通知标题' },
66
+                { max: 6, message: '通知标题名称不超过6个字符' }
67
+            ]
68
+        },
69
+        {
70
+            label: '性别',
71
+            name: 'sex',
72
+            type: FieldTypes.Select,
73
+            value: data.sex === 1 ? '男' : '女',
74
+            dict: [{
75
+                name: '男',
76
+                value: '1',
77
+            },
78
+            {
79
+                name: '女',
80
+                value: '2',
81
+            }],
82
+            rules: [
83
+                { required: false, message: '请选择性别' }
84
+            ]
85
+        },
86
+        {
87
+            label: '头像',
88
+            name: 'avatar',
89
+            type: FieldTypes.ImageUploader,
90
+            value: data.avatar,
91
+            rules: [
92
+                { required: false, message: '请选择头像' },
93
+            ],
94
+            help: '建议尺寸:Npx*Npx,比例:1:1,格式:jpg,大小:不超过300KB,用于客户查看',
95
+        },
96
+        {
97
+            label: '对外头衔',
98
+            name: 'appellation',
99
+            type: FieldTypes.Text,
100
+            value: data.appellation,
101
+            rules: [
102
+                { required: false, message: '请输入对外头衔' },
103
+                { max: 20, message: '对外头衔不能超过20个字符' }
104
+            ]
105
+        },
106
+        {
107
+            label: '固话',
108
+            name: 'telephone',
109
+            type: FieldTypes.Text,
110
+            value: data.telephone,
111
+            rules: [
112
+                { required: false, message: '请输入固话' },
113
+                { max: 20, message: '固话内容不能超过20个字符' }
114
+            ]
115
+        },
116
+        {
117
+            label: '手机号',
118
+            name: 'phone',
119
+            type: FieldTypes.Text,
120
+            value: data.phone,
121
+            rules: [
122
+                { required: true, message: '请输入手机号' },
123
+                // { max: 20, message: '' }
124
+            ]
125
+        },
126
+        {
127
+            label: '微信号',
128
+            name: 'wxCardImg',
129
+            type: FieldTypes.ImageUploader,
130
+            value: data.wxCardImg,
131
+            rules: [
132
+                { required: false, message: '请上传微信号' },
133
+            ],
134
+            help: '联系人的微信二维码名片,请到手机端微信-我-顶部微信号中保存后上传',
135
+        },
136
+        {
137
+            label: '邮箱',
138
+            name: 'mail',
139
+            type: FieldTypes.Text,
140
+            value: data.mail,
141
+            rules: [
142
+                { required: false, message: '请输入邮箱' },
143
+                { max: 20, message: '邮箱不能超过20个字符' }
144
+            ]
145
+        },
146
+        {
147
+            label: '联系地址*',
148
+            name: 'address',
149
+            type: FieldTypes.Text,
150
+            value: data.address,
151
+            rules: [
152
+                { required: false, message: '请输入联系地址' },
153
+                { max: 40, message: '邮箱不能超过40个字符' }
154
+            ]
155
+        },
156
+        {
157
+            label: '内部岗位*',
158
+            name: 'job',
159
+            type: FieldTypes.Text,
160
+            value: data.job,
161
+            rules: [
162
+                { required: false, message: '请输入内部岗位' },
163
+                { max: 20, message: '内部岗位不能超过20个字符' }
164
+            ]
165
+        },
166
+        {
167
+            label: '权重',
168
+            name: 'orderNo',
169
+            type: FieldTypes.Number,
170
+            value: data.orderNo,
171
+
172
+            help: '用于列表排序,越大越靠前'
173
+        },
174
+    ]
175
+
176
+    const handleSubmit = (values) => {
177
+        if (contactId) {
178
+            values.contactId = contactId
179
+            request({ ...apis.contact.taContactUpdate, urlData: { id: contactId }, data: { ...values } }).then((data) => {
180
+                cancelPage();
181
+            }).catch((err) => {
182
+                message.error(err.msg || err.message)
183
+            })
184
+        }
185
+    }
186
+    //model
187
+    const handleShowModel = val => {
188
+        setVisible(true);
189
+    }
190
+
191
+    const handleCancel = val => {
192
+        setVisible(false);
193
+    }
194
+
195
+    const cancelPage = () => {
196
+        router.push({
197
+            pathname: '/contact/contact/list',
198
+        });
199
+    }
200
+
201
+    return (
202
+        <>
203
+            <div>
204
+                <XForm onSubmit={handleSubmit} onCancel={cancelPage} fields={fields}></XForm>
205
+            </div>
206
+        </>
207
+    )
208
+}
209
+
210
+const WrappedNormalLoginForm = Form.create({ name: 'header' })(header);
211
+export default WrappedNormalLoginForm

+ 220
- 0
src/pages/contact/contact/list.jsx Parādīt failu

@@ -0,0 +1,220 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { PageHeaderWrapper } from '@ant-design/pro-layout';
3
+import { Form, Input, Button, Icon, Select, message, Table, Divider, Tag, Pagination, Modal, Breadcrumb } from 'antd';
4
+import router from 'umi/router';
5
+import moment from 'moment';
6
+import styles from './style.less';
7
+import { fetch, apis } from '../../../utils/request';
8
+import request from '../../../utils/request';
9
+import AuthButton from '@/components/AuthButton';
10
+
11
+function header(props) {
12
+
13
+    const [data, setData] = useState([])
14
+    const [contactList, setContactList] = useState([])
15
+
16
+    useEffect(() => {
17
+        getList({ pageNum: 1, pageSize: 10 });
18
+    }, [])
19
+    // 查询列表
20
+    const getList = params => {
21
+        request({ ...apis.contact.listContactByCondition, params: { ...params } }).then(data => {
22
+            console.log(data)
23
+            setData(data)
24
+        })
25
+    }
26
+
27
+    const toAdd = (id) => () => {
28
+        router.push({
29
+            pathname: '/contact/contact/add',
30
+            //   query: {
31
+            //     id
32
+            //   },
33
+        });
34
+    }
35
+
36
+    const toEdit = (id) => () => {
37
+        router.push({
38
+            pathname: '/contact/contact/detail',
39
+            query: {
40
+                id
41
+            },
42
+        });
43
+    }
44
+
45
+    const handleSubmit = (e, props) => {
46
+        console.log(e)
47
+        e.preventDefault();
48
+        props.form.validateFields((err, values) => {
49
+            if (!err) {
50
+                getList({ pageNum: 1, pageSize: 10, ...values })
51
+            }
52
+        });
53
+    }
54
+
55
+    function handleReset() {
56
+        props.form.resetFields();
57
+        getList({ pageNum: 1, pageSize: 10 });
58
+    }
59
+
60
+    const toDel = rowData => () => {
61
+        if (contactList.length < 1) {
62
+            openNotificationWithIcon('error', '请先选择需要删除的联系人')
63
+            return
64
+        }
65
+
66
+        Modal.confirm({
67
+            title: '确定联系人信息吗',
68
+            okText: '确定',
69
+            cancelText: '取消',
70
+            onOk() {
71
+                request({ ...apis.contact.batchDeleteContact, data: contactList, }).then((data) => {
72
+                    message.info("操作成功")
73
+                    getList({ pageNum: 1, pageSize: 10 });
74
+                }).catch((err) => {
75
+                    
76
+                })
77
+            },
78
+        });
79
+    }
80
+
81
+    const rowSelection = {
82
+        onChange: (selectedRowKeys, selectedRows) => {
83
+            console.log('selectedRowKeys:', selectedRowKeys, 'selectedRows: ', selectedRows);
84
+            setContactList(selectedRows)
85
+        },
86
+    };
87
+
88
+    const changePageNum = pageNumber => {
89
+        getList({ pageNum: pageNumber, pageSize: 10, ...props.form.getFieldsValue() })
90
+    }
91
+
92
+    const columns = [
93
+        {
94
+            title: '姓名',
95
+            dataIndex: 'contactName',
96
+            key: 'contactName',
97
+            align: 'center',
98
+
99
+        },
100
+        {
101
+            title: '性别',
102
+            dataIndex: 'sex',
103
+            key: 'sex',
104
+            align: 'center',
105
+            render: (sex) => <span>{sex === 1 ? '男' : '女'}</span>,
106
+        },
107
+        {
108
+            title: '头像',
109
+            dataIndex: 'avatar',
110
+            key: 'avatar',
111
+            align: 'center',
112
+            render: (text, record) => <img src={record.avatar} className={styles.touxiang} />,
113
+        },
114
+        {
115
+            title: '固话',
116
+            dataIndex: 'telephone',
117
+            key: 'telephone',
118
+            align: 'center',
119
+        },
120
+        {
121
+            title: '手机号',
122
+            dataIndex: 'phone',
123
+            key: 'phone',
124
+            align: 'center',
125
+        },
126
+        {
127
+            title: '内部岗位',
128
+            dataIndex: 'job',
129
+            key: 'job',
130
+            align: 'center',
131
+
132
+        },
133
+        {
134
+            title: '权重',
135
+            dataIndex: 'orderNo',
136
+            key: 'orderNo',
137
+            align: 'center',
138
+        },
139
+        {
140
+            title: '操作',
141
+            dataIndex: 'handle',
142
+            key: 'handle',
143
+            align: 'center',
144
+            render: (x, row) => (
145
+                <>
146
+                    <span style={{ color: '#FF925C', cursor: 'pointer' }} onClick={toEdit(row.contactId)}>
147
+                        编辑<Icon type="form" className={styles.edit} />
148
+                    </span>
149
+                </>
150
+            ),
151
+        },
152
+    ];
153
+
154
+    const { getFieldDecorator } = props.form
155
+    return (
156
+
157
+        <>
158
+            <div>
159
+                <Form layout="inline" onSubmit={e => handleSubmit(e, props)}>
160
+                    <Form.Item>
161
+                        {getFieldDecorator('contactName')(
162
+                            <Input
163
+                                prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
164
+                                placeholder="姓名"
165
+                            />,
166
+                        )}
167
+                    </Form.Item>
168
+                    <Form.Item>
169
+                        {getFieldDecorator('telephone')(
170
+                            <Input style={{ width: '180px' }} placeholder="固话">
171
+
172
+                            </Input>,
173
+                        )}
174
+                    </Form.Item>
175
+
176
+                    <Form.Item>
177
+                        {getFieldDecorator('phone')(
178
+                            <Input
179
+                                prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
180
+                                placeholder="手机号"
181
+                            />,
182
+                        )}
183
+                    </Form.Item>
184
+                    <Form.Item>
185
+                        {getFieldDecorator('job')(
186
+                            <Input
187
+                                prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
188
+                                placeholder="内部岗位"
189
+                            />,
190
+                        )}
191
+                    </Form.Item>
192
+                    <Form.Item>
193
+
194
+                        <Button type="primary" htmlType="submit" className={styles.searchBtn}>
195
+                            搜索
196
+              </Button>
197
+                        {/*  */}
198
+                        <Button style={{ marginLeft: 8 }} onClick={handleReset}>
199
+                            重置
200
+            </Button>
201
+                    </Form.Item>
202
+                </Form>
203
+
204
+                <Button type="danger" className={styles.addBtn} onClick={toAdd()}>新增</Button>
205
+
206
+                <Button type="primary" className={styles.addBtn} onClick={toDel()} style={{ marginLeft: '30px' }} >删除</Button>
207
+
208
+                <Table rowSelection={rowSelection} rowKey="goodsList" dataSource={data.records} columns={columns} pagination={false} />
209
+
210
+                <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '30px' }}>
211
+                    {<Pagination showQuickJumper defaultCurrent={1} total={data.total} onChange={e => changePageNum(e)} current={data.current} />}
212
+                </div>
213
+            </div>
214
+        </>
215
+    )
216
+}
217
+
218
+const WrappedHeader = Form.create({ name: 'header' })(header);
219
+
220
+export default WrappedHeader

+ 48
- 0
src/pages/contact/contact/style.less Parādīt failu

@@ -0,0 +1,48 @@
1
+.addBtn {
2
+    padding: 0 40px;
3
+    height: 36px;
4
+    margin: 30px 0;
5
+  }
6
+  
7
+  .touxiang {
8
+    width: 93px;
9
+    height: 93px;
10
+  }
11
+  
12
+  .imgPerfect {
13
+    width: 120px;
14
+    height: 40px;
15
+  }
16
+  
17
+  .imgIndex {
18
+    width: 150px;
19
+    height: 92.7px;
20
+  }
21
+  
22
+  .imgSmall {
23
+    width: 128px;
24
+    height: 192px;
25
+  }
26
+  
27
+  .propaganda {
28
+    width: 240px;
29
+    height: 60px;
30
+  }
31
+  
32
+  .ant-table-column-title {
33
+    font-weight: 600;
34
+  }
35
+  
36
+  .shoppingCart {
37
+    // color: #dcdcdc;
38
+    color: #bebebe;
39
+    margin-left: 6px;
40
+    font-size: 16px;
41
+  }
42
+  
43
+  .edit {
44
+    // color: #dcdcdc;
45
+    color: #bebebe;
46
+    margin-left: 6px;
47
+    font-size: 15px;
48
+  }

+ 1
- 1
src/pages/resource/openScreen/index.jsx Parādīt failu

@@ -109,7 +109,7 @@ function header(props) {
109 109
             dataIndex: 'status',
110 110
             key: 'status',
111 111
             align: 'center',
112
-            render: (status) => <><span>{status == 1 ? '是' : '否'}</span></>
112
+            render: (status) => <><span>{status === 1 ? '已上架' : status === 0 ? '已下架':'删除'}</span></>
113 113
         },
114 114
         {
115 115
             title: '自动下架时间',

+ 113
- 0
src/pages/sample/demand/edit.jsx Parādīt failu

@@ -0,0 +1,113 @@
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 XForm, { FieldTypes } from '../../../components/XForm';
5
+import router from 'umi/router';
6
+import apis from '../../../services/apis';
7
+import request from '../../../utils/request';
8
+import Wangedit from '../../../components/Wangedit/Wangedit'
9
+import moment from 'moment';
10
+
11
+
12
+const header = props => {
13
+    const demandId = props.location.query.id
14
+  
15
+    const [ data, setData ] = useState({})
16
+    if(demandId){
17
+      useEffect(() => {
18
+        getDemandData(demandId);
19
+      },[])
20
+  
21
+    // 查询列表
22
+    const getDemandData = (demandId) => {
23
+      request({
24
+          ...apis.sample.get,
25
+          urlData: { id: demandId }
26
+      }).then((data) => {
27
+        setData(data)
28
+      }).catch((err) => {
29
+        message.error(err.msg || err.message)
30
+      })
31
+    }
32
+    }
33
+  
34
+    const fields = [
35
+      {
36
+        label: '样例名',
37
+        name: 'sampleName',
38
+        type: FieldTypes.Text,
39
+        value: data.sampleName,
40
+      },    
41
+      {
42
+        label: '下单组织',
43
+        name: 'orgName',
44
+        type: FieldTypes.Text,
45
+        value: data.orgName,
46
+      },
47
+      {
48
+        label: '下单人',
49
+        name: 'orderer',
50
+        value: data.orderer,
51
+        type: FieldTypes.Text,
52
+      },
53
+      {
54
+        label: '联系方式',
55
+        name: 'phone',
56
+        value: data.phone,
57
+        type: FieldTypes.Text,
58
+      },
59
+      {
60
+        label: '下单时间',
61
+        name: 'createDate',
62
+        type: FieldTypes.DatePicker ,
63
+        value: data.createDate != null ? moment(data.createDate, 'YYYY-MM-DD') : null,
64
+      },
65
+      {
66
+        label: '需求单状态',
67
+        name: 'demandStatus',
68
+        value: data.demandStatus+'',
69
+        render: <Select style={{ width: '180px' }} placeholder="需求单状态">
70
+                  <Select.Option value="1">已提交</Select.Option>
71
+                  <Select.Option value="2">处理中</Select.Option>
72
+                  <Select.Option value="3">已交付</Select.Option>
73
+                  <Select.Option value="4">作废</Select.Option>
74
+                </Select>,
75
+      },
76
+      {
77
+        label: '备注',
78
+        name: 'remark',
79
+        type: FieldTypes.Text,
80
+        value: data.remark,
81
+      },
82
+      {
83
+        label: '需求描述',
84
+        name: 'demandContent',
85
+        value: data.demandContent,
86
+        render: <Wangedit />
87
+      },
88
+    ]
89
+  
90
+     
91
+    const handleSubmit = (values) => {
92
+      if(demandId){
93
+          request({ ...apis.sample.update, urlData: { id: demandId }, data: { ...values }}).then((data) => {
94
+            cancelPage();
95
+          }).catch((err) => {
96
+            message.error(err.msg || err.message)
97
+          })
98
+        }
99
+    }
100
+  
101
+    const cancelPage = () => {
102
+      router.push({
103
+        pathname: '/sample/demand/list',
104
+      });
105
+    }
106
+  
107
+    return (
108
+      <XForm onSubmit={handleSubmit} onCancel={cancelPage} fields={fields}></XForm>
109
+    )
110
+  }
111
+  
112
+  const WrappedNormalLoginForm = Form.create({ name: 'header' })(header);
113
+  export default WrappedNormalLoginForm

+ 120
- 62
src/pages/sample/demand/index.jsx Parādīt failu

@@ -1,6 +1,6 @@
1 1
 import React, { useState, useEffect } from 'react';
2 2
 import { PageHeaderWrapper } from '@ant-design/pro-layout';
3
-import { Form, Pagination, Card, Button, Icon, Tooltip, message,   notification, Modal, Table } from 'antd';
3
+import { Form, Pagination, Card, Button, Icon, Tooltip, message,   notification, Modal, Table, Select, Input, DatePicker } from 'antd';
4 4
 import router from 'umi/router';
5 5
 import moment from 'moment';
6 6
 import className from 'classnames';
@@ -10,11 +10,12 @@ import { fetch, apis } from '../../../utils/request';
10 10
 import request from '../../../utils/request';
11 11
 import AuthButton from '@/components/AuthButton';
12 12
 
13
-
13
+const { MonthPicker, RangePicker, WeekPicker } = DatePicker;
14 14
 
15 15
 function header(props) {
16 16
   // 获取初始化数据
17 17
   const [ data, setData ] = useState({})
18
+  const [demandIdList, setDemandIdList] = useState([])
18 19
 
19 20
   useEffect(() => {
20 21
     getList({ pageNum: 1, pageSize: 10 });
@@ -22,7 +23,7 @@ function header(props) {
22 23
 
23 24
   // 查询列表
24 25
   const getList = (params) => {
25
-    request({ ...apis.channel.list, params: { ...params } }).then((data) => {
26
+    request({ ...apis.sample.list, params: { ...params } }).then((data) => {
26 27
         console.log(data)
27 28
         setData(data)
28 29
     })
@@ -34,7 +35,16 @@ function header(props) {
34 35
     e.preventDefault();
35 36
     props.form.validateFields((err, values) => {
36 37
       if (!err) {
37
-        getList({ pageNum: 1, pageSize: 10, ...values })
38
+        let {createDate, ...submitValue} = values
39
+        if(null != createDate && createDate.length > 0){
40
+          const [startCreateDate, endCreateDate] = createDate
41
+          submitValue.startCreateDate = moment(startCreateDate).format('YYYY-MM-DD');
42
+          submitValue.endCreateDate = moment(endCreateDate).format('YYYY-MM-DD');
43
+        }else{
44
+          submitValue.startCreateDate = null
45
+          submitValue.endCreateDate = null
46
+        }
47
+        getList({ pageNum: 1, pageSize: 10, ...submitValue })
38 48
       }
39 49
     });
40 50
   }
@@ -43,11 +53,18 @@ function header(props) {
43 53
     getList({ pageNum: pageNumber, pageSize: 10 })
44 54
   }
45 55
 
56
+  const rowSelection = {
57
+    onChange: (selectedRowKeys, selectedRows) => {
58
+      console.log('selectedRowKeys:', selectedRowKeys, 'selectedRows: ', selectedRows);
59
+      setDemandIdList(selectedRows)
60
+    },
61
+  };
62
+
46 63
 
47 64
   // 跳转到编辑资讯
48
-  const toEditNews = (id) => () => {
65
+  const toEditDemand = (id) => () => {
49 66
     router.push({
50
-      pathname: '/channel/edit',
67
+      pathname: '/sample/demand/edit',
51 68
       query: {
52 69
         id
53 70
       },
@@ -55,31 +72,25 @@ function header(props) {
55 72
   }
56 73
 
57 74
   
58
-  const changeNewsStatus = (row, newsId) => () => {
59
-    const title = row.status === 0 ? '确定启用吗': '停用后,此账号将无法登录渠道代理商后台'
75
+  const changeStatus = () => {
76
+    if(demandIdList.length < 1){
77
+      message.error('请先选择要删除的数据!')
78
+      return
79
+    }
80
+    const title = '确认将所选的' + demandIdList.length + '条数据删除?可删除条件:需求单阶段 为 作废。'
60 81
     Modal.confirm({
61 82
       title: title,
62 83
       okText: '确认',
63 84
       cancelText: '取消',
64 85
       onOk() {
65
-        if(row.status === 0){
66
-          request({ ...apis.channel.put, urlData: { id: newsId }, data: { ...row, status: 1 } }).then((data) => {
67
-            message.info('操作成功!')
68
-            getList({ pageNum: 1, pageSize: 10 });
69
-          }).catch((err) => {
70
-            console.log(err)
71
-            message.info(err.msg || err.message)
72
-          })
73
-        }else{
74
-          request({ ...apis.channel.put, urlData: { id: newsId }, data: { ...row, status: 0 } }).then((data) => {
75
-            message.info('操作成功!')
76
-            getList({ pageNum: 1, pageSize: 10 });
77
-          }).catch((err) => {
78
-            console.log(err)
79
-            message.info(err.msg || err.message)
80
-          })
81
-        }
82
-        
86
+        request({ ...apis.sample.put, data: { ids: demandIdList.map(x => x.demandId) } }).then((data) => {
87
+          const resultMessage = '操作成功,其中'+data.successNum+'条成功删除,'+data.failNum+'条非作废状态未删除。'
88
+          message.info(resultMessage)
89
+          getList({ pageNum: 1, pageSize: 10 });
90
+        }).catch((err) => {
91
+          console.log(err)
92
+          message.info(err.msg || err.message)
93
+        })
83 94
       }
84 95
     });
85 96
   }
@@ -91,45 +102,43 @@ function header(props) {
91 102
    */
92 103
   const columns = [
93 104
     {
94
-      title: '渠道代理',
95
-      dataIndex: 'channelProxyName',
96
-      key: 'channelProxyName',
105
+      title: '样例名',
106
+      dataIndex: 'sampleName',
107
+      key: 'sampleName',
97 108
       align: 'center',
98 109
     },
99 110
     {
100
-      title: '账号名',
101
-      dataIndex: 'userName',
102
-      key: 'userName',
111
+      title: '下单组织',
112
+      dataIndex: 'orgName',
113
+      key: 'orgName',
103 114
       align: 'center',
104
-      render: (x, row) => <span>{row.userName === null || row.userName === '' ? row.channelTel : row.userName}</span>,
105 115
     },
106 116
     {
107
-      title: '小程序总数',
108
-      dataIndex: 'appMaxNum',
109
-      key: 'appMaxNum',
117
+      title: '下单人',
118
+      dataIndex: 'orderer',
119
+      key: 'orderer',
110 120
       align: 'center',
111 121
 
112 122
     },
113 123
     {
114
-      title: '现有小程序',
115
-      dataIndex: 'appCurrentNum',
116
-      key: 'appCurrentNum',
124
+      title: '联系方式',
125
+      dataIndex: 'phone',
126
+      key: 'phone',
117 127
       align: 'center',
118
-      render: (appCurrentNum) => <span>{appCurrentNum === 0 || appCurrentNum == null ? 0 : appCurrentNum}</span>,
119 128
     },
120 129
     {
121
-      title: '服务到期时间',
122
-      dataIndex: 'expireDate',
123
-      key: 'expireDate',
130
+      title: '下单时间',
131
+      dataIndex: 'createDate',
132
+      key: 'createDate',
124 133
       align: 'center',
125
-      render: (x, row) => <><span>{`${moment(row.expireDate).format('YYYY-MM-DD')}`}</span></>,
134
+      render: (x, row) => <><span>{`${moment(row.createDate).format('YYYY-MM-DD')}`}</span></>,
126 135
     },
127 136
     {
128
-      title: '状态',
129
-      dataIndex: 'status',
130
-      key: 'status',
137
+      title: '需求单状态',
138
+      dataIndex: 'demandStatus',
139
+      key: 'demandStatus',
131 140
       align: 'center',
132
-      render: (status) => <span>{status === 1 ? '启动' : '停用'}</span>,
141
+      render: (demandStatus) => <span>{demandStatus === 1 ? '已提交' : demandStatus === 2 ? '处理中' : demandStatus === 3 ? '已交付' : demandStatus === 4 ? '作废' : ''}</span>,
133 142
     },
134 143
     {
135 144
       title: '操作',
@@ -137,18 +146,9 @@ function header(props) {
137 146
       key: 'handle',
138 147
       align: 'center',
139 148
       render: (x, row) => (
140
-        <>
141
-          <AuthButton name="admin.taNewsType.id.delete" noRight={null}>
142
-            <span style={{ color: '#EF273A', marginRight: '20px', cursor: 'pointer' }} onClick={changeNewsStatus(row, row.channelId)}>
143
-              {row.status == 1 ? '停用' : '启用'}<Icon type="shopping-cart" className={styles.shoppingCart} />
144
-            </span>
145
-          </AuthButton>
146
-          <AuthButton name="admin.taNewsType.id.put" noRight={null}>
147
-            <span style={{ color: '#FF925C', cursor: 'pointer' }} onClick={toEditNews(row.channelId)}>
148
-              编辑<Icon type="form" className={styles.edit} />
149
-            </span>
150
-          </AuthButton>
151
-        </>
149
+        <span style={{ color: '#FF925C', cursor: 'pointer' }} onClick={toEditDemand(row.demandId)}>
150
+          查看详情<Icon type="form" className={styles.edit} />
151
+        </span>
152 152
       ),
153 153
     },
154 154
   ];
@@ -161,10 +161,68 @@ function header(props) {
161 161
   return (
162 162
 
163 163
     <>
164
+    <Form layout="inline" onSubmit={e => handleSubmit(e, props)}>
165
+        <Form.Item>
166
+          {getFieldDecorator('sampleName')(
167
+            <Input
168
+              prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
169
+              placeholder="样例名"
170
+            />,
171
+          )}
172
+        </Form.Item>
173
+        <Form.Item>
174
+          {getFieldDecorator('orgName')(
175
+            <Input
176
+              prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
177
+              placeholder="下单组织"
178
+            />,
179
+          )}
180
+        </Form.Item>
181
+        <Form.Item>
182
+          {getFieldDecorator('orderer')(
183
+            <Input
184
+              prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
185
+              placeholder="下单人"
186
+            />,
187
+          )}
188
+        </Form.Item>
189
+        <Form.Item>
190
+          {getFieldDecorator('phone')(
191
+            <Input
192
+              prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
193
+              placeholder="联系方式"
194
+            />,
195
+          )}
196
+        </Form.Item>
197
+        <Form.Item>
198
+            <span style={{marginRight:'10px'}}>下单时间段:</span>
199
+                {getFieldDecorator('createDate')(
200
+                  <RangePicker placeholder={['开始时间','结束时间']} />
201
+                )}
202
+        </Form.Item>
203
+        <Form.Item>
204
+          {getFieldDecorator('demandStatus')(
205
+            <Select style={{ width: '180px' }} placeholder="需求单状态">
206
+              <Select.Option value="1">已提交</Select.Option>
207
+              <Select.Option value="2">处理中</Select.Option>
208
+              <Select.Option value="3">已交付</Select.Option>
209
+              <Select.Option value="4">作废</Select.Option>
210
+            </Select>,
211
+          )}
212
+        </Form.Item>
213
+        <Form.Item>
214
+          <Button type="primary" htmlType="submit" className={styles.searchBtn}>
215
+            搜索
216
+          </Button>
217
+          <Button style={{ marginLeft: 8 }} onClick={handleReset}>
218
+              重置
219
+          </Button>
220
+        </Form.Item>
221
+      </Form>
164 222
       <AuthButton name="admin.taNewsType.post" noRight={null}>
165
-        <Button type="danger" className={styles.addBtn} onClick={toEditNews()}>新增</Button>
223
+        <Button type="danger" className={styles.addBtn} onClick={changeStatus}>删除</Button>
166 224
       </AuthButton>
167
-      <Table rowKey="newsType" dataSource={data.records} columns={columns} pagination={false} />
225
+      <Table rowSelection={rowSelection} rowKey="newsType" dataSource={data.records} columns={columns} pagination={false} />
168 226
       <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '30px' }}>
169 227
         <Pagination showQuickJumper defaultCurrent={1} total={data.total} onChange={changePageNum} current={data.current}/>
170 228
       </div>

+ 24
- 0
src/pages/sample/h5/components/H5Card.jsx Parādīt failu

@@ -0,0 +1,24 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Input, Menu, Dropdown, Button, Icon, message, Table, Divider, Tag, Select, Form, Alert, Card } from 'antd';
3
+import { FormattedMessage } from 'umi-plugin-react/locale';
4
+import router from 'umi/router';
5
+import apis from '../../../../services/apis';
6
+import request from '../../../../utils/request';
7
+import Wangedit from '../../../../components/Wangedit/Wangedit'
8
+import moment from 'moment';
9
+
10
+const { Meta } = Card
11
+
12
+const H5Card = props => {
13
+    return (
14
+    <Card
15
+      hoverable
16
+      style={{ width: 240 }}
17
+      cover={<img alt="example" src="https://os.alipayobjects.com/rmsportal/QBnOOoLaAfKPirc.png" />}
18
+    >
19
+      <Meta title="Europe Street beat" description="www.instagram.com" />
20
+    </Card>
21
+    )
22
+  }
23
+ 
24
+  export default H5Card

+ 208
- 0
src/pages/sample/h5/components/SelectContact.jsx Parādīt failu

@@ -0,0 +1,208 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Form, Select, Modal, Button, Table, Divider, Tag, Input,Row,Col,Icon,Pagination } from 'antd';
3
+import request from '../../../../utils/request';
4
+import apis from '../../../../services/apis';
5
+import styles from '../style.less';
6
+
7
+const { Column, ColumnGroup } = Table;
8
+const SelectContact = props => {
9
+
10
+  const [data, setData] = useState([]);
11
+  const [visible, setVisible] = useState(false);
12
+  const [group, setGroup] = useState({ groupId: undefined, groupName: '请选择' })
13
+  const [selectedData, setSelectedData ] = useState([]);
14
+
15
+  useEffect(() => {
16
+    if (props.value && props.value != selectedData) {
17
+      setSelectedData(props.value)
18
+    }
19
+  }, [props.value])
20
+
21
+  // 查询列表
22
+  const getList = (params) => {
23
+    request({ ...apis.contact.list, params: { ...params } }).then((data) => {
24
+        console.log(data)
25
+        setData(data)
26
+    })
27
+  }
28
+  
29
+  useEffect(() => {
30
+    getList({ pageNum: 1, pageSize: 10,})
31
+  }, []);
32
+
33
+  
34
+
35
+  const handleChange = val => {
36
+  }
37
+
38
+  const selectData = val => {
39
+    const list = selectedData.filter(x => x.contactId !== val.contactId).concat(val)
40
+    setSelectedData(list)
41
+    props.onSelected(list)
42
+    setVisible(false)
43
+  }
44
+
45
+  
46
+  // 提交事件
47
+  const handleSubmit = (e, props) => {
48
+    e.preventDefault();
49
+    e.stopPropagation();
50
+    props.form.validateFields((err, values) => {
51
+      if (!err) {
52
+        getList({ pageNum: 1, pageSize: 10, ...values })
53
+      }
54
+    });
55
+  }
56
+
57
+  function handleReset() {
58
+    props.form.resetFields();
59
+    getList({ pageNum: 1, pageSize: 10 })
60
+  }
61
+
62
+  const changePageNum = (pageNumber) => {
63
+    getList({ pageNum: pageNumber, pageSize: 10 })
64
+  }
65
+
66
+  const removeSelected = (val) => {
67
+    const list = selectedData.filter(x => x.contactId !== val.contactId)
68
+    setSelectedData(list)
69
+    props.onSelected(list)
70
+  }
71
+
72
+  const columns = [
73
+    {
74
+      title: '姓名',
75
+      dataIndex: 'contactName',
76
+      key: 'drainageId',
77
+      align: 'center',
78
+      ellipsis: true,
79
+      render: text => <a>{text}</a>,
80
+    },
81
+    {
82
+      title: '性别',
83
+      dataIndex: 'sex',
84
+      key: 'drainageId',
85
+      align: 'center',
86
+      ellipsis: true,
87
+      render: text => <a>{text}</a>,
88
+    },
89
+    {
90
+      title: '头像',
91
+      dataIndex: 'avatar',
92
+      key: 'drainageId',
93
+      align: 'center',
94
+      ellipsis: true,
95
+      render: text => <a>{text}</a>,
96
+    },
97
+    {
98
+      title: '固话',
99
+      dataIndex: 'telephone',
100
+      key: 'drainageId',
101
+      align: 'center',
102
+      ellipsis: true,
103
+      render: text => <a>{text}</a>,
104
+    },
105
+    {
106
+      title: '手机号',
107
+      dataIndex: 'phone',
108
+      key: 'drainageId',
109
+      align: 'center',
110
+      ellipsis: true,
111
+      render: text => <a>{text}</a>,
112
+    },
113
+    {
114
+      title: '内部岗位',
115
+      dataIndex: 'job',
116
+      key: 'drainageId',
117
+      align: 'center',
118
+      ellipsis: true,
119
+      render: text => <a>{text}</a>,
120
+    },
121
+    {
122
+      title: '操作',
123
+      align: 'center',
124
+      width: '20%',
125
+      render: (text, record) => (
126
+        <span>
127
+          <a onClick={() => selectData(record)} style={{ color: 'blue' }}>选择</a>
128
+        </span>
129
+      ),
130
+    },
131
+  ];
132
+
133
+  const { getFieldDecorator } = props.form
134
+
135
+  return (
136
+    <div>
137
+      <Row gutter={24}>
138
+        <Col span={2}><div onClick={() => setVisible(true)}>{group.groupName}</div></Col>
139
+        <Col span={16}><div>
140
+        {selectedData.map(x => {
141
+          return <Tag size="large" key={x.contactId} closable onClose={() => removeSelected(x)}>{x.contactName}</Tag>
142
+        })}
143
+      </div></Col>
144
+      </Row>     
145
+      
146
+      <Modal
147
+        title="请选择"
148
+        width="1200px"
149
+        visible={visible}
150
+        onCancel={() => setVisible(false)}
151
+        footer={[]}
152
+      >
153
+      
154
+        <Form layout="inline" onSubmit={e => handleSubmit(e, props)}>
155
+            <Form.Item>
156
+              {getFieldDecorator('contactName')(
157
+                <Input
158
+                  prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
159
+                  placeholder="姓名"
160
+                />,
161
+              )}
162
+            </Form.Item>
163
+            <Form.Item>
164
+              {getFieldDecorator('telephone')(
165
+                <Input
166
+                  prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
167
+                  placeholder="固话"
168
+                />,
169
+              )}
170
+            </Form.Item>
171
+            <Form.Item>
172
+              {getFieldDecorator('phone')(
173
+                <Input
174
+                  prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
175
+                  placeholder="手机号"
176
+                />,
177
+              )}
178
+            </Form.Item>
179
+            <Form.Item>
180
+              {getFieldDecorator('job')(
181
+                <Input
182
+                  prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
183
+                  placeholder="内部岗位"
184
+                />,
185
+              )}
186
+            </Form.Item>
187
+            <Form.Item>
188
+              <Button type="primary" htmlType="submit" className={styles.searchBtn}>
189
+                搜索
190
+              </Button>
191
+              <Button style={{ marginLeft: 8 }} onClick={handleReset}>
192
+                  重置
193
+              </Button>
194
+            </Form.Item>
195
+          </Form>
196
+    
197
+          <Table dataSource={data.records || []} columns={columns} pagination={false} />
198
+          <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '30px' }}>
199
+            <Pagination showQuickJumper defaultCurrent={1} total={data.total} onChange={changePageNum} current={data.current}/>
200
+          </div>
201
+    
202
+      </Modal>
203
+    </div>
204
+  )
205
+}
206
+
207
+const WrappedRegistrationForm = Form.create()(SelectContact);
208
+export default WrappedRegistrationForm;

+ 169
- 0
src/pages/sample/h5/edit.jsx Parādīt failu

@@ -0,0 +1,169 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Input, Menu, Dropdown, Button, Icon, message, Table, Divider, Tag, Select, Form, Alert, Radio } from 'antd';
3
+import { FormattedMessage } from 'umi-plugin-react/locale';
4
+import XForm, { FieldTypes } from '../../../components/XForm';
5
+import router from 'umi/router';
6
+import apis from '../../../services/apis';
7
+import request from '../../../utils/request';
8
+import Wangedit from '../../../components/Wangedit/Wangedit'
9
+import ImageUpload from '../../../components/XForm/ImageUpload'
10
+import SelectContact from './components/SelectContact';
11
+import moment from 'moment';
12
+
13
+const formItemLayout = {
14
+  labelCol: {
15
+    xs: { span: 24 },
16
+    sm: { span: 2 },
17
+  },
18
+  wrapperCol: {
19
+    xs: { span: 24 },
20
+    sm: { span: 16 },
21
+  },
22
+};
23
+
24
+const header = props => {
25
+    const sampleId = props.location.query.id
26
+  
27
+    const [ data, setData ] = useState({})
28
+    const [typeState, setTypeState] = useState("rich")
29
+
30
+    if(sampleId){
31
+      useEffect(() => {
32
+        getH5Data(sampleId);
33
+      },[])
34
+  
35
+    // 查询列表
36
+    const getH5Data = (sampleId) => {
37
+      request({
38
+          ...apis.sample.get,
39
+          urlData: { id: sampleId }
40
+      }).then((data) => {
41
+        setData(data)
42
+      }).catch((err) => {
43
+        message.error(err.msg || err.message)
44
+      })
45
+    }
46
+    }
47
+     
48
+    const handleSubmit = (e) => {
49
+      e.preventDefault();
50
+      // e.stopPropagation();
51
+      props.form.validateFieldsAndScroll((err, values) => {
52
+        console.log(values,"valuesvaluesvaluesvaluesvaluesvaluesvalues")
53
+        debugger
54
+        if (!err) {
55
+          console.log(values,"h5Sample/addh5Sample/add")
56
+          if(sampleId){
57
+            request({ ...apis.sample.update, urlData: { id: sampleId }, data: { ...values }}).then((data) => {
58
+              cancelPage();
59
+            }).catch((err) => {
60
+              message.error(err.msg || err.message)
61
+            })
62
+          }else{
63
+            request({ ...apis.sample.addh5, data: { ...values }}).then((data) => {
64
+              cancelPage();
65
+            }).catch((err) => {
66
+              message.error(err.msg || err.message)
67
+            })
68
+          }
69
+        }
70
+      });
71
+      
72
+    }
73
+  
74
+    const cancelPage = () => {
75
+      router.push({
76
+        pathname: '/sample/h5/list',
77
+      });
78
+    }
79
+
80
+    function sampleTypeChange(e) {
81
+      setTypeState(e.target.value)
82
+    }
83
+  
84
+    const { getFieldDecorator } = props.form;
85
+    return (
86
+      <Form {...formItemLayout} onSubmit={handleSubmit}>
87
+            
88
+          <Form.Item label="样例名" >
89
+            {getFieldDecorator('sampleName',{
90
+              rules: [{ required: true, message: '请输入样例名' },
91
+              { max: 20, message: '样例名不超过20个字符' }],
92
+            })(<Input placeholder="H5活动主题或目的,如植树节引流活动"/>)}
93
+          </Form.Item>
94
+          <Form.Item label="样例体验链接" >
95
+            {getFieldDecorator('sampleTryLink',{
96
+              rules: [{ max: 300, message: '样例体验链接不超过300个字符' }],
97
+            })(<Input placeholder="若样例暂未发布到小程序,可直接粘贴网页链接"/>)}
98
+          </Form.Item>
99
+          <Form.Item label="样例体验二维码/小程序码" >
100
+            {getFieldDecorator('sampleTryCode')(
101
+              <ImageUpload />,
102
+            )}
103
+          </Form.Item>
104
+          <Form.Item label="封面图" help="建议尺寸:495*330px,比例:3:2,格式:jpg,大小:不超过300KB,用于样例列表封面">
105
+            {getFieldDecorator('coverImg', {
106
+              rules: [{ required: true, message: '请选择列表图' }],
107
+            })(
108
+              <ImageUpload />,
109
+            )}
110
+          </Form.Item>
111
+          <Form.Item label="方案/报价/技术联系人" >
112
+            {getFieldDecorator('taContactList',{
113
+              trigger: 'onSelected'
114
+            })(<SelectContact />)}
115
+          </Form.Item>
116
+          <Form.Item label="发布状态" >
117
+            {getFieldDecorator('status', {
118
+              initialValue: "1",
119
+            })(
120
+            <Select style={{ width: '180px' }}>
121
+              <Select.Option value="1">是</Select.Option>
122
+              <Select.Option value="0">否</Select.Option>
123
+            </Select>)}
124
+          </Form.Item>
125
+          <Form.Item label="权重" help="数值越大越靠前">
126
+            {getFieldDecorator('orderNo')(<Input />)}
127
+          </Form.Item>
128
+          <Form.Item label="标签" help="标签长度6个字,最多3个标签">
129
+            {getFieldDecorator('tags')(
130
+              <Select mode="tags" placeholder="输入后选中" style={{ width: '1016px' }}>
131
+
132
+              </Select>,
133
+            )}
134
+          </Form.Item>
135
+          <Form.Item label="样例类型">
136
+            {getFieldDecorator('sampleType',{
137
+              initialValue: "rich",
138
+            })(
139
+            <Radio.Group onChange={e => sampleTypeChange(e)}>
140
+              <Radio value="rich">富文本</Radio>
141
+              <Radio value="link">外部链接</Radio>
142
+            </Radio.Group>,
143
+            )}
144
+          </Form.Item>
145
+          {typeState === 'link' && <Form.Item label="外部链接">
146
+            {getFieldDecorator('sampleContentLink',{
147
+              rules: [{ max: 300, message: '外部链接不超过300个字符' }],
148
+            })(<Input placeholder="填写外部链接,如公众号链接或135编辑器生成的页面链接" />)}
149
+          </Form.Item>}
150
+          {typeState === 'rich' && <Form.Item label="样例内容" >
151
+            {getFieldDecorator('sampleContent')(
152
+              <Wangedit />,
153
+            )}
154
+          </Form.Item> }
155
+          <Form.Item style={{ width: '400px', margin: 'auto', display: 'flex', justifyContent: 'space-between' }}>
156
+            <Button type="primary" htmlType="submit">
157
+                确定
158
+            </Button>
159
+            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
160
+            <Button onClick={() => router.go(-1)}>
161
+                取消
162
+            </Button>
163
+          </Form.Item>
164
+        </Form>
165
+    )
166
+  }
167
+  
168
+  const WrappedNormalLoginForm = Form.create({ name: 'header' })(header);
169
+  export default WrappedNormalLoginForm

+ 71
- 78
src/pages/sample/h5/index.jsx Parādīt failu

@@ -1,6 +1,6 @@
1 1
 import React, { useState, useEffect } from 'react';
2 2
 import { PageHeaderWrapper } from '@ant-design/pro-layout';
3
-import { Form, Pagination, Card, Button, Icon, Tooltip, message,   notification, Modal, Table } from 'antd';
3
+import { Form, Pagination, Card, Button, Icon, Tooltip, message,   notification, Modal, Table, Select,Input, DatePicker  } from 'antd';
4 4
 import router from 'umi/router';
5 5
 import moment from 'moment';
6 6
 import className from 'classnames';
@@ -9,8 +9,9 @@ import styles from './style.less';
9 9
 import { fetch, apis } from '../../../utils/request';
10 10
 import request from '../../../utils/request';
11 11
 import AuthButton from '@/components/AuthButton';
12
+import H5Card from './components/H5Card';
12 13
 
13
-
14
+const { MonthPicker, RangePicker, WeekPicker } = DatePicker;
14 15
 
15 16
 function header(props) {
16 17
   // 获取初始化数据
@@ -22,7 +23,7 @@ function header(props) {
22 23
 
23 24
   // 查询列表
24 25
   const getList = (params) => {
25
-    request({ ...apis.channel.list, params: { ...params } }).then((data) => {
26
+    request({ ...apis.sample.h5list, params: { ...params } }).then((data) => {
26 27
         console.log(data)
27 28
         setData(data)
28 29
     })
@@ -45,9 +46,9 @@ function header(props) {
45 46
 
46 47
 
47 48
   // 跳转到编辑资讯
48
-  const toEditNews = (id) => () => {
49
+  const toEditH5 = (id) => () => {
49 50
     router.push({
50
-      pathname: '/channel/edit',
51
+      pathname: '/sample/h5/edit',
51 52
       query: {
52 53
         id
53 54
       },
@@ -83,75 +84,7 @@ function header(props) {
83 84
       }
84 85
     });
85 86
   }
86
-  /**
87
-   *
88
-   *
89
-   * @param {*} props
90
-   * @returns
91
-   */
92
-  const columns = [
93
-    {
94
-      title: '渠道代理',
95
-      dataIndex: 'channelProxyName',
96
-      key: 'channelProxyName',
97
-      align: 'center',
98
-    },
99
-    {
100
-      title: '账号名',
101
-      dataIndex: 'userName',
102
-      key: 'userName',
103
-      align: 'center',
104
-      render: (x, row) => <span>{row.userName === null || row.userName === '' ? row.channelTel : row.userName}</span>,
105
-    },
106
-    {
107
-      title: '小程序总数',
108
-      dataIndex: 'appMaxNum',
109
-      key: 'appMaxNum',
110
-      align: 'center',
111
-
112
-    },
113
-    {
114
-      title: '现有小程序',
115
-      dataIndex: 'appCurrentNum',
116
-      key: 'appCurrentNum',
117
-      align: 'center',
118
-      render: (appCurrentNum) => <span>{appCurrentNum === 0 || appCurrentNum == null ? 0 : appCurrentNum}</span>,
119
-    },
120
-    {
121
-      title: '服务到期时间',
122
-      dataIndex: 'expireDate',
123
-      key: 'expireDate',
124
-      align: 'center',
125
-      render: (x, row) => <><span>{`${moment(row.expireDate).format('YYYY-MM-DD')}`}</span></>,
126
-    },
127
-    {
128
-      title: '状态',
129
-      dataIndex: 'status',
130
-      key: 'status',
131
-      align: 'center',
132
-      render: (status) => <span>{status === 1 ? '启动' : '停用'}</span>,
133
-    },
134
-    {
135
-      title: '操作',
136
-      dataIndex: 'handle',
137
-      key: 'handle',
138
-      align: 'center',
139
-      render: (x, row) => (
140
-        <>
141
-          <AuthButton name="admin.taNewsType.id.delete" noRight={null}>
142
-            <span style={{ color: '#EF273A', marginRight: '20px', cursor: 'pointer' }} onClick={changeNewsStatus(row, row.channelId)}>
143
-              {row.status == 1 ? '停用' : '启用'}<Icon type="shopping-cart" className={styles.shoppingCart} />
144
-            </span>
145
-          </AuthButton>
146
-          <AuthButton name="admin.taNewsType.id.put" noRight={null}>
147
-            <span style={{ color: '#FF925C', cursor: 'pointer' }} onClick={toEditNews(row.channelId)}>
148
-              编辑<Icon type="form" className={styles.edit} />
149
-            </span>
150
-          </AuthButton>
151
-        </>
152
-      ),
153
-    },
154
-  ];
87
+   
155 88
   function handleReset() {
156 89
     props.form.resetFields();
157 90
     getList({ pageNum: 1, pageSize: 10 })
@@ -161,10 +94,70 @@ function header(props) {
161 94
   return (
162 95
 
163 96
     <>
164
-      <AuthButton name="admin.taNewsType.post" noRight={null}>
165
-        <Button type="danger" className={styles.addBtn} onClick={toEditNews()}>新增</Button>
166
-      </AuthButton>
167
-      <Table rowKey="newsType" dataSource={data.records} columns={columns} pagination={false} />
97
+    <Form layout="inline" onSubmit={e => handleSubmit(e, props)}>
98
+        <Form.Item>
99
+          {getFieldDecorator('sampleName')(
100
+            <Input
101
+              prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
102
+              placeholder="样例名"
103
+            />,
104
+          )}
105
+        </Form.Item>
106
+        <Form.Item>
107
+          {getFieldDecorator('orgName')(
108
+            <Input
109
+              prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
110
+              placeholder="下单组织"
111
+            />,
112
+          )}
113
+        </Form.Item>
114
+        <Form.Item>
115
+          {getFieldDecorator('orderer')(
116
+            <Input
117
+              prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
118
+              placeholder="下单人"
119
+            />,
120
+          )}
121
+        </Form.Item>
122
+        <Form.Item>
123
+          {getFieldDecorator('phone')(
124
+            <Input
125
+              prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
126
+              placeholder="联系方式"
127
+            />,
128
+          )}
129
+        </Form.Item>
130
+        <Form.Item>
131
+            <span style={{marginRight:'10px'}}>下单时间段:</span>
132
+                {getFieldDecorator('createDate')(
133
+                  <RangePicker placeholder={['开始时间','结束时间']} />
134
+                )}
135
+        </Form.Item>
136
+        <Form.Item>
137
+          {getFieldDecorator('demandStatus')(
138
+            <Select style={{ width: '180px' }} placeholder="需求单状态">
139
+              <Select.Option value="1">已提交</Select.Option>
140
+              <Select.Option value="2">处理中</Select.Option>
141
+              <Select.Option value="3">已交付</Select.Option>
142
+              <Select.Option value="4">作废</Select.Option>
143
+            </Select>,
144
+          )}
145
+        </Form.Item>
146
+        <Form.Item>
147
+          <Button type="primary" htmlType="submit" className={styles.searchBtn}>
148
+            搜索
149
+          </Button>
150
+          <Button style={{ marginLeft: 8 }} onClick={handleReset}>
151
+              重置
152
+          </Button>
153
+        </Form.Item>
154
+      </Form>
155
+      
156
+      <Button type="danger" className={styles.addBtn} onClick={toEditH5()}>新增</Button>
157
+ 
158
+      {(data.records || []).map(x => (
159
+          <H5Card />
160
+        ))}
168 161
       <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '30px' }}>
169 162
         <Pagination showQuickJumper defaultCurrent={1} total={data.total} onChange={changePageNum} current={data.current}/>
170 163
       </div>

+ 66
- 0
src/services/apis.js Parādīt failu

@@ -64,6 +64,45 @@ const apis = {
64 64
       action: 'channel',
65 65
     },
66 66
   },
67
+  sample: {
68
+    list: {
69
+      url: `${prefix}/taH5Demand`,
70
+      method: 'GET',
71
+      action: 'channel',
72
+    },
73
+    put: {
74
+      url: `${prefix}/taH5Demand/batch`,
75
+      method: 'PUT',
76
+      action: 'channel',
77
+    },
78
+    get: {
79
+      url: `${prefix}/taH5Demand/:id`,
80
+      method: 'GET',
81
+      action: 'channel',
82
+    },
83
+    update: {
84
+      url: `${prefix}/taH5Demand/update/:id`,
85
+      method: 'PUT',
86
+      action: 'channel',
87
+    },
88
+    h5list: {
89
+      url: `${prefix}/h5Sample/list`,
90
+      method: 'GET',
91
+      action: 'channel',
92
+    },
93
+    addh5: {
94
+      url: `${prefix}/h5Sample/add`,
95
+      method: 'POST',
96
+      action: 'channel',
97
+    },
98
+  },
99
+  contact: {
100
+    list: {
101
+      url: `${prefix}/taContact`,
102
+      method: 'GET',
103
+      action: 'channel',
104
+    },
105
+  },
67 106
   image: {
68 107
     uploadForAnt: {
69 108
       url: `${prefix}/antd/image`,
@@ -113,6 +152,33 @@ const apis = {
113 152
     // /api/admin/ListH5SampleByCondition
114 153
   },
115 154
   
155
+  contact:{
156
+    listContactByCondition: {
157
+      url: `${prefix}/listContactByCondition`,
158
+      method: 'GET',
159
+      action: 'center',
160
+    },
161
+    taContactAdd: {
162
+      url: `${prefix}/taContact`,
163
+      method: 'POST',
164
+      action: 'center',
165
+    },
166
+    batchDeleteContact: {
167
+      url: `${prefix}/taContact/batchDelete`,
168
+      method: 'PUT',
169
+      action: 'center',
170
+    },
171
+    taContactGet: {
172
+      url: `${prefix}/taContact/:id`,
173
+      method: 'GET',
174
+      action: 'center',
175
+    },
176
+    taContactUpdate: {
177
+      url: `${prefix}/taContact/:id`,
178
+      method: 'PUT',
179
+      action: 'center',
180
+    },
181
+  }
116 182
   
117 183
 }
118 184