需求文档:https://www.yuque.com/xiumubai/fe/yk9lle
这一期我们就正式进入了页面开发的工作了,首先要解决的就是登陆页面
具体样式参考代码,就不列举了

登陆逻辑判断

当用户进入user页面的时候,在onShow中判断token是否为空,为空则跳转到登陆页面,否则就获取用户基础信息

  1. onShow() {
  2. if (!this.$store.state.token) {
  3. uni.navigateTo({
  4. url: "/pages/login/index",
  5. });
  6. }
  7. this.user = this.$store.state.user;
  8. },

:::info TIps:这里解释一下为什么要用onShow而不是onLoad,因为当登陆完成以后使用uni.naviagateBack()返回user页面的,是需要刷新用户信息的,而onLoad不会重新执行。 :::

登陆逻辑

下面是关于登陆的逻辑,简单来说就是先拿到code去换token,拿到token以后,去请求用户信息接口,有两种情况,第一种,服务端没有没有用户信息,就需要从getUserPrifile()中获取用户基础信息,传给后端,让后端保存。第二种,服务端有用户信息,直接返回,登陆成功。
06.登陆 - 图1

添加接口

接口文档参考:https://www.yuque.com/xiumubai/fe/yf8tf3

  1. class User extends Service {
  2. **
  3. * @description: 小程序登陆接口
  4. * @param {*} options
  5. * @return {*}
  6. */
  7. login(options = {}) {
  8. console.log(123);
  9. options.url = `/api/ucenter/webChat/callback?code=${options.code}`;
  10. return this.get(options);
  11. }
  12. /**
  13. * @description: 获取用户信息
  14. * @param {*} options
  15. * @return {*}
  16. */
  17. getLoginInfo(options = {}) {
  18. options.url = `/api/ucenter/member/auth/getLoginInfo`;
  19. return this.get(options);
  20. }
  21. /**
  22. * @description: 更新用户信息
  23. * @param {*} options
  24. * @return {*}
  25. */
  26. updateMember(options = {}) {
  27. options.url = `/api/ucenter/member/auth/updateMember`;
  28. return this.post(options);
  29. }
  30. }
  31. const userService = new User();
  32. export default userService;

调用微信登陆

先获取用户授权,就可以拿到用户基础信息(avatar,nickName),然后调用uni.login()获取code

  1. /**
  2. * @description: 调用微信登陆
  3. * @returns {*}
  4. */
  5. mpWeixinLogin() {
  6. const _this = this;
  7. try {
  8. // 先调用授权
  9. uni.getUserProfile({
  10. lang: "zh_CN",
  11. desc: "用于完善会员资料",
  12. success: async (res) => {
  13. console.log("userprofile", res);
  14. // 保存userinifo信息
  15. _this.userInfo = res.userInfo;
  16. // 授权成功
  17. uni.login({
  18. success(data) {
  19. // 获取到code
  20. const code = data.code;
  21. console.log("code", code);
  22. if (code) _this.login(code);
  23. },
  24. });
  25. },
  26. file: (err) => {
  27. console.log(err);
  28. },
  29. });
  30. } catch (e) {
  31. console.log(e);
  32. }
  33. },

获取token

拿到code后,请求login接口,返回token,存储到store当中

  1. /**
  2. * @description: 请求登陆
  3. * @param {*} code
  4. * @returns {*}
  5. */
  6. async login(code) {
  7. try {
  8. const res = await userService.login({
  9. code,
  10. });
  11. console.log("token", res.data.token);
  12. this.$store.dispatch("setToken", res.data.token);
  13. this.getUserInfo();
  14. } catch (e) {
  15. console.log(e);
  16. }
  17. },

获取用户信息

使用token去请求getLoginInfo()接口,拿到用户基础信息,如果用户名非空,登陆成功,返回上一页。反之更新用户信息。

  1. async getUserInfo() {
  2. try {
  3. const res = await userService.getLoginInfo();
  4. console.log("userLogininfo", res);
  5. if (res.data.item) {
  6. this.$store.dispatch("setUser", {
  7. ...res.data.item,
  8. });
  9. // 需要更新用户信息
  10. if (!res.data.item.nickname) {
  11. this.updateUserInfo();
  12. } else {
  13. this.jump();
  14. }
  15. }
  16. } catch (e) {
  17. console.log(e);
  18. }
  19. },

更新用户信息

如果服务端没有用户信息,请求updateMember()接口,更新用户信息,这里需要把用户的avatarnickname传给服务端。

  1. async updateUserInfo() {
  2. try {
  3. const res = await userService.updateMember({
  4. data: {
  5. avatar: this.userInfo.avatarUrl,
  6. nickname: this.userInfo.nickName,
  7. },
  8. });
  9. console.log("updateres", res);
  10. if (res.code == 200) {
  11. // 登陆成功,保存个人信息,返回个人页面
  12. this.$store.dispatch("setUser", {
  13. avatar: this.userInfo.avatarUrl,
  14. nickname: this.userInfo.nickName,
  15. });
  16. this.jump();
  17. }
  18. } catch (e) {
  19. console.log(e);
  20. }
  21. },

登陆成功

  1. jump() {
  2. uni.showToast({
  3. title: "登陆成功",
  4. icon: "success",
  5. success: () => {
  6. uni.navigateBack();
  7. },
  8. });
  9. },

登陆成功以后,直接跳转到上一页 :::info Tips: 这里使用naviagateBackI()是因为有可能用户不是从user页面跳跳转过来的,也有可能是从别的页面跳转过来的,所以我们需要登陆成功以后返回原来的页面。TODO:判断当前操作是否需要登陆!!! :::