Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
corporateCulture-qd
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
王立鹏
corporateCulture-qd
Commits
6c5db609
Commit
6c5db609
authored
Dec 09, 2025
by
lijiabin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
【需求 17679】 feat: 优化实名匿名部分等
parent
db74b8dc
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
122 additions
and
55 deletions
+122
-55
App.vue
src/App.vue
+1
-4
types.ts
src/api/login/types.ts
+3
-0
index.vue
src/components/common/ArticleContent/index.vue
+1
-1
index.vue
src/components/common/Comment/index.vue
+3
-3
index.vue
src/components/common/PublishBox/index.vue
+6
-3
onlineTime.vue
src/layoutCulture/components/onlineTime.vue
+7
-2
index.vue
src/layoutCulture/index.vue
+5
-1
index.vue
src/views/homePage/askTab/index.vue
+1
-4
practiceList.vue
src/views/homePage/yaTab/components/practiceList.vue
+1
-1
selfAnswer.vue
src/views/userPage/components/selfAnswer.vue
+1
-1
index.vue
src/views/userPage/index.vue
+93
-35
No files found.
src/App.vue
View file @
6c5db609
...
...
@@ -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
(()
=>
{
...
...
src/api/login/types.ts
View file @
6c5db609
...
...
@@ -27,4 +27,7 @@ export interface LoginResponseDto {
accountNonLocked
:
boolean
token
:
string
userId
:
number
hiddenAvatar
:
string
hiddenName
:
string
signature
:
string
}
src/components/common/ArticleContent/index.vue
View file @
6c5db609
...
...
@@ -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
...
...
src/components/common/Comment/index.vue
View file @
6c5db609
...
...
@@ -60,7 +60,7 @@
<!-- 发表评论 -->
<div
class=
"p-4 border-b border-gray-100"
>
<div
class=
"flex gap-3"
>
<img
:src=
"user
Info?.a
vatar"
alt=
""
class=
"w-10 h-10 rounded-full object-cover"
/>
<img
:src=
"user
A
vatar"
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=
"user
Info?.a
vatar"
alt=
""
class=
"w-10 h-10 rounded-full object-cover"
/>
<img
:src=
"user
A
vatar"
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
}
`
)
}
...
...
src/components/common/PublishBox/index.vue
View file @
6c5db609
...
...
@@ -4,7 +4,7 @@
<!-- 主输入区域 -->
<div
class=
"flex gap-3 mb-4 items-start"
>
<!-- 用户头像 -->
<el-avatar
:size=
"48"
:src=
"user
Info.a
vatar"
class=
"flex-shrink-0"
>
<el-avatar
:size=
"48"
:src=
"user
A
vatar"
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'
)
...
...
src/layoutCulture/components/onlineTime.vue
View file @
6c5db609
...
...
@@ -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
>
src/layoutCulture/index.vue
View file @
6c5db609
...
...
@@ -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'
)
...
...
src/views/homePage/askTab/index.vue
View file @
6c5db609
...
...
@@ -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
(
...
...
src/views/homePage/yaTab/components/practiceList.vue
View file @
6c5db609
<
template
>
<div>
<!-- 发布区域 -->
<PublishPractice
:type=
"ArticleTypeEnum.PRACTICE"
/>
<PublishPractice
:type=
"ArticleTypeEnum.PRACTICE"
:isReal=
"1"
/>
<!-- 标签导航 -->
<div
class=
"bg-white p-4 mb-6 rounded-lg shadow-sm"
>
...
...
src/views/userPage/components/selfAnswer.vue
View file @
6c5db609
...
...
@@ -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>
...
...
src/views/userPage/index.vue
View file @
6c5db609
...
...
@@ -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=
"[
<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=
"[
<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
.
a
vatar
,
hiddenName
:
userInfo
.
value
.
n
ame
,
signature
:
''
,
hiddenAvatar
:
userInfo
.
value
.
hiddenA
vatar
,
hiddenName
:
userInfo
.
value
.
hiddenN
ame
,
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
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment