Browse Source

全景图新需求

傅行帆 5 years ago
parent
commit
85306ab5bf

+ 1
- 1
package.json View File

@@ -63,7 +63,7 @@
63 63
     "react-dom": "^16.8.6",
64 64
     "react-zmage": "^0.8.5",
65 65
     "redux": "^4.0.1",
66
-    "umi": "^2.8.7",
66
+    "umi": "^2.13.3",
67 67
     "umi-plugin-pro-block": "^1.3.2",
68 68
     "umi-plugin-react": "^1.9.5",
69 69
     "umi-request": "^1.0.8",

+ 249
- 0
src/pages/building/list/add/components/modalPanoramaImage.jsx View File

@@ -0,0 +1,249 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Form, Icon, Input, Button, DatePicker, Select, Card, Row, Col, Pagination, Alert, Table, Avatar, Radio, Modal, Descriptions, notification } from 'antd';
3
+import moment from 'moment';
4
+import request from '../../../../../utils/request';
5
+import apis from '../../../../../services/apis';
6
+import Styles from '../style.less';
7
+import ImageUpload from '../../../../../components/XForm/ImageUpload'
8
+import ImageListUpload from '../../../../../components/XForm/ImageListUpload'
9
+import Wangedit from '../../../../../components/Wangedit/Wangedit'
10
+
11
+
12
+const { Option } = Select;
13
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
14
+const { Meta } = Card;
15
+
16
+const { TextArea } = Input;
17
+
18
+const formItemLayout = {
19
+  labelCol: {
20
+    xs: { span: 24 },
21
+    sm: { span: 2 },
22
+  },
23
+  wrapperCol: {
24
+    xs: { span: 24 },
25
+    sm: { span: 16 },
26
+  },
27
+};
28
+
29
+const saleType = [
30
+  {
31
+    id: 1,
32
+    name: '待售',
33
+  },
34
+  {
35
+    id: 2,
36
+    name: '售罄',
37
+  },
38
+  {
39
+    id: 3,
40
+    name: '在售',
41
+  },
42
+]
43
+
44
+const houseType = [
45
+  {
46
+    id: '1',
47
+    name: '1室',
48
+  },
49
+  {
50
+    id: '2',
51
+    name: '2室',
52
+  },
53
+  {
54
+    id: '3',
55
+    name: '3室',
56
+  },
57
+  {
58
+    id: '4',
59
+    name: '4室',
60
+  },
61
+  {
62
+    id: '5',
63
+    name: '5室及以上',
64
+  },
65
+]
66
+  
67
+/**
68
+ * 图片信息
69
+ *
70
+ * @param {*} props
71
+ * @returns
72
+ */
73
+class ModalPanoramaImage extends React.Component {
74
+  constructor(props) {
75
+    super(props);
76
+    this.state = {
77
+       visibleData: { visible: false, apartmentId: '', buildingId: '',panoramaType: "apartment" },
78
+    }
79
+  }
80
+
81
+  // 挂载之后
82
+  // componentDidMount() {
83
+  //
84
+  // }
85
+
86
+  componentDidUpdate(preProps, preState) {
87
+    if (this.props.visibleData.visible !== preState.visibleData.visible) {
88
+      console.log(this.props.visibleData)
89
+      this.getById()
90
+      this.setState({ visibleData: this.props.visibleData });
91
+    }
92
+  }
93
+
94
+  // 弹框确定按钮
95
+  // eslint-disable-next-line react/sort-comp
96
+  handleOk() {
97
+    this.setState({ visibleData: { visible: false, apartmentId: '', buildingId: '' } })
98
+  }
99
+
100
+  // 弹框取消按钮
101
+  handleCancel() {
102
+    this.setState({ visibleData: { visible: false, apartmentId: '', buildingId: '' } })
103
+  }
104
+
105
+  getById(params) {
106
+    const { apartmentId } = this.props.visibleData
107
+    if (apartmentId === '' || apartmentId === undefined) {
108
+      return
109
+    }
110
+
111
+    // 网路请求
112
+    request({ ...apis.building.buildingApartmentGetById, urlData: { id: apartmentId }, params: { ...params } }).then(res => {
113
+      // res.img = res.buildingImgList.map(item => item.url)
114
+      if (res.buildingImgList) {
115
+        res.img = res.buildingImgList[0].url
116
+      }
117
+      
118
+      this.props.form.setFieldsValue(res)
119
+    }).catch(err => {
120
+     this.openNotificationWithIcon('error', err)
121
+    })
122
+  }
123
+
124
+  openNotificationWithIcon = (type, message) => {
125
+    notification[type]({
126
+      message,
127
+      description:
128
+        '',
129
+    });
130
+  };
131
+
132
+  // 提交
133
+  handleSubmit(e) {
134
+    e.preventDefault();
135
+    this.props.form.validateFields((err, values) => {
136
+      if (!err) {
137
+        this.submitData(values)
138
+      }
139
+    });
140
+  }
141
+
142
+  submitData(data) {
143
+    data.buildingId = this.props.visibleData.buildingId;
144
+    const api = apis.paorama.add;
145
+
146
+    // 网路请求
147
+    request({ ...api, data: { ...data } }).then(() => {
148
+      // eslint-disable-next-line no-unused-expressions
149
+      this.openNotificationWithIcon('success', '操作成功')
150
+
151
+      // 传递父组件事件
152
+      // onSuccess() 是自定义
153
+      this.props.onSuccess()
154
+
155
+      // this.setState({ visibleData: { visible: false, apartmentId: '', buildingId: '' } }, () => console.log('回调:', this.state.visibleData))
156
+    }).catch(err => {
157
+      // eslint-disable-next-line no-unused-expressions
158
+      this.openNotificationWithIcon('error', err)
159
+    })
160
+  }
161
+
162
+  radioOnChange(e) {
163
+    this.setState({ visibleData: { ...this.state.visibleData, panoramaType: e.target.value } })
164
+  }
165
+
166
+  /**
167
+   * 取消按钮
168
+   *
169
+   * @memberof ModalImage
170
+   */
171
+  closeModal() {
172
+    this.setState({ visibleData: { visible: false, apartmentId: '', buildingId: '' } })
173
+  }
174
+
175
+  render() {
176
+    const { getFieldDecorator } = this.props.form;
177
+    return (
178
+      <>
179
+        <Modal
180
+            title="新增全景图"
181
+            width={1100}
182
+            destroyOnClose="true"
183
+            footer={null}
184
+            visible={this.state.visibleData.visible}
185
+            onOk={() => this.handleOk()}
186
+            onCancel={e => this.handleCancel(e)}
187
+          >
188
+            <Form {...formItemLayout} onSubmit={e => this.handleSubmit(e)}>
189
+              <Form.Item label="全景类型">
190
+                {getFieldDecorator('panoramaType', {
191
+                  rules: [
192
+                    {
193
+                      required: true,
194
+                      message: '请选择全景类型',
195
+                    },
196
+                  ],
197
+                })(
198
+                  <Radio.Group onChange={(e) => this.radioOnChange(e)}>
199
+                    <Radio value="apartment">户型</Radio>
200
+                    <Radio value="building">项目</Radio>
201
+                  </Radio.Group>,
202
+                )}
203
+              </Form.Item>
204
+              { this.state.visibleData.panoramaType == "apartment" && <Form.Item label="全景内容">
205
+                {getFieldDecorator('apartmentId', {
206
+                  rules: [{ required: true, message: '请选择全景内容' }],
207
+                })(
208
+                  <Select placeholder="户型">
209
+                    {
210
+                      (this.state.visibleData.panoramaList || []).map((item, _) => <Option value={item.apartmentId}>{item.apartmentName}</Option>)
211
+                    }
212
+                  </Select>,
213
+                )}
214
+              </Form.Item>}
215
+              { this.state.visibleData.panoramaType == "building" && <Form.Item label="全景内容">
216
+                {getFieldDecorator('content', {
217
+                  rules: [{ required: true, message: '请输入全景内容' }],
218
+                })(
219
+                  <Input />,
220
+                )}
221
+              </Form.Item>}
222
+              <Form.Item label="选择封面" help="建议图片尺寸750px*600px,比例5:4,格式:jpg">
223
+              {getFieldDecorator('coverImg', {
224
+                  rules: [{ required: true, message: '请上传封面图片' }],
225
+              })(
226
+                // <ImageListUpload />,
227
+                <ImageUpload />,
228
+              )}
229
+              </Form.Item>
230
+              <Form.Item label="链接地址">
231
+                {getFieldDecorator('panoramaLink', {
232
+                  rules: [{ required: true, message: '请输入链接地址' }],
233
+                })(<Input />)}
234
+              </Form.Item>
235
+              <Form.Item style={{ width: '400px', margin: 'auto', display: 'flex', justifyContent: 'space-between' }}>
236
+                <Button type="primary" htmlType="submit">保存</Button>
237
+                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
238
+                <Button onClick={() => this.closeModal()}>取消</Button>
239
+              </Form.Item>
240
+            </Form>
241
+        </Modal>
242
+      </>
243
+    );
244
+  }
245
+}
246
+
247
+const WrappedModalPanoramaImageForm = Form.create({ name: 'modalPanoramaImage' })(ModalPanoramaImage);
248
+
249
+export default WrappedModalPanoramaImageForm

+ 182
- 0
src/pages/building/list/add/components/panoramaImage.jsx View File

@@ -0,0 +1,182 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Form, Icon, Input, Button, DatePicker, Select, Card, Row, Col, Pagination, Alert, Radio, Tag, Tooltip, Tabs, Table, notification, Modal } from 'antd';
3
+import moment from 'moment';
4
+import request from '../../../../../utils/request';
5
+import apis from '../../../../../services/apis';
6
+import Styles from '../style.less';
7
+import { router } from 'umi';
8
+import ModalPanoramaImage from './modalPanoramaImage';
9
+
10
+const { confirm } = Modal;
11
+
12
+
13
+const saleType = [
14
+  {
15
+    id: 1,
16
+    name: '待售',
17
+  },
18
+  {
19
+    id: 2,
20
+    name: '售罄',
21
+  },
22
+  {
23
+    id: 3,
24
+    name: '在售',
25
+  },
26
+]
27
+
28
+const houseType = [
29
+  {
30
+    id: 1,
31
+    name: '1室',
32
+  },
33
+  {
34
+    id: 2,
35
+    name: '2室',
36
+  },
37
+  {
38
+    id: 3,
39
+    name: '3室',
40
+  },
41
+  {
42
+    id: 4,
43
+    name: '4室',
44
+  },
45
+  {
46
+    id: 5,
47
+    name: '5室及以上',
48
+  },
49
+]
50
+
51
+/**
52
+ *图片设置
53
+ *
54
+ * @param {*} props
55
+ * @returns
56
+ */
57
+function panoramaImage(props) {
58
+  // eslint-disable-next-line react-hooks/rules-of-hooks
59
+  const [data, setData] = useState([])
60
+
61
+  // eslint-disable-next-line react-hooks/rules-of-hooks
62
+  const [visibleData, setVisibleData] = useState({ visible: false, apartmentId: '', buildingId: '' })
63
+
64
+  // eslint-disable-next-line react-hooks/rules-of-hooks
65
+  useEffect(() => {
66
+    getList()
67
+  }, [])
68
+
69
+  function openNotificationWithIcon(type, message) {
70
+    notification[type]({
71
+      message,
72
+      description:
73
+        '',
74
+    });
75
+  }
76
+
77
+  function getList(params) {
78
+    // 网路请求
79
+    request({ ...apis.paorama.list, urlData: { id: props.building.buildingId }, params: { ...params, apartmentType: 'apart' } }).then(res => {
80
+      setData(res)
81
+    }).catch(err => {
82
+      openNotificationWithIcon('error', err.message)
83
+    })
84
+  }
85
+
86
+  /**
87
+   *回调事件
88
+   *
89
+   */
90
+  function onModalChange() {
91
+    getList()
92
+    setVisibleData({ visible: false, apartmentId: '', buildingId: '' })
93
+  }
94
+
95
+  /**
96
+   *打开编辑页
97
+   *
98
+   * @param {*} record
99
+   */
100
+  function showEdi(record) {
101
+    // 网路请求
102
+    request({ ...apis.paorama.panoramaApartList, params: { buildingId:  props.building.buildingId } }).then(res => {
103
+      setVisibleData({ visible: true, apartmentId: record === undefined ? '' : record.apartmentId, buildingId: props.building.buildingId, panoramaType: "apartment", panoramaList: res })
104
+     }).catch(err => {
105
+      this.openNotificationWithIcon('error', err)
106
+     })
107
+  }
108
+
109
+  /**
110
+   * 删除
111
+   *
112
+   * @param {*} record
113
+   */
114
+  function deleteApartment(record) {
115
+    confirm({
116
+      title: '确认删除当前数据?',
117
+      content: '确定后成功删除,点击取消则放弃当前操作',
118
+      okText: '确定',
119
+      cancelText: '取消',
120
+      onOk() {
121
+        // 网路请求
122
+        request({ ...apis.paorama.delete, urlData: { id: record.panoramaId } }).then(res => {
123
+          getList()
124
+          openNotificationWithIcon('success', '操作成功')
125
+        }).catch(err => {
126
+          // openNotificationWithIcon('error', err.message)
127
+        })
128
+      },
129
+      onCancel() {},
130
+    });
131
+  }
132
+
133
+
134
+  const columns = [
135
+    {
136
+      title: '封面图',
137
+      dataIndex: 'coverImg',
138
+      key: 'coverImg',
139
+      render: (x, record) =>  <img style={{ width: '150px', height: '120px' }} src={x} alt="" />,
140
+    },
141
+    {
142
+      title: '类型',
143
+      dataIndex: 'panoramaType',
144
+      key: 'panoramaType',
145
+      render: (x, record) => <span>{x === "apartment" ? "户型" : "项目"}</span>,
146
+    },
147
+    {
148
+      title: '内容',
149
+      dataIndex: 'content',
150
+      key: 'content',
151
+    },
152
+    {
153
+      title: '链接地址',
154
+      dataIndex: 'panoramaLink',
155
+      key: 'panoramaLink',
156
+    },
157
+    {
158
+      title: '操作',
159
+      dataIndex: 'apartmentId',
160
+      key: 'apartmentId',
161
+      render: (_, record) => (
162
+        <>
163
+          <Button type="link" style={{ color: 'red' }} onClick={() => deleteApartment(record)}>删除</Button>
164
+        </>
165
+      ),
166
+    },
167
+  ]
168
+
169
+  return (
170
+    <>
171
+      <Button type="primary" onClick={() => showEdi()}>新增全景图</Button>
172
+      <Button type="danger" style={{ marginLeft: '18px'}} onClick={() => router.go(-1)}>返回</Button>
173
+      <Table dataSource={data} columns={columns} pagination={false} rowKey="imageSet" />
174
+
175
+      {/* 编辑页 */}
176
+      {/*  onSuccess是子组件传递事件信息  */}
177
+      <ModalPanoramaImage visibleData={visibleData} key="ModalImage" onSuccess={() => onModalChange()}/>
178
+    </>
179
+  )
180
+}
181
+
182
+export default panoramaImage

+ 3
- 0
src/pages/building/list/add/index.jsx View File

@@ -12,6 +12,7 @@ import Wangedit from '../../../../components/Wangedit/Wangedit'
12 12
 import TagGroup from './components/tags'
13 13
 import Base from './components/base'
14 14
 import Apartment from './components/imageSet'
15
+import PanoramaImage from './components/panoramaImage'
15 16
 import Poster from './components/poster'
16 17
 import Share from './components/share'
17 18
 import BuildingImage from './components/buildingImage';
@@ -64,6 +65,7 @@ function AddBuilding(props) {
64 65
         <Radio.Button value="base">基本信息</Radio.Button>
65 66
         <Radio.Button value="apartment">户型库</Radio.Button>
66 67
         <Radio.Button value="image">项目相册</Radio.Button>
68
+        <Radio.Button value="panorama">全景图片</Radio.Button>
67 69
         <Radio.Button value="poster">海报图片</Radio.Button>
68 70
         <Radio.Button value="share">分享设置</Radio.Button>
69 71
       </Radio.Group>
@@ -71,6 +73,7 @@ function AddBuilding(props) {
71 73
         { tab === 'base' && <Base building={{ buildingId: buildingData.buildingId || (props.location.query && props.location.query.id) }} onSuccess={e => buildingOnSuccess(e)}/> }
72 74
         { (tab === 'apartment' && <Apartment building={buildingData} />)}
73 75
         { (tab === 'image' && <BuildingImage building={buildingData} />)}
76
+        { (tab === 'panorama' && <PanoramaImage building={buildingData} />)}
74 77
         { (tab === 'poster' && <Poster building={buildingData} />)}
75 78
         { (tab === 'share' && <Share building={buildingData} />)}
76 79
       </div>

+ 1
- 1
src/pages/building/list/index.jsx View File

@@ -175,7 +175,7 @@ function body(props) {
175 175
   const { getFieldDecorator } = props.form
176 176
 
177 177
   // eslint-disable-next-line react-hooks/rules-of-hooks
178
-  const [dataSource, setDataSource] = useState({ records: [] })
178
+  const [dataSource, setDataSource] = useState({ records: [],size: 0 })
179 179
 
180 180
   // eslint-disable-next-line react-hooks/rules-of-hooks
181 181
   useEffect(() => {

+ 22
- 0
src/services/apis.js View File

@@ -1028,6 +1028,28 @@ export default {
1028 1028
     action: 'admin.posterTemplate.get',
1029 1029
   },
1030 1030
  },
1031
+ paorama: {
1032
+  panoramaApartList: {
1033
+    url: `${prefix}/panorama/apartment`,
1034
+    method: 'GET',
1035
+    action: 'admin.panoramaApartList.get',
1036
+  },
1037
+  add: {
1038
+    url: `${prefix}/panorama`,
1039
+    method: 'POST',
1040
+    action: 'admin.panorama.post',
1041
+  },
1042
+  list: {
1043
+    url: `${prefix}/panorama/:id`,
1044
+    method: 'GET',
1045
+    action: 'admin.panorama.id.get',
1046
+  },
1047
+  delete: {
1048
+    method: 'DELETE',
1049
+    url: `${prefix}/panorama/:id`,
1050
+    action: 'admin.panorama.id.delete',
1051
+  }
1052
+ },
1031 1053
  amap: { // 高德地图
1032 1054
    webService: { // Web服务Api ---- 周边搜索
1033 1055
      url: `${amapPrefix}/place/around`,