fangmingyue 2 年之前
父節點
當前提交
f770a04b4c

+ 1
- 0
config/dev.js 查看文件

6
     // HOST: '"http://127.0.0.1:9087"',
6
     // HOST: '"http://127.0.0.1:9087"',
7
     HOST: '"http://localhost:9087"',
7
     HOST: '"http://localhost:9087"',
8
     AD_IMAGE: '"https://h5.njyunzhi.com/images/citizen_banner.png"',
8
     AD_IMAGE: '"https://h5.njyunzhi.com/images/citizen_banner.png"',
9
+    DEFAULT_POS: '"116.3476917447715,31.409912844296578"', // 霍山县人民政府 gcj02
9
   },
10
   },
10
   mini: {},
11
   mini: {},
11
   h5: {},
12
   h5: {},

+ 1
- 0
config/prod.js 查看文件

5
   defineConstants: {
5
   defineConstants: {
6
     HOST: '"https://t.njyz.tech"',
6
     HOST: '"https://t.njyz.tech"',
7
     AD_IMAGE: '"https://h5.njyunzhi.com/images/citizen_banner.png"',
7
     AD_IMAGE: '"https://h5.njyunzhi.com/images/citizen_banner.png"',
8
+    DEFAULT_POS: '"116.3476917447715,31.409912844296578"', // 霍山县人民政府 gcj02
8
   },
9
   },
9
   mini: {},
10
   mini: {},
10
   h5: {
11
   h5: {

+ 2
- 2
src/app.config.js 查看文件

16
     // 'pages/checkStand/index',
16
     // 'pages/checkStand/index',
17
     "pages/checkStand/list/index",
17
     "pages/checkStand/list/index",
18
     "pages/checkStand/detail/index",
18
     "pages/checkStand/detail/index",
19
-    "pages/reporting/index",
20
-    "pages/reporting/detail/index",
21
     "pages/reset-password/index",
19
     "pages/reset-password/index",
22
     "pages/check/list/index",
20
     "pages/check/list/index",
23
     "pages/check/loc/list/index",
21
     "pages/check/loc/list/index",
28
     "pages/my/edit/index",
26
     "pages/my/edit/index",
29
     "pages/feedback/issue/index",
27
     "pages/feedback/issue/index",
30
     "pages/feedback/issuelist/index",
28
     "pages/feedback/issuelist/index",
29
+    "pages/user/list/index",
30
+    "pages/user/add/index",
31
   ],
31
   ],
32
   subpackages: [
32
   subpackages: [
33
     {
33
     {

+ 5
- 2
src/components/Icon.jsx 查看文件

1
 import React from 'react';
1
 import React from 'react';
2
 import Taro from '@tarojs/taro';
2
 import Taro from '@tarojs/taro';
3
 import { Image } from '@tarojs/components';
3
 import { Image } from '@tarojs/components';
4
+import { Icon } from '@antmjs/vantui';
4
 import icon1 from '@/assets/icons/icon1.png';
5
 import icon1 from '@/assets/icons/icon1.png';
5
 import icon2 from '@/assets/icons/icon2.png';
6
 import icon2 from '@/assets/icons/icon2.png';
6
 import icon3 from '@/assets/icons/icon3.png';
7
 import icon3 from '@/assets/icons/icon3.png';
13
 import icon10 from '@/assets/icons/icon10.png';
14
 import icon10 from '@/assets/icons/icon10.png';
14
 import icon11 from '@/assets/icons/icon11.png';
15
 import icon11 from '@/assets/icons/icon11.png';
15
 import icon12 from '@/assets/icons/icon12.png';
16
 import icon12 from '@/assets/icons/icon12.png';
17
+import person from '@/assets/icons/peopleicon.png';
16
 
18
 
17
 const icons = {
19
 const icons = {
18
   icon1,
20
   icon1,
27
   icon10,
29
   icon10,
28
   icon11,
30
   icon11,
29
   icon12,
31
   icon12,
32
+  person,
30
 }
33
 }
31
 
34
 
32
 export default (props) => {
35
 export default (props) => {
33
-  const { className, style, name } = props;
36
+  const { className, style, name, info } = props;
34
   
37
   
35
   return (
38
   return (
36
-    <Image src={icons[name]} className={className} style={style} />
39
+    <Icon name={icons[name]} className={className} style={style} info={info} />
37
   )
40
   )
38
 }
41
 }

+ 14
- 2
src/components/MenuIcon.jsx 查看文件

27
 
27
 
28
 export default (props) => {
28
 export default (props) => {
29
   
29
   
30
-  const { icon, text, link } = props;
30
+  const { icon, text, link, request } = props;
31
+
32
+  const [info, setInfo] = React.useState();
31
 
33
 
32
   const onClick = () => {
34
   const onClick = () => {
33
     Taro.navigateTo({
35
     Taro.navigateTo({
35
     })
37
     })
36
   }
38
   }
37
 
39
 
40
+  React.useEffect(() => {
41
+    if (request) {
42
+      request().then(res => {
43
+        if (res) {
44
+          res > 99 ? setInfo('99+') : setInfo(res);
45
+        }
46
+      });
47
+    }
48
+  }, [request]);
49
+
38
   return (
50
   return (
39
     <RatioView>
51
     <RatioView>
40
       <View style={wrapperStyle} onClick={onClick}>
52
       <View style={wrapperStyle} onClick={onClick}>
41
         <View>
53
         <View>
42
-          <Icon name={icon} style={iconStyle} />
54
+          <Icon name={icon} style={iconStyle} info={info} />
43
           <View style={txtStyle}>{text}</View>
55
           <View style={txtStyle}>{text}</View>
44
         </View>
56
         </View>
45
       </View>
57
       </View>

+ 9
- 2
src/components/PowerList/index.jsx 查看文件

3
 import { View } from '@tarojs/components';
3
 import { View } from '@tarojs/components';
4
 import { PowerScrollView } from '@antmjs/vantui';
4
 import { PowerScrollView } from '@antmjs/vantui';
5
 
5
 
6
-export default (props) => {
6
+export default React.forwardRef((props, ref) => {
7
   const { request, params, renderItem, onLoadingChange } = props;
7
   const { request, params, renderItem, onLoadingChange } = props;
8
 
8
 
9
   const pageSize = 20;
9
   const pageSize = 20;
56
     pageNumRef.current = 1;
56
     pageNumRef.current = 1;
57
     queryData({pageNum : pageNumRef.current});
57
     queryData({pageNum : pageNumRef.current});
58
   }, [queryData]);
58
   }, [queryData]);
59
+
60
+  React.useImperativeHandle(ref, () => ({
61
+    refresh: () => {
62
+      pageNumRef.current = 1;
63
+      queryData({pageNum : pageNumRef.current});
64
+    }
65
+  }));
59
   
66
   
60
   return (
67
   return (
61
     <PowerScrollView
68
     <PowerScrollView
72
       }
79
       }
73
     </PowerScrollView>
80
     </PowerScrollView>
74
   )
81
   )
75
-}
82
+})

+ 81
- 41
src/components/map/index.jsx 查看文件

6
 import iconPath from '@/assets/icons/marker.png';
6
 import iconPath from '@/assets/icons/marker.png';
7
 import style from './style.module.less';
7
 import style from './style.module.less';
8
 
8
 
9
-// location 逻辑
10
-// 如果 props.location 有值, 那么放弃地图定位的点, 使用 props.location
11
-// 否则使用 地图定位的点
12
-// 如果地图定位失败 或者 props.location 为空, 那么不产生数据交互
13
-// 但是地图上默认使用 霍山县人民政府 的定位
14
 export default (props) => {
9
 export default (props) => {
15
-  const { location, onLocChange } = props;
10
+  const { readOnly, location, onChange } = props;
11
+
12
+  const id = React.useMemo(() => `map-${Math.random().toString(36).substring(2, 10)}`, []);
13
+  const mapCtxRef = React.useRef();
16
 
14
 
17
-  const [currentPos, setCurPos] = React.useState();
18
   const [
15
   const [
19
-    markers,
20
-    lngLat,
16
+    // markers,
17
+    center,
21
   ] = React.useMemo(() => {
18
   ] = React.useMemo(() => {
22
-    const loc = location || currentPos || '116.354259,31.415587';
19
+    // eslint-disable-next-line no-undef
20
+    const loc = location || DEFAULT_POS;
23
     const [longitude, latitude] = loc.split(',');
21
     const [longitude, latitude] = loc.split(',');
24
 
22
 
25
-    const mks = [{
26
-      id: 1,
27
-      longitude,
28
-      latitude,
29
-      iconPath,
30
-      width: 17,
31
-      height: 20
32
-    }];
23
+    // const mks = [{
24
+    //   id: 1,
25
+    //   longitude,
26
+    //   latitude,
27
+    //   iconPath,
28
+    //   width: 17,
29
+    //   height: 20
30
+    // }];
33
 
31
 
34
     return [
32
     return [
35
-      mks,
36
-      [longitude, latitude]
33
+      // mks,
34
+      { longitude, latitude }
37
     ]
35
     ]
38
-  }, [location, currentPos]);
36
+  }, [location]);
39
 
37
 
40
-  React.useEffect(() => {
41
-    getLocation().then((res) => {
42
-      setCurPos([res.longitude, res.latitude].join(','));
43
-    }).catch((err) => {
44
-      console.error(err);
45
-      Taro.showToast({
46
-        title: '定位失败',
47
-        icon: 'none',
38
+  const moveTo = (ctx, point) => {
39
+    ctx.moveToLocation({
40
+      ...point,
41
+      fail: console.error,
42
+    })
43
+  }
44
+
45
+  const getContext = React.useCallback(() => {
46
+    const query = Taro.createSelectorQuery();
47
+    query.select(`#${id}`).context(res => {
48
+      mapCtxRef.current = res.context;
49
+
50
+      // 修改中心图标 - 暂时不起作用, wx bug
51
+      mapCtxRef.current.setLocMarkerIcon({
52
+        iconPath,
53
+        fail: console.error,
48
       })
54
       })
55
+    }).exec();
56
+  }, [id]);
57
+
58
+  const fixedLocation = () => {
59
+    return new Promise((resolve) => {
60
+      getLocation({ type: 'gcj02' }).then((res) => {
61
+        resolve(res);
62
+      }).catch((err) => {
63
+        console.error(err);
64
+        Taro.showToast({
65
+          title: '定位失败',
66
+          icon: 'none',
67
+        })
68
+      });
49
     });
69
     });
50
-  }, []);
51
-  // console.log('markers latitude', mks)
52
-  React.useEffect(() => {
53
-    if (!location && !currentPos) return;
70
+  }
54
 
71
 
55
-    const loc = location || currentPos;
56
-    if (loc) {
57
-      onLocChange(loc);
72
+  const onRefresh = () => {
73
+    if (mapCtxRef.current) {
74
+      fixedLocation().then((res) => {
75
+        const { longitude, latitude } = res;
76
+        onChange([res.longitude, res.latitude].join(','));
77
+        moveTo(mapCtxRef.current, { longitude, latitude });
78
+      })
58
     }
79
     }
59
-  }, [location, currentPos]);
80
+  }
81
+
82
+  React.useEffect(() => {
83
+    if (!readOnly) {
84
+      fixedLocation().then((res) => {
85
+        const { longitude, latitude } = res;
86
+        onChange([longitude, latitude].join(','));
87
+      })
88
+    }
89
+  }, [readOnly]);
90
+
91
+  React.useEffect(() => {
92
+    getContext();
93
+  }, [getContext]);
60
 
94
 
61
   return (
95
   return (
62
     <View className={style['map-wrapper']}>
96
     <View className={style['map-wrapper']}>
63
       <Map
97
       <Map
64
-        longitude={lngLat[0]}
65
-        latitude={lngLat[1]}
66
-        markers={markers}
98
+        id={id}
99
+        showLocation
100
+        longitude={center.longitude}
101
+        latitude={center.latitude}
102
+      // markers={markers}
67
       >
103
       >
68
-        <CoverView className={style['control']}><Icon name="aim" size="26px" color="rgb(18,183,245)" /></CoverView>
104
+        {!readOnly && (
105
+          <CoverView className={style['control']} onClick={onRefresh}>
106
+            <Icon name="aim" size="24px" color="#1A7565" />
107
+          </CoverView>
108
+        )}
69
       </Map>
109
       </Map>
70
     </View>
110
     </View>
71
   )
111
   )

+ 2
- 2
src/components/map/style.module.less 查看文件

12
     left: 0;
12
     left: 0;
13
     .control {
13
     .control {
14
       position: absolute;
14
       position: absolute;
15
-      bottom: 14%;
16
-      right: 4%;
15
+      bottom: var(--main-space);
16
+      right: var(--main-space);
17
     }
17
     }
18
   }
18
   }
19
 }
19
 }

+ 2
- 1
src/layouts/index.jsx 查看文件

2
 import Taro from '@tarojs/taro';
2
 import Taro from '@tarojs/taro';
3
 import { View, Image } from '@tarojs/components';
3
 import { View, Image } from '@tarojs/components';
4
 import { useModel } from '@/store';
4
 import { useModel } from '@/store';
5
-import { Loading, Notify } from '@antmjs/vantui';
5
+import { Loading, Notify, Dialog } from '@antmjs/vantui';
6
 import NavLoading from '@/components/NavLoading';
6
 import NavLoading from '@/components/NavLoading';
7
 import Auth from '@/components/Auth';
7
 import Auth from '@/components/Auth';
8
 import TabBar from './TabBar';
8
 import TabBar from './TabBar';
35
   return (
35
   return (
36
     <View className={laySty['page-wrapper']}>
36
     <View className={laySty['page-wrapper']}>
37
       <Notify id="vanNotify" />
37
       <Notify id="vanNotify" />
38
+      <Dialog id="vanDialog" />
38
       <NavLoading loading={loading} />
39
       <NavLoading loading={loading} />
39
       <View className={containerClass} style={style}>
40
       <View className={containerClass} style={style}>
40
         {
41
         {

+ 17
- 11
src/pages/check/edit/components/LocForm.jsx 查看文件

10
 export default (props) => {
10
 export default (props) => {
11
   const { checkItemInfo, checkType, answer, readonly, onChange, onLoadingChange } = props;
11
   const { checkItemInfo, checkType, answer, readonly, onChange, onLoadingChange } = props;
12
 
12
 
13
-  const [loc, setLoc] = React.useState();
14
   const [showAgePicker, setShowAgePicker] = React.useState(false);
13
   const [showAgePicker, setShowAgePicker] = React.useState(false);
15
 
14
 
16
   const setLoading = (v) => {
15
   const setLoading = (v) => {
21
 
20
 
22
   const setFieldChange = (key, val) => {
21
   const setFieldChange = (key, val) => {
23
     onChange({
22
     onChange({
24
-      location: loc,
25
       ...answer || {},
23
       ...answer || {},
26
       [key]: val,
24
       [key]: val,
27
     })
25
     })
46
 
44
 
47
   return (
45
   return (
48
     <View>
46
     <View>
49
-      <Map location={answer?.location} onLocChange={setLoc} />
47
+      <Map
48
+        readOnly={readonly}
49
+        location={answer?.location}
50
+        onChange={e => setFieldChange('location', e)}
51
+      />
50
       <CellGroup>
52
       <CellGroup>
51
         {
53
         {
52
           checkType == 'loc' && (
54
           checkType == 'loc' && (
56
             />
58
             />
57
           )
59
           )
58
         }
60
         }
61
+        {
62
+          checkType == 'survey' && (
63
+            <Field
64
+              label="社区"
65
+              placeholder="请填写社区名称"
66
+              readonly={readonly}
67
+              value={answer?.communityName}
68
+              onChange={e => setFieldChange('communityName', e.detail)}
69
+            />
70
+          )
71
+        }
59
         <Field
72
         <Field
60
           readonly={readonly}
73
           readonly={readonly}
61
-          placeholder={checkType == 'loc' ? '请输入地址' : '请填写社区名称'}
62
-          // value={answer}
63
-          leftIcon={mapIcon}
64
-        // onChange={e => setFieldChange('', e.detail)}
65
-        />
66
-        <Field
67
-          readonly={readonly}
74
+          label={checkType == 'loc' ? '地址' : '小区'}
68
           placeholder={checkType == 'loc' ? '请输入地址' : '请填写小区名称'}
75
           placeholder={checkType == 'loc' ? '请输入地址' : '请填写小区名称'}
69
           value={answer?.addr}
76
           value={answer?.addr}
70
-          leftIcon={mapIcon}
71
           onChange={e => setFieldChange('addr', e.detail)}
77
           onChange={e => setFieldChange('addr', e.detail)}
72
         />
78
         />
73
       </CellGroup>
79
       </CellGroup>

+ 1
- 1
src/pages/check/edit/index.jsx 查看文件

44
     if (index == -1 && n != -1) {
44
     if (index == -1 && n != -1) {
45
       if (!readonly) {
45
       if (!readonly) {
46
         try {
46
         try {
47
+          warn(typ == 'survey' && !answer?.communityName, '请填写社区名称');
47
           warn(!answer?.addr, typ == 'loc' ? '请填写地址' : '请填写小区名称');
48
           warn(!answer?.addr, typ == 'loc' ? '请填写地址' : '请填写小区名称');
48
-          // warn(!answer, typ == 'loc' ? '请填写地址' : '请填写社区名称');
49
           warn(!answer?.location, '未能获取定位信息, 请重试');
49
           warn(!answer?.location, '未能获取定位信息, 请重试');
50
           warn(typ == 'survey' && !answer?.sex, '请选择性别');
50
           warn(typ == 'survey' && !answer?.sex, '请选择性别');
51
           warn(typ == 'survey' && !answer?.age, '请选择年龄段');
51
           warn(typ == 'survey' && !answer?.age, '请选择年龄段');

+ 5
- 4
src/pages/check/loc/edit/components/LocForm.jsx 查看文件

9
 export default (props) => {
9
 export default (props) => {
10
   const { checkItemInfo, answer, readonly, onChange, onLoadingChange } = props;
10
   const { checkItemInfo, answer, readonly, onChange, onLoadingChange } = props;
11
 
11
 
12
-  const [loc, setLoc] = React.useState();
13
-
14
   const setLoading = (v) => {
12
   const setLoading = (v) => {
15
     if (onLoadingChange) {
13
     if (onLoadingChange) {
16
       onLoadingChange(v)
14
       onLoadingChange(v)
19
   
17
   
20
   const setFieldChange = (key, val) => {
18
   const setFieldChange = (key, val) => {
21
     onChange({
19
     onChange({
22
-      location: loc,
23
       ...answer || {},
20
       ...answer || {},
24
       [key]: val,
21
       [key]: val,
25
     })
22
     })
42
   
39
   
43
   return (
40
   return (
44
     <View>
41
     <View>
45
-      <Map location={answer?.location} onLocChange={setLoc} />
42
+      <Map
43
+        readOnly={readonly}
44
+        location={answer?.location}
45
+        onChange={(e) => setFieldChange('location', e)}
46
+      />
46
       <CellGroup>
47
       <CellGroup>
47
         <Cell
48
         <Cell
48
           title="点位"
49
           title="点位"

+ 2
- 1
src/pages/feedback/issue/index.jsx 查看文件

64
   return (
64
   return (
65
     <Page tabBar="feedback">
65
     <Page tabBar="feedback">
66
       <Map
66
       <Map
67
+        readOnly={readOnly}
67
         location={formData.location}
68
         location={formData.location}
68
-        onLocChange={e => !formData.location && setFieldChange('location', e)}
69
+        onChange={e => !formData.location && setFieldChange('location', e)}
69
       />
70
       />
70
 
71
 
71
       <CellGroup>
72
       <CellGroup>

+ 17
- 6
src/pages/home/index.jsx 查看文件

5
 import MenuIcon from '@/components/MenuIcon';
5
 import MenuIcon from '@/components/MenuIcon';
6
 import { ROLE_CITIZEN, ROLE_INSPECTOR, ROLE_MANAGER, ROLE_ORG_MANAGER, ROLE_ORG_USER, ROLE_QUERY_PERSON } from '@/utils/user';
6
 import { ROLE_CITIZEN, ROLE_INSPECTOR, ROLE_MANAGER, ROLE_ORG_MANAGER, ROLE_ORG_USER, ROLE_QUERY_PERSON } from '@/utils/user';
7
 import { PROCESS_APPLY_DELAY, PROCESS_APPLY_END, PROCESS_APPLY_REJECT, PROCESS_APPLY_VERIFY, PROCESS_ASSIGNED, PROCESS_END, PROCESS_START } from '@/utils/biz';
7
 import { PROCESS_APPLY_DELAY, PROCESS_APPLY_END, PROCESS_APPLY_REJECT, PROCESS_APPLY_VERIFY, PROCESS_ASSIGNED, PROCESS_END, PROCESS_START } from '@/utils/biz';
8
+import { getApplyNum } from '@/services/taissueapply';
8
 import Head from './components/Head';
9
 import Head from './components/Head';
9
 import Banner from './components/Banner';
10
 import Banner from './components/Banner';
10
 import StatCard from './components/StatCard';
11
 import StatCard from './components/StatCard';
11
 import './index.less';
12
 import './index.less';
12
 
13
 
14
+const getRejctApply = () => getApplyNum({ applyType: PROCESS_APPLY_REJECT });
15
+const getDelayApply = () => getApplyNum({ applyType: PROCESS_APPLY_DELAY });
16
+const getVerifyApply = () => getApplyNum({ applyType: PROCESS_APPLY_VERIFY });
17
+const getEdnApply = () => getApplyNum({ applyType: PROCESS_APPLY_END });
18
+
13
 const menus = {
19
 const menus = {
14
   // 督查员
20
   // 督查员
15
   [ROLE_INSPECTOR]: [
21
   [ROLE_INSPECTOR]: [
23
     { icon: 'icon1', text: '待 交 办', link: `/pages/issue/list2/index?title=待交办&bizStatus=${PROCESS_START}` },
29
     { icon: 'icon1', text: '待 交 办', link: `/pages/issue/list2/index?title=待交办&bizStatus=${PROCESS_START}` },
24
     { icon: 'icon2', text: '已 交 办', link: `/pages/issue/list2/index?title=已交办&bizStatus=${PROCESS_ASSIGNED}`, },
30
     { icon: 'icon2', text: '已 交 办', link: `/pages/issue/list2/index?title=已交办&bizStatus=${PROCESS_ASSIGNED}`, },
25
     { icon: 'icon3', text: '已 办 结', link: `/pages/issue/list2/index?title=已办结&bizStatus=${PROCESS_END}` },
31
     { icon: 'icon3', text: '已 办 结', link: `/pages/issue/list2/index?title=已办结&bizStatus=${PROCESS_END}` },
26
-    { icon: 'icon4', text: '消单申请', link: `/pages/apply/list/index?title=消单申请&applyType=${PROCESS_APPLY_END}` },
32
+    { icon: 'icon4', text: '消单申请', request: getEdnApply, link: `/pages/apply/list/index?title=消单申请&applyType=${PROCESS_APPLY_END}` },
27
     { icon: 'icon5', text: '逾期警告', link: `/pages/issue/list2/index?title=逾期警告&bizStatus=expired` },
33
     { icon: 'icon5', text: '逾期警告', link: `/pages/issue/list2/index?title=逾期警告&bizStatus=expired` },
28
-    { icon: 'icon6', text: '延期申请', link: `/pages/apply/list/index?title=延期申请&applyType=${PROCESS_APPLY_DELAY}` },
29
-    { icon: 'icon12', text: '驳回申请', link: `/pages/apply/list/index?title=驳回申请&applyType=${PROCESS_APPLY_REJECT}` },
34
+    { icon: 'icon6', text: '延期申请', request: getDelayApply, link: `/pages/apply/list/index?title=延期申请&applyType=${PROCESS_APPLY_DELAY}` },
35
+    { icon: 'icon12', text: '驳回申请', request: getRejctApply, link: `/pages/apply/list/index?title=驳回申请&applyType=${PROCESS_APPLY_REJECT}` },
30
     { icon: 'icon7', text: '统计查询', link: '/subpkg1/pages/statistics/index' },
36
     { icon: 'icon7', text: '统计查询', link: '/subpkg1/pages/statistics/index' },
31
     { icon: 'icon9', text: '我的上报', link: '/pages/issue/list2/index?title=我的上报&mine=true' },
37
     { icon: 'icon9', text: '我的上报', link: '/pages/issue/list2/index?title=我的上报&mine=true' },
32
     { icon: 'icon11', text: '消息通知', link: '/pages/message/list/index' },
38
     { icon: 'icon11', text: '消息通知', link: '/pages/message/list/index' },
45
     { icon: 'icon2', text: '处 理 中', link: `/pages/org/issue/list/index?title=处理中&bizStatus=${PROCESS_ASSIGNED}` },
51
     { icon: 'icon2', text: '处 理 中', link: `/pages/org/issue/list/index?title=处理中&bizStatus=${PROCESS_ASSIGNED}` },
46
     { icon: 'icon3', text: '已 办 结', link: `/pages/org/issue/list/index?title=已办结&bizStatus=${PROCESS_END}` },
52
     { icon: 'icon3', text: '已 办 结', link: `/pages/org/issue/list/index?title=已办结&bizStatus=${PROCESS_END}` },
47
     { icon: 'icon5', text: '已 逾 期', link: '/pages/org/issue/list/index?title=已办结&bizStatus=expired' },
53
     { icon: 'icon5', text: '已 逾 期', link: '/pages/org/issue/list/index?title=已办结&bizStatus=expired' },
48
-    { icon: 'icon9', text: '审核申请', link: `/pages/apply/list/index?title=审核申请&applyType=${PROCESS_APPLY_VERIFY}` },
54
+    { icon: 'icon9', text: '审核申请', request: getVerifyApply, link: `/pages/apply/list/index?title=审核申请&applyType=${PROCESS_APPLY_VERIFY}` },
49
     { icon: 'icon11', text: '消息通知', link: '/pages/message/list/index' },
55
     { icon: 'icon11', text: '消息通知', link: '/pages/message/list/index' },
56
+    { icon: 'person', text: '人员管理', link: '/pages/user/list/index' },
50
   ],
57
   ],
51
 
58
 
52
   // 查询人员
59
   // 查询人员
68
 export default (props) => {
75
 export default (props) => {
69
 
76
 
70
   const userModel = useModel('user');
77
   const userModel = useModel('user');
71
-  const { user, duty } = userModel || {};
78
+  const { user, duty, signOut, changePwd } = userModel || {};
72
 
79
 
73
   const menuArr = React.useMemo(() => {
80
   const menuArr = React.useMemo(() => {
74
     if (!duty) return [];
81
     if (!duty) return [];
78
 
85
 
79
   return (
86
   return (
80
     <Page tabBar="home" className="home-page">
87
     <Page tabBar="home" className="home-page">
81
-      <Head userModel={userModel} />
88
+      <Head
89
+        userModel={userModel}
90
+        onChangePwd={changePwd}
91
+        onExit={signOut}
92
+      />
82
       <Banner duty={duty} />
93
       <Banner duty={duty} />
83
       <StatCard duty={duty} />
94
       <StatCard duty={duty} />
84
 
95
 

+ 2
- 1
src/pages/issue/components/Issue/index.jsx 查看文件

144
       />
144
       />
145
 
145
 
146
       <Map
146
       <Map
147
+        readOnly={readOnly}
147
         location={formData.location}
148
         location={formData.location}
148
-        onLocChange={e => !formData.location && setFieldChange('location', e)}
149
+        onChange={e => !formData.location && setFieldChange('location', e)}
149
       />
150
       />
150
 
151
 
151
       <CellGroup>
152
       <CellGroup>

+ 35
- 2
src/pages/my/components/Head/index.jsx 查看文件

1
 import React from 'react';
1
 import React from 'react';
2
 import Taro from '@tarojs/taro';
2
 import Taro from '@tarojs/taro';
3
 import { View, Image } from '@tarojs/components';
3
 import { View, Image } from '@tarojs/components';
4
+import { ActionSheet } from '@antmjs/vantui';
5
+import ResetPwd from '../ResetPwd';
4
 import styles from './style.module.less';
6
 import styles from './style.module.less';
5
 
7
 
6
 export default (props) => {
8
 export default (props) => {
7
 
9
 
8
-  const { name, avatar } = props;
10
+  const { name, avatar, onChangePwd, onExit } = props;
11
+  const [show, setShow] = React.useState(false);
12
+  const [show2, setShow2] = React.useState(false);
13
+
14
+  const actions =[
15
+    { name: '重置密码', value: 'reset-pwd' },
16
+    { name: '退出', value: 'exit' },
17
+  ]
18
+
19
+  const onAction = (e) => {
20
+    const { value } = e.detail;
21
+
22
+    if (value === 'reset-pwd') {
23
+      setShow(false);
24
+      setShow2(true);
25
+    }
26
+
27
+    if (value === 'exit') {
28
+      onExit();
29
+    }
30
+  }
9
   
31
   
10
   return (
32
   return (
11
     <View className={styles['my-head-box']}>
33
     <View className={styles['my-head-box']}>
12
       <View className={styles['profile-box']}>
34
       <View className={styles['profile-box']}>
13
-        <View className={styles['profile-avatar']}>
35
+        <View className={styles['profile-avatar']} onClick={() => setShow(true)}>
14
           <Image src={avatar} />
36
           <Image src={avatar} />
15
         </View>
37
         </View>
16
         <View className={styles['profile-name']}>{name}</View>
38
         <View className={styles['profile-name']}>{name}</View>
17
       </View>
39
       </View>
40
+      <ActionSheet
41
+        show={show}
42
+        actions={actions}
43
+        onClose={() => setShow(false)}
44
+        onSelect={onAction}
45
+      />
46
+      <ResetPwd
47
+        show={show2}
48
+        onClose={() => setShow2(false)}
49
+        onSubmit={onChangePwd}
50
+      />
18
     </View>
51
     </View>
19
   )
52
   )
20
 }
53
 }

+ 82
- 0
src/pages/my/components/ResetPwd/index.jsx 查看文件

1
+import React from 'react';
2
+import Taro from '@tarojs/taro';
3
+import { View } from '@tarojs/components';
4
+import { Dialog, CellGroup, Field, Button } from '@antmjs/vantui';
5
+import { warn } from '@/utils/message';
6
+
7
+export default (props) => {
8
+
9
+  const { show, onClose, onSubmit } = props;
10
+  const id = React.useMemo(() => {
11
+    return `dialog-${Math.random().toString(36).substring(2, 10)}`
12
+  }, []);
13
+
14
+  const [formData, setFormData] = React.useState({});
15
+
16
+  const setField = (name, value) => {
17
+    setFormData({
18
+      ...formData,
19
+      [name]: value,
20
+    })
21
+  }
22
+
23
+  const onConfirm = () => {
24
+    console.log(formData.newPassword)
25
+    try {
26
+      warn(formData.newPassword != formData.newPassword2, '两次新密码不一致');
27
+      warn(!formData.originPassword, '请输入原始密码');
28
+      warn(!formData.newPassword, '请输入新密码');
29
+    } catch (er) {
30
+      return ;
31
+    }
32
+
33
+    onClose();
34
+    onSubmit(formData);
35
+  }
36
+  
37
+  return (
38
+    <Dialog
39
+      showConfirmButton={false}
40
+      showCancelButton={false}
41
+      id={id}
42
+      show={show}
43
+      onClose={onClose}
44
+    >
45
+      <View style={{ padding: 'var(--main-space)', textAlign: 'center' }}>修改密码</View>
46
+      <CellGroup style={{ padding: 'var(--main-space)' }}>
47
+        <Field
48
+          required
49
+          label="原始密码"
50
+          type="password"
51
+          placeholder="请输入原始密码"
52
+          value={formData.originPassword}
53
+          onChange={(e) => setField('originPassword', e.detail)}
54
+        />
55
+        <Field
56
+          required
57
+          label="新密码"
58
+          type="password"
59
+          placeholder="请输入新密码"
60
+          value={formData.newPassword}
61
+          onChange={(e) => setField('newPassword', e.detail)}
62
+        />
63
+        <Field
64
+          required
65
+          label="确认密码"
66
+          type="password"
67
+          placeholder="请再次输入新密码"
68
+          value={formData.newPassword2}
69
+          onChange={(e) => setField('newPassword2', e.detail)}
70
+        />
71
+      </CellGroup>
72
+      <View style={{ display: 'flex', justifyContent: "space-around", alignItems: 'center' }}>
73
+        <View style={{ flex: 'none' }}>
74
+          <Button plain onClick={onClose}>取消</Button>
75
+        </View>
76
+        <View style={{ flex: 'none' }}>
77
+          <Button plain type="primary" onClick={onConfirm}>确定</Button>
78
+        </View>
79
+      </View>
80
+    </Dialog>
81
+  )
82
+}

+ 7
- 5
src/pages/my/index.jsx 查看文件

14
 
14
 
15
 export default (props) => {
15
 export default (props) => {
16
 
16
 
17
-  const { user, person, duty, signOut } = useModel('user');
17
+  const { user, person, duty, signOut, changePwd } = useModel('user');
18
   const [org, setOrg] = React.useState();
18
   const [org, setOrg] = React.useState();
19
 
19
 
20
   const [
20
   const [
51
     })
51
     })
52
   }
52
   }
53
 
53
 
54
+  const onChangePwd = (data) => {
55
+    changePwd(data);
56
+  }
57
+
54
   React.useEffect(() => {
58
   React.useEffect(() => {
55
     if (user) {
59
     if (user) {
56
       getSysOrgById(user.orgId).then(setOrg);
60
       getSysOrgById(user.orgId).then(setOrg);
62
       <Head
66
       <Head
63
         avatar={user?.avatar || person?.avatar || logo}
67
         avatar={user?.avatar || person?.avatar || logo}
64
         name={user?.name || person?.name || '市民先生'}
68
         name={user?.name || person?.name || '市民先生'}
69
+        onChangePwd={onChangePwd}
70
+        onExit={onExit}
65
       />
71
       />
66
       <View className={styles['bg-menu-box']}>
72
       <View className={styles['bg-menu-box']}>
67
         {
73
         {
82
           )
88
           )
83
         }
89
         }
84
       </View>
90
       </View>
85
-      <View className={styles.exit} onClick={onExit}>
86
-        退出
87
-        <Image src={iconExit} />
88
-      </View>
89
     </Page>
91
     </Page>
90
   )
92
   )
91
 }
93
 }

+ 0
- 20
src/pages/reporting/detail/components/Issue.jsx 查看文件

1
-import React from 'react';
2
-import { View } from '@tarojs/components';
3
-import style from './issue.module.less';
4
-
5
-export default (props) => {
6
-  
7
-  return (
8
-    <View className={style['issue-container']}>
9
-      <View class={style.card}>
10
-        <View className={style.title}>状态</View>
11
-      </View>
12
-      <View class={style.card}>
13
-        <View className={style.title}>问题描述</View>
14
-      </View>
15
-      <View class={style.card}>
16
-        <View className={style.title}>拍照</View>
17
-      </View>
18
-    </View>
19
-  )
20
-}

+ 0
- 17
src/pages/reporting/detail/components/Map.jsx 查看文件

1
-import React from 'react';
2
-import { View } from '@tarojs/components';
3
-import Map from '@/components/map';
4
-import style from './map.module.less';
5
-
6
-export default (props) => {
7
-  const { location } = props;
8
-  
9
-  return (
10
-    <View className={style['map-box']}>
11
-      <Map location={location} />
12
-      <View className={style.address}>
13
-        阳光丽景小区
14
-      </View>
15
-    </View>
16
-  )
17
-}

+ 0
- 21
src/pages/reporting/detail/components/issue.module.less 查看文件

1
-
2
-.issue-container {
3
-  margin-top: var(--main-space);
4
-
5
-  .card {
6
-    background: #fff;
7
-    padding: 0 var(--main-space);
8
-
9
-    & + .card {
10
-      margin-top: 2.67vw;
11
-    }
12
-  }
13
-
14
-  .title {
15
-    height: 90px;
16
-    font-size: 32px;
17
-    font-weight: bold;
18
-    color: #202020;
19
-    line-height: 90px;
20
-  }
21
-}

+ 0
- 16
src/pages/reporting/detail/components/map.module.less 查看文件

1
-
2
-.map-box {
3
-  width: 100vw;
4
-
5
-  .address {
6
-    width: 100%;
7
-    background: #fff;
8
-    height: 90px;
9
-    font-size: 24px;
10
-    font-weight: 500;
11
-    color: #202020;
12
-    line-height: 90px;
13
-    padding: 0 var(--main-space);
14
-  }
15
-  
16
-}

+ 0
- 3
src/pages/reporting/detail/index.config.js 查看文件

1
-export default definePageConfig({
2
-  navigationBarTitleText: '详情'
3
-})

+ 0
- 41
src/pages/reporting/detail/index.jsx 查看文件

1
-import React from 'react';
2
-import Taro from '@tarojs/taro';
3
-import { View } from '@tarojs/components';
4
-import { Notify } from '@antmjs/vantui';
5
-import Page from '@/layouts/index';
6
-import getAuthorize from '@/utils/authorize';
7
-import Map from './components/Map';
8
-import Issue from './components/Issue';
9
-
10
-export default (props) => {
11
-
12
-  const [loc, setLoc] = React.useState();
13
-
14
-  React.useMemo(() => {
15
-    getAuthorize('scope.userLocation').then(() => {
16
-      Taro.getLocation({
17
-        success(res) {
18
-          setLoc(`${res.longitude},${res.latitude}`);
19
-        },
20
-        fail() {
21
-          Notify.show({
22
-            message: '获取位置失败, 请退出重试',
23
-            type: 'warning',
24
-          })
25
-        }
26
-      });
27
-    }).catch((err) => {
28
-      Notify.show({
29
-        message: '未能获取位置, 程序部分功能将不能正常使用',
30
-        type: 'warning',
31
-      })
32
-    });
33
-  }, []);
34
-
35
-  return (
36
-    <Page>
37
-      <Map location={loc} />
38
-      <Issue />
39
-    </Page>
40
-  )
41
-}

+ 0
- 3
src/pages/reporting/index.config.js 查看文件

1
-export default definePageConfig({
2
-  navigationBarTitleText: '我的上报'
3
-})

+ 0
- 9
src/pages/reporting/index.jsx 查看文件

1
-import React from 'react';
2
-import { View } from '@tarojs/components';
3
-
4
-export default (props) => {
5
-  
6
-  return (
7
-    <View></View>
8
-  )
9
-}

+ 112
- 0
src/pages/user/add/index.jsx 查看文件

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 {
6
+  Button,
7
+  Field,
8
+  Cell,
9
+  CellGroup,
10
+  CheckboxGroup,
11
+  Checkbox,
12
+} from "@antmjs/vantui";
13
+import { ROLE_ORG_MANAGER, ROLE_ORG_USER } from "@/utils/user";
14
+
15
+import { warn } from "@/utils/message";
16
+import { postSysUser } from "@/services/sysuser";
17
+
18
+export default (props) => {
19
+  const [loading, setLoading] = React.useState(false);
20
+  const [identity, setIdentity] = React.useState([]);
21
+  const [formData, setFormData] = React.useState({});
22
+
23
+  const setField = (name, value) => {
24
+    setFormData((data) => ({
25
+      ...data,
26
+      [name]: value,
27
+    }));
28
+  };
29
+  const onSubmit = () => {
30
+    try {
31
+      warn(!formData.name, "请填写姓名");
32
+      warn(!formData.phone, "请填写手机号");
33
+      warn(identity.length < 1, "请选择身份");
34
+    } catch (e) {
35
+      return;
36
+    }
37
+
38
+    setLoading(true);
39
+    postSysUser({ ...formData, dutyList: identity })
40
+      .then(() => {
41
+        setLoading(false);
42
+        Taro.navigateBack({
43
+          delta: 1,
44
+          fail: () => {
45
+            Taro.reLaunch({
46
+              url: "/pages/user/list/index",
47
+            });
48
+          },
49
+        });
50
+      })
51
+      .catch(() => {
52
+        setLoading(false);
53
+      });
54
+  };
55
+
56
+  return (
57
+    <Page>
58
+      <CellGroup>
59
+        <Field
60
+          required
61
+          label="姓名"
62
+          placeholder="请输入姓名"
63
+          value={formData.name}
64
+          onChange={(e) => setField("name", e.detail)}
65
+        />
66
+        <Field
67
+          required
68
+          label="手机号"
69
+          placeholder="请输入手机号"
70
+          value={formData.phone}
71
+          onChange={(e) => setField("phone", e.detail)}
72
+        />
73
+        <Cell
74
+          title="身份"
75
+          required
76
+          titleWidth="100px"
77
+          titleStyle={{
78
+            maxWidth: "6.2em",
79
+            minWidth: "6.2em",
80
+            marginRight: "12px",
81
+          }}
82
+        >
83
+          <View style={{ display: "flex" }}>
84
+            <CheckboxGroup
85
+              direction="horizontal"
86
+              value={identity}
87
+              onChange={(e) => {
88
+                console.info(e);
89
+                setIdentity([...e.detail]);
90
+              }}
91
+            >
92
+              <Checkbox name={ROLE_ORG_USER}>单位人员</Checkbox>
93
+              <Checkbox name={ROLE_ORG_MANAGER}>单位管理员</Checkbox>
94
+            </CheckboxGroup>
95
+          </View>
96
+        </Cell>
97
+
98
+        {/* // 单位人员
99
+export const ROLE_ORG_USER = 'org_user';
100
+
101
+// 单位管理员
102
+export const ROLE_ORG_MANAGER = 'org_manager'; */}
103
+      </CellGroup>
104
+
105
+      <View style={{ padding: "var(--main-space)", background: "#fff" }}>
106
+        <Button block type="primary" loading={loading} onClick={onSubmit}>
107
+          提交
108
+        </Button>
109
+      </View>
110
+    </Page>
111
+  );
112
+};

+ 4
- 0
src/pages/user/list/index.config.js 查看文件

1
+// eslint-disable-next-line no-undef
2
+export default definePageConfig({
3
+  navigationBarTitleText: '人员列表'
4
+})

+ 82
- 0
src/pages/user/list/index.jsx 查看文件

1
+import React from "react";
2
+import Taro from "@tarojs/taro";
3
+import { View } from "@tarojs/components";
4
+import { Cell, Button, Dialog } from "@antmjs/vantui";
5
+import Page from "@/layouts/index";
6
+import PowerList from "@/components/PowerList";
7
+import { getSysUser, deleteSysUser } from "@/services/sysuser";
8
+import styles from "./index.module.less";
9
+
10
+export default (props) => {
11
+  const [loading, setLoading] = React.useState(false);
12
+  const listRef = React.useRef();
13
+
14
+  const onAdd = () => {
15
+    Taro.navigateTo({
16
+      url: "/pages/user/add/index",
17
+    });
18
+  };
19
+
20
+  const onDelete = (user) => {
21
+    Dialog.confirm({
22
+      title: "确认删除用户?",
23
+    }).then((e) => {
24
+      const { action } = e.detail;
25
+      if (action === "confirm") {
26
+        setLoading(true);
27
+        deleteSysUser(user.id)
28
+          .then(() => {
29
+            setLoading(false);
30
+
31
+            // 刷新列表
32
+            listRef.current.refresh();
33
+          })
34
+          .catch(() => {
35
+            setLoading(false);
36
+          });
37
+      }
38
+    });
39
+  };
40
+
41
+  return (
42
+    <Page loading={loading}>
43
+      <view className={styles["user-warpper"]}>
44
+        <view className={styles["user-warpper-list"]}>
45
+          <PowerList
46
+            ref={listRef}
47
+            request={getSysUser}
48
+            onLoadingChange={setLoading}
49
+            renderItem={(item) => (
50
+              <Cell
51
+                key={item.userId}
52
+                title={item.name}
53
+                label={item.createDate.substring(0, 10)}
54
+              >
55
+                <Button
56
+                  plain
57
+                  type="danger"
58
+                  size="small"
59
+                  onClick={() => onDelete(item)}
60
+                >
61
+                  删除
62
+                </Button>
63
+              </Cell>
64
+            )}
65
+          />
66
+        </view>
67
+
68
+        <Button
69
+          type="primary"
70
+          size="large"
71
+          onClick={() => onAdd()}
72
+          style={{
73
+            margin: "var(--main-space)",
74
+            width: "calc(100% - var(--main-space) * 2)",
75
+          }}
76
+        >
77
+          添加
78
+        </Button>
79
+      </view>
80
+    </Page>
81
+  );
82
+};

+ 12
- 0
src/pages/user/list/index.module.less 查看文件

1
+// height: calc(100% - env(safe-area-inset-bottom));
2
+.user-warpper {
3
+  height: 100%;
4
+  display: flex;
5
+  flex-direction: column;
6
+  .user-warpper-list {
7
+    height: calc(100% - 78px);
8
+  }
9
+  .user-warpper-btn {
10
+    width: 100%;
11
+  }
12
+}

+ 21
- 0
src/services/sysuser.js 查看文件

1
+import request from '@/utils/request';
2
+
3
+/*
4
+ * 分页查询
5
+ */
6
+export const getSysUser = (params) => request('/api/ma/sysUser', { params });
7
+
8
+/*
9
+ * 新增数据
10
+ */
11
+export const postSysUser = (data) => request('/api/ma/sysUser', { data, method: 'post' });
12
+
13
+/*
14
+ * 通过主键删除数据
15
+ */
16
+export const deleteSysUser = (id) => request(`/api/ma/sysUser/${id}`, { method: 'delete' });
17
+
18
+/*
19
+ * 修改密码
20
+ */
21
+export const changePassword = (data) => request('/api/ma/sysUser/change-password', { method: 'put', data });

+ 2
- 0
src/services/taissueapply.js 查看文件

27
  * 通过主键删除数据
27
  * 通过主键删除数据
28
  */
28
  */
29
 export const deleteTaIssueApply = (id) => request(`/api/taIssueApply/${id}`, { method: 'delete' });
29
 export const deleteTaIssueApply = (id) => request(`/api/taIssueApply/${id}`, { method: 'delete' });
30
+
31
+export const getApplyNum = params => request('/api/taIssueApply/nums', { params });

+ 11
- 0
src/store/user.js 查看文件

2
 import Taro from '@tarojs/taro';
2
 import Taro from '@tarojs/taro';
3
 import md5 from 'md5';
3
 import md5 from 'md5';
4
 import { login, signin, currentUser, authPhone, authUser } from '@/services/wxma';
4
 import { login, signin, currentUser, authPhone, authUser } from '@/services/wxma';
5
+import { changePassword } from '@/services/sysuser';
5
 import { ROLE_CITIZEN } from '@/utils/user';
6
 import { ROLE_CITIZEN } from '@/utils/user';
6
 
7
 
7
 export default function useUser() {
8
 export default function useUser() {
75
     initDuty([]);
76
     initDuty([]);
76
   }
77
   }
77
 
78
 
79
+  const changePwd = (params) => {
80
+    const data = {
81
+      originPassword: md5(params.originPassword),
82
+      newPassword: md5(params.newPassword),
83
+    }
84
+
85
+    changePassword(data);
86
+  }
87
+
78
   return {
88
   return {
79
     user,
89
     user,
80
     person,
90
     person,
86
     signinByPhone,
96
     signinByPhone,
87
     authProfile,
97
     authProfile,
88
     signOut,
98
     signOut,
99
+    changePwd,
89
   }
100
   }
90
 }
101
 }

+ 2
- 1
src/utils/authorize.js 查看文件

25
   });
25
   });
26
 }
26
 }
27
 
27
 
28
-export const getLocation = () => {
28
+export const getLocation = (options) => {
29
   return new Promise((resolve, reject) => {
29
   return new Promise((resolve, reject) => {
30
     getAuthorize('scope.userLocation').then(() => {
30
     getAuthorize('scope.userLocation').then(() => {
31
       Taro.getLocation({
31
       Taro.getLocation({
32
+        ...options || {},
32
         success(res) {
33
         success(res) {
33
           resolve(res);
34
           resolve(res);
34
         },
35
         },