Commit dcc2b827 by lijiabin

【需求 25171】feat: 专栏/专访/视频/问吧/帖子管理新增撤回推送功能

对接后端新增的 pushInfo(直接挂在文章列表接口返回里,不用再单独查一次
推送状态)和 recallPush 接口。列表新增"推送状态"列:展示未设置推送/已
推送/定时待推送/已全部撤回,recallable 为 true 时显示撤回按钮(定时待
推送显示"取消定时推送"),点击二次确认后调用撤回接口并刷新列表。表头
加了提示:推送后 24 小时内才能撤回,超时会自动隐藏按钮;定时待推送的
可以随时取消。
parent 3186589c
......@@ -222,6 +222,17 @@ export const updateArticleRecommendAndSort = (data: UpdateArticleRecommendAndSor
}
/**
* 撤回/取消推送。定时待推送时是取消这次定时推送,已推送时是撤回已发送的批次;
* 已经撤回的批次会自动跳过,重复调用失败可以重试。能不能点由列表 pushInfo.recallable 决定。
*/
export const recallPush = (articleId: number) => {
return service.request({
url: `/cultureEventPushPersons/recallPush?articleId=${articleId}`,
method: 'POST',
})
}
/**
* 删除文章接口
*/
export const deleteArticle = (id: number) => {
......
......@@ -256,6 +256,24 @@ export interface ArticleItemDto {
deptId: string
isShowLatest?: BooleanFlag
publishTime: number
// 官方账号推送的文章才有这个字段,列表接口直接带出来,不用再单独查一次推送状态
pushInfo?: ArticlePushInfoDto
}
/**
* 文章的推送状态(列表接口 pushInfo 字段),后端已经算好了 recallable(含 24 小时窗口、
* 定时待推送等情况),前端直接拿来控制"撤回推送"按钮显隐,不用自己拿 lastSendTime 去算。
*/
export interface ArticlePushInfoDto {
articleId: number
/** 0 未推送 / 1 已推送 / 2 定时待推送 / 3 已全部撤回 */
pushStatus: number
recallable: boolean
totalBatch: number
recalledBatch: number
receiverNum: number
lastSendTime: number | null
scheduleTime: number | null
}
/**
......
......@@ -2,7 +2,7 @@
import { Search, Upload } from '@element-plus/icons-vue'
import { usePageSearch, useResetData } from '@/hooks'
import { addOrUpdateColumn } from '@/api/backend'
import { getArticleList, updateArticleRecommendAndSort } from '@/api'
import { getArticleList, updateArticleRecommendAndSort, recallPush } from '@/api'
import type { FormInstance, FormRules } from 'element-plus'
import type { BackendColumnListItemDto, AddOrUpdateColumnDto } from '@/api/backend'
import dayjs from 'dayjs'
......@@ -11,7 +11,7 @@ import type { ArticleItemDto } from '@/api/article/types'
import { push } from 'notivue'
import { useMessageBox } from '@/hooks'
const { prompt } = useMessageBox()
const { prompt, confirm } = useMessageBox()
const { loading, list, total, reset, goToPage, changePageSize, refresh, searchParams, search } =
usePageSearch(getArticleList, {
defaultParams: {
......@@ -107,6 +107,34 @@ const handleShowContent = (row: ArticleItemDto) => {
dangerouslyUseHTMLString: true,
})
}
// 推送状态文案:0 文章未设置推送 / 1 已推送 / 2 定时待推送 / 3 已全部撤回
const pushStatusTextMap: Record<number, string> = {
0: '文章未设置推送',
1: '已推送',
2: '定时待推送',
3: '已全部撤回',
}
const pushStatusText = (status: number) => pushStatusTextMap[status] ?? '未知'
// 撤回是有时间限制的(推送后 24 小时内才能撤回),超时后按钮会自动隐藏,这里加个提示说明规则
const PUSH_RECALL_TOOLTIP =
'已推送的内容仅支持在推送后 24 小时内撤回,超过 24 小时将无法撤回;定时待推送的可以随时取消'
// 撤回推送:能不能点由后端算好的 pushInfo.recallable 决定,定时待推送时文案改成"取消定时推送"
const handleRecallPush = async (row: ArticleItemDto) => {
const isScheduled = row.pushInfo?.pushStatus === 2
await confirm({
title: '提示',
message: isScheduled
? '确定要取消这次定时推送吗?'
: '确定要撤回这条推送吗?已经收到通知的用户不会撤回消息。',
type: 'warning',
})
await recallPush(row.id)
push.success(isScheduled ? '取消定时推送成功' : '撤回成功')
refresh()
}
</script>
<template>
......@@ -189,6 +217,32 @@ const handleShowContent = (row: ArticleItemDto) => {
{{ dayjs(row.createTime * 1000).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<!-- 只有官方账号推送过的文章才会带 pushInfo -->
<el-table-column label="推送状态" min-width="220">
<template #header>
<div class="flex items-center gap-2">
<span>推送状态</span>
<el-tooltip :content="PUSH_RECALL_TOOLTIP" placement="top">
<el-icon><IEpInfoFilled /></el-icon>
</el-tooltip>
</div>
</template>
<template #default="{ row }">
<div v-if="row.pushInfo" class="flex items-center gap-2">
<span>{{ pushStatusText(row.pushInfo.pushStatus) }}</span>
<el-button
v-if="row.pushInfo.recallable"
type="danger"
link
@click="handleRecallPush(row)"
>
{{ row.pushInfo.pushStatus === 2 ? '取消定时推送' : '撤回推送' }}
</el-button>
</div>
<span v-else>{{ pushStatusText(0) }}</span>
</template>
</el-table-column>
</el-table>
</div>
......
......@@ -2,7 +2,7 @@
import { Search, Upload } from '@element-plus/icons-vue'
import { usePageSearch, useResetData } from '@/hooks'
import { addOrUpdateColumn } from '@/api/backend'
import { getArticleList, updateArticleRecommendAndSort } from '@/api'
import { getArticleList, updateArticleRecommendAndSort, recallPush } from '@/api'
import type { FormInstance, FormRules } from 'element-plus'
import type { BackendColumnListItemDto, AddOrUpdateColumnDto } from '@/api/backend'
import dayjs from 'dayjs'
......@@ -11,7 +11,7 @@ import type { ArticleItemDto } from '@/api/article/types'
import { push } from 'notivue'
import { useMessageBox } from '@/hooks'
const { prompt } = useMessageBox()
const { prompt, confirm } = useMessageBox()
const { loading, list, total, reset, goToPage, changePageSize, refresh, searchParams, search } =
usePageSearch(getArticleList, {
defaultParams: {
......@@ -108,6 +108,34 @@ const handleShowContent = (row: ArticleItemDto) => {
dangerouslyUseHTMLString: true,
})
}
// 推送状态文案:0 文章未设置推送 / 1 已推送 / 2 定时待推送 / 3 已全部撤回
const pushStatusTextMap: Record<number, string> = {
0: '文章未设置推送',
1: '已推送',
2: '定时待推送',
3: '已全部撤回',
}
const pushStatusText = (status: number) => pushStatusTextMap[status] ?? '未知'
// 撤回是有时间限制的(推送后 24 小时内才能撤回),超时后按钮会自动隐藏,这里加个提示说明规则
const PUSH_RECALL_TOOLTIP =
'已推送的内容仅支持在推送后 24 小时内撤回,超过 24 小时将无法撤回;定时待推送的可以随时取消'
// 撤回推送:能不能点由后端算好的 pushInfo.recallable 决定,定时待推送时文案改成"取消定时推送"
const handleRecallPush = async (row: ArticleItemDto) => {
const isScheduled = row.pushInfo?.pushStatus === 2
await confirm({
title: '提示',
message: isScheduled
? '确定要取消这次定时推送吗?'
: '确定要撤回这条推送吗?已经收到通知的用户不会撤回消息。',
type: 'warning',
})
await recallPush(row.id)
push.success(isScheduled ? '取消定时推送成功' : '撤回成功')
refresh()
}
</script>
<template>
......@@ -190,6 +218,32 @@ const handleShowContent = (row: ArticleItemDto) => {
{{ dayjs(row.createTime * 1000).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<!-- 只有官方账号推送过的文章才会带 pushInfo -->
<el-table-column label="推送状态" min-width="220">
<template #header>
<div class="flex items-center gap-2">
<span>推送状态</span>
<el-tooltip :content="PUSH_RECALL_TOOLTIP" placement="top">
<el-icon><IEpInfoFilled /></el-icon>
</el-tooltip>
</div>
</template>
<template #default="{ row }">
<div v-if="row.pushInfo" class="flex items-center gap-2">
<span>{{ pushStatusText(row.pushInfo.pushStatus) }}</span>
<el-button
v-if="row.pushInfo.recallable"
type="danger"
link
@click="handleRecallPush(row)"
>
{{ row.pushInfo.pushStatus === 2 ? '取消定时推送' : '撤回推送' }}
</el-button>
</div>
<span v-else>{{ pushStatusText(0) }}</span>
</template>
</el-table-column>
</el-table>
</div>
......
......@@ -2,7 +2,7 @@
import { Search, Upload } from '@element-plus/icons-vue'
import { usePageSearch, useResetData } from '@/hooks'
import { addOrUpdateColumn } from '@/api/backend'
import { getArticleList, updateArticleRecommendAndSort } from '@/api'
import { getArticleList, updateArticleRecommendAndSort, recallPush } from '@/api'
import type { FormInstance, FormRules } from 'element-plus'
import type { BackendColumnListItemDto, AddOrUpdateColumnDto } from '@/api/backend'
import dayjs from 'dayjs'
......@@ -11,7 +11,7 @@ import type { ArticleItemDto } from '@/api/article/types'
import { push } from 'notivue'
import { useMessageBox } from '@/hooks'
const { prompt } = useMessageBox()
const { prompt, confirm } = useMessageBox()
const { loading, list, total, reset, goToPage, changePageSize, refresh, searchParams, search } =
usePageSearch(getArticleList, {
defaultParams: {
......@@ -98,6 +98,34 @@ const selectedRows = ref<BackendColumnListItemDto[]>([])
const handleSelectionChange = (selection: BackendColumnListItemDto[]) => {
selectedRows.value = selection
}
// 推送状态文案:0 文章未设置推送 / 1 已推送 / 2 定时待推送 / 3 已全部撤回
const pushStatusTextMap: Record<number, string> = {
0: '文章未设置推送',
1: '已推送',
2: '定时待推送',
3: '已全部撤回',
}
const pushStatusText = (status: number) => pushStatusTextMap[status] ?? '未知'
// 撤回是有时间限制的(推送后 24 小时内才能撤回),超时后按钮会自动隐藏,这里加个提示说明规则
const PUSH_RECALL_TOOLTIP =
'已推送的内容仅支持在推送后 24 小时内撤回,超过 24 小时将无法撤回;定时待推送的可以随时取消'
// 撤回推送:能不能点由后端算好的 pushInfo.recallable 决定,定时待推送时文案改成"取消定时推送"
const handleRecallPush = async (row: ArticleItemDto) => {
const isScheduled = row.pushInfo?.pushStatus === 2
await confirm({
title: '提示',
message: isScheduled
? '确定要取消这次定时推送吗?'
: '确定要撤回这条推送吗?已经收到通知的用户不会撤回消息。',
type: 'warning',
})
await recallPush(row.id)
push.success(isScheduled ? '取消定时推送成功' : '撤回成功')
refresh()
}
</script>
<template>
......@@ -183,6 +211,32 @@ const handleSelectionChange = (selection: BackendColumnListItemDto[]) => {
{{ dayjs(row.createTime * 1000).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<!-- 只有官方账号推送过的文章才会带 pushInfo -->
<el-table-column label="推送状态" min-width="220">
<template #header>
<div class="flex items-center gap-2">
<span>推送状态</span>
<el-tooltip :content="PUSH_RECALL_TOOLTIP" placement="top">
<el-icon><IEpInfoFilled /></el-icon>
</el-tooltip>
</div>
</template>
<template #default="{ row }">
<div v-if="row.pushInfo" class="flex items-center gap-2">
<span>{{ pushStatusText(row.pushInfo.pushStatus) }}</span>
<el-button
v-if="row.pushInfo.recallable"
type="danger"
link
@click="handleRecallPush(row)"
>
{{ row.pushInfo.pushStatus === 2 ? '取消定时推送' : '撤回推送' }}
</el-button>
</div>
<span v-else>{{ pushStatusText(0) }}</span>
</template>
</el-table-column>
</el-table>
</div>
......
......@@ -2,7 +2,7 @@
import { Search, Upload } from '@element-plus/icons-vue'
import { usePageSearch, useResetData } from '@/hooks'
import { addOrUpdateColumn } from '@/api/backend'
import { getArticleList, updateArticleRecommendAndSort } from '@/api'
import { getArticleList, updateArticleRecommendAndSort, recallPush } from '@/api'
import type { FormInstance, FormRules } from 'element-plus'
import type { BackendColumnListItemDto, AddOrUpdateColumnDto } from '@/api/backend'
import dayjs from 'dayjs'
......@@ -11,7 +11,7 @@ import type { ArticleItemDto } from '@/api/article/types'
import { push } from 'notivue'
import { useMessageBox } from '@/hooks'
const { prompt } = useMessageBox()
const { prompt, confirm } = useMessageBox()
const { loading, list, total, reset, goToPage, changePageSize, refresh, searchParams, search } =
usePageSearch(getArticleList, {
defaultParams: {
......@@ -98,6 +98,34 @@ const selectedRows = ref<BackendColumnListItemDto[]>([])
const handleSelectionChange = (selection: BackendColumnListItemDto[]) => {
selectedRows.value = selection
}
// 推送状态文案:0 文章未设置推送 / 1 已推送 / 2 定时待推送 / 3 已全部撤回
const pushStatusTextMap: Record<number, string> = {
0: '文章未设置推送',
1: '已推送',
2: '定时待推送',
3: '已全部撤回',
}
const pushStatusText = (status: number) => pushStatusTextMap[status] ?? '未知'
// 撤回是有时间限制的(推送后 24 小时内才能撤回),超时后按钮会自动隐藏,这里加个提示说明规则
const PUSH_RECALL_TOOLTIP =
'已推送的内容仅支持在推送后 24 小时内撤回,超过 24 小时将无法撤回;定时待推送的可以随时取消'
// 撤回推送:能不能点由后端算好的 pushInfo.recallable 决定,定时待推送时文案改成"取消定时推送"
const handleRecallPush = async (row: ArticleItemDto) => {
const isScheduled = row.pushInfo?.pushStatus === 2
await confirm({
title: '提示',
message: isScheduled
? '确定要取消这次定时推送吗?'
: '确定要撤回这条推送吗?已经收到通知的用户不会撤回消息。',
type: 'warning',
})
await recallPush(row.id)
push.success(isScheduled ? '取消定时推送成功' : '撤回成功')
refresh()
}
</script>
<template>
......@@ -188,6 +216,32 @@ const handleSelectionChange = (selection: BackendColumnListItemDto[]) => {
{{ dayjs(row.createTime * 1000).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<!-- 只有官方账号推送过的文章才会带 pushInfo -->
<el-table-column label="推送状态" min-width="220">
<template #header>
<div class="flex items-center gap-2">
<span>推送状态</span>
<el-tooltip :content="PUSH_RECALL_TOOLTIP" placement="top">
<el-icon><IEpInfoFilled /></el-icon>
</el-tooltip>
</div>
</template>
<template #default="{ row }">
<div v-if="row.pushInfo" class="flex items-center gap-2">
<span>{{ pushStatusText(row.pushInfo.pushStatus) }}</span>
<el-button
v-if="row.pushInfo.recallable"
type="danger"
link
@click="handleRecallPush(row)"
>
{{ row.pushInfo.pushStatus === 2 ? '取消定时推送' : '撤回推送' }}
</el-button>
</div>
<span v-else>{{ pushStatusText(0) }}</span>
</template>
</el-table-column>
</el-table>
</div>
......
......@@ -2,7 +2,12 @@
import { Search, Upload } from '@element-plus/icons-vue'
import { usePageSearch, useResetData } from '@/hooks'
import { addOrUpdateColumn } from '@/api/backend'
import { getArticleList, updateArticleRecommendAndSort, updateArticleShowLatest } from '@/api'
import {
getArticleList,
updateArticleRecommendAndSort,
updateArticleShowLatest,
recallPush,
} from '@/api'
import type { FormInstance, FormRules } from 'element-plus'
import type { BackendColumnListItemDto, AddOrUpdateColumnDto } from '@/api/backend'
import dayjs from 'dayjs'
......@@ -10,7 +15,7 @@ import { ArticleTypeEnum, BooleanFlag } from '@/constants'
import type { ArticleItemDto } from '@/api/article/types'
import { push } from 'notivue'
import { useMessageBox } from '@/hooks'
const { prompt } = useMessageBox()
const { prompt, confirm } = useMessageBox()
const { loading, list, total, reset, goToPage, changePageSize, refresh, searchParams, search } =
usePageSearch(getArticleList, {
......@@ -107,6 +112,34 @@ const selectedRows = ref<BackendColumnListItemDto[]>([])
const handleSelectionChange = (selection: BackendColumnListItemDto[]) => {
selectedRows.value = selection
}
// 推送状态文案:0 文章未设置推送 / 1 已推送 / 2 定时待推送 / 3 已全部撤回
const pushStatusTextMap: Record<number, string> = {
0: '文章未设置推送',
1: '已推送',
2: '定时待推送',
3: '已全部撤回',
}
const pushStatusText = (status: number) => pushStatusTextMap[status] ?? '未知'
// 撤回是有时间限制的(推送后 24 小时内才能撤回),超时后按钮会自动隐藏,这里加个提示说明规则
const PUSH_RECALL_TOOLTIP =
'已推送的内容仅支持在推送后 24 小时内撤回,超过 24 小时将无法撤回;定时待推送的可以随时取消'
// 撤回推送:能不能点由后端算好的 pushInfo.recallable 决定,定时待推送时文案改成"取消定时推送"
const handleRecallPush = async (row: ArticleItemDto) => {
const isScheduled = row.pushInfo?.pushStatus === 2
await confirm({
title: '提示',
message: isScheduled
? '确定要取消这次定时推送吗?'
: '确定要撤回这条推送吗?已经收到通知的用户不会撤回消息。',
type: 'warning',
})
await recallPush(row.id)
push.success(isScheduled ? '取消定时推送成功' : '撤回成功')
refresh()
}
</script>
<template>
......@@ -211,6 +244,32 @@ const handleSelectionChange = (selection: BackendColumnListItemDto[]) => {
{{ dayjs(row.createTime * 1000).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<!-- 只有官方账号推送过的文章才会带 pushInfo -->
<el-table-column label="推送状态" min-width="220">
<template #header>
<div class="flex items-center gap-2">
<span>推送状态</span>
<el-tooltip :content="PUSH_RECALL_TOOLTIP" placement="top">
<el-icon><IEpInfoFilled /></el-icon>
</el-tooltip>
</div>
</template>
<template #default="{ row }">
<div v-if="row.pushInfo" class="flex items-center gap-2">
<span>{{ pushStatusText(row.pushInfo.pushStatus) }}</span>
<el-button
v-if="row.pushInfo.recallable"
type="danger"
link
@click="handleRecallPush(row)"
>
{{ row.pushInfo.pushStatus === 2 ? '取消定时推送' : '撤回推送' }}
</el-button>
</div>
<span v-else>{{ pushStatusText(0) }}</span>
</template>
</el-table-column>
</el-table>
</div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment