parent
35326f1fa6
commit
bb82588208
@ -1,99 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<div class="text-center">
|
|
||||||
<UserAvatar :img="userInfo?.avatar" />
|
|
||||||
</div>
|
|
||||||
<ul class="list-group list-group-striped">
|
|
||||||
<li class="list-group-item">
|
|
||||||
<Icon class="mr-5px" icon="ep:user" />
|
|
||||||
{{ t('profile.user.username') }}
|
|
||||||
<div class="pull-right">{{ userInfo?.username }}</div>
|
|
||||||
</li>
|
|
||||||
<li class="list-group-item">
|
|
||||||
<Icon class="mr-5px" icon="ep:phone" />
|
|
||||||
{{ t('profile.user.mobile') }}
|
|
||||||
<div class="pull-right">{{ userInfo?.mobile }}</div>
|
|
||||||
</li>
|
|
||||||
<li class="list-group-item">
|
|
||||||
<Icon class="mr-5px" icon="fontisto:email" />
|
|
||||||
{{ t('profile.user.email') }}
|
|
||||||
<div class="pull-right">{{ userInfo?.email }}</div>
|
|
||||||
</li>
|
|
||||||
<li class="list-group-item">
|
|
||||||
<Icon class="mr-5px" icon="carbon:tree-view-alt" />
|
|
||||||
{{ t('profile.user.dept') }}
|
|
||||||
<div v-if="userInfo?.dept" class="pull-right">{{ userInfo?.dept.name }}</div>
|
|
||||||
</li>
|
|
||||||
<li class="list-group-item">
|
|
||||||
<Icon class="mr-5px" icon="ep:suitcase" />
|
|
||||||
{{ t('profile.user.posts') }}
|
|
||||||
<div v-if="userInfo?.posts" class="pull-right">
|
|
||||||
{{ userInfo?.posts.map((post) => post.name).join(',') }}
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li class="list-group-item">
|
|
||||||
<Icon class="mr-5px" icon="icon-park-outline:peoples" />
|
|
||||||
{{ t('profile.user.roles') }}
|
|
||||||
<div v-if="userInfo?.roles" class="pull-right">
|
|
||||||
{{ userInfo?.roles.map((role) => role.name).join(',') }}
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li class="list-group-item">
|
|
||||||
<Icon class="mr-5px" icon="ep:calendar" />
|
|
||||||
{{ t('profile.user.createTime') }}
|
|
||||||
<div class="pull-right">{{ formatDate(userInfo?.createTime) }}</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { formatDate } from '@/utils/formatTime'
|
|
||||||
import UserAvatar from './UserAvatar.vue'
|
|
||||||
|
|
||||||
import { getUserProfile, ProfileVO } from '@/api/system/user/profile'
|
|
||||||
|
|
||||||
defineOptions({ name: 'ProfileUser' })
|
|
||||||
|
|
||||||
const { t } = useI18n()
|
|
||||||
const userInfo = ref<ProfileVO>()
|
|
||||||
const getUserInfo = async () => {
|
|
||||||
const users = await getUserProfile()
|
|
||||||
userInfo.value = users
|
|
||||||
}
|
|
||||||
onMounted(async () => {
|
|
||||||
await getUserInfo()
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.text-center {
|
|
||||||
position: relative;
|
|
||||||
height: 120px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-group-striped > .list-group-item {
|
|
||||||
padding-right: 0;
|
|
||||||
padding-left: 0;
|
|
||||||
border-right: 0;
|
|
||||||
border-left: 0;
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-group {
|
|
||||||
padding-left: 0;
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-group-item {
|
|
||||||
padding: 11px 0;
|
|
||||||
margin-bottom: -1px;
|
|
||||||
font-size: 13px;
|
|
||||||
border-top: 1px solid #e7eaec;
|
|
||||||
border-bottom: 1px solid #e7eaec;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pull-right {
|
|
||||||
float: right !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -0,0 +1,204 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container system-notice">
|
||||||
|
<div class="subject">
|
||||||
|
<div class="lc"></div>
|
||||||
|
<div class="lh">系统通知</div>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<div class="types">
|
||||||
|
<template v-for="(item, index) in types" :key="index">
|
||||||
|
<el-button :type="item.type == activeIndex ? 'primary' : 'default'" plain
|
||||||
|
@click="changeNoticeType(item.type)">{{ item.name }}</el-button>
|
||||||
|
</template>
|
||||||
|
<div class="yidu">
|
||||||
|
<el-button type="info" :icon="Check">全部标记为已读</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="list">
|
||||||
|
<el-table :data="noticeList" height="590" :header-cell-style="{ 'background-color': '#f2f2f2' }"
|
||||||
|
:row-style="{ 'height': '55px', 'cursor': 'pointer' }" style="width: 100%" stripe @row-click="noticeInfoClick">
|
||||||
|
<el-table-column prop="title" label="标题" />
|
||||||
|
<el-table-column prop="status" label="状态" width="120">
|
||||||
|
<template #default="scope">
|
||||||
|
<div style="display: flex; align-items: center">
|
||||||
|
<template v-if="scope.row.status == 1">
|
||||||
|
<el-badge is-dot type="danger" style="margin: 10px 10px 0 0;">
|
||||||
|
<el-button size="small" plain>已读</el-button>
|
||||||
|
</el-badge>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<el-badge is-dot type="success" style="margin: 10px 10px 0 0;">
|
||||||
|
<el-button size="small" plain>未读</el-button>
|
||||||
|
</el-badge>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="type" label="类型" width="120" />
|
||||||
|
<el-table-column prop="createTime" label="发布时间" width="180" />
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
<div class="page">
|
||||||
|
<el-pagination background layout="prev, pager, next" :total="page.total" hide-on-single-page
|
||||||
|
v-model:current-page="page.current" v-model:page-size="page.pageSize" @current-change="handleCurrentChange" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { Check } from '@element-plus/icons-vue'
|
||||||
|
defineOptions({ name: 'SystemNotice' })
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
const message = useMessage()
|
||||||
|
|
||||||
|
const emits = defineEmits(['changeNoticeComponent', 'toNoticeInfo'])
|
||||||
|
|
||||||
|
const types = ref<any>([
|
||||||
|
{
|
||||||
|
type: 0,
|
||||||
|
name: '全部消息',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 1,
|
||||||
|
name: '服务消息',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 2,
|
||||||
|
name: '活动消息',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 3,
|
||||||
|
name: '商品消息',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 4,
|
||||||
|
name: '安全消息',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 5,
|
||||||
|
name: '故障消息',
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
const activeIndex = ref<number>(0);
|
||||||
|
|
||||||
|
const noticeList = ref<any>([]);
|
||||||
|
|
||||||
|
const page = reactive({
|
||||||
|
current: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 100
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getNoiceData();
|
||||||
|
});
|
||||||
|
|
||||||
|
const getNoiceData = () => {
|
||||||
|
noticeList.value = [
|
||||||
|
{
|
||||||
|
'id': 1,
|
||||||
|
'title': '供应链管理平台正式上线1',
|
||||||
|
'status': 1,
|
||||||
|
'type': '商品消息',
|
||||||
|
'createTime': '2022-08-22 18:05:11',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': 2,
|
||||||
|
'title': '供应链管理平台正式上线2',
|
||||||
|
'status': 1,
|
||||||
|
'type': '商品消息',
|
||||||
|
'createTime': '2022-08-22 18:05:11',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': 3,
|
||||||
|
'title': '供应链管理平台正式上线3',
|
||||||
|
'status': 2,
|
||||||
|
'type': '商品消息',
|
||||||
|
'createTime': '2022-08-22 18:05:11',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': 4,
|
||||||
|
'title': '供应链管理平台正式上线4',
|
||||||
|
'status': 2,
|
||||||
|
'type': '商品消息',
|
||||||
|
'createTime': '2022-08-22 18:05:11',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': 5,
|
||||||
|
'title': '供应链管理平台正式上线5',
|
||||||
|
'status': 1,
|
||||||
|
'type': '商品消息',
|
||||||
|
'createTime': '2022-08-22 18:05:11',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
// 切换通知类型
|
||||||
|
const changeNoticeType = (type: number) => {
|
||||||
|
activeIndex.value = type;
|
||||||
|
// todo
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切换页码
|
||||||
|
const handleCurrentChange = (val: number) => {
|
||||||
|
console.log(`current page: ${val}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 进入通知详情
|
||||||
|
const noticeInfoClick = (row, column, event) => {
|
||||||
|
emits('changeNoticeComponent', 'SystemNoticeInfo');
|
||||||
|
emits('toNoticeInfo', row);
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.system-notice {
|
||||||
|
width: 100%;
|
||||||
|
padding: 20px;
|
||||||
|
padding-left: 50px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.subject {
|
||||||
|
height: 60px;
|
||||||
|
color: #666;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
line-height: 20px;
|
||||||
|
|
||||||
|
.lc {
|
||||||
|
width: 8px;
|
||||||
|
height: 20px;
|
||||||
|
background: #409eff;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lh {
|
||||||
|
color: #666;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.types {
|
||||||
|
height: 50px;
|
||||||
|
line-height: 50px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
.yidu {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
float: right;
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,39 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="change-avatar">
|
|
||||||
<CropperAvatar
|
|
||||||
ref="cropperRef"
|
|
||||||
:btnProps="{ preIcon: 'ant-design:cloud-upload-outlined' }"
|
|
||||||
:showBtn="false"
|
|
||||||
:value="img"
|
|
||||||
width="120px"
|
|
||||||
@change="handelUpload"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { propTypes } from '@/utils/propTypes'
|
|
||||||
import { uploadAvatar } from '@/api/system/user/profile'
|
|
||||||
import { CropperAvatar } from '@/components/Cropper'
|
|
||||||
|
|
||||||
defineOptions({ name: 'UserAvatar' })
|
|
||||||
|
|
||||||
defineProps({
|
|
||||||
img: propTypes.string.def('')
|
|
||||||
})
|
|
||||||
|
|
||||||
const cropperRef = ref()
|
|
||||||
const handelUpload = async ({ data }) => {
|
|
||||||
await uploadAvatar({ avatarFile: data })
|
|
||||||
cropperRef.value.close()
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.change-avatar {
|
|
||||||
img {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,94 +0,0 @@
|
|||||||
<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 { getUserProfile, ProfileVO } from '@/api/system/user/profile'
|
|
||||||
import { socialAuthRedirect, socialBind, socialUnbind } from '@/api/system/user/socialUser'
|
|
||||||
|
|
||||||
defineOptions({ name: 'UserSocial' })
|
|
||||||
|
|
||||||
const message = useMessage()
|
|
||||||
const socialUsers = ref<any[]>([])
|
|
||||||
const userInfo = ref<ProfileVO>()
|
|
||||||
|
|
||||||
const initSocial = async () => {
|
|
||||||
const res = await getUserProfile()
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const route = useRoute()
|
|
||||||
const bindSocial = () => {
|
|
||||||
// 社交绑定
|
|
||||||
const type = route.query.type
|
|
||||||
const code = route.query.code
|
|
||||||
const state = route.query.state
|
|
||||||
if (!code) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
socialBind(type, code, state).then(() => {
|
|
||||||
message.success('绑定成功')
|
|
||||||
initSocial()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const bind = (row) => {
|
|
||||||
const redirectUri = location.origin + '/user/profile?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,
|
|
||||||
(newRoute) => {
|
|
||||||
bindSocial()
|
|
||||||
console.log(newRoute)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
immediate: true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
</script>
|
|
@ -1,8 +1,7 @@
|
|||||||
import BaseInfo from './BaseInfo.vue'
|
import BaseInfo from './BaseInfo.vue'
|
||||||
import LoginRecord from './LoginRecord.vue'
|
import LoginRecord from './LoginRecord.vue'
|
||||||
import ResetPwd from './ResetPwd.vue'
|
import ResetPwd from './ResetPwd.vue'
|
||||||
import ProfileUser from './ProfileUser.vue'
|
import SystemNotice from './SystemNotice.vue'
|
||||||
import UserAvatarVue from './UserAvatar.vue'
|
import SystemNoticeInfo from './SystemNoticeInfo.vue'
|
||||||
import UserSocial from './UserSocial.vue'
|
|
||||||
|
|
||||||
export { BaseInfo, ResetPwd, LoginRecord,ProfileUser, UserAvatarVue, UserSocial }
|
export { BaseInfo, ResetPwd, LoginRecord, SystemNotice, SystemNoticeInfo }
|
||||||
|
Loading…
Reference in new issue