| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- <template>
- <div class="social-bindings">
- <div class="section-title">第三方账号</div>
- <div class="description">绑定 QQ 和微信后,无论使用哪种方式登录,都会进入当前 RunForge 账户。</div>
- <div class="account-list">
- <div v-for="item in accounts" :key="item.type" class="account-card">
- <div class="account-info">
- <a-avatar :size="44" v-if="getBinding(item.type)?.avatar" :imageUrl="getBinding(item.type)?.avatar"></a-avatar>
- <a-avatar :size="44" :style="{ backgroundColor: '#FE82A5' }" v-else>
- <icon-qq v-if="item.type === 'qq'" />
- <icon-wechat v-else />
- </a-avatar>
- <div>
- <div class="account-name">{{ item.name }}</div>
- <a-tag :color="isBound(item.type) ? 'green' : 'gray'" size="small">
- {{ isBound(item.type) ? '已绑定' : '未绑定' }}
- </a-tag>
- <div v-if="isBound(item.type)" class="account-nickname">
- 昵称:{{ getBinding(item.type)?.nickname || '未获取' }}
- </div>
- </div>
- </div>
- <a-button
- v-if="!isBound(item.type)"
- type="primary"
- :loading="state.loadingType === item.type"
- @click="bind(item.type)"
- >
- 立即绑定
- </a-button>
- <a-button
- v-else
- status="danger"
- :loading="state.loadingType === item.type"
- @click="unbind(item.type)"
- >
- 解绑
- </a-button>
- </div>
- </div>
- </div>
- </template>
- <script setup>
- import { onBeforeMount, reactive, ref } from 'vue'
- import { getLoginUrl } from '@/api/login'
- import { useUserStore } from '@/store/modules/user'
- import { isElectron } from '@/utils/electron'
- import { Message, Modal, Notification } from '@arco-design/web-vue'
- const userStore = useUserStore()
- const user = ref({})
- const state = reactive({
- loadingType: ''
- })
- const accounts = [
- { type: 'qq', name: 'QQ' },
- { type: 'wx', name: '微信' }
- ]
- const refreshUser = async () => {
- user.value = await userStore.getInfoFromServer()
- }
- const isBound = (type) => {
- return user.value?.boundTypes?.includes(type) ||
- user.value?.socialBindings?.some(item => item.type === type && item.bound)
- }
- const getBinding = (type) => {
- return user.value?.socialBindings?.find(item => item.type === type && item.bound) || null
- }
- const bind = async (type) => {
- try {
- state.loadingType = type
- const res = await getLoginUrl({
- type,
- mode: 'uniLogin',
- action: 'bind',
- from: '/user/setting'
- })
- if (!res || res.code !== 0)
- throw new Error(res?.msg ?? '获取绑定链接失败!')
- if (isElectron())
- window.electron.openNewWindow(res.data)
- else
- window.location.href = res.data
- } catch (error) {
- Notification.error({
- title: '获取绑定链接失败',
- content: error.message || '请稍后再试'
- })
- } finally {
- state.loadingType = ''
- }
- }
- const unbind = (type) => {
- const accountName = type === 'qq' ? 'QQ' : '微信'
- Modal.confirm({
- title: `解绑${accountName}`,
- content: `解绑后将无法继续通过该${accountName}账号登录当前账户,是否继续?`,
- onOk: async () => {
- try {
- state.loadingType = type
- await userStore.unbindSocial(type)
- await refreshUser()
- Message.success(`${accountName}解绑成功`)
- } catch (error) {
- Notification.error({
- title: `${accountName}解绑失败`,
- content: error.message || '请稍后再试'
- })
- } finally {
- state.loadingType = ''
- }
- }
- })
- }
- onBeforeMount(refreshUser)
- </script>
- <style scoped lang="less">
- .social-bindings {
- width: 560px;
- margin: 0 auto;
- }
- .description {
- margin-bottom: 18px;
- color: var(--color-text-3);
- }
- .account-list {
- display: flex;
- flex-direction: column;
- gap: 16px;
- }
- .account-card {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 18px;
- border: 1px solid var(--color-border-2);
- border-radius: 8px;
- }
- .account-info {
- display: flex;
- align-items: center;
- gap: 14px;
- }
- .account-name {
- margin-bottom: 6px;
- font-size: 16px;
- font-weight: 600;
- }
- .account-nickname {
- margin-top: 6px;
- color: var(--color-text-3);
- font-size: 12px;
- }
- </style>
|