Commit 770bf45f01a239d42a95cb74ec0a6bfac2dac1b6

Authored by xingyu4j
1 parent fab2366d

refactor: profile

yudao-ui-admin-vue3/src/api/system/user/profile/types.ts renamed to yudao-ui-admin-vue3/src/api/system/user/profile.ts
1 -export type ProfileDept = { 1 +import request from '@/config/axios'
  2 +
  3 +export interface ProfileDept {
2 id: number 4 id: number
3 name: string 5 name: string
4 } 6 }
5 -export type ProfileRole = { 7 +export interface ProfileRole {
6 id: number 8 id: number
7 name: string 9 name: string
8 } 10 }
9 -export type ProfilePost = { 11 +export interface ProfilePost {
10 id: number 12 id: number
11 name: string 13 name: string
12 } 14 }
13 -export type SocialUser = { 15 +export interface SocialUser {
14 id: number 16 id: number
15 type: number 17 type: number
16 openid: string 18 openid: string
@@ -22,7 +24,7 @@ export type SocialUser = { @@ -22,7 +24,7 @@ export type SocialUser = {
22 code: string 24 code: string
23 state: string 25 state: string
24 } 26 }
25 -export type ProfileVO = { 27 +export interface ProfileVO {
26 id: number 28 id: number
27 username: string 29 username: string
28 nickname: string 30 nickname: string
@@ -40,3 +42,36 @@ export type ProfileVO = { @@ -40,3 +42,36 @@ export type ProfileVO = {
40 loginDate: Date 42 loginDate: Date
41 createTime: Date 43 createTime: Date
42 } 44 }
  45 +
  46 +export interface UserProfileUpdateReqVO {
  47 + nickname: string
  48 + email: string
  49 + mobile: string
  50 + sex: number
  51 +}
  52 +
  53 +// 查询用户个人信息
  54 +export const getUserProfileApi = () => {
  55 + return request.get({ url: '/system/user/profile/get' })
  56 +}
  57 +
  58 +// 修改用户个人信息
  59 +export const updateUserProfileApi = (data: UserProfileUpdateReqVO) => {
  60 + return request.put({ url: '/system/user/profile/update', data })
  61 +}
  62 +
  63 +// 用户密码重置
  64 +export const updateUserPwdApi = (oldPassword: string, newPassword: string) => {
  65 + return request.put({
  66 + url: '/system/user/profile/update-password',
  67 + data: {
  68 + oldPassword: oldPassword,
  69 + newPassword: newPassword
  70 + }
  71 + })
  72 +}
  73 +
  74 +// 用户头像上传
  75 +export const uploadAvatarApi = (data) => {
  76 + return request.upload({ url: '/system/user/profile/update-avatar', data: data })
  77 +}
yudao-ui-admin-vue3/src/api/system/user/profile/index.ts deleted
1 -import request from '@/config/axios'  
2 -  
3 -// 查询用户个人信息  
4 -export const getUserProfileApi = () => {  
5 - return request.get({ url: '/system/user/profile/get' })  
6 -}  
7 -  
8 -// 修改用户个人信息  
9 -export const updateUserProfileApi = (params) => {  
10 - return request.put({ url: '/system/user/profile/update', params })  
11 -}  
12 -  
13 -// 用户密码重置  
14 -export const updateUserPwdApi = (oldPassword: string, newPassword: string) => {  
15 - return request.put({  
16 - url: '/system/user/profile/update-password',  
17 - data: {  
18 - oldPassword: oldPassword,  
19 - newPassword: newPassword  
20 - }  
21 - })  
22 -}  
23 -  
24 -// 用户头像上传  
25 -export const uploadAvatarApi = (data) => {  
26 - return request.upload({ url: '/system/user/profile/update-avatar', data: data })  
27 -}  
yudao-ui-admin-vue3/src/api/system/user/socialUser.ts 0 → 100644
  1 +import request from '@/config/axios'
  2 +
  3 +// 社交绑定,使用 code 授权码
  4 +export const socialBind = (type, code, state) => {
  5 + return request.post({
  6 + url: '/system/social-user/bind',
  7 + data: {
  8 + type,
  9 + code,
  10 + state
  11 + }
  12 + })
  13 +}
  14 +
  15 +// 取消社交绑定
  16 +export const socialUnbind = (type, openid) => {
  17 + return request.delete({
  18 + url: '/system/social-user/unbind',
  19 + data: {
  20 + type,
  21 + openid
  22 + }
  23 + })
  24 +}
  25 +
  26 +// 社交授权的跳转
  27 +export const socialAuthRedirect = (type, redirectUri) => {
  28 + return request.get({
  29 + url: '/system/auth/social-auth-redirect?type=' + type + '&redirectUri=' + redirectUri
  30 + })
  31 +}
yudao-ui-admin-vue3/src/views/Profile/Index.vue
1 -<script setup lang="ts">  
2 -import { ref } from 'vue'  
3 -import { useI18n } from '@/hooks/web/useI18n'  
4 -import { ElCard, ElTabs, ElTabPane } from 'element-plus'  
5 -import { BasicInfo, ProfileUser, ResetPwd, UserSocial } from './components/'  
6 -const { t } = useI18n()  
7 -const activeName = ref('basicInfo')  
8 -</script>  
9 <template> 1 <template>
10 <div class="flex"> 2 <div class="flex">
11 <el-card class="w-1/3 user" shadow="hover"> 3 <el-card class="w-1/3 user" shadow="hover">
@@ -38,6 +30,15 @@ const activeName = ref(&#39;basicInfo&#39;) @@ -38,6 +30,15 @@ const activeName = ref(&#39;basicInfo&#39;)
38 </el-card> 30 </el-card>
39 </div> 31 </div>
40 </template> 32 </template>
  33 +<script setup lang="ts">
  34 +import { ref } from 'vue'
  35 +import { useI18n } from '@/hooks/web/useI18n'
  36 +import { ElCard, ElTabs, ElTabPane } from 'element-plus'
  37 +import { BasicInfo, ProfileUser, ResetPwd, UserSocial } from './components/'
  38 +const { t } = useI18n()
  39 +
  40 +const activeName = ref('basicInfo')
  41 +</script>
41 <style scoped> 42 <style scoped>
42 .user { 43 .user {
43 max-height: 960px; 44 max-height: 960px;
yudao-ui-admin-vue3/src/views/Profile/components/BasicInfo.vue
  1 +<template>
  2 + <Form ref="formRef" :rules="rules" :schema="schema" :labelWidth="80">
  3 + <template #sex>
  4 + <el-radio-group v-model="sexVlue">
  5 + <el-radio :label="1">{{ t('profile.user.man') }}</el-radio>
  6 + <el-radio :label="2">{{ t('profile.user.woman') }}</el-radio>
  7 + </el-radio-group>
  8 + </template>
  9 + </Form>
  10 + <el-button type="primary" @click="submit()">{{ t('common.save') }}</el-button>
  11 + <el-button type="danger" @click="init()">{{ t('common.reset') }}</el-button>
  12 +</template>
1 <script setup lang="ts"> 13 <script setup lang="ts">
2 -import { ref, reactive, onMounted } from 'vue'  
3 -import type { FormRules, FormInstance } from 'element-plus'  
4 -import { ElForm, ElFormItem, ElInput, ElRadioGroup, ElRadio, ElMessage } from 'element-plus' 14 +import { reactive, onMounted, unref, ref } from 'vue'
  15 +import type { FormRules } from 'element-plus'
  16 +import { ElMessage, ElRadioGroup, ElRadio } from 'element-plus'
5 import { useI18n } from '@/hooks/web/useI18n' 17 import { useI18n } from '@/hooks/web/useI18n'
6 -import { getUserProfileApi, updateUserProfileApi } from '@/api/system/user/profile' 18 +import {
  19 + getUserProfileApi,
  20 + updateUserProfileApi,
  21 + UserProfileUpdateReqVO
  22 +} from '@/api/system/user/profile'
  23 +import { FormSchema } from '@/types/form'
  24 +import { FormExpose } from '@/components/Form'
7 const { t } = useI18n() 25 const { t } = useI18n()
8 -const formRef = ref<FormInstance>()  
9 -interface BasicUserInfoVO {  
10 - id: number  
11 - nickname: string  
12 - email: string  
13 - mobile: string  
14 - sex: number  
15 -}  
16 -interface userInfoType {  
17 - basicUserInfo: BasicUserInfoVO  
18 -}  
19 -const user = reactive<userInfoType>({  
20 - basicUserInfo: {  
21 - id: 0,  
22 - nickname: '',  
23 - mobile: '',  
24 - email: '',  
25 - sex: 0  
26 - }  
27 -})  
28 // 表单校验 26 // 表单校验
29 const rules = reactive<FormRules>({ 27 const rules = reactive<FormRules>({
30 nickname: [{ required: true, message: t('profile.rules.nickname'), trigger: 'blur' }], 28 nickname: [{ required: true, message: t('profile.rules.nickname'), trigger: 'blur' }],
@@ -45,47 +43,49 @@ const rules = reactive&lt;FormRules&gt;({ @@ -45,47 +43,49 @@ const rules = reactive&lt;FormRules&gt;({
45 } 43 }
46 ] 44 ]
47 }) 45 })
48 -const submit = (formEl: FormInstance | undefined) => {  
49 - if (!formEl) return  
50 - formEl.validate(async (valid) => { 46 +const schema = reactive<FormSchema[]>([
  47 + {
  48 + field: 'nickname',
  49 + label: t('profile.user.nickname'),
  50 + component: 'Input'
  51 + },
  52 + {
  53 + field: 'mobile',
  54 + label: t('profile.user.mobile'),
  55 + component: 'Input'
  56 + },
  57 + {
  58 + field: 'email',
  59 + label: t('profile.user.email'),
  60 + component: 'Input'
  61 + },
  62 + {
  63 + field: 'sex',
  64 + label: t('profile.user.sex'),
  65 + component: 'InputNumber'
  66 + }
  67 +])
  68 +const sexVlue = ref<number>()
  69 +const formRef = ref<FormExpose>() // 表单 Ref
  70 +const submit = () => {
  71 + const elForm = unref(formRef)?.getElFormRef()
  72 + if (!elForm) return
  73 + elForm.validate(async (valid) => {
51 if (valid) { 74 if (valid) {
52 - await updateUserProfileApi({ params: user.basicUserInfo }) 75 + const data = unref(formRef)?.formModel as UserProfileUpdateReqVO
  76 + data.sex = sexVlue.value as unknown as number
  77 + await updateUserProfileApi(data)
53 ElMessage.success(t('common.updateSuccess')) 78 ElMessage.success(t('common.updateSuccess'))
  79 + await init()
54 } 80 }
55 }) 81 })
56 } 82 }
57 -const reset = async (formEl: FormInstance | undefined) => {  
58 - if (!formEl) return  
59 - await getUserInfo()  
60 -}  
61 -const getUserInfo = async () => {  
62 - const users = await getUserProfileApi()  
63 - user.basicUserInfo = users 83 +const init = async () => {
  84 + const res = await getUserProfileApi()
  85 + sexVlue.value = res.sex
  86 + unref(formRef)?.setValues(res)
64 } 87 }
65 onMounted(async () => { 88 onMounted(async () => {
66 - await getUserInfo() 89 + await init()
67 }) 90 })
68 </script> 91 </script>
69 -<template>  
70 - <el-form ref="form" :model="user.basicUserInfo" :rules="rules" label-width="80px">  
71 - <el-form-item :label="t('profile.user.nickname')" prop="nickname">  
72 - <el-input v-model="user.basicUserInfo.nickname" />  
73 - </el-form-item>  
74 - <el-form-item :label="t('profile.user.mobile')" prop="mobile">  
75 - <el-input v-model="user.basicUserInfo.mobile" maxlength="11" />  
76 - </el-form-item>  
77 - <el-form-item :label="t('profile.user.email')" prop="email">  
78 - <el-input v-model="user.basicUserInfo.email" maxlength="50" />  
79 - </el-form-item>  
80 - <el-form-item :label="t('profile.user.sex')" prop="sex">  
81 - <el-radio-group v-model="user.basicUserInfo.sex">  
82 - <el-radio :label="1">{{ t('profile.user.man') }}</el-radio>  
83 - <el-radio :label="2">{{ t('profile.user.woman') }}</el-radio>  
84 - </el-radio-group>  
85 - </el-form-item>  
86 - <el-form-item>  
87 - <el-button type="primary" @click="submit(formRef)">{{ t('common.save') }}</el-button>  
88 - <el-button type="danger" @click="reset(formRef)">{{ t('common.reset') }}</el-button>  
89 - </el-form-item>  
90 - </el-form>  
91 -</template>  
yudao-ui-admin-vue3/src/views/Profile/components/ProfileUser.vue
1 -<script setup lang="ts">  
2 -import { getUserProfileApi } from '@/api/system/user/profile'  
3 -import { onMounted, reactive } from 'vue'  
4 -import dayjs from 'dayjs'  
5 -import UserAvatar from './UserAvatar.vue'  
6 -import { ProfileVO } from '@/api/system/user/profile/types'  
7 -import { useI18n } from '@/hooks/web/useI18n'  
8 -const { t } = useI18n()  
9 -interface userInfoType {  
10 - user: ProfileVO  
11 -}  
12 -const userInfo = reactive<userInfoType>({  
13 - user: {  
14 - id: 0,  
15 - username: '',  
16 - nickname: '',  
17 - dept: {  
18 - id: 0,  
19 - name: ''  
20 - },  
21 - roles: [],  
22 - posts: [],  
23 - socialUsers: [],  
24 - email: '',  
25 - mobile: '',  
26 - sex: 0,  
27 - avatar: '',  
28 - status: 0,  
29 - remark: '',  
30 - loginIp: '',  
31 - loginDate: new Date(),  
32 - createTime: new Date()  
33 - }  
34 -})  
35 -const getUserInfo = async () => {  
36 - const users = await getUserProfileApi()  
37 - userInfo.user = users  
38 -}  
39 -onMounted(async () => {  
40 - await getUserInfo()  
41 -})  
42 -</script>  
43 <template> 1 <template>
44 <div> 2 <div>
45 <div class="text-center"> 3 <div class="text-center">
46 - <UserAvatar :img="userInfo.user.avatar" /> 4 + <UserAvatar :img="userInfo?.avatar" />
47 </div> 5 </div>
48 <ul class="list-group list-group-striped"> 6 <ul class="list-group list-group-striped">
49 <li class="list-group-item"> 7 <li class="list-group-item">
50 <Icon icon="ep:user" class="mr-5px" />{{ t('profile.user.username') }} 8 <Icon icon="ep:user" class="mr-5px" />{{ t('profile.user.username') }}
51 - <div class="pull-right">{{ userInfo.user.username }}</div> 9 + <div class="pull-right">{{ userInfo?.username }}</div>
52 </li> 10 </li>
53 <li class="list-group-item"> 11 <li class="list-group-item">
54 <Icon icon="ep:phone" class="mr-5px" />{{ t('profile.user.mobile') }} 12 <Icon icon="ep:phone" class="mr-5px" />{{ t('profile.user.mobile') }}
55 - <div class="pull-right">{{ userInfo.user.mobile }}</div> 13 + <div class="pull-right">{{ userInfo?.mobile }}</div>
56 </li> 14 </li>
57 <li class="list-group-item"> 15 <li class="list-group-item">
58 <Icon icon="fontisto:email" class="mr-5px" />{{ t('profile.user.email') }} 16 <Icon icon="fontisto:email" class="mr-5px" />{{ t('profile.user.email') }}
59 - <div class="pull-right">{{ userInfo.user.email }}</div> 17 + <div class="pull-right">{{ userInfo?.email }}</div>
60 </li> 18 </li>
61 <li class="list-group-item"> 19 <li class="list-group-item">
62 <Icon icon="carbon:tree-view-alt" class="mr-5px" />{{ t('profile.user.dept') }} 20 <Icon icon="carbon:tree-view-alt" class="mr-5px" />{{ t('profile.user.dept') }}
63 - <div class="pull-right" v-if="userInfo.user.dept">{{ userInfo.user.dept.name }}</div> 21 + <div class="pull-right" v-if="userInfo?.dept">{{ userInfo?.dept.name }}</div>
64 </li> 22 </li>
65 <li class="list-group-item"> 23 <li class="list-group-item">
66 <Icon icon="ep:suitcase" class="mr-5px" />{{ t('profile.user.posts') }} 24 <Icon icon="ep:suitcase" class="mr-5px" />{{ t('profile.user.posts') }}
67 - <div class="pull-right" v-if="userInfo.user.posts">  
68 - {{ userInfo.user.posts.map((post) => post.name).join(',') }} 25 + <div class="pull-right" v-if="userInfo?.posts">
  26 + {{ userInfo?.posts.map((post) => post.name).join(',') }}
69 </div> 27 </div>
70 </li> 28 </li>
71 <li class="list-group-item"> 29 <li class="list-group-item">
72 <Icon icon="icon-park-outline:peoples" class="mr-5px" />{{ t('profile.user.roles') }} 30 <Icon icon="icon-park-outline:peoples" class="mr-5px" />{{ t('profile.user.roles') }}
73 - <div class="pull-right" v-if="userInfo.user.roles">  
74 - {{ userInfo.user.roles.map((role) => role.name).join(',') }} 31 + <div class="pull-right" v-if="userInfo?.roles">
  32 + {{ userInfo?.roles.map((role) => role.name).join(',') }}
75 </div> 33 </div>
76 </li> 34 </li>
77 <li class="list-group-item"> 35 <li class="list-group-item">
78 <Icon icon="ep:calendar" class="mr-5px" />{{ t('profile.user.createTime') }} 36 <Icon icon="ep:calendar" class="mr-5px" />{{ t('profile.user.createTime') }}
79 - <div class="pull-right">{{ dayjs(userInfo.user.createTime).format('YYYY-MM-DD') }}</div> 37 + <div class="pull-right">{{ dayjs(userInfo?.createTime).format('YYYY-MM-DD') }}</div>
80 </li> 38 </li>
81 </ul> 39 </ul>
82 </div> 40 </div>
83 </template> 41 </template>
  42 +<script setup lang="ts">
  43 +import { getUserProfileApi, ProfileVO } from '@/api/system/user/profile'
  44 +import { onMounted, ref } from 'vue'
  45 +import dayjs from 'dayjs'
  46 +import UserAvatar from './UserAvatar.vue'
  47 +import { useI18n } from '@/hooks/web/useI18n'
  48 +const { t } = useI18n()
  49 +const userInfo = ref<ProfileVO>()
  50 +const getUserInfo = async () => {
  51 + const users = await getUserProfileApi()
  52 + userInfo.value = users
  53 +}
  54 +onMounted(async () => {
  55 + await getUserInfo()
  56 +})
  57 +</script>
  58 +
84 <style scoped> 59 <style scoped>
85 .text-center { 60 .text-center {
86 text-align: center; 61 text-align: center;
yudao-ui-admin-vue3/src/views/Profile/components/ResetPwd.vue
  1 +<template>
  2 + <el-form ref="formRef" :model="password" :rules="rules" label-width="80px">
  3 + <el-form-item :label="t('profile.password.oldPassword')">
  4 + <InputPassword v-model="password.oldPassword" />
  5 + </el-form-item>
  6 + <el-form-item :label="t('profile.password.newPassword')">
  7 + <InputPassword v-model="password.newPassword" strength />
  8 + </el-form-item>
  9 + <el-form-item :label="t('profile.password.confirmPassword')">
  10 + <InputPassword v-model="password.confirmPassword" strength />
  11 + </el-form-item>
  12 + <el-form-item>
  13 + <XButton type="primary" @click="submit(formRef)" :title="t('common.save')" />
  14 + <XButton type="danger" :title="t('common.reset')" @click="reset(formRef)" />
  15 + </el-form-item>
  16 + </el-form>
  17 +</template>
1 <script setup lang="ts"> 18 <script setup lang="ts">
2 import { InputPassword } from '@/components/InputPassword' 19 import { InputPassword } from '@/components/InputPassword'
3 import { ElForm, ElFormItem, ElMessage } from 'element-plus' 20 import { ElForm, ElFormItem, ElMessage } from 'element-plus'
@@ -49,20 +66,3 @@ const reset = (formEl: FormInstance | undefined) =&gt; { @@ -49,20 +66,3 @@ const reset = (formEl: FormInstance | undefined) =&gt; {
49 formEl.resetFields() 66 formEl.resetFields()
50 } 67 }
51 </script> 68 </script>
52 -<template>  
53 - <el-form ref="formRef" :model="password" :rules="rules" label-width="80px">  
54 - <el-form-item :label="t('profile.password.oldPassword')">  
55 - <InputPassword v-model="password.oldPassword" />  
56 - </el-form-item>  
57 - <el-form-item :label="t('profile.password.newPassword')">  
58 - <InputPassword v-model="password.newPassword" strength />  
59 - </el-form-item>  
60 - <el-form-item :label="t('profile.password.confirmPassword')">  
61 - <InputPassword v-model="password.confirmPassword" strength />  
62 - </el-form-item>  
63 - <el-form-item>  
64 - <el-button type="primary" @click="submit(formRef)">{{ t('common.save') }}</el-button>  
65 - <el-button type="danger" @click="reset(formRef)">{{ t('common.reset') }}</el-button>  
66 - </el-form-item>  
67 - </el-form>  
68 -</template>  
yudao-ui-admin-vue3/src/views/Profile/components/UserSocial.vue
1 -<script setup lang="ts">  
2 -import { ElTable, ElTableColumn } from 'element-plus'  
3 -import { onMounted, reactive } from 'vue'  
4 -interface sociaType {  
5 - title: string  
6 - type: string  
7 - source: string  
8 - img: string  
9 -}  
10 -interface socialUserType {  
11 - socialUser: {  
12 - socia: sociaType[]  
13 - }  
14 -}  
15 -const state = reactive<socialUserType>({  
16 - socialUser: {  
17 - socia: []  
18 - }  
19 -})  
20 -const initSocial = () => {  
21 - console.info(1)  
22 -}  
23 -const bind = () => {  
24 - console.info(1)  
25 -}  
26 -const unbind = () => {  
27 - console.info(1)  
28 -}  
29 -onMounted(async () => {  
30 - await initSocial()  
31 -})  
32 -</script>  
33 <template> 1 <template>
34 - <el-table :data="state.socialUser.socia" :show-header="false">  
35 - <el-table-column label="社交平台" align="left" width="120" prop="socia">  
36 - <template #socia="{ row }"> 2 + <el-table :data="socialUsers" :show-header="false">
  3 + <el-table-column type="seq" title="序号" width="60" fixed="left" />
  4 + <el-table-column label="社交平台" align="left" width="120">
  5 + <template #default="{ row }">
37 <img style="height: 20px; vertical-align: middle" :src="row.img" alt="" /> 6 <img style="height: 20px; vertical-align: middle" :src="row.img" alt="" />
38 {{ row.title }} 7 {{ row.title }}
39 </template> 8 </template>
40 </el-table-column> 9 </el-table-column>
41 - <el-table-column label="操作" align="left" prop="action">  
42 - <template #action="{ row }">  
43 - <div v-if="row.openid"> 10 + <el-table-column label="操作" align="center">
  11 + <template #default="{ row }">
  12 + <template v-if="row.openid">
44 已绑定 13 已绑定
45 - <el-button link type="primary" @click="unbind()">(解绑)</el-button>  
46 - </div>  
47 - <div v-else> 14 + <XTextButton type="primary" @click="unbind(row)" title="(解绑)" />
  15 + </template>
  16 + <template v-else>
48 未绑定 17 未绑定
49 - <el-button link type="primary" @click="bind()">(绑定)</el-button>  
50 - </div> 18 + <XTextButton type="primary" @click="bind(row)" title="(绑定)" />
  19 + </template>
51 </template> 20 </template>
52 </el-table-column> 21 </el-table-column>
53 </el-table> 22 </el-table>
54 </template> 23 </template>
  24 +<script setup lang="ts">
  25 +import { onMounted, ref } from 'vue'
  26 +import { ElTable, ElTableColumn } from 'element-plus'
  27 +import { SystemUserSocialTypeEnum } from '@/utils/constants'
  28 +import { getUserProfileApi, ProfileVO } from '@/api/system/user/profile'
  29 +import { socialAuthRedirect, socialUnbind } from '@/api/system/user/socialUser'
  30 +import { ElMessage } from 'element-plus'
  31 +
  32 +const socialUsers = ref<any[]>([])
  33 +const userInfo = ref<ProfileVO>()
  34 +const initSocial = async () => {
  35 + const res = await getUserProfileApi()
  36 + userInfo.value = res
  37 + for (const i in SystemUserSocialTypeEnum) {
  38 + const socialUser = { ...SystemUserSocialTypeEnum[i] }
  39 + socialUsers.value.push(socialUser)
  40 + if (userInfo.value?.socialUsers) {
  41 + for (const j in userInfo.value.socialUsers) {
  42 + if (socialUser.type === userInfo.value.socialUsers[j].type) {
  43 + socialUser.openid = userInfo.value.socialUsers[j].openid
  44 + break
  45 + }
  46 + }
  47 + }
  48 + }
  49 + console.info(socialUsers.value)
  50 +}
  51 +const bind = (row) => {
  52 + const redirectUri = location.origin + '/user/profile?type=' + row.type
  53 + // 进行跳转
  54 + socialAuthRedirect(row.type, encodeURIComponent(redirectUri)).then((res) => {
  55 + console.log(res.url)
  56 + window.location.href = res.data
  57 + })
  58 +}
  59 +const unbind = async (row) => {
  60 + const res = await socialUnbind(row.type, row.openid)
  61 + if (res) {
  62 + row.openid = undefined
  63 + }
  64 + ElMessage.success('解绑成功')
  65 +}
  66 +
  67 +onMounted(async () => {
  68 + await initSocial()
  69 +})
  70 +</script>