张延森 4 vuotta sitten
vanhempi
commit
cc1617bb4e

+ 80
- 0
src/pages/mpSetting/components/MainSeting.jsx Näytä tiedosto

@@ -0,0 +1,80 @@
1
+import React, { useEffect, useState } from 'react'
2
+import { Form, Modal, Button, Input, InputNumber, Select, Radio } from 'antd'
3
+import { fetch, apis } from '@/utils/request'
4
+import MiniAppMedia from './MiniAppMedia'
5
+
6
+const formItemLayout = {
7
+  labelCol: {
8
+    xs: { span: 24 },
9
+    sm: { span: 6 },
10
+  },
11
+  wrapperCol: {
12
+    xs: { span: 24 },
13
+    sm: { span: 12 },
14
+  },
15
+}
16
+
17
+const tailFormItemLayout = {
18
+  wrapperCol: {
19
+    xs: {
20
+      span: 24,
21
+      offset: 0,
22
+    },
23
+    sm: {
24
+      span: 16,
25
+      offset: 6,
26
+    },
27
+  },
28
+}
29
+
30
+export default Form.create()(props => {
31
+  const handleMiniAppChange = vals => {
32
+    setDetailData({
33
+      ...props.value,
34
+      miniappMedia: vals.mediaId,
35
+      miniappUrl: vals.url
36
+    })
37
+  }
38
+
39
+  useEffect(() => {
40
+    props.form.setFieldsValue(props.value)
41
+  }, [props.value])
42
+
43
+  return (
44
+    <div>
45
+      <Form {...formItemLayout}>
46
+        {/* <Form.Item label="名称">
47
+          {
48
+            props.form.getFieldDecorator('name')(<Input placeholder="请填写名称" readOnly />)
49
+          }
50
+        </Form.Item> */}
51
+        <Form.Item label="APPID">
52
+          {
53
+            props.form.getFieldDecorator('appid')(<Input placeholder="请填写 APPID" readOnly />)
54
+          }
55
+        </Form.Item>
56
+        <Form.Item label="SECRET">
57
+          {
58
+            props.form.getFieldDecorator('secret')(<Input placeholder="请填写 SECRET" readOnly />)
59
+          }
60
+        </Form.Item>
61
+        <Form.Item label="TOKEN">
62
+          {
63
+            props.form.getFieldDecorator('token')(<Input placeholder="请填写 TOKEN" readOnly />)
64
+          }
65
+        </Form.Item>
66
+        <Form.Item label="AES_KEY">
67
+          {
68
+            props.form.getFieldDecorator('aesKey')(<Input placeholder="请填写 AES_KEY" readOnly />)
69
+          }
70
+        </Form.Item>
71
+        <Form.Item label="小程序封面" help="仅支持JPG图片,建议大小为520*416">
72
+          <div>
73
+            {props.value.miniappMedia && <span style={{display: 'inline-block', marginRight: '24px'}}>{props.value.miniappMedia}</span>}
74
+            <MiniAppMedia onChange={handleMiniAppChange} />
75
+          </div>
76
+        </Form.Item>
77
+      </Form>
78
+    </div>
79
+  )
80
+})

+ 103
- 0
src/pages/mpSetting/components/TemplateItem.jsx Näytä tiedosto

@@ -0,0 +1,103 @@
1
+import React, { useEffect, useState } from 'react'
2
+import { Button, Input, Menu, Dropdown, Select, Modal, Icon } from 'antd'
3
+import { fetch, apis } from '@/utils/request'
4
+
5
+export default props => {
6
+  const [isInDB, setIsInDB] = useState(false)
7
+  const [typeInfo, setTypeInfo] = useState({})
8
+  const [dataSource, setDataSource] = useState({})
9
+  const [typeDict, setTypeDict] = useState([
10
+    {typeCode: 'birthday', typeName: '生日'},
11
+    {typeCode: 'festival', typeName: '节日'},
12
+  ])
13
+
14
+  const handleChange = e => {
15
+    const templateCode = e.target.value
16
+    setDataSource({
17
+      ...dataSource,
18
+      templateCode
19
+    })
20
+  }
21
+
22
+  const handleTypeChange = e => {
23
+    const val = typeDict.filter(x => x.typeCode === e)[0] || {}
24
+    setTypeInfo(val)
25
+  }
26
+
27
+  const handleSubmit = () => {
28
+    if (props.onChange) {
29
+      props.onChange({
30
+        ...dataSource,
31
+        ...typeInfo,
32
+      })
33
+    }
34
+  }
35
+
36
+  const handleOverMenuClick = e => {
37
+    if (e.key === 'delete') {
38
+      if (!isInDB) {
39
+        if (props.onDelete) {
40
+          props.onDelete(dataSource)
41
+        }
42
+      } else {
43
+        if (props.onDelete) {
44
+          Modal.confirm({
45
+            title: '确认删除当前记录?',
46
+            okType: 'danger',
47
+            onOk: () => {
48
+              props.onDelete(dataSource)
49
+            }
50
+          })
51
+        }
52
+      }
53
+    }
54
+  }
55
+
56
+  const OverMenu = (
57
+    <Menu onClick={handleOverMenuClick}>
58
+      <Menu.Item key="delete">删除</Menu.Item>
59
+    </Menu>
60
+  )
61
+
62
+  useEffect(() => {
63
+    const val = props.value || {}
64
+    setDataSource({...val})
65
+    setTypeInfo({
66
+      typeCode: val.typeCode,
67
+      typeName: val.typeName,
68
+    })
69
+    setIsInDB(val.serialNo && `${val.serialNo}`.indexOf('tmp') === -1)
70
+  }, [props.value])
71
+
72
+  return (
73
+    <Input.Group compact size="large">
74
+      <Select
75
+        size="large"
76
+        disabled={isInDB}
77
+        value={typeInfo.typeCode}
78
+        onChange={handleTypeChange}
79
+        style={{width: '15%'}}
80
+        placeholder="请选择分类"
81
+      >
82
+        {
83
+          typeDict.map(typ => (<Select.Option key={typ.typeCode} value={typ.typeCode}>{typ.typeName}</Select.Option>))
84
+        }
85
+      </Select>
86
+      <Input
87
+        value={dataSource.templateCode}
88
+        onChange={handleChange}
89
+        style={{width: '70%'}}
90
+        placeholder="请填写消息模板ID"
91
+        />
92
+      <Dropdown.Button
93
+         size="large"
94
+        overlay={OverMenu}
95
+        onClick={handleSubmit}
96
+        icon={<Icon type="down" />}
97
+        style={{width: '15%'}}
98
+      >
99
+        提交
100
+      </Dropdown.Button>
101
+    </Input.Group>
102
+  )
103
+}

+ 90
- 0
src/pages/mpSetting/components/TemplateSetting.jsx Näytä tiedosto

@@ -0,0 +1,90 @@
1
+import React, { useEffect, useState } from 'react'
2
+import { List, Input, Button, notification } from 'antd'
3
+import { fetch, apis, fetchList } from '@/utils/request'
4
+import TemplateItem from './TemplateItem'
5
+
6
+const getTemplateList = fetchList(apis.mp.template.list)
7
+const saveTemplate = fetch(apis.mp.template.save)
8
+const updateTemplate = fetch(apis.mp.template.update)
9
+const deleteTemplate = fetch(apis.mp.template.delete)
10
+
11
+export default props => {
12
+  const [loading, setLoading] = useState(false)
13
+  const [listData, setListData] = useState([])
14
+  const [query, setQuery] = useState({pageSize: 999})
15
+
16
+  const isTemp = x => !x.serialNo || `${x.serialNo}`.indexOf('tmp') > -1
17
+
18
+  const handleAdd = () => {
19
+    const template = {
20
+      orgId: props.value.orgI,
21
+      appid: props.value.appid,
22
+      typeCode: undefined,
23
+      typeName: undefined,
24
+      templateCode: undefined,
25
+      serialNo: `tmp-${Math.random().toString(36).substring(2)}`
26
+    }
27
+
28
+    setListData([template].concat(listData))
29
+  }
30
+
31
+  const handleRowChange = row => {
32
+    if (isTemp(row)) {
33
+      saveTemplate({data: {
34
+        ...row,
35
+        serialNo: undefined,
36
+      }}).then(res => {
37
+        notification.success({message: '保存信息成功'})
38
+        setQuery({...query})
39
+      })
40
+    } else {
41
+      updateTemplate({data: row, urlData: {id: row.serialNo}}).then(res => {
42
+        notification.success({message: '更新信息成功'})
43
+        setQuery({...query})
44
+      })
45
+    }
46
+  }
47
+
48
+  const handleRowDelete = row => {
49
+    if (isTemp(row)) {
50
+      setListData(listData.filter(x => x.serialNo !== row.serialNo))
51
+    } else {
52
+      deleteTemplate({urlData: {id: row.serialNo}}).then(res => {
53
+        notification.success({message: '删除信息成功'})
54
+        setQuery({...query})
55
+      })
56
+    }
57
+  }
58
+
59
+  useEffect(() => {
60
+    setLoading(true)
61
+    getTemplateList(query).then(res => {
62
+      const [list] = res
63
+      setListData(list || [])
64
+      setLoading(false)
65
+    }).catch(() => setLoading(false))
66
+  }, [query])
67
+
68
+
69
+  return (
70
+    <div>
71
+      <Button onClick={handleAdd}>新增</Button>
72
+      <div style={{maxWidth: '800px', marginTop: '16px' }}>
73
+        <List
74
+          loading={loading}
75
+          dataSource={listData}
76
+          size="large"
77
+          bordered={false}
78
+          itemLayout="horizontal"
79
+          renderItem={item => {
80
+            return (
81
+              <List.Item>
82
+                  <TemplateItem value={item} onChange={handleRowChange} onDelete={handleRowDelete} />
83
+              </List.Item>
84
+            )
85
+          }}
86
+        />
87
+      </div>
88
+    </div>
89
+  )
90
+}

+ 13
- 70
src/pages/mpSetting/index.jsx Näytä tiedosto

@@ -1,88 +1,31 @@
1 1
 import React, { useEffect, useState } from 'react'
2
-import { Form, Modal, Button, Input, InputNumber, Select, Radio, PageHeader } from 'antd'
2
+import { Form, Modal, Button, Input, InputNumber, Select, Radio, PageHeader, Tabs } from 'antd'
3 3
 import { fetch, apis } from '@/utils/request'
4
-import MiniAppMedia from './components/MiniAppMedia'
5
-
6
-const formItemLayout = {
7
-  labelCol: {
8
-    xs: { span: 24 },
9
-    sm: { span: 6 },
10
-  },
11
-  wrapperCol: {
12
-    xs: { span: 24 },
13
-    sm: { span: 12 },
14
-  },
15
-}
16
-
17
-const tailFormItemLayout = {
18
-  wrapperCol: {
19
-    xs: {
20
-      span: 24,
21
-      offset: 0,
22
-    },
23
-    sm: {
24
-      span: 16,
25
-      offset: 6,
26
-    },
27
-  },
28
-}
4
+import MainSeting from './components/MainSeting'
5
+import TemplateSetting from './components/TemplateSetting'
29 6
 
30 7
 const mpDetail = fetch(apis.mp.detail)
31 8
 
32
-export default Form.create()(props => {
9
+export default props => {
33 10
   const [detailData, setDetailData] = useState({})
34 11
 
35
-  const handleMiniAppChange = vals => {
36
-    setDetailData({
37
-      ...detailData,
38
-      miniappMedia: vals.mediaId,
39
-      miniappUrl: vals.url
40
-    })
41
-  }
42
-
43 12
   useEffect(() => {
44 13
     mpDetail().then(res => {
45 14
       setDetailData(res)
46
-      props.form.setFieldsValue(res)
47 15
     })
48 16
   }, [])
49 17
 
50 18
   return (
51 19
     <div>
52 20
       <PageHeader title="公众号设置" backIcon={false} />
53
-      <Form {...formItemLayout}>
54
-        {/* <Form.Item label="名称">
55
-          {
56
-            props.form.getFieldDecorator('name')(<Input placeholder="请填写名称" readOnly />)
57
-          }
58
-        </Form.Item> */}
59
-        <Form.Item label="APPID">
60
-          {
61
-            props.form.getFieldDecorator('appid')(<Input placeholder="请填写 APPID" readOnly />)
62
-          }
63
-        </Form.Item>
64
-        <Form.Item label="SECRET">
65
-          {
66
-            props.form.getFieldDecorator('secret')(<Input placeholder="请填写 SECRET" readOnly />)
67
-          }
68
-        </Form.Item>
69
-        <Form.Item label="TOKEN">
70
-          {
71
-            props.form.getFieldDecorator('token')(<Input placeholder="请填写 TOKEN" readOnly />)
72
-          }
73
-        </Form.Item>
74
-        <Form.Item label="AES_KEY">
75
-          {
76
-            props.form.getFieldDecorator('aesKey')(<Input placeholder="请填写 AES_KEY" readOnly />)
77
-          }
78
-        </Form.Item>
79
-        <Form.Item label="小程序封面" help="仅支持JPG图片,建议大小为520*416">
80
-          <div>
81
-            {detailData.miniappMedia && <span style={{display: 'inline-block', marginRight: '24px'}}>{detailData.miniappMedia}</span>}
82
-            <MiniAppMedia onChange={handleMiniAppChange} value={detailData.miniapp_url} />
83
-          </div>
84
-        </Form.Item>
85
-      </Form>
21
+      <Tabs defaultActiveKey="1">
22
+        <Tabs.TabPane tab="基础设置" key="1">
23
+          <MainSeting value={detailData} />
24
+        </Tabs.TabPane>
25
+        <Tabs.TabPane tab="模板设置" key="2">
26
+          <TemplateSetting value={detailData} />
27
+        </Tabs.TabPane>
28
+      </Tabs>
86 29
     </div>
87 30
   )
88
-})
31
+}

+ 23
- 1
src/services/apis.js Näytä tiedosto

@@ -21,7 +21,7 @@ export default {
21 21
   propNews: propNews(prefix),
22 22
   mp: {
23 23
     detail: {
24
-      url: `${prefix}/mp/taMpInfo`,
24
+      url: `${prefix}/taMpInfo`,
25 25
       method: 'GET',
26 26
       action: 'admin.taMpInfo.get',
27 27
     },
@@ -29,6 +29,28 @@ export default {
29 29
       url: `${prefix}/mp/material/miniapp`,
30 30
       method: 'POST',
31 31
       action: 'admin.mp-material.miniapp',
32
+    },
33
+    template: {
34
+      list: {
35
+        url: `${prefix}/taMpTemplate`,
36
+        method: 'GET',
37
+        action: 'admin.taMpTemplate.get',
38
+      },
39
+      save: {
40
+        url: `${prefix}/taMpTemplate`,
41
+        method: 'POST',
42
+        action: 'admin.taMpTemplate.post',
43
+      },
44
+      update: {
45
+        url: `${prefix}/taMpTemplate/:id`,
46
+        method: 'PUT',
47
+        action: 'admin.taMpTemplate.put',
48
+      },
49
+      delete: {
50
+        url: `${prefix}/taMpTemplate/:id`,
51
+        method: 'DELETE',
52
+        action: 'admin.taMpTemplate.delete',
53
+      },
32 54
     }
33 55
   },
34 56
   person: {