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
97019bbf
Commit
97019bbf
authored
Dec 30, 2025
by
lijiabin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
【需求 17679】 feat: 我的页面完成案例库页面,上传文件增加cacel功能等
parent
f0fed940
Show whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
421 additions
and
67 deletions
+421
-67
index.ts
src/api/case/index.ts
+21
-1
types.ts
src/api/case/types.ts
+13
-0
index.ts
src/api/common/index.ts
+31
-11
index.ts
src/api/user/index.ts
+3
-2
types.ts
src/api/user/types.ts
+7
-0
index.vue
src/components/common/ArticleContent/index.vue
+1
-1
index.vue
src/components/common/PublishBox/index.vue
+4
-2
index.vue
src/components/common/UploadFile/index.vue
+6
-3
index.vue
src/components/common/UploadVideo/index.vue
+26
-5
index.vue
src/components/common/WangEditor/index.vue
+3
-3
index.vue
src/views/publishCase/index.vue
+43
-6
index.vue
src/views/publishLongArticle/index.vue
+1
-0
index.vue
src/views/publishVideo/index.vue
+18
-7
SelfComplaint.vue
src/views/userPage/components/SelfComplaint.vue
+3
-1
selfAnswer.vue
src/views/userPage/components/selfAnswer.vue
+5
-2
selfAudit.vue
src/views/userPage/components/selfAudit.vue
+1
-1
selfCase.vue
src/views/userPage/components/selfCase.vue
+210
-7
selfCollect.vue
src/views/userPage/components/selfCollect.vue
+5
-4
selfComment.vue
src/views/userPage/components/selfComment.vue
+1
-1
selfDraft.vue
src/views/userPage/components/selfDraft.vue
+2
-1
selfPraise.vue
src/views/userPage/components/selfPraise.vue
+2
-1
selfPublish.vue
src/views/userPage/components/selfPublish.vue
+5
-4
index.vue
src/views/userPage/index.vue
+2
-2
index.vue
src/views/videoDetail/index.vue
+8
-2
No files found.
src/api/case/index.ts
View file @
97019bbf
import
service
from
'@/utils/request/index'
import
type
{
AddOrUpdateCaseDto
}
from
'./types'
import
type
{
AddOrUpdateCaseDto
,
CaseDetailDto
}
from
'./types'
// 案例库相关的接口
...
...
@@ -24,3 +24,23 @@ export const addOrUpdateCase = (data: AddOrUpdateCaseDto) => {
data
,
})
}
/**
* 获取案例详情
*/
export
const
getCaseDetail
=
(
id
:
number
)
=>
{
return
service
.
request
<
CaseDetailDto
>
({
url
:
`/api/cultureCase/getCaseDetail?caseId=
${
id
}
`
,
method
:
'POST'
,
})
}
/**
* 删除案例库
*/
export
const
deleteCase
=
(
id
:
number
)
=>
{
return
service
.
request
({
url
:
`/api/cultureCase/deleteCase?id=
${
id
}
`
,
method
:
'POST'
,
})
}
src/api/case/types.ts
View file @
97019bbf
...
...
@@ -19,3 +19,16 @@ export interface AddOrUpdateCaseDto {
tagRelationDtoList
:
TagItemDto
[]
title
:
string
}
export
interface
CaseDetailDto
{
id
:
number
title
:
string
content
:
string
caseTags
:
TagItemDto
[]
depIdList
:
number
[]
depNameList
:
string
[]
isSync
:
BooleanFlag
cultureKeywordMain
:
string
cultureKeywordSub
:
string
[]
sceneKeywordMain
:
string
sceneKeywordSub
:
string
[]
}
src/api/common/index.ts
View file @
97019bbf
...
...
@@ -21,10 +21,8 @@
/**
* 暂时调用oa正式接口
*/
import
axios
from
'axios'
type
UploadFileResponse
=
{
data
:
{
data
:
{
import
axios
,
{
type
AxiosRequestConfig
}
from
'axios'
type
UploadFileResponseItem
=
{
createTime
:
string
createUser
:
number
fileBucket
:
string
...
...
@@ -37,19 +35,41 @@ type UploadFileResponse = {
realPath
:
string
updateTime
:
string
updateUser
:
string
}[]
}
}
// 单个文件上传
export
const
uploadFile
=
(
file
:
File
,
onProgress
?:
(
progress
:
number
)
=>
void
,
):
Promise
<
UploadFileResponse
>
=>
{
options
:
{
onProgress
?:
(
progress
:
number
)
=>
void
}
=
{},
):
{
cancel
:
()
=>
void
promise
:
Promise
<
UploadFileResponseItem
>
}
=>
{
const
formData
=
new
FormData
()
formData
.
append
(
'fileList'
,
file
)
return
axios
.
post
(
'http://47.112.96.71:8082/mobiles/uploadFile'
,
formData
,
{
onUploadProgress
:
(
progressEvent
)
=>
{
const
{
onProgress
}
=
options
const
controller
=
new
AbortController
()
const
axiosOptions
:
AxiosRequestConfig
=
{
signal
:
controller
.
signal
,
}
if
(
onProgress
)
{
axiosOptions
.
onUploadProgress
=
(
progressEvent
)
=>
{
const
percentCompleted
=
Math
.
round
((
progressEvent
.
loaded
*
100
)
/
(
progressEvent
.
total
||
1
))
onProgress
?.(
percentCompleted
)
}
}
return
{
cancel
:
()
=>
{
controller
.
abort
()
},
})
promise
:
axios
.
post
(
'http://47.112.96.71:8082/mobiles/uploadFile'
,
formData
,
axiosOptions
)
.
then
((
data
)
=>
data
.
data
.
data
[
0
]
as
UploadFileResponseItem
),
}
}
src/api/user/index.ts
View file @
97019bbf
...
...
@@ -20,8 +20,9 @@ import type {
ComplaintListItemDto
,
AuditComplaintDto
,
ComplaintListSearchParams
,
SelfCaseSearchParams
,
}
from
'./types'
import
type
{
BackendServicePageResult
,
PageSearchParams
}
from
'@/utils/request/types'
import
type
{
BackendServicePageResult
}
from
'@/utils/request/types'
/**
* 更新用户信息
...
...
@@ -92,7 +93,7 @@ export const getSelfPraiseList = (data: SelfPraiseSearchParams) => {
/**
* 获取我的案例库列表
*/
export
const
getSelfCaseList
=
(
data
:
Pag
eSearchParams
)
=>
{
export
const
getSelfCaseList
=
(
data
:
SelfCas
eSearchParams
)
=>
{
return
service
.
request
<
BackendServicePageResult
<
SelfCaseItemDto
>>
({
url
:
'/api/personalCenter/selfCase'
,
method
:
'POST'
,
...
...
src/api/user/types.ts
View file @
97019bbf
...
...
@@ -3,6 +3,7 @@ import {
AuditStatusEnum
,
BooleanFlag
,
CommentTypeEnum
,
ReleaseStatusTypeEnum
,
TaskDateLimitTypeEnum
,
TaskTypeEnum
,
}
from
'@/constants'
...
...
@@ -61,6 +62,11 @@ export interface SelfPraiseSearchParams extends PageSearchParams {
type
:
ArticleTypeEnum
}
// 我的案例库搜索
export
interface
SelfCaseSearchParams
extends
PageSearchParams
{
releaseStatus
:
ReleaseStatusTypeEnum
}
export
interface
SelfPraiseDetailDto
{
collectionCount
:
number
content
:
string
...
...
@@ -200,6 +206,7 @@ export interface SelfCaseItemDto {
deptName
:
string
id
:
number
integrity
:
number
isAudit
:
AuditStatusEnum
isDelete
:
number
isDispose
:
number
isUse
:
number
...
...
src/components/common/ArticleContent/index.vue
View file @
97019bbf
...
...
@@ -76,7 +76,7 @@
<!-- 文章内容 -->
<div
v-if=
"!isHtml"
class=
"prose prose-lg max-w-none"
>
<div
class=
"text-gray-700 leading-relaxed space-y-4 whitespace-pre-line"
>
<div
class=
"text-gray-700 leading-relaxed space-y-4 whitespace-pre-line
text-17px
"
>
{{
articleDetail
?.
content
}}
</div>
...
...
src/components/common/PublishBox/index.vue
View file @
97019bbf
...
...
@@ -271,8 +271,10 @@ const handleAddTag = () => {
const
handleFileChange
=
async
(
e
:
Event
)
=>
{
const
file
=
(
e
.
target
as
HTMLInputElement
).
files
?.[
0
]
if
(
file
)
{
const
{
data
}
=
await
uploadFile
(
file
)
form
.
value
.
imgUrl
.
push
(
data
.
data
[
0
]?.
filePath
||
''
)
const
{
promise
}
=
uploadFile
(
file
)
const
data
=
await
promise
console
.
log
(
data
)
form
.
value
.
imgUrl
.
push
(
data
.
filePath
)
}
}
...
...
src/components/common/UploadFile/index.vue
View file @
97019bbf
...
...
@@ -126,12 +126,15 @@ const handleChange: UploadProps['onChange'] = async (uploadFile, uploadFiles) =>
fileList
.
value
[
fileIndex
]
!
.
status
=
'uploading'
}
const
{
data
}
=
await
uploadFileApi
(
uploadFile
.
raw
,
(
progress
)
=>
{
const
{
promise
}
=
uploadFileApi
(
uploadFile
.
raw
,
{
onProgress
:
(
progress
)
=>
{
console
.
log
(
'progress'
,
progress
)
},
})
const
data
=
await
promise
console
.
log
(
'data'
,
data
)
const
url
=
data
.
data
[
0
]?.
filePath
||
''
const
name
=
data
.
data
[
0
]?.
finalName
||
''
const
url
=
data
.
filePath
||
''
const
name
=
data
.
finalName
||
''
fileIndex
=
fileList
.
value
.
findIndex
((
file
)
=>
file
.
uid
===
uid
)
...
...
src/components/common/UploadVideo/index.vue
View file @
97019bbf
...
...
@@ -30,7 +30,7 @@
</div>
</div>
<el-progress
:percentage=
"uploadProgress"
:stroke-width=
"8"
class=
"progress-bar"
/>
<el-button
type=
"danger"
size=
"small"
@
click=
"cancelUpload"
class=
"cancel-btn"
>
<el-button
type=
"danger"
size=
"small"
@
click
.
stop
=
"cancelUpload"
class=
"cancel-btn"
>
取消上传
</el-button>
</div>
...
...
@@ -163,6 +163,7 @@ const handleFileChange = async (file: UploadFile) => {
await
startUpload
()
}
let
cancelUploadController
=
()
=>
{}
// 开始上传
const
startUpload
=
async
()
=>
{
if
(
!
currentFile
.
value
)
return
...
...
@@ -173,9 +174,14 @@ const startUpload = async () => {
uploadProgress
.
value
=
0
// 调用你的上传方法
const
{
data
}
=
await
uploadFileApi
(
currentFile
.
value
,
(
progress
)
=>
{
const
{
promise
,
cancel
}
=
uploadFileApi
(
currentFile
.
value
,
{
onProgress
:
(
progress
)
=>
{
uploadProgress
.
value
=
progress
},
})
cancelUploadController
=
cancel
const
data
=
await
promise
console
.
log
(
data
)
// 获取视频元数据
...
...
@@ -183,15 +189,15 @@ const startUpload = async () => {
// 根据你的 API 返回结构调整
const
videoData
:
VideoInfo
=
{
url
:
data
.
data
[
0
]?.
filePath
||
''
,
url
:
data
.
filePath
||
''
,
// 暂时写死
// url: 'https://soundasia.oss-cn-shenzhen.aliyuncs.com/OA/readName/mp4/2025/11/12/Common/1762918987602.mp4',
name
:
currentFile
.
value
.
name
,
size
:
currentFile
.
value
.
size
,
duration
:
metadata
.
duration
,
resolution
:
metadata
.
resolution
,
poster
:
data
.
data
[
0
]?.
filePath
||
''
,
fileId
:
data
.
data
[
0
]?.
fileId
||
''
,
poster
:
data
.
filePath
||
''
,
fileId
:
data
.
fileId
||
''
,
}
videoInfo
.
value
=
videoData
...
...
@@ -215,6 +221,7 @@ const startUpload = async () => {
// 取消上传
const
cancelUpload
=
()
=>
{
cancelUploadController
()
uploading
.
value
=
false
uploadProgress
.
value
=
0
ElMessage
.
info
(
'已取消上传'
)
...
...
@@ -233,6 +240,20 @@ const retryUpload = () => {
uploadError
.
value
=
''
startUpload
()
}
// reset
const
reset
=
()
=>
{
uploadRef
.
value
=
null
uploading
.
value
=
false
uploadProgress
.
value
=
0
uploadError
.
value
=
''
currentFile
.
value
=
null
videoInfo
.
value
=
null
modelValue
.
value
=
''
}
defineExpose
({
reset
,
})
</
script
>
<
style
scoped
>
...
...
src/components/common/WangEditor/index.vue
View file @
97019bbf
...
...
@@ -37,9 +37,9 @@ const editorConfig = {
MENU_CONF
:
{
uploadImage
:
{
customUpload
:
async
(
file
:
File
,
insertFn
:
(
url
:
string
)
=>
void
)
=>
{
const
{
data
}
=
await
uploadFile
(
file
)
cons
ole
.
log
(
data
)
insertFn
(
data
.
data
[
0
]?.
filePath
||
''
)
const
{
promise
}
=
uploadFile
(
file
)
cons
t
data
=
await
promise
insertFn
(
data
.
filePath
)
},
},
},
...
...
src/views/publishCase/index.vue
View file @
97019bbf
...
...
@@ -107,7 +107,7 @@
</
template
>
<
script
setup
lang=
"tsx"
>
import
{
addOrUpdateCase
}
from
'@/api'
import
{
addOrUpdateCase
,
getCaseDetail
}
from
'@/api'
import
{
useResetData
}
from
'@/hooks'
import
type
{
AddOrUpdateCaseDto
}
from
'@/api'
import
SelectTags
from
'@/components/common/SelectTags/index.vue'
...
...
@@ -117,6 +117,7 @@ import { TagTypeEnum, TagLevelEnum, BooleanFlag, ReleaseStatusTypeEnum } from '@
import
{
selectDepOrUser
}
from
'@/utils'
import
{
useUserStore
}
from
'@/stores'
import
{
storeToRefs
}
from
'pinia'
import
type
{
ISelectDept
}
from
'@/utils/wxUtil'
const
router
=
useRouter
()
const
userStore
=
useUserStore
()
const
{
userInfo
}
=
storeToRefs
(
userStore
)
...
...
@@ -137,10 +138,7 @@ const [form, resetForm] = useResetData({
relatedScenariosMainTagId
:
''
,
relatedScenariosSubTagIds
:
[],
isSync
:
BooleanFlag
.
NO
,
releaseStatus
:
ReleaseStatusTypeEnum
.
PUBLISH
,
deptId
:
''
,
deptName
:
''
,
departmentList
:
[],
departmentList
:
[]
as
ISelectDept
[],
})
// 选择部门
...
...
@@ -187,6 +185,7 @@ const transformData = (releaseStatus: ReleaseStatusTypeEnum): AddOrUpdateCaseDto
...
rest
,
releaseStatus
,
tagRelationDtoList
:
[],
sourceUser
:
''
,
}
// 添加文化标签内容
obj
.
tagRelationDtoList
.
push
({
...
...
@@ -302,8 +301,46 @@ const filterRelatedScenariosTagsFn = (allTags: TagItemDto[]) => {
return
allTags
.
filter
((
tag
)
=>
tag
.
id
!==
Number
(
form
.
value
.
relatedScenariosMainTagId
))
}
onActivated
(()
=>
{
onDeactivated
(()
=>
{
// 重置表单
resetForm
()
})
onActivated
(
async
()
=>
{
const
id
=
Number
(
router
.
currentRoute
.
value
.
query
.
id
)
if
(
id
)
{
// 编辑草稿箱
const
{
data
}
=
await
getCaseDetail
(
id
)
const
cultureTagList
=
data
.
caseTags
.
filter
((
i
)
=>
i
.
type
===
TagTypeEnum
.
CULTURE_TAG
)
const
relatedScenariosTagList
=
data
.
caseTags
.
filter
((
i
)
=>
i
.
type
===
TagTypeEnum
.
SCENE_TAG
)
const
obj
=
{
id
:
data
.
id
,
title
:
data
.
title
,
content
:
data
.
content
,
mainTagId
:
String
(
cultureTagList
.
find
((
i
)
=>
i
.
keywordType
===
TagLevelEnum
.
MAIN_TAG
)?.
tagId
||
''
,
),
subTagIds
:
cultureTagList
.
filter
((
i
)
=>
i
.
keywordType
===
TagLevelEnum
.
SUB_TAG
)
.
map
((
i
)
=>
i
.
tagId
),
relatedScenariosMainTagId
:
String
(
relatedScenariosTagList
.
find
((
i
)
=>
i
.
keywordType
===
TagLevelEnum
.
MAIN_TAG
)?.
tagId
||
''
,
),
relatedScenariosSubTagIds
:
relatedScenariosTagList
.
filter
((
i
)
=>
i
.
keywordType
===
TagLevelEnum
.
SUB_TAG
)
.
map
((
i
)
=>
i
.
tagId
),
isSync
:
data
.
isSync
,
departmentList
:
data
.
depIdList
.
map
((
id
,
index
)
=>
({
id
,
name
:
data
.
depNameList
[
index
],
})),
}
form
.
value
=
obj
console
.
log
(
'form'
,
form
.
value
)
}
else
{
showSubmissionGuide
()
}
})
</
script
>
...
...
src/views/publishLongArticle/index.vue
View file @
97019bbf
...
...
@@ -430,6 +430,7 @@ const handleSubmit = async (releaseStatus: ReleaseStatusTypeEnum) => {
:
await
addOrUpdateArticle
(
transFormData
(
releaseStatus
))
console
.
log
(
res
)
drawerVisible
.
value
=
false
ElMessage
.
success
(
releaseStatus
===
ReleaseStatusTypeEnum
.
PUBLISH
?
'发布成功'
:
'存草稿成功'
)
resetForm
()
router
.
back
()
// 发布成功后的逻辑...
...
...
src/views/publishVideo/index.vue
View file @
97019bbf
...
...
@@ -12,7 +12,11 @@
<h3
class=
"text-xl font-bold text-gray-800"
>
上传视频
</h3>
</div>
<el-form-item
prop=
"videoUrl"
>
<UploadVideo
v-model=
"form.videoUrl"
@
uploadSuccess=
"handleVideoChange"
/>
<UploadVideo
v-model=
"form.videoUrl"
@
uploadSuccess=
"handleVideoChange"
ref=
"uploadVideoRef"
/>
</el-form-item>
</div>
...
...
@@ -339,7 +343,7 @@
import
UploadVideo
from
'@/components/common/UploadVideo/index.vue'
import
{
useResetData
}
from
'@/hooks'
import
{
ArticleTypeEnum
,
ReleaseStatusTypeEnum
,
SendTypeEnum
}
from
'@/constants'
import
{
addOrUpdateArticle
,
uploadFile
,
getArticleDetail
}
from
'@/api'
import
{
addOrUpdateArticle
,
uploadFile
}
from
'@/api'
import
SelectTags
from
'@/components/common/SelectTags/index.vue'
import
type
{
TagItemDto
,
AddOrUpdateVideoDto
}
from
'@/api'
import
{
Camera
,
Picture
}
from
'@element-plus/icons-vue'
...
...
@@ -360,7 +364,7 @@ const router = useRouter()
const
route
=
useRoute
()
const
formRef
=
useTemplateRef
(
'formRef'
)
const
coverInputRef
=
useTemplateRef
(
'coverInputRef'
)
const
uploadVideoRef
=
useTemplateRef
(
'uploadVideoRef'
)
const
[
form
,
resetData
]
=
useResetData
<
AddOrUpdateVideoDto
>
({
videoUrl
:
''
,
title
:
''
,
...
...
@@ -467,8 +471,9 @@ const captureFrame = () => {
async
(
blob
)
=>
{
if
(
blob
)
{
// 直接在这里上传 不转为本地了
const
{
data
}
=
await
uploadFile
(
new
File
([
blob
],
`video
${
Date
.
now
()}
.jpg`
))
form
.
value
.
faceUrl
=
data
.
data
[
0
].
filePath
const
{
promise
}
=
uploadFile
(
new
File
([
blob
],
`video
${
Date
.
now
()}
.jpg`
))
const
data
=
await
promise
form
.
value
.
faceUrl
=
data
.
filePath
ElMessage
.
success
(
'封面截取成功'
)
}
},
...
...
@@ -581,9 +586,15 @@ const handleFileChange = async (e: Event) => {
const
target
=
e
.
target
as
HTMLInputElement
const
file
=
target
.
files
?.[
0
]
if
(
!
file
)
return
const
{
data
}
=
await
uploadFile
(
file
)
form
.
value
.
faceUrl
=
data
.
data
[
0
].
filePath
const
{
promise
}
=
uploadFile
(
file
)
const
data
=
await
promise
form
.
value
.
faceUrl
=
data
.
filePath
}
onDeactivated
(()
=>
{
// 清空页面的数据
resetPageData
()
uploadVideoRef
.
value
?.
reset
()
})
// const isEdit = computed(() => {
// return !!route.query.id
...
...
src/views/userPage/components/SelfComplaint.vue
View file @
97019bbf
...
...
@@ -63,7 +63,9 @@
</div>
-->
</div>
<div
class=
"text-gray-700 font-medium"
>
举报理由:
{{
item
.
reason
}}
</div>
<div
class=
"text-gray-700 font-medium truncate line-clamp-1"
>
举报理由:
{{
item
.
reason
}}
</div>
</div>
</div>
</div>
...
...
src/views/userPage/components/selfAnswer.vue
View file @
97019bbf
...
...
@@ -26,7 +26,9 @@
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=
"text-gray-900 font-medium truncate"
>
{{
item
.
title
}}
</div>
<div
class=
"text-gray-900 font-medium truncate line-clamp-1"
>
{{
item
.
title
}}
</div>
<div
class=
"text-gray-500 text-sm mt-1 truncate"
>
<span
class=
"mr-2"
>
{{
dayjs
(
item
.
createTime
*
1000
).
format
(
'YYYY-MM-DD HH:mm:ss'
)
}}
...
...
@@ -39,7 +41,7 @@
<el-button
type=
"primary"
link
@
click=
"jumpToArticleDetailPage(
{ type:
'question'
, id: item.id })"
@
click=
"jumpToArticleDetailPage(
{ type:
ArticleTypeEnum.QUESTION
, id: item.id })"
>去回复
</el-button
>
</div>
...
...
@@ -73,6 +75,7 @@ import { answerQuestionPage } from '@/api'
import
{
usePageSearch
}
from
'@/hooks'
import
dayjs
from
'dayjs'
import
{
jumpToArticleDetailPage
}
from
'@/utils'
import
{
ArticleTypeEnum
}
from
'@/constants'
const
{
list
,
loading
,
searchParams
,
total
,
refresh
,
goToPage
,
changePageSize
}
=
usePageSearch
(
answerQuestionPage
,
...
...
src/views/userPage/components/selfAudit.vue
View file @
97019bbf
...
...
@@ -54,7 +54,7 @@
</div>
<!-- 第二行:标题 -->
<div
class=
"text-gray-700 font-medium"
>
<div
class=
"text-gray-700 font-medium
truncate line-clamp-1
"
>
{{
item
.
title
}}
</div>
</div>
...
...
src/views/userPage/components/selfCase.vue
View file @
97019bbf
...
...
@@ -2,6 +2,24 @@
<div
class=
"flex-1 flex flex-col"
v-loading=
"loading"
>
<!-- List Container -->
<div
class=
"flex-1 p-4 pt-1"
>
<div
class=
"relative"
>
<el-tabs
v-model=
"searchParams.releaseStatus"
@
tab-change=
"toggleTab"
>
<el-tab-pane
v-for=
"tab in caseTypeListOptions"
:key=
"tab.value"
:label=
"tab.label"
:name=
"tab.value"
/>
</el-tabs>
<div
class=
"absolute right-0 top-2.5 z-1000"
>
<el-icon
size=
"15"
class=
"cursor-pointer hover:rotate-180 transition-all duration-300"
@
click=
"refresh"
><Refresh
/></el-icon>
</div>
</div>
<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"
>
<el-icon
class=
"text-2xl text-gray-300"
><Document
/></el-icon>
...
...
@@ -17,11 +35,25 @@
>
<!-- Content -->
<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 line-clamp-1"
>
{{
item
.
title
}}
</div>
<div
class=
"text-gray-500 text-sm mt-1 truncate"
>
<span
class=
"mr-2"
>
{{
dayjs
(
item
.
createTime
*
1000
).
format
(
'YYYY-MM-DD HH:mm:ss'
)
}}
</span>
<span
class=
"mr-2"
>
<el-tag
v-if=
"item.isAudit === AuditStatusEnum.UNAUDITED"
type=
"warning"
>
待审核
</el-tag
>
<el-tag
v-else-if=
"item.isAudit === AuditStatusEnum.AGREED"
type=
"success"
size=
"small"
>
已通过
</el-tag
>
<el-tag
v-else
type=
"warning"
>
已驳回
</el-tag>
</span>
<!--
<span
class=
"mr-2"
>
浏览
{{
item
.
viewCount
}}
</span>
<span
class=
"mr-2"
>
点赞
{{
item
.
replyCount
}}
</span>
<span
class=
"mr-2"
>
评论
{{
item
.
collectionCount
}}
</span>
...
...
@@ -31,8 +63,25 @@
<!-- Meta Info -->
<div
class=
"flex items-center text-gray-400 text-sm ml-4"
>
<el-button
type=
"primary"
link
>
编辑
</el-button>
<el-button
type=
"danger"
link
>
删除
</el-button>
<el-button
type=
"primary"
link
@
click=
"handleEdit(item)"
>
{{
searchParams
.
releaseStatus
===
ReleaseStatusTypeEnum
.
PUBLISH
&&
item
.
isAudit
!==
AuditStatusEnum
.
UNAUDITED
?
'查看'
:
'编辑'
}}
</el-button>
<el-button
v-if=
"
searchParams.releaseStatus === ReleaseStatusTypeEnum.DRAFT ||
(searchParams.releaseStatus === ReleaseStatusTypeEnum.PUBLISH &&
item.isAudit === AuditStatusEnum.UNAUDITED)
"
type=
"danger"
link
@
click=
"handleDelete(item)"
>
删除
</el-button
>
</div>
</div>
</div>
...
...
@@ -58,13 +107,167 @@
</div>
</
template
>
<
script
lang=
"ts"
setup
>
<
script
lang=
"ts
x
"
setup
>
import
{
Document
}
from
'@element-plus/icons-vue'
import
{
getSelfCaseList
}
from
'@/api'
import
{
getSelfCaseList
,
deleteCase
,
getCaseDetail
}
from
'@/api'
import
{
usePageSearch
}
from
'@/hooks'
import
dayjs
from
'dayjs'
import
{
ReleaseStatusTypeEnum
,
AuditStatusEnum
}
from
'@/constants'
import
type
{
TabPaneName
}
from
'element-plus'
import
type
{
SelfCaseItemDto
}
from
'@/api/user/types'
const
router
=
useRouter
()
const
caseTypeListOptions
=
[
{
label
:
'已发布'
,
value
:
ReleaseStatusTypeEnum
.
PUBLISH
},
{
label
:
'草稿'
,
value
:
ReleaseStatusTypeEnum
.
DRAFT
},
]
const
toggleTab
=
(
key
:
TabPaneName
)
=>
{
searchParams
.
value
.
releaseStatus
=
key
as
ReleaseStatusTypeEnum
refresh
()
}
const
{
list
,
loading
,
searchParams
,
total
,
goToPage
,
changePageSize
,
refresh
}
=
usePageSearch
(
getSelfCaseList
,
{
defaultParams
:
{
releaseStatus
:
caseTypeListOptions
[
0
]
!
.
value
,
},
immediate
:
false
,
},
)
const
handleEdit
=
async
(
item
:
SelfCaseItemDto
)
=>
{
if
(
searchParams
.
value
.
releaseStatus
===
ReleaseStatusTypeEnum
.
PUBLISH
&&
item
.
isAudit
!==
AuditStatusEnum
.
UNAUDITED
)
{
// 根据 id获取详情数据
const
{
data
}
=
await
getCaseDetail
(
item
.
id
)
console
.
log
(
data
)
// 打开弹窗 查看详情
const
formData
=
{
title
:
data
.
title
,
content
:
data
.
content
,
keywords
:
[
data
.
cultureKeywordMain
,
...(
data
.
cultureKeywordSub
||
[])].
filter
(
Boolean
),
scenes
:
[
data
.
sceneKeywordMain
,
...(
data
.
sceneKeywordSub
||
[])].
filter
(
Boolean
),
departments
:
data
.
depNameList
.
filter
(
Boolean
),
syncPublish
:
data
.
isSync
?
'是'
:
'否'
,
}
console
.
log
(
formData
)
ElMessageBox
({
title
:
'案例详情'
,
message
:
(
<
div
class
=
"max-h-500px overflow-y-auto px-4"
>
{
/* 标题 */
}
<
div
class
=
"mb-5"
>
<
div
class
=
"text-13px text-gray-500 mb-2 flex items-center"
>
<
span
class
=
"text-red-500 mr-1"
>*<
/span
>
标题
<
/div
>
<
div
class
=
"bg-gray-50 rounded-lg px-4 py-3 text-gray-700"
>
{
formData
.
title
}
<
/div
>
<
/div
>
{
/* 内容 */
}
<
div
class
=
"mb-5"
>
<
div
class
=
"text-13px text-gray-500 mb-2 flex items-center"
>
<
span
class
=
"text-red-500 mr-1"
>*<
/span
>
内容
<
/div
>
<
div
class
=
"bg-gray-50 rounded-lg px-4 py-3 text-gray-700 min-h-80px whitespace-pre-wrap break-words"
>
{
formData
.
content
}
<
/div
>
<
/div
>
{
/* 文化关键词 */
}
<
div
class
=
"mb-5"
>
<
div
class
=
"text-13px text-gray-500 mb-2 flex items-center"
>
<
span
class
=
"text-red-500 mr-1"
>*<
/span
>
文化关键词
<
/div
>
<
div
class
=
"flex flex-wrap gap-2"
>
{
formData
.
keywords
.
map
((
keyword
,
index
)
=>
(
<
span
key
=
{
index
}
class
=
"px-3 py-1.5 bg-blue-50 text-blue-600 rounded-md text-13px"
>
{
keyword
}
<
/span
>
))}
<
/div
>
<
/div
>
{
/* 关联场景 */
}
<
div
class
=
"mb-5"
>
<
div
class
=
"text-13px text-gray-500 mb-2"
>
关联场景
<
/div
>
{
formData
.
scenes
.
length
>
0
?
(
<
div
class
=
"flex flex-wrap gap-2"
>
{
formData
.
scenes
.
map
((
scene
,
index
)
=>
(
<
span
key
=
{
index
}
class
=
"px-3 py-1.5 bg-blue-50 text-blue-600 rounded-md text-13px"
>
{
scene
}
<
/span
>
))}
<
/div
>
)
:
(
<
div
class
=
"text-gray-400 text-13px"
>
暂无
<
/div
>
)}
<
/div
>
{
/* 关联部门 */
}
<
div
class
=
"mb-5"
>
<
div
class
=
"text-13px text-gray-500 mb-2"
>
关联部门
<
/div
>
{
formData
.
departments
.
length
>
0
?
(
<
div
class
=
"flex flex-wrap gap-2"
>
{
formData
.
departments
.
map
((
dept
,
index
)
=>
(
<
span
key
=
{
index
}
class
=
"px-3 py-1.5 bg-gray-50 text-gray-700 rounded-md text-13px"
>
{
dept
}
<
/span
>
))}
<
/div
>
)
:
(
<
div
class
=
"text-gray-400 text-13px"
>
暂无
<
/div
>
)}
<
/div
>
{
/* 是否同步发布到实践 */
}
<
div
>
<
div
class
=
"text-13px text-gray-500 mb-2 flex items-center"
>
<
span
class
=
"text-red-500 mr-1"
>*<
/span
>
是否同步发布到实践
<
/div
>
<
div
class
=
"px-4 py-2.5 bg-gray-50 rounded-lg text-gray-700 inline-block"
>
{
formData
.
syncPublish
}
<
/div
>
<
/div
>
<
/div
>
),
confirmButtonText
:
'确定'
,
showCancelButton
:
false
,
width
:
'680px'
,
// 从 520px 增加到 680px
customClass
:
'form-detail-dialog'
,
})
}
else
{
router
.
push
(
`/publishCase?id=
${
item
.
id
}
`
)
}
}
const
handleDelete
=
async
(
item
:
SelfCaseItemDto
)
=>
{
await
ElMessageBox
.
confirm
(
'确定删除该案例吗?'
,
'提示'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
,
})
await
deleteCase
(
item
.
id
)
ElMessage
.
success
(
'删除成功'
)
refresh
()
}
const
{
list
,
loading
,
searchParams
,
total
,
goToPage
,
changePageSize
}
=
usePageSearch
(
getSelfCaseList
)
onActivated
(()
=>
{
refresh
()
})
</
script
>
src/views/userPage/components/selfCollect.vue
View file @
97019bbf
...
...
@@ -34,15 +34,15 @@
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=
"text-gray-900 font-medium truncate"
>
{{
item
.
title
}}
</div>
<div
class=
"text-gray-900 font-medium truncate
line-clamp-1
"
>
{{
item
.
title
}}
</div>
<div
class=
"text-gray-500 text-sm mt-1 truncate"
>
<span
class=
"mr-2"
>
{{
dayjs
(
item
.
createTime
*
1000
).
format
(
'YYYY-MM-DD HH:mm:ss'
)
}}
</span>
<span
class=
"mr-2"
>
浏览
{{
item
.
viewCount
}}
</span>
<span
class=
"mr-2"
>
点赞
{{
item
.
reply
Count
}}
</span>
<span
class=
"mr-2"
>
评论
{{
item
.
collection
Count
}}
</span>
<span
class=
"mr-2"
>
收藏
{{
item
.
praise
Count
}}
</span>
<span
class=
"mr-2"
>
点赞
{{
item
.
praise
Count
}}
</span>
<span
class=
"mr-2"
>
评论
{{
item
.
reply
Count
}}
</span>
<span
class=
"mr-2"
>
收藏
{{
item
.
collection
Count
}}
</span>
</div>
</div>
...
...
@@ -113,6 +113,7 @@ const { list, loading, searchParams, total, refresh, goToPage, changePageSize }
defaultParams
:
{
type
:
filterArticleType
.
value
[
0
]
!
.
value
,
},
immediate
:
false
,
},
)
...
...
src/views/userPage/components/selfComment.vue
View file @
97019bbf
...
...
@@ -50,7 +50,7 @@
>
<!-- Content -->
<div
class=
"flex-1 min-w-0 space-y-1.5"
>
<div
class=
"text-gray-900 font-medium text-base line-clamp-
2
"
>
<div
class=
"text-gray-900 font-medium text-base line-clamp-
1
"
>
{{
item
.
title
}}
</div>
<div
class=
"text-gray-600 text-sm line-clamp-2"
>
评论内容:
{{
item
.
content
}}
</div>
...
...
src/views/userPage/components/selfDraft.vue
View file @
97019bbf
...
...
@@ -36,7 +36,7 @@
>
<!-- Content -->
<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
line-clamp-1
"
>
{{
item
.
title
}}
</div>
<div
class=
"text-gray-500 text-sm mt-1 truncate"
>
<span
class=
"mr-2"
>
{{
dayjs
(
item
.
createTime
*
1000
).
format
(
'YYYY-MM-DD HH:mm:ss'
)
}}
...
...
@@ -113,6 +113,7 @@ const { list, loading, searchParams, total, refresh, goToPage, changePageSize }
defaultParams
:
{
type
:
filterArticleType
.
value
[
0
]
!
.
value
,
},
immediate
:
false
,
},
)
...
...
src/views/userPage/components/selfPraise.vue
View file @
97019bbf
...
...
@@ -33,7 +33,7 @@
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=
"text-gray-900 font-medium truncate"
>
{{
item
.
title
}}
</div>
<div
class=
"text-gray-900 font-medium truncate
line-clamp-1
"
>
{{
item
.
title
}}
</div>
<div
class=
"text-gray-500 text-sm mt-1 truncate"
>
<span
class=
"mr-2"
>
{{
dayjs
(
item
.
createTime
*
1000
).
format
(
'YYYY-MM-DD HH:mm:ss'
)
}}
...
...
@@ -111,6 +111,7 @@ const { list, loading, searchParams, total, refresh, goToPage, changePageSize }
defaultParams
:
{
type
:
filterArticleType
.
value
[
0
]
!
.
value
,
},
immediate
:
false
,
},
)
...
...
src/views/userPage/components/selfPublish.vue
View file @
97019bbf
...
...
@@ -34,15 +34,15 @@
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=
"text-gray-900 font-medium truncate"
>
{{
item
.
title
}}
</div>
<div
class=
"text-gray-900 font-medium truncate
line-clamp-1
"
>
{{
item
.
title
}}
</div>
<div
class=
"text-gray-500 text-sm mt-1 truncate"
>
<span
class=
"mr-2"
>
{{
dayjs
(
item
.
createTime
*
1000
).
format
(
'YYYY-MM-DD HH:mm:ss'
)
}}
</span>
<span
class=
"mr-2"
>
浏览
{{
item
.
viewCount
}}
</span>
<span
class=
"mr-2"
>
点赞
{{
item
.
reply
Count
}}
</span>
<span
class=
"mr-2"
>
评论
{{
item
.
collection
Count
}}
</span>
<span
class=
"mr-2"
>
收藏
{{
item
.
praise
Count
}}
</span>
<span
class=
"mr-2"
>
点赞
{{
item
.
praise
Count
}}
</span>
<span
class=
"mr-2"
>
评论
{{
item
.
reply
Count
}}
</span>
<span
class=
"mr-2"
>
收藏
{{
item
.
collection
Count
}}
</span>
</div>
</div>
...
...
@@ -118,6 +118,7 @@ const { list, loading, searchParams, total, refresh, goToPage, changePageSize }
defaultParams
:
{
type
:
filterArticleType
.
value
[
0
]
!
.
value
,
},
immediate
:
false
,
},
)
...
...
src/views/userPage/index.vue
View file @
97019bbf
...
...
@@ -42,7 +42,7 @@
<!-- 主要内容区域 -->
<div
class=
"relative -mt-20 p-6"
>
<div
class=
"flex gap-6"
>
<div
class=
"flex gap-6
w-100% flex-nowrap
"
>
<!-- 左侧个人信息卡片 -->
<div
class=
"w-300px"
>
<!-- 个人信息卡片 -->
...
...
@@ -135,7 +135,7 @@
<!-- 左侧菜单 -->
</div>
<!-- 右侧内容区域 -->
<div
class=
"flex-1"
>
<div
class=
"flex-1
min-w-0
"
>
<div
class=
"bg-white rounded-lg shadow-sm min-h-500px"
>
<router-view
v-slot=
"
{ Component, route }">
<transition
name=
"fade"
mode=
"out-in"
>
...
...
src/views/videoDetail/index.vue
View file @
97019bbf
...
...
@@ -224,7 +224,13 @@
</div>
</div>
<Comment
ref=
"commentRef"
:id=
"videoId"
v-model:total=
"videoDetail.replyCount"
:isReal=
"0"
/>
<Comment
ref=
"commentRef"
:id=
"videoId"
v-model:total=
"videoDetail.replyCount"
:isReal=
"0"
class=
"mt-5"
/>
<RewardDialog
ref=
"rewardDialogRef"
v-model:rewardNum=
"videoDetail.rewardNum"
/>
</div>
</
template
>
...
...
@@ -246,7 +252,7 @@ import ActionMore from '@/components/common/ActionMore/index.vue'
import
{
jumpToUserHomePage
}
from
'@/utils'
const
route
=
useRoute
()
const
videoId
=
route
.
params
.
id
as
string
const
videoId
=
Number
(
route
.
params
.
id
)
// 视频详情
const
videoDetail
=
ref
({}
as
ArticleItemDto
)
...
...
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