feat: 本次提交更新内容如下
This commit is contained in:
@@ -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;
|
||||
@@ -1,8 +0,0 @@
|
||||
import React from "react";
|
||||
import PlaceholderPage from "@/components/PlaceholderPage";
|
||||
|
||||
const AutoGroupDetail: React.FC = () => {
|
||||
return <PlaceholderPage title="自动分组详情" />;
|
||||
};
|
||||
|
||||
export default AutoGroupDetail;
|
||||
6
nkebao/src/pages/workspace/auto-group/detail/api.ts
Normal file
6
nkebao/src/pages/workspace/auto-group/detail/api.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import request from "@/api/request";
|
||||
|
||||
// 获取自动建群任务详情
|
||||
export function getAutoGroupDetail(id: string) {
|
||||
return request(`/api/auto-group/detail/${id}`);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
.autoGroupDetail {
|
||||
// 这里写详情页样式
|
||||
}
|
||||
7
nkebao/src/pages/workspace/auto-group/detail/index.tsx
Normal file
7
nkebao/src/pages/workspace/auto-group/detail/index.tsx
Normal file
@@ -0,0 +1,7 @@
|
||||
import React from "react";
|
||||
|
||||
const AutoGroupDetail: React.FC = () => {
|
||||
return <div>自动建群详情页</div>;
|
||||
};
|
||||
|
||||
export default AutoGroupDetail;
|
||||
11
nkebao/src/pages/workspace/auto-group/form/api.ts
Normal file
11
nkebao/src/pages/workspace/auto-group/form/api.ts
Normal 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");
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
.autoGroupForm {
|
||||
// 这里写新建/编辑页样式
|
||||
}
|
||||
7
nkebao/src/pages/workspace/auto-group/form/index.tsx
Normal file
7
nkebao/src/pages/workspace/auto-group/form/index.tsx
Normal file
@@ -0,0 +1,7 @@
|
||||
import React from "react";
|
||||
|
||||
const AutoGroupForm: React.FC = () => {
|
||||
return <div>自动建群新建/编辑页</div>;
|
||||
};
|
||||
|
||||
export default AutoGroupForm;
|
||||
8
nkebao/src/pages/workspace/auto-group/list/api.ts
Normal file
8
nkebao/src/pages/workspace/auto-group/list/api.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import request from "@/api/request";
|
||||
|
||||
// 获取自动建群任务列表
|
||||
export function getAutoGroupList(params?: any) {
|
||||
return request("/api/auto-group/list", params, "GET");
|
||||
}
|
||||
|
||||
// 其他相关API可按需添加
|
||||
@@ -0,0 +1,3 @@
|
||||
.autoGroupList {
|
||||
// 这里写列表页样式
|
||||
}
|
||||
378
nkebao/src/pages/workspace/auto-group/list/index.tsx
Normal file
378
nkebao/src/pages/workspace/auto-group/list/index.tsx
Normal 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;
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user