从消息推送助手任务创建中删除弃用的提示示例,更新推送历史API以使用pushTypeCode和状态,并通过改进的类型处理和UI调整来增强PushHistory组件。

This commit is contained in:
超级老白兔
2025-11-20 15:52:05 +08:00
parent 7fdb993f57
commit 16a8656b49
5 changed files with 149 additions and 127 deletions

View File

@@ -32,6 +32,7 @@
.rightColumn {
flex: 1;
max-width: 500px;
display: flex;
flex-direction: column;
gap: 20px;

View File

@@ -746,10 +746,6 @@ const StepSendMessage: React.FC<StepSendMessageProps> = ({
/>
</div>
</div>
<div className={styles.scriptGroupContent}>
{group.messages[0]}
{group.messages.length > 1 && " ..."}
</div>
</div>
))
)}

View File

@@ -1,79 +0,0 @@
帮我对接数据,以下是传参实例,三种模式都是同一界面的。
群发助手传参实例
{
"name": "群群发-新品宣传", // 任务名称
"type": 3, // 工作台类型3=群消息推送
"autoStart": 1, // 保存后自动启动
"status": 1, // 是否启用
"pushType": 0, // 推送方式0=定时1=立即
"targetType": 1, // 目标类型1=群推送
"groupPushSubType": 1, // 群推送子类型1=群群发2=群公告
"startTime": "09:00", // 推送起始时间
"endTime": "20:00", // 推送结束时间
"maxPerDay": 200, // 每日最大推送群数
"pushOrder": 1, // 推送顺序1=最早优先2=最新优先
"wechatGroups": [102, 205, 318], // 选择的微信群 ID 列表
"contentGroups": [11, 12], // 关联内容库 ID 列表
"friendIntervalMin": 10, // 群间最小间隔(秒)
"friendIntervalMax": 25, // 群间最大间隔(秒)
"messageIntervalMin": 2, // 同一群消息间最小间隔(秒)
"messageIntervalMax": 6, // 同一群消息间最大间隔(秒)
"isRandomTemplate": 1, // 是否随机选择话术模板
"postPushTags": [301, 302], // 推送完成后打的标签
ownerWechatIds[123123,1231231] //客服id
}
//群公告传参实例
{
"name": "群公告-双11活动", // 任务名称
"type": 3, // 群消息推送
"autoStart": 0, // 不自动启动
"status": 1, // 启用
"pushType": 1, // 立即推送
"targetType": 1, // 群推送
"groupPushSubType": 2, // 群公告
"startTime": "08:30", // 开始时间
"endTime": "18:30", // 结束时间
"maxPerDay": 80, // 每日最大公告数
"pushOrder": 2, // 最新优先
"wechatGroups": [5021, 5026], // 公告目标群
"announcementContent": "…", // 公告正文
"enableAiRewrite": 1, // 启用 AI 改写
"aiRewritePrompt": "保持活泼口吻…", // AI 改写提示词
"contentGroups": [21], // 关联内容库
"friendIntervalMin": 15, // 群间最小间隔
"friendIntervalMax": 30, // 群间最大间隔
"messageIntervalMin": 3, // 消息间最小间隔
"messageIntervalMax": 9, // 消息间最大间隔
"isRandomTemplate": 0, // 不随机模板
"postPushTags": [], // 推送后标签
ownerWechatIds[123123,1231231] //客服id
}
//好友传参实例
{
"name": "好友私聊-新客转化", // 任务名称
"type": 3, // 群消息推送
"autoStart": 1, // 自动启动
"status": 1, // 启用
"pushType": 0, // 定时推送
"targetType": 2, // 目标类型2=好友推送
"groupPushSubType": 1, // 固定为群群发(好友推送不支持公告)
"startTime": "10:00", // 开始时间
"endTime": "22:00", // 结束时间
"maxPerDay": 150, // 每日最大推送好友数
"pushOrder": 1, // 最早优先
"wechatFriends": ["12312"], // 指定好友列表(可为空数组)
"deviceGroups": [9001, 9002], // 必选:推送设备分组 ID
"contentGroups": [41, 42], // 话术内容库
"friendIntervalMin": 12, // 好友间最小间隔
"friendIntervalMax": 28, // 好友间最大间隔
"messageIntervalMin": 4, // 消息间最小间隔
"messageIntervalMax": 10, // 消息间最大间隔
"isRandomTemplate": 1, // 随机话术
"postPushTags": [501], // 推送后标签
ownerWechatIds[123123,1231231] //客服id
}
请求接口是 queryWorkbenchCreate

View File

@@ -6,8 +6,10 @@ export interface GetPushHistoryParams {
page?: number;
pageSize?: number;
keyword?: string;
pushType?: string;
status?: string;
pushTypeCode?: string; // 推送类型代码friend, group, announcement
status?: string; // 状态pending, completed, failed
workbenchId?: string;
[property: string]: any;
}
// 获取推送历史接口响应
@@ -27,11 +29,30 @@ export interface GetPushHistoryResponse {
*/
export interface GetGroupPushHistoryParams {
keyword?: string;
limit: string;
page: string;
limit?: string | number;
page?: string | number;
pageSize?: string | number;
pushTypeCode?: string;
status?: string;
workbenchId?: string;
[property: string]: any;
}
export const getPushHistory = async (params: GetGroupPushHistoryParams) => {
return request("/v1/workbench/group-push-history", params, "GET");
export const getPushHistory = async (
params: GetGroupPushHistoryParams,
): Promise<GetPushHistoryResponse> => {
// 转换参数格式,确保 limit 和 page 是字符串
const requestParams: Record<string, any> = {
...params,
};
if (params.page !== undefined) {
requestParams.page = String(params.page);
}
if (params.pageSize !== undefined) {
requestParams.limit = String(params.pageSize);
}
return request("/v1/workbench/group-push-history", requestParams, "GET");
};

View File

@@ -15,30 +15,33 @@ import styles from "./index.module.scss";
const { Option } = Select;
// 推送类型枚举
export enum PushType {
FRIEND_MESSAGE = "friend-message", // 好友消息
GROUP_MESSAGE = "group-message", // 群消息
GROUP_ANNOUNCEMENT = "group-announcement", // 群公告
// 推送类型代码枚举
export enum PushTypeCode {
FRIEND = "friend", // 好友消息
GROUP = "group", // 群消息
ANNOUNCEMENT = "announcement", // 群公告
}
// 推送状态枚举
export enum PushStatus {
PENDING = "pending", // 进行中
COMPLETED = "completed", // 已完成
IN_PROGRESS = "in-progress", // 进行中
FAILED = "failed", // 失败
}
// 推送历史记录接口
export interface PushHistoryRecord {
id: string;
pushType: PushType;
pushContent: string;
workbenchId: number;
taskName: string;
pushType: string; // 推送类型中文名称,如 "好友消息"
pushTypeCode: string; // 推送类型代码,如 "friend"
targetCount: number;
successCount: number;
failureCount: number;
status: PushStatus;
failCount: number;
status: string; // 状态代码,如 "pending"
statusText: string; // 状态中文名称,如 "进行中"
createTime: string;
contentLibraryName: string; // 内容库名称
}
const PushHistory: React.FC = () => {
@@ -59,8 +62,8 @@ const PushHistory: React.FC = () => {
try {
setLoading(true);
const params: any = {
page,
pageSize: pagination.pageSize,
page: String(page),
limit: String(pagination.pageSize),
};
if (searchValue.trim()) {
@@ -68,7 +71,7 @@ const PushHistory: React.FC = () => {
}
if (typeFilter !== "all") {
params.pushType = typeFilter;
params.pushTypeCode = typeFilter;
}
if (statusFilter !== "all") {
@@ -157,13 +160,33 @@ const PushHistory: React.FC = () => {
};
// 获取推送类型标签
const getPushTypeTag = (type: PushType) => {
const typeMap = {
[PushType.FRIEND_MESSAGE]: { text: "好友消息", color: "#666" },
[PushType.GROUP_MESSAGE]: { text: "群消息", color: "#666" },
[PushType.GROUP_ANNOUNCEMENT]: { text: "群公告", color: "#666" },
const getPushTypeTag = (pushType: string, pushTypeCode?: string) => {
// 优先使用中文名称,如果没有则根据代码映射
if (pushType) {
const colorMap: Record<string, string> = {
: "#1890ff",
: "#52c41a",
: "#722ed1",
};
return (
<Tag
color={colorMap[pushType] || "#666"}
style={{ borderRadius: "12px" }}
>
{pushType}
</Tag>
);
}
// 如果没有中文名称,根据代码映射
const codeMap: Record<string, { text: string; color: string }> = {
[PushTypeCode.FRIEND]: { text: "好友消息", color: "#1890ff" },
[PushTypeCode.GROUP]: { text: "群消息", color: "#52c41a" },
[PushTypeCode.ANNOUNCEMENT]: { text: "群公告", color: "#722ed1" },
};
const config = typeMap[type] || { text: "未知", color: "#666" };
const config =
pushTypeCode && codeMap[pushTypeCode]
? codeMap[pushTypeCode]
: { text: pushType || "未知", color: "#666" };
return (
<Tag color={config.color} style={{ borderRadius: "12px" }}>
{config.text}
@@ -172,14 +195,31 @@ const PushHistory: React.FC = () => {
};
// 获取状态标签
const getStatusTag = (status: PushStatus) => {
const statusMap = {
const getStatusTag = (status: string, statusText?: string) => {
// 优先使用中文状态文本
const displayText = statusText || status;
// 根据状态代码或文本匹配
const statusMap: Record<
string,
{ text: string; color: string; icon: React.ReactNode }
> = {
[PushStatus.COMPLETED]: {
text: "已完成",
color: "#52c41a",
icon: <CheckCircleOutlined />,
},
[PushStatus.IN_PROGRESS]: {
completed: {
text: "已完成",
color: "#52c41a",
icon: <CheckCircleOutlined />,
},
[PushStatus.PENDING]: {
text: "进行中",
color: "#1890ff",
icon: <ClockCircleOutlined />,
},
pending: {
text: "进行中",
color: "#1890ff",
icon: <ClockCircleOutlined />,
@@ -189,12 +229,43 @@ const PushHistory: React.FC = () => {
color: "#ff4d4f",
icon: <CloseCircleOutlined />,
},
failed: {
text: "失败",
color: "#ff4d4f",
icon: <CloseCircleOutlined />,
},
};
const config = statusMap[status] || {
text: "未知",
color: "#666",
icon: null,
// 根据状态文本匹配
const textMap: Record<
string,
{ text: string; color: string; icon: React.ReactNode }
> = {
: {
text: "已完成",
color: "#52c41a",
icon: <CheckCircleOutlined />,
},
: {
text: "进行中",
color: "#1890ff",
icon: <ClockCircleOutlined />,
},
: {
text: "失败",
color: "#ff4d4f",
icon: <CloseCircleOutlined />,
},
};
const config = textMap[displayText] ||
statusMap[status] ||
statusMap[status.toLowerCase()] || {
text: displayText,
color: "#666",
icon: null,
};
return (
<Tag
color={config.color}
@@ -217,15 +288,26 @@ const PushHistory: React.FC = () => {
dataIndex: "pushType",
key: "pushType",
width: 120,
render: (type: PushType) => getPushTypeTag(type),
render: (pushType: string, record: PushHistoryRecord) =>
getPushTypeTag(pushType, record.pushTypeCode),
},
{
title: "任务名称",
dataIndex: "pushContent",
key: "pushContent",
dataIndex: "taskName",
key: "taskName",
ellipsis: true,
render: (text: string) => <span style={{ color: "#333" }}>{text}</span>,
},
{
title: "内容库",
dataIndex: "contentLibraryName",
key: "contentLibraryName",
width: 150,
ellipsis: true,
render: (text: string) => (
<span style={{ color: "#666", fontSize: "13px" }}>{text || "-"}</span>
),
},
{
title: "目标数量",
dataIndex: "targetCount",
@@ -246,8 +328,8 @@ const PushHistory: React.FC = () => {
},
{
title: "失败数",
dataIndex: "failureCount",
key: "failureCount",
dataIndex: "failCount",
key: "failCount",
width: 100,
align: "center" as const,
render: (count: number) => (
@@ -260,7 +342,8 @@ const PushHistory: React.FC = () => {
key: "status",
width: 120,
align: "center" as const,
render: (status: PushStatus) => getStatusTag(status),
render: (status: string, record: PushHistoryRecord) =>
getStatusTag(status, record.statusText),
},
{
title: "创建时间",
@@ -329,9 +412,9 @@ const PushHistory: React.FC = () => {
suffixIcon={<span></span>}
>
<Option value="all"></Option>
<Option value={PushType.FRIEND_MESSAGE}></Option>
<Option value={PushType.GROUP_MESSAGE}></Option>
<Option value={PushType.GROUP_ANNOUNCEMENT}></Option>
<Option value={PushTypeCode.FRIEND}></Option>
<Option value={PushTypeCode.GROUP}></Option>
<Option value={PushTypeCode.ANNOUNCEMENT}></Option>
</Select>
<Select
value={statusFilter}
@@ -340,8 +423,8 @@ const PushHistory: React.FC = () => {
suffixIcon={<span></span>}
>
<Option value="all"></Option>
<Option value={PushStatus.PENDING}></Option>
<Option value={PushStatus.COMPLETED}></Option>
<Option value={PushStatus.IN_PROGRESS}></Option>
<Option value={PushStatus.FAILED}></Option>
</Select>
</div>
@@ -353,7 +436,7 @@ const PushHistory: React.FC = () => {
columns={columns}
dataSource={dataSource}
loading={loading}
rowKey="id"
rowKey="workbenchId"
pagination={false}
className={styles.dataTable}
/>