feat: 本次提交更新内容如下
消息推送列表优化
This commit is contained in:
@@ -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;
|
||||
@@ -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 }>();
|
||||
|
||||
107
nkebao/src/pages/workspace/group-push/list/index.module.scss
Normal file
107
nkebao/src/pages/workspace/group-push/list/index.module.scss
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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 ? (
|
||||
@@ -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";
|
||||
|
||||
Reference in New Issue
Block a user