Pārlūkot izejas kodu

Merge branch 'dev' of http://git.ycjcjy.com/zhiyuxing/estateagents-admin-manager into dev

weichaochao 5 gadus atpakaļ
vecāks
revīzija
bf088a34b2

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

@@ -521,6 +521,24 @@ export default [
521 521
               },
522 522
             ],
523 523
           },
524
+          // {
525
+          //   path: '/miniapp',
526
+          //   name: '小程序管理',
527
+          //   component: '../layouts/BlankLayout',
528
+          //   routes: [
529
+          //     {
530
+          //       path: '/miniapp/menuList',
531
+          //       name: '首页菜单管理',
532
+          //       component: './miniapp/menuList',
533
+          //     },
534
+          //     {
535
+          //       path: '/miniapp/editIcons',
536
+          //       name: '首页菜单编辑',
537
+          //       hideInMenu: true,
538
+          //       component: './miniapp/editIcons',
539
+          //     },
540
+          //   ],
541
+          // },
524 542
           {
525 543
             component: './404',
526 544
           },

+ 64
- 0
src/components/SelectButton/MiniappIconSelect.jsx Parādīt failu

@@ -0,0 +1,64 @@
1
+import React, { useState, useEffect, useRef } from 'react';
2
+import { Select } from 'antd';
3
+import apis from '../../services/apis';
4
+import request from '../../utils/request'
5
+
6
+const { Option } = Select;
7
+
8
+function usePrevious(props) {
9
+  const ref = useRef();
10
+  useEffect(() => {
11
+    ref.current = props;
12
+  });
13
+  return ref.current;
14
+}
15
+
16
+/**
17
+ *
18
+ *
19
+ * @param {*} props
20
+ * @returns
21
+ */
22
+const MiniappIconSelect = props => {
23
+  const [data, setData] = useState([])
24
+  const [value, setValue] = useState([])
25
+  useEffect(() => {
26
+    getMiniappIconSelect();
27
+  }, [props.value])
28
+
29
+
30
+  const getMiniappIconSelect = e => {
31
+    request({ ...apis.icon.minippIconList, params: { pageNum: 1, pageSize: 999 } }).then(data => {
32
+        setData(data)
33
+        checkValue(data)
34
+        // 默认选中第一个
35
+    })
36
+  }
37
+
38
+
39
+  const checkValue = (data) => {
40
+    if (props.value) {
41
+      const tempData = data.filter(f => f.iconCode == props.value)
42
+      const va = (tempData.length > 0) ? props.value : ''
43
+      props.onChange(va)
44
+
45
+    }
46
+  }
47
+
48
+  return (
49
+      <Select
50
+      showSearch
51
+      value={props.value}
52
+      style={{ width: '300px' }}
53
+      placeholder="请选择功能"
54
+      onChange={props.onChange}
55
+      filterOption={(input, option) =>
56
+        option.props.children && option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
57
+      }>
58
+          {data.map(icon => (
59
+            <Option key={icon.iconCode} value={icon.iconCode}>{icon.iconName}</Option>
60
+          ))}
61
+      </Select>
62
+  )
63
+}
64
+export default MiniappIconSelect

+ 28
- 19
src/pages/building/list/add/components/base.jsx Parādīt failu

@@ -45,7 +45,7 @@ function AddBuilding(props) {
45 45
 
46 46
   const [poi, setPoi] = useState([])
47 47
   const [videoImage, setVideoImage] = useState(false)
48
-  const [priceTypeList, setPriceTypeList] = useState([])
48
+  const [typeState, setTypeState] = useState("rich")
49 49
 
50 50
   // 存放所以 buildingData 基础信息
51 51
   const [buildingData, setBuildingData] = useState({})
@@ -87,8 +87,7 @@ function AddBuilding(props) {
87 87
       // if (res.openingDate !== null) {
88 88
       //   res.openingDate = moment(res.openingDate)
89 89
       // }
90
-      //构造下拉框
91
-      setPriceTypeList(res.buildingProjectType)
90
+      setTypeState(res.highlightsType)
92 91
       if (res.receivedDate !== null) {
93 92
         res.receivedDate = moment(res.receivedDate)
94 93
       }
@@ -280,6 +279,11 @@ function AddBuilding(props) {
280 279
     })
281 280
   }
282 281
 
282
+  function highlightsTypeChange(e) {
283
+    console.log(e.target.value,"ee")
284
+    setTypeState(e.target.value)
285
+  }
286
+
283 287
   function setFormMapScopeValue(key, pois) {
284 288
     const poiArray = pois.map(p => ({
285 289
         address: p.address,
@@ -310,12 +314,6 @@ function AddBuilding(props) {
310 314
     return newPoi
311 315
   }
312 316
 
313
-  //组装项目类型
314
-  function getBuildingProjectTypeList(e) {
315
-    console.log(e,"项目类型------")
316
-    setPriceTypeList(e)
317
-  }
318
-
319 317
   function setFormMapScopeTagValue(keyType, item) {
320 318
     const tag = item.data.map(t => ({ tagName: t.name, delete: true, automatic: true }))
321 319
     switch (keyType) {
@@ -369,16 +367,11 @@ function AddBuilding(props) {
369 367
           <Form.Item label="项目类型">
370 368
             {getFieldDecorator('buildingProjectType', {
371 369
               rules: [{ required: true, message: '请选择项目类型' }],
372
-            })(<BudildingProjectType onChange={e => getBuildingProjectTypeList(e)}/>)}
370
+            })(<BudildingProjectType />)}
373 371
           </Form.Item>
374
-          <Form.Item label="列表展示均价" >
372
+          <Form.Item label="列表展示均价" help="项目列表展示价格,示例:约10000元/㎡、约1000万元/套起">
375 373
             {/* {getFieldDecorator('price')(<Input type="number" style={{ width: '210px' }}/>)}元/m² */}
376
-            {getFieldDecorator('buildingTypeId')(
377
-              <Select placeholder="请选择项目类型的价格">
378
-                    {
379
-                      priceTypeList.map((item, _) => <Option value={item.buildingTypeId}>{item.buildingTypeName}</Option>)
380
-                    }
381
-              </Select>)}
374
+            {getFieldDecorator('price')(<Input />)}
382 375
           </Form.Item>
383 376
           <Form.Item label="开盘时间" >
384 377
             {getFieldDecorator('openingDate')(<Input placeholder="预计xxxx年xx月开盘" maxLength = "15"/>)}
@@ -587,11 +580,27 @@ function AddBuilding(props) {
587 580
               <ImageUpload />,
588 581
             )}
589 582
           </Form.Item>*/}
590
-          <Form.Item label="项目亮点" >
583
+          <Form.Item label="亮点封面" help="建议尺寸690*230px,用于项目详情-项目亮点封面图">
584
+            {getFieldDecorator('highlightsCover')(
585
+              <ImageUpload />,
586
+            )}
587
+          </Form.Item>
588
+          <Form.Item label="亮点类型">
589
+            {getFieldDecorator('highlightsType')(
590
+            <Radio.Group onChange={e => highlightsTypeChange(e)}>
591
+              <Radio value="rich">自定义</Radio>
592
+              <Radio value="link">公众号链接</Radio>
593
+            </Radio.Group>,
594
+            )}
595
+          </Form.Item>
596
+          {typeState === 'link' && <Form.Item label="公众号链接" help="只能填写同一主体公众号的文章链接">
597
+            {getFieldDecorator('highlightsLink')(<Input placeholder="请输入公众号链接" />)}
598
+          </Form.Item>}
599
+          {typeState === 'rich' && <Form.Item label="亮点内容" >
591 600
             {getFieldDecorator('highlights')(
592 601
               <Wangedit />,
593 602
             )}
594
-          </Form.Item> 
603
+          </Form.Item> }
595 604
           <Form.Item style={{ width: '400px', margin: 'auto', display: 'flex', justifyContent: 'space-between' }}>
596 605
             <Button type="primary" htmlType="submit">
597 606
                 确定

+ 1
- 1
src/pages/building/list/add/components/modalPanoramaImage.jsx Parādīt failu

@@ -187,7 +187,7 @@ class ModalPanoramaImage extends React.Component {
187 187
             onCancel={e => this.handleCancel(e)}
188 188
           >
189 189
             <Form {...formItemLayout} onSubmit={e => this.handleSubmit(e)}>
190
-              <Form.Item label="全景类型">
190
+              <Form.Item label="全景类型" help="全景图展示位置: 项目详情Banner,户型介绍">
191 191
                 {getFieldDecorator('panoramaType', {
192 192
                   rules: [
193 193
                     {

+ 96
- 0
src/pages/miniapp/editIcons.jsx Parādīt failu

@@ -0,0 +1,96 @@
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 channels from '../channel/channelList.less';
5
+import MiniappIconSelect from '../../components/SelectButton/MiniappIconSelect'
6
+import XForm, { FieldTypes } from '../../components/XForm';
7
+import Wangedit from '../../components/Wangedit/Wangedit'
8
+import router from 'umi/router';
9
+import apis from '../../services/apis';
10
+import request from '../../utils/request'
11
+
12
+const { TextArea } = Input;
13
+const { Option } = Select;
14
+
15
+const header = props => {
16
+  const goodsId = props.location.query.goodsId
17
+  const [ goodsData, setGoodsData ] = useState({})
18
+  if(goodsId){
19
+    useEffect(() => {
20
+      getGoodsData(goodsId);
21
+    },[])
22
+
23
+  // 查询列表
24
+  const getGoodsData = (goodsId) => {
25
+    request({ ...apis.integralMall.taGoods, urlData: { id: goodsId },}).then((data) => {
26
+        console.log(data)
27
+        setGoodsData(data)
28
+    })
29
+  }
30
+  }
31
+
32
+  const fields = [
33
+    {
34
+      label: '请选择首页功能',
35
+      name: 'iconCode',
36
+      render: <MiniappIconSelect />,
37
+      value: goodsData.iconCode,
38
+      rules: [
39
+        {required: true, message: '请选择所属项目'},
40
+      ]
41
+    },
42
+    {
43
+      label: '功能名称',
44
+      name: 'iconName',
45
+      type: FieldTypes.Text,
46
+      value: goodsData.iconName ,
47
+      help: '不填就使用默认名称',
48
+    },
49
+    {
50
+      label: '权重',
51
+      name: 'sort',
52
+      type: FieldTypes.Number,
53
+      render: <Input type="number" style={{ width: 80}} />,
54
+      value: goodsData.sort,
55
+      rules: [
56
+        { required: true, message: '请输入权重' },
57
+      ],
58
+      help: '数字越大越靠前',
59
+    },
60
+  ]
61
+
62
+  const handleSubmit = values => {
63
+    if (values.inventory > values.totalNum) {
64
+      message.error('商品剩余数量不能大于商品总数量')
65
+      return
66
+  }
67
+
68
+    if (goodsId) {
69
+      values.goodsId = goodsId
70
+      request({ ...apis.integralMall.updateTaGoods, data: values,}).then((data) => {
71
+        cancelPage()
72
+      }).catch((err) => {
73
+        message.info(err.msg || err.message)
74
+      })
75
+      }else{
76
+      request({ ...apis.integralMall.addTaGoods, data: values,}).then((data) => {
77
+        cancelPage()
78
+      }).catch((err) => {
79
+        message.info(err.msg || err.message)
80
+      })
81
+      }
82
+  }
83
+
84
+  const cancelPage = () => {
85
+    router.push({
86
+      pathname: '/integralMall/GoodsList',
87
+    });
88
+  }
89
+
90
+  return (
91
+    <XForm onSubmit={handleSubmit} onCancel={cancelPage} fields={fields}></XForm>
92
+  )
93
+}
94
+
95
+const WrappedNormalLoginForm = Form.create({ name: 'header' })(header);
96
+export default WrappedNormalLoginForm

+ 220
- 0
src/pages/miniapp/menuList.jsx Parādīt failu

@@ -0,0 +1,220 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Form, Input, Button, Icon, Select, message, Table, Divider, Tag, Pagination, Modal,Breadcrumb } from 'antd';
3
+import { FormattedMessage } from 'umi-plugin-react/locale';
4
+import styles from '../style/GoodsList.less';
5
+import router from 'umi/router';
6
+import BuildSelect from '../../components/SelectButton/BuildSelect'
7
+import apis from '../../services/apis';
8
+import request from '../../utils/request'
9
+import AuthButton from '@/components/AuthButton';
10
+
11
+const { Option } = Select;
12
+
13
+
14
+function header(props) {
15
+  // 获取初始化数据
16
+  const [ data, setData ] = useState({})
17
+
18
+  useEffect(() => {
19
+    getList({ pageNum: 1, pageSize: 10 });
20
+  },[])
21
+
22
+  // 查询列表
23
+  const getList = (params) => {
24
+    request({ ...apis.integralMall.getTaGoods, params: { ...params },}).then((data) => {
25
+        console.log(data)
26
+        setData(data)
27
+    })
28
+  }
29
+  
30
+  // 提交事件
31
+  const handleSubmit = (e, props) => {
32
+    e.preventDefault();
33
+    props.form.validateFields((err, values) => {
34
+      if (!err) {
35
+        getList({ pageNum: 1, pageSize: 10, ...values })
36
+      }
37
+    });
38
+  }
39
+
40
+  const changePageNum = (pageNumber) => {
41
+    props.form.validateFields((err, values) => {
42
+      if (!err) {
43
+        getList({ pageNumber: pageNumber, pageSize: 10, ...values })
44
+      }
45
+    });
46
+  }
47
+
48
+  function handleReset() {
49
+    props.form.resetFields();
50
+    getList({ pageNum: 1, pageSize: 10 });
51
+  }
52
+
53
+  // 跳转到编辑商品
54
+  const toEditIcons = (goodsId) => () => {
55
+    router.push({
56
+      pathname: '/miniapp/editIcons',
57
+      query: {
58
+        goodsId
59
+      },
60
+    });
61
+  }
62
+
63
+  
64
+  const changeGoodsStatus = (row) => () => {
65
+    const title = row.status === 1 ? '商品在小程序端隐藏,后台可继续编辑重新发布?':'商品会重新显示在小程序端?'
66
+
67
+    Modal.confirm({
68
+      title: title,
69
+      okText: '确认',
70
+      cancelText: '取消',
71
+      onOk() {
72
+        request({ ...apis.integralMall.changeTaGoods, data: { ...row },}).then((data) => {
73
+          message.info('操作成功!')
74
+          getList({ pageNum: 1, pageSize: 10, ...props.form.getFieldsValue() });
75
+        })
76
+      }
77
+    });
78
+  }
79
+  /**
80
+   *
81
+   *
82
+   * @param {*} props
83
+   * @returns
84
+   */
85
+  const columns = [
86
+    {
87
+      title: '商品图片',
88
+      dataIndex: 'imgUrl',
89
+      key: 'imgUrl',
90
+      align: 'center',
91
+      render: (text, record) => <img src={record.imgUrl} className={styles.touxiang} />,
92
+    },
93
+    {
94
+      title: '商品名称',
95
+      dataIndex: 'goodsName',
96
+      key: 'goodsName',
97
+      align: 'center',
98
+
99
+    },
100
+    {
101
+      title: '所属积分',
102
+      dataIndex: 'pointPrice',
103
+      key: 'pointPrice',
104
+      align: 'center',
105
+    },
106
+    {
107
+      title: '总数量',
108
+      dataIndex: 'totalNum',
109
+      key: 'totalNum',
110
+      align: 'center',
111
+    },
112
+    {
113
+      title: '已兑换数量',
114
+      dataIndex: 'exchanged',
115
+      key: 'exchanged',
116
+      align: 'center',
117
+      render: (x,row) => <><span>{row.totalNum - row.inventory}</span></>
118
+    },
119
+    {
120
+      title: '剩余数量',
121
+      dataIndex: 'inventory',
122
+      key: 'inventory',
123
+      align: 'center',
124
+    },
125
+    {
126
+      title: '状态',
127
+      dataIndex: 'status',
128
+      key: 'status',
129
+      align: 'center',
130
+      render: (status)=> <><span>{status == 1 ? '已上架' : '已下架'}</span></>
131
+    },
132
+    {
133
+      title: '操作',
134
+      dataIndex: 'handle',
135
+      key: 'handle',
136
+      align: 'center',
137
+      render: (x, row) => (
138
+        <>
139
+          <AuthButton name="admin.taGoods.change.put" noRight={null}>
140
+            <span style={{ color: '#EF273A', marginRight: '20px',cursor: 'pointer' }} onClick={changeGoodsStatus(row)}>
141
+              {row.status == 1 ? '下架' : '上架'}
142
+              {<Icon type="shopping-cart" className={styles.shoppingCart} />}
143
+            </span>
144
+          </AuthButton>
145
+          <AuthButton name="admin.taGoods.put" noRight={null}>
146
+            <span style={{ color: '#FF925C',cursor: 'pointer' }} onClick={toEditIcons(row.goodsId)}>
147
+              编辑<Icon type="form" className={styles.edit} />
148
+            </span>
149
+          </AuthButton>
150
+        </>
151
+      ),
152
+    },
153
+  ];
154
+
155
+  const { getFieldDecorator } = props.form
156
+  return (
157
+
158
+    <>
159
+      <Form layout="inline" onSubmit={e => handleSubmit(e, props)}>
160
+        <Form.Item>
161
+          {getFieldDecorator('goodsName')(
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('status')(
170
+            <Select style={{ width: '180px' }} placeholder="状态">
171
+              <Option value="1">已上架</Option>
172
+              <Option value="0">已下架</Option>
173
+            </Select>,
174
+          )}
175
+        </Form.Item>
176
+        <Form.Item>
177
+          {getFieldDecorator('buildingId')(
178
+            <BuildSelect />,
179
+          )}
180
+        </Form.Item>
181
+        <Form.Item>
182
+          {getFieldDecorator('priceLesser')(
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('priceGreater')(
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
+            <AuthButton name="admin.taGoods.search" noRight={null}>
199
+              <Button type="primary" htmlType="submit" className={styles.searchBtn}>
200
+                搜索
201
+              </Button>
202
+            </AuthButton>
203
+            <Button style={{ marginLeft: 8 }} onClick={handleReset}>
204
+              重置
205
+            </Button>
206
+        </Form.Item>
207
+      </Form>
208
+      <AuthButton name="admin.taGoods.add.post" noRight={null}>
209
+        <Button type="danger" className={styles.addBtn} onClick={toEditIcons()}>新增</Button>
210
+      </AuthButton>
211
+      <Table rowKey="goodsList" dataSource={data.records} columns={columns} pagination={false} />
212
+      <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '30px' }}>
213
+        <Pagination showQuickJumper defaultCurrent={1} total={data.total} onChange={changePageNum} current={data.current}/>
214
+      </div>
215
+    </>
216
+  )
217
+}
218
+const WrappedHeader = Form.create({ name: 'header' })(header);
219
+
220
+export default WrappedHeader

+ 1
- 0
src/pages/news/list/editNewsList.jsx Parādīt failu

@@ -110,6 +110,7 @@ const Basic = (props) => {
110 110
       type: FieldTypes.Text,
111 111
       hidden: () => !urlVisible,
112 112
       value: dynamicData.newsDetail,
113
+      help: "只能填写同一主体公众号的文章链接",
113 114
       rules: [
114 115
         {required: true, message: '请输入公众号链接'},
115 116
       ]

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

@@ -1070,6 +1070,13 @@ export default {
1070 1070
     action: 'admin.panorama.id.delete',
1071 1071
   }
1072 1072
  },
1073
+ icon: {
1074
+  minippIconList: {
1075
+    url: `${prefix}/taMiniappIcon`,
1076
+    method: 'GET',
1077
+    action: 'admin.taMiniappIcon.get',
1078
+  },
1079
+ },
1073 1080
  amap: { // 高德地图
1074 1081
    webService: { // Web服务Api ---- 周边搜索
1075 1082
      url: `${amapPrefix}/place/around`,