Просмотр исходного кода

Update 优化登录,添加解绑微信号功能

Yue 2 лет назад
Родитель
Сommit
ec393ec4ab

+ 2 - 0
SERVER/YanZhongXYH/xyh-common/src/main/java/cn/xyh/common/core/domain/model/LoginBody.java

@@ -36,5 +36,7 @@ public class LoginBody {
      * 唯一标识
      */
     private String uuid;
+    
+    private String openid;
 
 }

+ 1 - 1
SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/amActivity/service/impl/AmAlumnusServiceImpl.java

@@ -238,7 +238,7 @@ public class AmAlumnusServiceImpl implements IAmAlumnusService {
         if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
             throw new ServiceException("修改校友'" + user.getUserName() + "'失败,邮箱账号已存在");
         }
-        boolean flag = userService.updateUser(user) > 0;
+        boolean flag = userService.updateUserOnly(user) > 0;
         if (!flag) {
             return flag;
         }

+ 11 - 1
SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/system/controller/system/SysLoginController.java

@@ -52,7 +52,7 @@ public class SysLoginController {
         Map<String, Object> ajax = new HashMap<>();
         // 生成令牌
         String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
-                loginBody.getUuid());
+                loginBody.getUuid(), loginBody.getOpenid());
         ajax.put(Constants.TOKEN, token);
         return R.ok(ajax);
     }
@@ -125,6 +125,16 @@ public class SysLoginController {
         return R.ok("退出成功");
     }
 
+    /**
+     * 退出登录
+     */
+    @SaIgnore
+    @PostMapping("/logoutWechat")
+    public R<Void> logoutWechat() {
+        loginService.logoutWechat();
+        return R.ok("退出成功");
+    }
+
     /**
      * 获取用户信息
      *

+ 4 - 0
SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/system/service/ISysUserService.java

@@ -142,6 +142,10 @@ public interface ISysUserService {
      */
     int updateUser(SysUser user);
 
+    int updateUserOnly(SysUser user);
+
+    int updateUserOpenId(SysUser user);
+
     /**
      * 用户授权角色
      *

+ 30 - 3
SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/system/service/SysLoginService.java

@@ -44,6 +44,7 @@ import org.springframework.stereotype.Service;
 
 import java.time.Duration;
 import java.util.List;
+import java.util.Objects;
 import java.util.function.Supplier;
 
 /**
@@ -78,7 +79,7 @@ public class SysLoginService {
      * @param uuid     唯一标识
      * @return 结果
      */
-    public String login(String username, String password, String code, String uuid) {
+    public String login(String username, String password, String code, String uuid, String openId) {
         boolean captchaEnabled = configService.selectCaptchaEnabled();
         // 验证码开关
         if (captchaEnabled) {
@@ -86,11 +87,24 @@ public class SysLoginService {
         }
         // 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可
         SysUser user = loadUserByPeu(username);
-        checkLogin(LoginType.PASSWORD, username, () -> !BCrypt.checkpw(password, user.getPassword()));
+        checkLogin(LoginType.PASSWORD, user.getUserName(), () -> !BCrypt.checkpw(password, user.getPassword()));
+        if (StringUtils.isNotEmpty(openId) && (StringUtils.isEmpty(user.getOpenId()) || !user.getOpenId().equals(openId))) {
+            SysUser user2 = userService.selectUserByOpenid(openId);
+            if (user2 != null && !Objects.equals(user2.getUserId(), user.getUserId())) {
+                user2.setOpenId(null);
+                userService.updateUserOpenId(user2);
+            }
+            user.setOpenId(openId);
+            userService.updateUserOpenId(user);
+        }
         // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
         LoginUser loginUser = buildLoginUser(user);
         // 生成token
-        LoginHelper.loginByDevice(loginUser, DeviceType.PC);
+        if (StringUtils.isEmpty(openId)) {
+            LoginHelper.loginByDevice(loginUser, DeviceType.PC);
+        } else {
+            LoginHelper.loginByDevice(loginUser, DeviceType.XCX);
+        }
 
         recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
         recordLoginInfo(user.getUserId(), username);
@@ -405,4 +419,17 @@ public class SysLoginService {
         // 登录成功 清空错误次数
         RedisUtils.deleteObject(errorKey);
     }
+
+    /**
+     * 解绑微信
+     */
+    public void logoutWechat() {
+        Long userId = LoginHelper.getUserId();
+        SysUser user = userService.selectUserById(userId);
+        if (user != null) {
+            user.setOpenId(null);
+            userService.updateUserOpenId(user);
+        }
+        logout();
+    }
 }

+ 16 - 0
SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/system/service/impl/SysUserServiceImpl.java

@@ -343,6 +343,22 @@ public class SysUserServiceImpl implements ISysUserService, IUserService {
         return baseMapper.updateById(user);
     }
 
+    @Caching(evict = {
+            @CacheEvict(cacheNames = CacheNames.SYS_USER_NAME, key = "#user.userName")
+            , @CacheEvict(cacheNames = CacheNames.SYS_USER_NAME, key = "#user.userId")
+    })
+    @Override
+    public int updateUserOnly(SysUser user) {
+        return baseMapper.updateById(user);
+    }
+
+    @Override
+    public int updateUserOpenId(SysUser user) {
+        return baseMapper.update(null, new LambdaUpdateWrapper<SysUser>()
+                .set(SysUser::getOpenId, user.getOpenId())
+                .eq(SysUser::getUserId, user.getUserId()));
+    }
+
 
     /**
      * 用户授权角色

+ 9 - 1
UI/XYH.APP/src/api/_login.ts

@@ -9,10 +9,11 @@ class loginApi {
     })
   }
 
-  login = (username: string, password: string, code: string, uuid: string) => {
+  login = (username: string, password: string, openid: string, code: string, uuid: string) => {
     const data = {
       username,
       password,
+      openid,
       code,
       uuid,
     }
@@ -40,6 +41,13 @@ class loginApi {
       successAlert: false,
     })
   }
+  logoutWechat = () => {
+    return Rs.post({
+      url: "/logoutWechat",
+      method: "post",
+      successAlert: false,
+    })
+  }
 
   register = (data: any) => {
     return Rs.post({

+ 14 - 10
UI/XYH.APP/src/pages-sub/activity/applyAudit.vue

@@ -101,20 +101,24 @@ function onGoAmDetail(item: any) {
   route.navigate("alumnusDetail", { id: item.amId })
 }
 function onConfirmApply(item: any) {
-  message.confirm(`确认通过【${item.name}】的报名吗?`).then(() => {
-    apis.amActivity.activityApi.auditApply(item.applyId, "1").then(() => {
-      message.msgSuccess("操作成功")
-      queryParams.value = Object.assign({}, queryParams.value)
-    })
+  message.confirm(`确认通过【${item.name}】的报名吗?`).then((res: any) => {
+    if (res.confirm) {
+      apis.amActivity.activityApi.auditApply(item.applyId, "1").then(() => {
+        message.msgSuccess("操作成功")
+        queryParams.value = Object.assign({}, queryParams.value)
+      })
+    }
   })
 }
 
 function onRejectApply(item: any) {
-  message.confirm(`确认拒绝【${item.name}】的报名吗?`).then(() => {
-    apis.amActivity.activityApi.auditApply(item.applyId, "2").then(() => {
-      message.msgSuccess("操作成功")
-      queryParams.value = Object.assign({}, queryParams.value)
-    })
+  message.confirm(`确认拒绝【${item.name}】的报名吗?`).then((res: any) => {
+    if (res.confirm) {
+      apis.amActivity.activityApi.auditApply(item.applyId, "2").then(() => {
+        message.msgSuccess("操作成功")
+        queryParams.value = Object.assign({}, queryParams.value)
+      })
+    }
   })
 }
 const costForm = ref<any>({})

+ 16 - 12
UI/XYH.APP/src/pages-sub/alumnus/detail.vue

@@ -205,22 +205,26 @@ const resources = computed(() => {
 })
 
 function onFriend() {
-  message.confirm(`确定申请加[ ${am.value.name} ]为好友吗?`).then(() => {
-    apis.amActivity.friendApi
-      .addFriends({ amId: amId.value, friendId: appStore.authStore.getUser().userId })
-      .then(() => {
-        loadData()
-        message.msgSuccess("申请已发送")
-      })
+  message.confirm(`确定申请加[ ${am.value.name} ]为好友吗?`).then((res: any) => {
+    if (res.confirm) {
+      apis.amActivity.friendApi
+        .addFriends({ amId: amId.value, friendId: appStore.authStore.getUser().userId })
+        .then(() => {
+          loadData()
+          message.msgSuccess("申请已发送")
+        })
+    }
   })
 }
 function onFollow(isFollow = true) {
   const text = isFollow ? "关注" : "取消关注"
-  message.confirm(`确定${text}[ ${am.value.name} ]吗?`).then(() => {
-    apis.amActivity.friendApi.follow(amId.value, isFollow ? "1" : "0").then(() => {
-      loadData()
-      message.msgSuccess(text + "成功")
-    })
+  message.confirm(`确定${text}[ ${am.value.name} ]吗?`).then((res: any) => {
+    if (res.confirm) {
+      apis.amActivity.friendApi.follow(amId.value, isFollow ? "1" : "0").then(() => {
+        loadData()
+        message.msgSuccess(text + "成功")
+      })
+    }
   })
 }
 

+ 8 - 4
UI/XYH.APP/src/pages-sub/mine/help.vue

@@ -7,15 +7,19 @@ const list = ref<Array<any>>([
     childList: [
       {
         title: "如何退出登录?",
-        content: "请点击[我的] - [应用设置] - [退出登录]即可退出登录",
+        content: "请点击[我的] - [应用设置] - [退出登录] 即可退出登录",
+      },
+      {
+        title: "如何解绑微信号?",
+        content: "请点击[我的] - [应用设置] - [解绑微信] 即可解绑微信号",
       },
       {
         title: "如何修改用户头像?",
-        content: "请点击[我的] - [点击头像] - [选择头像] - [点击提交]即可更换用户头像",
+        content: "请点击[我的] - [点击头像] - [选择头像] - [点击提交] 即可更换用户头像",
       },
       {
         title: "如何修改登录密码?",
-        content: "请点击[我的] - [应用设置] - [修改密码]即可修改登录密码",
+        content: "请点击[我的] - [应用设置] - [修改密码] 即可修改登录密码",
       },
     ],
   },
@@ -28,7 +32,7 @@ function handleText(item: any) {
 
 <template>
   <view class="page-container">
-    <vb-cell-group v-for="(item, i) in list" :key="i" :title="item.title" :icon="question">
+    <vb-cell-group v-for="(item, i) in list" :key="i" :title="item.title" icon="question">
       <vb-cell
         v-for="(child, k) in item.childList"
         :key="k"

+ 13 - 1
UI/XYH.APP/src/pages-sub/mine/setting.vue

@@ -12,7 +12,16 @@ function handleLogout() {
   message.confirm("确定注销并退出系统吗?").then((res: any) => {
     if (res.confirm) {
       appStore.authStore.logout().then(() => {
-        route.reLaunch("login")
+        route.reLaunch("login", { loginType: "logout" })
+      })
+    }
+  })
+}
+function handleLogoutWechat() {
+  message.confirm("确定解绑微信号并退出系统吗?").then((res: any) => {
+    if (res.confirm) {
+      appStore.authStore.logoutWechat().then(() => {
+        route.reLaunch("login", { loginType: "logout" })
       })
     }
   })
@@ -29,5 +38,8 @@ function handleLogout() {
     <vb-cell-group>
       <vb-button @click="handleLogout" block>退出登录</vb-button>
     </vb-cell-group>
+    <vb-cell-group>
+      <vb-button @click="handleLogoutWechat" type="danger" block>解绑微信</vb-button>
+    </vb-cell-group>
   </view>
 </template>

+ 38 - 17
UI/XYH.APP/src/pages/account/login.vue

@@ -7,6 +7,9 @@ const codeUrl = ref("")
 const code = ref("")
 const captchaEnabled = ref(true)
 const register = ref(true)
+const ready = ref(false)
+const pageParams = route.getRouteParams("login")
+
 const loginForm = reactive({
   openid: "",
   // username: "admin",
@@ -39,6 +42,14 @@ function getCode() {
   })
 }
 function handleLogin() {
+  if (!loginForm.openid) {
+    message.confirm("微信需要重新授权").then((res: any) => {
+      if (res.confirm) {
+        handleWechatLogin()
+      }
+    })
+    return
+  }
   if (loginForm.username === "") {
     message.msgError("请输入您的账号")
   } else if (loginForm.password === "") {
@@ -63,25 +74,11 @@ function handleUserRegister() {
 function handleForgetPwd() {
   route.navigate("forgetPwd")
 }
-// function handleSysUserLogin() {
-//   route.redirect("systemLogin")
-// }
-// function handleUserAgreement() {
-//   let site = config.appInfo.agreements[0]
-//   route.navigate("webview", { title: site.title, url: site.url })
-// }
-// function handlePrivacy() {
-//   let site = config.appInfo.agreements[1]
-//   route.navigate("webview", { title: site.title, url: site.url })
-// }
 
-getCode()
-loginForm.openid = appStore.authStore.getOpenId()
-
-onLoad(() => {
+function handleWechatLogin() {
   appStore.authStore
     .xcxLogin()
-    .then((res: boolean) => {
+    .then((res: any) => {
       if (res) {
         store.getInfo().then(() => {
           route.reLaunch("index")
@@ -89,13 +86,37 @@ onLoad(() => {
       } else {
         getCode()
         loginForm.openid = appStore.authStore.getOpenId()
+        ready.value = true
         //message.msgSuccess("获取到openid: " + loginForm.openid)
       }
     })
     .catch((err: any) => {
-      message.error(err)
+      message.msgError(err)
       getCode()
     })
+}
+// function handleSysUserLogin() {
+//   route.redirect("systemLogin")
+// }
+// function handleUserAgreement() {
+//   let site = config.appInfo.agreements[0]
+//   route.navigate("webview", { title: site.title, url: site.url })
+// }
+// function handlePrivacy() {
+//   let site = config.appInfo.agreements[1]
+//   route.navigate("webview", { title: site.title, url: site.url })
+// }
+
+getCode()
+loginForm.openid = appStore.authStore.getOpenId()
+
+onLoad(() => {
+  if (pageParams && pageParams.loginType == "logout") {
+    ready.value = true
+    console.log("退出登录", loginForm)
+    return
+  }
+  handleWechatLogin()
 })
 </script>
 <template>

+ 1 - 1
UI/XYH.APP/src/pages/account/register.vue

@@ -122,7 +122,7 @@ getCode()
           </uni-easyinput>
         </uni-forms-item>
       </vb-cell-group>
-      <vb-button round block @click="onSubmit">立即注册</vb-button>
+      <vb-button round block custom-class="mb-15" @click="onSubmit">立即注册</vb-button>
       <vb-button round block plain class="mt" @click="onBack">返回登录</vb-button>
     </uni-forms>
   </view>

+ 1 - 1
UI/XYH.APP/src/route/_pages.ts

@@ -40,7 +40,7 @@ const activitySub = {
 }
 const friendSub = {
   friendApply: "/pages-sub/friend/apply",
-  myFriend: "/pages-sub/friend/myFriend",
+  myFriend: "/pages-sub/friend/index",
 }
 
 const subPackage = {

+ 5 - 0
UI/XYH.APP/src/static/scss/vb-component/_cell.scss

@@ -57,11 +57,16 @@ view {
 
   &__title {
     font-weight: 600;
+    width: 100%;
     font-size: var(--vb-cell-group-title-font-size);
     line-height: var(--vb-cell-group-title-line-height);
     color: var(--vb-cell-group-title-color);
     padding: var(--vb-cell-group-title-padding);
     border-bottom: 1px solid var(--vb-cell-group-title-border-color);
+    display: inline-flex;
+    [class*="icon-"] {
+      margin-right: 5px;
+    }
   }
   .vb-cell {
     &__title {

+ 24 - 5
UI/XYH.APP/src/stores/_auth.ts

@@ -11,7 +11,7 @@ export const useAuthStore = defineStore("auth", () => {
 
   const isAuthenticated = ref(!!JwtService.getToken())
   //oR0I65C3nS6KlxF2UHcKOq5-oqmE
-  const openid = ref("oR0I65C3nS6KlxF2UHcKOq5-oqmE")
+  const openid = ref("")
   function setToken(authToken: string) {
     isAuthenticated.value = true
     user.value.token = authToken
@@ -56,6 +56,7 @@ export const useAuthStore = defineStore("auth", () => {
   function purgeAuth() {
     isAuthenticated.value = false
     user.value = {} as User
+    openid.value = ""
     localCache.setJSON(USER_KEY, user.value)
     appStore.amProfileStore.clean()
     JwtService.destroyToken()
@@ -70,8 +71,10 @@ export const useAuthStore = defineStore("auth", () => {
           console.log("openid", res)
           if (res.code === 200) {
             setToken(res.data.token)
-            getInfo()
-            appStore.amProfileStore.loadProfile()
+            getInfo().then(() => {
+              appStore.amProfileStore.loadProfile()
+            })
+
             resolve(true)
           } else if (res.code === 401) {
             openid.value = res.data.openid
@@ -87,13 +90,14 @@ export const useAuthStore = defineStore("auth", () => {
   function login(userInfo: any) {
     const username = userInfo.username.trim()
     const password = userInfo.password
+    const openid = userInfo.openid
     const code = userInfo.code
     const uuid = userInfo.uuid
     return new Promise((resolve, reject) => {
       apis.loginApi
-        .login(username, password, code, uuid)
+        .login(username, password, openid, code, uuid)
         .then((res: any) => {
-          console.log("---", res)
+          //console.log("---", res)
           setToken(res.token)
           resolve(true)
         })
@@ -132,6 +136,20 @@ export const useAuthStore = defineStore("auth", () => {
     })
   }
 
+  function logoutWechat() {
+    return new Promise((resolve, reject) => {
+      apis.loginApi
+        .logoutWechat()
+        .then(() => {
+          purgeAuth()
+          resolve(true)
+        })
+        .catch((error: any) => {
+          reject(error)
+        })
+    })
+  }
+
   function getUser() {
     return user.value
   }
@@ -150,6 +168,7 @@ export const useAuthStore = defineStore("auth", () => {
     xcxLogin,
     login,
     logout,
+    logoutWechat,
     getInfo,
     changeAvatar,
     getUser,