feat: 本次提交更新内容如下

消息推送列表优化
This commit is contained in:
笔记本里的永平
2025-07-21 16:57:02 +08:00
parent 7ce3a92250
commit c8dda56bc9
6 changed files with 125 additions and 273 deletions

View File

@@ -1,250 +0,0 @@
import React, { useEffect, useState } from "react";
import { useParams, useNavigate } from "react-router-dom";
import { Button, Spin, message } from "antd";
import { ArrowLeftOutlined } from "@ant-design/icons";
import Layout from "@/components/Layout/Layout";
import MeauMobile from "@/components/MeauMobile/MeauMoible";
import StepIndicator from "./form/components/StepIndicator";
import BasicSettings from "./form/components/BasicSettings";
import GroupSelector from "./form/components/GroupSelector";
import ContentSelector from "./form/components/ContentSelector";
import {
getGroupPushTaskDetail,
updateGroupPushTask,
GroupPushTask,
} from "@/api/groupPush";
const steps = [
{ id: 1, title: "步骤 1", subtitle: "基础设置" },
{ id: 2, title: "步骤 2", subtitle: "选择社群" },
{ id: 3, title: "步骤 3", subtitle: "选择内容库" },
{ id: 4, title: "步骤 4", subtitle: "京东联盟" },
];
const EditGroupPush: React.FC = () => {
const { id } = useParams<{ id: string }>();
const navigate = useNavigate();
const [currentStep, setCurrentStep] = useState(1);
const [loading, setLoading] = useState(true);
const [saving, setSaving] = useState(false);
const [formData, setFormData] = useState<any>(null);
useEffect(() => {
if (!id) return;
setLoading(true);
getGroupPushTaskDetail(id)
.then((res) => {
const task = res.data || res;
setFormData({
name: task.name,
pushTimeStart: task.timeRange?.start || "06:00",
pushTimeEnd: task.timeRange?.end || "23:59",
dailyPushCount: task.maxPushPerDay,
pushOrder: task.pushOrder || "latest",
isLoopPush: task.isLoopPush || false,
isImmediatePush: task.pushMode === "immediate",
isEnabled: task.isEnabled || false,
groups: (task.targetGroups || []).map(
(name: string, idx: number) => ({
id: String(idx + 1),
name,
avatar: "",
serviceAccount: { id: "", name: "", avatar: "" },
})
),
contentLibraries: (task.contentLibraries || []).map(
(name: string, idx: number) => ({
id: String(idx + 1),
name,
targets: [],
})
),
});
})
.finally(() => setLoading(false));
}, [id]);
const handleBasicSettingsNext = (values: any) => {
setFormData((prev: any) => ({ ...prev, ...values }));
setCurrentStep(2);
};
const handleGroupsChange = (groups: any[]) => {
setFormData((prev: any) => ({ ...prev, groups }));
};
const handleLibrariesChange = (contentLibraries: any[]) => {
setFormData((prev: any) => ({ ...prev, contentLibraries }));
};
const handleSave = async () => {
if (!formData.name.trim()) {
message.error("请输入任务名称");
return;
}
if (!formData.groups || formData.groups.length === 0) {
message.error("请选择至少一个社群");
return;
}
if (!formData.contentLibraries || formData.contentLibraries.length === 0) {
message.error("请选择至少一个内容库");
return;
}
setSaving(true);
try {
const apiData = {
name: formData.name,
timeRange: {
start: formData.pushTimeStart,
end: formData.pushTimeEnd,
},
maxPushPerDay: formData.dailyPushCount,
pushOrder: formData.pushOrder,
isLoopPush: formData.isLoopPush,
isImmediatePush: formData.isImmediatePush,
isEnabled: formData.isEnabled,
targetGroups: formData.groups.map((g: any) => g.name),
contentLibraries: formData.contentLibraries.map((c: any) => c.name),
pushMode: formData.isImmediatePush
? ("immediate" as const)
: ("scheduled" as const),
messageType: "text" as const,
messageContent: "",
targetTags: [],
pushInterval: 60,
};
const response = await updateGroupPushTask(id!, apiData);
if (response.code === 200) {
message.success("保存成功");
navigate("/workspace/group-push");
} else {
message.error("保存失败,请稍后重试");
}
} catch (error) {
message.error("保存失败,请稍后重试");
} finally {
setSaving(false);
}
};
const handleCancel = () => {
navigate("/workspace/group-push");
};
if (loading || !formData) {
return (
<Layout
header={
<div
style={{
background: "#fff",
padding: "0 16px",
fontWeight: 600,
fontSize: 18,
}}
>
<ArrowLeftOutlined
onClick={() => navigate(-1)}
style={{ marginRight: 12, cursor: "pointer" }}
/>
</div>
}
footer={<MeauMobile />}
>
<div style={{ padding: 48, textAlign: "center" }}>
<Spin />
</div>
</Layout>
);
}
return (
<Layout
header={
<div
style={{
background: "#fff",
padding: "0 16px",
fontWeight: 600,
fontSize: 18,
}}
>
<ArrowLeftOutlined
onClick={() => navigate(-1)}
style={{ marginRight: 12, cursor: "pointer" }}
/>
</div>
}
footer={<MeauMobile />}
>
<div style={{ maxWidth: 600, margin: "0 auto", padding: 16 }}>
<StepIndicator currentStep={currentStep} steps={steps} />
<div style={{ marginTop: 32 }}>
{currentStep === 1 && (
<BasicSettings
defaultValues={{
name: formData.name,
pushTimeStart: formData.pushTimeStart,
pushTimeEnd: formData.pushTimeEnd,
dailyPushCount: formData.dailyPushCount,
pushOrder: formData.pushOrder,
isLoopPush: formData.isLoopPush,
isImmediatePush: formData.isImmediatePush,
isEnabled: formData.isEnabled,
}}
onNext={handleBasicSettingsNext}
onSave={handleSave}
onCancel={handleCancel}
loading={saving}
/>
)}
{currentStep === 2 && (
<GroupSelector
selectedGroups={formData.groups}
onGroupsChange={handleGroupsChange}
onPrevious={() => setCurrentStep(1)}
onNext={() => setCurrentStep(3)}
onSave={handleSave}
onCancel={handleCancel}
loading={saving}
/>
)}
{currentStep === 3 && (
<ContentSelector
selectedLibraries={formData.contentLibraries}
onLibrariesChange={handleLibrariesChange}
onPrevious={() => setCurrentStep(2)}
onNext={() => setCurrentStep(4)}
onSave={handleSave}
onCancel={handleCancel}
loading={saving}
/>
)}
{currentStep === 4 && (
<div style={{ padding: 32, textAlign: "center", color: "#888" }}>
<div
style={{
marginTop: 24,
display: "flex",
justifyContent: "center",
gap: 8,
}}
>
<Button onClick={() => setCurrentStep(3)} disabled={saving}>
</Button>
<Button type="primary" onClick={handleSave} loading={saving}>
</Button>
<Button onClick={handleCancel} disabled={saving}>
</Button>
</div>
</div>
)}
</div>
</div>
</Layout>
);
};
export default EditGroupPush;

View File

@@ -11,7 +11,7 @@ import {
import Layout from "@/components/Layout/Layout";
import MeauMobile from "@/components/MeauMobile/MeauMoible";
import { getGroupPushTaskDetail, GroupPushTask } from "@/api/groupPush";
import styles from "./GroupPush.module.scss";
import styles from "./index.module.scss";
const Detail: React.FC = () => {
const { id } = useParams<{ id: string }>();

View File

@@ -0,0 +1,107 @@
.searchBar {
display: flex;
gap: 8px;
padding: 16px;
}
.refresh-btn {
height: 38px;
width: 40px;
padding: 0;
border-radius: 8px;
}
.taskList {
display: flex;
flex-direction: column;
gap: 16px;
padding: 0 16px;
}
.emptyCard {
text-align: center;
padding: 48px 0;
background: #fff;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0,0,0,0.04);
}
.taskCard {
background: #fff;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0,0,0,0.04);
padding: 20px 16px 12px 16px;
}
.taskHeader {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 12px;
}
.taskTitle {
display: flex;
align-items: center;
font-size: 16px;
font-weight: 600;
}
.taskActions {
display: flex;
align-items: center;
gap: 8px;
}
.taskInfoGrid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px 16px;
font-size: 13px;
color: #666;
margin-bottom: 12px;
}
.progressBlock {
margin-bottom: 12px;
}
.progressLabel {
font-size: 13px;
color: #888;
margin-bottom: 4px;
}
.taskFooter {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 12px;
color: #888;
border-top: 1px dashed #eee;
padding-top: 8px;
margin-top: 8px;
}
.expandedPanel {
margin-top: 16px;
padding-top: 16px;
border-top: 1px dashed #eee;
}
.expandedGrid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 16px;
}
@media (max-width: 600px) {
.taskCard {
padding: 12px 6px 8px 6px;
}
.expandedGrid {
grid-template-columns: 1fr;
}
}

View File

@@ -1,5 +1,6 @@
import React, { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { NavBar } from "antd-mobile";
import {
PlusOutlined,
SearchOutlined,
@@ -37,7 +38,7 @@ import {
copyGroupPushTask,
GroupPushTask,
} from "@/api/groupPush";
import styles from "./GroupPush.module.scss";
import styles from "./index.module.scss";
const { Search } = Input;
@@ -146,37 +147,31 @@ const GroupPush: React.FC = () => {
return (
<Layout
header={
<div style={{ background: "#fff", padding: "0 16px" }}>
<div style={{ display: "flex", alignItems: "center", height: 48 }}>
<span style={{ fontWeight: 600, fontSize: 18 }}></span>
<Button
type="primary"
icon={<PlusOutlined />}
style={{ marginLeft: "auto" }}
onClick={handleCreateNew}
>
</Button>
</div>
</div>
<NavBar back={null} style={{ background: "#fff" }}>
<span style={{ fontWeight: 600, fontSize: 18 }}></span>
</NavBar>
}
footer={<MeauMobile />}
>
<div className={styles.bg}>
<div className={styles.searchBar}>
<Search
placeholder="搜索任务名称"
<Input
placeholder="搜索计划名称"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
enterButton={<SearchOutlined />}
style={{ maxWidth: 320 }}
prefix={<SearchOutlined />}
allowClear
size="large"
/>
<Button
icon={<ReloadOutlined />}
className={styles["refresh-btn"]}
size="small"
onClick={fetchTasks}
loading={loading}
style={{ marginLeft: 8 }}
/>
>
<ReloadOutlined />
</Button>
</div>
<div className={styles.taskList}>
{filteredTasks.length === 0 ? (

View File

@@ -4,7 +4,7 @@ import NewAutoLike from "@/pages/workspace/auto-like/NewAutoLike";
import AutoLikeDetail from "@/pages/workspace/auto-like/AutoLikeDetail";
import AutoGroup from "@/pages/workspace/auto-group/AutoGroup";
import AutoGroupDetail from "@/pages/workspace/auto-group/Detail";
import GroupPush from "@/pages/workspace/group-push/GroupPush";
import GroupPush from "@/pages/workspace/group-push/list";
import FormGroupPush from "@/pages/workspace/group-push/form";
import DetailGroupPush from "@/pages/workspace/group-push/detail";
import MomentsSync from "@/pages/workspace/moments-sync/MomentsSync";