Yansen 2 years ago
parent
commit
0152d88502

+ 2
- 1
src/app.config.js View File

@@ -24,7 +24,8 @@ export default defineAppConfig({
24 24
     'pages/notice/detail/index',
25 25
     'pages/my/index',
26 26
     'pages/my/edit/index',
27
-    'pages/feedback/index'
27
+    'pages/feedback/issue/index',
28
+    'pages/feedback/issuelist/index'
28 29
   ],
29 30
   subpackages: [
30 31
     {

BIN
src/assets/icons/headportrait.png View File


+ 1
- 1
src/components/IssueCard/index.jsx View File

@@ -39,7 +39,7 @@ export default (props) => {
39 39
   return (
40 40
     <View className={style['issue-card-wrapper']} onClick={onClick}>
41 41
       <View className={style['issue-card-header']}>
42
-        <View>问题:</View>
42
+        <View>问题清单</View>
43 43
         <View>{createDate}</View>
44 44
       </View>
45 45
       <View className={style['issue-card-body']} style={{ backgroundColor: styleColor[0] }}>

+ 3
- 3
src/components/IssueCard/style.module.less View File

@@ -11,16 +11,16 @@
11 11
     display: flex;
12 12
     align-items: center;
13 13
     justify-content: space-between;
14
+    font-size: 28px;
14 15
 
15 16
     & > view {
16 17
       flex: 1;
17
-      font-size: 24px;
18 18
       line-height: 42px;
19 19
       color: #202020;
20 20
 
21 21
       &:last-child {
22 22
         flex: none;
23
-        font-size: 20px;
23
+        font-size: 24px;
24 24
         color: #222;
25 25
       }
26 26
     }
@@ -40,7 +40,7 @@
40 40
     align-items: center;
41 41
     justify-content: space-between;
42 42
     
43
-    font-size: 24px;
43
+    font-size: 28px;
44 44
     line-height: 32px;
45 45
     color: #202020;
46 46
     margin-top: var(--main-space);

+ 8
- 6
src/layouts/TabBar.jsx View File

@@ -1,6 +1,6 @@
1 1
 import React from 'react';
2 2
 import Taro from '@tarojs/taro';
3
-import { Image } from '@tarojs/components';
3
+import { View, Image } from '@tarojs/components';
4 4
 import { Tabbar, TabbarItem } from '@antmjs/vantui';
5 5
 import {
6 6
   ROLE_INSPECTOR,
@@ -44,10 +44,10 @@ const issue = {
44 44
 }
45 45
 const feedback = {
46 46
   name: 'feedback',
47
-  label: '发布',
47
+  label: '随手拍',
48 48
   icon: issueIcon,
49 49
   activeIcon: issueActiveIcon,
50
-  page: '/pages/feedback/index'
50
+  page: '/pages/feedback/issue/index'
51 51
 }
52 52
 const check = {
53 53
   name: 'check',
@@ -131,18 +131,20 @@ export default (props) => {
131 131
               <Image
132 132
                 src={item.icon}
133 133
                 mode="aspectFit"
134
-                style="width: 30px; height: 18px;"
134
+                style="width: 30px; height: 20px;"
135 135
               ></Image>
136 136
             }
137 137
             renderIconActive={
138 138
               <Image
139 139
                 src={item.activeIcon}
140 140
                 mode="aspectFit"
141
-                style="width: 30px; height: 18px;"
141
+                style="width: 30px; height: 20px;"
142 142
               ></Image>
143 143
             }
144 144
           >
145
-            {item.label}
145
+            <View style={{fontSize: '14px'}}>
146
+              {item.label}
147
+            </View>
146 148
           </TabbarItem>
147 149
         ))
148 150
       }

+ 0
- 3
src/pages/feedback/index.config.js View File

@@ -1,3 +0,0 @@
1
-export default definePageConfig({
2
-  navigationBarTitleText: '新建随手拍'
3
-})

+ 0
- 184
src/pages/feedback/index.jsx View File

@@ -1,184 +0,0 @@
1
-import React from 'react';
2
-import Taro from '@tarojs/taro';
3
-import { View } from '@tarojs/components';
4
-import { Button, Notify, Field, Cell, CellGroup } from '@antmjs/vantui';
5
-import LocType from '@/components/LocType';
6
-import IssueType from '@/components/IssueType';
7
-import OrgPicker from '@/components/OrgPicker';
8
-import DatePicker from '@/components/DatePicker';
9
-import Map from '@/components/map';
10
-import Uploader from '@/components/Uploader/index';
11
-import { getIssueStatus } from '@/utils/biz';
12
-import { getDateStr } from '@/utils/date';
13
-import mapIcon from '@/assets/icons/marker.png';
14
-
15
-export default (props) => {
16
-  const today = new Date();
17
-
18
-  const {
19
-    issue,
20
-    readOnly,
21
-    showOrg,
22
-    showExpireDate,
23
-    renderFields,
24
-    renderAction
25
-  } = props;
26
-
27
-  const [formData, setFormData] = React.useState({
28
-    typeId: undefined,
29
-    typeName: undefined,
30
-    locId: undefined,
31
-    locName: undefined,
32
-    location: undefined,
33
-    addr: undefined,
34
-    content: undefined,
35
-    attachList: [],
36
-  });
37
-  const [showLocType, setShowLocType] = React.useState(false);
38
-  const [showIssueType, setShowIssueType] = React.useState(false);
39
-  const [showOrgPicker, setShowOrgPicker] = React.useState(false);
40
-  const [showDatePicker, setShowDatePicker] = React.useState(false);
41
-  const [bizStatus, setBizStatus] = React.useState();
42
-  const [issueProcess, setIssueProcess] = React.useState([]);
43
-
44
-  const issueReject = React.useMemo(() => {
45
-    if (!issueProcess || !issueProcess.length) return {};
46
-
47
-    return issueProcess.filter(x => x.processStatus === 'reject')[0] || {};
48
-  }, [issueProcess]);
49
-
50
-  const onLocTypeChange = (_, it) => {
51
-    setFormData({
52
-      ...formData,
53
-      locId: it.typeId,
54
-      locName: it.name,
55
-    });
56
-    setShowLocType(false);
57
-  }
58
-
59
-  const onIssueTypeChange = (_, it) => {
60
-    setFormData({
61
-      ...formData,
62
-      typeId: it.typeId,
63
-      typeName: it.name,
64
-    });
65
-    setShowIssueType(false);
66
-  }
67
-
68
-  const onOrgChange = (_, it) => {
69
-    setFormData({
70
-      ...formData,
71
-      orgId: it.orgId,
72
-      orgName: it.name,
73
-    });
74
-    setShowOrgPicker(false);
75
-  }
76
-
77
-  const onDateChange = (dt) => {
78
-    const date = getDateStr(dt);
79
-    setFormData({
80
-      ...formData,
81
-      expireDate: date,
82
-    });
83
-    setShowDatePicker(false);
84
-  }
85
-
86
-  const setFieldChange = (field, value) => {
87
-    setFormData({
88
-      ...formData,
89
-      [field]: value,
90
-    })
91
-  }
92
-
93
-  React.useEffect(() => {
94
-    if (issue) {
95
-      setFormData(issue);
96
-      setBizStatus(getIssueStatus(issue));
97
-
98
-      // if (issue.processStatus == 'reject') {
99
-      //   getIssueProcess({ pageSize: 100, issueId: issue.issueId }).then(res => {
100
-      //     setIssueProcess(res.records || []);
101
-      //   })
102
-      // }
103
-    }
104
-  }, [issue]);
105
-
106
-  return (
107
-    <View>
108
-      {/* <LocType
109
-        show={showLocType}
110
-        value={formData.locId}
111
-        onCancel={() => setShowLocType(false)}
112
-        onChange={onLocTypeChange}
113
-      />
114
-
115
-      <IssueType
116
-        show={showIssueType}
117
-        value={formData.typeName}
118
-        onCancel={() => setShowIssueType(false)}
119
-        onChange={onIssueTypeChange}
120
-      />
121
-
122
-      <OrgPicker
123
-        show={showOrgPicker}
124
-        value={formData.orgName}
125
-        onCancel={() => setShowOrgPicker(false)}
126
-        onChange={onOrgChange}
127
-      />
128
-
129
-      <DatePicker
130
-        type="date"
131
-        minDate={today}
132
-        show={showDatePicker}
133
-        value={formData.expireDate}
134
-        onCancel={() => setShowDatePicker(false)}
135
-        onChange={onDateChange}
136
-      /> */}
137
-
138
-      <Map location={formData.location} />
139
-
140
-      <CellGroup>
141
-        <Field
142
-          placeholder="阳光丽景小区"
143
-          value={formData.addr}
144
-          leftIcon={mapIcon}
145
-          readonly={readOnly}
146
-          onChange={e => setFieldChange('addr', e.detail)}
147
-        />
148
-      </CellGroup>
149
-
150
-      <CellGroup style={{ marginTop: '20px' }}>
151
-
152
-        <Cell title="问题描述" size="large" border={false} />
153
-
154
-        <Field
155
-          type="textarea"
156
-          placeholder="请输入问题描述"
157
-          readonly={readOnly}
158
-          autosize={{ minHeight: '120px' }}
159
-          value={formData.content}
160
-          onChange={e => setFieldChange('content', e.detail)}
161
-        />
162
-      </CellGroup>
163
-
164
-      <CellGroup style={{ marginTop: '20px' }}>
165
-        <Cell title="拍照" size="large" border={false} />
166
-
167
-        <Cell
168
-          renderTitle={
169
-            <Uploader
170
-              value={formData.attachList}
171
-              disabled={readOnly}
172
-              onChange={e => setFieldChange('attachList', e)}
173
-            />
174
-          }
175
-        />
176
-      </CellGroup>
177
-
178
-      <View style={{ padding: 'var(--main-space)', background: '#fff' }}>
179
-        <Button block type="primary">提交</Button>
180
-      </View>
181
-
182
-    </View>
183
-  )
184
-}

+ 4
- 0
src/pages/feedback/issue/index.config.js View File

@@ -0,0 +1,4 @@
1
+// eslint-disable-next-line no-undef
2
+export default definePageConfig({
3
+  navigationBarTitleText: '随手拍'
4
+})

+ 114
- 0
src/pages/feedback/issue/index.jsx View File

@@ -0,0 +1,114 @@
1
+import React from 'react';
2
+import Taro from '@tarojs/taro';
3
+import { View } from '@tarojs/components';
4
+import Page from '@/layouts/index';
5
+import { Button, Notify, Field, Cell, CellGroup } from '@antmjs/vantui';
6
+import Map from '@/components/map';
7
+import Uploader from '@/components/Uploader/index';
8
+import mapIcon from '@/assets/icons/marker.png';
9
+import { warn } from '@/utils/message';
10
+import { postTaFeedback } from '@/services/tafeedback';
11
+
12
+export default (props) => {
13
+  const readOnly = false;
14
+
15
+  const [loading, setLoading] = React.useState(false);
16
+  const fmRef = React.useRef({
17
+    typeId: undefined,
18
+    typeName: undefined,
19
+    locId: undefined,
20
+    locName: undefined,
21
+    location: undefined,
22
+    addr: undefined,
23
+    content: undefined,
24
+    attachList: [],
25
+  });
26
+  const [formData, setFormData] = React.useState(fmRef.current);
27
+
28
+  const setFieldChange = (field, value) => {
29
+    const data = {
30
+      ...fmRef.current,
31
+      [field]: value,
32
+    };
33
+
34
+    fmRef.current = data;
35
+    setFormData(data);
36
+  }
37
+
38
+  const onSubmit = () => {
39
+    try {
40
+      warn(!formData.addr, '请填写地址')
41
+      warn(!formData.content, '请填写问题描述')
42
+      warn(!formData.attachList || formData.attachList.length < 1, '请上传照片')
43
+    } catch (e) {
44
+      return;
45
+    }
46
+
47
+    setLoading(true)
48
+    postTaFeedback(formData).then(() => {
49
+      setLoading(false);
50
+      Taro.navigateBack({
51
+        delta: 1,
52
+        fail: () => {
53
+          Taro.reLaunch({
54
+            url: '/pages/home/index'
55
+          })
56
+        } 
57
+      });
58
+    }).catch(() => {
59
+      setLoading(false);
60
+    })
61
+
62
+  }
63
+
64
+  return (
65
+    <Page tabBar="feedback">
66
+      <Map
67
+        location={formData.location}
68
+        onLocChange={e => !formData.location && setFieldChange('location', e)}
69
+      />
70
+
71
+      <CellGroup>
72
+        <Field
73
+          placeholder="请填写当前位置"
74
+          value={formData.addr}
75
+          leftIcon={mapIcon}
76
+          readonly={readOnly}
77
+          onChange={e => setFieldChange('addr', e.detail)}
78
+        />
79
+      </CellGroup>
80
+
81
+      <CellGroup style={{ marginTop: '20px' }}>
82
+
83
+        <Cell title="问题描述" size="large" border={false} />
84
+
85
+        <Field
86
+          type="textarea"
87
+          placeholder="请输入问题描述"
88
+          readonly={readOnly}
89
+          autosize={{ minHeight: '120px' }}
90
+          value={formData.content}
91
+          onChange={e => setFieldChange('content', e.detail)}
92
+        />
93
+      </CellGroup>
94
+
95
+      <CellGroup style={{ marginTop: '20px' }}>
96
+        <Cell title="拍照" size="large" border={false} />
97
+
98
+        <Cell
99
+          renderTitle={
100
+            <Uploader
101
+              value={formData.attachList}
102
+              disabled={readOnly}
103
+              onChange={e => setFieldChange('attachList', e)}
104
+            />
105
+          }
106
+        />
107
+      </CellGroup>
108
+
109
+      <View style={{ padding: 'var(--main-space)', background: '#fff' }}>
110
+        <Button block type="primary" onClick={onSubmit}>提交</Button>
111
+      </View>
112
+    </Page>
113
+  )
114
+}

+ 3
- 3
src/pages/home/index.jsx View File

@@ -49,9 +49,9 @@ const menus = {
49 49
   
50 50
   // 市民
51 51
   [ROLE_CITIZEN]: [
52
-    { icon: 'icon1', text: '未处理', link: '/pages/issue/list2/index?title=未处理&bizStatus=start&from=citizen' },
53
-    { icon: 'icon2', text: '已处理', link: '/pages/issue/list2/index?title=已处理&bizStatus=assigned&from=citizen' },
54
-    { icon: 'icon12', text: '已打回', link: '/pages/issue/list2/index?title=已打回&bizStatus=reject&from=citizen' },
52
+    { icon: 'icon1', text: '未处理', link: '/pages/feedback/issuelist/index?title=未处理&bizStatus=start' },
53
+    { icon: 'icon2', text: '已处理', link: '/pages/feedback/issuelist/index?title=已处理&bizStatus=assigned' },
54
+    { icon: 'icon12', text: '已打回', link: '/pages/feedback/issuelist/index?title=已打回&bizStatus=reject' },
55 55
   ],
56 56
 }
57 57
 

+ 1
- 1
src/pages/issue/edit/components/Edit.jsx View File

@@ -30,7 +30,7 @@ export default (props) => {
30 30
         delta: 1,
31 31
         fail: () => {
32 32
           Taro.reLaunch({
33
-            url: 'pages/home/index'
33
+            url: '/pages/home/index'
34 34
           })
35 35
         } 
36 36
       });

+ 16
- 11
src/pages/issue/edit/index.jsx View File

@@ -4,7 +4,7 @@ import { View } from '@tarojs/components';
4 4
 import { CellGroup, Cell } from '@antmjs/vantui';
5 5
 import Page from '@/layouts/index';
6 6
 import { useModel } from '@/store';
7
-import { ROLE_INSPECTOR, ROLE_MANAGER, ROLE_CITIZEN } from '@/utils/user';
7
+import { ROLE_INSPECTOR, ROLE_MANAGER, ROLE_CITIZEN, ROLE_QUERY_PERSON } from '@/utils/user';
8 8
 import { getTaIssueById } from '@/services/taissue';
9 9
 import { getSysOrgById } from '@/services/sysorg';
10 10
 import IssueForm from '../components/Issue';
@@ -65,8 +65,8 @@ export default (props) => {
65 65
       ]
66 66
     }
67 67
 
68
-    // 如果是市民
69
-    if (duty == ROLE_CITIZEN) {
68
+    // 如果是市民 或者查询员
69
+    if (duty == ROLE_CITIZEN || duty == ROLE_QUERY_PERSON) {
70 70
       return [
71 71
         true,
72 72
         false,
@@ -91,13 +91,18 @@ export default (props) => {
91 91
       setLoading(true)
92 92
       getTaIssueById(id).then(res => {
93 93
         setLoading(false);
94
-
95
-        getSysOrgById(res.orgId).then(r => {
96
-          setIssue({
97
-            ...res,
98
-            orgName: r.name
99
-          });
100
-        })
94
+        if (res.orgId) {
95
+          getSysOrgById(res.orgId).then(r => {
96
+            setIssue({
97
+              ...res,
98
+              orgName: r?.name
99
+            });
100
+          }).catch(() => {
101
+            setIssue(res);
102
+          })
103
+        } else {
104
+          setIssue(res);
105
+        }
101 106
       }).catch(() => {
102 107
         setLoading(false);
103 108
       });
@@ -105,7 +110,7 @@ export default (props) => {
105 110
   }, [id]);
106 111
 
107 112
   return (
108
-    <Page roles={[ROLE_INSPECTOR, ROLE_MANAGER, ROLE_CITIZEN]} loading={loading}>
113
+    <Page roles={[ROLE_INSPECTOR, ROLE_MANAGER, ROLE_CITIZEN, ROLE_QUERY_PERSON]} loading={loading}>
109 114
       <IssueForm
110 115
         issue={issue}
111 116
         readOnly={readOnly}

+ 20
- 0
src/pages/my/components/Head/index.jsx View File

@@ -0,0 +1,20 @@
1
+import React from 'react';
2
+import Taro from '@tarojs/taro';
3
+import { View, Image } from '@tarojs/components';
4
+import styles from './style.module.less';
5
+
6
+export default (props) => {
7
+
8
+  const { name, avatar } = props;
9
+  
10
+  return (
11
+    <View className={styles['my-head-box']}>
12
+      <View className={styles['profile-box']}>
13
+        <View className={styles['profile-avatar']}>
14
+          <Image src={avatar} />
15
+        </View>
16
+        <View className={styles['profile-name']}>{name}</View>
17
+      </View>
18
+    </View>
19
+  )
20
+}

+ 65
- 0
src/pages/my/components/Head/style.module.less View File

@@ -0,0 +1,65 @@
1
+
2
+.my-head-box {
3
+  background: var(--main-bg-color);
4
+  border-radius: 0px 0px 120px 120px;
5
+  height: 50vw;
6
+  display: flex;
7
+  justify-content: center;
8
+
9
+  .profile-box {
10
+    flex: none;
11
+    width: 40vw;
12
+    height: 40vw;
13
+
14
+    .profile-avatar {
15
+      position: relative;
16
+      width: 100%;
17
+      height: 100%;
18
+      display: grid;
19
+      place-items: center;
20
+
21
+      &::before {
22
+        content: '';
23
+        position: absolute;
24
+        top: 0;
25
+        left: 0;
26
+        width: 100%;
27
+        height: 100%;
28
+        z-index: 1;
29
+        background-color: rgba(255, 255, 255, .01);
30
+        border-radius: 50%;
31
+      }
32
+      
33
+      &::after {
34
+        content: '';
35
+        position: absolute;
36
+        top: 15%;
37
+        left: 15%;
38
+        width: 70%;
39
+        height: 70%;
40
+        z-index: 2;
41
+        background-color: rgba(255, 255, 255, .03);
42
+        border-radius: 50%;
43
+      }
44
+
45
+
46
+      image {
47
+        position: relative;
48
+        display: block;
49
+        width: 16vw;
50
+        height: 16vw;
51
+        border-radius: 50%;
52
+        overflow: hidden;
53
+        background: #fff;
54
+        z-index: 3;
55
+        margin: auto;
56
+      }
57
+    }
58
+
59
+    .profile-name {
60
+      font-size: 32px;
61
+      color: #FFFFFF;
62
+      text-align: center;
63
+    }
64
+  }
65
+}

+ 43
- 16
src/pages/my/index.jsx View File

@@ -1,14 +1,29 @@
1 1
 import React from 'react';
2
+import Taro from '@tarojs/taro';
2 3
 import Page from '@/layouts/index';
3 4
 import { View, Image } from '@tarojs/components';
4
-import headportrait from '@/assets/icons/headportrait.png';
5
+import Head from './components/Head';
5 6
 import peopleicon from '@/assets/icons/peopleicon.png';
6 7
 import smallbell from '@/assets/icons/smallbell.png';
7
-import { Card } from '@antmjs/vantui';
8
-import Taro from '@tarojs/taro';
8
+import logo from '@/assets/image/logo.png';
9
+import { useModel } from '@/store';
10
+import { ROLE_CITIZEN } from '@/utils/user';
9 11
 import './index.less';
10 12
 
11 13
 export default (props) => {
14
+
15
+  const { user, person, duty } = useModel('user');
16
+
17
+  const [
18
+    show1,
19
+    show2,
20
+  ] = React.useMemo(() => {
21
+    return [
22
+      false,
23
+      false,
24
+    ]
25
+  }, [duty]);
26
+
12 27
   const onClick = () => {
13 28
     Taro.navigateTo({
14 29
       url: `/pages/my/edit/index`
@@ -17,29 +32,41 @@ export default (props) => {
17 32
 
18 33
   return (
19 34
     <Page tabBar="mine">
20
-      <View className="wrapper-header">
35
+      <Head
36
+        avatar={user?.avatar || person?.avatar || logo}
37
+        name={user?.name || person?.name || '市民先生'}
38
+      />
39
+      {/* <View className="wrapper-header">
21 40
         <View className="wrapper-header-circle">
22 41
           <View className="wrapper-header-circle2" />
23 42
         </View>
24 43
         <View className="wrapper-header-box">
25
-          <Image className="wrapper-header-img" src={headportrait} />
44
+          <Image className="wrapper-header-img" src={user?.avatar || person?.avatar || logo} />
26 45
         </View>
27 46
         <View className="wrapper-header-box2">
28
-          <View className="wrapper-header-text">昵称:Tomorrow</View>
47
+          <View className="wrapper-header-text">{user?.name || person?.name || '市民先生'}</View>
29 48
         </View>
30 49
       </View>
31 50
 
32 51
       <View className="wrapper-middle">
33
-        <View className="wrapper-middle-box">
34
-          <Image className="wrapper-middle-img" src={peopleicon} />
35
-          <View className="wrapper-middle-text">所在部门</View>
36
-          <View className="wrapper-middle-text2">县文明办</View>
37
-        </View>
38
-        <View className="wrapper-middle-box" onClick={onClick}>
39
-          <Image className="wrapper-middle-img" src={smallbell} />
40
-          <View className="wrapper-middle-text3">消息通知</View>
41
-        </View>
42
-      </View>
52
+        {
53
+          show1 && (
54
+            <View className="wrapper-middle-box">
55
+              <Image className="wrapper-middle-img" src={peopleicon} />
56
+              <View className="wrapper-middle-text">所在部门</View>
57
+              <View className="wrapper-middle-text2">县文明办</View>
58
+            </View>
59
+          )
60
+        }
61
+        {
62
+          show2 && (
63
+            <View className="wrapper-middle-box" onClick={onClick}>
64
+              <Image className="wrapper-middle-img" src={smallbell} />
65
+              <View className="wrapper-middle-text3">消息通知</View>
66
+            </View>
67
+          )
68
+        }
69
+      </View> */}
43 70
     </Page>
44 71
   )
45 72
 }

+ 2
- 1
src/pages/my/index.less View File

@@ -1,10 +1,11 @@
1 1
 .wrapper-header {
2 2
   background: var(--main-bg-color);
3 3
   border-radius: 0px 0px 120px 120px;
4
-  height: 359px;
4
+  height: 50vw;
5 5
   align-items: center;
6 6
   display: flex;
7 7
   justify-content: center;
8
+
8 9
   .wrapper-header-circle {
9 10
     position: relative;
10 11
     opacity: 0.02;

+ 2
- 2
src/pages/org/issue/detail/index.jsx View File

@@ -34,11 +34,11 @@ export default (props) => {
34 34
 
35 35
     return [
36 36
       issue?.applyId,
37
-      status[orgIssue.result],
37
+      status[issue.applyType],
38 38
       orgIssue.processStatus == 'start' && !issue?.applyId
39 39
     ]
40 40
 
41
-  }, [issue, orgIssue.issueId]);
41
+  }, [issue, orgIssue]);
42 42
 
43 43
   const setFormData = (key, value) => {
44 44
     setOrgIssue({