Your Name 2 years ago
parent
commit
bda3aebaad

+ 2
- 1
.eslintrc View File

@@ -3,6 +3,7 @@
3 3
   "rules": {
4 4
     "react/jsx-uses-react": "off",
5 5
     "react/react-in-jsx-scope": "off",
6
-    "no-unused-vars": "warn"
6
+    "no-unused-vars": "warn",
7
+    "jsx-quotes": ["warn", "prefer-double"]
7 8
   }
8 9
 }

+ 1
- 1
babel.config.js View File

@@ -13,7 +13,7 @@ module.exports = {
13 13
       {
14 14
         libraryName: "@antmjs/vantui",
15 15
         libraryDirectory: "es",
16
-        style: true
16
+        style: (name) => `${name}/style/less`,
17 17
       },
18 18
       "@antmjs/vantui"
19 19
     ]

+ 2
- 1
config/dev.js View File

@@ -3,7 +3,8 @@ module.exports = {
3 3
     NODE_ENV: '"development"'
4 4
   },
5 5
   defineConstants: {
6
-    HOST: '"http://192.168.89.147:9087"'
6
+    // HOST: '"http://127.0.0.1:9087"'
7
+    HOST: '"http://192.168.1.2:9087"'
7 8
   },
8 9
   mini: {},
9 10
   h5: {}

+ 1
- 0
package.json View File

@@ -48,6 +48,7 @@
48 48
     "@tarojs/taro": "3.5.7",
49 49
     "@tarojs/taro-h5": "3.5.7",
50 50
     "@zjxpcyc/react-tiny-store": "^2.0.1",
51
+    "md5": "^2.3.0",
51 52
     "react": "^18.0.0",
52 53
     "react-dom": "^18.0.0"
53 54
   },

+ 3
- 3
src/app.config.js View File

@@ -1,7 +1,7 @@
1 1
 export default defineAppConfig({
2 2
   pages: [
3
-    'pages/login/index',
4 3
     'pages/home/index',
4
+    'pages/login/index',
5 5
     'pages/index3/index',
6 6
     'pages/index4/index',
7 7
     'pages/index5/index',
@@ -11,11 +11,11 @@ export default defineAppConfig({
11 11
   tabBar: {
12 12
     list: [
13 13
       {
14
-        "pagePath": "pages/login/index",
14
+        "pagePath": "pages/home/index",
15 15
         "text": "首页"
16 16
       },
17 17
       {
18
-        "pagePath": "pages/home/index",
18
+        "pagePath": "pages/reporting/index",
19 19
         "text": "公告"
20 20
       },
21 21
       {

+ 3
- 1
src/app.js View File

@@ -10,7 +10,9 @@ const App = (props) => {
10 10
       success: (res) => {
11 11
         store.getState('user').login(res.code);
12 12
       }
13
-    })
13
+    });
14
+
15
+    store.getState('user').current();
14 16
   });
15 17
 
16 18
   return (

+ 4
- 3
src/app.less View File

@@ -7,10 +7,11 @@ page {
7 7
   --main-space: 4vw;
8 8
 
9 9
   // antm-js 样式修改
10
-  // 按钮主色
11
-  --buttonPrimaryBackgroundColor: #1A7565;
10
+  // 按钮
11
+  --button-primary-color: #FFFFFF;
12
+  --button-primary-background-color: var(--main-bg-color);
12 13
   // 菊花转主色
13
-  --loading-spinner-color: #1A7565;
14
+  --loading-spinner-color: var(--main-bg-color);
14 15
 }
15 16
 
16 17
 view {

+ 1
- 1
src/components/Auth.jsx View File

@@ -20,7 +20,7 @@ export default (props) => {
20 20
     }
21 21
   }
22 22
 
23
-  return hasRights ? props.children : (
23
+  return !roles.length || hasRights ? props.children : (
24 24
     <View style={{width: '100%', height: '100%', display: 'grid', placeItems: 'center'}}>
25 25
       <View>暂无权限</View>
26 26
     </View>

+ 23
- 2
src/layouts/index.jsx View File

@@ -1,4 +1,5 @@
1 1
 import React from 'react';
2
+import Taro from '@tarojs/taro';
2 3
 import { View } from '@tarojs/components';
3 4
 import { useModel } from '@/store';
4 5
 import { Loading } from '@antmjs/vantui';
@@ -6,12 +7,32 @@ import Auth from '@/components/Auth';
6 7
 import laySty from './layout.module.less';
7 8
 
8 9
 export default (props) => {
9
-  const { className, style, roles } = props;
10
+  const { className, style, roles, showTabBar } = props;
10 11
 
11
-  const { person } = useModel('user');
12
+  const { person, user } = useModel('user');
12 13
 
13 14
   const classNames = `${laySty['page-wrapper']} ${className}`;
14 15
 
16
+  React.useMemo(() => {
17
+    if (showTabBar) {
18
+      Taro.showTabBar();
19
+    } else {
20
+      Taro.hideTabBar();
21
+    }
22
+  }, [showTabBar]);
23
+
24
+  React.useEffect(() => {
25
+    console.log('----------->', person, user);
26
+    if (person && !user) {
27
+      const currentPage = Taro.getCurrentPages().slice().pop();      
28
+      if ('pages/login/index' !== currentPage.route) {
29
+        Taro.navigateTo({
30
+          url: '/pages/login/index',
31
+        })
32
+      }
33
+    }
34
+  }, [person, user]);
35
+
15 36
   return (
16 37
     <View className={classNames} style={style}>
17 38
       {

+ 7
- 2
src/pages/home/components/Head.jsx View File

@@ -1,15 +1,20 @@
1 1
 import React from 'react';
2 2
 import { View } from '@tarojs/components';
3
+import { ROLES, ROLE_CITIZEN } from '@/utils/user';
3 4
 import style from './head.module.less';
4 5
 
5 6
 export default (props) => {
7
+  const { user = {} } = props;
8
+  const { dutyList = [] } = user;
9
+  const role = ROLES[dutyList[0] || ROLE_CITIZEN];
10
+
6 11
   return (
7 12
     <View className={style.head}>
8 13
       <View className={style.profile}>
9
-        <View>Hi, 张三!</View>
14
+        <View style={{ letterSpacing: '2px' }}>Hi, {user.name}!</View>
10 15
         <View className={style.badge}>
11 16
           <View className={style.icon}></View>
12
-          <View>督察员</View>
17
+          <View>{role}</View>
13 18
         </View>
14 19
       </View>
15 20
       <View className={style.avatar}>

+ 23
- 8
src/pages/home/components/head.module.less View File

@@ -14,24 +14,39 @@
14 14
     font-size: 42px;
15 15
 
16 16
     .badge {
17
+      display: inline-block;
17 18
       position: relative;
18
-      padding-left: 64px;
19
+      padding-right: 24px;
20
+      padding-left: 72px;
19 21
       margin-top: var(--main-space);
20 22
       height: 48px;
21
-      line-height: 48px;
23
+      line-height: 46px; // 向上偏移2像素
22 24
       background: linear-gradient(0, #E36A00, #FFA658);
23 25
       border-radius: 22px;
24 26
       font-size: 24px;
27
+      text-align: center;
25 28
 
26 29
       .icon {
27
-        top: -8px;
28
-        left: -8px;
30
+        top: -12px;
31
+        left: -12px;
29 32
         position: absolute;
30
-        width: 64px;
31
-        height: 64px;
32
-        background: linear-gradient(0, #E36A00, #FFA658);
33
+        width: 56px;
34
+        height: 56px;
35
+        border: 8px solid rgba(251, 239, 121, 0.6);
33 36
         border-radius: 50%;
34
-        border: 8px solid rgba(251, 239, 121, 0.2);
37
+        box-sizing: content-box;
38
+
39
+        &::before {
40
+          content: '';
41
+          position: absolute;
42
+          top: 0;
43
+          left: 0;
44
+          width: 56px;
45
+          height: 56px;
46
+          background: linear-gradient(0, #E36A00, #FFA658);
47
+          border-radius: 50%;
48
+          overflow: hidden;
49
+        }
35 50
       }
36 51
     }
37 52
   }

+ 6
- 2
src/pages/home/index.jsx View File

@@ -1,15 +1,19 @@
1 1
 import React from 'react'
2 2
 import { View, Text, Image } from '@tarojs/components'
3 3
 import Page from '@/layouts/index';
4
+import { useModel } from '@/store';
4 5
 import Head from './components/Head';
5 6
 import BannerCard from './components/BannerCard';
6 7
 import MenuCard from './components/MenuCard';
7 8
 import './index.less';
8 9
 
9 10
 export default (props) => {
11
+
12
+  const { user } = useModel('user');
13
+
10 14
   return (
11
-    <Page className='index'>
12
-      <Head />
15
+    <Page showTabBar className='index'>
16
+      <Head user={user} />
13 17
       <BannerCard />
14 18
       <MenuCard />
15 19
     </Page>

+ 70
- 24
src/pages/login/components/Form.jsx View File

@@ -1,30 +1,76 @@
1 1
 import React from 'react';
2
-import { View, Image, Input } from '@tarojs/components';
3
-import { Form, Button } from '@antmjs/vantui'
4
-import user from '../../../assets/image/user.png';
5
-import password from '../../../assets/image/password.png';
6
-import style from './form.module.less';
2
+import { View } from '@tarojs/components';
3
+import { Form, FormItem, Field, Button } from '@antmjs/vantui'
4
+import { useModel } from '@/store';
5
+import user from '@/assets/image/user.png';
6
+import password from '@/assets/image/password.png';
7
+import './form.less';
7 8
 
8 9
 export default (props) => {
10
+  const { onSuccess } = props;
11
+
12
+  const { signin } = useModel('user');
13
+  const form = Form.useForm();
14
+  const [accErr, setAccErr] = React.useState();
15
+  const [pwdErr, setPwdErr] = React.useState();
16
+
17
+  const onFinish = (errs, res) => {
18
+    if (!res.account) {
19
+      setAccErr('账户不能为空');
20
+      return;
21
+    } else {
22
+      setAccErr();
23
+    }
24
+    if (!res.password) {
25
+      setPwdErr('密码不能为空');
26
+      return;
27
+    } else {
28
+      setPwdErr();
29
+    }
30
+
31
+    signin(res).then(onSuccess);
32
+  }
33
+
9 34
   return (
10
-    <Form className={style.form}>
11
-      <View className={style['input-box']}>
12
-        <Image src={user} className={style['img-icon']} />账号<Input className={style.input} placeholder='请输入您的登录账号' />
13
-      </View>
14
-      <View className={style['input-box']}>
15
-        <Image src={password} className={style['img-icon']} />密码<Input className={style.input} placeholder='请输入您的登录密码' />
16
-      </View>
17
-      <View
18
-        className={style['forget-pwd']}
19
-      >
20
-        忘记密码?
21
-      </View>
22
-      <Button
23
-        type='primary'
24
-        className={style.submit}
25
-      >
26
-        登录
27
-      </Button>
28
-    </Form>
35
+    <View className="login-form">
36
+      <Form form={form} onFinish={onFinish}>
37
+        <FormItem
38
+          name="account"
39
+          valueFormat={(e) => e.detail}
40
+        >
41
+          <Field
42
+            border
43
+            label="账号"
44
+            leftIcon={user}
45
+            errorMessage={accErr}
46
+            placeholder="请输入您的登录账号"
47
+          ></Field>
48
+        </FormItem>
49
+        <FormItem
50
+          name="password"
51
+          valueFormat={(e) => e.detail}
52
+        >
53
+          <Field
54
+            password
55
+            label="密码"
56
+            leftIcon={password}
57
+            errorMessage={pwdErr}
58
+            placeholder="请输入您的登录密码"
59
+          ></Field>
60
+        </FormItem>
61
+        <View className="forget-password">
62
+          忘记密码?
63
+        </View>
64
+        <View>
65
+          <Button
66
+            block
67
+            type="primary"
68
+            formType="submit"
69
+          >
70
+            登录
71
+          </Button>
72
+        </View>
73
+      </Form>
74
+    </View>
29 75
   )
30 76
 }

+ 63
- 0
src/pages/login/components/form.less View File

@@ -0,0 +1,63 @@
1
+.login-form {
2
+  width: 100%;
3
+  box-sizing: border-box;
4
+  padding: 0 var(--main-space);
5
+
6
+  .vant-form-formItem,
7
+  .vant-form-formItem-wrapper,
8
+  .vant-form-formItem-controll {
9
+    margin: 0;
10
+    padding: 0;
11
+    background-color: transparent;
12
+  }
13
+
14
+  .vant-form-formItem-wrapper {
15
+    & + .vant-form-formItem-wrapper {
16
+      margin-top: var(--main-space);
17
+    }
18
+  }
19
+
20
+  .vant-form-label {
21
+    width: 0;
22
+  }
23
+
24
+  .field-wrapper {
25
+    width: 100%;
26
+    padding: 0 var(--main-space);
27
+  }
28
+
29
+  .van-cell {
30
+    background-color: transparent;
31
+
32
+    &::after {
33
+      border-bottom-color: rgba(0,0,0,0.12);
34
+    }
35
+  }
36
+
37
+  .van-icon__image {
38
+    width: 42px;
39
+    height: 42px;
40
+    vertical-align: middle;
41
+  }
42
+
43
+  .van-cell__title {
44
+    margin-left: 20px;
45
+    font-size: 16px;
46
+    vertical-align: middle;
47
+    border-right: 1px solid #000;
48
+  }
49
+
50
+  .van-field__label {
51
+    font-size: 32px;
52
+  }
53
+
54
+  .forget-password {
55
+    text-align: right;
56
+    font-size: 28px;
57
+    font-weight: 400;
58
+    color: var(--main-bg-color);
59
+    height: 148px;
60
+    line-height: 148px;
61
+    padding: 0 var(--main-space);
62
+  }
63
+}

+ 0
- 36
src/pages/login/components/form.module.less View File

@@ -1,36 +0,0 @@
1
-.form {
2
-  width: 620px;
3
-  .input-box {
4
-    display: flex;
5
-    border-bottom: 1px solid #e9eaea;
6
-    width: 600px;
7
-    margin: 26px auto;
8
-    padding-bottom: 30px;
9
-    margin-top: 60px;
10
-    .img-icon {
11
-      margin-right: 30px;
12
-      width: 42px;
13
-      height: 44px;
14
-    }
15
-    .input {
16
-      color: rgb(174, 174, 174);
17
-      margin-left: 15px;
18
-      padding-left: 20px;
19
-      flex-direction: column;
20
-      border-left: 1px solid black;
21
-    }
22
-  }
23
-  .forget-pwd {
24
-    font-size: 28px;
25
-    color: var(--main-bg-color);
26
-    float: right;
27
-    margin-right: 72px;
28
-    margin-bottom: 104px;
29
-  }
30
-  .submit {
31
-    width: 666px;
32
-    margin: 80px auto;
33
-    background-color: var(--main-bg-color);
34
-    color: #fff;
35
-  }
36
-}

+ 22
- 5
src/pages/login/index.jsx View File

@@ -1,19 +1,36 @@
1
-import Page from '@/layouts/index';
1
+import React from 'react';
2
+import Taro from '@tarojs/taro';
2 3
 import { View } from '@tarojs/components';
4
+import Page from '@/layouts/index';
3 5
 import Head from "./components/Head";
4 6
 import Form from "./components/Form";
5 7
 import Bottom from "./components/Bottom";
6 8
 import './index.less'
7 9
 
8 10
 export default (props) => {
11
+
12
+  React.useMemo(() => {  
13
+    Taro.hideTabBar();
14
+  }, []);
15
+
16
+  const onSuccess = () => {
17
+    Taro.navigateBack({
18
+      delta: 1,
19
+      fail: () => {
20
+        Taro.reLaunch({
21
+          url: '/pages/home/index'
22
+        })
23
+      }
24
+    });
25
+  }
26
+
9 27
   return (
10
-    <Page className='index'>
11
-      <View className='login-box'>
28
+    <Page className="index">
29
+      <View className="login-box">
12 30
         <Head />
13
-        <Form />
31
+        <Form onSuccess={onSuccess} />
14 32
         <Bottom />
15 33
       </View>
16 34
     </Page>
17
-
18 35
   )
19 36
 }

+ 10
- 0
src/services/wxma.js View File

@@ -14,3 +14,13 @@ export const authUser = (id, data) => request(`/api/ma/auth-user`, { data, metho
14 14
  * 小程序登录
15 15
  */
16 16
 export const login = (code) => request(`/api/ma/login?code=${code}`, { method: 'post', silent: true });
17
+
18
+/*
19
+ * 小程序登录
20
+ */
21
+export const signin = (data) => request(`/api/ma/signin`, { method: 'post', data });
22
+
23
+/*
24
+ * 获取当前人员
25
+ */
26
+export const currentUser = () => request(`/api/ma/current`);

+ 24
- 4
src/store/user.js View File

@@ -1,22 +1,42 @@
1 1
 import React from 'react';
2 2
 import Taro from '@tarojs/taro';
3
-import { login } from '@/services/wxma';
3
+import md5 from 'md5';
4
+import { login, signin, currentUser } from '@/services/wxma';
4 5
 
5 6
 export default function useUser() {
6
-  const [person, setPerson] = React.useState({});
7
-  const [user, setUser] = React.useState({});
7
+  const [person, setPerson] = React.useState();
8
+  const [user, setUser] = React.useState();
8 9
 
9 10
   const maLogin = (code) => {
10 11
     login(code).then(res => {
11 12
       setPerson(res.person);
12
-      setUser(res.user);
13
+      Taro.setStorage({ key: 'personId', data: res.person.personId })
13 14
       Taro.setStorage({ key: 'sessionKey', data: res.sessionKey })
14 15
     });
15 16
   }
16 17
 
18
+  const maSignIn = (params) => {
19
+    const data = {
20
+      ...params,
21
+      password: md5(params.password)
22
+    }
23
+
24
+    return signin(data).then(res => {
25
+      setUser(res.user);
26
+    })
27
+  }
28
+
29
+  const current = () => {
30
+    currentUser().then(res => {
31
+      setUser(res.user);
32
+    })
33
+  }
34
+
17 35
   return {
18 36
     user,
19 37
     person,
38
+    current,
39
+    signin: maSignIn,
20 40
     login: maLogin,
21 41
   }
22 42
 }

+ 3
- 1
src/utils/request.js View File

@@ -16,7 +16,8 @@ export default function request(api, options = {}) {
16 16
     const { method = 'GET', params, data = {}, header = {}, silent = false, ...cfgs } = options;
17 17
     const queryStr = params ? getQueryStrByParams(params) : undefined;
18 18
     // eslint-disable-next-line no-undef
19
-    const url = queryStr ? `${HOST}${api}?${queryStr}` : `${HOST}${api}`
19
+    const url = queryStr ? `${HOST}${api}?${queryStr}` : `${HOST}${api}`;
20
+    const personId = Taro.getStorageSync('personId');
20 21
     
21 22
     const onError = (err) => {
22 23
       console.error(err);
@@ -39,6 +40,7 @@ export default function request(api, options = {}) {
39 40
       data,
40 41
       method,
41 42
       header: {
43
+        'x-personId': personId,
42 44
         'content-type': 'application/json',
43 45
         'authorization': getToken(),
44 46
         ...header,

+ 9
- 0
src/utils/user.js View File

@@ -13,3 +13,12 @@ export const ROLE_QUERY_PERSON = 'query_person';
13 13
 
14 14
 // 市民
15 15
 export const ROLE_CITIZEN = 'citizen';
16
+
17
+
18
+export const ROLES = {
19
+  [ROLE_INSPECTOR]: '督察员',
20
+  [ROLE_MANAGER]: '管理员',
21
+  [ROLE_ORG_USER]: '单位人员',
22
+  [ROLE_QUERY_PERSON]: '查询员',
23
+  [ROLE_CITIZEN]: '市民',
24
+}

+ 1
- 1
yarn.lock View File

@@ -8180,7 +8180,7 @@ md5.js@^1.3.4:
8180 8180
 
8181 8181
 md5@^2.3.0:
8182 8182
   version "2.3.0"
8183
-  resolved "https://registry.npmmirror.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f"
8183
+  resolved "https://registry.yarnpkg.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f"
8184 8184
   integrity sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==
8185 8185
   dependencies:
8186 8186
     charenc "0.0.2"