Explorar el Código

Merge branch 'master' into dev

张延森 hace 5 años
padre
commit
033f35a445

+ 1
- 0
.npmrc Ver fichero

@@ -0,0 +1 @@
1
+registry=https://registry.npm.taobao.org

+ 1
- 0
package.json Ver fichero

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

+ 229
- 0
src/pages/UserManage/Editor/Miniapp.bak.jsx Ver fichero

@@ -0,0 +1,229 @@
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;

+ 58
- 61
src/pages/UserManage/Editor/Miniapp.jsx Ver fichero

@@ -1,45 +1,57 @@
1 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 4
 import Style from '../style.less';
5 5
 import { fetch, apis } from '../../../utils/request';
6 6
 
7
+const XForm = createForm();
7 8
 const saveMiniapp = fetch(apis.member.miniapp.edit);
8 9
 const checkMiniapp = fetch(apis.member.miniapp.check);
9 10
 
10
-const TplItem = React.forwardRef((props, ref) => {
11
-  const [val, setVal] = useState({})
12
-
13
-  useEffect(() => {
14
-    setVal(props.value)
15
-  }, [props.value])
11
+const getEventValue = e => {
12
+  return Object.prototype.hasOwnProperty.call(e, 'checked') ?
13
+    e.checked : (e.target ? e.target.value : e)
14
+}
16 15
 
17
-  console.log('props.value:', props)
16
+const TplItem = React.forwardRef((props, ref) => {
17
+  const [val, setVal] = useState(props.value)
18
+  const [isSubs, setIsSubs] = useState(props.value.isSubscribe)
18 19
 
19 20
   const handleChange = field => e => {
20
-    // console.log(field, e)
21
-    let inputVal = null
22
-    if (field === 'tplId') {
23
-      inputVal = (e.target ? e.target.value : e)
24
-    }
25
-    if (field === 'fieldNum') {
26
-      inputVal = e
27
-    }
28
-    const newVal = { ...val, [`${field}`]: inputVal }
21
+    const fv = getEventValue(e);
22
+    const newVal = { ...val, [`${field}`]: fv }
29 23
     setVal(newVal)
24
+
25
+    if (field === 'isSubscribe') {
26
+      setIsSubs(fv)
27
+    }
28
+
30 29
     if (typeof props.onChange === 'function') {
31
-      console.log('--change--->', newVal)
32 30
       props.onChange(newVal)
33 31
     }
34 32
   }
35 33
 
36 34
   return (
37
-    <Input.Group compact ref={ref}>
38
-      <Input style={{ width: '70%' }} value={val.tplId} placeholder="消息模板ID" onChange={e => handleChange('tplId')(e)}></Input>
39
-      <InputNumber style={{ width: '30%' }} value={val.fieldNum} placeholder="字段数" onChange={e => handleChange('fieldNum')(e)}></InputNumber>
40
-    </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>
41 53
   );
42
-})
54
+});
43 55
 
44 56
 const Miniapp = (props) => {
45 57
   const [ visible, changeVisible ] = useState(false);
@@ -83,9 +95,10 @@ const Miniapp = (props) => {
83 95
     console.log('tpls.filter: ', tpls.filter(y => y.tplType === x.code)[0] || {})
84 96
     return {
85 97
       label: x.name,
86
-      name: `tpl-${x.code}`,
87
-      render: <TplItem />,
98
+      name: `tpl.${x.code}`,
99
+      node: TplItem,
88 100
       value: tpls.filter(y => y.tplType === x.code)[0] || {},
101
+      hidden: vals => vals.isSubscribe,
89 102
     }
90 103
   })
91 104
 
@@ -93,14 +106,14 @@ const Miniapp = (props) => {
93 106
     {
94 107
       label: '名称',
95 108
       name: 'name',
96
-      type: FieldTypes.Text,
109
+      node: Input,
97 110
       value: appdata.name,
98 111
       rules: [{required: true, message: '请填写小程序名称'}]
99 112
     },
100 113
     {
101 114
       label: 'APPID',
102 115
       name: 'miniappId',
103
-      type: FieldTypes.Text,
116
+      node: Input,
104 117
       value: appdata.miniappId,
105 118
       props: {
106 119
         disabled: !!appdata.miniappId,
@@ -113,7 +126,7 @@ const Miniapp = (props) => {
113 126
     {
114 127
       label: 'Secret',
115 128
       name: 'secret',
116
-      type: FieldTypes.Text,
129
+      node: Input,
117 130
       value: appdata.secret,
118 131
       rules: [
119 132
         { required: true, message: '请填写 Secret' },
@@ -123,8 +136,8 @@ const Miniapp = (props) => {
123 136
     {
124 137
       label: 'Token',
125 138
       name: 'token',
139
+      node: Input,
126 140
       value: appdata.token,
127
-      type: FieldTypes.Text,
128 141
       rules: [
129 142
         { pattern: /^[a-zA-Z0-9]+$/, message: 'token 只能由字母与数字组成' }
130 143
       ]
@@ -132,8 +145,8 @@ const Miniapp = (props) => {
132 145
     {
133 146
       label: 'AES_KEY',
134 147
       name: 'aesKey',
148
+      node: Input,
135 149
       value: appdata.aesKey,
136
-      type: FieldTypes.Text,
137 150
       rules: [
138 151
         { pattern: /^[a-zA-Z0-9]+$/, message: 'AES_KEY 只能由字母与数字组成' }
139 152
       ]
@@ -171,36 +184,23 @@ const Miniapp = (props) => {
171 184
   ]
172 185
 
173 186
   const checkTPLData = (submitData) => {
174
-    // let tplData = [...tpls]
175
-    let tplData = []
176 187
     let errors = []
177 188
 
178
-    Object.keys(submitData).forEach((key) => {
179
-      if (key.indexOf('tpl-') === 0) {
180
-        // const [, code] = key.split('-')
181
-        const code = key.substring(key.indexOf('-') + 1, key.length)
182
-        console.log('code:', code)
183
-        const { tplId, fieldNum } = submitData[key].result || submitData[key]
184
-        const tplType = (props.tplTyps || []).filter(x => x.code === code)[0] || {}
185
-    
186
-        if (tplId && !fieldNum) {
187
-          errors.push(`请填写${tplType.name}模板字段数`)
188
-          return
189
-        }
189
+    const tplData = Object.keys(submitData).map((key) => {
190
+      const { tplId, fieldNum, tplFields, isSubscribe, ...left } = submitData[key]
191
+      const tplType = (props.tplTyps || []).filter(x => x.code === key)[0] || {}
190 192
 
191
-        console.log('--->', submitData[key])
192
-
193
-        if (tplId) {
194
-          tplData = [
195
-            ...tplData.filter(x => x.tplType !== code),
196
-            {
197
-              ...submitData[key],
198
-              tplType: code,
199
-              tplName: tplType.name,
200
-            }
201
-          ]
193
+      if (isSubscribe) {
194
+        if (tplId && !tplFields) {
195
+          errors.push(`请填写${tplType.name}模板字段内容`)
196
+          return
202 197
         }
198
+      } else if (tplId && !fieldNum) {
199
+        errors.push(`请填写${tplType.name}模板字段数`)
200
+        return
203 201
       }
202
+
203
+      return submitData[key]
204 204
     })
205 205
 
206 206
     return [tplData, errors]
@@ -208,12 +208,9 @@ const Miniapp = (props) => {
208 208
 
209 209
   const handleSubmit = val => {
210 210
     // 校验字段
211
-    const { mainbiz, newCustomer, notice, ...otherData} = val
212
-
213
-    console.log('-----val--->', val)
211
+    const { tpl, ...otherData} = val
214 212
 
215
-    const [tplData, errors] = checkTPLData(otherData)
216
-    console.log('-----tplData--->', tplData)
213
+    const [tplData, errors] = checkTPLData(tpl)
217 214
 
218 215
     if (errors.length > 0) {
219 216
       notification.error({ message: errors[0] })

+ 2
- 2
src/pages/UserManage/Editor/index.jsx Ver fichero

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