UserSocial.vue
3.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
<template>
<el-table :data="socialUsers" :show-header="false">
<el-table-column fixed="left" title="序号" type="seq" width="60" />
<el-table-column align="left" label="社交平台" width="120">
<template #default="{ row }">
<img :src="row.img" alt="" class="h-5 align-middle" />
<p class="mr-5">{{ row.title }}</p>
</template>
</el-table-column>
<el-table-column align="center" label="操作">
<template #default="{ row }">
<template v-if="row.openid">
已绑定
<XTextButton class="mr-5" title="(解绑)" type="primary" @click="unbind(row)" />
</template>
<template v-else>
未绑定
<XTextButton class="mr-5" title="(绑定)" type="primary" @click="bind(row)" />
</template>
</template>
</el-table-column>
</el-table>
</template>
<script lang="ts" setup>
import { SystemUserSocialTypeEnum } from '@/utils/constants'
import { getBindSocialUserList } from '@/api/system/social/user'
import { socialAuthRedirect, socialBind, socialUnbind } from '@/api/system/user/socialUser'
defineOptions({ name: 'UserSocial' })
defineProps<{
activeName: string
}>()
const message = useMessage()
const socialUsers = ref<any[]>([])
const initSocial = async () => {
socialUsers.value = [] // 重置避免无限增长
// 获取已绑定的社交用户列表
const bindSocialUserList = await getBindSocialUserList()
// 检查该社交平台是否已绑定
for (const i in SystemUserSocialTypeEnum) {
const socialUser = { ...SystemUserSocialTypeEnum[i] }
socialUsers.value.push(socialUser)
if (bindSocialUserList && bindSocialUserList.length > 0) {
for (const bindUser of bindSocialUserList) {
if (socialUser.type === bindUser.type) {
socialUser.openid = bindUser.openid
break
}
}
}
}
}
const route = useRoute()
const emit = defineEmits<{
(e: 'update:activeName', v: string): void
}>()
const bindSocial = () => {
// 社交绑定
const type = getUrlValue('type')
const code = route.query.code
const state = route.query.state
if (!code) {
return
}
socialBind(type, code, state).then(() => {
message.success('绑定成功')
emit('update:activeName', 'userSocial')
})
}
// 双层 encode 需要在回调后进行 decode
function getUrlValue(key: string): string {
const url = new URL(decodeURIComponent(location.href))
return url.searchParams.get(key) ?? ''
}
const bind = (row) => {
// 双层 encode 解决钉钉回调 type 参数丢失的问题
const redirectUri = location.origin + '/user/profile?' + encodeURIComponent(`type=${row.type}`)
// 进行跳转
socialAuthRedirect(row.type, encodeURIComponent(redirectUri)).then((res) => {
window.location.href = res
})
}
const unbind = async (row) => {
const res = await socialUnbind(row.type, row.openid)
if (res) {
row.openid = undefined
}
message.success('解绑成功')
}
onMounted(async () => {
await initSocial()
})
watch(
() => route,
() => {
bindSocial()
},
{
immediate: true
}
)
</script>