Browse Source

add subscribe message

张延森 5 years ago
parent
commit
5d67c7efd1

+ 1
- 0
.npmrc View File

1
+registry=https://registry.npm.taobao.org

+ 1
- 0
package.json View File

43
   "dependencies": {
43
   "dependencies": {
44
     "@ant-design/pro-layout": "^4.5.9",
44
     "@ant-design/pro-layout": "^4.5.9",
45
     "@antv/data-set": "^0.10.2",
45
     "@antv/data-set": "^0.10.2",
46
+    "@zjxpcyc/xrc-form2": "^2.1.0",
46
     "antd": "^3.20.0",
47
     "antd": "^3.20.0",
47
     "classnames": "^2.2.6",
48
     "classnames": "^2.2.6",
48
     "dva": "^2.4.1",
49
     "dva": "^2.4.1",

+ 229
- 0
src/pages/UserManage/Editor/Miniapp.bak.jsx View File

1
+import React, { useState, useEffect } from 'react';
2
+import { Button, Row, Col, Input, InputNumber, Modal, notification } from 'antd';
3
+import XForm, { FieldTypes } from '../../../components/XForm';
4
+import Style from '../style.less';
5
+import { fetch, apis } from '../../../utils/request';
6
+
7
+const saveMiniapp = fetch(apis.member.miniapp.edit);
8
+const checkMiniapp = fetch(apis.member.miniapp.check);
9
+
10
+const TplItem = React.forwardRef((props, ref) => {
11
+  const [val, setVal] = useState(props.value)
12
+
13
+  const handleChange = field => e => {
14
+    const newVal = { ...val, [`${field}`]: (e.target ? e.target.value : e) }
15
+    setVal(newVal)
16
+
17
+    if (typeof props.onChange === 'function') {
18
+      console.log('--change--->', newVal)
19
+      props.onChange(newVal)
20
+    }
21
+  }
22
+
23
+  return (
24
+    <Input.Group compact ref={ref}>
25
+      <Input style={{ width: '70%' }} value={val.tplId} placeholder="消息模板ID" onChange={handleChange('tplId')}></Input>
26
+      <InputNumber style={{ width: '30%' }} value={val.fieldNum} placeholder="字段数" onChange={handleChange('fieldNum')}></InputNumber>
27
+    </Input.Group>
28
+  );
29
+})
30
+
31
+const Miniapp = (props) => {
32
+  const [ visible, changeVisible ] = useState(false);
33
+  const [ path, changePath ] = useState('/pages/project/index');
34
+  const [ qrCode, setQrCode ] = useState();
35
+
36
+  const user = props.data || {}
37
+  const appdata = user.miniapp || {};
38
+  const tpls = appdata.tpls || [];
39
+
40
+  useEffect(() => {
41
+    setQrCode(appdata.qrCode)
42
+  }, [])
43
+
44
+  const showModal = () => {
45
+    changeVisible(true);
46
+  }
47
+
48
+  let form = undefined;
49
+  const handleForm = f => {
50
+    if (f) {
51
+      form = f.props.form
52
+    }
53
+  }
54
+
55
+  const handleModalOk = () => {
56
+    const values = form.getFieldsValue()
57
+    const data = { ...values, path }
58
+
59
+    checkMiniapp({ data }).then(dt => {
60
+      setQrCode(dt.qrCode)
61
+      changeVisible(false)
62
+      notification.success({ message: '校验成功' });
63
+    }).catch();
64
+  }
65
+
66
+  const tplFields = (props.tplTyps || []).map((x) => {
67
+    return {
68
+      label: x.name,
69
+      name: `tpl-${x.code}`,
70
+      render: <TplItem />,
71
+      value: tpls.filter(y => y.tplType === x.code)[0] || {},
72
+    }
73
+  })
74
+
75
+  const fields = [
76
+    {
77
+      label: '名称',
78
+      name: 'name',
79
+      type: FieldTypes.Text,
80
+      value: appdata.name,
81
+      rules: [{required: true, message: '请填写小程序名称'}]
82
+    },
83
+    {
84
+      label: 'APPID',
85
+      name: 'miniappId',
86
+      type: FieldTypes.Text,
87
+      value: appdata.miniappId,
88
+      props: {
89
+        disabled: !!appdata.miniappId,
90
+      },
91
+      rules: [
92
+        { required: true, message: '请填写 APPID' },
93
+        { pattern: /^[a-zA-Z0-9]+$/, message: 'APPID 只能由字母与数字组成' }
94
+      ]
95
+    },
96
+    {
97
+      label: 'Secret',
98
+      name: 'secret',
99
+      type: FieldTypes.Text,
100
+      value: appdata.secret,
101
+      rules: [
102
+        { required: true, message: '请填写 Secret' },
103
+        { pattern: /^[a-zA-Z0-9]+$/, message: 'APPID 只能由字母与数字组成' }
104
+      ]
105
+    },
106
+    {
107
+      label: 'Token',
108
+      name: 'token',
109
+      value: appdata.token,
110
+      type: FieldTypes.Text,
111
+      rules: [
112
+        { pattern: /^[a-zA-Z0-9]+$/, message: 'token 只能由字母与数字组成' }
113
+      ]
114
+    },
115
+    {
116
+      label: 'AES_KEY',
117
+      name: 'aesKey',
118
+      value: appdata.aesKey,
119
+      type: FieldTypes.Text,
120
+      rules: [
121
+        { pattern: /^[a-zA-Z0-9]+$/, message: 'AES_KEY 只能由字母与数字组成' }
122
+      ]
123
+    },
124
+    ...tplFields,
125
+    {
126
+      label: '小程序码',
127
+      name: 'qrCode',
128
+      render: () => <img src={qrCode} style={{ width: '240px' }} alt=""/>,
129
+      value: qrCode,
130
+    },
131
+    {
132
+      action: true,
133
+      render: () => {
134
+        return (
135
+          <div className={Style['flex-box']}>
136
+            <div className={Style['flex-item']}>
137
+              <img src="" alt="" style={{ width: '128px' }}/>
138
+            </div>
139
+            <div className={Style['flex-auto']}>
140
+              <Button type="primary" ghost onClick={showModal}>验证</Button>
141
+            </div>
142
+            <Modal
143
+              title="填写首页地址"
144
+              visible={visible}
145
+              onOk={handleModalOk}
146
+              onCancel={() => changeVisible(false)}
147
+            >
148
+              <Input value={path} onChange={e => changePath(e.target.value)}></Input>
149
+            </Modal>
150
+          </div>
151
+        )
152
+      }
153
+    },
154
+  ]
155
+
156
+  const checkTPLData = (submitData) => {
157
+    let tplData = [...tpls]
158
+    let errors = []
159
+
160
+    Object.keys(submitData).forEach((key) => {
161
+      if (key.indexOf('tpl-') === 0) {
162
+        const [, code] = key.split('-')
163
+        const { tplId, fieldNum } = submitData[key].result || submitData[key]
164
+        const tplType = (props.tplTyps || []).filter(x => x.code === code)[0] || {}
165
+
166
+        if (tplId && !fieldNum) {
167
+          errors.push(`请填写${tplType.name}模板字段数`)
168
+          return
169
+        }
170
+
171
+        console.log('--->', submitData[key])
172
+
173
+        if (tplId) {
174
+          tplData = [
175
+            ...tplData.filter(x => x.tplType !== code),
176
+            {
177
+              ...submitData[key],
178
+              tplType: code,
179
+              tplName: tplType.name,
180
+            }
181
+          ]
182
+        }
183
+      }
184
+    })
185
+
186
+    return [tplData, errors]
187
+  }
188
+
189
+  const handleSubmit = val => {
190
+    // 校验字段
191
+    const { mainbiz, newCustomer, notice, ...otherData} = val
192
+
193
+    console.log('-----val--->', val)
194
+
195
+    const [tplData, errors] = checkTPLData(otherData)
196
+
197
+    if (errors.length > 0) {
198
+      notification.error({ message: errors[0] })
199
+      return
200
+    }
201
+
202
+    const data = {
203
+      ...appdata,
204
+      ...otherData,
205
+      qrCode: qrCode || appdata.appdata,
206
+      orgId: user.orgId,
207
+      tpls: tplData,
208
+    }
209
+
210
+    saveMiniapp({ data }).then((miniapp) => {
211
+      
212
+      if (typeof props.onChange === 'function') {
213
+        props.onChange({ ...user, miniapp })
214
+      }
215
+
216
+      notification.success({ message: '保存小程序信息成功' })
217
+    }).catch(x => x)
218
+  }
219
+
220
+  const handleCancel = () => {
221
+    if (typeof props.onCancel === 'function') {
222
+      props.onCancel()
223
+    }
224
+  }
225
+
226
+  return (<XForm wrappedComponentRef={handleForm} onSubmit={handleSubmit} onCancel={handleCancel} fields={fields}></XForm>)
227
+}
228
+
229
+export default Miniapp;

+ 55
- 41
src/pages/UserManage/Editor/Miniapp.jsx View File

1
 import React, { useState, useEffect } from 'react';
1
 import React, { useState, useEffect } from 'react';
2
-import { Button, Row, Col, Input, InputNumber, Modal, notification } from 'antd';
3
-import XForm, { FieldTypes } from '../../../components/XForm';
2
+import { Button, Row, Col, Input, InputNumber, Modal, notification, Select, Tooltip } from 'antd';
3
+import createForm from '@zjxpcyc/xrc-form2';
4
 import Style from '../style.less';
4
 import Style from '../style.less';
5
 import { fetch, apis } from '../../../utils/request';
5
 import { fetch, apis } from '../../../utils/request';
6
 
6
 
7
+const XForm = createForm();
7
 const saveMiniapp = fetch(apis.member.miniapp.edit);
8
 const saveMiniapp = fetch(apis.member.miniapp.edit);
8
 const checkMiniapp = fetch(apis.member.miniapp.check);
9
 const checkMiniapp = fetch(apis.member.miniapp.check);
9
 
10
 
11
+const getEventValue = e => {
12
+  return Object.prototype.hasOwnProperty.call(e, 'checked') ?
13
+    e.checked : (e.target ? e.target.value : e)
14
+}
15
+
10
 const TplItem = React.forwardRef((props, ref) => {
16
 const TplItem = React.forwardRef((props, ref) => {
11
   const [val, setVal] = useState(props.value)
17
   const [val, setVal] = useState(props.value)
18
+  const [isSubs, setIsSubs] = useState(props.value.isSubscribe)
12
 
19
 
13
   const handleChange = field => e => {
20
   const handleChange = field => e => {
14
-    const newVal = { ...val, [`${field}`]: (e.target ? e.target.value : e) }
21
+    const fv = getEventValue(e);
22
+    const newVal = { ...val, [`${field}`]: fv }
15
     setVal(newVal)
23
     setVal(newVal)
16
 
24
 
25
+    if (field === 'isSubscribe') {
26
+      setIsSubs(fv)
27
+    }
28
+
17
     if (typeof props.onChange === 'function') {
29
     if (typeof props.onChange === 'function') {
18
-      console.log('--change--->', newVal)
19
       props.onChange(newVal)
30
       props.onChange(newVal)
20
     }
31
     }
21
   }
32
   }
22
 
33
 
23
   return (
34
   return (
24
-    <Input.Group compact ref={ref}>
25
-      <Input style={{ width: '70%' }} value={val.tplId} placeholder="消息模板ID" onChange={handleChange('tplId')}></Input>
26
-      <InputNumber style={{ width: '30%' }} value={val.fieldNum} placeholder="字段数" onChange={handleChange('fieldNum')}></InputNumber>
27
-    </Input.Group>
35
+    <div ref={ref}>
36
+      <Input.Group compact>
37
+        <Tooltip title="消息类型">
38
+          <Select style={{ width: '15%' }} value={!!val.isSubscribe} onChange={handleChange('isSubscribe')}>
39
+            <Option value={true}>订阅</Option>
40
+            <Option value={false}>普通</Option>
41
+          </Select>
42
+        </Tooltip>
43
+        <Tooltip title="消息模板ID">
44
+          <Input style={{ width: '45%' }} value={val.tplId} placeholder="消息模板ID" onChange={handleChange('tplId')}></Input>
45
+        </Tooltip>
46
+        {
47
+          !isSubs ?
48
+            (<Tooltip title="消息字段数"><InputNumber style={{ width: '40%' }} value={val.fieldNum} placeholder="字段数" onChange={handleChange('fieldNum')}></InputNumber></Tooltip>) :
49
+            (<Tooltip title="消息字段, 多字段用 | 分隔"><Input style={{ width: '40%' }} value={val.tplFields} placeholder="字段内容" onChange={handleChange('tplFields')}></Input></Tooltip>)
50
+        }
51
+      </Input.Group>
52
+    </div>
28
   );
53
   );
29
-})
54
+});
30
 
55
 
31
 const Miniapp = (props) => {
56
 const Miniapp = (props) => {
32
   const [ visible, changeVisible ] = useState(false);
57
   const [ visible, changeVisible ] = useState(false);
66
   const tplFields = (props.tplTyps || []).map((x) => {
91
   const tplFields = (props.tplTyps || []).map((x) => {
67
     return {
92
     return {
68
       label: x.name,
93
       label: x.name,
69
-      name: `tpl-${x.code}`,
70
-      render: <TplItem />,
94
+      name: `tpl.${x.code}`,
95
+      node: TplItem,
71
       value: tpls.filter(y => y.tplType === x.code)[0] || {},
96
       value: tpls.filter(y => y.tplType === x.code)[0] || {},
97
+      hidden: vals => vals.isSubscribe,
72
     }
98
     }
73
   })
99
   })
74
 
100
 
76
     {
102
     {
77
       label: '名称',
103
       label: '名称',
78
       name: 'name',
104
       name: 'name',
79
-      type: FieldTypes.Text,
105
+      node: Input,
80
       value: appdata.name,
106
       value: appdata.name,
81
       rules: [{required: true, message: '请填写小程序名称'}]
107
       rules: [{required: true, message: '请填写小程序名称'}]
82
     },
108
     },
83
     {
109
     {
84
       label: 'APPID',
110
       label: 'APPID',
85
       name: 'miniappId',
111
       name: 'miniappId',
86
-      type: FieldTypes.Text,
112
+      node: Input,
87
       value: appdata.miniappId,
113
       value: appdata.miniappId,
88
       props: {
114
       props: {
89
         disabled: !!appdata.miniappId,
115
         disabled: !!appdata.miniappId,
96
     {
122
     {
97
       label: 'Secret',
123
       label: 'Secret',
98
       name: 'secret',
124
       name: 'secret',
99
-      type: FieldTypes.Text,
125
+      node: Input,
100
       value: appdata.secret,
126
       value: appdata.secret,
101
       rules: [
127
       rules: [
102
         { required: true, message: '请填写 Secret' },
128
         { required: true, message: '请填写 Secret' },
106
     {
132
     {
107
       label: 'Token',
133
       label: 'Token',
108
       name: 'token',
134
       name: 'token',
135
+      node: Input,
109
       value: appdata.token,
136
       value: appdata.token,
110
-      type: FieldTypes.Text,
111
       rules: [
137
       rules: [
112
         { pattern: /^[a-zA-Z0-9]+$/, message: 'token 只能由字母与数字组成' }
138
         { pattern: /^[a-zA-Z0-9]+$/, message: 'token 只能由字母与数字组成' }
113
       ]
139
       ]
115
     {
141
     {
116
       label: 'AES_KEY',
142
       label: 'AES_KEY',
117
       name: 'aesKey',
143
       name: 'aesKey',
144
+      node: Input,
118
       value: appdata.aesKey,
145
       value: appdata.aesKey,
119
-      type: FieldTypes.Text,
120
       rules: [
146
       rules: [
121
         { pattern: /^[a-zA-Z0-9]+$/, message: 'AES_KEY 只能由字母与数字组成' }
147
         { pattern: /^[a-zA-Z0-9]+$/, message: 'AES_KEY 只能由字母与数字组成' }
122
       ]
148
       ]
154
   ]
180
   ]
155
 
181
 
156
   const checkTPLData = (submitData) => {
182
   const checkTPLData = (submitData) => {
157
-    let tplData = [...tpls]
158
     let errors = []
183
     let errors = []
159
 
184
 
160
-    Object.keys(submitData).forEach((key) => {
161
-      if (key.indexOf('tpl-') === 0) {
162
-        const [, code] = key.split('-')
163
-        const { tplId, fieldNum } = submitData[key].result || submitData[key]
164
-        const tplType = (props.tplTyps || []).filter(x => x.code === code)[0] || {}
185
+    const tplData = Object.keys(submitData).map((key) => {
186
+      const { tplId, fieldNum, tplFields, isSubscribe, ...left } = submitData[key]
187
+      const tplType = (props.tplTyps || []).filter(x => x.code === key)[0] || {}
165
 
188
 
166
-        if (tplId && !fieldNum) {
167
-          errors.push(`请填写${tplType.name}模板字段数`)
189
+      if (isSubscribe) {
190
+        if (tplId && !tplFields) {
191
+          errors.push(`请填写${tplType.name}模板字段内容`)
168
           return
192
           return
169
         }
193
         }
170
-
171
-        console.log('--->', submitData[key])
172
-
173
-        if (tplId) {
174
-          tplData = [
175
-            ...tplData.filter(x => x.tplType !== code),
176
-            {
177
-              ...submitData[key],
178
-              tplType: code,
179
-              tplName: tplType.name,
180
-            }
181
-          ]
182
-        }
194
+      } else if (tplId && !fieldNum) {
195
+        errors.push(`请填写${tplType.name}模板字段数`)
196
+        return
183
       }
197
       }
198
+
199
+      return submitData[key]
184
     })
200
     })
185
 
201
 
186
     return [tplData, errors]
202
     return [tplData, errors]
188
 
204
 
189
   const handleSubmit = val => {
205
   const handleSubmit = val => {
190
     // 校验字段
206
     // 校验字段
191
-    const { mainbiz, newCustomer, notice, ...otherData} = val
192
-
193
-    console.log('-----val--->', val)
207
+    const { tpl, ...otherData} = val
194
 
208
 
195
-    const [tplData, errors] = checkTPLData(otherData)
209
+    const [tplData, errors] = checkTPLData(tpl)
196
 
210
 
197
     if (errors.length > 0) {
211
     if (errors.length > 0) {
198
       notification.error({ message: errors[0] })
212
       notification.error({ message: errors[0] })

+ 1
- 1
src/pages/UserManage/Editor/index.jsx View File

64
           <Radio.Button value={3}>开通权限</Radio.Button>
64
           <Radio.Button value={3}>开通权限</Radio.Button>
65
         </Radio.Group>
65
         </Radio.Group>
66
       </div>
66
       </div>
67
-      <div style={{ width: '680px', margin: '0 auto' }}>
67
+      <div style={{ width: '800px', margin: '0 auto' }}>
68
         { tab === 1 ? <User data={user} {...props} onChange={handleChangeUser} onCancel={handleCancel(1)}/> : null}
68
         { tab === 1 ? <User data={user} {...props} onChange={handleChangeUser} onCancel={handleCancel(1)}/> : null}
69
         { tab === 2 ? <MiniApp data={user} tplTyps={tplTyps} {...props} onChange={handleChangeUser} onCancel={handleCancel(2)}/> : null}
69
         { tab === 2 ? <MiniApp data={user} tplTyps={tplTyps} {...props} onChange={handleChangeUser} onCancel={handleCancel(2)}/> : null}
70
         { tab === 3 ? <Menus data={user} {...props} onCancel={handleCancel(3)}/> : null}
70
         { tab === 3 ? <Menus data={user} {...props} onCancel={handleCancel(3)}/> : null}