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
a30e1e03
Commit
a30e1e03
authored
Dec 08, 2025
by
lijiabin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
【需求 17679】 feat: 继续完善
parent
37e7420a
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
97 additions
and
112 deletions
+97
-112
index.vue
src/components/common/ArticleContent/index.vue
+1
-1
index.vue
src/views/otherUserPage/index.vue
+33
-60
index.vue
src/views/userPage/index.vue
+63
-51
No files found.
src/components/common/ArticleContent/index.vue
View file @
a30e1e03
...
@@ -113,6 +113,6 @@ const articleType = computed(() => {
...
@@ -113,6 +113,6 @@ const articleType = computed(() => {
})
})
const
isHtml
=
computed
(()
=>
{
const
isHtml
=
computed
(()
=>
{
return
articleDetail
.
content
.
includes
(
'<'
)
||
articleDetail
.
content
.
includes
(
'</'
)
return
articleDetail
.
content
?.
includes
(
'<'
)
||
articleDetail
.
content
?
.
includes
(
'</'
)
})
})
</
script
>
</
script
>
src/views/otherUserPage/index.vue
View file @
a30e1e03
...
@@ -4,30 +4,12 @@
...
@@ -4,30 +4,12 @@
<div
class=
"box relative h-200px bg-gradient-to-r from-purple-400 via-pink-300 to-blue-300"
>
<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"
>
<div
class=
"absolute top-4 right-4 flex gap-2"
>
<el-button
<el-button
v-if=
"!userInfo.isOfficialAccount"
type=
"info"
plain
size=
"small"
v-if=
"!userInfo.isOfficialAccount"
@
click=
"handleClearCache"
>
清除缓存
</el-button>
type=
"info"
<el-button
v-if=
"officialAccountList.length"
type=
"info"
plain
size=
"small"
plain
@
click=
"handleSwitchAccount"
>
切换账号
</el-button>
size=
"small"
<el-button
v-if=
"userInfo.isOfficialAccount"
type=
"info"
plain
size=
"small"
@
click=
"handleClearCache"
@
click=
"handleBackUser"
>
返回个人账号
</el-button>
>
清除缓存
</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" 暂时不加权限 -->
<!-- v-if="userInfo.isAdmin" 暂时不加权限 -->
<el-button
type=
"primary"
plain
size=
"small"
@
click=
"handleAdmin"
>
后台管理
</el-button>
<el-button
type=
"primary"
plain
size=
"small"
@
click=
"handleAdmin"
>
后台管理
</el-button>
</div>
</div>
...
@@ -41,16 +23,14 @@
...
@@ -41,16 +23,14 @@
<!-- 个人信息卡片 -->
<!-- 个人信息卡片 -->
<div
class=
"bg-white rounded-lg shadow-sm p-6 mb-4"
>
<div
class=
"bg-white rounded-lg shadow-sm p-6 mb-4"
>
<div
class=
"flex items-start gap-4"
>
<div
class=
"flex items-start gap-4"
>
<el-avatar
<el-avatar
:size=
"80"
:src=
"userInfo?.avatar"
class=
"border-4 border-white shadow-lg"
/>
:size=
"80"
:src=
"userInfo?.avatar"
class=
"border-4 border-white shadow-lg"
/>
<div
class=
"flex-1"
>
<div
class=
"flex-1"
>
<h2
class=
"text-xl font-semibold text-gray-800 mb-1"
>
{{
userInfo
?.
name
}}
</h2>
<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>
<p
class=
"text-gray-500 text-sm mb-2"
>
{{
userInfo
?.
signature
}}
</p>
<el-button
type=
"warning"
size=
"small"
plain
@
click=
"handleEdit"
>
<el-button
type=
"warning"
size=
"small"
plain
@
click=
"handleEdit"
>
<el-icon><Edit
/></el-icon>
<el-icon>
<Edit
/>
</el-icon>
修改资料
修改资料
</el-button>
</el-button>
</div>
</div>
...
@@ -61,24 +41,25 @@
...
@@ -61,24 +41,25 @@
<div
class=
"bg-white rounded-lg shadow-sm mb-4"
>
<div
class=
"bg-white rounded-lg shadow-sm mb-4"
>
<div
v-if=
"!list.length"
class=
"flex flex-col items-center justify-center h-64"
>
<div
v-if=
"!list.length"
class=
"flex flex-col items-center justify-center h-64"
>
<div
class=
"w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center mb-4"
>
<div
class=
"w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center mb-4"
>
<el-icon
class=
"text-2xl text-gray-300"
><Document
/></el-icon>
<el-icon
class=
"text-2xl text-gray-300"
>
<Document
/>
</el-icon>
</div>
</div>
<div
class=
"text-gray-500 text-lg mb-2"
>
暂无内容
</div>
<div
class=
"text-gray-500 text-lg mb-2"
>
暂无内容
</div>
</div>
</div>
<div
v-else
class=
"space-y-4"
>
<div
v-else
class=
"space-y-4"
>
<div
<div
v-for=
"item in list"
:key=
"item.id"
v-for=
"item in list"
class=
"flex items-center p-2 rounded-lg hover:bg-gray-100 transition-colors cursor-pointer px-6"
>
:key=
"item.id"
class=
"flex items-center p-2 rounded-lg hover:bg-gray-100 transition-colors cursor-pointer"
>
<div
class=
"flex-1 min-w-0"
>
<div
class=
"flex-1 min-w-0"
>
<div
class=
"text-gray-900 font-medium truncate"
>
{{
item
.
title
}}
</div>
<div
class=
"text-gray-900 font-medium truncate"
>
{{
item
.
title
||
'测试标题'
}}
</div>
<div
class=
"text-gray-500 text-sm mt-1 truncate"
>
<div
class=
"text-gray-500 text-sm mt-1 truncate"
>
<span
class=
"mr-2"
>
<span
class=
"mr-2"
>
{{
dayjs
(
item
.
createTime
*
1000
).
format
(
'YYYY-MM-DD HH:mm:ss'
)
}}
{{
dayjs
(
item
.
createTime
*
1000
).
format
(
'YYYY-MM-DD HH:mm:ss'
)
}}
</span>
</span>
<span
class=
"mr-2"
>
评论
{{
item
.
collectionCount
}}
</span>
<span
class=
"mr-2"
>
评论
{{
item
.
collectionCount
||
0
}}
</span>
<span
class=
"mr-2"
>
点赞
{{
item
.
collectionCount
||
0
}}
</span>
<span
class=
"mr-2"
>
收藏
{{
item
.
collectionCount
||
0
}}
</span>
</div>
</div>
</div>
</div>
...
@@ -87,13 +68,13 @@
...
@@ -87,13 +68,13 @@
去回复
去回复
</el-button>
</el-button>
</div>
</div>
<!--
<el-divider
/>
-->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<EditUserInfo
ref=
"editUserInfoRef"
/>
</div>
</div>
</
template
>
</
template
>
...
@@ -101,9 +82,8 @@
...
@@ -101,9 +82,8 @@
import
{
Document
}
from
'@element-plus/icons-vue'
import
{
Document
}
from
'@element-plus/icons-vue'
import
{
useUserStore
}
from
'@/stores/user'
import
{
useUserStore
}
from
'@/stores/user'
import
{
storeToRefs
}
from
'pinia'
import
{
storeToRefs
}
from
'pinia'
import
EditUserInfo
from
'./components/editUserInfo.vue'
import
{
generateLoginKey
,
hasOfficialAccount
}
from
'@/api'
import
{
generateLoginKey
,
hasOfficialAccount
,
getOtherUserData
,
getOtherUserPostData
}
from
'@/api'
import
type
{
OfficialAccountItemDto
}
from
'@/api/user/types'
import
type
{
OfficialAccountItemDto
}
from
'@/api/user/types'
import
{
wxLogin
}
from
'@/utils/wxUtil'
import
{
wxLogin
}
from
'@/utils/wxUtil'
import
dayjs
from
'dayjs'
import
dayjs
from
'dayjs'
...
@@ -112,18 +92,9 @@ const route = useRoute()
...
@@ -112,18 +92,9 @@ const route = useRoute()
const
list
=
[{},
{}]
const
list
=
[{},
{}]
const
editUserInfoRef
=
useTemplateRef
<
InstanceType
<
typeof
EditUserInfo
>>
(
'editUserInfoRef'
)
const
userStore
=
useUserStore
()
const
userStore
=
useUserStore
()
const
{
userInfo
}
=
storeToRefs
(
userStore
)
const
{
userInfo
}
=
storeToRefs
(
userStore
)
const
handleEdit
=
()
=>
{
console
.
log
(
'修改资料'
)
editUserInfoRef
.
value
?.
open
({
hiddenAvatar
:
userInfo
.
value
.
avatar
,
hiddenName
:
userInfo
.
value
.
name
,
signature
:
''
,
})
}
const
officialAccountList
=
ref
<
OfficialAccountItemDto
[]
>
([])
const
officialAccountList
=
ref
<
OfficialAccountItemDto
[]
>
([])
const
getIsOfficial
=
async
()
=>
{
const
getIsOfficial
=
async
()
=>
{
...
@@ -132,16 +103,16 @@ const getIsOfficial = async () => {
...
@@ -132,16 +103,16 @@ const getIsOfficial = async () => {
officialAccountList
.
value
=
data
officialAccountList
.
value
=
data
}
}
onMounted
(()
=>
{
onMounted
(()
=>
{
getOtherUserData
({
//
getOtherUserData({
userId
:
route
.
params
.
userId
as
string
,
//
userId: route.params.userId as string,
isReal
:
1
,
//
isReal: 1,
})
//
})
getOtherUserPostData
({
//
getOtherUserPostData({
userId
:
route
.
params
.
userId
as
string
,
//
userId: route.params.userId as string,
isReal
:
1
,
//
isReal: 1,
current
:
1
,
//
current: 1,
size
:
10
,
//
size: 10,
})
//
})
})
})
const
handleSwitchAccount
=
async
()
=>
{
const
handleSwitchAccount
=
async
()
=>
{
const
selectedEmail
=
ref
(
''
)
const
selectedEmail
=
ref
(
''
)
...
@@ -259,11 +230,13 @@ onMounted(() => {
...
@@ -259,11 +230,13 @@ onMounted(() => {
.box
{
.box
{
background-image
:
url('http://soundasia.oss-cn-shenzhen.aliyuncs.com/OA/2022/10/13/1665643787806.jpg')
;
background-image
:
url('http://soundasia.oss-cn-shenzhen.aliyuncs.com/OA/2022/10/13/1665643787806.jpg')
;
}
}
/* 如果需要额外的样式可以在这里添加 */
/* 如果需要额外的样式可以在这里添加 */
.fade-enter-active
,
.fade-enter-active
,
.fade-leave-active
{
.fade-leave-active
{
transition
:
opacity
0.5s
ease
;
transition
:
opacity
0.5s
ease
;
}
}
.fade-enter-from
,
.fade-enter-from
,
.fade-leave-to
{
.fade-leave-to
{
opacity
:
0
;
opacity
:
0
;
...
...
src/views/userPage/index.vue
View file @
a30e1e03
...
@@ -4,30 +4,12 @@
...
@@ -4,30 +4,12 @@
<div
class=
"box relative h-200px bg-gradient-to-r from-purple-400 via-pink-300 to-blue-300"
>
<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"
>
<div
class=
"absolute top-4 right-4 flex gap-2"
>
<el-button
<el-button
v-if=
"!userInfo.isOfficialAccount"
type=
"info"
plain
size=
"small"
v-if=
"!userInfo.isOfficialAccount"
@
click=
"handleClearCache"
>
清除缓存
</el-button>
type=
"info"
<el-button
v-if=
"officialAccountList.length"
type=
"info"
plain
size=
"small"
plain
@
click=
"handleSwitchAccount"
>
切换账号
</el-button>
size=
"small"
<el-button
v-if=
"userInfo.isOfficialAccount"
type=
"info"
plain
size=
"small"
@
click=
"handleClearCache"
@
click=
"handleBackUser"
>
返回个人账号
</el-button>
>
清除缓存
</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" 暂时不加权限 -->
<!-- v-if="userInfo.isAdmin" 暂时不加权限 -->
<el-button
type=
"primary"
plain
size=
"small"
@
click=
"handleAdmin"
>
后台管理
</el-button>
<el-button
type=
"primary"
plain
size=
"small"
@
click=
"handleAdmin"
>
后台管理
</el-button>
</div>
</div>
...
@@ -39,37 +21,39 @@
...
@@ -39,37 +21,39 @@
<!-- 左侧个人信息卡片 -->
<!-- 左侧个人信息卡片 -->
<div
class=
"w-300px"
>
<div
class=
"w-300px"
>
<!-- 个人信息卡片 -->
<!-- 个人信息卡片 -->
<div
class=
"bg-white rounded-lg shadow-sm p-6 mb-4"
>
<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"
>
切换
{{
isReal
?
'匿名'
:
'实名'
}}
</el-link>
<!-- 卡片内容切换动画 -->
<div
class=
"flex items-start gap-4"
>
<div
class=
"flex items-start gap-4"
>
<el-avatar
<el-avatar
:size=
"80"
:src=
"userInfo?.avatar"
class=
"border-4 border-white shadow-lg"
/>
:size=
"80"
:src=
"userInfo?.avatar"
class=
"border-4 border-white shadow-lg"
/>
<div
class=
"flex-1"
>
<div
class=
"flex-1"
>
<h2
class=
"text-xl font-semibold text-gray-800 mb-1"
>
{{
userInfo
?.
name
}}
</h2>
<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>
<p
class=
"text-gray-500 text-sm mb-2"
>
{{
userInfo
?.
signature
}}
</p>
<el-button
type=
"warning"
size=
"small"
plain
@
click=
"handleEdit"
>
<el-button
type=
"warning"
size=
"small"
plain
@
click=
"handleEdit"
>
<el-icon><Edit
/></el-icon>
<el-icon>
<Edit
/>
</el-icon>
修改资料
修改资料
</el-button>
</el-button>
</div>
</div>
</div>
</div>
</div>
</div>
</transition>
<!-- 左侧菜单 ——个人菜单 -->
<!-- 左侧菜单 ——个人菜单 -->
<div
class=
"bg-white rounded-lg shadow-sm mb-4"
>
<div
class=
"bg-white rounded-lg shadow-sm mb-4"
>
<div
<div
v-for=
"item in menuUserItems"
:key=
"item.path"
@
click=
"changeMenu(item.path)"
:class=
"[
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',
'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
activeMenu === item.path
? 'bg-blue-50 text-blue-600 border-r-3 border-r-blue-600'
? 'bg-blue-50 text-blue-600 border-r-3 border-r-blue-600'
: 'text-gray-700 hover:bg-gray-50',
: 'text-gray-700 hover:bg-gray-50',
]"
]"
>
>
<el-icon
:size=
"16"
>
<el-icon
:size=
"16"
>
<component
:is=
"item.icon"
/>
<component
:is=
"item.icon"
/>
</el-icon>
</el-icon>
...
@@ -78,17 +62,12 @@
...
@@ -78,17 +62,12 @@
</div>
</div>
<!-- 左侧菜单 —— 官方账号菜单 审核操作等 -->
<!-- 左侧菜单 —— 官方账号菜单 审核操作等 -->
<div
class=
"bg-white rounded-lg shadow-sm"
>
<div
class=
"bg-white rounded-lg shadow-sm"
>
<div
<div
v-for=
"item in menuOfficialItems"
:key=
"item.path"
@
click=
"changeMenu(item.path)"
:class=
"[
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',
'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
activeMenu === item.path
? 'bg-blue-50 text-blue-600 border-r-3 border-r-blue-600'
? 'bg-blue-50 text-blue-600 border-r-3 border-r-blue-600'
: 'text-gray-700 hover:bg-gray-50',
: 'text-gray-700 hover:bg-gray-50',
]"
]"
>
>
<el-icon
:size=
"16"
>
<el-icon
:size=
"16"
>
<component
:is=
"item.icon"
/>
<component
:is=
"item.icon"
/>
</el-icon>
</el-icon>
...
@@ -202,6 +181,8 @@ const menuOfficialItems = [
...
@@ -202,6 +181,8 @@ const menuOfficialItems = [
},
},
]
]
const
isReal
=
ref
(
1
)
const
changeMenu
=
(
key
:
TabPaneName
)
=>
{
const
changeMenu
=
(
key
:
TabPaneName
)
=>
{
router
.
push
(
`/userPage/
${
key
}
`
)
router
.
push
(
`/userPage/
${
key
}
`
)
}
}
...
@@ -338,13 +319,44 @@ onMounted(() => {
...
@@ -338,13 +319,44 @@ onMounted(() => {
.box
{
.box
{
background-image
:
url('http://soundasia.oss-cn-shenzhen.aliyuncs.com/OA/2022/10/13/1665643787806.jpg')
;
background-image
:
url('http://soundasia.oss-cn-shenzhen.aliyuncs.com/OA/2022/10/13/1665643787806.jpg')
;
}
}
/* 如果需要额外的样式可以在这里添加 */
.slide-fade-enter-from
{
.fade-enter-active
,
opacity
:
0
;
.fade-leave-active
{
transform
:
translateY
(
20px
)
rotateY
(
-10deg
)
translateZ
(
-300px
)
scale
(
0.95
);
transition
:
opacity
0.5s
ease
;
filter
:
blur
(
6px
);
}
.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
;
transform-style
:
preserve-3d
;
}
.slide-fade-enter-to
{
opacity
:
1
;
transform
:
translateY
(
0
)
rotateY
(
0deg
)
translateZ
(
0
)
scale
(
1
);
filter
:
blur
(
0
);
box-shadow
:
0
15px
40px
rgba
(
0
,
0
,
0
,
.18
);
}
}
.fade-enter-from
,
.fade-leave-to
{
.slide-fade-leave-from
{
opacity
:
1
;
transform
:
translateY
(
0
)
rotateY
(
0deg
)
translateZ
(
0
)
scale
(
1
);
filter
:
blur
(
0
);
}
.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
;
transform-style
:
preserve-3d
;
}
.slide-fade-leave-to
{
opacity
:
0
;
opacity
:
0
;
transform
:
translateY
(
-20px
)
rotateY
(
10deg
)
translateZ
(
200px
)
scale
(
0.9
);
filter
:
blur
(
6px
);
}
}
</
style
>
</
style
>
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