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
992e6a69
Commit
992e6a69
authored
Feb 06, 2026
by
lijiabin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
【需求 20331】 feat: 优化后台页面,优化二级菜单,完成推荐置顶功能;以及案例库的导入编辑功能等
parent
50ca5eb9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
2549 additions
and
81 deletions
+2549
-81
editDialog.vue
src/views/backend/caseManage/components/editDialog.vue
+320
-0
errorListDialog.vue
src/views/backend/caseManage/components/errorListDialog.vue
+136
-0
index.vue
src/views/backend/caseManage/index.vue
+0
-0
index.vue
src/views/backend/columnsMenu/columnManage/index.vue
+339
-0
index.vue
src/views/backend/columnsMenu/interviewManage/index.vue
+0
-0
index.vue
src/views/backend/columnsMenu/videoManage/index.vue
+338
-0
index.vue
src/views/backend/contentsMenu/columnManage/index.vue
+319
-0
index.vue
src/views/backend/contentsMenu/interviewManage/index.vue
+319
-0
index.vue
src/views/backend/contentsMenu/questionManage/index.vue
+327
-0
index.vue
src/views/backend/contentsMenu/videoManage/index.vue
+320
-0
index.vue
src/views/backend/index.vue
+124
-74
index.vue
src/views/backend/settingsMenu/goodsManage/index.vue
+0
-0
index.vue
src/views/backend/videoManage/index.vue
+7
-7
No files found.
src/views/backend/caseManage/components/editDialog.vue
0 → 100644
View file @
992e6a69
<
script
setup
lang=
"ts"
>
import
type
{
BackendCaseListItemDto
,
BackendEditCaseDto
}
from
'@/api/backend/case/types'
import
{
useResetData
}
from
'@/hooks'
import
SelectTags
from
'@/components/common/SelectTags/index.vue'
import
type
{
TagItemDto
}
from
'@/api/tag/types'
import
{
TagLevelEnum
,
TagTypeEnum
}
from
'@/constants'
import
{
selectDepOrUser
}
from
'@/utils'
import
{
backendEditCase
}
from
'@/api/backend'
const
emit
=
defineEmits
<
{
refresh
:
[]
}
>
()
const
[
form
]
=
useResetData
<
{
id
:
number
sourceProject
:
string
sourceType
:
string
caseType
:
string
integrity
:
string
cultureRelation
:
string
title
:
string
content
:
string
cultureKeywordMain
:
string
cultureKeywordSecond
:
number
[]
yearKeywordMain
:
string
yearKeywordSecond
:
string
sceneKeywordMain
:
string
sceneKeywordSecond
:
number
[]
departmentList
:
{
id
:
string
;
name
:
string
}[]
}
>
({
id
:
0
,
sourceProject
:
''
,
sourceType
:
''
,
caseType
:
''
,
integrity
:
''
,
cultureRelation
:
''
,
title
:
''
,
content
:
''
,
cultureKeywordMain
:
''
,
cultureKeywordSecond
:
[],
yearKeywordMain
:
''
,
yearKeywordSecond
:
''
,
sceneKeywordMain
:
''
,
sceneKeywordSecond
:
[],
departmentList
:
[],
})
const
visible
=
ref
(
false
)
const
open
=
(
row
:
BackendCaseListItemDto
)
=>
{
visible
.
value
=
true
form
.
value
=
{
id
:
row
.
id
,
sourceProject
:
row
.
sourceProject
,
sourceType
:
row
.
sourceType
,
caseType
:
row
.
caseType
,
integrity
:
row
.
integrity
,
cultureRelation
:
row
.
cultureRelation
,
title
:
row
.
title
,
content
:
row
.
content
,
// 文化关键词
cultureKeywordMain
:
String
(
row
.
cultureKeywordMain
[
0
]?.
id
||
''
),
cultureKeywordSecond
:
row
.
cultureKeywordSecond
.
map
((
item
)
=>
item
.
id
),
// 年度主推关键词
yearKeywordMain
:
String
(
row
.
yearKeywordMain
[
0
]?.
id
||
''
),
yearKeywordSecond
:
String
(
row
.
yearKeywordSecond
[
0
]?.
id
||
''
),
// 关联场景主关键词
sceneKeywordMain
:
String
(
row
.
sceneKeywordMain
[
0
]?.
id
||
''
),
sceneKeywordSecond
:
row
.
sceneKeywordSecond
.
map
((
item
)
=>
item
.
id
),
// 关联部门
departmentList
:
row
.
depIdList
.
map
((
id
,
index
)
=>
({
id
:
String
(
id
),
name
:
row
.
depNameList
[
index
]
||
''
,
})),
}
}
const
filterTagsFn
=
(
tagType
:
TagTypeEnum
,
allTags
:
TagItemDto
[])
=>
{
if
(
tagType
===
TagTypeEnum
.
CULTURE_TAG
)
{
return
allTags
.
filter
((
tag
)
=>
tag
.
id
!==
Number
(
form
.
value
.
cultureKeywordMain
))
}
else
if
(
tagType
===
TagTypeEnum
.
YEAR_TAG
)
{
return
allTags
.
filter
((
tag
)
=>
tag
.
id
!==
Number
(
form
.
value
.
yearKeywordMain
))
}
else
if
(
tagType
===
TagTypeEnum
.
SCENE_TAG
)
{
return
allTags
.
filter
((
tag
)
=>
tag
.
id
!==
Number
(
form
.
value
.
sceneKeywordMain
))
}
return
allTags
}
// 选择部门
const
selcetDept
=
async
()
=>
{
const
{
departmentList
}
=
await
selectDepOrUser
({
mode
:
'multi'
,
// single multi
type
:
[
'department'
],
selectedDepartmentIds
:
form
.
value
.
departmentList
.
map
((
i
)
=>
i
.
id
),
})
if
(
departmentList
.
length
>
3
)
{
return
ElMessage
.
warning
(
'最多只能选择3个部门,请重新选择'
)
}
form
.
value
.
departmentList
=
departmentList
}
// 删除部门
const
delDept
=
(
id
:
string
)
=>
{
form
.
value
.
departmentList
=
form
.
value
.
departmentList
.
filter
((
i
)
=>
i
.
id
!==
id
)
}
// 数据转换
const
transformData
=
()
=>
{
const
{
cultureKeywordMain
,
cultureKeywordSecond
,
yearKeywordMain
,
yearKeywordSecond
,
sceneKeywordMain
,
sceneKeywordSecond
,
departmentList
,
...
rest
}
=
form
.
value
const
data
:
BackendEditCaseDto
=
{
...
rest
,
tagRelationDtoList
:
[],
deptId
:
departmentList
.
map
((
i
)
=>
i
.
id
).
join
(
','
),
deptName
:
departmentList
.
map
((
i
)
=>
i
.
name
).
join
(
','
),
}
// 添加文化关键词数据
if
(
cultureKeywordMain
)
{
data
.
tagRelationDtoList
.
push
({
tagId
:
Number
(
cultureKeywordMain
),
type
:
TagTypeEnum
.
CULTURE_TAG
,
keywordType
:
TagLevelEnum
.
MAIN_TAG
,
})
}
cultureKeywordSecond
.
forEach
((
id
)
=>
{
data
.
tagRelationDtoList
.
push
({
tagId
:
id
,
type
:
TagTypeEnum
.
CULTURE_TAG
,
keywordType
:
TagLevelEnum
.
SUB_TAG
,
})
})
// 添加年度主推关键词数据
if
(
yearKeywordMain
)
{
data
.
tagRelationDtoList
.
push
({
tagId
:
Number
(
yearKeywordMain
),
type
:
TagTypeEnum
.
YEAR_TAG
,
keywordType
:
TagLevelEnum
.
MAIN_TAG
,
})
}
if
(
yearKeywordSecond
)
{
data
.
tagRelationDtoList
.
push
({
tagId
:
Number
(
yearKeywordSecond
),
type
:
TagTypeEnum
.
YEAR_TAG
,
keywordType
:
TagLevelEnum
.
SUB_TAG
,
})
}
// 添加关联场景主关键词数据
if
(
sceneKeywordMain
)
{
data
.
tagRelationDtoList
.
push
({
tagId
:
Number
(
sceneKeywordMain
),
type
:
TagTypeEnum
.
SCENE_TAG
,
keywordType
:
TagLevelEnum
.
MAIN_TAG
,
})
}
sceneKeywordSecond
.
forEach
((
id
)
=>
{
data
.
tagRelationDtoList
.
push
({
tagId
:
id
,
type
:
TagTypeEnum
.
SCENE_TAG
,
keywordType
:
TagLevelEnum
.
SUB_TAG
,
})
})
return
data
}
const
loading
=
ref
(
false
)
const
handleSave
=
async
()
=>
{
loading
.
value
=
true
try
{
const
data
=
transformData
()
const
res
=
await
backendEditCase
(
data
)
if
(
res
.
code
===
200
)
{
ElMessage
.
success
(
'编辑成功'
)
visible
.
value
=
false
}
visible
.
value
=
false
emit
(
'refresh'
)
}
catch
(
error
)
{
console
.
log
(
error
,
'error'
)
}
finally
{
loading
.
value
=
false
}
}
defineExpose
({
open
,
})
</
script
>
<
template
>
<el-dialog
v-model=
"visible"
title=
"编辑"
width=
"35vw"
>
<el-scrollbar
height=
"500px"
>
<el-form
:model=
"form"
label-width=
"auto"
class=
"px-3"
label-position=
"top"
>
<el-form-item
label=
"来源项目:"
>
<el-input
v-model=
"form.sourceProject"
/>
</el-form-item>
<el-form-item
label=
"来源类型:"
>
<el-input
v-model=
"form.sourceType"
/>
</el-form-item>
<!-- 案例类型 -->
<el-form-item
label=
"案例类型:"
>
<el-input
v-model=
"form.caseType"
/>
</el-form-item>
<el-form-item
label=
"案例完整性:"
>
<el-input
v-model=
"form.integrity"
/>
</el-form-item>
<el-form-item
label=
"企业文化关联程度:"
>
<el-input
v-model=
"form.cultureRelation"
/>
</el-form-item>
<el-form-item
label=
"案例标题:"
>
<el-input
v-model=
"form.title"
/>
</el-form-item>
<el-form-item
label=
"案例文本内容:"
>
<el-input
type=
"textarea"
v-model=
"form.content"
:maxlength=
"5000"
:show-word-limit=
"true"
:rows=
"10"
/>
</el-form-item>
<!-- 下面是标签等相关的 -->
<!-- 文化关键词 -->
<el-form-item
label=
"文化主关键词:"
>
<div
class=
"flex items-start"
>
<div
class=
"flex flex-wrap gap-3 items-start"
>
主标签
<SelectTags
v-model=
"form.cultureKeywordMain"
/>
</div>
<div
class=
"flex flex-wrap gap-3 items-start ml-5"
>
副标签
<SelectTags
v-model=
"form.cultureKeywordSecond"
:max-selected-tags=
"3"
:filter-tags-fn=
"(allTags) => filterTagsFn(TagTypeEnum.CULTURE_TAG, allTags)"
/>
</div>
</div>
</el-form-item>
<!-- 年度主推关键词 -->
<el-form-item
label=
"年度主推主关键词:"
>
<div
class=
"flex items-start"
>
<div
class=
"flex flex-wrap gap-3 items-start"
>
主标签
<SelectTags
v-model=
"form.yearKeywordMain"
:tagType=
"TagTypeEnum.YEAR_TAG"
/>
</div>
<div
class=
"flex flex-wrap gap-3 items-start ml-5"
>
副标签
<SelectTags
v-model=
"form.yearKeywordSecond"
:tagType=
"TagTypeEnum.YEAR_TAG"
:filter-tags-fn=
"(allTags) => filterTagsFn(TagTypeEnum.YEAR_TAG, allTags)"
/>
</div>
</div>
</el-form-item>
<el-form-item
label=
"关联场景主关键词:"
>
<div
class=
"flex items-start"
>
<div
class=
"flex flex-wrap gap-3 items-start"
>
主标签
<SelectTags
v-model=
"form.sceneKeywordMain"
:tagType=
"TagTypeEnum.SCENE_TAG"
/>
</div>
<div
class=
"flex flex-wrap gap-3 items-start ml-5"
>
副标签
<SelectTags
v-model=
"form.sceneKeywordSecond"
:max-selected-tags=
"4"
:tagType=
"TagTypeEnum.SCENE_TAG"
:filter-tags-fn=
"(allTags) => filterTagsFn(TagTypeEnum.SCENE_TAG, allTags)"
/>
</div>
</div>
</el-form-item>
<!-- 关联部门 -->
<el-form-item
label=
"关联部门:"
>
<div
class=
"flex items-start gap-3"
>
<el-button
class=
"button-new-tag"
size=
"small"
@
click=
"selcetDept"
>
+ 添加部门
</el-button>
<el-tag
v-for=
"tag in form.departmentList"
:key=
"tag.id"
closable
type=
"primary"
@
close=
"() => delDept(tag.id)"
>
{{
tag
.
name
}}
</el-tag>
</div>
</el-form-item>
</el-form>
</el-scrollbar>
<template
#
footer
>
<el-button
@
click=
"visible = false"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"handleSave"
:loading=
"loading"
>
保存
</el-button>
</
template
>
</el-dialog>
</template>
<
style
scoped
></
style
>
src/views/backend/caseManage/components/errorListDialog.vue
0 → 100644
View file @
992e6a69
<
script
setup
lang=
"ts"
generic=
"T"
>
const
{
errorList
}
=
defineProps
<
{
errorList
:
T
[]
}
>
()
const
visible
=
defineModel
<
boolean
>
(
'visible'
,
{
required
:
true
})
const
handleContent
=
(
content
:
string
)
=>
{
// 弹窗展示
ElMessageBox
.
alert
(
content
,
'案例全部文本内容'
,
{
confirmButtonText
:
'确定'
,
})
}
</
script
>
<
template
>
<el-dialog
v-model=
"visible"
title=
"以下数据导入失败"
width=
"80vw"
>
<el-table
:data=
"errorList"
style=
"width: 100%"
height=
"500"
>
<el-table-column
prop=
"errorMsg"
label=
"错误信息"
width=
"200"
></el-table-column>
<el-table-column
label=
"来源对象"
align=
"center"
>
<el-table-column
prop=
"jobNo"
label=
"工号"
width=
"120"
></el-table-column>
<el-table-column
prop=
"name"
label=
"姓名"
width=
"120"
></el-table-column>
</el-table-column>
<el-table-column
prop=
"title"
label=
"案例标题"
width=
"200"
></el-table-column>
<!-- 内容过多加入tooltip -->
<el-table-column
prop=
"content"
label=
"案例文本内容"
width=
"300"
>
<template
#
default=
"
{ row }">
<!-- 省略号 -->
<div
class=
"line-clamp-1 text-blue-500 cursor-pointer"
@
click=
"handleContent(row.content)"
>
{{
row
.
content
}}
</div>
</
template
>
</el-table-column>
<el-table-column
label=
"文化关键词(次关键词选填)"
align=
"center"
>
<el-table-column
prop=
"cultureKeywordMain"
label=
"主关键词"
width=
"160"
>
<
template
#
default=
"{ row }"
>
<el-tag
type=
"primary"
>
{{
row
.
cultureMain
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
prop=
"cultureKeywordSecond"
label=
"次关键词1"
width=
"160"
>
<
template
#
default=
"{ row }"
>
<el-tag
v-if=
"row.cultureSub1"
type=
"primary"
>
{{
row
.
cultureSub1
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
prop=
"cultureKeywordSecond"
label=
"次关键词2"
width=
"160"
>
<
template
#
default=
"{ row }"
>
<el-tag
v-if=
"row.cultureSub2"
type=
"primary"
>
{{
row
.
cultureSub2
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
prop=
"cultureKeywordSecond"
label=
"次关键词3"
width=
"160"
>
<
template
#
default=
"{ row }"
>
<el-tag
v-if=
"row.cultureSub3"
type=
"primary"
>
{{
row
.
cultureSub3
}}
</el-tag>
</
template
>
</el-table-column>
</el-table-column>
<el-table-column
label=
"年度主推关键词(选填)"
align=
"center"
>
<el-table-column
prop=
"yearMain"
label=
"主关键词"
width=
"160"
></el-table-column>
<el-table-column
prop=
"yearSub1"
label=
"次关键词1"
width=
"160"
></el-table-column>
</el-table-column>
<el-table-column
prop=
"caseType"
label=
"案例类型(选填)"
width=
"120"
></el-table-column>
<el-table-column
label=
"关联场景(选填)"
align=
"center"
>
<el-table-column
prop=
"sceneMain"
label=
"主关键词"
width=
"160"
>
<
template
#
default=
"{ row }"
>
<el-tag
v-if=
"row.sceneMain"
type=
"primary"
>
{{
row
.
sceneMain
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
prop=
"abnormalReason"
label=
"次关键词1"
width=
"160"
>
<
template
#
default=
"{ row }"
>
<el-tag
v-if=
"row.sceneSub1"
type=
"primary"
>
{{
row
.
sceneSub1
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
prop=
"abnormalReason"
label=
"次关键词2"
width=
"160"
>
<
template
#
default=
"{ row }"
>
<el-tag
v-if=
"row.sceneSub2"
type=
"primary"
>
{{
row
.
sceneSub2
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
prop=
"abnormalReason"
label=
"次关键词3"
width=
"160"
>
<
template
#
default=
"{ row }"
>
<el-tag
v-if=
"row.sceneSub3"
type=
"primary"
>
{{
row
.
sceneSub3
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
prop=
"abnormalReason"
label=
"次关键词4"
width=
"160"
>
<
template
#
default=
"{ row }"
>
<el-tag
v-if=
"row.sceneSub4"
type=
"primary"
>
{{
row
.
sceneSub4
}}
</el-tag>
</
template
>
</el-table-column>
</el-table-column>
<el-table-column
label=
"关联部门(选填)"
align=
"center"
>
<el-table-column
label=
"部门1"
width=
"160"
>
<
template
#
default=
"{ row }"
>
<el-tag
v-if=
"row.dept1"
type=
"primary"
>
{{
row
.
dept1
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
prop=
"taxBracket2"
label=
"部门2"
width=
"160"
>
<
template
#
default=
"{ row }"
>
<el-tag
v-if=
"row.dept2"
type=
"primary"
>
{{
row
.
dept2
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
prop=
"taxBracket3"
label=
"部门3"
width=
"160"
>
<
template
#
default=
"{ row }"
>
<el-tag
v-if=
"row.dept3"
type=
"primary"
>
{{
row
.
dept3
}}
</el-tag>
</
template
>
</el-table-column>
</el-table-column>
<el-table-column
prop=
"remarks"
label=
"来源渠道(选填)"
width=
"120"
>
<el-table-column
prop=
"sourceProject"
label=
"来源项目"
width=
"120"
></el-table-column>
<el-table-column
prop=
"sourceType"
label=
"来源类型"
width=
"120"
></el-table-column>
</el-table-column>
</el-table>
</el-dialog>
</template>
src/views/backend/caseManage/index.vue
View file @
992e6a69
This diff is collapsed.
Click to expand it.
src/views/backend/columnsMenu/columnManage/index.vue
0 → 100644
View file @
992e6a69
<!-- views/backend/official/index.vue -->
<
template
>
<div
class=
"official-tag-page"
>
<!-- 搜索栏 -->
<div
class=
"search-section"
>
<div
class=
"flex-1 flex gap-2"
>
<el-input
v-model=
"searchParams.title"
placeholder=
"请输入栏目标题"
class=
"w-200px"
clearable
></el-input>
<el-select
v-model=
"searchParams.status"
placeholder=
"请选择发布状态"
class=
"search-select"
clearable
>
<el-option
label=
"发布"
:value=
"1"
/>
<el-option
label=
"隐藏"
:value=
"0"
/>
</el-select>
<el-button
type=
"primary"
:icon=
"Search"
@
click=
"refresh"
>
搜索
</el-button>
<el-button
@
click=
"reset"
>
重置
</el-button>
</div>
<div
class=
"flex justify-end"
>
<el-button
type=
"primary"
@
click=
"handleAdd"
>
<el-icon><Plus
/></el-icon>
新增
</el-button>
<el-button
type=
"primary"
@
click=
"handleBatchPublish"
>
批量发布/隐藏
</el-button>
<el-button
type=
"danger"
@
click=
"handleBatchDelete"
>
批量删除
</el-button>
</div>
</div>
<!-- 表格区域 -->
<div
class=
"table-section"
>
<!-- 表格 -->
<div
class=
"table-wrapper"
>
<el-table
v-loading=
"loading"
:data=
"list"
height=
"100%"
@
selection-change=
"handleSelectionChange"
>
<el-table-column
type=
"selection"
width=
"55"
>
</el-table-column>
<el-table-column
prop=
"sort"
label=
"栏目顺序"
width=
"180"
>
</el-table-column>
<el-table-column
prop=
"title"
label=
"栏目名称"
min-width=
"200"
/>
<el-table-column
prop=
"postCount"
label=
"栏目帖子数量"
min-width=
"200"
/>
<el-table-column
prop=
"color"
label=
"颜色"
width=
"300"
>
<template
#
default=
"
{ row }">
<div
class=
"color-cell"
>
<div
class=
"color-block"
:style=
"
{ backgroundColor: row.color }" />
<span
class=
"color-text"
>
{{
row
.
color
}}
</span>
</div>
</
template
>
</el-table-column>
<el-table-column
prop=
"createUserId"
label=
"创建人"
min-width=
"200"
/>
<el-table-column
prop=
"createTime"
label=
"创建时间"
min-width=
"200"
>
<
template
#
default=
"{ row }"
>
{{
dayjs
(
row
.
createTime
*
1000
).
format
(
'YYYY-MM-DD HH:mm:ss'
)
}}
</
template
>
</el-table-column>
<el-table-column
prop=
"status"
label=
"状态"
min-width=
"200"
>
<
template
#
default=
"{ row }"
>
<el-switch
:model-value=
"row.status"
:active-value=
"1"
:inactive-value=
"0"
@
change=
"handleStatusChange(row)"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"操作"
width=
"150"
fixed=
"right"
>
<
template
#
default=
"{ row }"
>
<el-button
type=
"primary"
link
@
click=
"handleEdit(row)"
>
编辑
</el-button>
<el-button
type=
"danger"
link
@
click=
"handleDelete(row)"
>
删除
</el-button>
</
template
>
</el-table-column>
</el-table>
</div>
<!-- 分页 -->
<div
class=
"pagination-wrapper"
>
<el-pagination
v-model:current-page=
"searchParams.current"
v-model:page-size=
"searchParams.size"
:total=
"total"
:page-sizes=
"[10, 20, 30]"
layout=
"total, sizes, prev, pager, next, jumper"
@
size-change=
"changePageSize"
@
current-change=
"goToPage"
/>
</div>
</div>
<!-- 新增/编辑对话框 -->
<el-dialog
v-model=
"dialogVisible"
:title=
"dialogTitle"
width=
"500px"
:close-on-click-modal=
"false"
>
<el-form
ref=
"formRef"
:model=
"form"
:rules=
"formRules"
label-width=
"80px"
>
<el-form-item
label=
"标题"
prop=
"title"
>
<el-input
v-model=
"form.title"
placeholder=
"请输入标题"
/>
</el-form-item>
<el-form-item
label=
"颜色"
prop=
"color"
>
<el-color-picker
v-model=
"form.color"
/>
<span
class=
"color-value"
>
{{ form.color }}
</span>
</el-form-item>
<el-form-item
label=
"排序"
prop=
"sort"
>
<el-input-number
v-model=
"form.sort"
:min=
"0"
:max=
"100"
/>
</el-form-item>
</el-form>
<
template
#
footer
>
<el-button
@
click=
"dialogVisible = false"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"handleSubmit"
>
<el-icon
class=
"btn-icon"
><Upload
/></el-icon>
保存
</el-button>
</
template
>
</el-dialog>
</div>
</template>
<
script
setup
lang=
"ts"
>
import
{
Search
,
Plus
,
Upload
}
from
'@element-plus/icons-vue'
import
{
usePageSearch
,
useResetData
}
from
'@/hooks'
import
{
listOfCultureColumn
,
addOrUpdateColumn
,
deleteColumn
,
hideColumn
}
from
'@/api/backend'
import
type
{
FormInstance
,
FormRules
}
from
'element-plus'
import
type
{
BackendColumnListItemDto
,
AddOrUpdateColumnDto
}
from
'@/api/backend'
import
dayjs
from
'dayjs'
const
{
loading
,
list
,
total
,
reset
,
goToPage
,
changePageSize
,
refresh
,
searchParams
,
search
}
=
usePageSearch
(
listOfCultureColumn
,
{
defaultParams
:
{
type
:
'column'
,
},
})
// 对话框
const
dialogVisible
=
ref
(
false
)
const
dialogTitle
=
computed
(()
=>
(
form
.
value
.
id
?
'编辑标签'
:
'新增标签'
))
const
formRef
=
ref
<
FormInstance
>
()
// 表单数据
const
[
form
,
resetForm
]
=
useResetData
<
AddOrUpdateColumnDto
>
({
title
:
''
,
color
:
'#000000'
,
id
:
undefined
,
sort
:
0
,
type
:
'column'
,
})
// 表单验证规则
const
formRules
:
FormRules
=
{
title
:
[{
required
:
true
,
message
:
'请输入标题'
,
trigger
:
'blur'
}],
color
:
[{
required
:
true
,
message
:
'请选择颜色'
,
trigger
:
'change'
}],
sort
:
[{
required
:
true
,
message
:
'请输入排序'
,
trigger
:
'blur'
}],
}
// 新增
const
handleAdd
=
()
=>
{
resetForm
()
dialogVisible
.
value
=
true
}
// 编辑
const
handleEdit
=
(
row
:
BackendColumnListItemDto
)
=>
{
resetForm
()
form
.
value
=
{
title
:
row
.
title
,
color
:
row
.
color
,
id
:
row
.
id
,
sort
:
row
.
sort
,
type
:
'column'
,
}
dialogVisible
.
value
=
true
}
// 状态改变
const
handleStatusChange
=
async
(
row
:
BackendColumnListItemDto
)
=>
{
await
hideColumn
([
row
.
id
])
refresh
()
}
// 删除
const
handleDelete
=
async
(
row
:
BackendColumnListItemDto
)
=>
{
try
{
await
ElMessageBox
.
confirm
(
`确定要删除标签"
${
row
.
title
}
"吗?`
,
'提示'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
,
})
await
deleteColumn
([
row
.
id
])
ElMessage
.
success
(
'删除成功'
)
refresh
()
}
catch
(
error
)
{
if
(
error
!==
'cancel'
)
{
ElMessage
.
error
(
'删除失败'
)
}
}
}
// 提交表单
const
handleSubmit
=
async
()
=>
{
if
(
!
formRef
.
value
)
return
try
{
await
formRef
.
value
.
validate
()
if
(
form
.
value
.
id
)
{
await
addOrUpdateColumn
(
form
.
value
)
}
else
{
await
addOrUpdateColumn
(
form
.
value
)
}
ElMessage
.
success
(
form
.
value
.
id
?
'编辑成功'
:
'新增成功'
)
dialogVisible
.
value
=
false
if
(
form
.
value
.
id
)
{
search
()
}
else
{
refresh
()
}
}
catch
(
error
)
{
console
.
error
(
'表单验证失败:'
,
error
)
}
}
const
selectedRows
=
ref
<
BackendColumnListItemDto
[]
>
([])
// 选择
const
handleSelectionChange
=
(
selection
:
BackendColumnListItemDto
[])
=>
{
selectedRows
.
value
=
selection
}
// 批量发布/隐藏
const
handleBatchPublish
=
async
()
=>
{
await
hideColumn
(
selectedRows
.
value
.
map
((
item
)
=>
item
.
id
))
refresh
()
selectedRows
.
value
=
[]
ElMessage
.
success
(
'发布/隐藏成功'
)
}
// 批量删除
const
handleBatchDelete
=
async
()
=>
{
await
deleteColumn
(
selectedRows
.
value
.
map
((
item
)
=>
item
.
id
))
refresh
()
selectedRows
.
value
=
[]
ElMessage
.
success
(
'删除成功'
)
}
</
script
>
<
style
scoped
lang=
"scss"
>
.official-tag-page
{
height
:
100%
;
display
:
flex
;
flex-direction
:
column
;
gap
:
16px
;
}
//
搜索区域
.search-section
{
background
:
#fff
;
border-radius
:
8px
;
padding
:
20px
;
display
:
flex
;
gap
:
12px
;
flex-shrink
:
0
;
.search-select
{
width
:
200px
;
}
}
//
表格区域
.table-section
{
flex
:
1
;
background
:
#fff
;
border-radius
:
8px
;
padding
:
20px
;
display
:
flex
;
flex-direction
:
column
;
min-height
:
0
;
}
.table-wrapper
{
flex
:
1
;
min-height
:
0
;
.color-cell
{
display
:
flex
;
align-items
:
center
;
gap
:
12px
;
.color-block
{
width
:
100%
;
height
:
36px
;
border-radius
:
4px
;
border
:
1px
solid
#e5e7eb
;
flex
:
1
;
}
.color-text
{
color
:
#fff
;
font-size
:
14px
;
font-weight
:
500
;
position
:
absolute
;
left
:
50%
;
transform
:
translateX
(
-50%
);
text-shadow
:
0
0
3px
rgba
(
0
,
0
,
0
,
0.5
);
}
}
}
.pagination-wrapper
{
display
:
flex
;
justify-content
:
flex-end
;
padding-top
:
16px
;
flex-shrink
:
0
;
}
//
对话框内的颜色显示
.color-value
{
margin-left
:
12px
;
color
:
#606266
;
font-family
:
monospace
;
}
.btn-icon
{
margin-right
:
4px
;
}
</
style
>
src/views/backend/
interviewSettings
/index.vue
→
src/views/backend/
columnsMenu/interviewManage
/index.vue
View file @
992e6a69
File moved
src/views/backend/columnsMenu/videoManage/index.vue
0 → 100644
View file @
992e6a69
<
template
>
<div
class=
"official-tag-page"
>
<!-- 搜索栏 -->
<div
class=
"search-section"
>
<div
class=
"flex-1 flex gap-2"
>
<el-input
v-model=
"searchParams.title"
placeholder=
"请输入栏目标题"
class=
"w-200px"
clearable
></el-input>
<el-select
v-model=
"searchParams.status"
placeholder=
"请选择发布状态"
class=
"search-select"
clearable
>
<el-option
label=
"发布"
:value=
"1"
/>
<el-option
label=
"隐藏"
:value=
"0"
/>
</el-select>
<el-button
type=
"primary"
:icon=
"Search"
@
click=
"refresh"
>
搜索
</el-button>
<el-button
@
click=
"reset"
>
重置
</el-button>
</div>
<div
class=
"flex justify-end"
>
<el-button
type=
"primary"
@
click=
"handleAdd"
>
<el-icon><Plus
/></el-icon>
新增
</el-button>
<el-button
type=
"primary"
@
click=
"handleBatchPublish"
>
批量发布/隐藏
</el-button>
<el-button
type=
"danger"
@
click=
"handleBatchDelete"
>
批量删除
</el-button>
</div>
</div>
<!-- 表格区域 -->
<div
class=
"table-section"
>
<!-- 表格 -->
<div
class=
"table-wrapper"
>
<el-table
v-loading=
"loading"
:data=
"list"
height=
"100%"
@
selection-change=
"handleSelectionChange"
>
<el-table-column
type=
"selection"
width=
"55"
>
</el-table-column>
<el-table-column
prop=
"sort"
label=
"栏目顺序"
width=
"180"
>
</el-table-column>
<el-table-column
prop=
"title"
label=
"栏目名称"
min-width=
"200"
/>
<el-table-column
prop=
"postCount"
label=
"栏目帖子数量"
min-width=
"200"
/>
<el-table-column
prop=
"color"
label=
"颜色"
width=
"300"
>
<template
#
default=
"
{ row }">
<div
class=
"color-cell"
>
<div
class=
"color-block"
:style=
"
{ backgroundColor: row.color }" />
<span
class=
"color-text"
>
{{
row
.
color
}}
</span>
</div>
</
template
>
</el-table-column>
<el-table-column
prop=
"createUserId"
label=
"创建人"
min-width=
"200"
/>
<el-table-column
prop=
"createTime"
label=
"创建时间"
min-width=
"200"
>
<
template
#
default=
"{ row }"
>
{{
dayjs
(
row
.
createTime
*
1000
).
format
(
'YYYY-MM-DD HH:mm:ss'
)
}}
</
template
>
</el-table-column>
<el-table-column
prop=
"status"
label=
"状态"
min-width=
"200"
>
<
template
#
default=
"{ row }"
>
<el-switch
:model-value=
"row.status"
:active-value=
"1"
:inactive-value=
"0"
@
change=
"handleStatusChange(row)"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"操作"
width=
"150"
fixed=
"right"
>
<
template
#
default=
"{ row }"
>
<el-button
type=
"primary"
link
@
click=
"handleEdit(row)"
>
编辑
</el-button>
<el-button
type=
"danger"
link
@
click=
"handleDelete(row)"
>
删除
</el-button>
</
template
>
</el-table-column>
</el-table>
</div>
<!-- 分页 -->
<div
class=
"pagination-wrapper"
>
<el-pagination
v-model:current-page=
"searchParams.current"
v-model:page-size=
"searchParams.size"
:total=
"total"
:page-sizes=
"[10, 20, 30]"
layout=
"total, sizes, prev, pager, next, jumper"
@
size-change=
"changePageSize"
@
current-change=
"goToPage"
/>
</div>
</div>
<!-- 新增/编辑对话框 -->
<el-dialog
v-model=
"dialogVisible"
:title=
"dialogTitle"
width=
"500px"
:close-on-click-modal=
"false"
>
<el-form
ref=
"formRef"
:model=
"form"
:rules=
"formRules"
label-width=
"80px"
>
<el-form-item
label=
"标题"
prop=
"title"
>
<el-input
v-model=
"form.title"
placeholder=
"请输入标题"
/>
</el-form-item>
<el-form-item
label=
"颜色"
prop=
"color"
>
<el-color-picker
v-model=
"form.color"
/>
<span
class=
"color-value"
>
{{ form.color }}
</span>
</el-form-item>
<el-form-item
label=
"排序"
prop=
"sort"
>
<el-input-number
v-model=
"form.sort"
:min=
"0"
:max=
"100"
/>
</el-form-item>
</el-form>
<
template
#
footer
>
<el-button
@
click=
"dialogVisible = false"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"handleSubmit"
>
<el-icon
class=
"btn-icon"
><Upload
/></el-icon>
保存
</el-button>
</
template
>
</el-dialog>
</div>
</template>
<
script
setup
lang=
"ts"
>
import
{
Search
,
Plus
,
Upload
}
from
'@element-plus/icons-vue'
import
{
usePageSearch
,
useResetData
}
from
'@/hooks'
import
{
listOfCultureColumn
,
addOrUpdateColumn
,
deleteColumn
,
hideColumn
}
from
'@/api/backend'
import
type
{
FormInstance
,
FormRules
}
from
'element-plus'
import
type
{
BackendColumnListItemDto
,
AddOrUpdateColumnDto
}
from
'@/api/backend'
import
dayjs
from
'dayjs'
const
{
loading
,
list
,
total
,
reset
,
goToPage
,
changePageSize
,
refresh
,
searchParams
,
search
}
=
usePageSearch
(
listOfCultureColumn
,
{
defaultParams
:
{
type
:
'video'
,
},
})
// 对话框
const
dialogVisible
=
ref
(
false
)
const
dialogTitle
=
computed
(()
=>
(
form
.
value
.
id
?
'编辑标签'
:
'新增标签'
))
const
formRef
=
ref
<
FormInstance
>
()
// 表单数据
const
[
form
,
resetForm
]
=
useResetData
<
AddOrUpdateColumnDto
>
({
title
:
''
,
color
:
'#000000'
,
id
:
undefined
,
sort
:
0
,
type
:
'video'
,
})
// 表单验证规则
const
formRules
:
FormRules
=
{
title
:
[{
required
:
true
,
message
:
'请输入标题'
,
trigger
:
'blur'
}],
color
:
[{
required
:
true
,
message
:
'请选择颜色'
,
trigger
:
'change'
}],
sort
:
[{
required
:
true
,
message
:
'请输入排序'
,
trigger
:
'blur'
}],
}
// 新增
const
handleAdd
=
()
=>
{
resetForm
()
dialogVisible
.
value
=
true
}
// 编辑
const
handleEdit
=
(
row
:
BackendColumnListItemDto
)
=>
{
resetForm
()
form
.
value
=
{
title
:
row
.
title
,
color
:
row
.
color
,
id
:
row
.
id
,
sort
:
row
.
sort
,
type
:
'video'
,
}
dialogVisible
.
value
=
true
}
// 状态改变
const
handleStatusChange
=
async
(
row
:
BackendColumnListItemDto
)
=>
{
await
hideColumn
([
row
.
id
])
refresh
()
}
// 删除
const
handleDelete
=
async
(
row
:
BackendColumnListItemDto
)
=>
{
try
{
await
ElMessageBox
.
confirm
(
`确定要删除标签"
${
row
.
title
}
"吗?`
,
'提示'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
,
})
await
deleteColumn
([
row
.
id
])
ElMessage
.
success
(
'删除成功'
)
refresh
()
}
catch
(
error
)
{
if
(
error
!==
'cancel'
)
{
ElMessage
.
error
(
'删除失败'
)
}
}
}
// 提交表单
const
handleSubmit
=
async
()
=>
{
if
(
!
formRef
.
value
)
return
try
{
await
formRef
.
value
.
validate
()
if
(
form
.
value
.
id
)
{
await
addOrUpdateColumn
(
form
.
value
)
}
else
{
await
addOrUpdateColumn
(
form
.
value
)
}
ElMessage
.
success
(
form
.
value
.
id
?
'编辑成功'
:
'新增成功'
)
dialogVisible
.
value
=
false
if
(
form
.
value
.
id
)
{
search
()
}
else
{
refresh
()
}
}
catch
(
error
)
{
console
.
error
(
'表单验证失败:'
,
error
)
}
}
const
selectedRows
=
ref
<
BackendColumnListItemDto
[]
>
([])
// 选择
const
handleSelectionChange
=
(
selection
:
BackendColumnListItemDto
[])
=>
{
selectedRows
.
value
=
selection
}
// 批量发布/隐藏
const
handleBatchPublish
=
async
()
=>
{
await
hideColumn
(
selectedRows
.
value
.
map
((
item
)
=>
item
.
id
))
refresh
()
selectedRows
.
value
=
[]
ElMessage
.
success
(
'发布/隐藏成功'
)
}
// 批量删除
const
handleBatchDelete
=
async
()
=>
{
await
deleteColumn
(
selectedRows
.
value
.
map
((
item
)
=>
item
.
id
))
refresh
()
selectedRows
.
value
=
[]
ElMessage
.
success
(
'删除成功'
)
}
</
script
>
<
style
scoped
lang=
"scss"
>
.official-tag-page
{
height
:
100%
;
display
:
flex
;
flex-direction
:
column
;
gap
:
16px
;
}
//
搜索区域
.search-section
{
background
:
#fff
;
border-radius
:
8px
;
padding
:
20px
;
display
:
flex
;
gap
:
12px
;
flex-shrink
:
0
;
.search-select
{
width
:
200px
;
}
}
//
表格区域
.table-section
{
flex
:
1
;
background
:
#fff
;
border-radius
:
8px
;
padding
:
20px
;
display
:
flex
;
flex-direction
:
column
;
min-height
:
0
;
}
.table-wrapper
{
flex
:
1
;
min-height
:
0
;
.color-cell
{
display
:
flex
;
align-items
:
center
;
gap
:
12px
;
.color-block
{
width
:
100%
;
height
:
36px
;
border-radius
:
4px
;
border
:
1px
solid
#e5e7eb
;
flex
:
1
;
}
.color-text
{
color
:
#fff
;
font-size
:
14px
;
font-weight
:
500
;
position
:
absolute
;
left
:
50%
;
transform
:
translateX
(
-50%
);
text-shadow
:
0
0
3px
rgba
(
0
,
0
,
0
,
0.5
);
}
}
}
.pagination-wrapper
{
display
:
flex
;
justify-content
:
flex-end
;
padding-top
:
16px
;
flex-shrink
:
0
;
}
//
对话框内的颜色显示
.color-value
{
margin-left
:
12px
;
color
:
#606266
;
font-family
:
monospace
;
}
.btn-icon
{
margin-right
:
4px
;
}
</
style
>
src/views/backend/contentsMenu/columnManage/index.vue
0 → 100644
View file @
992e6a69
<
script
setup
lang=
"ts"
>
import
{
Search
,
Upload
}
from
'@element-plus/icons-vue'
import
{
usePageSearch
,
useResetData
}
from
'@/hooks'
import
{
addOrUpdateColumn
}
from
'@/api/backend'
import
{
getArticleList
,
updateArticleRecommendAndSort
}
from
'@/api'
import
type
{
FormInstance
,
FormRules
}
from
'element-plus'
import
type
{
BackendColumnListItemDto
,
AddOrUpdateColumnDto
}
from
'@/api/backend'
import
dayjs
from
'dayjs'
import
{
ArticleTypeEnum
,
BooleanFlag
}
from
'@/constants'
import
type
{
ArticleItemDto
}
from
'@/api/article/types'
const
{
loading
,
list
,
total
,
reset
,
goToPage
,
changePageSize
,
refresh
,
searchParams
,
search
}
=
usePageSearch
(
getArticleList
,
{
defaultParams
:
{
type
:
ArticleTypeEnum
.
COLUMN
,
},
})
// 对话框
const
dialogVisible
=
ref
(
false
)
const
dialogTitle
=
computed
(()
=>
(
form
.
value
.
id
?
'编辑标签'
:
'新增标签'
))
const
formRef
=
ref
<
FormInstance
>
()
// 表单数据
const
[
form
]
=
useResetData
<
AddOrUpdateColumnDto
>
({
title
:
''
,
color
:
'#000000'
,
id
:
undefined
,
sort
:
0
,
type
:
'column'
,
})
// 表单验证规则
const
formRules
:
FormRules
=
{
title
:
[{
required
:
true
,
message
:
'请输入标题'
,
trigger
:
'blur'
}],
color
:
[{
required
:
true
,
message
:
'请选择颜色'
,
trigger
:
'change'
}],
sort
:
[{
required
:
true
,
message
:
'请输入排序'
,
trigger
:
'blur'
}],
}
// 是否推荐改变
const
handleIsRecommendChange
=
async
(
val
:
BooleanFlag
,
row
:
ArticleItemDto
)
=>
{
await
updateArticleRecommendAndSort
({
articleId
:
row
.
id
,
recommendSort
:
0
,
// 默认传 0
isRecommend
:
val
,
})
ElMessage
.
success
(
'修改成功'
)
refresh
()
}
// 编辑排序
const
handleEditSort
=
async
(
row
:
ArticleItemDto
)
=>
{
const
{
value
}
=
await
ElMessageBox
.
prompt
(
'请输入排序值'
,
'提示'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
// 数字
inputPattern
:
/^
\d
+$/
,
inputErrorMessage
:
'请输入数字'
,
})
await
updateArticleRecommendAndSort
({
articleId
:
row
.
id
,
recommendSort
:
Number
(
value
),
isRecommend
:
BooleanFlag
.
YES
,
})
ElMessage
.
success
(
'修改成功'
)
refresh
()
}
// 提交表单
const
handleSubmit
=
async
()
=>
{
if
(
!
formRef
.
value
)
return
try
{
await
formRef
.
value
.
validate
()
if
(
form
.
value
.
id
)
{
await
addOrUpdateColumn
(
form
.
value
)
}
else
{
await
addOrUpdateColumn
(
form
.
value
)
}
ElMessage
.
success
(
form
.
value
.
id
?
'编辑成功'
:
'新增成功'
)
dialogVisible
.
value
=
false
if
(
form
.
value
.
id
)
{
search
()
}
else
{
refresh
()
}
}
catch
(
error
)
{
console
.
error
(
'表单验证失败:'
,
error
)
}
}
const
selectedRows
=
ref
<
BackendColumnListItemDto
[]
>
([])
// 选择
const
handleSelectionChange
=
(
selection
:
BackendColumnListItemDto
[])
=>
{
selectedRows
.
value
=
selection
}
// 函数弹窗 v-html
const
handleShowContent
=
(
row
:
ArticleItemDto
)
=>
{
console
.
log
(
row
.
content
)
ElMessageBox
.
alert
(
row
.
content
,
'内容'
,
{
showCancelButton
:
false
,
showConfirmButton
:
false
,
dangerouslyUseHTMLString
:
true
,
})
}
</
script
>
<
template
>
<div
class=
"official-tag-page"
>
<!-- 搜索栏 -->
<div
class=
"search-section"
>
<div
class=
"flex-1 flex gap-2"
>
<el-input
v-model=
"searchParams.title"
placeholder=
"请输入标题"
class=
"w-200px"
></el-input>
<div>
<el-button
type=
"primary"
:icon=
"Search"
@
click=
"refresh"
>
搜索
</el-button>
<el-button
@
click=
"reset"
>
重置
</el-button>
</div>
</div>
</div>
<!-- 表格区域 -->
<div
class=
"table-section"
>
<!-- 表格 -->
<div
class=
"table-wrapper"
>
<el-table
v-loading=
"loading"
:data=
"list"
height=
"100%"
@
selection-change=
"handleSelectionChange"
>
<el-table-column
prop=
"title"
label=
"标题"
min-width=
"200"
/>
<el-table-column
prop=
"content"
label=
"内容"
min-width=
"200"
>
<template
#
default=
"
{ row }">
<el-link
type=
"primary"
:underline=
"false"
@
click=
"handleShowContent(row)"
>
内容为富文本,点击查看
</el-link>
</
template
>
</el-table-column>
<el-table-column
prop=
"releaseStatus"
label=
"标签"
min-width=
"200"
>
<
template
#
default=
"{ row }"
>
<el-tag
v-for=
"tag in row.tagNameList"
:key=
"tag.tagId"
type=
"primary"
class=
"mr-2! mb-2!"
>
{{
tag
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
prop=
"status"
label=
"是否推荐"
min-width=
"200"
>
<
template
#
header
>
<div
class=
"flex items-center gap-2"
>
<span>
是否推荐
</span>
<el-tooltip
content=
"推荐后前台将按照排序值从大到小展示"
placement=
"top"
>
<el-icon><IEpInfoFilled
/></el-icon>
</el-tooltip>
</div>
</
template
>
<
template
#
default=
"{ row }"
>
<div
class=
"flex items-center gap-2"
>
<el-switch
:model-value=
"row.isRecommend"
:active-value=
"BooleanFlag.YES"
:inactive-value=
"BooleanFlag.NO"
@
change=
"(val) => handleIsRecommendChange(val as BooleanFlag, row)"
/>
<el-link
v-if=
"row.isRecommend"
class=
"flex items-center gap-2"
type=
"primary"
@
click=
"handleEditSort(row)"
:underline=
"false"
>
排序值:
{{
row
.
recommendSort
}}
</el-link
>
</div>
</
template
>
</el-table-column>
<el-table-column
prop=
"showName"
label=
"创建人"
min-width=
"200"
/>
<el-table-column
prop=
"createTime"
label=
"创建时间"
min-width=
"200"
>
<
template
#
default=
"{ row }"
>
{{
dayjs
(
row
.
createTime
*
1000
).
format
(
'YYYY-MM-DD HH:mm:ss'
)
}}
</
template
>
</el-table-column>
</el-table>
</div>
<!-- 分页 -->
<div
class=
"pagination-wrapper"
>
<el-pagination
v-model:current-page=
"searchParams.current"
v-model:page-size=
"searchParams.size"
:total=
"total"
:page-sizes=
"[10, 20, 30]"
layout=
"total, sizes, prev, pager, next, jumper"
@
size-change=
"changePageSize"
@
current-change=
"goToPage"
/>
</div>
</div>
<!-- 新增/编辑对话框 -->
<el-dialog
v-model=
"dialogVisible"
:title=
"dialogTitle"
width=
"500px"
:close-on-click-modal=
"false"
>
<el-form
ref=
"formRef"
:model=
"form"
:rules=
"formRules"
label-width=
"80px"
>
<el-form-item
label=
"标题"
prop=
"title"
>
<el-input
v-model=
"form.title"
placeholder=
"请输入标题"
/>
</el-form-item>
<el-form-item
label=
"颜色"
prop=
"color"
>
<el-color-picker
v-model=
"form.color"
/>
<span
class=
"color-value"
>
{{ form.color }}
</span>
</el-form-item>
<el-form-item
label=
"排序"
prop=
"sort"
>
<el-input-number
v-model=
"form.sort"
:min=
"0"
:max=
"100"
/>
</el-form-item>
</el-form>
<
template
#
footer
>
<el-button
@
click=
"dialogVisible = false"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"handleSubmit"
>
<el-icon
class=
"btn-icon"
><Upload
/></el-icon>
保存
</el-button>
</
template
>
</el-dialog>
</div>
</template>
<
style
scoped
lang=
"scss"
>
.official-tag-page
{
height
:
100%
;
display
:
flex
;
flex-direction
:
column
;
gap
:
16px
;
}
//
搜索区域
.search-section
{
background
:
#fff
;
border-radius
:
8px
;
padding
:
20px
;
display
:
flex
;
gap
:
12px
;
flex-shrink
:
0
;
.search-select
{
width
:
200px
;
}
}
//
表格区域
.table-section
{
flex
:
1
;
background
:
#fff
;
border-radius
:
8px
;
padding
:
20px
;
display
:
flex
;
flex-direction
:
column
;
min-height
:
0
;
}
.table-wrapper
{
flex
:
1
;
min-height
:
0
;
.color-cell
{
display
:
flex
;
align-items
:
center
;
gap
:
12px
;
.color-block
{
width
:
100%
;
height
:
36px
;
border-radius
:
4px
;
border
:
1px
solid
#e5e7eb
;
flex
:
1
;
}
.color-text
{
color
:
#fff
;
font-size
:
14px
;
font-weight
:
500
;
position
:
absolute
;
left
:
50%
;
transform
:
translateX
(
-50%
);
text-shadow
:
0
0
3px
rgba
(
0
,
0
,
0
,
0.5
);
}
}
}
.pagination-wrapper
{
display
:
flex
;
justify-content
:
flex-end
;
padding-top
:
16px
;
flex-shrink
:
0
;
}
//
对话框内的颜色显示
.color-value
{
margin-left
:
12px
;
color
:
#606266
;
font-family
:
monospace
;
}
.btn-icon
{
margin-right
:
4px
;
}
</
style
>
src/views/backend/contentsMenu/interviewManage/index.vue
0 → 100644
View file @
992e6a69
<
script
setup
lang=
"ts"
>
import
{
Search
,
Upload
}
from
'@element-plus/icons-vue'
import
{
usePageSearch
,
useResetData
}
from
'@/hooks'
import
{
addOrUpdateColumn
}
from
'@/api/backend'
import
{
getArticleList
,
updateArticleRecommendAndSort
}
from
'@/api'
import
type
{
FormInstance
,
FormRules
}
from
'element-plus'
import
type
{
BackendColumnListItemDto
,
AddOrUpdateColumnDto
}
from
'@/api/backend'
import
dayjs
from
'dayjs'
import
{
ArticleTypeEnum
,
BooleanFlag
}
from
'@/constants'
import
type
{
ArticleItemDto
}
from
'@/api/article/types'
const
{
loading
,
list
,
total
,
reset
,
goToPage
,
changePageSize
,
refresh
,
searchParams
,
search
}
=
usePageSearch
(
getArticleList
,
{
defaultParams
:
{
type
:
ArticleTypeEnum
.
INTERVIEW
,
},
})
// 对话框
const
dialogVisible
=
ref
(
false
)
const
dialogTitle
=
computed
(()
=>
(
form
.
value
.
id
?
'编辑标签'
:
'新增标签'
))
const
formRef
=
ref
<
FormInstance
>
()
// 表单数据
const
[
form
]
=
useResetData
<
AddOrUpdateColumnDto
>
({
title
:
''
,
color
:
'#000000'
,
id
:
undefined
,
sort
:
0
,
type
:
'column'
,
})
// 表单验证规则
const
formRules
:
FormRules
=
{
title
:
[{
required
:
true
,
message
:
'请输入标题'
,
trigger
:
'blur'
}],
color
:
[{
required
:
true
,
message
:
'请选择颜色'
,
trigger
:
'change'
}],
sort
:
[{
required
:
true
,
message
:
'请输入排序'
,
trigger
:
'blur'
}],
}
// 是否推荐改变
const
handleIsRecommendChange
=
async
(
val
:
BooleanFlag
,
row
:
ArticleItemDto
)
=>
{
await
updateArticleRecommendAndSort
({
articleId
:
row
.
id
,
recommendSort
:
0
,
// 默认传 0
isRecommend
:
val
,
})
ElMessage
.
success
(
'修改成功'
)
refresh
()
}
// 编辑排序
const
handleEditSort
=
async
(
row
:
ArticleItemDto
)
=>
{
const
{
value
}
=
await
ElMessageBox
.
prompt
(
'请输入排序值'
,
'提示'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
// 数字
inputPattern
:
/^
\d
+$/
,
inputErrorMessage
:
'请输入数字'
,
})
await
updateArticleRecommendAndSort
({
articleId
:
row
.
id
,
recommendSort
:
Number
(
value
),
isRecommend
:
BooleanFlag
.
YES
,
})
ElMessage
.
success
(
'修改成功'
)
refresh
()
}
// 提交表单
const
handleSubmit
=
async
()
=>
{
if
(
!
formRef
.
value
)
return
try
{
await
formRef
.
value
.
validate
()
if
(
form
.
value
.
id
)
{
await
addOrUpdateColumn
(
form
.
value
)
}
else
{
await
addOrUpdateColumn
(
form
.
value
)
}
ElMessage
.
success
(
form
.
value
.
id
?
'编辑成功'
:
'新增成功'
)
dialogVisible
.
value
=
false
if
(
form
.
value
.
id
)
{
search
()
}
else
{
refresh
()
}
}
catch
(
error
)
{
console
.
error
(
'表单验证失败:'
,
error
)
}
}
const
selectedRows
=
ref
<
BackendColumnListItemDto
[]
>
([])
// 选择
const
handleSelectionChange
=
(
selection
:
BackendColumnListItemDto
[])
=>
{
selectedRows
.
value
=
selection
}
// 函数弹窗 v-html
const
handleShowContent
=
(
row
:
ArticleItemDto
)
=>
{
console
.
log
(
row
.
content
)
ElMessageBox
.
alert
(
row
.
content
,
'内容'
,
{
showCancelButton
:
false
,
showConfirmButton
:
false
,
dangerouslyUseHTMLString
:
true
,
})
}
</
script
>
<
template
>
<div
class=
"official-tag-page"
>
<!-- 搜索栏 -->
<div
class=
"search-section"
>
<div
class=
"flex-1 flex gap-2"
>
<el-input
v-model=
"searchParams.title"
placeholder=
"请输入标题"
class=
"w-200px"
></el-input>
<div>
<el-button
type=
"primary"
:icon=
"Search"
@
click=
"refresh"
>
搜索
</el-button>
<el-button
@
click=
"reset"
>
重置
</el-button>
</div>
</div>
</div>
<!-- 表格区域 -->
<div
class=
"table-section"
>
<!-- 表格 -->
<div
class=
"table-wrapper"
>
<el-table
v-loading=
"loading"
:data=
"list"
height=
"100%"
@
selection-change=
"handleSelectionChange"
>
<el-table-column
prop=
"title"
label=
"标题"
min-width=
"200"
/>
<el-table-column
prop=
"content"
label=
"内容"
min-width=
"200"
>
<template
#
default=
"
{ row }">
<el-link
type=
"primary"
:underline=
"false"
@
click=
"handleShowContent(row)"
>
内容为富文本,点击查看
</el-link>
</
template
>
</el-table-column>
<el-table-column
prop=
"releaseStatus"
label=
"标签"
min-width=
"200"
>
<
template
#
default=
"{ row }"
>
<el-tag
v-for=
"tag in row.tagNameList"
:key=
"tag.tagId"
type=
"primary"
class=
"mr-2! mb-2!"
>
{{
tag
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
prop=
"status"
label=
"是否推荐"
min-width=
"200"
>
<
template
#
header
>
<div
class=
"flex items-center gap-2"
>
<span>
是否推荐
</span>
<el-tooltip
content=
"推荐后前台将按照排序值从大到小展示"
placement=
"top"
>
<el-icon><IEpInfoFilled
/></el-icon>
</el-tooltip>
</div>
</
template
>
<
template
#
default=
"{ row }"
>
<div
class=
"flex items-center gap-2"
>
<el-switch
:model-value=
"row.isRecommend"
:active-value=
"BooleanFlag.YES"
:inactive-value=
"BooleanFlag.NO"
@
change=
"(val) => handleIsRecommendChange(val as BooleanFlag, row)"
/>
<el-link
v-if=
"row.isRecommend"
class=
"flex items-center gap-2"
type=
"primary"
@
click=
"handleEditSort(row)"
:underline=
"false"
>
排序值:
{{
row
.
recommendSort
}}
</el-link
>
</div>
</
template
>
</el-table-column>
<el-table-column
prop=
"showName"
label=
"创建人"
min-width=
"200"
/>
<el-table-column
prop=
"createTime"
label=
"创建时间"
min-width=
"200"
>
<
template
#
default=
"{ row }"
>
{{
dayjs
(
row
.
createTime
*
1000
).
format
(
'YYYY-MM-DD HH:mm:ss'
)
}}
</
template
>
</el-table-column>
</el-table>
</div>
<!-- 分页 -->
<div
class=
"pagination-wrapper"
>
<el-pagination
v-model:current-page=
"searchParams.current"
v-model:page-size=
"searchParams.size"
:total=
"total"
:page-sizes=
"[10, 20, 30]"
layout=
"total, sizes, prev, pager, next, jumper"
@
size-change=
"changePageSize"
@
current-change=
"goToPage"
/>
</div>
</div>
<!-- 新增/编辑对话框 -->
<el-dialog
v-model=
"dialogVisible"
:title=
"dialogTitle"
width=
"500px"
:close-on-click-modal=
"false"
>
<el-form
ref=
"formRef"
:model=
"form"
:rules=
"formRules"
label-width=
"80px"
>
<el-form-item
label=
"标题"
prop=
"title"
>
<el-input
v-model=
"form.title"
placeholder=
"请输入标题"
/>
</el-form-item>
<el-form-item
label=
"颜色"
prop=
"color"
>
<el-color-picker
v-model=
"form.color"
/>
<span
class=
"color-value"
>
{{ form.color }}
</span>
</el-form-item>
<el-form-item
label=
"排序"
prop=
"sort"
>
<el-input-number
v-model=
"form.sort"
:min=
"0"
:max=
"100"
/>
</el-form-item>
</el-form>
<
template
#
footer
>
<el-button
@
click=
"dialogVisible = false"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"handleSubmit"
>
<el-icon
class=
"btn-icon"
><Upload
/></el-icon>
保存
</el-button>
</
template
>
</el-dialog>
</div>
</template>
<
style
scoped
lang=
"scss"
>
.official-tag-page
{
height
:
100%
;
display
:
flex
;
flex-direction
:
column
;
gap
:
16px
;
}
//
搜索区域
.search-section
{
background
:
#fff
;
border-radius
:
8px
;
padding
:
20px
;
display
:
flex
;
gap
:
12px
;
flex-shrink
:
0
;
.search-select
{
width
:
200px
;
}
}
//
表格区域
.table-section
{
flex
:
1
;
background
:
#fff
;
border-radius
:
8px
;
padding
:
20px
;
display
:
flex
;
flex-direction
:
column
;
min-height
:
0
;
}
.table-wrapper
{
flex
:
1
;
min-height
:
0
;
.color-cell
{
display
:
flex
;
align-items
:
center
;
gap
:
12px
;
.color-block
{
width
:
100%
;
height
:
36px
;
border-radius
:
4px
;
border
:
1px
solid
#e5e7eb
;
flex
:
1
;
}
.color-text
{
color
:
#fff
;
font-size
:
14px
;
font-weight
:
500
;
position
:
absolute
;
left
:
50%
;
transform
:
translateX
(
-50%
);
text-shadow
:
0
0
3px
rgba
(
0
,
0
,
0
,
0.5
);
}
}
}
.pagination-wrapper
{
display
:
flex
;
justify-content
:
flex-end
;
padding-top
:
16px
;
flex-shrink
:
0
;
}
//
对话框内的颜色显示
.color-value
{
margin-left
:
12px
;
color
:
#606266
;
font-family
:
monospace
;
}
.btn-icon
{
margin-right
:
4px
;
}
</
style
>
src/views/backend/contentsMenu/questionManage/index.vue
0 → 100644
View file @
992e6a69
<
script
setup
lang=
"ts"
>
import
{
Search
,
Upload
}
from
'@element-plus/icons-vue'
import
{
usePageSearch
,
useResetData
}
from
'@/hooks'
import
{
addOrUpdateColumn
}
from
'@/api/backend'
import
{
getArticleList
,
updateArticleRecommendAndSort
}
from
'@/api'
import
type
{
FormInstance
,
FormRules
}
from
'element-plus'
import
type
{
BackendColumnListItemDto
,
AddOrUpdateColumnDto
}
from
'@/api/backend'
import
dayjs
from
'dayjs'
import
{
ArticleTypeEnum
,
BooleanFlag
}
from
'@/constants'
import
type
{
ArticleItemDto
}
from
'@/api/article/types'
const
{
loading
,
list
,
total
,
reset
,
goToPage
,
changePageSize
,
refresh
,
searchParams
,
search
}
=
usePageSearch
(
getArticleList
,
{
defaultParams
:
{
type
:
ArticleTypeEnum
.
QUESTION
,
},
})
// 对话框
const
dialogVisible
=
ref
(
false
)
const
dialogTitle
=
computed
(()
=>
(
form
.
value
.
id
?
'编辑标签'
:
'新增标签'
))
const
formRef
=
ref
<
FormInstance
>
()
// 表单数据
const
[
form
]
=
useResetData
<
AddOrUpdateColumnDto
>
({
title
:
''
,
color
:
'#000000'
,
id
:
undefined
,
sort
:
0
,
type
:
'column'
,
})
// 表单验证规则
const
formRules
:
FormRules
=
{
title
:
[{
required
:
true
,
message
:
'请输入标题'
,
trigger
:
'blur'
}],
color
:
[{
required
:
true
,
message
:
'请选择颜色'
,
trigger
:
'change'
}],
sort
:
[{
required
:
true
,
message
:
'请输入排序'
,
trigger
:
'blur'
}],
}
// 是否推荐改变
const
handleIsRecommendChange
=
async
(
val
:
BooleanFlag
,
row
:
ArticleItemDto
)
=>
{
await
updateArticleRecommendAndSort
({
articleId
:
row
.
id
,
recommendSort
:
0
,
// 默认传 0
isRecommend
:
val
,
})
ElMessage
.
success
(
'修改成功'
)
refresh
()
}
// 编辑排序
const
handleEditSort
=
async
(
row
:
ArticleItemDto
)
=>
{
const
{
value
}
=
await
ElMessageBox
.
prompt
(
'请输入排序值'
,
'提示'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
// 数字
inputPattern
:
/^
\d
+$/
,
inputErrorMessage
:
'请输入数字'
,
})
await
updateArticleRecommendAndSort
({
articleId
:
row
.
id
,
recommendSort
:
Number
(
value
),
isRecommend
:
BooleanFlag
.
YES
,
})
ElMessage
.
success
(
'修改成功'
)
refresh
()
}
// 提交表单
const
handleSubmit
=
async
()
=>
{
if
(
!
formRef
.
value
)
return
try
{
await
formRef
.
value
.
validate
()
if
(
form
.
value
.
id
)
{
await
addOrUpdateColumn
(
form
.
value
)
}
else
{
await
addOrUpdateColumn
(
form
.
value
)
}
ElMessage
.
success
(
form
.
value
.
id
?
'编辑成功'
:
'新增成功'
)
dialogVisible
.
value
=
false
if
(
form
.
value
.
id
)
{
search
()
}
else
{
refresh
()
}
}
catch
(
error
)
{
console
.
error
(
'表单验证失败:'
,
error
)
}
}
const
selectedRows
=
ref
<
BackendColumnListItemDto
[]
>
([])
// 选择
const
handleSelectionChange
=
(
selection
:
BackendColumnListItemDto
[])
=>
{
selectedRows
.
value
=
selection
}
// 函数弹窗 v-html
// const handleShowContent = (row: ArticleItemDto) => {
// console.log(row.content)
// ElMessageBox.alert(row.content, '内容', {
// showCancelButton: false,
// showConfirmButton: false,
// dangerouslyUseHTMLString: true,
// })
// }
</
script
>
<
template
>
<div
class=
"official-tag-page"
>
<!-- 搜索栏 -->
<div
class=
"search-section"
>
<div
class=
"flex-1 flex gap-2"
>
<el-input
v-model=
"searchParams.title"
placeholder=
"请输入标题"
class=
"w-200px"
></el-input>
<div>
<el-button
type=
"primary"
:icon=
"Search"
@
click=
"refresh"
>
搜索
</el-button>
<el-button
@
click=
"reset"
>
重置
</el-button>
</div>
</div>
</div>
<!-- 表格区域 -->
<div
class=
"table-section"
>
<!-- 表格 -->
<div
class=
"table-wrapper"
>
<el-table
v-loading=
"loading"
:data=
"list"
height=
"100%"
@
selection-change=
"handleSelectionChange"
>
<el-table-column
prop=
"title"
label=
"标题"
min-width=
"200"
/>
<el-table-column
prop=
"content"
label=
"内容"
min-width=
"200"
:show-overflow-tooltip=
"
{
placement: 'top',
popperClass: 'max-w-300',
}"
>
<!--
<template
#
default=
"
{ row }">
<el-link
type=
"primary"
:underline=
"false"
@
click=
"handleShowContent(row)"
>
内容为富文本,点击查看
</el-link>
</
template
>
-->
</el-table-column>
<el-table-column
prop=
"releaseStatus"
label=
"标签"
min-width=
"200"
>
<
template
#
default=
"{ row }"
>
<el-tag
v-for=
"tag in row.tagNameList"
:key=
"tag.tagId"
type=
"primary"
class=
"mr-2! mb-2!"
>
{{
tag
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
prop=
"status"
label=
"是否推荐"
min-width=
"200"
>
<
template
#
header
>
<div
class=
"flex items-center gap-2"
>
<span>
是否推荐
</span>
<el-tooltip
content=
"推荐后前台将按照排序值从大到小展示"
placement=
"top"
>
<el-icon><IEpInfoFilled
/></el-icon>
</el-tooltip>
</div>
</
template
>
<
template
#
default=
"{ row }"
>
<div
class=
"flex items-center gap-2"
>
<el-switch
:model-value=
"row.isRecommend"
:active-value=
"BooleanFlag.YES"
:inactive-value=
"BooleanFlag.NO"
@
change=
"(val) => handleIsRecommendChange(val as BooleanFlag, row)"
/>
<el-link
v-if=
"row.isRecommend"
class=
"flex items-center gap-2"
type=
"primary"
@
click=
"handleEditSort(row)"
:underline=
"false"
>
排序值:
{{
row
.
recommendSort
}}
</el-link
>
</div>
</
template
>
</el-table-column>
<el-table-column
prop=
"showName"
label=
"创建人"
min-width=
"200"
/>
<el-table-column
prop=
"createTime"
label=
"创建时间"
min-width=
"200"
>
<
template
#
default=
"{ row }"
>
{{
dayjs
(
row
.
createTime
*
1000
).
format
(
'YYYY-MM-DD HH:mm:ss'
)
}}
</
template
>
</el-table-column>
</el-table>
</div>
<!-- 分页 -->
<div
class=
"pagination-wrapper"
>
<el-pagination
v-model:current-page=
"searchParams.current"
v-model:page-size=
"searchParams.size"
:total=
"total"
:page-sizes=
"[10, 20, 30]"
layout=
"total, sizes, prev, pager, next, jumper"
@
size-change=
"changePageSize"
@
current-change=
"goToPage"
/>
</div>
</div>
<!-- 新增/编辑对话框 -->
<el-dialog
v-model=
"dialogVisible"
:title=
"dialogTitle"
width=
"500px"
:close-on-click-modal=
"false"
>
<el-form
ref=
"formRef"
:model=
"form"
:rules=
"formRules"
label-width=
"80px"
>
<el-form-item
label=
"标题"
prop=
"title"
>
<el-input
v-model=
"form.title"
placeholder=
"请输入标题"
/>
</el-form-item>
<el-form-item
label=
"颜色"
prop=
"color"
>
<el-color-picker
v-model=
"form.color"
/>
<span
class=
"color-value"
>
{{ form.color }}
</span>
</el-form-item>
<el-form-item
label=
"排序"
prop=
"sort"
>
<el-input-number
v-model=
"form.sort"
:min=
"0"
:max=
"100"
/>
</el-form-item>
</el-form>
<
template
#
footer
>
<el-button
@
click=
"dialogVisible = false"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"handleSubmit"
>
<el-icon
class=
"btn-icon"
><Upload
/></el-icon>
保存
</el-button>
</
template
>
</el-dialog>
</div>
</template>
<
style
scoped
lang=
"scss"
>
.official-tag-page
{
height
:
100%
;
display
:
flex
;
flex-direction
:
column
;
gap
:
16px
;
}
//
搜索区域
.search-section
{
background
:
#fff
;
border-radius
:
8px
;
padding
:
20px
;
display
:
flex
;
gap
:
12px
;
flex-shrink
:
0
;
.search-select
{
width
:
200px
;
}
}
//
表格区域
.table-section
{
flex
:
1
;
background
:
#fff
;
border-radius
:
8px
;
padding
:
20px
;
display
:
flex
;
flex-direction
:
column
;
min-height
:
0
;
}
.table-wrapper
{
flex
:
1
;
min-height
:
0
;
.color-cell
{
display
:
flex
;
align-items
:
center
;
gap
:
12px
;
.color-block
{
width
:
100%
;
height
:
36px
;
border-radius
:
4px
;
border
:
1px
solid
#e5e7eb
;
flex
:
1
;
}
.color-text
{
color
:
#fff
;
font-size
:
14px
;
font-weight
:
500
;
position
:
absolute
;
left
:
50%
;
transform
:
translateX
(
-50%
);
text-shadow
:
0
0
3px
rgba
(
0
,
0
,
0
,
0.5
);
}
}
}
.pagination-wrapper
{
display
:
flex
;
justify-content
:
flex-end
;
padding-top
:
16px
;
flex-shrink
:
0
;
}
//
对话框内的颜色显示
.color-value
{
margin-left
:
12px
;
color
:
#606266
;
font-family
:
monospace
;
}
.btn-icon
{
margin-right
:
4px
;
}
</
style
>
src/views/backend/contentsMenu/videoManage/index.vue
0 → 100644
View file @
992e6a69
<
script
setup
lang=
"ts"
>
import
{
Search
,
Upload
}
from
'@element-plus/icons-vue'
import
{
usePageSearch
,
useResetData
}
from
'@/hooks'
import
{
addOrUpdateColumn
}
from
'@/api/backend'
import
{
getArticleList
,
updateArticleRecommendAndSort
}
from
'@/api'
import
type
{
FormInstance
,
FormRules
}
from
'element-plus'
import
type
{
BackendColumnListItemDto
,
AddOrUpdateColumnDto
}
from
'@/api/backend'
import
dayjs
from
'dayjs'
import
{
ArticleTypeEnum
,
BooleanFlag
}
from
'@/constants'
import
type
{
ArticleItemDto
}
from
'@/api/article/types'
const
{
loading
,
list
,
total
,
reset
,
goToPage
,
changePageSize
,
refresh
,
searchParams
,
search
}
=
usePageSearch
(
getArticleList
,
{
defaultParams
:
{
type
:
ArticleTypeEnum
.
VIDEO
,
},
})
// 对话框
const
dialogVisible
=
ref
(
false
)
const
dialogTitle
=
computed
(()
=>
(
form
.
value
.
id
?
'编辑标签'
:
'新增标签'
))
const
formRef
=
ref
<
FormInstance
>
()
// 表单数据
const
[
form
]
=
useResetData
<
AddOrUpdateColumnDto
>
({
title
:
''
,
color
:
'#000000'
,
id
:
undefined
,
sort
:
0
,
type
:
'column'
,
})
// 表单验证规则
const
formRules
:
FormRules
=
{
title
:
[{
required
:
true
,
message
:
'请输入标题'
,
trigger
:
'blur'
}],
color
:
[{
required
:
true
,
message
:
'请选择颜色'
,
trigger
:
'change'
}],
sort
:
[{
required
:
true
,
message
:
'请输入排序'
,
trigger
:
'blur'
}],
}
// 是否推荐改变
const
handleIsRecommendChange
=
async
(
val
:
BooleanFlag
,
row
:
ArticleItemDto
)
=>
{
await
updateArticleRecommendAndSort
({
articleId
:
row
.
id
,
recommendSort
:
0
,
// 默认传 0
isRecommend
:
val
,
})
ElMessage
.
success
(
'修改成功'
)
refresh
()
}
// 编辑排序
const
handleEditSort
=
async
(
row
:
ArticleItemDto
)
=>
{
const
{
value
}
=
await
ElMessageBox
.
prompt
(
'请输入排序值'
,
'提示'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
// 数字
inputPattern
:
/^
\d
+$/
,
inputErrorMessage
:
'请输入数字'
,
})
await
updateArticleRecommendAndSort
({
articleId
:
row
.
id
,
recommendSort
:
Number
(
value
),
isRecommend
:
BooleanFlag
.
YES
,
})
ElMessage
.
success
(
'修改成功'
)
refresh
()
}
// 提交表单
const
handleSubmit
=
async
()
=>
{
if
(
!
formRef
.
value
)
return
try
{
await
formRef
.
value
.
validate
()
if
(
form
.
value
.
id
)
{
await
addOrUpdateColumn
(
form
.
value
)
}
else
{
await
addOrUpdateColumn
(
form
.
value
)
}
ElMessage
.
success
(
form
.
value
.
id
?
'编辑成功'
:
'新增成功'
)
dialogVisible
.
value
=
false
if
(
form
.
value
.
id
)
{
search
()
}
else
{
refresh
()
}
}
catch
(
error
)
{
console
.
error
(
'表单验证失败:'
,
error
)
}
}
const
selectedRows
=
ref
<
BackendColumnListItemDto
[]
>
([])
// 选择
const
handleSelectionChange
=
(
selection
:
BackendColumnListItemDto
[])
=>
{
selectedRows
.
value
=
selection
}
</
script
>
<
template
>
<div
class=
"official-tag-page"
>
<!-- 搜索栏 -->
<div
class=
"search-section"
>
<div
class=
"flex-1 flex gap-2"
>
<el-input
v-model=
"searchParams.title"
placeholder=
"请输入标题"
class=
"w-200px"
></el-input>
<div>
<el-button
type=
"primary"
:icon=
"Search"
@
click=
"refresh"
>
搜索
</el-button>
<el-button
@
click=
"reset"
>
重置
</el-button>
</div>
</div>
</div>
<!-- 表格区域 -->
<div
class=
"table-section"
>
<!-- 表格 -->
<div
class=
"table-wrapper"
>
<el-table
v-loading=
"loading"
:data=
"list"
height=
"100%"
@
selection-change=
"handleSelectionChange"
>
<el-table-column
prop=
"title"
label=
"视频标题"
min-width=
"200"
/>
<el-table-column
prop=
"content"
label=
"视频简介"
min-width=
"200"
/>
<el-table-column
prop=
"faceUrl"
label=
"视频封面"
width=
"300"
>
<template
#
default=
"
{ row }">
<el-image
:preview-teleported=
"true"
:src=
"row.faceUrl"
class=
"w-20 h-20 object-cover"
:preview-src-list=
"[row.faceUrl]"
/>
</
template
>
</el-table-column>
<el-table-column
prop=
"videoUrl"
label=
"视频地址"
min-width=
"200"
>
<
template
#
default=
"{ row }"
>
<el-link
type=
"primary"
:href=
"row.videoUrl"
target=
"_blank"
:underline=
"false"
>
{{
row
.
videoUrl
}}
</el-link>
</
template
>
</el-table-column>
<el-table-column
prop=
"releaseStatus"
label=
"标签"
min-width=
"200"
>
<
template
#
default=
"{ row }"
>
<el-tag
v-for=
"tag in row.tagNameList"
:key=
"tag.tagId"
type=
"primary"
class=
"mr-2! mb-2!"
>
{{
tag
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
prop=
"status"
label=
"是否推荐"
min-width=
"200"
>
<
template
#
header
>
<div
class=
"flex items-center gap-2"
>
<span>
是否推荐
</span>
<el-tooltip
content=
"推荐后前台将按照排序值从大到小展示"
placement=
"top"
>
<el-icon><IEpInfoFilled
/></el-icon>
</el-tooltip>
</div>
</
template
>
<
template
#
default=
"{ row }"
>
<div
class=
"flex items-center gap-2"
>
<el-switch
:model-value=
"row.isRecommend"
:active-value=
"BooleanFlag.YES"
:inactive-value=
"BooleanFlag.NO"
@
change=
"(val) => handleIsRecommendChange(val as BooleanFlag, row)"
/>
<el-link
v-if=
"row.isRecommend"
class=
"flex items-center gap-2"
type=
"primary"
@
click=
"handleEditSort(row)"
:underline=
"false"
>
排序值:
{{
row
.
recommendSort
}}
</el-link
>
</div>
</
template
>
</el-table-column>
<el-table-column
prop=
"showName"
label=
"创建人"
min-width=
"200"
/>
<el-table-column
prop=
"createTime"
label=
"创建时间"
min-width=
"200"
>
<
template
#
default=
"{ row }"
>
{{
dayjs
(
row
.
createTime
*
1000
).
format
(
'YYYY-MM-DD HH:mm:ss'
)
}}
</
template
>
</el-table-column>
</el-table>
</div>
<!-- 分页 -->
<div
class=
"pagination-wrapper"
>
<el-pagination
v-model:current-page=
"searchParams.current"
v-model:page-size=
"searchParams.size"
:total=
"total"
:page-sizes=
"[10, 20, 30]"
layout=
"total, sizes, prev, pager, next, jumper"
@
size-change=
"changePageSize"
@
current-change=
"goToPage"
/>
</div>
</div>
<!-- 新增/编辑对话框 -->
<el-dialog
v-model=
"dialogVisible"
:title=
"dialogTitle"
width=
"500px"
:close-on-click-modal=
"false"
>
<el-form
ref=
"formRef"
:model=
"form"
:rules=
"formRules"
label-width=
"80px"
>
<el-form-item
label=
"标题"
prop=
"title"
>
<el-input
v-model=
"form.title"
placeholder=
"请输入标题"
/>
</el-form-item>
<el-form-item
label=
"颜色"
prop=
"color"
>
<el-color-picker
v-model=
"form.color"
/>
<span
class=
"color-value"
>
{{ form.color }}
</span>
</el-form-item>
<el-form-item
label=
"排序"
prop=
"sort"
>
<el-input-number
v-model=
"form.sort"
:min=
"0"
:max=
"100"
/>
</el-form-item>
</el-form>
<
template
#
footer
>
<el-button
@
click=
"dialogVisible = false"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"handleSubmit"
>
<el-icon
class=
"btn-icon"
><Upload
/></el-icon>
保存
</el-button>
</
template
>
</el-dialog>
</div>
</template>
<
style
scoped
lang=
"scss"
>
.official-tag-page
{
height
:
100%
;
display
:
flex
;
flex-direction
:
column
;
gap
:
16px
;
}
//
搜索区域
.search-section
{
background
:
#fff
;
border-radius
:
8px
;
padding
:
20px
;
display
:
flex
;
gap
:
12px
;
flex-shrink
:
0
;
.search-select
{
width
:
200px
;
}
}
//
表格区域
.table-section
{
flex
:
1
;
background
:
#fff
;
border-radius
:
8px
;
padding
:
20px
;
display
:
flex
;
flex-direction
:
column
;
min-height
:
0
;
}
.table-wrapper
{
flex
:
1
;
min-height
:
0
;
.color-cell
{
display
:
flex
;
align-items
:
center
;
gap
:
12px
;
.color-block
{
width
:
100%
;
height
:
36px
;
border-radius
:
4px
;
border
:
1px
solid
#e5e7eb
;
flex
:
1
;
}
.color-text
{
color
:
#fff
;
font-size
:
14px
;
font-weight
:
500
;
position
:
absolute
;
left
:
50%
;
transform
:
translateX
(
-50%
);
text-shadow
:
0
0
3px
rgba
(
0
,
0
,
0
,
0.5
);
}
}
}
.pagination-wrapper
{
display
:
flex
;
justify-content
:
flex-end
;
padding-top
:
16px
;
flex-shrink
:
0
;
}
//
对话框内的颜色显示
.color-value
{
margin-left
:
12px
;
color
:
#606266
;
font-family
:
monospace
;
}
.btn-icon
{
margin-right
:
4px
;
}
</
style
>
src/views/backend/index.vue
View file @
992e6a69
<!-- views/backend/index.vue -->
<
template
>
<div
class=
"backend-layout"
>
<!-- 侧边栏 -->
<aside
class=
"backend-sidebar"
>
<div
class=
"sidebar-header"
>
<img
src=
"/webicon.png"
alt=
"SOUNDASIA"
class=
"logo"
/>
<span
class=
"header-title"
>
企业文化后台管理
</span>
</div>
<
script
lang=
"tsx"
>
import
{
Transition
}
from
'vue'
export
default
defineComponent
(()
=>
{
interface
MenuItem
{
path
:
string
title
:
string
children
?:
MenuItem
[]
}
const
route
=
useRoute
()
const
router
=
useRouter
()
const
menuList
:
MenuItem
[]
=
[
// { path: '/backend/manager', title: '企业文化管理员' },
{
path
:
'/backend/tags'
,
title
:
'官方标签'
},
{
path
:
'/backend/carousel'
,
title
:
'轮播图设置'
},
// { path: '/backend/topic-admin', title: '专栏——管理员' },
// { path: '/backend/columnSettings', title: '专栏——栏目管理' },
// { path: '/backend/interview-admin', title: '专访——管理员' },
// { path: '/backend/interviewSettings', title: '专访——栏目管理' },
// { path: '/backend/videoSettings', title: '视频——栏目管理' },
// { path: '/backend/videoManage', title: '视频管理' },
{
path
:
'/backend/caseManage'
,
title
:
'YAYA案例库管理'
},
{
path
:
'/backend/goodsManage'
,
title
:
'积分商城——商品配置'
},
{
path
:
'/backend/goodsDistribution'
,
title
:
'积分商城——商品分发'
},
// 内容管理
{
path
:
'/backend/contentsMenu'
,
title
:
'内容管理'
,
children
:
[
{
path
:
'/backend/contentsMenu/columnManage'
,
title
:
'专栏管理'
},
{
path
:
'/backend/contentsMenu/interviewManage'
,
title
:
'专访管理'
},
{
path
:
'/backend/contentsMenu/videoManage'
,
title
:
'视频管理'
},
{
path
:
'/backend/contentsMenu/questionManage'
,
title
:
'问吧管理'
},
],
},
// 配置管理
{
path
:
'/backend/settingsMenu'
,
title
:
'配置管理'
,
children
:
[
{
path
:
'/backend/settingsMenu/auctionManage'
,
title
:
'限时竞拍配置'
},
{
path
:
'/backend/settingsMenu/goodsManage'
,
title
:
'积分商城配置'
},
],
},
// 栏目管理
{
path
:
'/backend/columnsMenu'
,
title
:
'栏目管理'
,
children
:
[
{
path
:
'/backend/columnsMenu/columnManage'
,
title
:
'专栏——栏目管理'
},
{
path
:
'/backend/columnsMenu/interviewManage'
,
title
:
'专访——栏目管理'
},
{
path
:
'/backend/columnsMenu/videoManage'
,
title
:
'视频——栏目管理'
},
],
},
]
const
activeMenu
=
computed
(()
=>
route
.
path
)
const
currentTitle
=
computed
(()
=>
{
const
current
=
menuList
.
find
((
item
)
=>
item
.
path
===
route
.
path
)
return
current
?.
title
||
''
})
const
handleMenuSelect
=
(
path
:
string
)
=>
{
router
.
push
(
path
)
}
<el-menu
:default-active=
"activeMenu"
class=
"sidebar-menu"
@
select=
"handleMenuSelect"
>
<el-menu-item
v-for=
"item in menuList"
:key=
"item.path"
:index=
"item.path"
>
<span>
{{
item
.
title
}}
</span>
const
renderMenu
=
(
menuList
:
MenuItem
[])
=>
menuList
.
map
((
item
)
=>
item
.
children
?.
length
?
(
<
el
-
sub
-
menu
key
=
{
item
.
path
}
index
=
{
item
.
path
}
>
{{
title
:
()
=>
{
return
<
span
>
{
item
.
title
}
<
/span
>
},
default
:
()
=>
{
return
renderMenu
(
item
.
children
||
[])
},
}}
<
/el-sub-menu
>
)
:
(
<
el
-
menu
-
item
key
=
{
item
.
path
}
index
=
{
item
.
path
}
>
<
span
>
{
item
.
title
}
<
/span
>
<
/el-menu-item
>
</el-menu>
</aside>
<!-- 右侧主内容区 -->
<div
class=
"backend-content"
>
<!-- 顶部标题栏 -->
<header
class=
"content-header"
>
<div
class=
"header-left"
>
<img
src=
"/webicon.png"
alt=
""
class=
"header-icon"
/>
<h1
class=
"header-title"
>
{{
currentTitle
}}
</h1>
),
)
return
()
=>
(
<
div
class
=
"backend-layout"
>
<
aside
class
=
"backend-sidebar"
>
<
div
class
=
"sidebar-header"
>
<
img
src
=
"/webicon.png"
alt
=
"SOUNDASIA"
class
=
"logo"
/>
<
span
class
=
"header-title"
>
企业文化后台管理
<
/span
>
<
/div
>
<div
class=
"header-right"
>
<!-- 可以放置用户信息、退出登录等 -->
</div>
</header>
<!-- 内容区 -->
<main
class=
"content-main"
>
<router-view
v-slot=
"
{ Component }">
<transition
name=
"fade"
mode=
"out-in"
>
<component
:is=
"Component"
/>
</transition>
</router-view>
</main>
</div>
</div>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
computed
}
from
'vue'
import
{
useRoute
,
useRouter
}
from
'vue-router'
const
route
=
useRoute
()
const
router
=
useRouter
()
interface
MenuItem
{
path
:
string
title
:
string
}
const
menuList
:
MenuItem
[]
=
[
// { path: '/backend/manager', title: '企业文化管理员' },
{
path
:
'/backend/tags'
,
title
:
'官方标签'
},
{
path
:
'/backend/carousel'
,
title
:
'轮播图设置'
},
// { path: '/backend/topic-admin', title: '专栏——管理员' },
{
path
:
'/backend/columnSettings'
,
title
:
'专栏——栏目管理'
},
// { path: '/backend/interview-admin', title: '专访——管理员' },
{
path
:
'/backend/interviewSettings'
,
title
:
'专访——栏目管理'
},
{
path
:
'/backend/videoSettings'
,
title
:
'视频——栏目管理'
},
{
path
:
'/backend/videoManage'
,
title
:
'视频管理'
},
{
path
:
'/backend/caseManage'
,
title
:
'YAYA案例库管理'
},
{
path
:
'/backend/goodsManage'
,
title
:
'积分商城——商品配置'
},
{
path
:
'/backend/goodsDistribution'
,
title
:
'积分商城——商品分发'
},
]
const
activeMenu
=
computed
(()
=>
route
.
path
)
const
currentTitle
=
computed
(()
=>
{
const
current
=
menuList
.
find
((
item
)
=>
item
.
path
===
route
.
path
)
return
current
?.
title
||
''
<
el
-
menu
defaultActive
=
{
activeMenu
.
value
}
class
=
"sidebar-menu"
onSelect
=
{
handleMenuSelect
}
router
collapse
=
{
false
}
>
{
renderMenu
(
menuList
)}
<
/el-menu
>
<
/aside
>
<
div
class
=
"backend-content"
>
<
header
class
=
"content-header"
>
<
div
class
=
"header-left"
>
<
img
src
=
"/webicon.png"
alt
=
""
class
=
"header-icon"
/>
<
h1
class
=
"header-title"
>
{
currentTitle
.
value
}
<
/h1
>
<
/div
>
<
div
class
=
"header-right"
><
/div
>
<
/header
>
<
main
class
=
"content-main"
>
<
RouterView
>
{({
Component
}:
{
Component
:
VNode
})
=>
(
<
Transition
name
=
"fade"
mode
=
"out-in"
>
{
Component
}
<
/Transition
>
)}
<
/RouterView
>
<
/main
>
<
/div
>
<
/div
>
)
})
const
handleMenuSelect
=
(
path
:
string
)
=>
{
router
.
push
(
path
)
}
</
script
>
<
style
scoped
lang=
"scss"
>
...
...
src/views/backend/settingsMenu/goodsManage/index.vue
0 → 100644
View file @
992e6a69
This diff is collapsed.
Click to expand it.
src/views/backend/videoManage/index.vue
View file @
992e6a69
...
...
@@ -22,14 +22,14 @@
<el-button
@
click=
"reset"
>
重置
</el-button>
</div>
<div
class=
"flex justify-end"
>
<
!--
<
div
class=
"flex justify-end"
>
<el-button
type=
"primary"
@
click=
"handleAdd"
>
<el-icon><Plus
/></el-icon>
新增
</el-button>
<el-button
type=
"primary"
@
click=
"handleBatchPublish"
>
批量发布/隐藏
</el-button>
<el-button
type=
"danger"
@
click=
"handleBatchDelete"
>
批量删除
</el-button>
</div>
</div>
-->
</div>
<!-- 表格区域 -->
...
...
@@ -94,12 +94,12 @@
</
template
>
</el-table-column>
<el-table-column
label=
"操作"
width=
"150"
fixed=
"right"
>
<
!-- <
el-table-column label="操作" width="150" fixed="right">
<template #default="{ row }">
<el-button type="primary" link @click="handleEdit(row)">编辑</el-button>
<el-button type="danger" link @click="handleDelete(row)">删除</el-button>
</template>
</el-table-column>
</el-table-column>
-->
</el-table>
</div>
...
...
@@ -150,10 +150,10 @@
</template>
<
script
setup
lang=
"ts"
>
import
{
Search
,
Plus
,
Upload
}
from
'@element-plus/icons-vue'
import
{
Search
,
Upload
}
from
'@element-plus/icons-vue'
import
{
usePageSearch
,
useResetData
}
from
'@/hooks'
import
{
addOrUpdateColumn
,
deleteColumn
,
hideColumn
}
from
'@/api/backend'
import
{
getArticleList
,
updateArticleRecommend
}
from
'@/api'
import
{
getArticleList
,
updateArticleRecommend
AndSort
}
from
'@/api'
import
type
{
FormInstance
,
FormRules
}
from
'element-plus'
import
type
{
BackendColumnListItemDto
,
AddOrUpdateColumnDto
}
from
'@/api/backend'
import
dayjs
from
'dayjs'
...
...
@@ -208,7 +208,7 @@ const handleEdit = (row: BackendColumnListItemDto) => {
// 是否置顶改变
const
handleIsRecommendChange
=
async
(
row
:
ArticleItemDto
)
=>
{
await
updateArticleRecommend
(
row
.
id
)
await
updateArticleRecommend
AndSort
(
row
.
id
)
ElMessage
.
success
(
'修改成功'
)
refresh
()
}
...
...
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