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
883f32cb
Commit
883f32cb
authored
Dec 19, 2025
by
lijiabin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
【需求 17679】 feat: 完成专栏专访视频 官方账号发布时可以选择推送功能
parent
19d84a7f
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
257 additions
and
26 deletions
+257
-26
types.ts
src/api/article/types.ts
+10
-2
index.ts
src/utils/wxUtil/index.ts
+2
-2
recommendList.vue
src/views/homePage/homeTab/components/recommendList.vue
+6
-2
videoList.vue
src/views/homePage/homeTab/components/videoList.vue
+4
-4
videoList.vue
src/views/homePage/yaTab/components/videoList.vue
+2
-2
index.vue
src/views/publishLongArticle/index.vue
+111
-4
index.vue
src/views/publishVideo/index.vue
+112
-6
index.vue
src/views/searchPage/index.vue
+5
-1
index.vue
src/views/videoDetail/index.vue
+2
-2
index.vue
src/views/videoSearchList/index.vue
+3
-1
No files found.
src/api/article/types.ts
View file @
883f32cb
...
@@ -61,7 +61,7 @@ export interface AddOrUpdateColumnForm extends AddOrUpdateColumnBase {
...
@@ -61,7 +61,7 @@ export interface AddOrUpdateColumnForm extends AddOrUpdateColumnBase {
/**
/**
* 添加专栏的DTO
* 添加专栏的DTO
*/
*/
export
interface
AddOrUpdateColumnDto
extends
AddOrUpdateColumnBase
{
export
interface
AddOrUpdateColumnDto
extends
AddOrUpdateColumnBase
,
PushSettingBase
{
tagList
:
{
tagId
:
number
;
sort
:
number
}[]
tagList
:
{
tagId
:
number
;
sort
:
number
}[]
}
}
...
@@ -85,10 +85,16 @@ export interface AddOrUpdateInterviewForm extends AddOrUpdateInterviewBase {
...
@@ -85,10 +85,16 @@ export interface AddOrUpdateInterviewForm extends AddOrUpdateInterviewBase {
tagList
:
number
[]
tagList
:
number
[]
}
}
interface
PushSettingBase
{
pushType
:
SendTypeEnum
pushTime
:
string
pushList
:
{
valueId
:
string
;
valueName
:
string
|
number
}[]
}
// 推送设置相关的字段
/**
/**
* 添加专访的DTO
* 添加专访的DTO
*/
*/
export
interface
AddOrUpdateInterviewDto
extends
AddOrUpdateInterviewBase
{
export
interface
AddOrUpdateInterviewDto
extends
AddOrUpdateInterviewBase
,
PushSettingBase
{
tagList
:
{
tagId
:
number
;
sort
:
number
}[]
tagList
:
{
tagId
:
number
;
sort
:
number
}[]
}
}
...
@@ -128,6 +134,7 @@ export interface ArticleItemDto {
...
@@ -128,6 +134,7 @@ export interface ArticleItemDto {
createUserId
:
number
createUserId
:
number
createTime
:
number
createTime
:
number
viewCount
:
number
viewCount
:
number
playCount
:
number
isRecommend
:
BooleanFlag
isRecommend
:
BooleanFlag
type
:
ArticleTypeEnum
type
:
ArticleTypeEnum
isRelateColleague
:
BooleanFlag
isRelateColleague
:
BooleanFlag
...
@@ -222,6 +229,7 @@ export interface ColumnItemDto {
...
@@ -222,6 +229,7 @@ export interface ColumnItemDto {
videoDuration
:
string
videoDuration
:
string
showName
:
string
showName
:
string
showAvatar
:
string
showAvatar
:
string
playCount
:
number
}[]
}[]
}
}
...
...
src/utils/wxUtil/index.ts
View file @
883f32cb
...
@@ -52,12 +52,12 @@ interface IResult {
...
@@ -52,12 +52,12 @@ interface IResult {
userList
:
ISelectUser
[]
userList
:
ISelectUser
[]
departmentList
:
ISelectDept
[]
departmentList
:
ISelectDept
[]
}
}
interface
ISelectUser
{
export
interface
ISelectUser
{
id
:
string
id
:
string
name
:
string
name
:
string
avatar
:
string
avatar
:
string
}
}
interface
ISelectDept
{
export
interface
ISelectDept
{
id
:
string
id
:
string
name
:
string
name
:
string
}
}
...
...
src/views/homePage/homeTab/components/recommendList.vue
View file @
883f32cb
...
@@ -53,7 +53,11 @@
...
@@ -53,7 +53,11 @@
<div
class=
"hidden sm:block w-1 h-1 bg-gray-300 rounded-full"
></div>
<div
class=
"hidden sm:block w-1 h-1 bg-gray-300 rounded-full"
></div>
<div
class=
"flex items-center gap-1 hover:text-blue-500 transition-colors"
>
<div
class=
"flex items-center gap-1 hover:text-blue-500 transition-colors"
>
<el-icon
class=
"text-sm"
><View
/></el-icon>
<el-icon
class=
"text-sm"
><View
/></el-icon>
<span
class=
"font-medium"
>
{{
item
.
viewCount
}}
</span>
<span
class=
"font-medium"
>
{{
item
.
type
===
ArticleTypeEnum
.
VIDEO
?
Math
.
max
(
item
.
playCount
,
item
.
viewCount
)
:
item
.
viewCount
}}
</span>
</div>
</div>
<div
class=
"flex items-center gap-1 hover:text-red-500 transition-colors"
>
<div
class=
"flex items-center gap-1 hover:text-red-500 transition-colors"
>
<el-icon
class=
"text-sm"
><ChatDotRound
/></el-icon>
<el-icon
class=
"text-sm"
><ChatDotRound
/></el-icon>
...
@@ -129,7 +133,7 @@
...
@@ -129,7 +133,7 @@
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
{
usePageSearch
}
from
'@/hooks'
import
{
usePageSearch
}
from
'@/hooks'
import
{
getArticleList
}
from
'@/api'
import
{
getArticleList
}
from
'@/api'
import
{
TABS_REF_KEY
}
from
'@/constants'
import
{
TABS_REF_KEY
,
ArticleTypeEnum
}
from
'@/constants'
import
{
useScrollTop
}
from
'@/hooks'
import
{
useScrollTop
}
from
'@/hooks'
import
dayjs
from
'dayjs'
import
dayjs
from
'dayjs'
import
{
jumpToArticleDetailPage
}
from
'@/utils'
import
{
jumpToArticleDetailPage
}
from
'@/utils'
...
...
src/views/homePage/homeTab/components/videoList.vue
View file @
883f32cb
...
@@ -68,7 +68,7 @@
...
@@ -68,7 +68,7 @@
<el-icon
class=
"text-sm"
>
<el-icon
class=
"text-sm"
>
<View
/>
<View
/>
</el-icon>
</el-icon>
<span>
{{
list
[
0
]?.
viewCount
}}
</span>
<span>
{{
Math
.
max
(
list
[
0
]?.
playCount
,
list
[
0
]?.
viewCount
)
}}
</span>
</div>
</div>
<div
<div
class=
"flex items-center gap-1 bg-black/50 backdrop-blur-sm px-3 py-1.5 rounded-lg"
class=
"flex items-center gap-1 bg-black/50 backdrop-blur-sm px-3 py-1.5 rounded-lg"
...
@@ -162,7 +162,7 @@
...
@@ -162,7 +162,7 @@
<el-icon
class=
"text-sm"
>
<el-icon
class=
"text-sm"
>
<View
/>
<View
/>
</el-icon>
</el-icon>
<span>
{{
item
?.
viewCount
}}
</span>
<span>
{{
Math
.
max
(
item
?.
playCount
,
item
?.
viewCount
)
}}
</span>
</div>
</div>
<div
<div
class=
"flex items-center gap-1 bg-black/50 backdrop-blur-sm px-2 py-1 rounded-lg"
class=
"flex items-center gap-1 bg-black/50 backdrop-blur-sm px-2 py-1 rounded-lg"
...
@@ -259,7 +259,7 @@
...
@@ -259,7 +259,7 @@
<el-icon
class=
"text-sm"
>
<el-icon
class=
"text-sm"
>
<View
/>
<View
/>
</el-icon>
</el-icon>
<span>
{{
item
.
viewCount
}}
</span>
<span>
{{
Math
.
max
(
item
.
playCount
,
item
.
viewCount
)
}}
</span>
</div>
</div>
<div
<div
class=
"flex items-center gap-1 bg-black/50 backdrop-blur-sm px-2 py-1 rounded-lg"
class=
"flex items-center gap-1 bg-black/50 backdrop-blur-sm px-2 py-1 rounded-lg"
...
@@ -355,7 +355,7 @@
...
@@ -355,7 +355,7 @@
<el-icon
class=
"text-sm"
>
<el-icon
class=
"text-sm"
>
<View
/>
<View
/>
</el-icon>
</el-icon>
<span>
{{
item
.
viewCount
}}
</span>
<span>
{{
Math
.
max
(
item
.
playCount
,
item
.
viewCount
)
}}
</span>
</div>
</div>
<div
<div
class=
"flex items-center gap-1 bg-black/50 backdrop-blur-sm px-2 py-1 rounded-lg"
class=
"flex items-center gap-1 bg-black/50 backdrop-blur-sm px-2 py-1 rounded-lg"
...
...
src/views/homePage/yaTab/components/videoList.vue
View file @
883f32cb
...
@@ -68,7 +68,7 @@
...
@@ -68,7 +68,7 @@
<div
class=
"absolute bottom-3 left-3 flex gap-3 text-white text-xs"
>
<div
class=
"absolute bottom-3 left-3 flex gap-3 text-white text-xs"
>
<div
class=
"flex items-center gap-1 bg-black/50 backdrop-blur-sm px-2 py-1 rounded-lg"
>
<div
class=
"flex items-center gap-1 bg-black/50 backdrop-blur-sm px-2 py-1 rounded-lg"
>
<el-icon
class=
"text-sm"
><View
/></el-icon>
<el-icon
class=
"text-sm"
><View
/></el-icon>
<span>
{{
item
.
viewCount
}}
</span>
<span>
{{
Math
.
max
(
item
.
playCount
,
item
.
viewCount
)
}}
</span>
</div>
</div>
<div
class=
"flex items-center gap-1 bg-black/50 backdrop-blur-sm px-2 py-1 rounded-lg"
>
<div
class=
"flex items-center gap-1 bg-black/50 backdrop-blur-sm px-2 py-1 rounded-lg"
>
<el-icon
class=
"text-sm"
><ChatDotRound
/></el-icon>
<el-icon
class=
"text-sm"
><ChatDotRound
/></el-icon>
...
@@ -172,7 +172,7 @@
...
@@ -172,7 +172,7 @@
class=
"flex items-center gap-1 bg-black/50 backdrop-blur-sm px-2 py-1 rounded-lg"
class=
"flex items-center gap-1 bg-black/50 backdrop-blur-sm px-2 py-1 rounded-lg"
>
>
<el-icon
class=
"text-sm"
><View
/></el-icon>
<el-icon
class=
"text-sm"
><View
/></el-icon>
<span>
{{
i
.
viewCount
}}
</span>
<span>
{{
Math
.
max
(
i
.
playCount
,
i
.
viewCount
)
}}
</span>
</div>
</div>
<div
<div
class=
"flex items-center gap-1 bg-black/50 backdrop-blur-sm px-2 py-1 rounded-lg"
class=
"flex items-center gap-1 bg-black/50 backdrop-blur-sm px-2 py-1 rounded-lg"
...
...
src/views/publishLongArticle/index.vue
View file @
883f32cb
...
@@ -70,7 +70,7 @@
...
@@ -70,7 +70,7 @@
>
>
<el-form
ref=
"formRef"
:model=
"form"
:rules=
"rules"
label-position=
"top"
class=
"px-4"
>
<el-form
ref=
"formRef"
:model=
"form"
:rules=
"rules"
label-position=
"top"
class=
"px-4"
>
<!-- 基础设置 -->
<!-- 基础设置 -->
<div
class=
"mb-6"
>
<div>
<!-- 文章类型 -->
<!-- 文章类型 -->
<el-form-item
label=
"文章类型"
prop=
"type"
>
<el-form-item
label=
"文章类型"
prop=
"type"
>
<el-button
<el-button
...
@@ -118,7 +118,7 @@
...
@@ -118,7 +118,7 @@
<
template
<
template
v-if=
"form.type === ArticleTypeEnum.COLUMN || form.type === ArticleTypeEnum.INTERVIEW"
v-if=
"form.type === ArticleTypeEnum.COLUMN || form.type === ArticleTypeEnum.INTERVIEW"
>
>
<div
class=
"mb-6"
>
<div>
<el-form-item
label=
"所属栏目"
prop=
"relateColumnId"
>
<el-form-item
label=
"所属栏目"
prop=
"relateColumnId"
>
<el-select
<el-select
v-model=
"form.relateColumnId"
v-model=
"form.relateColumnId"
...
@@ -165,11 +165,35 @@
...
@@ -165,11 +165,35 @@
<el-radio
:value=
"BooleanFlag.NO"
>
否
</el-radio>
<el-radio
:value=
"BooleanFlag.NO"
>
否
</el-radio>
</el-radio-group>
</el-radio-group>
</el-form-item>
</el-form-item>
<!-- 如果是官方账号的话还有推送相关的配置 -->
<template
v-if=
"userInfo.isOfficialAccount"
>
<el-form-item
label=
"推送给"
>
<el-button
class=
"button-new-tag"
size=
"small"
@
click=
"handleSelectUserAndDept"
>
+ 添加部门
</el-button>
<span
class=
"ml-2 text-sm text-gray-600"
>
{{
selectedText
}}
已选择下属部门
</span>
</el-form-item>
<el-form-item
label=
"推送类型"
prop=
"pushType"
>
<el-radio-group
v-model=
"form.pushType"
>
<el-radio
:value=
"SendTypeEnum.IMMEDIATE"
>
立即推送
</el-radio>
<el-radio
:value=
"SendTypeEnum.SCHEDULED"
>
定时推送
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
v-if=
"form.pushType === SendTypeEnum.SCHEDULED"
prop=
"pushTime"
>
<el-date-picker
v-model=
"form.pushTime"
type=
"datetime"
placeholder=
"选择推送时间"
:disabled-date=
"(time: Date) => time.getTime()
<
Date
.
now
()
-
1000
*
60
*
60
*
24
"
value-format=
"X"
/>
</el-form-item>
</
template
>
</div>
</div>
</template>
</template>
<!-- 发布设置 -->
<!-- 发布设置 -->
<div
class=
"mb-6"
>
<div>
<el-form-item
label=
"发布时间"
prop=
"sendType"
>
<el-form-item
label=
"发布时间"
prop=
"sendType"
>
<el-radio-group
v-model=
"form.sendType"
>
<el-radio-group
v-model=
"form.sendType"
>
<el-radio
:value=
"SendTypeEnum.IMMEDIATE"
>
立即发布
</el-radio>
<el-radio
:value=
"SendTypeEnum.IMMEDIATE"
>
立即发布
</el-radio>
...
@@ -226,11 +250,15 @@ import { useInterviewStore } from '@/stores/interview'
...
@@ -226,11 +250,15 @@ import { useInterviewStore } from '@/stores/interview'
import
{
storeToRefs
}
from
'pinia'
import
{
storeToRefs
}
from
'pinia'
import
{
addOrUpdateArticle
,
addOrUpdatePractice
,
getArticleDetail
}
from
'@/api'
import
{
addOrUpdateArticle
,
addOrUpdatePractice
,
getArticleDetail
}
from
'@/api'
import
{
useRouter
,
useRoute
}
from
'vue-router'
import
{
useRouter
,
useRoute
}
from
'vue-router'
import
{
useUserStore
}
from
'@/stores/user'
import
{
selectDepOrUser
,
type
ISelectDept
,
type
ISelectUser
}
from
'@/utils'
const
columnStore
=
useColumnStore
()
const
columnStore
=
useColumnStore
()
const
{
columnList
}
=
storeToRefs
(
columnStore
)
const
{
columnList
}
=
storeToRefs
(
columnStore
)
const
interviewStore
=
useInterviewStore
()
const
interviewStore
=
useInterviewStore
()
const
{
interviewList
}
=
storeToRefs
(
interviewStore
)
const
{
interviewList
}
=
storeToRefs
(
interviewStore
)
const
userStore
=
useUserStore
()
const
{
userInfo
}
=
storeToRefs
(
userStore
)
const
loading
=
ref
(
false
)
const
loading
=
ref
(
false
)
const
router
=
useRouter
()
const
router
=
useRouter
()
...
@@ -264,6 +292,11 @@ const [form, resetForm] = useResetData({
...
@@ -264,6 +292,11 @@ const [form, resetForm] = useResetData({
sendType
:
SendTypeEnum
.
IMMEDIATE
,
sendType
:
SendTypeEnum
.
IMMEDIATE
,
sendTime
:
''
,
sendTime
:
''
,
releaseStatus
:
ReleaseStatusTypeEnum
.
PUBLISH
,
releaseStatus
:
ReleaseStatusTypeEnum
.
PUBLISH
,
// 推送设置
pushType
:
SendTypeEnum
.
IMMEDIATE
,
pushTime
:
''
,
pushList
:
[],
})
})
const
rules
=
{
const
rules
=
{
...
@@ -279,6 +312,44 @@ const rules = {
...
@@ -279,6 +312,44 @@ const rules = {
isRecommend
:
[{
required
:
true
,
message
:
'是否推荐'
,
trigger
:
'trigger'
}],
isRecommend
:
[{
required
:
true
,
message
:
'是否推荐'
,
trigger
:
'trigger'
}],
isRelateColleague
:
[{
required
:
true
,
message
:
'是否同步同事吧'
,
trigger
:
'trigger'
}],
isRelateColleague
:
[{
required
:
true
,
message
:
'是否同步同事吧'
,
trigger
:
'trigger'
}],
relateColumnId
:
[{
required
:
true
,
message
:
'请选择对应的栏目'
,
trigger
:
'trigger'
}],
relateColumnId
:
[{
required
:
true
,
message
:
'请选择对应的栏目'
,
trigger
:
'trigger'
}],
// 推送设置
pushType
:
[{
required
:
true
,
message
:
'请选择推送类型'
,
trigger
:
'trigger'
}],
pushTime
:
[{
required
:
true
,
message
:
'请选择推送时间'
,
trigger
:
'trigger'
}],
pushList
:
[{
required
:
true
,
message
:
'请选择推送对象'
,
trigger
:
'trigger'
}],
}
// 选中的部门
const
selectedDepts
=
ref
<
{
id
:
string
;
name
:
string
}[]
>
([])
// 选中的成员
const
selectedUsers
=
ref
<
{
id
:
string
;
name
:
string
}[]
>
([])
const
selectedText
=
computed
(()
=>
{
let
text
=
''
if
(
selectedDepts
.
value
.
length
>
0
)
{
text
+=
`已选择
${
selectedDepts
.
value
.
length
}
个部门`
}
if
(
selectedUsers
.
value
.
length
>
0
)
{
text
+=
`已选择
${
selectedUsers
.
value
.
length
}
个成员`
}
return
text
})
const
handleSelectUserAndDept
=
async
()
=>
{
const
{
departmentList
,
userList
}
=
await
selectDepOrUser
({
mode
:
'multi'
,
type
:
[
'user'
,
'department'
],
selectedDepartmentIds
:
selectedDepts
.
value
.
map
((
item
)
=>
item
.
id
),
selectedUserIds
:
selectedUsers
.
value
.
map
((
item
)
=>
item
.
id
),
})
console
.
log
(
departmentList
,
userList
)
selectedDepts
.
value
=
departmentList
.
map
((
item
)
=>
({
id
:
item
.
id
,
name
:
item
.
name
,
}))
selectedUsers
.
value
=
userList
.
map
((
item
)
=>
({
id
:
item
.
id
,
name
:
item
.
name
,
}))
}
}
const
filterTagsFn
=
(
allTags
:
any
[])
=>
{
const
filterTagsFn
=
(
allTags
:
any
[])
=>
{
...
@@ -299,6 +370,25 @@ const transFormData = (releaseStatus: ReleaseStatusTypeEnum) => {
...
@@ -299,6 +370,25 @@ const transFormData = (releaseStatus: ReleaseStatusTypeEnum) => {
data
.
faceUrl
=
data
.
imgUrl
.
split
(
','
)[
0
]
data
.
faceUrl
=
data
.
imgUrl
.
split
(
','
)[
0
]
}
}
}
}
if
(
(
data
.
type
===
ArticleTypeEnum
.
COLUMN
||
data
.
type
===
ArticleTypeEnum
.
INTERVIEW
)
&&
userInfo
.
value
.
isOfficialAccount
)
{
data
.
pushList
=
[
...
selectedDepts
.
value
.
map
((
item
)
=>
({
valueId
:
item
.
id
,
valueType
:
1
,
valueName
:
item
.
name
,
})),
...
selectedUsers
.
value
.
map
((
item
)
=>
({
valueId
:
item
.
id
,
valueType
:
2
,
valueName
:
item
.
name
,
})),
]
}
return
data
return
data
}
}
...
@@ -389,7 +479,24 @@ onActivated(async () => {
...
@@ -389,7 +479,24 @@ onActivated(async () => {
}
else
{
}
else
{
form
.
value
.
faceUrl
=
faceUrl
form
.
value
.
faceUrl
=
faceUrl
}
}
console
.
log
(
form
.
value
,
'form.value'
)
// 回显推送人员设置
if
(
(
type
===
ArticleTypeEnum
.
COLUMN
||
type
===
ArticleTypeEnum
.
INTERVIEW
)
&&
userInfo
.
value
.
isOfficialAccount
)
{
selectedDepts
.
value
=
data
.
pushList
.
filter
((
item
)
=>
item
.
valueType
===
1
)
.
map
((
item
)
=>
({
id
:
item
.
valueId
,
name
:
item
.
valueName
,
}))
selectedUsers
.
value
=
data
.
pushList
.
filter
((
item
)
=>
item
.
valueType
===
2
)
.
map
((
item
)
=>
({
id
:
item
.
valueId
,
name
:
item
.
valueName
,
}))
}
}
}
})
})
</
script
>
</
script
>
...
...
src/views/publishVideo/index.vue
View file @
883f32cb
...
@@ -128,6 +128,55 @@
...
@@ -128,6 +128,55 @@
</el-form-item>
</el-form-item>
</div>
</div>
<!-- 新增推送设置 -->
<template
v-if=
"userInfo.isOfficialAccount"
>
<div
class=
"mb-8"
>
<el-form-item>
<label
class=
"block text-sm font-semibold text-gray-700 mb-3"
>
推送对象
</label>
<div
class=
"w-full"
>
<el-button
class=
"button-new-tag"
size=
"small"
@
click=
"handleSelectUserAndDept"
>
+ 添加部门
</el-button>
<span
class=
"ml-2 text-sm text-gray-600"
>
{{
selectedText
}}
已选择下属部门
</span
>
</div>
</el-form-item>
</div>
<div
class=
"mb-8"
>
<el-form-item
prop=
"pushType"
>
<label
class=
"block text-sm font-semibold text-gray-700 mb-3"
>
推送类型
</label>
<div
class=
"w-full"
>
<el-radio-group
v-model=
"form.pushType"
>
<el-radio
:value=
"SendTypeEnum.IMMEDIATE"
>
立即推送
</el-radio>
<el-radio
:value=
"SendTypeEnum.SCHEDULED"
>
定时推送
</el-radio>
</el-radio-group>
</div>
</el-form-item>
</div>
<div
class=
"mb-8"
>
<el-form-item
v-if=
"form.pushType === SendTypeEnum.SCHEDULED"
prop=
"pushTime"
>
<label
class=
"block text-sm font-semibold text-gray-700 mb-3"
>
推送时间
</label>
<div
class=
"w-full"
>
<el-date-picker
v-model=
"form.pushTime"
type=
"datetime"
placeholder=
"请选择推送时间"
value-format=
"X"
:disabled-date=
"
(time: Date) =>
{
return time.getTime()
<
Date
.
now
()
-
1000
*
60
*
60
*
24
}
"
/>
</div>
</el-form-item>
</div>
</
template
>
<div
class=
"mb-8"
>
<div
class=
"mb-8"
>
<el-form-item
prop=
"relateColumnId"
>
<el-form-item
prop=
"relateColumnId"
>
<label
class=
"block text-sm font-semibold text-gray-700 mb-3"
>
<label
class=
"block text-sm font-semibold text-gray-700 mb-3"
>
...
@@ -185,6 +234,7 @@
...
@@ -185,6 +234,7 @@
<div
class=
"bg-white/70 backdrop-blur-sm rounded-lg shadow-lg border border-white/20 p-6"
>
<div
class=
"bg-white/70 backdrop-blur-sm rounded-lg shadow-lg border border-white/20 p-6"
>
<div
class=
"space-y-3 flex justify-center items-center gap-4"
>
<div
class=
"space-y-3 flex justify-center items-center gap-4"
>
<el-button
<el-button
@
click=
"handleSubmit(ReleaseStatusTypeEnum.DRAFT)"
size=
"large"
size=
"large"
class=
"w-full !border-gray-200 hover:!border-indigo-300 hover:!text-indigo-600 transition-all duration-200"
class=
"w-full !border-gray-200 hover:!border-indigo-300 hover:!text-indigo-600 transition-all duration-200"
>
>
...
@@ -197,7 +247,7 @@
...
@@ -197,7 +247,7 @@
type=
"primary"
type=
"primary"
size=
"large"
size=
"large"
class=
"w-full !bg-gradient-to-r !from-indigo-500 !to-purple-600 !border-none shadow-lg hover:shadow-xl transition-all duration-300"
class=
"w-full !bg-gradient-to-r !from-indigo-500 !to-purple-600 !border-none shadow-lg hover:shadow-xl transition-all duration-300"
@
click=
"handleSubmit"
@
click=
"handleSubmit
(ReleaseStatusTypeEnum.PUBLISH)
"
>
>
<el-icon
class=
"mr-2"
>
<el-icon
class=
"mr-2"
>
<Upload
/>
<Upload
/>
...
@@ -295,6 +345,7 @@ import type { TagItemDto, AddOrUpdateVideoDto } from '@/api'
...
@@ -295,6 +345,7 @@ import type { TagItemDto, AddOrUpdateVideoDto } from '@/api'
import
{
Camera
,
Picture
}
from
'@element-plus/icons-vue'
import
{
Camera
,
Picture
}
from
'@element-plus/icons-vue'
import
{
useVideoStore
,
useUserStore
}
from
'@/stores'
import
{
useVideoStore
,
useUserStore
}
from
'@/stores'
import
{
storeToRefs
}
from
'pinia'
import
{
storeToRefs
}
from
'pinia'
import
{
selectDepOrUser
}
from
'@/utils'
const
videoStore
=
useVideoStore
()
const
videoStore
=
useVideoStore
()
const
{
videoList
}
=
storeToRefs
(
videoStore
)
const
{
videoList
}
=
storeToRefs
(
videoStore
)
...
@@ -323,7 +374,41 @@ const [form, resetData] = useResetData<AddOrUpdateVideoDto>({
...
@@ -323,7 +374,41 @@ const [form, resetData] = useResetData<AddOrUpdateVideoDto>({
faceUrl
:
''
,
// 封面URL
faceUrl
:
''
,
// 封面URL
videoDuration
:
''
,
videoDuration
:
''
,
relateColumnId
:
undefined
,
relateColumnId
:
undefined
,
// 推送设置
pushType
:
SendTypeEnum
.
IMMEDIATE
,
pushTime
:
''
,
pushList
:
[],
})
const
selectedDepts
=
ref
<
{
id
:
string
;
name
:
string
}[]
>
([])
const
selectedUsers
=
ref
<
{
id
:
string
;
name
:
string
}[]
>
([])
const
selectedText
=
computed
(()
=>
{
let
text
=
''
if
(
selectedDepts
.
value
.
length
>
0
)
{
text
+=
`已选择
${
selectedDepts
.
value
.
length
}
个部门`
}
if
(
selectedUsers
.
value
.
length
>
0
)
{
text
+=
`已选择
${
selectedUsers
.
value
.
length
}
个成员`
}
return
text
})
})
const
handleSelectUserAndDept
=
async
()
=>
{
const
{
departmentList
,
userList
}
=
await
selectDepOrUser
({
mode
:
'multi'
,
type
:
[
'user'
,
'department'
],
selectedDepartmentIds
:
selectedDepts
.
value
.
map
((
item
)
=>
item
.
id
),
selectedUserIds
:
selectedUsers
.
value
.
map
((
item
)
=>
item
.
id
),
})
selectedDepts
.
value
=
departmentList
.
map
((
item
)
=>
({
id
:
item
.
id
,
name
:
item
.
name
,
}))
selectedUsers
.
value
=
userList
.
map
((
item
)
=>
({
id
:
item
.
id
,
name
:
item
.
name
,
}))
}
// 封面选择相关
// 封面选择相关
...
@@ -419,17 +504,38 @@ const rules = {
...
@@ -419,17 +504,38 @@ const rules = {
mainTagId
:
[{
required
:
true
,
message
:
'请选择主标签'
,
trigger
:
'change'
}],
mainTagId
:
[{
required
:
true
,
message
:
'请选择主标签'
,
trigger
:
'change'
}],
faceUrl
:
[{
required
:
true
,
message
:
'请选择视频封面'
,
trigger
:
'change'
}],
faceUrl
:
[{
required
:
true
,
message
:
'请选择视频封面'
,
trigger
:
'change'
}],
relateColumnId
:
[{
required
:
true
,
message
:
'请选择视频栏目'
,
trigger
:
'change'
}],
relateColumnId
:
[{
required
:
true
,
message
:
'请选择视频栏目'
,
trigger
:
'change'
}],
// 推送设置
pushType
:
[{
required
:
true
,
message
:
'请选择推送类型'
,
trigger
:
'trigger'
}],
pushTime
:
[{
required
:
true
,
message
:
'请选择推送时间'
,
trigger
:
'trigger'
}],
pushList
:
[{
required
:
true
,
message
:
'请选择推送对象'
,
trigger
:
'trigger'
}],
}
}
const
tansformData
=
()
=>
{
const
tansformData
=
(
releaseStatus
:
ReleaseStatusTypeEnum
)
=>
{
return
{
const
data
=
{
...
form
.
value
,
...
form
.
value
,
tagList
:
[
form
.
value
.
mainTagId
,
...
form
.
value
.
tagList
].
map
((
item
,
index
)
=>
({
tagList
:
[
form
.
value
.
mainTagId
,
...
form
.
value
.
tagList
].
map
((
item
,
index
)
=>
({
tagId
:
Number
(
item
),
tagId
:
Number
(
item
),
sort
:
index
,
sort
:
index
,
})),
})),
mainTagId
:
Number
(
form
.
value
.
mainTagId
),
mainTagId
:
Number
(
form
.
value
.
mainTagId
),
releaseStatus
,
}
if
(
userInfo
.
value
.
isOfficialAccount
)
{
data
.
pushList
=
[
...
selectedDepts
.
value
.
map
((
item
)
=>
({
valueId
:
item
.
id
,
valueType
:
1
,
valueName
:
item
.
name
,
})),
...
selectedUsers
.
value
.
map
((
item
)
=>
({
valueId
:
item
.
id
,
valueType
:
2
,
valueName
:
item
.
name
,
})),
]
}
}
return
data
}
}
const
loading
=
ref
(
false
)
const
loading
=
ref
(
false
)
...
@@ -437,12 +543,12 @@ const resetPageData = () => {
...
@@ -437,12 +543,12 @@ const resetPageData = () => {
resetData
()
resetData
()
locationVideoBlolUrl
.
value
=
''
locationVideoBlolUrl
.
value
=
''
}
}
const
handleSubmit
=
async
()
=>
{
const
handleSubmit
=
async
(
releaseStatus
:
ReleaseStatusTypeEnum
)
=>
{
await
formRef
.
value
?.
validate
()
await
formRef
.
value
?.
validate
()
loading
.
value
=
true
loading
.
value
=
true
try
{
try
{
addOrUpdateArticle
(
tansformData
())
addOrUpdateArticle
(
tansformData
(
releaseStatus
))
ElMessage
.
success
(
'发布
成功'
)
ElMessage
.
success
(
releaseStatus
===
ReleaseStatusTypeEnum
.
PUBLISH
?
'发布成功'
:
'存草稿
成功'
)
resetPageData
()
resetPageData
()
router
.
push
(
'/'
)
router
.
push
(
'/'
)
// 重置数据
// 重置数据
...
...
src/views/searchPage/index.vue
View file @
883f32cb
...
@@ -132,7 +132,11 @@
...
@@ -132,7 +132,11 @@
<el-icon
class=
"text-sm"
>
<el-icon
class=
"text-sm"
>
<View
/>
<View
/>
</el-icon>
</el-icon>
<span
class=
"font-medium text-gray-500"
>
{{
item
.
viewCount
}}
</span>
<span
class=
"font-medium text-gray-500"
>
{{
item
.
type
===
ArticleTypeEnum
.
VIDEO
?
Math
.
max
(
item
.
playCount
,
item
.
viewCount
)
:
item
.
viewCount
}}
</span>
</div>
</div>
<div
class=
"flex items-center gap-1"
>
<div
class=
"flex items-center gap-1"
>
<el-icon
class=
"text-sm"
>
<el-icon
class=
"text-sm"
>
...
...
src/views/videoDetail/index.vue
View file @
883f32cb
...
@@ -15,7 +15,7 @@
...
@@ -15,7 +15,7 @@
<div
class=
"flex items-center text-14px text-gray-500 gap-4 flex-wrap"
>
<div
class=
"flex items-center text-14px text-gray-500 gap-4 flex-wrap"
>
<span
class=
"flex items-center gap-1"
>
<span
class=
"flex items-center gap-1"
>
<i
class=
"i-carbon-play-filled text-gray-400"
></i>
<i
class=
"i-carbon-play-filled text-gray-400"
></i>
{{
formatNumber
(
videoDetail
?.
view
Count
)
}}
播放
{{
formatNumber
(
videoDetail
?.
play
Count
)
}}
播放
</span>
</span>
<span
class=
"flex items-center gap-1"
>
<span
class=
"flex items-center gap-1"
>
<i
class=
"i-carbon-time text-gray-400"
></i>
<i
class=
"i-carbon-time text-gray-400"
></i>
...
@@ -266,7 +266,7 @@ const formatNumber = (num: number) => {
...
@@ -266,7 +266,7 @@ const formatNumber = (num: number) => {
// 播放 记录播放量 + 1
// 播放 记录播放量 + 1
const
handlePlay
=
async
()
=>
{
const
handlePlay
=
async
()
=>
{
await
addVideoPlayCount
(
videoDetail
.
value
.
id
)
await
addVideoPlayCount
(
videoDetail
.
value
.
id
)
videoDetail
.
value
.
viewCount
=
videoDetail
.
value
.
view
Count
+
1
videoDetail
.
value
.
playCount
=
videoDetail
.
value
.
play
Count
+
1
}
}
const
handlePause
=
()
=>
{
const
handlePause
=
()
=>
{
...
...
src/views/videoSearchList/index.vue
View file @
883f32cb
...
@@ -105,7 +105,9 @@
...
@@ -105,7 +105,9 @@
<el-icon
class=
"text-sm"
>
<el-icon
class=
"text-sm"
>
<View
/>
<View
/>
</el-icon>
</el-icon>
<span
class=
"font-medium text-gray-500"
>
{{ item.viewCount }}
</span>
<span
class=
"font-medium text-gray-500"
>
{{
Math.max(item.playCount, item.viewCount)
}}
</span>
</div>
</div>
<div
class=
"flex items-center gap-1"
>
<div
class=
"flex items-center gap-1"
>
<el-icon
class=
"text-sm"
>
<el-icon
class=
"text-sm"
>
...
...
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