mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 18:28:43 +08:00 
			
		
		
		
	refactor: profile
This commit is contained in:
		| @@ -1,11 +1,3 @@ | ||||
| <script setup lang="ts"> | ||||
| import { ref } from 'vue' | ||||
| import { useI18n } from '@/hooks/web/useI18n' | ||||
| import { ElCard, ElTabs, ElTabPane } from 'element-plus' | ||||
| import { BasicInfo, ProfileUser, ResetPwd, UserSocial } from './components/' | ||||
| const { t } = useI18n() | ||||
| const activeName = ref('basicInfo') | ||||
| </script> | ||||
| <template> | ||||
|   <div class="flex"> | ||||
|     <el-card class="w-1/3 user" shadow="hover"> | ||||
| @@ -38,6 +30,15 @@ const activeName = ref('basicInfo') | ||||
|     </el-card> | ||||
|   </div> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| import { ref } from 'vue' | ||||
| import { useI18n } from '@/hooks/web/useI18n' | ||||
| import { ElCard, ElTabs, ElTabPane } from 'element-plus' | ||||
| import { BasicInfo, ProfileUser, ResetPwd, UserSocial } from './components/' | ||||
| const { t } = useI18n() | ||||
|  | ||||
| const activeName = ref('basicInfo') | ||||
| </script> | ||||
| <style scoped> | ||||
| .user { | ||||
|   max-height: 960px; | ||||
|   | ||||
| @@ -1,30 +1,28 @@ | ||||
| <template> | ||||
|   <Form ref="formRef" :rules="rules" :schema="schema" :labelWidth="80"> | ||||
|     <template #sex> | ||||
|       <el-radio-group v-model="sexVlue"> | ||||
|         <el-radio :label="1">{{ t('profile.user.man') }}</el-radio> | ||||
|         <el-radio :label="2">{{ t('profile.user.woman') }}</el-radio> | ||||
|       </el-radio-group> | ||||
|     </template> | ||||
|   </Form> | ||||
|   <el-button type="primary" @click="submit()">{{ t('common.save') }}</el-button> | ||||
|   <el-button type="danger" @click="init()">{{ t('common.reset') }}</el-button> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| import { ref, reactive, onMounted } from 'vue' | ||||
| import type { FormRules, FormInstance } from 'element-plus' | ||||
| import { ElForm, ElFormItem, ElInput, ElRadioGroup, ElRadio, ElMessage } from 'element-plus' | ||||
| import { reactive, onMounted, unref, ref } from 'vue' | ||||
| import type { FormRules } from 'element-plus' | ||||
| import { ElMessage, ElRadioGroup, ElRadio } from 'element-plus' | ||||
| import { useI18n } from '@/hooks/web/useI18n' | ||||
| import { getUserProfileApi, updateUserProfileApi } from '@/api/system/user/profile' | ||||
| import { | ||||
|   getUserProfileApi, | ||||
|   updateUserProfileApi, | ||||
|   UserProfileUpdateReqVO | ||||
| } from '@/api/system/user/profile' | ||||
| import { FormSchema } from '@/types/form' | ||||
| import { FormExpose } from '@/components/Form' | ||||
| const { t } = useI18n() | ||||
| const formRef = ref<FormInstance>() | ||||
| interface BasicUserInfoVO { | ||||
|   id: number | ||||
|   nickname: string | ||||
|   email: string | ||||
|   mobile: string | ||||
|   sex: number | ||||
| } | ||||
| interface userInfoType { | ||||
|   basicUserInfo: BasicUserInfoVO | ||||
| } | ||||
| const user = reactive<userInfoType>({ | ||||
|   basicUserInfo: { | ||||
|     id: 0, | ||||
|     nickname: '', | ||||
|     mobile: '', | ||||
|     email: '', | ||||
|     sex: 0 | ||||
|   } | ||||
| }) | ||||
| // 表单校验 | ||||
| const rules = reactive<FormRules>({ | ||||
|   nickname: [{ required: true, message: t('profile.rules.nickname'), trigger: 'blur' }], | ||||
| @@ -45,47 +43,49 @@ const rules = reactive<FormRules>({ | ||||
|     } | ||||
|   ] | ||||
| }) | ||||
| const submit = (formEl: FormInstance | undefined) => { | ||||
|   if (!formEl) return | ||||
|   formEl.validate(async (valid) => { | ||||
| const schema = reactive<FormSchema[]>([ | ||||
|   { | ||||
|     field: 'nickname', | ||||
|     label: t('profile.user.nickname'), | ||||
|     component: 'Input' | ||||
|   }, | ||||
|   { | ||||
|     field: 'mobile', | ||||
|     label: t('profile.user.mobile'), | ||||
|     component: 'Input' | ||||
|   }, | ||||
|   { | ||||
|     field: 'email', | ||||
|     label: t('profile.user.email'), | ||||
|     component: 'Input' | ||||
|   }, | ||||
|   { | ||||
|     field: 'sex', | ||||
|     label: t('profile.user.sex'), | ||||
|     component: 'InputNumber' | ||||
|   } | ||||
| ]) | ||||
| const sexVlue = ref<number>() | ||||
| const formRef = ref<FormExpose>() // 表单 Ref | ||||
| const submit = () => { | ||||
|   const elForm = unref(formRef)?.getElFormRef() | ||||
|   if (!elForm) return | ||||
|   elForm.validate(async (valid) => { | ||||
|     if (valid) { | ||||
|       await updateUserProfileApi({ params: user.basicUserInfo }) | ||||
|       const data = unref(formRef)?.formModel as UserProfileUpdateReqVO | ||||
|       data.sex = sexVlue.value as unknown as number | ||||
|       await updateUserProfileApi(data) | ||||
|       ElMessage.success(t('common.updateSuccess')) | ||||
|       await init() | ||||
|     } | ||||
|   }) | ||||
| } | ||||
| const reset = async (formEl: FormInstance | undefined) => { | ||||
|   if (!formEl) return | ||||
|   await getUserInfo() | ||||
| } | ||||
| const getUserInfo = async () => { | ||||
|   const users = await getUserProfileApi() | ||||
|   user.basicUserInfo = users | ||||
| const init = async () => { | ||||
|   const res = await getUserProfileApi() | ||||
|   sexVlue.value = res.sex | ||||
|   unref(formRef)?.setValues(res) | ||||
| } | ||||
| onMounted(async () => { | ||||
|   await getUserInfo() | ||||
|   await init() | ||||
| }) | ||||
| </script> | ||||
| <template> | ||||
|   <el-form ref="form" :model="user.basicUserInfo" :rules="rules" label-width="80px"> | ||||
|     <el-form-item :label="t('profile.user.nickname')" prop="nickname"> | ||||
|       <el-input v-model="user.basicUserInfo.nickname" /> | ||||
|     </el-form-item> | ||||
|     <el-form-item :label="t('profile.user.mobile')" prop="mobile"> | ||||
|       <el-input v-model="user.basicUserInfo.mobile" maxlength="11" /> | ||||
|     </el-form-item> | ||||
|     <el-form-item :label="t('profile.user.email')" prop="email"> | ||||
|       <el-input v-model="user.basicUserInfo.email" maxlength="50" /> | ||||
|     </el-form-item> | ||||
|     <el-form-item :label="t('profile.user.sex')" prop="sex"> | ||||
|       <el-radio-group v-model="user.basicUserInfo.sex"> | ||||
|         <el-radio :label="1">{{ t('profile.user.man') }}</el-radio> | ||||
|         <el-radio :label="2">{{ t('profile.user.woman') }}</el-radio> | ||||
|       </el-radio-group> | ||||
|     </el-form-item> | ||||
|     <el-form-item> | ||||
|       <el-button type="primary" @click="submit(formRef)">{{ t('common.save') }}</el-button> | ||||
|       <el-button type="danger" @click="reset(formRef)">{{ t('common.reset') }}</el-button> | ||||
|     </el-form-item> | ||||
|   </el-form> | ||||
| </template> | ||||
|   | ||||
| @@ -1,86 +1,61 @@ | ||||
| <template> | ||||
|   <div> | ||||
|     <div class="text-center"> | ||||
|       <UserAvatar :img="userInfo?.avatar" /> | ||||
|     </div> | ||||
|     <ul class="list-group list-group-striped"> | ||||
|       <li class="list-group-item"> | ||||
|         <Icon icon="ep:user" class="mr-5px" />{{ t('profile.user.username') }} | ||||
|         <div class="pull-right">{{ userInfo?.username }}</div> | ||||
|       </li> | ||||
|       <li class="list-group-item"> | ||||
|         <Icon icon="ep:phone" class="mr-5px" />{{ t('profile.user.mobile') }} | ||||
|         <div class="pull-right">{{ userInfo?.mobile }}</div> | ||||
|       </li> | ||||
|       <li class="list-group-item"> | ||||
|         <Icon icon="fontisto:email" class="mr-5px" />{{ t('profile.user.email') }} | ||||
|         <div class="pull-right">{{ userInfo?.email }}</div> | ||||
|       </li> | ||||
|       <li class="list-group-item"> | ||||
|         <Icon icon="carbon:tree-view-alt" class="mr-5px" />{{ t('profile.user.dept') }} | ||||
|         <div class="pull-right" v-if="userInfo?.dept">{{ userInfo?.dept.name }}</div> | ||||
|       </li> | ||||
|       <li class="list-group-item"> | ||||
|         <Icon icon="ep:suitcase" class="mr-5px" />{{ t('profile.user.posts') }} | ||||
|         <div class="pull-right" v-if="userInfo?.posts"> | ||||
|           {{ userInfo?.posts.map((post) => post.name).join(',') }} | ||||
|         </div> | ||||
|       </li> | ||||
|       <li class="list-group-item"> | ||||
|         <Icon icon="icon-park-outline:peoples" class="mr-5px" />{{ t('profile.user.roles') }} | ||||
|         <div class="pull-right" v-if="userInfo?.roles"> | ||||
|           {{ userInfo?.roles.map((role) => role.name).join(',') }} | ||||
|         </div> | ||||
|       </li> | ||||
|       <li class="list-group-item"> | ||||
|         <Icon icon="ep:calendar" class="mr-5px" />{{ t('profile.user.createTime') }} | ||||
|         <div class="pull-right">{{ dayjs(userInfo?.createTime).format('YYYY-MM-DD') }}</div> | ||||
|       </li> | ||||
|     </ul> | ||||
|   </div> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| import { getUserProfileApi } from '@/api/system/user/profile' | ||||
| import { onMounted, reactive } from 'vue' | ||||
| import { getUserProfileApi, ProfileVO } from '@/api/system/user/profile' | ||||
| import { onMounted, ref } from 'vue' | ||||
| import dayjs from 'dayjs' | ||||
| import UserAvatar from './UserAvatar.vue' | ||||
| import { ProfileVO } from '@/api/system/user/profile/types' | ||||
| import { useI18n } from '@/hooks/web/useI18n' | ||||
| const { t } = useI18n() | ||||
| interface userInfoType { | ||||
|   user: ProfileVO | ||||
| } | ||||
| const userInfo = reactive<userInfoType>({ | ||||
|   user: { | ||||
|     id: 0, | ||||
|     username: '', | ||||
|     nickname: '', | ||||
|     dept: { | ||||
|       id: 0, | ||||
|       name: '' | ||||
|     }, | ||||
|     roles: [], | ||||
|     posts: [], | ||||
|     socialUsers: [], | ||||
|     email: '', | ||||
|     mobile: '', | ||||
|     sex: 0, | ||||
|     avatar: '', | ||||
|     status: 0, | ||||
|     remark: '', | ||||
|     loginIp: '', | ||||
|     loginDate: new Date(), | ||||
|     createTime: new Date() | ||||
|   } | ||||
| }) | ||||
| const userInfo = ref<ProfileVO>() | ||||
| const getUserInfo = async () => { | ||||
|   const users = await getUserProfileApi() | ||||
|   userInfo.user = users | ||||
|   userInfo.value = users | ||||
| } | ||||
| onMounted(async () => { | ||||
|   await getUserInfo() | ||||
| }) | ||||
| </script> | ||||
| <template> | ||||
|   <div> | ||||
|     <div class="text-center"> | ||||
|       <UserAvatar :img="userInfo.user.avatar" /> | ||||
|     </div> | ||||
|     <ul class="list-group list-group-striped"> | ||||
|       <li class="list-group-item"> | ||||
|         <Icon icon="ep:user" class="mr-5px" />{{ t('profile.user.username') }} | ||||
|         <div class="pull-right">{{ userInfo.user.username }}</div> | ||||
|       </li> | ||||
|       <li class="list-group-item"> | ||||
|         <Icon icon="ep:phone" class="mr-5px" />{{ t('profile.user.mobile') }} | ||||
|         <div class="pull-right">{{ userInfo.user.mobile }}</div> | ||||
|       </li> | ||||
|       <li class="list-group-item"> | ||||
|         <Icon icon="fontisto:email" class="mr-5px" />{{ t('profile.user.email') }} | ||||
|         <div class="pull-right">{{ userInfo.user.email }}</div> | ||||
|       </li> | ||||
|       <li class="list-group-item"> | ||||
|         <Icon icon="carbon:tree-view-alt" class="mr-5px" />{{ t('profile.user.dept') }} | ||||
|         <div class="pull-right" v-if="userInfo.user.dept">{{ userInfo.user.dept.name }}</div> | ||||
|       </li> | ||||
|       <li class="list-group-item"> | ||||
|         <Icon icon="ep:suitcase" class="mr-5px" />{{ t('profile.user.posts') }} | ||||
|         <div class="pull-right" v-if="userInfo.user.posts"> | ||||
|           {{ userInfo.user.posts.map((post) => post.name).join(',') }} | ||||
|         </div> | ||||
|       </li> | ||||
|       <li class="list-group-item"> | ||||
|         <Icon icon="icon-park-outline:peoples" class="mr-5px" />{{ t('profile.user.roles') }} | ||||
|         <div class="pull-right" v-if="userInfo.user.roles"> | ||||
|           {{ userInfo.user.roles.map((role) => role.name).join(',') }} | ||||
|         </div> | ||||
|       </li> | ||||
|       <li class="list-group-item"> | ||||
|         <Icon icon="ep:calendar" class="mr-5px" />{{ t('profile.user.createTime') }} | ||||
|         <div class="pull-right">{{ dayjs(userInfo.user.createTime).format('YYYY-MM-DD') }}</div> | ||||
|       </li> | ||||
|     </ul> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <style scoped> | ||||
| .text-center { | ||||
|   text-align: center; | ||||
|   | ||||
| @@ -1,3 +1,20 @@ | ||||
| <template> | ||||
|   <el-form ref="formRef" :model="password" :rules="rules" label-width="80px"> | ||||
|     <el-form-item :label="t('profile.password.oldPassword')"> | ||||
|       <InputPassword v-model="password.oldPassword" /> | ||||
|     </el-form-item> | ||||
|     <el-form-item :label="t('profile.password.newPassword')"> | ||||
|       <InputPassword v-model="password.newPassword" strength /> | ||||
|     </el-form-item> | ||||
|     <el-form-item :label="t('profile.password.confirmPassword')"> | ||||
|       <InputPassword v-model="password.confirmPassword" strength /> | ||||
|     </el-form-item> | ||||
|     <el-form-item> | ||||
|       <XButton type="primary" @click="submit(formRef)" :title="t('common.save')" /> | ||||
|       <XButton type="danger" :title="t('common.reset')" @click="reset(formRef)" /> | ||||
|     </el-form-item> | ||||
|   </el-form> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| import { InputPassword } from '@/components/InputPassword' | ||||
| import { ElForm, ElFormItem, ElMessage } from 'element-plus' | ||||
| @@ -49,20 +66,3 @@ const reset = (formEl: FormInstance | undefined) => { | ||||
|   formEl.resetFields() | ||||
| } | ||||
| </script> | ||||
| <template> | ||||
|   <el-form ref="formRef" :model="password" :rules="rules" label-width="80px"> | ||||
|     <el-form-item :label="t('profile.password.oldPassword')"> | ||||
|       <InputPassword v-model="password.oldPassword" /> | ||||
|     </el-form-item> | ||||
|     <el-form-item :label="t('profile.password.newPassword')"> | ||||
|       <InputPassword v-model="password.newPassword" strength /> | ||||
|     </el-form-item> | ||||
|     <el-form-item :label="t('profile.password.confirmPassword')"> | ||||
|       <InputPassword v-model="password.confirmPassword" strength /> | ||||
|     </el-form-item> | ||||
|     <el-form-item> | ||||
|       <el-button type="primary" @click="submit(formRef)">{{ t('common.save') }}</el-button> | ||||
|       <el-button type="danger" @click="reset(formRef)">{{ t('common.reset') }}</el-button> | ||||
|     </el-form-item> | ||||
|   </el-form> | ||||
| </template> | ||||
|   | ||||
| @@ -1,54 +1,70 @@ | ||||
| <script setup lang="ts"> | ||||
| import { ElTable, ElTableColumn } from 'element-plus' | ||||
| import { onMounted, reactive } from 'vue' | ||||
| interface sociaType { | ||||
|   title: string | ||||
|   type: string | ||||
|   source: string | ||||
|   img: string | ||||
| } | ||||
| interface socialUserType { | ||||
|   socialUser: { | ||||
|     socia: sociaType[] | ||||
|   } | ||||
| } | ||||
| const state = reactive<socialUserType>({ | ||||
|   socialUser: { | ||||
|     socia: [] | ||||
|   } | ||||
| }) | ||||
| const initSocial = () => { | ||||
|   console.info(1) | ||||
| } | ||||
| const bind = () => { | ||||
|   console.info(1) | ||||
| } | ||||
| const unbind = () => { | ||||
|   console.info(1) | ||||
| } | ||||
| onMounted(async () => { | ||||
|   await initSocial() | ||||
| }) | ||||
| </script> | ||||
| <template> | ||||
|   <el-table :data="state.socialUser.socia" :show-header="false"> | ||||
|     <el-table-column label="社交平台" align="left" width="120" prop="socia"> | ||||
|       <template #socia="{ row }"> | ||||
|   <el-table :data="socialUsers" :show-header="false"> | ||||
|     <el-table-column type="seq" title="序号" width="60" fixed="left" /> | ||||
|     <el-table-column label="社交平台" align="left" width="120"> | ||||
|       <template #default="{ row }"> | ||||
|         <img style="height: 20px; vertical-align: middle" :src="row.img" alt="" /> | ||||
|         {{ row.title }} | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|     <el-table-column label="操作" align="left" prop="action"> | ||||
|       <template #action="{ row }"> | ||||
|         <div v-if="row.openid"> | ||||
|     <el-table-column label="操作" align="center"> | ||||
|       <template #default="{ row }"> | ||||
|         <template v-if="row.openid"> | ||||
|           已绑定 | ||||
|           <el-button link type="primary" @click="unbind()">(解绑)</el-button> | ||||
|         </div> | ||||
|         <div v-else> | ||||
|           <XTextButton type="primary" @click="unbind(row)" title="(解绑)" /> | ||||
|         </template> | ||||
|         <template v-else> | ||||
|           未绑定 | ||||
|           <el-button link type="primary" @click="bind()">(绑定)</el-button> | ||||
|         </div> | ||||
|           <XTextButton type="primary" @click="bind(row)" title="(绑定)" /> | ||||
|         </template> | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|   </el-table> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| import { onMounted, ref } from 'vue' | ||||
| import { ElTable, ElTableColumn } from 'element-plus' | ||||
| import { SystemUserSocialTypeEnum } from '@/utils/constants' | ||||
| import { getUserProfileApi, ProfileVO } from '@/api/system/user/profile' | ||||
| import { socialAuthRedirect, socialUnbind } from '@/api/system/user/socialUser' | ||||
| import { ElMessage } from 'element-plus' | ||||
|  | ||||
| const socialUsers = ref<any[]>([]) | ||||
| const userInfo = ref<ProfileVO>() | ||||
| const initSocial = async () => { | ||||
|   const res = await getUserProfileApi() | ||||
|   userInfo.value = res | ||||
|   for (const i in SystemUserSocialTypeEnum) { | ||||
|     const socialUser = { ...SystemUserSocialTypeEnum[i] } | ||||
|     socialUsers.value.push(socialUser) | ||||
|     if (userInfo.value?.socialUsers) { | ||||
|       for (const j in userInfo.value.socialUsers) { | ||||
|         if (socialUser.type === userInfo.value.socialUsers[j].type) { | ||||
|           socialUser.openid = userInfo.value.socialUsers[j].openid | ||||
|           break | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   console.info(socialUsers.value) | ||||
| } | ||||
| const bind = (row) => { | ||||
|   const redirectUri = location.origin + '/user/profile?type=' + row.type | ||||
|   // 进行跳转 | ||||
|   socialAuthRedirect(row.type, encodeURIComponent(redirectUri)).then((res) => { | ||||
|     console.log(res.url) | ||||
|     window.location.href = res.data | ||||
|   }) | ||||
| } | ||||
| const unbind = async (row) => { | ||||
|   const res = await socialUnbind(row.type, row.openid) | ||||
|   if (res) { | ||||
|     row.openid = undefined | ||||
|   } | ||||
|   ElMessage.success('解绑成功') | ||||
| } | ||||
|  | ||||
| onMounted(async () => { | ||||
|   await initSocial() | ||||
| }) | ||||
| </script> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 xingyu4j
					xingyu4j