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

This commit is contained in:
2025-07-21 16:59:55 +08:00
parent a9b5868016
commit 340bd3e2f5
12 changed files with 441 additions and 22 deletions

View File

@@ -1,10 +0,0 @@
import React from "react";
import PlaceholderPage from "@/components/PlaceholderPage";
const AutoGroup: React.FC = () => {
return (
<PlaceholderPage title="自动分组" showAddButton addButtonText="新建分组" />
);
};
export default AutoGroup;

View File

@@ -1,8 +0,0 @@
import React from "react";
import PlaceholderPage from "@/components/PlaceholderPage";
const AutoGroupDetail: React.FC = () => {
return <PlaceholderPage title="自动分组详情" />;
};
export default AutoGroupDetail;

View File

@@ -0,0 +1,6 @@
import request from "@/api/request";
// 获取自动建群任务详情
export function getAutoGroupDetail(id: string) {
return request(`/api/auto-group/detail/${id}`);
}

View File

@@ -0,0 +1,3 @@
.autoGroupDetail {
// 这里写详情页样式
}

View File

@@ -0,0 +1,7 @@
import React from "react";
const AutoGroupDetail: React.FC = () => {
return <div></div>;
};
export default AutoGroupDetail;

View File

@@ -0,0 +1,11 @@
import request from "@/api/request";
// 新建自动建群任务
export function createAutoGroup(data: any) {
return request("/api/auto-group/create", data, "POST");
}
// 编辑自动建群任务
export function updateAutoGroup(id: string, data: any) {
return request(`/api/auto-group/update/${id}`, data, "POST");
}

View File

@@ -0,0 +1,3 @@
.autoGroupForm {
// 这里写新建/编辑页样式
}

View File

@@ -0,0 +1,7 @@
import React from "react";
const AutoGroupForm: React.FC = () => {
return <div>/</div>;
};
export default AutoGroupForm;

View File

@@ -0,0 +1,8 @@
import request from "@/api/request";
// 获取自动建群任务列表
export function getAutoGroupList(params?: any) {
return request("/api/auto-group/list", params, "GET");
}
// 其他相关API可按需添加

View File

@@ -0,0 +1,3 @@
.autoGroupList {
// 这里写列表页样式
}

View File

@@ -0,0 +1,378 @@
import React, { useState } from "react";
import { useNavigate } from "react-router-dom";
import {
Button,
Card,
Input,
Switch,
ProgressBar,
Popover,
Toast,
} from "antd-mobile";
import {
MoreOutline,
AddCircleOutline,
SearchOutline,
FilterOutline,
UserAddOutline,
ClockCircleOutline,
TeamOutline,
CalendarOutline,
} from "antd-mobile-icons";
import { ReloadOutlined, SettingOutlined } from "@ant-design/icons";
import Layout from "@/components/Layout/Layout";
import MeauMobile from "@/components/MeauMobile/MeauMoible";
import style from "./index.module.scss";
interface GroupTask {
id: string;
name: string;
status: "running" | "paused" | "completed";
deviceCount: number;
targetFriends: number;
createdGroups: number;
lastCreateTime: string;
createTime: string;
creator: string;
createInterval: number;
maxGroupsPerDay: number;
timeRange: { start: string; end: string };
groupSize: { min: number; max: number };
targetTags: string[];
groupNameTemplate: string;
groupDescription: string;
}
const mockTasks: GroupTask[] = [
{
id: "1",
name: "VIP客户建群",
deviceCount: 2,
targetFriends: 156,
createdGroups: 12,
lastCreateTime: "2025-02-06 13:12:35",
createTime: "2024-11-20 19:04:14",
creator: "admin",
status: "running",
createInterval: 300,
maxGroupsPerDay: 20,
timeRange: { start: "09:00", end: "21:00" },
groupSize: { min: 20, max: 50 },
targetTags: ["VIP客户", "高价值"],
groupNameTemplate: "VIP客户交流群{序号}",
groupDescription: "VIP客户专属交流群提供优质服务",
},
{
id: "2",
name: "产品推广建群",
deviceCount: 1,
targetFriends: 89,
createdGroups: 8,
lastCreateTime: "2024-03-04 14:09:35",
createTime: "2024-03-04 14:29:04",
creator: "manager",
status: "paused",
createInterval: 600,
maxGroupsPerDay: 10,
timeRange: { start: "10:00", end: "20:00" },
groupSize: { min: 15, max: 30 },
targetTags: ["潜在客户", "中意向"],
groupNameTemplate: "产品推广群{序号}",
groupDescription: "产品推广交流群,了解最新产品信息",
},
];
const getStatusColor = (status: string) => {
switch (status) {
case "running":
return style.statusRunning;
case "paused":
return style.statusPaused;
case "completed":
return style.statusCompleted;
default:
return style.statusPaused;
}
};
const getStatusText = (status: string) => {
switch (status) {
case "running":
return "进行中";
case "paused":
return "已暂停";
case "completed":
return "已完成";
default:
return "未知";
}
};
const AutoGroupList: React.FC = () => {
const navigate = useNavigate();
const [expandedTaskId, setExpandedTaskId] = useState<string | null>(null);
const [searchTerm, setSearchTerm] = useState("");
const [tasks, setTasks] = useState<GroupTask[]>(mockTasks);
const toggleExpand = (taskId: string) => {
setExpandedTaskId(expandedTaskId === taskId ? null : taskId);
};
const handleDelete = (taskId: string) => {
const taskToDelete = tasks.find((task) => task.id === taskId);
if (!taskToDelete) return;
window.confirm(`确定要删除"${taskToDelete.name}"吗?`) &&
setTasks(tasks.filter((task) => task.id !== taskId));
Toast.show({ content: "删除成功" });
};
const handleEdit = (taskId: string) => {
navigate(`/workspace/auto-group/${taskId}/edit`);
};
const handleView = (taskId: string) => {
navigate(`/workspace/auto-group/${taskId}`);
};
const handleCopy = (taskId: string) => {
const taskToCopy = tasks.find((task) => task.id === taskId);
if (taskToCopy) {
const newTask = {
...taskToCopy,
id: `${Date.now()}`,
name: `${taskToCopy.name} (复制)`,
createTime: new Date().toISOString().replace("T", " ").substring(0, 19),
};
setTasks([...tasks, newTask]);
Toast.show({ content: "复制成功" });
}
};
const toggleTaskStatus = (taskId: string) => {
setTasks((prev) =>
prev.map((task) =>
task.id === taskId
? {
...task,
status: task.status === "running" ? "paused" : "running",
}
: task
)
);
Toast.show({ content: "状态已切换" });
};
const handleCreateNew = () => {
navigate("/workspace/auto-group/new");
};
const filteredTasks = tasks.filter((task) =>
task.name.toLowerCase().includes(searchTerm.toLowerCase())
);
return (
<Layout
header={
<div className={style.headerBar}>
<div className={style.title}></div>
<Button
color="primary"
fill="solid"
size="small"
onClick={handleCreateNew}
>
<AddCircleOutline />
</Button>
</div>
}
footer={<MeauMobile />}
>
<div className={style.autoGroupList}>
<div className={style.searchBar}>
<Input
placeholder="搜索任务名称"
value={searchTerm}
onChange={(val) => setSearchTerm(val)}
prefix={<SearchOutline />}
clearable
/>
<Button size="small" fill="outline" style={{ marginLeft: 8 }}>
<FilterOutline />
</Button>
<Button size="small" fill="outline" style={{ marginLeft: 8 }}>
<ReloadOutlined />
</Button>
</div>
<div className={style.taskList}>
{filteredTasks.length === 0 ? (
<Card className={style.emptyCard}>
<UserAddOutline style={{ fontSize: 48, color: "#ccc" }} />
<div className={style.emptyTitle}></div>
<div className={style.emptyDesc}></div>
<Button color="primary" onClick={handleCreateNew}>
<AddCircleOutline />
</Button>
</Card>
) : (
filteredTasks.map((task) => (
<Card key={task.id} className={style.taskCard}>
<div className={style.taskHeader}>
<div className={style.taskTitle}>{task.name}</div>
<span className={getStatusColor(task.status)}>
{getStatusText(task.status)}
</span>
<Switch
checked={task.status === "running"}
onChange={() => toggleTaskStatus(task.id)}
disabled={task.status === "completed"}
style={{ marginLeft: 8 }}
/>
<Popover
content={
<div>
<div
className={style.menuItem}
onClick={() => handleView(task.id)}
>
</div>
<div
className={style.menuItem}
onClick={() => handleEdit(task.id)}
>
</div>
<div
className={style.menuItem}
onClick={() => handleCopy(task.id)}
>
</div>
<div
className={style.menuItemDanger}
onClick={() => handleDelete(task.id)}
>
</div>
</div>
}
trigger="click"
>
<MoreOutline style={{ fontSize: 20, marginLeft: 8 }} />
</Popover>
</div>
<div className={style.taskInfoGrid}>
<div>
<div className={style.infoLabel}></div>
<div className={style.infoValue}>{task.deviceCount} </div>
</div>
<div>
<div className={style.infoLabel}></div>
<div className={style.infoValue}>
{task.targetFriends}
</div>
</div>
<div>
<div className={style.infoLabel}></div>
<div className={style.infoValue}>
{task.createdGroups}
</div>
</div>
<div>
<div className={style.infoLabel}></div>
<div className={style.infoValue}>{task.creator}</div>
</div>
</div>
<div className={style.taskFooter}>
<div className={style.footerLeft}>
<ClockCircleOutline style={{ marginRight: 4 }} />
{task.lastCreateTime}
</div>
<div className={style.footerRight}>
{task.createTime}
<Button
size="mini"
fill="none"
onClick={() => toggleExpand(task.id)}
style={{ marginLeft: 8 }}
>
{expandedTaskId === task.id ? "收起" : "展开"}
</Button>
</div>
</div>
{expandedTaskId === task.id && (
<div className={style.expandPanel}>
<div className={style.expandGrid}>
<div>
<div className={style.expandTitle}>
<SettingOutlined style={{ marginRight: 4 }} />{" "}
</div>
<div className={style.expandInfo}>
{task.createInterval}
</div>
<div className={style.expandInfo}>
{task.maxGroupsPerDay}
</div>
<div className={style.expandInfo}>
{task.timeRange.start} -{" "}
{task.timeRange.end}
</div>
<div className={style.expandInfo}>
{task.groupSize.min}-{task.groupSize.max}
</div>
</div>
<div>
<div className={style.expandTitle}>
<TeamOutline style={{ marginRight: 4 }} />
</div>
<div className={style.expandTags}>
{task.targetTags.map((tag) => (
<span key={tag} className={style.tag}>
{tag}
</span>
))}
</div>
</div>
<div>
<div className={style.expandTitle}>
<UserAddOutline style={{ marginRight: 4 }} />
</div>
<div className={style.expandInfo}>
{task.groupNameTemplate}
</div>
<div className={style.expandInfo}>
{task.groupDescription}
</div>
</div>
<div>
<div className={style.expandTitle}>
<CalendarOutline style={{ marginRight: 4 }} />{" "}
</div>
<div className={style.expandInfo}>
{task.createdGroups} /{" "}
{task.maxGroupsPerDay}
</div>
<ProgressBar
percent={Math.round(
(task.createdGroups / task.maxGroupsPerDay) * 100
)}
style={{ marginTop: 8 }}
/>
</div>
</div>
</div>
)}
</Card>
))
)}
</div>
</div>
</Layout>
);
};
export default AutoGroupList;

View File

@@ -2,8 +2,9 @@ import Workspace from "@/pages/workspace/main";
import AutoLike from "@/pages/workspace/auto-like/AutoLike";
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 AutoGroupList from "@/pages/workspace/auto-group/list";
import AutoGroupDetail from "@/pages/workspace/auto-group/detail";
import AutoGroupForm from "@/pages/workspace/auto-group/form";
import GroupPush from "@/pages/workspace/group-push/GroupPush";
import NewGroupPush from "@/pages/workspace/group-push/new";
import MomentsSync from "@/pages/workspace/moments-sync/MomentsSync";
@@ -42,10 +43,15 @@ const workspaceRoutes = [
element: <NewAutoLike />,
auth: true,
},
// 自动分组
// 自动建群
{
path: "/workspace/auto-group",
element: <AutoGroup />,
element: <AutoGroupList />,
auth: true,
},
{
path: "/workspace/auto-group/new",
element: <AutoGroupForm />,
auth: true,
},
{
@@ -53,6 +59,11 @@ const workspaceRoutes = [
element: <AutoGroupDetail />,
auth: true,
},
{
path: "/workspace/auto-group/:id/edit",
element: <AutoGroupForm />,
auth: true,
},
// 群发推送
{
path: "/workspace/group-push",