Your Name 2 lat temu
rodzic
commit
3364763975

BIN
src/assets/icons/close.png Wyświetl plik


BIN
src/assets/icons/uploader.png Wyświetl plik


+ 0
- 16
src/components/Uploader/ImageUploader.jsx Wyświetl plik

@@ -1,16 +0,0 @@
1
-import React from 'react';
2
-import Uploader from '.';
3
-
4
-export default (props) => {
5
-  const {value, onChange} = props;
6
-
7
-  const onDelete = (e) => {
8
-    const { file } = e.detail
9
-    const newVals = value.filter(x => x.url != file.url);
10
-    onChange(newVals);
11
-  }
12
-  
13
-  return (
14
-    <Uploader deletable fileList={value} onDelete={onDelete} onChange={onChange} />
15
-  )
16
-}

+ 71
- 9
src/components/Uploader/index.jsx Wyświetl plik

@@ -1,21 +1,83 @@
1 1
 import React from 'react';
2
-import { Uploader } from '@antmjs/vantui';
2
+import Taro from '@tarojs/taro';
3
+import { View, Image, Video } from '@tarojs/components';
4
+import { Loading } from '@antmjs/vantui';
3 5
 import { uploadFiles } from '@/utils/request';
6
+import icon from '@/assets/icons/uploader.png';
7
+import closeIcon from '@/assets/icons/close.png';
8
+import style from './style.modules.less';
4 9
 
5 10
 export default (props) => {
6
-  const { fileList = [] } = props;
11
+  // value 为数组
12
+  // 单个元素结构为 { url, fileType }
13
+  const { value = [], onChange } = props;
14
+  const [loading, setLoading] = React.useState(false);
7 15
 
8
-  const onAfterRead = (e) => {
9
-    const { file, name } = e.detail
16
+  const onAdd = (e) => {
17
+    e.preventDefault();
18
+    e.stopPropagation();
10 19
 
11
-    uploadFiles([file.url]).then(res => {
12
-      if (props.onChange) {
13
-        props.onChange(fileList.concat([{url: res[0], name}]));
20
+    setLoading(true);
21
+    Taro.chooseMedia({
22
+      maxDuration: 60,
23
+      sizeType: 'compressed',
24
+      success: (res) => {
25
+        const { tempFiles } = res;
26
+        uploadFiles(tempFiles).then(resp => {
27
+          setLoading(false);          
28
+          onChange(value.concat(resp));
29
+        }).catch((err) => {
30
+          console.error(err);
31
+          setLoading(false);
32
+        })
33
+      },
34
+      fail: (err) => {
35
+        console.error(err);
36
+        setLoading(false);
14 37
       }
15
-    });
38
+    })
39
+  }
40
+
41
+  const onDelete = (item) => {
42
+    const newVal = value.filter(x => x.url != item.url);
43
+    onChange(newVal);
44
+  }
45
+
46
+  const onPreview = (inx) => {
47
+    Taro.previewMedia({
48
+      sources: value.map(x => ({ url: x.url, type: x.fileType })),
49
+      current: inx,
50
+    })
16 51
   }
17 52
 
18 53
   return (
19
-    <Uploader onAfterRead={onAfterRead} {...props} />
54
+    <View className={style['uploader-wrapper']}>
55
+      <View className={style['uploader-box']}>
56
+        <View className={style['uploader-add']}>
57
+          <Image src={icon} onClick={onAdd} />
58
+          {
59
+            loading && (
60
+              <View>
61
+                <Loading color="#fff" />
62
+              </View>
63
+            )
64
+          }
65
+        </View>
66
+        {
67
+          value.map((item, inx) => (
68
+            <View key={item.url} className={style['uploader-item']}>
69
+              {
70
+                item.fileType == 'image' ?
71
+                  <Image src={item.url} onClick={() => onPreview(inx)} /> :
72
+                  <Video src={item.url} controls={false} onClick={() => onPreview(inx)} />
73
+              }
74
+              <View onClick={() => onDelete(item)}>
75
+                <Image src={closeIcon} />
76
+              </View>
77
+            </View>
78
+          ))
79
+        }
80
+      </View>
81
+    </View>
20 82
   )
21 83
 }

+ 64
- 0
src/components/Uploader/style.modules.less Wyświetl plik

@@ -0,0 +1,64 @@
1
+
2
+.uploader-wrapper {
3
+  display: inline-block;
4
+  .uploader-box {
5
+    display: flex;
6
+
7
+    & > view {
8
+      flex: none;
9
+      width: 160px;
10
+      height: 160px;
11
+      position: relative;
12
+
13
+      image {
14
+        width: 100%;
15
+        height: 100%;
16
+      }
17
+
18
+      video {
19
+        width: 100%;
20
+        height: 100%;
21
+      }
22
+
23
+      & + view {
24
+        margin-left: 20px;
25
+      }
26
+    }
27
+
28
+    .uploader-add {
29
+      & > view {
30
+        position: absolute;
31
+        z-index: 2;
32
+        width: 100%;
33
+        height: 100%;
34
+        left: 0;
35
+        top: 0;
36
+
37
+        display: grid;
38
+        place-items: center;
39
+        background-color: rgba(0, 0, 0, .75);
40
+      }
41
+    }
42
+
43
+    .uploader-item {
44
+      background-color: rgba(0, 0, 0, .05);
45
+
46
+      & > view {
47
+        position: absolute;
48
+        z-index: 2;
49
+        width: 40%;
50
+        height: 40%;
51
+        top: 0;
52
+        right: 0;
53
+
54
+        & > image {
55
+          position: absolute;
56
+          width: 60%;
57
+          height: 60%;
58
+          top: -10px;
59
+          right: -10px;
60
+        }
61
+      }
62
+    }
63
+  }
64
+}

+ 32
- 19
src/pages/issue/add/index.jsx Wyświetl plik

@@ -1,15 +1,17 @@
1 1
 import React from 'react';
2 2
 import Taro from '@tarojs/taro';
3 3
 import { View } from '@tarojs/components';
4
-import { Button, Notify, Field, Cell, CellGroup, Uploader } from '@antmjs/vantui';
4
+import { Button, Notify, Field, Cell, CellGroup } from '@antmjs/vantui';
5 5
 import Page from '@/layouts/index';
6 6
 import LocType from '@/components/locType';
7 7
 import IssueType from '@/components/issueType';
8 8
 import Map from '@/components/map';
9
-import ImageUploader from '@/components/Uploader/ImageUploader';
10
-import getAuthorize from '@/utils/authorize';
9
+import Uploader from '@/components/Uploader/index';
10
+import { getLocation } from '@/utils/authorize';
11 11
 import { ROLE_INSPECTOR } from '@/utils/user';
12 12
 import mapIcon from '@/assets/icons/marker.png';
13
+import { postTaIssue } from '@/services/taissue';
14
+import { warn } from '@/utils/message';
13 15
 
14 16
 export default (props) => {
15 17
 
@@ -21,10 +23,11 @@ export default (props) => {
21 23
     location: undefined,
22 24
     addr: undefined,
23 25
     content: undefined,
24
-    images: [],
26
+    attachList: [],
25 27
   });
26 28
   const [showLocType, setShowLocType] = React.useState(false);
27 29
   const [showIssueType, setShowIssueType] = React.useState(false);
30
+  const [loading, setLoading] = React.useState(false);
28 31
 
29 32
   const onLocTypeChange = (_, it) => {
30 33
     setFormData({
@@ -50,23 +53,33 @@ export default (props) => {
50 53
       [field]: value,
51 54
     })
52 55
   }
56
+
57
+  const onSubmit = () => {
58
+    try {
59
+      warn(!formData.addr, '请填写地址')
60
+      warn(!formData.locId, '请选择点位')
61
+      warn(!formData.content, '请填写问题描述')
62
+      warn(!formData.typeId, '请选择问题分类')
63
+      warn(!formData.attachList || formData.attachList.length < 1, '请上传照片')
64
+    } catch (e) {
65
+      return;
66
+    }
67
+
68
+    setLoading(true)
69
+    postTaIssue(formData).then(() => {
70
+      setLoading(false);
71
+      Taro.navigateBack({delta: 1});
72
+    }).catch(() => {
73
+      setLoading(false);
74
+    })
75
+  }
53 76
   
54 77
   React.useMemo(() => {
55
-    getAuthorize('scope.userLocation').then(() => {
56
-      Taro.getLocation({
57
-        success(res) {
58
-          onFieldChange('location', `${res.longitude},${res.latitude}`);
59
-        },
60
-        fail() {
61
-          Notify.show({
62
-            message: '获取位置失败, 请退出重试',
63
-            type: 'warning',
64
-          })
65
-        }
66
-      });
78
+    getLocation().then((res) => {
79
+      onFieldChange('location', `${res.longitude},${res.latitude}`);
67 80
     }).catch((err) => {
68 81
       Notify.show({
69
-        message: '未能获取位置, 程序部分功能将不能正常使用',
82
+        message: '获取位置失败, 请退出重试',
70 83
         type: 'warning',
71 84
       })
72 85
     });
@@ -130,13 +143,13 @@ export default (props) => {
130 143
 
131 144
         <Cell
132 145
           renderTitle={
133
-            <ImageUploader value={formData.images} onChange={e => onFieldChange('images',e)} />
146
+            <Uploader value={formData.attachList} onChange={e => onFieldChange('attachList',e)} />
134 147
           }
135 148
         />
136 149
       </CellGroup>
137 150
 
138 151
       <View style={{margin: '20px auto', padding: '0 1em'}}>
139
-        <Button block type="primary">提交</Button>
152
+        <Button block type="primary" loading={loading} onClick={onSubmit}>提交</Button>
140 153
       </View>
141 154
     </Page>
142 155
   )

+ 26
- 0
src/services/taissue.js Wyświetl plik

@@ -0,0 +1,26 @@
1
+import request from '@/utils/request';
2
+
3
+/*
4
+ * 分页查询
5
+ */
6
+export const getTaIssue = (params) => request('/api/taIssue', { params });
7
+
8
+/*
9
+ * 新增数据
10
+ */
11
+export const postTaIssue = (data) => request('/api/taIssue', { data, method: 'post' });
12
+
13
+/*
14
+ * 通过ID查询单条数据
15
+ */
16
+export const getTaIssueById = (id) => request(`/api/taIssue/${id}`);
17
+
18
+/*
19
+ * 更新数据
20
+ */
21
+export const putTaIssue = (id, data) => request(`/api/taIssue/${id}`, { data, method: 'put' });
22
+
23
+/*
24
+ * 通过主键删除数据
25
+ */
26
+export const deleteTaIssue = (id) => request(`/api/taIssue/${id}`, { method: 'delete' });

+ 20
- 1
src/utils/authorize.js Wyświetl plik

@@ -1,6 +1,6 @@
1 1
 import Taro from '@tarojs/taro';
2 2
 
3
-export default (scope) => {
3
+export default function getAuthorize(scope) {
4 4
   return new Promise((resolve, reject) => {
5 5
     Taro.getSetting({
6 6
       success(res) {
@@ -24,3 +24,22 @@ export default (scope) => {
24 24
     });
25 25
   });
26 26
 }
27
+
28
+export const getLocation = () => {
29
+  return new Promise((resolve, reject) => {
30
+    getAuthorize('scope.userLocation').then(() => {
31
+      Taro.getLocation({
32
+        success(res) {
33
+          resolve(res);
34
+        },
35
+        fail(err) {
36
+          console.error(err);
37
+          reject(err);
38
+        }
39
+      });
40
+    }).catch((err) => {
41
+      console.error(err);
42
+      reject(err);
43
+    });
44
+  });
45
+}

+ 12
- 0
src/utils/message.js Wyświetl plik

@@ -0,0 +1,12 @@
1
+
2
+import { Notify } from '@antmjs/vantui';
3
+
4
+export function warn(predicate, message) {
5
+  if (predicate) {
6
+    Notify.show({
7
+      message,
8
+      type: 'warning',
9
+    })
10
+    throw new Error(message);
11
+  }
12
+}

+ 6
- 2
src/utils/request.js Wyświetl plik

@@ -80,12 +80,16 @@ export const uploadFiles = async (files, url) => {
80 80
   for (var i = 0; i < files.length; i++) {
81 81
     uploads[i] = new Promise((resolve, reject) => {
82 82
       Taro.uploadFile({
83
-        url: url || `${HOST}/api/ma/image`,
84
-        filePath: files[i],
83
+        // eslint-disable-next-line no-undef
84
+        url: url || `${HOST}/api/ma/file`,
85
+        filePath: files[i].tempFilePath,
85 86
         header: {
86 87
           'authorization': token,
87 88
         },
88 89
         name: 'file',
90
+        formData: {
91
+          fileType: files[i].fileType,
92
+        },
89 93
         success: function (res) {
90 94
           // debugger
91 95
           const _data = JSON.parse(res.data)