diff --git a/nkebao/src/pages/workspace/moments-sync/new.tsx b/nkebao/src/pages/workspace/moments-sync/new.tsx deleted file mode 100644 index b32d13a6..00000000 --- a/nkebao/src/pages/workspace/moments-sync/new.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import React from "react"; -import PlaceholderPage from "@/components/PlaceholderPage"; - -const NewMomentsSync: React.FC = () => { - return ; -}; - -export default NewMomentsSync; diff --git a/nkebao/src/pages/workspace/moments-sync/new/index.module.scss b/nkebao/src/pages/workspace/moments-sync/new/index.module.scss new file mode 100644 index 00000000..3cf58561 --- /dev/null +++ b/nkebao/src/pages/workspace/moments-sync/new/index.module.scss @@ -0,0 +1,243 @@ +.formBg { + padding: 16px; +} + +.formSteps { + display: flex; + justify-content: center; + margin-bottom: 32px; + gap: 32px; +} + +.formStepIndicator { + display: flex; + flex-direction: column; + align-items: center; + color: #bbb; + font-size: 13px; + font-weight: 400; + transition: color 0.2s; +} + +.formStepActive { + color: #188eee; + font-weight: 600; +} + +.formStepDone { + color: #19c37d; +} + +.formStepNum { + width: 28px; + height: 28px; + border-radius: 50%; + background: #e5e7eb; + color: #888; + display: flex; + align-items: center; + justify-content: center; + font-size: 15px; + margin-bottom: 4px; +} + +.formStepActive .formStepNum { + background: #188eee; + color: #fff; +} + +.formStepDone .formStepNum { + background: #19c37d; + color: #fff; +} + +.formStep { + background: #fff; + border-radius: 10px; + box-shadow: 0 2px 8px rgba(0,0,0,0.06); + padding: 32px 24px 24px 24px; + width: 100%; + max-width: 420px; + margin: 0 auto 24px auto; +} + +.formItem { + margin-bottom: 24px; +} + +.formLabel { + font-size: 15px; + color: #222; + font-weight: 500; + margin-bottom: 10px; +} + +.input { + height: 44px; + border-radius: 8px; + font-size: 15px; +} + +.timeRow { + display: flex; + align-items: center; +} + +.inputTime { + width: 90px; + height: 40px; + border-radius: 8px; + font-size: 15px; +} + +.timeTo { + margin: 0 8px; + color: #888; +} + +.counterRow { + display: flex; + align-items: center; + gap: 0; +} + +.counterBtn { + width: 40px; + height: 40px; + border-radius: 8px; + background: #fff; + border: 1px solid #e5e7eb; + font-size: 20px; + color: #188eee; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: border 0.2s; +} + +.counterBtn:hover { + border: 1px solid #188eee; +} + +.counterValue { + width: 48px; + text-align: center; + font-size: 18px; + font-weight: 600; + color: #222; +} + +.counterUnit { + margin-left: 8px; + color: #888; + font-size: 14px; +} + +.accountTypeRow { + display: flex; + gap: 12px; +} + +.accountTypeBtn { + flex: 1; + height: 44px; + border-radius: 8px; + background: #fff; + border: 1px solid #e5e7eb; + font-size: 15px; + color: #666; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: all 0.2s; + position: relative; +} + +.accountTypeBtn:hover { + border: 1px solid #188eee; +} + +.accountTypeActive { + background: #f0f8ff; + border: 1px solid #188eee; + color: #188eee; +} + +.questionIcon { + position: absolute; + right: 8px; + top: 50%; + transform: translateY(-50%); + font-size: 14px; + color: #999; +} + +.switchRow { + display: flex; + align-items: center; + justify-content: space-between; +} + +.switchLabel { + font-size: 15px; + color: #222; + font-weight: 500; +} + +.switch { + margin-top: 0; +} + +.searchInput { + height: 44px; + border-radius: 8px; + font-size: 15px; +} + +.searchIcon { + color: #999; + font-size: 16px; +} + +.selectedTip { + font-size: 13px; + color: #888; + margin-top: 8px; +} + +.formStepBtnRow { + display: flex; + justify-content: flex-end; + gap: 12px; + margin-top: 32px; +} + +.prevBtn { + height: 44px; + border-radius: 8px; + font-size: 15px; + min-width: 100px; +} + +.nextBtn { + height: 44px; + border-radius: 8px; + font-size: 15px; + min-width: 100px; +} + +.completeBtn { + height: 44px; + border-radius: 8px; + font-size: 15px; + min-width: 100px; +} + +.formLoading { + min-height: 200px; + display: flex; + align-items: center; + justify-content: center; +} diff --git a/nkebao/src/pages/workspace/moments-sync/new/index.tsx b/nkebao/src/pages/workspace/moments-sync/new/index.tsx new file mode 100644 index 00000000..f42ff0f0 --- /dev/null +++ b/nkebao/src/pages/workspace/moments-sync/new/index.tsx @@ -0,0 +1,326 @@ +import React, { useState, useEffect, useCallback } from "react"; +import { useNavigate, useParams } from "react-router-dom"; +import { Button, Input, Switch, message, Spin } from "antd"; +import { ArrowLeftOutlined } from "@ant-design/icons"; +import { NavBar } from "antd-mobile"; + +import Layout from "@/components/Layout/Layout"; +import style from "./index.module.scss"; +import request from "@/api/request"; + +const steps = ["基础设置", "设备选择", "内容库选择"]; + +const defaultForm = { + taskName: "", + startTime: "06:00", + endTime: "23:59", + syncCount: 5, + accountType: "business" as "business" | "personal", + enabled: true, + selectedDevices: [] as string[], + selectedLibraries: [] as string[], +}; + +const NewMomentsSync: React.FC = () => { + const navigate = useNavigate(); + const { id } = useParams<{ id: string }>(); + const isEditMode = !!id; + const [currentStep, setCurrentStep] = useState(0); + const [loading, setLoading] = useState(false); + const [formData, setFormData] = useState({ ...defaultForm }); + + // 获取详情(编辑) + const fetchDetail = useCallback(async () => { + if (!id) return; + setLoading(true); + try { + const res = await request("/v1/workbench/detail", { id }, "GET"); + if (res) { + setFormData({ + taskName: res.name, + startTime: res.timeRange?.start || "06:00", + endTime: res.timeRange?.end || "23:59", + syncCount: res.config?.syncCount || res.syncCount || 5, + accountType: res.accountType === 1 ? "business" : "personal", + enabled: res.status === 1, + selectedDevices: res.config?.devices || [], + selectedLibraries: res.config?.contentLibraryNames || [], + }); + } + } catch { + message.error("获取详情失败"); + } finally { + setLoading(false); + } + }, [id]); + + useEffect(() => { + if (isEditMode) fetchDetail(); + }, [isEditMode, fetchDetail]); + + // 步骤切换 + const next = () => setCurrentStep((s) => Math.min(s + 1, steps.length - 1)); + const prev = () => setCurrentStep((s) => Math.max(s - 1, 0)); + + // 表单数据更新 + const updateForm = (data: Partial) => { + setFormData((prev) => ({ ...prev, ...data })); + }; + + // 提交 + const handleSubmit = async () => { + if (!formData.taskName.trim()) { + message.error("请输入任务名称"); + return; + } + if (formData.selectedDevices.length === 0) { + message.error("请选择设备"); + return; + } + if (formData.selectedLibraries.length === 0) { + message.error("请选择内容库"); + return; + } + setLoading(true); + try { + const params = { + name: formData.taskName, + devices: formData.selectedDevices, + contentLibraries: formData.selectedLibraries, + syncCount: formData.syncCount, + startTime: formData.startTime, + endTime: formData.endTime, + accountType: formData.accountType === "business" ? 1 : 2, + status: formData.enabled ? 1 : 2, + type: 2, + }; + if (isEditMode && id) { + await request("/v1/workbench/update", { id, ...params }, "POST"); + message.success("更新成功"); + navigate(`/workspace/moments-sync/${id}`); + } else { + await request("/v1/workbench/create", params, "POST"); + message.success("创建成功"); + navigate("/workspace/moments-sync"); + } + } catch { + message.error(isEditMode ? "更新失败" : "创建失败"); + } finally { + setLoading(false); + } + }; + + // 步骤内容 + const renderStep = () => { + if (currentStep === 0) { + return ( +
+
+
任务名称
+ updateForm({ taskName: e.target.value })} + placeholder="请输入任务名称" + maxLength={30} + className={style.input} + /> +
+ +
+
允许发布时间段
+
+ updateForm({ startTime: e.target.value })} + className={style.inputTime} + /> + + updateForm({ endTime: e.target.value })} + className={style.inputTime} + /> +
+
+ +
+
每日同步数量
+
+ + {formData.syncCount} + + 条朋友圈 +
+
+ +
+
账号类型
+
+ + +
+
+ +
+
+ 是否启用 + updateForm({ enabled: checked })} + className={style.switch} + /> +
+
+ +
+ +
+
+ ); + } + if (currentStep === 1) { + return ( +
+
+ Q} + className={style.searchInput} + onClick={() => message.info("这里应弹出设备选择器")} + readOnly + /> + {formData.selectedDevices.length > 0 && ( +
+ 已选设备: {formData.selectedDevices.length}个 +
+ )} +
+
+ + +
+
+ ); + } + if (currentStep === 2) { + return ( +
+
+ Q} + className={style.searchInput} + onClick={() => message.info("这里应弹出内容库选择器")} + readOnly + /> + {formData.selectedLibraries.length > 0 && ( +
+ 已选内容库: {formData.selectedLibraries.length}个 +
+ )} +
+
+ + +
+
+ ); + } + return null; + }; + + return ( + + + navigate(-1)} /> + + {isEditMode ? "编辑朋友圈同步" : "新建朋友圈同步"} + + } + /> + } + > +
+
+ {steps.map((s, i) => ( +
+ {i + 1} + {s} +
+ ))} +
+ {loading ? ( +
+ +
+ ) : ( + renderStep() + )} +
+
+ ); +}; + +export default NewMomentsSync; diff --git a/nkebao/src/router/module/workspace.tsx b/nkebao/src/router/module/workspace.tsx index b7ccc7c2..2fe6d775 100644 --- a/nkebao/src/router/module/workspace.tsx +++ b/nkebao/src/router/module/workspace.tsx @@ -8,7 +8,7 @@ import GroupPush from "@/pages/workspace/group-push/GroupPush"; import NewGroupPush from "@/pages/workspace/group-push/new"; import MomentsSync from "@/pages/workspace/moments-sync/MomentsSync"; import MomentsSyncDetail from "@/pages/workspace/moments-sync/Detail"; -import NewMomentsSync from "@/pages/workspace/moments-sync/new"; +import NewMomentsSync from "@/pages/workspace/moments-sync/new/index"; import AIAssistant from "@/pages/workspace/ai-assistant/AIAssistant"; import TrafficDistribution from "@/pages/workspace/traffic-distribution/TrafficDistribution"; import TrafficDistributionDetail from "@/pages/workspace/traffic-distribution/Detail";