From efe455736c158e73bf0c6514c31bec5d83fe843b Mon Sep 17 00:00:00 2001 From: Charles7c Date: Thu, 19 Oct 2023 23:44:56 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=B8=AA=E4=BA=BA=E4=B8=AD=E5=BF=83-?= =?UTF-8?q?=E5=AE=89=E5=85=A8=E8=AE=BE=E7=BD=AE=EF=BC=8C=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E7=BB=91=E5=AE=9A=E3=80=81=E8=A7=A3=E7=BB=91=E4=B8=89=E6=96=B9?= =?UTF-8?q?=E8=B4=A6=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/enums/SocialSourceEnum.java | 39 +++++ .../system/model/vo/UserSocialBindVO.java | 48 +++++ .../system/service/UserSocialService.java | 33 ++++ .../service/impl/UserSocialServiceImpl.java | 38 ++++ .../src/api/system/user-center.ts | 19 +- continew-admin-ui/src/views/login/index.vue | 2 +- .../src/views/login/locale/en-US.ts | 1 + .../src/views/login/locale/zh-CN.ts | 1 + .../src/views/login/social/index.vue | 41 ++++- .../center/components/security-settings.vue | 14 +- .../security-settings/bind-social.vue | 165 ++++++++++++++++++ .../security-settings/update-email.vue | 17 +- .../security-settings/update-phone.vue | 19 +- .../security-settings/update-pwd.vue | 17 +- .../src/views/system/user/center/index.vue | 18 +- .../views/system/user/center/locale/en-US.ts | 34 ++-- .../views/system/user/center/locale/zh-CN.ts | 29 +-- .../controller/auth/SocialAuthController.java | 6 +- .../system/UserCenterController.java | 55 +++++- 19 files changed, 520 insertions(+), 76 deletions(-) create mode 100644 continew-admin-common/src/main/java/top/charles7c/cnadmin/common/enums/SocialSourceEnum.java create mode 100644 continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/UserSocialBindVO.java create mode 100644 continew-admin-ui/src/views/system/user/center/components/security-settings/bind-social.vue diff --git a/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/enums/SocialSourceEnum.java b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/enums/SocialSourceEnum.java new file mode 100644 index 00000000..7269fcd9 --- /dev/null +++ b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/enums/SocialSourceEnum.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.charles7c.cnadmin.common.enums; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * 第三方账号平台枚举 + * + * @author Charles7c + * @since 2023/10/19 21:22 + */ +@Getter +@RequiredArgsConstructor +public enum SocialSourceEnum { + + /** 码云 */ + GITEE("码云"), + + /** GitHub */ + GITHUB("GitHub"),; + + private final String description; +} diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/UserSocialBindVO.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/UserSocialBindVO.java new file mode 100644 index 00000000..679bcb58 --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/UserSocialBindVO.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.charles7c.cnadmin.system.model.vo; + +import java.io.Serializable; + +import lombok.Data; + +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * 第三方账号绑定信息 + * + * @author Charles7c + * @since 2023/10/19 21:29 + */ +@Data +@Schema(description = "第三方账号绑定信息") +public class UserSocialBindVO implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 来源 + */ + @Schema(description = "来源", example = "GITEE") + private String source; + + /** + * 描述 + */ + @Schema(description = "描述", example = "码云") + private String description; +} diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/UserSocialService.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/UserSocialService.java index b59e3162..e0fd08a0 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/UserSocialService.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/UserSocialService.java @@ -16,8 +16,12 @@ package top.charles7c.cnadmin.system.service; +import java.util.List; + import top.charles7c.cnadmin.system.model.entity.UserSocialDO; +import me.zhyd.oauth.model.AuthUser; + /** * 用户社会化关联业务接口 * @@ -44,4 +48,33 @@ public interface UserSocialService { * 用户社会化关联信息 */ void saveOrUpdate(UserSocialDO userSocial); + + /** + * 根据用户 ID 查询 + * + * @param userId + * 用户 ID + * @return 用户社会化关联信息 + */ + List listByUserId(Long userId); + + /** + * 绑定 + * + * @param authUser + * 社交身份信息 + * @param userId + * 用户 ID + */ + void bind(AuthUser authUser, Long userId); + + /** + * 根据来源和用户 ID 删除 + * + * @param source + * 来源 + * @param userId + * 用户 ID + */ + void deleteBySourceAndUserId(String source, Long userId); } \ No newline at end of file diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/UserSocialServiceImpl.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/UserSocialServiceImpl.java index 7b614fb9..d0380c3c 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/UserSocialServiceImpl.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/UserSocialServiceImpl.java @@ -16,15 +16,25 @@ package top.charles7c.cnadmin.system.service.impl; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import cn.hutool.json.JSONUtil; + +import top.charles7c.cnadmin.common.util.validate.CheckUtils; import top.charles7c.cnadmin.system.mapper.UserSocialMapper; import top.charles7c.cnadmin.system.model.entity.UserSocialDO; import top.charles7c.cnadmin.system.service.UserSocialService; +import me.zhyd.oauth.model.AuthUser; + /** * 用户社会化关联业务实现 * @@ -54,4 +64,32 @@ public class UserSocialServiceImpl implements UserSocialService { .update(); } } + + @Override + public List listByUserId(Long userId) { + return baseMapper.lambdaQuery().eq(UserSocialDO::getUserId, userId).list(); + } + + @Override + public void bind(AuthUser authUser, Long userId) { + String source = authUser.getSource(); + String openId = authUser.getUuid(); + List userSocialList = this.listByUserId(userId); + Set boundSocialSet = userSocialList.stream().map(UserSocialDO::getSource).collect(Collectors.toSet()); + CheckUtils.throwIf(boundSocialSet.contains(source), "您已经绑定过了 [{}] 平台,请先解绑"); + UserSocialDO userSocial = this.getBySourceAndOpenId(source, openId); + CheckUtils.throwIfNotNull(userSocial, "[{}] 平台账号 [{}] 已被其他用户绑定", source, authUser.getUsername()); + userSocial = new UserSocialDO(); + userSocial.setUserId(userId); + userSocial.setSource(source); + userSocial.setOpenId(openId); + userSocial.setMetaJson(JSONUtil.toJsonStr(authUser)); + userSocial.setLastLoginTime(LocalDateTime.now()); + baseMapper.insert(userSocial); + } + + @Override + public void deleteBySourceAndUserId(String source, Long userId) { + baseMapper.lambdaUpdate().eq(UserSocialDO::getSource, source).eq(UserSocialDO::getUserId, userId).remove(); + } } diff --git a/continew-admin-ui/src/api/system/user-center.ts b/continew-admin-ui/src/api/system/user-center.ts index ac55f70e..e96e8398 100644 --- a/continew-admin-ui/src/api/system/user-center.ts +++ b/continew-admin-ui/src/api/system/user-center.ts @@ -1,6 +1,6 @@ import axios from 'axios'; -const BASE_URL = '/system/user/center'; +const BASE_URL = '/system/user'; export interface BasicInfoModel { username: string; @@ -43,3 +43,20 @@ export interface UpdateEmailReq { export function updateEmail(req: UpdateEmailReq) { return axios.patch(`${BASE_URL}/email`, req); } + +export interface UserSocialBindRecord { + source: string; + description: string; +} + +export function listSocial() { + return axios.get(`${BASE_URL}/social`); +} + +export function bindSocial(source: string, req: any) { + return axios.post(`${BASE_URL}/social/${source}`, req); +} + +export function unbindSocial(source: string) { + return axios.delete(`${BASE_URL}/social/${source}`); +} diff --git a/continew-admin-ui/src/views/login/index.vue b/continew-admin-ui/src/views/login/index.vue index dc49cece..4d6c2f7d 100644 --- a/continew-admin-ui/src/views/login/index.vue +++ b/continew-admin-ui/src/views/login/index.vue @@ -34,7 +34,7 @@ - + - +
@@ -9,6 +9,8 @@ import { useRoute, useRouter } from 'vue-router'; import { useUserStore } from '@/store'; import { useI18n } from 'vue-i18n'; + import { isLogin } from '@/utils/auth'; + import { bindSocial } from '@/api/system/user-center'; const { proxy } = getCurrentInstance() as any; const { t } = useI18n(); @@ -45,7 +47,42 @@ loading.value = false; }); }; - handleSocialLogin(); + + /** + * 绑定第三方账号 + */ + const handleBindSocial = () => { + if (loading.value) return; + loading.value = true; + const { redirect, ...othersQuery } = router.currentRoute.value.query; + bindSocial(source, othersQuery) + .then((res) => { + router.push({ + name: 'UserCenter', + query: { + tab: 'security-setting', + }, + }); + proxy.$message.success(res.msg); + }) + .catch(() => { + router.push({ + name: 'UserCenter', + query: { + tab: 'security-setting', + }, + }); + }) + .finally(() => { + loading.value = false; + }); + }; + + if (isLogin()) { + handleBindSocial(); + } else { + handleSocialLogin(); + } diff --git a/continew-admin-ui/src/views/system/user/center/components/security-settings/update-email.vue b/continew-admin-ui/src/views/system/user/center/components/security-settings/update-email.vue index 79eba158..d5c04ad1 100644 --- a/continew-admin-ui/src/views/system/user/center/components/security-settings/update-email.vue +++ b/continew-admin-ui/src/views/system/user/center/components/security-settings/update-email.vue @@ -2,24 +2,19 @@