feat: 本次提交更新内容如下
旧项目抢救
This commit is contained in:
@@ -123,7 +123,7 @@ export default function MomentsSyncDetail() {
|
||||
>
|
||||
<ChevronLeft className="h-5 w-5" />
|
||||
</Button>
|
||||
<h1 className="text-lg font-medium">朋友圈同步任务详情</h1>
|
||||
<h1 className="text-lg font-medium">任务详情</h1>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<Button variant="outline" size="sm" onClick={handleEdit}>
|
||||
@@ -138,7 +138,6 @@ export default function MomentsSyncDetail() {
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
footer={<BottomNav />}
|
||||
>
|
||||
<div className="bg-gray-50">
|
||||
<div className="p-4 space-y-6">
|
||||
@@ -172,12 +171,16 @@ export default function MomentsSyncDetail() {
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-gray-600">内容库</span>
|
||||
<span className="font-medium">
|
||||
{task.contentLib || "未设置"}
|
||||
{task.config?.contentLibraries
|
||||
.map((item: any) => item.name)
|
||||
.join(",")}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-gray-600">已同步</span>
|
||||
<span className="font-medium">{task.syncCount} 条</span>
|
||||
<span className="font-medium">
|
||||
{task.config?.syncCount} 条
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-gray-600">创建人</span>
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Switch } from '@/components/ui/switch';
|
||||
import { useToast } from '@/components/ui/toast';
|
||||
import { createMomentsSyncTask, updateMomentsSyncTask, fetchMomentsSyncTaskDetail } from '@/api/momentsSync';
|
||||
import { ChevronLeft } from 'lucide-react';
|
||||
import { DeviceSelectionDialog } from '@/components/DeviceSelectionDialog';
|
||||
import { ContentLibrarySelectionDialog } from '@/components/ContentLibrarySelectionDialog';
|
||||
import { ContentType } from '@/types/moments-sync';
|
||||
import React, { useState, useEffect, useCallback } from "react";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { useToast } from "@/components/ui/toast";
|
||||
import {
|
||||
createMomentsSyncTask,
|
||||
updateMomentsSyncTask,
|
||||
fetchMomentsSyncTaskDetail,
|
||||
} from "@/api/momentsSync";
|
||||
import { ChevronLeft } from "lucide-react";
|
||||
import { DeviceSelectionDialog } from "@/components/DeviceSelectionDialog";
|
||||
import { ContentLibrarySelectionDialog } from "@/components/ContentLibrarySelectionDialog";
|
||||
import { ContentType } from "@/types/moments-sync";
|
||||
|
||||
// 步骤指示器组件
|
||||
interface StepIndicatorProps {
|
||||
@@ -25,36 +29,41 @@ function StepIndicator({ currentStep }: StepIndicatorProps) {
|
||||
return (
|
||||
<div className="relative flex justify-between px-6 mb-8">
|
||||
{/* 连线 - 背景线 */}
|
||||
<div className="absolute top-5 left-0 right-0 h-[1px] bg-gray-200" style={{ width: '100%', zIndex: 0 }} />
|
||||
|
||||
{/* 连线 - 已完成线 */}
|
||||
<div
|
||||
className="absolute top-5 left-0 h-[1px] bg-blue-600 transition-all duration-300"
|
||||
style={{
|
||||
width: `${((currentStep - 1) / (steps.length - 1)) * 100}%`,
|
||||
zIndex: 1
|
||||
}}
|
||||
<div
|
||||
className="absolute top-5 left-0 right-0 h-[1px] bg-gray-200"
|
||||
style={{ width: "100%", zIndex: 0 }}
|
||||
/>
|
||||
|
||||
|
||||
{/* 连线 - 已完成线 */}
|
||||
<div
|
||||
className="absolute top-5 left-0 h-[1px] bg-blue-600 transition-all duration-300"
|
||||
style={{
|
||||
width: `${((currentStep - 1) / (steps.length - 1)) * 100}%`,
|
||||
zIndex: 1,
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* 步骤圆圈 */}
|
||||
{steps.map((step, index) => (
|
||||
<div key={step.id} className="flex flex-col items-center relative z-10">
|
||||
<div
|
||||
<div
|
||||
className={`w-10 h-10 rounded-full flex items-center justify-center mb-2 ${
|
||||
currentStep === index + 1
|
||||
? "bg-blue-600 text-white"
|
||||
currentStep === index + 1
|
||||
? "bg-blue-600 text-white"
|
||||
: index + 1 < currentStep
|
||||
? "bg-blue-600 text-white"
|
||||
: "bg-white text-gray-400 border border-gray-200"
|
||||
? "bg-blue-600 text-white"
|
||||
: "bg-white text-gray-400 border border-gray-200"
|
||||
}`}
|
||||
>
|
||||
{index + 1}
|
||||
</div>
|
||||
<div className={`text-sm ${
|
||||
currentStep === index + 1 || index + 1 < currentStep
|
||||
? "text-blue-600"
|
||||
: "text-gray-400"
|
||||
}`}>
|
||||
<div
|
||||
className={`text-sm ${
|
||||
currentStep === index + 1 || index + 1 < currentStep
|
||||
? "text-blue-600"
|
||||
: "text-gray-400"
|
||||
}`}
|
||||
>
|
||||
{step.title}
|
||||
</div>
|
||||
</div>
|
||||
@@ -70,18 +79,19 @@ export default function NewMomentsSyncTask() {
|
||||
const [currentStep, setCurrentStep] = useState(1);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [deviceDialogOpen, setDeviceDialogOpen] = useState(false);
|
||||
const [contentLibraryDialogOpen, setContentLibraryDialogOpen] = useState(false);
|
||||
const [contentLibraryDialogOpen, setContentLibraryDialogOpen] =
|
||||
useState(false);
|
||||
const [formData, setFormData] = useState({
|
||||
taskName: '',
|
||||
startTime: '06:00',
|
||||
endTime: '23:59',
|
||||
taskName: "",
|
||||
startTime: "06:00",
|
||||
endTime: "23:59",
|
||||
syncCount: 5,
|
||||
interval: 30, // 同步间隔,单位:分钟
|
||||
accountType: 'business' as 'business' | 'personal',
|
||||
accountType: "business" as "business" | "personal",
|
||||
enabled: true,
|
||||
selectedDevices: [] as string[],
|
||||
selectedLibraries: [] as string[],
|
||||
contentTypes: ['text', 'image', 'video'] as ContentType[],
|
||||
contentTypes: ["text", "image", "video"] as ContentType[],
|
||||
targetTags: [] as string[],
|
||||
filterKeywords: [] as string[],
|
||||
});
|
||||
@@ -109,21 +119,21 @@ export default function NewMomentsSyncTask() {
|
||||
if (taskData) {
|
||||
setFormData({
|
||||
taskName: taskData.name,
|
||||
startTime: taskData.timeRange?.start || '06:00',
|
||||
endTime: taskData.timeRange?.end || '23:59',
|
||||
syncCount: taskData.maxSyncPerDay || 5,
|
||||
startTime: taskData.timeRange?.start || "06:00",
|
||||
endTime: taskData.timeRange?.end || "23:59",
|
||||
syncCount: taskData?.config?.syncCount || 0,
|
||||
interval: taskData.syncInterval || 30,
|
||||
accountType: taskData.syncMode === 'auto' ? 'business' : 'personal',
|
||||
accountType: taskData.syncMode === "auto" ? "business" : "personal",
|
||||
enabled: taskData.status === 1,
|
||||
selectedDevices: taskData.devices || [],
|
||||
selectedLibraries: taskData.contentLib ? [taskData.contentLib] : [],
|
||||
contentTypes: taskData.contentTypes || ['text', 'image', 'video'],
|
||||
contentTypes: taskData.contentTypes || ["text", "image", "video"],
|
||||
targetTags: taskData.targetTags || [],
|
||||
filterKeywords: taskData.filterKeywords || [],
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
toast({ title: '获取任务详情失败', variant: 'destructive' });
|
||||
toast({ title: "获取任务详情失败", variant: "destructive" });
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@@ -137,15 +147,15 @@ export default function NewMomentsSyncTask() {
|
||||
|
||||
const handleComplete = async () => {
|
||||
if (!formData.taskName.trim()) {
|
||||
toast({ title: '请输入任务名称', variant: 'destructive' });
|
||||
toast({ title: "请输入任务名称", variant: "destructive" });
|
||||
return;
|
||||
}
|
||||
if (formData.selectedDevices.length === 0) {
|
||||
toast({ title: '请选择设备', variant: 'destructive' });
|
||||
toast({ title: "请选择设备", variant: "destructive" });
|
||||
return;
|
||||
}
|
||||
if (formData.selectedLibraries.length === 0) {
|
||||
toast({ title: '请选择内容库', variant: 'destructive' });
|
||||
toast({ title: "请选择内容库", variant: "destructive" });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -157,10 +167,10 @@ export default function NewMomentsSyncTask() {
|
||||
contentLibraries: formData.selectedLibraries,
|
||||
syncInterval: formData.interval,
|
||||
syncCount: formData.syncCount,
|
||||
syncType: formData.accountType === 'business' ? 1 : 2,
|
||||
syncType: formData.accountType === "business" ? 1 : 2,
|
||||
startTime: formData.startTime,
|
||||
endTime: formData.endTime,
|
||||
accountType: formData.accountType === 'business' ? 1 : 2,
|
||||
accountType: formData.accountType === "business" ? 1 : 2,
|
||||
contentTypes: formData.contentTypes,
|
||||
targetTags: formData.targetTags,
|
||||
filterKeywords: formData.filterKeywords,
|
||||
@@ -171,15 +181,18 @@ export default function NewMomentsSyncTask() {
|
||||
id,
|
||||
...taskData,
|
||||
});
|
||||
toast({ title: '更新成功' });
|
||||
toast({ title: "更新成功" });
|
||||
navigate(`/workspace/moments-sync/${id}`);
|
||||
} else {
|
||||
await createMomentsSyncTask(taskData);
|
||||
toast({ title: '创建成功' });
|
||||
navigate('/workspace/moments-sync');
|
||||
toast({ title: "创建成功" });
|
||||
navigate("/workspace/moments-sync");
|
||||
}
|
||||
} catch (error) {
|
||||
toast({ title: isEditMode ? '更新失败' : '创建失败', variant: 'destructive' });
|
||||
toast({
|
||||
title: isEditMode ? "更新失败" : "创建失败",
|
||||
variant: "destructive",
|
||||
});
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@@ -202,8 +215,12 @@ export default function NewMomentsSyncTask() {
|
||||
<div className="mb-6">
|
||||
<div className="text-base font-medium mb-2">每日同步数量</div>
|
||||
<div className="flex items-center">
|
||||
<button
|
||||
onClick={() => handleUpdateFormData({ syncCount: Math.max(1, formData.syncCount - 1) })}
|
||||
<button
|
||||
onClick={() =>
|
||||
handleUpdateFormData({
|
||||
syncCount: Math.max(1, formData.syncCount - 1),
|
||||
})
|
||||
}
|
||||
className="w-12 h-12 rounded-lg bg-white border border-gray-200 flex items-center justify-center text-xl"
|
||||
>
|
||||
-
|
||||
@@ -211,8 +228,10 @@ export default function NewMomentsSyncTask() {
|
||||
<div className="flex-1 text-center text-lg font-medium">
|
||||
{formData.syncCount}
|
||||
</div>
|
||||
<button
|
||||
onClick={() => handleUpdateFormData({ syncCount: formData.syncCount + 1 })}
|
||||
<button
|
||||
onClick={() =>
|
||||
handleUpdateFormData({ syncCount: formData.syncCount + 1 })
|
||||
}
|
||||
className="w-12 h-12 rounded-lg bg-white border border-gray-200 flex items-center justify-center text-xl"
|
||||
>
|
||||
+
|
||||
@@ -224,8 +243,12 @@ export default function NewMomentsSyncTask() {
|
||||
<div className="mb-6">
|
||||
<div className="text-base font-medium mb-2">同步间隔</div>
|
||||
<div className="flex items-center">
|
||||
<button
|
||||
onClick={() => handleUpdateFormData({ interval: Math.max(1, formData.interval - 1) })}
|
||||
<button
|
||||
onClick={() =>
|
||||
handleUpdateFormData({
|
||||
interval: Math.max(1, formData.interval - 1),
|
||||
})
|
||||
}
|
||||
className="w-12 h-12 rounded-lg bg-white border border-gray-200 flex items-center justify-center text-xl"
|
||||
>
|
||||
-
|
||||
@@ -233,15 +256,19 @@ export default function NewMomentsSyncTask() {
|
||||
<div className="flex-1 text-center text-lg font-medium">
|
||||
{formData.interval}
|
||||
</div>
|
||||
<button
|
||||
onClick={() => handleUpdateFormData({ interval: formData.interval + 1 })}
|
||||
<button
|
||||
onClick={() =>
|
||||
handleUpdateFormData({ interval: formData.interval + 1 })
|
||||
}
|
||||
className="w-12 h-12 rounded-lg bg-white border border-gray-200 flex items-center justify-center text-xl"
|
||||
>
|
||||
+
|
||||
</button>
|
||||
<span className="ml-2 text-gray-500">分钟</span>
|
||||
</div>
|
||||
<div className="text-xs text-gray-500 mt-1">设置每次发朋友圈的时间间隔</div>
|
||||
<div className="text-xs text-gray-500 mt-1">
|
||||
设置每次发朋友圈的时间间隔
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mb-6">
|
||||
@@ -251,7 +278,9 @@ export default function NewMomentsSyncTask() {
|
||||
<Input
|
||||
type="time"
|
||||
value={formData.startTime}
|
||||
onChange={(e) => handleUpdateFormData({ startTime: e.target.value })}
|
||||
onChange={(e) =>
|
||||
handleUpdateFormData({ startTime: e.target.value })
|
||||
}
|
||||
className="h-12 rounded-lg border-gray-200 text-base"
|
||||
/>
|
||||
</div>
|
||||
@@ -260,7 +289,9 @@ export default function NewMomentsSyncTask() {
|
||||
<Input
|
||||
type="time"
|
||||
value={formData.endTime}
|
||||
onChange={(e) => handleUpdateFormData({ endTime: e.target.value })}
|
||||
onChange={(e) =>
|
||||
handleUpdateFormData({ endTime: e.target.value })
|
||||
}
|
||||
className="h-12 rounded-lg border-gray-200 text-base"
|
||||
/>
|
||||
</div>
|
||||
@@ -297,7 +328,9 @@ export default function NewMomentsSyncTask() {
|
||||
<span className="text-base font-medium">是否启用</span>
|
||||
<Switch
|
||||
checked={formData.enabled}
|
||||
onCheckedChange={(checked) => handleUpdateFormData({ enabled: checked })}
|
||||
onCheckedChange={(checked) =>
|
||||
handleUpdateFormData({ enabled: checked })
|
||||
}
|
||||
className="data-[state=checked]:bg-blue-600 h-7 w-12"
|
||||
/>
|
||||
</div>
|
||||
@@ -316,7 +349,12 @@ export default function NewMomentsSyncTask() {
|
||||
<div className="min-h-screen bg-gray-50">
|
||||
<header className="sticky top-0 z-10 bg-white border-b">
|
||||
<div className="flex items-center h-14 px-4">
|
||||
<Button variant="ghost" size="icon" onClick={() => navigate(-1)} className="hover:bg-gray-50">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={() => navigate(-1)}
|
||||
className="hover:bg-gray-50"
|
||||
>
|
||||
<ChevronLeft className="h-6 w-6" />
|
||||
</Button>
|
||||
<h1 className="ml-2 text-lg font-medium">新建朋友圈同步</h1>
|
||||
@@ -327,7 +365,7 @@ export default function NewMomentsSyncTask() {
|
||||
<StepIndicator currentStep={currentStep} />
|
||||
|
||||
{currentStep === 1 && renderBasicSettings()}
|
||||
|
||||
|
||||
{currentStep === 2 && (
|
||||
<div className="px-4 space-y-6">
|
||||
<Input
|
||||
@@ -336,15 +374,19 @@ export default function NewMomentsSyncTask() {
|
||||
onClick={() => setDeviceDialogOpen(true)}
|
||||
readOnly
|
||||
/>
|
||||
|
||||
|
||||
{formData.selectedDevices.length > 0 && (
|
||||
<div className="text-base text-gray-500">
|
||||
已选设备:{formData.selectedDevices.length} 个
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
<div className="flex space-x-4 pt-4">
|
||||
<Button variant="outline" onClick={handlePrev} className="flex-1 h-12 rounded-lg">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={handlePrev}
|
||||
className="flex-1 h-12 rounded-lg"
|
||||
>
|
||||
上一步
|
||||
</Button>
|
||||
<Button
|
||||
@@ -354,7 +396,7 @@ export default function NewMomentsSyncTask() {
|
||||
下一步
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
|
||||
<DeviceSelectionDialog
|
||||
open={deviceDialogOpen}
|
||||
onOpenChange={setDeviceDialogOpen}
|
||||
@@ -365,7 +407,7 @@ export default function NewMomentsSyncTask() {
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
{currentStep === 3 && (
|
||||
<div className="px-4 space-y-6">
|
||||
<Input
|
||||
@@ -374,15 +416,19 @@ export default function NewMomentsSyncTask() {
|
||||
onClick={() => setContentLibraryDialogOpen(true)}
|
||||
readOnly
|
||||
/>
|
||||
|
||||
|
||||
{formData.selectedLibraries.length > 0 && (
|
||||
<div className="text-base text-gray-500">
|
||||
已选内容库:{formData.selectedLibraries.length} 个
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
<div className="flex space-x-4 pt-4">
|
||||
<Button variant="outline" onClick={handlePrev} className="flex-1 h-12 rounded-lg">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={handlePrev}
|
||||
className="flex-1 h-12 rounded-lg"
|
||||
>
|
||||
上一步
|
||||
</Button>
|
||||
<Button
|
||||
@@ -390,10 +436,10 @@ export default function NewMomentsSyncTask() {
|
||||
loading={loading}
|
||||
className="flex-1 h-12 bg-blue-500 hover:bg-blue-600 rounded-lg text-white"
|
||||
>
|
||||
{loading ? '创建中...' : '完成'}
|
||||
{loading ? "创建中..." : "完成"}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
|
||||
<ContentLibrarySelectionDialog
|
||||
open={contentLibraryDialogOpen}
|
||||
onOpenChange={setContentLibraryDialogOpen}
|
||||
@@ -407,4 +453,4 @@ export default function NewMomentsSyncTask() {
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user