Commit 2da6a746e4761c85749a8433a25d79d51daff1ce
1 parent
86ef156d
增加个人信息的加载
Showing
13 changed files
with
295 additions
and
99 deletions
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/util/SecurityFrameworkUtils.java
| 1 | 1 | package cn.iocoder.yudao.framework.security.core.util; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | |
| 3 | 4 | import cn.iocoder.yudao.framework.security.core.LoginUser; |
| 4 | 5 | import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; |
| 5 | 6 | import org.springframework.lang.Nullable; |
| ... | ... | @@ -11,6 +12,7 @@ import org.springframework.security.web.authentication.WebAuthenticationDetailsS |
| 11 | 12 | import org.springframework.util.StringUtils; |
| 12 | 13 | |
| 13 | 14 | import javax.servlet.http.HttpServletRequest; |
| 15 | +import java.util.Objects; | |
| 14 | 16 | import java.util.Set; |
| 15 | 17 | |
| 16 | 18 | /** |
| ... | ... | @@ -100,7 +102,9 @@ public class SecurityFrameworkUtils { |
| 100 | 102 | WebFrameworkUtils.setLoginUserId(request, loginUser.getId()); |
| 101 | 103 | WebFrameworkUtils.setLoginUserType(request, loginUser.getUserType()); |
| 102 | 104 | // TODO @jason:使用 userId 会不会更合适哈? |
| 103 | - org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(loginUser.getUsername()); | |
| 105 | + if (Objects.equals(UserTypeEnum.ADMIN.getValue(), loginUser.getUserType())) { | |
| 106 | + org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(loginUser.getUsername()); | |
| 107 | + } | |
| 104 | 108 | } |
| 105 | 109 | |
| 106 | 110 | } | ... | ... |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/SysUserProfileController.http
| 1 | -### 请求 /system/user/profile/get 接口 => 没有权限 | |
| 2 | -GET {{userServerUrl}}/system/user/profile/get | |
| 1 | +### 请求 /member/user/profile/get 接口 => 没有权限 | |
| 2 | +GET {{userServerUrl}}/member/user/profile/get | |
| 3 | 3 | Authorization: Bearer test245 |
| 4 | 4 | |
| 5 | -### 请求 /system/user/profile/revise-nickname 接口 成功 | |
| 6 | -PUT {{userServerUrl}}/system/user/profile/update-nickname?nickName=yunai222 | |
| 5 | +### 请求 /member/user/profile/revise-nickname 接口 成功 | |
| 6 | +PUT {{userServerUrl}}/member/user/profile/update-nickname?nickName=yunai222 | |
| 7 | 7 | Authorization: Bearer test245 |
| 8 | 8 | |
| 9 | -### 请求 /system/user/profile/get-user-info 接口 成功 | |
| 10 | -GET {{userServerUrl}}/system/user/profile/get-user-info?id=245 | |
| 11 | -Authorization: Bearer test245 | |
| 12 | 9 | \ No newline at end of file |
| 10 | +### 请求 /member/user/profile/get-user-info 接口 成功 | |
| 11 | +GET {{userServerUrl}}/member/user/profile/get-user-info?id=245 | |
| 12 | +Authorization: Bearer test245 | ... | ... |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/SysUserProfileController.java
| ... | ... | @@ -27,7 +27,7 @@ import static cn.iocoder.yudao.userserver.modules.member.enums.MbrErrorCodeConst |
| 27 | 27 | |
| 28 | 28 | @Api(tags = "用户个人中心") |
| 29 | 29 | @RestController |
| 30 | -@RequestMapping("/system/user/profile") | |
| 30 | +@RequestMapping("/member/user/profile") | |
| 31 | 31 | @Validated |
| 32 | 32 | @Slf4j |
| 33 | 33 | public class SysUserProfileController { |
| ... | ... | @@ -57,14 +57,13 @@ public class SysUserProfileController { |
| 57 | 57 | return success(avatar); |
| 58 | 58 | } |
| 59 | 59 | |
| 60 | - @GetMapping("/get-user-info") | |
| 61 | - @ApiOperation("获取用户头像与昵称") | |
| 60 | + @GetMapping("/get") | |
| 61 | + @ApiOperation("获得基本信息") | |
| 62 | 62 | @PreAuthenticated |
| 63 | 63 | public CommonResult<MbrUserInfoRespVO> getUserInfo() { |
| 64 | 64 | return success(userService.getUserInfo(getLoginUserId())); |
| 65 | 65 | } |
| 66 | 66 | |
| 67 | - | |
| 68 | 67 | @PostMapping("/update-mobile") |
| 69 | 68 | @ApiOperation(value = "修改用户手机") |
| 70 | 69 | @PreAuthenticated | ... | ... |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/MbrUserService.java
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.java
| ... | ... | @@ -40,7 +40,6 @@ public class SysAuthController { |
| 40 | 40 | @Resource |
| 41 | 41 | private SysSocialService socialService; |
| 42 | 42 | |
| 43 | - | |
| 44 | 43 | @PostMapping("/login") |
| 45 | 44 | @ApiOperation("使用手机 + 密码登录") |
| 46 | 45 | public CommonResult<SysAuthLoginRespVO> login(@RequestBody @Valid SysAuthLoginReqVO reqVO) { | ... | ... |
yudao-vue-ui/App.vue
| 1 | 1 | <script> |
| 2 | + import Vue from 'vue' | |
| 3 | + import { getAuthToken } from '@/common/js/util.js' | |
| 4 | + let __timerId = 0; | |
| 2 | 5 | export default { |
| 3 | - onLaunch: function() { | |
| 4 | - console.log('App Launch') | |
| 6 | + onLaunch() { | |
| 7 | + uni.getSystemInfo({ | |
| 8 | + success: e=> { | |
| 9 | + this.initSize(e); | |
| 10 | + } | |
| 11 | + }) | |
| 12 | + this.initLogin(); | |
| 5 | 13 | }, |
| 6 | - onShow: function() { | |
| 7 | - console.log('App Show') | |
| 14 | + methods: { | |
| 15 | + // 初始化登陆状态 | |
| 16 | + async initLogin(){ | |
| 17 | + const token = getAuthToken() | |
| 18 | + if (!token) { | |
| 19 | + return; | |
| 20 | + } | |
| 21 | + // 通过设置 Token 的方式,触发加载用户信息 | |
| 22 | + this.$store.commit('setToken', { | |
| 23 | + token | |
| 24 | + }); | |
| 25 | + }, | |
| 26 | + /** | |
| 27 | + * 存储设备信息 参考colorUI | |
| 28 | + * @param {Object} | |
| 29 | + */ | |
| 30 | + initSize(e){ | |
| 31 | + const systemInfo = e; | |
| 32 | + let navigationBarHeight; | |
| 33 | + let custom = {}; | |
| 34 | + // #ifndef MP | |
| 35 | + custom = {height: 36,width: 88}; | |
| 36 | + navigationBarHeight = 44; | |
| 37 | + // #endif | |
| 38 | + // #ifdef MP | |
| 39 | + custom = wx.getMenuButtonBoundingClientRect(); | |
| 40 | + navigationBarHeight = custom.bottom + custom.top - e.statusBarHeight * 2; | |
| 41 | + // #endif | |
| 42 | + systemInfo.custom = custom; | |
| 43 | + systemInfo.navigationBarHeight = navigationBarHeight; | |
| 44 | + Vue.prototype.systemInfo = systemInfo; | |
| 45 | + }, | |
| 46 | + //打开全局定时器 | |
| 47 | + openTimer(){ | |
| 48 | + this.closeTimer(); | |
| 49 | + __timerId = setInterval(()=>{ | |
| 50 | + this.$store.commit('setStateAttr', { | |
| 51 | + key: 'timerIdent', | |
| 52 | + val: !this.$store.state.timerIdent | |
| 53 | + }) | |
| 54 | + }, 1000) | |
| 55 | + }, | |
| 56 | + //关闭定时器 | |
| 57 | + closeTimer(){ | |
| 58 | + if(__timerId != 0){ | |
| 59 | + clearInterval(__timerId); | |
| 60 | + __timerId = 0; | |
| 61 | + } | |
| 62 | + }, | |
| 8 | 63 | }, |
| 9 | - onHide: function() { | |
| 10 | - console.log('App Hide') | |
| 64 | + onShow() { | |
| 65 | + console.log('app show'); | |
| 66 | + this.openTimer(); | |
| 67 | + }, | |
| 68 | + onHide() { | |
| 69 | + this.closeTimer(); | |
| 11 | 70 | } |
| 12 | 71 | } |
| 13 | 72 | </script> |
| 14 | 73 | |
| 15 | -<style> | |
| 74 | +<style lang="scss"> | |
| 16 | 75 | /*每个页面公共css */ |
| 17 | 76 | @import url("./common/css/common.css"); |
| 18 | 77 | @import url("./common/css/icon.css"); |
| 19 | -</style> | |
| 20 | 78 | \ No newline at end of file |
| 79 | + | |
| 80 | + .lazyload{ | |
| 81 | + position: relative; | |
| 82 | + | |
| 83 | + &.lazypic{ | |
| 84 | + &:after{ | |
| 85 | + content: ''; | |
| 86 | + position: absolute; | |
| 87 | + left: 0; | |
| 88 | + top: 0; | |
| 89 | + width: 100%; | |
| 90 | + height: 100%; | |
| 91 | + background-image: url(data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAA8AAD/4QONaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjMtYzAxMSA2Ni4xNDU2NjEsIDIwMTIvMDIvMDYtMTQ6NTY6MjcgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6NDk2YzE1OGEtNDgwYi1lZjRhLTk1NzYtZWM0MzZmNmMyNDQ4IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjQ2RjVCRUM2QTY0QzExRTlCM0Y1OEVDNUMxRTQ3REE2IiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjQ2RjVCRUM1QTY0QzExRTlCM0Y1OEVDNUMxRTQ3REE2IiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOmQ3NTBhNjM2LWIxN2UtOGQ0MS1hMGFlLTllZTliZjkzMzhhMCIgc3RSZWY6ZG9jdW1lbnRJRD0iYWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOjAyZTYxMzJlLTYyYzItOTQ0My1iMmYwLWE3NzA0NjVmMTljOCIvPiA8L3Jk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); | |
| 92 | + background-size: 100% 100%; | |
| 93 | + opacity: 0.3; | |
| 94 | + } | |
| 95 | + } | |
| 96 | + image{ | |
| 97 | + position: relative; | |
| 98 | + z-index: 1; | |
| 99 | + opacity: 0; | |
| 100 | + } | |
| 101 | + &.loaded image{ | |
| 102 | + transition: .7s; | |
| 103 | + opacity: 1 !important; | |
| 104 | + } | |
| 105 | + } | |
| 106 | +</style> | ... | ... |
yudao-vue-ui/api/member/userProfile.js
0 → 100644
yudao-vue-ui/api/system/auth.js
0 → 100644
| 1 | +import { request } from '@/common/js/request.js' | |
| 2 | + | |
| 3 | +// 手机号 + 密码登陆 | |
| 4 | +export function login(mobile, password) { | |
| 5 | + const data = { | |
| 6 | + mobile, | |
| 7 | + password | |
| 8 | + } | |
| 9 | + return request({ | |
| 10 | + url: 'login', | |
| 11 | + method: 'post', | |
| 12 | + data: data | |
| 13 | + }) | |
| 14 | +} | |
| 15 | + | |
| 16 | +// 手机号 + 验证码登陆 | |
| 17 | +export function smsLogin(mobile, code) { | |
| 18 | + const data = { | |
| 19 | + mobile, | |
| 20 | + code | |
| 21 | + } | |
| 22 | + return request({ | |
| 23 | + url: 'sms-login', | |
| 24 | + method: 'post', | |
| 25 | + data: data | |
| 26 | + }) | |
| 27 | +} | |
| 0 | 28 | \ No newline at end of file | ... | ... |
yudao-vue-ui/common/js/request.js
| 1 | 1 | const BASE_URL = 'http://127.0.0.1:28080/api/'; |
| 2 | -import { msg } from './util' | |
| 2 | +import { msg, getAuthToken } from './util' | |
| 3 | 3 | |
| 4 | 4 | export const request = (options) => { |
| 5 | 5 | return new Promise((resolve, reject) => { |
| 6 | 6 | // 发起请求 |
| 7 | + const authToken = getAuthToken(); | |
| 7 | 8 | uni.request({ |
| 8 | 9 | url: BASE_URL + options.url, |
| 9 | 10 | method: options.method || 'GET', |
| 10 | 11 | data: options.data || {}, |
| 11 | 12 | header: { |
| 12 | - 'Authorization': '' // TODO 芋艿:带 token | |
| 13 | + 'Authorization': authToken ? `Bearer ${authToken}` : '' | |
| 13 | 14 | } |
| 14 | 15 | }).then(res => { |
| 15 | - debugger | |
| 16 | 16 | res = res[1]; |
| 17 | 17 | const statusCode = res.statusCode; |
| 18 | 18 | if (statusCode !== 200) { | ... | ... |
yudao-vue-ui/common/js/util.js
| ... | ... | @@ -34,14 +34,103 @@ export const throttle = (fn, delay=500) => { |
| 34 | 34 | } |
| 35 | 35 | |
| 36 | 36 | /** |
| 37 | - * toast | |
| 37 | + * toast 提示 | |
| 38 | + * | |
| 39 | + * @param {String} title 标题 | |
| 40 | + * @param {Object} param 拓展参数 | |
| 41 | + * @param {Integer} param.duration 持续时间 | |
| 42 | + * @param {Boolean} param.mask 是否遮罩 | |
| 43 | + * @param {Boolean} param.icon 图标 | |
| 38 | 44 | */ |
| 39 | 45 | export const msg = (title = '', param={}) => { |
| 40 | - if(!title) return; | |
| 46 | + if (!title) { | |
| 47 | + return; | |
| 48 | + } | |
| 41 | 49 | uni.showToast({ |
| 42 | 50 | title, |
| 43 | 51 | duration: param.duration || 1500, |
| 44 | 52 | mask: param.mask || false, |
| 45 | - icon: param.icon || 'none' | |
| 53 | + icon: param.icon || 'none' // TODO 芋艿:是否要区分下 error 的提示,或者专门的封装 | |
| 46 | 54 | }); |
| 55 | +} | |
| 56 | + | |
| 57 | +/** | |
| 58 | + * 检查登录 | |
| 59 | + * | |
| 60 | + * @param {Boolean} options.nav 如果未登陆,是否跳转到登陆页。默认为 true | |
| 61 | + * @return {Boolean} 是否登陆 | |
| 62 | + */ | |
| 63 | +export const isLogin = (options = {}) => { | |
| 64 | + const token = this.getAuthToken(); | |
| 65 | + if (token) { | |
| 66 | + return true; | |
| 67 | + } | |
| 68 | + // 若 nav 不为 false,则进行跳转登陆页 | |
| 69 | + if (options.nav !== false) { | |
| 70 | + uni.navigateTo({ | |
| 71 | + url: '/pages/auth/login' | |
| 72 | + }) | |
| 73 | + } | |
| 74 | + return false; | |
| 75 | +} | |
| 76 | + | |
| 77 | +/** | |
| 78 | + * 获得认证 Token | |
| 79 | + * | |
| 80 | + * @return 认证 Token | |
| 81 | + */ | |
| 82 | +export const getAuthToken = () => { | |
| 83 | + return uni.getStorageSync('token'); | |
| 84 | +} | |
| 85 | + | |
| 86 | +/** | |
| 87 | + * 校验参数 | |
| 88 | + * | |
| 89 | + * @param {String} 字符串 | |
| 90 | + * @param {String} 数据的类型。例如说 mobile 手机号、tel 座机 TODO 芋艿:是否组件里解决 | |
| 91 | + */ | |
| 92 | +export const checkStr = (str, type) => { | |
| 93 | + switch (type) { | |
| 94 | + case 'mobile': //手机号码 | |
| 95 | + return /^1[3|4|5|6|7|8|9][0-9]{9}$/.test(str); | |
| 96 | + case 'tel': //座机 | |
| 97 | + return /^(0\d{2,3}-\d{7,8})(-\d{1,4})?$/.test(str); | |
| 98 | + case 'card': //身份证 | |
| 99 | + return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(str); | |
| 100 | + case 'mobileCode': //6位数字验证码 | |
| 101 | + return /^[0-9]{6}$/.test(str) | |
| 102 | + case 'pwd': //密码以字母开头,长度在6~18之间,只能包含字母、数字和下划线 | |
| 103 | + return /^([a-zA-Z0-9_]){6,18}$/.test(str) | |
| 104 | + case 'payPwd': //支付密码 6位纯数字 | |
| 105 | + return /^[0-9]{6}$/.test(str) | |
| 106 | + case 'postal': //邮政编码 | |
| 107 | + return /[1-9]\d{5}(?!\d)/.test(str); | |
| 108 | + case 'QQ': //QQ号 | |
| 109 | + return /^[1-9][0-9]{4,9}$/.test(str); | |
| 110 | + case 'email': //邮箱 | |
| 111 | + return /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(str); | |
| 112 | + case 'money': //金额(小数点2位) | |
| 113 | + return /^\d*(?:\.\d{0,2})?$/.test(str); | |
| 114 | + case 'URL': //网址 | |
| 115 | + return /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/.test(str) | |
| 116 | + case 'IP': //IP | |
| 117 | + return /((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))/.test(str); | |
| 118 | + case 'date': //日期时间 | |
| 119 | + return /^(\d{4})\-(\d{2})\-(\d{2}) (\d{2})(?:\:\d{2}|:(\d{2}):(\d{2}))$/.test(str) || /^(\d{4})\-(\d{2})\-(\d{2})$/ | |
| 120 | + .test(str) | |
| 121 | + case 'number': //数字 | |
| 122 | + return /^[0-9]$/.test(str); | |
| 123 | + case 'english': //英文 | |
| 124 | + return /^[a-zA-Z]+$/.test(str); | |
| 125 | + case 'chinese': //中文 | |
| 126 | + return /^[\\u4E00-\\u9FA5]+$/.test(str); | |
| 127 | + case 'lower': //小写 | |
| 128 | + return /^[a-z]+$/.test(str); | |
| 129 | + case 'upper': //大写 | |
| 130 | + return /^[A-Z]+$/.test(str); | |
| 131 | + case 'HTML': //HTML标记 | |
| 132 | + return /<("[^"]*"|'[^']*'|[^'">])*>/.test(str); | |
| 133 | + default: | |
| 134 | + return true; | |
| 135 | + } | |
| 47 | 136 | } |
| 48 | 137 | \ No newline at end of file | ... | ... |
yudao-vue-ui/pages/auth/login.vue
| ... | ... | @@ -42,7 +42,7 @@ |
| 42 | 42 | placeholder="请输入密码" placeholder-style="color: #909399"/> |
| 43 | 43 | </view> |
| 44 | 44 | </view> |
| 45 | - <mix-button ref="confirmBtn" text="立即登录" marginTop="60rpx" @onConfirm="login"></mix-button> | |
| 45 | + <mix-button ref="confirmBtn" text="立即登录" marginTop="60rpx" @onConfirm="mobileLogin"></mix-button> | |
| 46 | 46 | <!-- 切换登陆 --> |
| 47 | 47 | <view class="login-type" v-if="loginType == 'code'" @click="setLoginType('password')">账号密码登录</view> |
| 48 | 48 | <view class="login-type" v-else @click="setLoginType('code')">免密登录</view> |
| ... | ... | @@ -78,9 +78,11 @@ |
| 78 | 78 | </template> |
| 79 | 79 | |
| 80 | 80 | <script> |
| 81 | - import {checkStr} from '@/common/js/util' | |
| 81 | + import { checkStr } from '@/common/js/util' | |
| 82 | + import { login, smsLogin } from '@/api/system/auth.js' | |
| 82 | 83 | import loginMpWx from './mixin/login-mp-wx.js' |
| 83 | 84 | import loginAppWx from './mixin/login-app-wx.js' |
| 85 | + | |
| 84 | 86 | export default{ |
| 85 | 87 | mixins: [loginMpWx, loginAppWx], |
| 86 | 88 | data(){ |
| ... | ... | @@ -95,17 +97,10 @@ |
| 95 | 97 | onLoad() { |
| 96 | 98 | }, |
| 97 | 99 | methods: { |
| 98 | - loginSuccessCallBack(data){ | |
| 99 | - this.$util.msg('登录成功'); | |
| 100 | - this.$store.commit('setToken', data); | |
| 101 | - setTimeout(()=>{ | |
| 102 | - uni.navigateBack(); | |
| 103 | - }, 1000) | |
| 104 | - }, | |
| 105 | 100 | // 手机号登录 |
| 106 | - async login(){ | |
| 107 | - // 参数校验 | |
| 108 | - if (!this.agreement){ | |
| 101 | + async mobileLogin() { | |
| 102 | + // 参数校验 TODO 芋艿:表单校验的支持 | |
| 103 | + if (!this.agreement) { | |
| 109 | 104 | this.$util.msg('请阅读并同意用户服务及隐私协议'); |
| 110 | 105 | this.$refs.confirmBtn.stop(); |
| 111 | 106 | return; |
| ... | ... | @@ -116,23 +111,37 @@ |
| 116 | 111 | this.$refs.confirmBtn.stop(); |
| 117 | 112 | return; |
| 118 | 113 | } |
| 119 | - if (!checkStr(code, 'mobileCode')) { | |
| 120 | - this.$util.msg('验证码错误'); | |
| 114 | + if (this.loginType === 'code' && !checkStr(code, 'mobileCode')) { | |
| 115 | + this.$util.msg('验证码格式错误'); | |
| 116 | + this.$refs.confirmBtn.stop(); | |
| 117 | + return; | |
| 118 | + } | |
| 119 | + if (this.loginType === 'password' && !checkStr(password, 'pwd')) { | |
| 120 | + this.$util.msg('密码格式错误'); | |
| 121 | 121 | this.$refs.confirmBtn.stop(); |
| 122 | 122 | return; |
| 123 | 123 | } |
| 124 | 124 | |
| 125 | 125 | // 执行登陆 |
| 126 | - const res = await this.$request('user', 'login', {mobile,code}); | |
| 127 | - this.$refs.confirmBtn.stop(); | |
| 128 | - | |
| 129 | - if (res.status === 1){ | |
| 130 | - this.loginSuccessCallBack(res.data); | |
| 131 | - } else{ | |
| 132 | - this.$util.msg(res.msg); | |
| 126 | + try { | |
| 127 | + const data = this.loginType === 'code' ? await smsLogin(mobile, code) | |
| 128 | + : await login(mobile, password); | |
| 129 | + // 登陆成功 | |
| 130 | + this.loginSuccessCallBack(data); | |
| 131 | + } finally { | |
| 132 | + this.$refs.confirmBtn.stop(); | |
| 133 | 133 | } |
| 134 | 134 | }, |
| 135 | - navBack(){ | |
| 135 | + // 登陆成功的处理逻辑 | |
| 136 | + loginSuccessCallBack(data){ | |
| 137 | + this.$util.msg('登录成功'); | |
| 138 | + this.$store.commit('setToken', data); | |
| 139 | + // TODO 芋艿:如果当前页是第一页,则无法返回。期望是能够回到首页 | |
| 140 | + setTimeout(()=>{ | |
| 141 | + uni.navigateBack(); | |
| 142 | + }, 1000) | |
| 143 | + }, | |
| 144 | + navBack() { | |
| 136 | 145 | uni.navigateBack(); |
| 137 | 146 | }, |
| 138 | 147 | setLoginType(loginType) { | ... | ... |
yudao-vue-ui/pages/tabbar/user.vue
yudao-vue-ui/store/index.js
| 1 | 1 | import Vue from 'vue' |
| 2 | 2 | import Vuex from 'vuex' |
| 3 | 3 | // import {request} from '@/common/js/request' |
| 4 | +import { getUserInfo } from '@/api/member/userProfile.js' | |
| 4 | 5 | |
| 5 | 6 | Vue.use(Vuex) |
| 6 | 7 | |
| ... | ... | @@ -10,7 +11,6 @@ const store = new Vuex.Store({ |
| 10 | 11 | token: '', // 用户身份 Token |
| 11 | 12 | userInfo: {}, // 用户基本信息 |
| 12 | 13 | timerIdent: false, // 全局 1s 定时器,只在全局开启一个,所有需要定时执行的任务监听该值即可,无需额外开启 TODO 芋艿:需要看看 |
| 13 | - orderCount: {}, // 订单数量 | |
| 14 | 14 | }, |
| 15 | 15 | getters: { |
| 16 | 16 | hasLogin(state){ |
| ... | ... | @@ -18,73 +18,45 @@ const store = new Vuex.Store({ |
| 18 | 18 | } |
| 19 | 19 | }, |
| 20 | 20 | mutations: { |
| 21 | - //更新state数据 | |
| 22 | - setStateAttr(state, param){ | |
| 23 | - if(param instanceof Array){ | |
| 21 | + // 更新 state 的通用方法 | |
| 22 | + setStateAttr(state, param) { | |
| 23 | + if (param instanceof Array) { | |
| 24 | 24 | for(let item of param){ |
| 25 | 25 | state[item.key] = item.val; |
| 26 | 26 | } |
| 27 | - }else{ | |
| 27 | + } else { | |
| 28 | 28 | state[param.key] = param.val; |
| 29 | 29 | } |
| 30 | 30 | }, |
| 31 | - //更新token | |
| 32 | - setToken(state, data){ | |
| 33 | - const {token, tokenExpired} = data; | |
| 31 | + // 更新token | |
| 32 | + setToken(state, data) { | |
| 33 | + // 设置 Token | |
| 34 | + const { token } = data; | |
| 34 | 35 | state.token = token; |
| 35 | - uni.setStorageSync('uniIdToken', token); | |
| 36 | - uni.setStorageSync('tokenExpired', tokenExpired); | |
| 37 | - this.dispatch('getUserInfo'); //更新用户信息 | |
| 38 | - this.dispatch('getCartCount');//更新购物车数量 | |
| 39 | - uni.$emit('refreshCart');//刷新购物车 | |
| 40 | - this.dispatch('getOrderCount'); //更新订单数量 | |
| 36 | + uni.setStorageSync('token', token); | |
| 37 | + | |
| 38 | + // 加载用户信息 | |
| 39 | + this.dispatch('obtainUserInfo'); | |
| 41 | 40 | }, |
| 42 | 41 | // 退出登录 |
| 43 | 42 | logout(state) { |
| 43 | + // 清空 Token | |
| 44 | 44 | state.token = ''; |
| 45 | - uni.removeStorageSync('uniIdToken'); | |
| 46 | - this.dispatch('getCartCount');//更新购物车数量 | |
| 47 | - uni.$emit('refreshCart');//刷新购物车 | |
| 48 | - this.dispatch('getOrderCount'); //更新订单数量 | |
| 45 | + uni.removeStorageSync('token'); | |
| 46 | + // 清空用户信息 TODO 芋艿:这里 setTimeout 的原因是,上面可能还有一些 request 请求。后续得优化下 | |
| 49 | 47 | setTimeout(()=>{ |
| 50 | 48 | state.userInfo = {}; |
| 51 | 49 | }, 1100) |
| 52 | 50 | }, |
| 53 | 51 | }, |
| 54 | 52 | actions: { |
| 55 | - //更新用户信息 | |
| 56 | - async getUserInfo({state, commit}){ | |
| 57 | - const res = await request('user', 'get', {}, { | |
| 58 | - checkAuthInvalid: false | |
| 59 | - }); | |
| 60 | - if(res.status === 1){ | |
| 61 | - const userInfo = res.data; | |
| 62 | - commit('setStateAttr', { | |
| 63 | - key: 'userInfo', | |
| 64 | - val: userInfo | |
| 65 | - }) | |
| 66 | - } | |
| 67 | - }, | |
| 68 | - //更新用户订单数量 | |
| 69 | - async getOrderCount({state, commit}){ | |
| 70 | - let data = { | |
| 71 | - c0: 0, | |
| 72 | - c1: 0, | |
| 73 | - c2: 0, | |
| 74 | - c3: 0 | |
| 75 | - } | |
| 76 | - if(state.token){ | |
| 77 | - try { | |
| 78 | - const res = await request('order', 'getOrderCount'); | |
| 79 | - data = res; | |
| 80 | - }catch (err){ | |
| 81 | - console.error('更新用户订单数量 => ', err); | |
| 82 | - } | |
| 83 | - } | |
| 53 | + // 获得用户基本信息 | |
| 54 | + async obtainUserInfo({state, commit}) { | |
| 55 | + const data = await getUserInfo(); | |
| 84 | 56 | commit('setStateAttr', { |
| 85 | - key: 'orderCount', | |
| 57 | + key: 'userInfo', | |
| 86 | 58 | val: data |
| 87 | - }) | |
| 59 | + }); | |
| 88 | 60 | } |
| 89 | 61 | } |
| 90 | 62 | }) | ... | ... |