Commit 6c5db609 by lijiabin

【需求 17679】 feat: 优化实名匿名部分等

parent db74b8dc
......@@ -9,10 +9,7 @@
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import { initWxConfig } from '@/utils/wxUtil/initWXConfig'
const locale = ref(zhCn)
// const userStore = useUserStore()
// userStore.fetchUserInfo().then((res) => {
// console.log(res)
// })
onMounted(() => {
if (import.meta.env.MODE === 'production') {
setTimeout(() => {
......
......@@ -27,4 +27,7 @@ export interface LoginResponseDto {
accountNonLocked: boolean
token: string
userId: number
hiddenAvatar: string
hiddenName: string
signature: string
}
......@@ -3,7 +3,7 @@
class="bg-white backdrop-blur-sm rounded-lg shadow-sm border border-white/50 overflow-hidden"
>
<!-- 发布者信息 -->
<div class="p-6 border-b border-gray-100">
<div class="p-6 border-b border-gray-100 pb-0">
<div class="flex items-center gap-4">
<div class="relative">
<img
......
......@@ -60,7 +60,7 @@
<!-- 发表评论 -->
<div class="p-4 border-b border-gray-100">
<div class="flex gap-3">
<img :src="userInfo?.avatar" alt="" class="w-10 h-10 rounded-full object-cover" />
<img :src="userAvatar" alt="" class="w-10 h-10 rounded-full object-cover" />
<div class="flex-1">
<div ref="commentInputRef">
<el-input
......@@ -232,7 +232,7 @@
<!-- 展示 回复评论的输入框 -->
<!-- <transition name="fade" mode="out-in"> -->
<div v-show="showCommentBox(item)" class="flex gap-3 mt-4">
<img :src="userInfo?.avatar" alt="" class="w-10 h-10 rounded-full object-cover" />
<img :src="userAvatar" alt="" class="w-10 h-10 rounded-full object-cover" />
<div class="flex-1">
<el-input
v-model="comment"
......@@ -313,6 +313,7 @@ const total = defineModel<number>('total', { required: true, default: 0 })
const userStore = useUserStore()
const { userInfo } = storeToRefs(userStore)
const userAvatar = computed(() => (isReal ? userInfo.value.avatar : userInfo.value.hiddenAvatar))
const commentRef = useTemplateRef<HTMLElement | null>('commentRef')
const commentInputRef = useTemplateRef<HTMLElement | null>('commentInputRef')
......@@ -480,7 +481,6 @@ const getCurrentChildrenList = (item: CommentItemDto) => {
}
const handleUserInfo = (item: CommentItemDto) => {
console.log(item)
router.push(`/otherUserPage/${item.userId}/${isReal}`)
}
......
......@@ -4,7 +4,7 @@
<!-- 主输入区域 -->
<div class="flex gap-3 mb-4 items-start">
<!-- 用户头像 -->
<el-avatar :size="48" :src="userInfo.avatar" class="flex-shrink-0">
<el-avatar :size="48" :src="userAvatar" class="flex-shrink-0">
<el-icon><User /></el-icon>
</el-avatar>
......@@ -156,12 +156,14 @@ import { useTagsStore } from '@/stores'
import { uploadFile } from '@/api'
import { Close } from '@element-plus/icons-vue'
import { addOrUpdatePractice, addOrUpdateArticle } from '@/api'
import type { AddOrUpdatePracticeDto } from '@/api/practice/types'
import type { AddOrUpdatePracticeDto } from '@/api'
import type { BooleanFlag } from '@/constants'
type ArticleType = ArticleTypeEnum.QUESTION | ArticleTypeEnum.PRACTICE
const { type } = defineProps<{
const { type, isReal } = defineProps<{
type: ArticleType
isReal: BooleanFlag
}>()
const textMap: Record<
......@@ -185,6 +187,7 @@ const { tagList } = storeToRefs(tagsStore)
const userStore = useUserStore()
const { userInfo } = storeToRefs(userStore)
const userAvatar = computed(() => (isReal ? userInfo.value.avatar : userInfo.value.hiddenAvatar))
const selectTagsDialogRef =
useTemplateRef<InstanceType<typeof SelectTagsDialog>>('selectTagsDialogRef')
......
......@@ -106,13 +106,18 @@ const formatSeconds = computed(() => {
onMounted(async () => {
const { data } = await getTodayOnlineSeconds()
heartbeat()
currentSeconds.value = data
})
setInterval(() => {
const timer1 = setInterval(() => {
currentSeconds.value++
}, 1000)
setInterval(async () => {
const timer2 = setInterval(async () => {
heartbeat()
}, 1000 * 30)
onUnmounted(() => {
clearInterval(timer1)
clearInterval(timer2)
})
</script>
......@@ -107,7 +107,7 @@
</div>
</div>
</div>
<OnlineTime />
<OnlineTime v-if="showOnlineTime" />
<PublishDialog ref="PublishDialogRef" />
</template>
......@@ -145,6 +145,10 @@ const getSecondLevelKey = (route: RouteLocationNormalizedLoadedGeneric) => {
return key
}
const showOnlineTime = computed(() => {
return !route.path.includes('/videoDetail') && !route.path.includes('/articleDetail')
})
const handlePost = async (type: ArticleTypeEnum) => {
if (type === ArticleTypeEnum.VIDEO) {
router.push('/publishVideo')
......
......@@ -13,7 +13,7 @@
<!-- 主要内容区域 -->
<div class="mx-auto pt-6">
<PublishBox :type="ArticleTypeEnum.QUESTION" ref="publishBoxRef" />
<PublishBox :type="ArticleTypeEnum.QUESTION" ref="publishBoxRef" :isReal="0" />
<div v-loading="loading" v-if="list.length">
<!-- 问题列表 -->
<div class="space-y-4">
......@@ -298,9 +298,6 @@ const isOverThreeLine = (index: number) => {
const handleExpand = (item: ArticleItemDto) => {
item.isExpand = !item.isExpand
}
setInterval(() => {
console.log(contentRefList.value)
}, 3000)
// 是否打开漫游
watch(
......
<template>
<div>
<!-- 发布区域 -->
<PublishPractice :type="ArticleTypeEnum.PRACTICE" />
<PublishPractice :type="ArticleTypeEnum.PRACTICE" :isReal="1" />
<!-- 标签导航 -->
<div class="bg-white p-4 mb-6 rounded-lg shadow-sm">
......
......@@ -31,7 +31,7 @@
<span class="mr-2">
{{ dayjs(item.createTime * 1000).format('YYYY-MM-DD HH:mm:ss') }}
</span>
<span class="mr-2">评论 {{ item.collectionCount }}</span>
<!-- <span class="mr-2">评论 {{ item.collectionCount }}</span> -->
</div>
</div>
......
......@@ -4,12 +4,30 @@
<div class="box relative h-200px bg-gradient-to-r from-purple-400 via-pink-300 to-blue-300">
<!-- 顶部操作按钮 -->
<div class="absolute top-4 right-4 flex gap-2">
<el-button v-if="!userInfo.isOfficialAccount" type="info" plain size="small"
@click="handleClearCache">清除缓存</el-button>
<el-button v-if="officialAccountList.length" type="info" plain size="small"
@click="handleSwitchAccount">切换账号</el-button>
<el-button v-if="userInfo.isOfficialAccount" type="info" plain size="small"
@click="handleBackUser">返回个人账号</el-button>
<el-button
v-if="!userInfo.isOfficialAccount"
type="info"
plain
size="small"
@click="handleClearCache"
>清除缓存</el-button
>
<el-button
v-if="officialAccountList.length"
type="info"
plain
size="small"
@click="handleSwitchAccount"
>切换账号</el-button
>
<el-button
v-if="userInfo.isOfficialAccount"
type="info"
plain
size="small"
@click="handleBackUser"
>返回个人账号</el-button
>
<!-- v-if="userInfo.isAdmin" 暂时不加权限 -->
<el-button type="primary" plain size="small" @click="handleAdmin">后台管理</el-button>
</div>
......@@ -22,23 +40,40 @@
<div class="w-300px">
<!-- 个人信息卡片 -->
<transition name="slide-fade" mode="out-in">
<div :key="isReal" class="bg-white rounded-lg shadow-sm p-6 mb-4 relative">
<!-- 右上角实时切换按钮 -->
<el-link size="small" type="primary" :underline="false" plain class="absolute! right-4 top-4"
@click="isReal = isReal ? 0 : 1">
<div
:key="isReal"
class="bg-white rounded-lg shadow-sm p-6 mb-4 relative overflow-hidden"
>
<div
class="absolute -right-9 top-3 bg-blue-500 text-white text-xs px-10 py-1 rotate-45 cursor-pointer shadow-md hover:from-blue-600 hover:to-blue-700 transition-all"
@click="isReal = isReal ? 0 : 1"
>
切换{{ isReal ? '匿名' : '实名' }}
</el-link>
<!-- 卡片内容切换动画 -->
</div>
<!-- 内容区域 -->
<div class="flex items-start gap-4">
<el-avatar :size="80" :src="userInfo?.avatar" class="border-4 border-white shadow-lg" />
<div class="flex-1">
<h2 class="text-xl font-semibold text-gray-800 mb-1">{{ userInfo?.name }}</h2>
<p class="text-gray-500 text-sm mb-2">{{ userInfo?.signature }}</p>
<el-button type="warning" size="small" plain @click="handleEdit">
<el-icon>
<Edit />
</el-icon>
<el-avatar
:size="80"
:src="currentUserInfo.avatar"
class="border-4 border-white shadow-lg flex-shrink-0"
/>
<div class="flex-1 min-w-0">
<el-tooltip :content="currentUserInfo.name" placement="top">
<span class="text-xl font-semibold text-gray-800 mb-1 truncate">
{{ currentUserInfo.name }}
</span>
</el-tooltip>
<el-tooltip :content="currentUserInfo.signature" placement="right">
<span class="text-gray-500 text-sm mb-3 line-clamp-2">
{{ currentUserInfo.signature }}
</span>
</el-tooltip>
<el-button v-if="!isReal" type="warning" size="small" plain @click="handleEdit">
<el-icon><Edit /></el-icon>
修改资料
</el-button>
</div>
......@@ -48,12 +83,17 @@
<!-- 左侧菜单 ——个人菜单 -->
<div class="bg-white rounded-lg shadow-sm mb-4">
<div v-for="item in menuUserItems" :key="item.path" @click="changeMenu(item.path)" :class="[
'flex items-center gap-3 px-4 py-3 cursor-pointer transition-colors border-b border-gray-100 last:border-b-0',
activeMenu === item.path
? 'bg-blue-50 text-blue-600 border-r-3 border-r-blue-600'
: 'text-gray-700 hover:bg-gray-50',
]">
<div
v-for="item in menuUserItems"
:key="item.path"
@click="changeMenu(item.path)"
:class="[
'flex items-center gap-3 px-4 py-3 cursor-pointer transition-colors border-b border-gray-100 last:border-b-0',
activeMenu === item.path
? 'bg-blue-50 text-blue-600 border-r-3 border-r-blue-600'
: 'text-gray-700 hover:bg-gray-50',
]"
>
<el-icon :size="16">
<component :is="item.icon" />
</el-icon>
......@@ -62,12 +102,17 @@
</div>
<!-- 左侧菜单 —— 官方账号菜单 审核操作等 -->
<div class="bg-white rounded-lg shadow-sm">
<div v-for="item in menuOfficialItems" :key="item.path" @click="changeMenu(item.path)" :class="[
'flex items-center gap-3 px-4 py-3 cursor-pointer transition-colors border-b border-gray-100 last:border-b-0',
activeMenu === item.path
? 'bg-blue-50 text-blue-600 border-r-3 border-r-blue-600'
: 'text-gray-700 hover:bg-gray-50',
]">
<div
v-for="item in menuOfficialItems"
:key="item.path"
@click="changeMenu(item.path)"
:class="[
'flex items-center gap-3 px-4 py-3 cursor-pointer transition-colors border-b border-gray-100 last:border-b-0',
activeMenu === item.path
? 'bg-blue-50 text-blue-600 border-r-3 border-r-blue-600'
: 'text-gray-700 hover:bg-gray-50',
]"
>
<el-icon :size="16">
<component :is="item.icon" />
</el-icon>
......@@ -182,6 +227,19 @@ const menuOfficialItems = [
]
const isReal = ref(1)
const currentUserInfo = computed(() =>
isReal.value
? {
avatar: userInfo.value.avatar,
name: userInfo.value.name,
signature: '',
}
: {
avatar: userInfo.value.hiddenAvatar,
name: userInfo.value.hiddenName,
signature: userInfo.value.signature,
},
)
const changeMenu = (key: TabPaneName) => {
router.push(`/userPage/${key}`)
......@@ -190,9 +248,9 @@ const changeMenu = (key: TabPaneName) => {
const handleEdit = () => {
console.log('修改资料')
editUserInfoRef.value?.open({
hiddenAvatar: userInfo.value.avatar,
hiddenName: userInfo.value.name,
signature: '',
hiddenAvatar: userInfo.value.hiddenAvatar,
hiddenName: userInfo.value.hiddenName,
signature: userInfo.value.signature,
})
}
......@@ -327,9 +385,9 @@ onMounted(() => {
.slide-fade-enter-active {
transition:
opacity .6s cubic-bezier(0.22, 1, 0.36, 1),
transform .6s cubic-bezier(0.22, 1, 0.36, 1),
filter .6s ease;
opacity 0.6s cubic-bezier(0.22, 1, 0.36, 1),
transform 0.6s cubic-bezier(0.22, 1, 0.36, 1),
filter 0.6s ease;
transform-style: preserve-3d;
}
......@@ -337,7 +395,7 @@ onMounted(() => {
opacity: 1;
transform: translateY(0) rotateY(0deg) translateZ(0) scale(1);
filter: blur(0);
box-shadow: 0 15px 40px rgba(0, 0, 0, .18);
/* box-shadow: 0 15px 40px rgba(0, 0, 0, 0.18); */
}
.slide-fade-leave-from {
......@@ -348,9 +406,9 @@ onMounted(() => {
.slide-fade-leave-active {
transition:
opacity .5s cubic-bezier(0.55, 0, 0.55, 0.2),
transform .5s cubic-bezier(0.55, 0, 0.55, 0.2),
filter .4s;
opacity 0.5s cubic-bezier(0.55, 0, 0.55, 0.2),
transform 0.5s cubic-bezier(0.55, 0, 0.55, 0.2),
filter 0.4s;
transform-style: preserve-3d;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment