diff --git a/Cunkebao/dist/.vite/manifest.json b/Cunkebao/dist/.vite/manifest.json
index 739932df..eae30d1e 100644
--- a/Cunkebao/dist/.vite/manifest.json
+++ b/Cunkebao/dist/.vite/manifest.json
@@ -1,9 +1,9 @@
{
- "_charts-D0fT04H8.js": {
- "file": "assets/charts-D0fT04H8.js",
+ "_charts-DHgoott5.js": {
+ "file": "assets/charts-DHgoott5.js",
"name": "charts",
"imports": [
- "_ui-qLeQLv1F.js",
+ "_ui-Upu1eBzw.js",
"_vendor-2vc8h_ct.js"
]
},
@@ -11,8 +11,8 @@
"file": "assets/ui-D0C0OGrH.css",
"src": "_ui-D0C0OGrH.css"
},
- "_ui-qLeQLv1F.js": {
- "file": "assets/ui-qLeQLv1F.js",
+ "_ui-Upu1eBzw.js": {
+ "file": "assets/ui-Upu1eBzw.js",
"name": "ui",
"imports": [
"_vendor-2vc8h_ct.js"
@@ -33,18 +33,18 @@
"name": "vendor"
},
"index.html": {
- "file": "assets/index-Bos-kh2O.js",
+ "file": "assets/index-Cqw-bDjj.js",
"name": "index",
"src": "index.html",
"isEntry": true,
"imports": [
"_vendor-2vc8h_ct.js",
- "_ui-qLeQLv1F.js",
+ "_ui-Upu1eBzw.js",
"_utils-6WF66_dS.js",
- "_charts-D0fT04H8.js"
+ "_charts-DHgoott5.js"
],
"css": [
- "assets/index-4EWIsBVv.css"
+ "assets/index-Ta4vyxDJ.css"
]
}
}
\ No newline at end of file
diff --git a/Cunkebao/dist/index.html b/Cunkebao/dist/index.html
index dd832d12..1a1857e9 100644
--- a/Cunkebao/dist/index.html
+++ b/Cunkebao/dist/index.html
@@ -11,13 +11,13 @@
-
+
-
+
-
+
-
+
diff --git a/Cunkebao/src/pages/mobile/workspace/auto-group/detail/index.tsx b/Cunkebao/src/pages/mobile/workspace/auto-group/detail/index.tsx
index a0d88e7d..a82f5d73 100644
--- a/Cunkebao/src/pages/mobile/workspace/auto-group/detail/index.tsx
+++ b/Cunkebao/src/pages/mobile/workspace/auto-group/detail/index.tsx
@@ -1,17 +1,10 @@
import React, { useEffect, useState } from "react";
import { useParams, useNavigate } from "react-router-dom";
-import {
- Card,
- Button,
- Toast,
- ProgressBar,
- Tag,
- SpinLoading,
-} from "antd-mobile";
+import { Card, Button, Toast, ProgressBar, Tag } from "antd-mobile";
import { TeamOutline, LeftOutline } from "antd-mobile-icons";
import { AlertOutlined } from "@ant-design/icons";
import Layout from "@/components/Layout/Layout";
-import MeauMobile from "@/components/MeauMobile/MeauMoible";
+import NavCommon from "@/components/NavCommon/index";
import style from "./index.module.scss";
interface GroupMember {
@@ -280,37 +273,10 @@ const AutoGroupDetail: React.FC = () => {
Toast.show({ content: "所有群组已创建完成" });
};
- if (loading) {
- return (
-
-
- 建群详情
-
- }
- footer={}
- loading={true}
- >
-
-
- );
- }
-
if (!taskDetail) {
return (
-
- 建群详情
-
- }
- footer={}
+ header={ navigate(-1)} />}
>
@@ -330,14 +296,12 @@ const AutoGroupDetail: React.FC = () => {
return (
-
- {taskDetail.name} - 建群详情
-
+ navigate(-1)}
+ />
}
- footer={}
+ loading={loading}
>
diff --git a/Cunkebao/src/pages/mobile/workspace/auto-group/form/api.ts b/Cunkebao/src/pages/mobile/workspace/auto-group/form/api.ts
index 811d1e56..68dc7135 100644
--- a/Cunkebao/src/pages/mobile/workspace/auto-group/form/api.ts
+++ b/Cunkebao/src/pages/mobile/workspace/auto-group/form/api.ts
@@ -1,11 +1,17 @@
import request from "@/api/request";
-// 新建自动建群任务
-export function createAutoGroup(data: any) {
- return request("/api/auto-group/create", data, "POST");
-}
+// 创建朋友圈同步任务
+export const createAutoGroup = (params: any) =>
+ request("/v1/workbench/create", params, "POST");
-// 编辑自动建群任务
-export function updateAutoGroup(id: string, data: any) {
- return request(`/api/auto-group/update/${id}`, data, "POST");
-}
+// 更新朋友圈同步任务
+export const updateAutoGroup = (params: any) =>
+ request("/v1/workbench/update", params, "POST");
+
+// 获取朋友圈同步任务详情
+export const getAutoGroupDetail = (id: string) =>
+ request("/v1/workbench/detail", { id }, "GET");
+
+// 获取朋友圈同步任务列表
+export const getAutoGroupList = (params: any) =>
+ request("/v1/workbench/list", params, "GET");
diff --git a/Cunkebao/src/pages/mobile/workspace/auto-group/form/index.module.scss b/Cunkebao/src/pages/mobile/workspace/auto-group/form/index.module.scss
index 6a7bd15a..df8a4331 100644
--- a/Cunkebao/src/pages/mobile/workspace/auto-group/form/index.module.scss
+++ b/Cunkebao/src/pages/mobile/workspace/auto-group/form/index.module.scss
@@ -22,13 +22,4 @@
text-align: center;
}
-.timeRangeRow {
- display: flex;
- align-items: center;
- gap: 8px;
-}
-.groupSizeRow {
- display: flex;
- align-items: center;
- gap: 8px;
-}
+
diff --git a/Cunkebao/src/pages/mobile/workspace/auto-group/form/index.tsx b/Cunkebao/src/pages/mobile/workspace/auto-group/form/index.tsx
index 1e7dc78d..4b039b3a 100644
--- a/Cunkebao/src/pages/mobile/workspace/auto-group/form/index.tsx
+++ b/Cunkebao/src/pages/mobile/workspace/auto-group/form/index.tsx
@@ -1,45 +1,36 @@
import React, { useState, useEffect } from "react";
import { useNavigate, useParams } from "react-router-dom";
-import {
- Form,
- Input,
- Button,
- Toast,
- Switch,
- Selector,
- TextArea,
- NavBar,
-} from "antd-mobile";
-import { ArrowLeftOutlined } from "@ant-design/icons";
+import { Form, Toast, TextArea } from "antd-mobile";
+import { Input, InputNumber, Button, Switch } from "antd";
import Layout from "@/components/Layout/Layout";
import style from "./index.module.scss";
import { createAutoGroup, updateAutoGroup } from "./api";
+import { AutoGroupFormData } from "./types";
+import DeviceSelection from "@/components/DeviceSelection/index";
+import NavCommon from "@/components/NavCommon/index";
+import dayjs from "dayjs";
+import { DeviceSelectionItem } from "@/components/DeviceSelection/data";
-const defaultForm = {
+const defaultForm: AutoGroupFormData = {
name: "",
- deviceCount: 1,
- targetFriends: 0,
- createInterval: 300,
- maxGroupsPerDay: 10,
- timeRange: { start: "09:00", end: "21:00" },
- groupSize: { min: 20, max: 50 },
- targetTags: [],
- groupNameTemplate: "VIP客户交流群{序号}",
- groupDescription: "",
+ type: 4,
+ deveiceGroups: [], // 设备组
+ deveiceGroupsOptions: [], // 设备组选项
+ startTime: dayjs().format("HH:mm"), // 开始时间 (HH:mm)
+ endTime: dayjs().add(1, "hour").format("HH:mm"), // 结束时间 (HH:mm)
+ groupSizeMin: 20, // 群组最小人数
+ groupSizeMax: 50, // 群组最大人数
+ maxGroupsPerDay: 10, // 每日最大建群数
+ groupNameTemplate: "VIP客户交流群{序号}", // 群名称模板
+ groupDescription: "", // 群描述
+ status: 1, // 是否启用 (1: 启用, 0: 禁用)
};
-const tagOptions = [
- { label: "VIP客户", value: "VIP客户" },
- { label: "高价值", value: "高价值" },
- { label: "潜在客户", value: "潜在客户" },
- { label: "中意向", value: "中意向" },
-];
-
const AutoGroupForm: React.FC = () => {
const navigate = useNavigate();
const { id } = useParams();
const isEdit = Boolean(id);
- const [form, setForm] = useState(defaultForm);
+ const [form, setForm] = useState(defaultForm);
const [loading, setLoading] = useState(false);
useEffect(() => {
@@ -48,15 +39,15 @@ const AutoGroupForm: React.FC = () => {
setForm({
...defaultForm,
name: "VIP客户建群",
- deviceCount: 2,
- targetFriends: 156,
- createInterval: 300,
+ deveiceGroups: [],
+ startTime: dayjs().format("HH:mm"),
+ endTime: dayjs().add(1, "hour").format("HH:mm"),
+ groupSizeMin: 20,
+ groupSizeMax: 50,
maxGroupsPerDay: 20,
- timeRange: { start: "09:00", end: "21:00" },
- groupSize: { min: 20, max: 50 },
- targetTags: ["VIP客户", "高价值"],
groupNameTemplate: "VIP客户交流群{序号}",
groupDescription: "VIP客户专属交流群,提供优质服务",
+ status: 1,
});
}
}, [isEdit, id]);
@@ -65,7 +56,7 @@ const AutoGroupForm: React.FC = () => {
setLoading(true);
try {
if (isEdit) {
- await updateAutoGroup(id as string, form);
+ await updateAutoGroup(form);
Toast.show({ content: "编辑成功" });
} else {
await createAutoGroup(form);
@@ -79,25 +70,24 @@ const AutoGroupForm: React.FC = () => {
}
};
+ const setTaskName = (val: string) => {
+ setForm((f: any) => ({ ...f, name: val }));
+ };
+ const setDeviceGroups = (val: DeviceSelectionItem[]) => {
+ console.log(val);
+ setForm((f: any) => ({
+ ...f,
+ deveiceGroups: val.map(item => item.id),
+ deveiceGroupsOptions: val,
+ }));
+ };
return (
- navigate(-1)}
- />
-
- }
- >
-
- {isEdit ? "编辑建群任务" : "新建建群任务"}
-
-
+ navigate(-1)}
+ />
}
>
@@ -106,7 +96,7 @@ const AutoGroupForm: React.FC = () => {
footer={
diff --git a/Cunkebao/src/pages/mobile/workspace/auto-group/form/types.ts b/Cunkebao/src/pages/mobile/workspace/auto-group/form/types.ts
new file mode 100644
index 00000000..82856afa
--- /dev/null
+++ b/Cunkebao/src/pages/mobile/workspace/auto-group/form/types.ts
@@ -0,0 +1,53 @@
+import { DeviceSelectionItem } from "@/components/DeviceSelection/data";
+// 自动建群表单数据类型定义
+export interface AutoGroupFormData {
+ id?: string; // 任务ID
+ type: number; // 任务类型
+ name: string; // 任务名称
+ deveiceGroups: string[]; // 设备组
+ deveiceGroupsOptions: DeviceSelectionItem[]; // 设备组选项
+ startTime: string; // 开始时间 (YYYY-MM-DD HH:mm:ss)
+ endTime: string; // 结束时间 (YYYY-MM-DD HH:mm:ss)
+ groupSizeMin: number; // 群组最小人数
+ groupSizeMax: number; // 群组最大人数
+ maxGroupsPerDay: number; // 每日最大建群数
+ groupNameTemplate: string; // 群名称模板
+ groupDescription: string; // 群描述
+ status: number; // 是否启用 (1: 启用, 0: 禁用)
+}
+
+// 表单验证规则
+export const formValidationRules = {
+ name: [
+ { required: true, message: "请输入任务名称" },
+ { min: 2, max: 50, message: "任务名称长度应在2-50个字符之间" },
+ ],
+ deveiceGroups: [
+ { required: true, message: "请选择设备组" },
+ { type: "array", min: 1, message: "至少选择一个设备组" },
+ ],
+ startTime: [{ required: true, message: "请选择开始时间" }],
+ endTime: [{ required: true, message: "请选择结束时间" }],
+ groupSizeMin: [
+ { required: true, message: "请输入群组最小人数" },
+ { type: "number", min: 1, max: 500, message: "群组最小人数应在1-500之间" },
+ ],
+ groupSizeMax: [
+ { required: true, message: "请输入群组最大人数" },
+ { type: "number", min: 1, max: 500, message: "群组最大人数应在1-500之间" },
+ ],
+ maxGroupsPerDay: [
+ { required: true, message: "请输入每日最大建群数" },
+ {
+ type: "number",
+ min: 1,
+ max: 100,
+ message: "每日最大建群数应在1-100之间",
+ },
+ ],
+ groupNameTemplate: [
+ { required: true, message: "请输入群名称模板" },
+ { min: 2, max: 100, message: "群名称模板长度应在2-100个字符之间" },
+ ],
+ groupDescription: [{ max: 200, message: "群描述不能超过200个字符" }],
+};
diff --git a/Cunkebao/src/pages/mobile/workspace/auto-group/list/index.tsx b/Cunkebao/src/pages/mobile/workspace/auto-group/list/index.tsx
index 0d919b57..806a3553 100644
--- a/Cunkebao/src/pages/mobile/workspace/auto-group/list/index.tsx
+++ b/Cunkebao/src/pages/mobile/workspace/auto-group/list/index.tsx
@@ -1,7 +1,7 @@
-import React, { useState } from "react";
+import React, { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { Button, Card, Popover, Toast } from "antd-mobile";
-import { Input, Switch } from "antd";
+import { Input, Switch, Pagination } from "antd";
import {
MoreOutline,
AddCircleOutline,
@@ -14,7 +14,7 @@ import {
PlusOutlined,
SearchOutlined,
} from "@ant-design/icons";
-
+import { getAutoGroupList } from "../form/api";
import Layout from "@/components/Layout/Layout";
import style from "./index.module.scss";
import NavCommon from "@/components/NavCommon";
@@ -22,91 +22,92 @@ import NavCommon from "@/components/NavCommon";
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;
+ status: number; // 1 开启, 0 关闭
+ 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 mockTasks: GroupTask[] = [];
-const getStatusColor = (status: string) => {
+const getStatusColor = (status: number) => {
switch (status) {
- case "running":
+ case 1:
return style.statusRunning;
- case "paused":
+ case 0:
return style.statusPaused;
- case "completed":
- return style.statusCompleted;
default:
return style.statusPaused;
}
};
-const getStatusText = (status: string) => {
+const getStatusText = (status: number) => {
switch (status) {
- case "running":
- return "进行中";
- case "paused":
- return "已暂停";
- case "completed":
- return "已完成";
+ case 1:
+ return "开启";
+ case 0:
+ return "关闭";
default:
- return "未知";
+ return "关闭";
}
};
const AutoGroupList: React.FC = () => {
const navigate = useNavigate();
const [searchTerm, setSearchTerm] = useState("");
- const [tasks, setTasks] = useState(mockTasks);
+ const [tasks, setTasks] = useState([]);
+ const [page, setPage] = useState(1);
+ const [pageSize, setPageSize] = useState(10);
+ const [total, setTotal] = useState(0);
+
+ const refreshTasks = async (p = page, ps = pageSize) => {
+ try {
+ const res: any = await getAutoGroupList({ type: 4, page: p, limit: ps });
+ // 兼容不同返回结构
+ const list = res?.list || res?.records || res?.data || [];
+ const totalCount = res?.total || res?.totalCount || list.length;
+ const normalized: GroupTask[] = (list as any[]).map(item => ({
+ id: String(item.id),
+ name: item.name,
+ status: Number(item.status) === 1 ? 1 : 0,
+ deviceCount: Array.isArray(item.config?.devices)
+ ? item.config.devices.length
+ : 0,
+ maxGroupsPerDay: item.config?.maxGroupsPerDay ?? 0,
+ timeRange: {
+ start: item.config?.startTime ?? "-",
+ end: item.config?.endTime ?? "-",
+ },
+ groupSize: {
+ min: item.config?.groupSizeMin ?? 0,
+ max: item.config?.groupSizeMax ?? 0,
+ },
+ creator: item.creatorName ?? "",
+ createTime: item.createTime ?? "",
+ lastCreateTime: item.updateTime ?? "",
+ }));
+ setTasks(normalized);
+ setTotal(totalCount);
+ } catch (e) {
+ Toast.show({ content: "获取列表失败" });
+ }
+ };
+
+ useEffect(() => {
+ refreshTasks(1, pageSize);
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
const handleDelete = (taskId: string) => {
const taskToDelete = tasks.find(task => task.id === taskId);
@@ -144,7 +145,7 @@ const AutoGroupList: React.FC = () => {
task.id === taskId
? {
...task,
- status: task.status === "running" ? "paused" : "running",
+ status: task.status === 1 ? 0 : 1,
}
: task,
),
@@ -187,7 +188,7 @@ const AutoGroupList: React.FC = () => {
{}}
+ onClick={() => refreshTasks()}
loading={false}
className="refresh-btn"
>
@@ -217,9 +218,9 @@ const AutoGroupList: React.FC = () => {
{getStatusText(task.status)}
toggleTaskStatus(task.id)}
- disabled={task.status === "completed"}
+ disabled={false}
style={{ marginLeft: 8 }}
/>
{
执行设备
-
{task.deviceCount} 个
-
-
-
目标好友
- {task.targetFriends} 个
+ {task.deviceCount ?? 0} 个
+
+
+ {/* 该字段暂无,预留位 */}
+
+
时间段
+
+ {task.timeRange?.start} - {task.timeRange?.end}
-
已建群
+
单日上限
- {task.createdGroups} 个
+ {task.maxGroupsPerDay ?? 0} 个
创建人
-
{task.creator}
+
{task.creator ?? ""}
@@ -291,6 +295,21 @@ const AutoGroupList: React.FC = () => {
))
)}
+ {/* 分页 */}
+
+
{
+ setPage(p);
+ setPageSize(ps);
+ refreshTasks(p, ps);
+ }}
+ showSizeChanger
+ showTotal={t => `共 ${t} 条`}
+ />
+
);