feat: 本次提交更新内容如下
列表迁移成功
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
ChevronDown,
|
||||
ChevronUp,
|
||||
MoreVertical,
|
||||
Eye,
|
||||
Edit,
|
||||
@@ -10,10 +8,8 @@ import {
|
||||
Plus,
|
||||
Search,
|
||||
RefreshCw,
|
||||
Settings,
|
||||
Calendar,
|
||||
Users,
|
||||
ThumbsUp,
|
||||
ChevronDown,
|
||||
} from "lucide-react";
|
||||
import { Card } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
@@ -22,7 +18,7 @@ import { Badge } from "@/components/ui/badge";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { useToast } from "@/components/ui/toast";
|
||||
import { Progress } from "@/components/ui/progress";
|
||||
|
||||
import { fetchAutoLikeTasks, deleteAutoLikeTask, toggleAutoLikeTask, copyAutoLikeTask, LikeTask } from '@/api/autoLike';
|
||||
|
||||
type CardMenuProps = {
|
||||
@@ -87,7 +83,6 @@ function CardMenu({ onView, onEdit, onCopy, onDelete }: CardMenuProps) {
|
||||
export default function AutoLike() {
|
||||
const navigate = useNavigate();
|
||||
const { toast } = useToast();
|
||||
const [expandedTaskId, setExpandedTaskId] = useState<string | null>(null);
|
||||
const [tasks, setTasks] = React.useState<LikeTask[]>([]);
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
@@ -127,10 +122,7 @@ export default function AutoLike() {
|
||||
fetchTasks();
|
||||
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const toggleExpand = (taskId: string) => {
|
||||
setExpandedTaskId(expandedTaskId === taskId ? null : taskId);
|
||||
};
|
||||
|
||||
|
||||
const handleDelete = async (id: string) => {
|
||||
if (!window.confirm("确定要删除该任务吗?")) return;
|
||||
@@ -170,17 +162,35 @@ export default function AutoLike() {
|
||||
};
|
||||
|
||||
const toggleTaskStatus = async (id: string, status: number) => {
|
||||
// 先更新本地状态
|
||||
const newStatus = (status === 1 ? 2 : 1) as 1 | 2;
|
||||
setTasks(prevTasks =>
|
||||
prevTasks.map(task =>
|
||||
task.id === id ? { ...task, status: newStatus } : task
|
||||
)
|
||||
);
|
||||
|
||||
try {
|
||||
// status: 1(开启)-> 2(要关闭),2(关闭)-> 1(要开启)
|
||||
const newStatus = status === 1 ? 2 : 1;
|
||||
const response = await toggleAutoLikeTask(id, String(newStatus));
|
||||
if (response.code === 200) {
|
||||
toast({ title: "操作成功" });
|
||||
fetchTasks();
|
||||
// 成功时不刷新列表,保持本地状态
|
||||
} else {
|
||||
// 请求失败,回退本地状态
|
||||
setTasks(prevTasks =>
|
||||
prevTasks.map(task =>
|
||||
task.id === id ? { ...task, status: status as 1 | 2 } : task
|
||||
)
|
||||
);
|
||||
toast({ title: "操作失败", description: response.msg || "请稍后重试", variant: "destructive" });
|
||||
}
|
||||
} catch (error) {
|
||||
// 请求异常,回退本地状态
|
||||
setTasks(prevTasks =>
|
||||
prevTasks.map(task =>
|
||||
task.id === id ? { ...task, status: status as 1 | 2 } : task
|
||||
)
|
||||
);
|
||||
toast({ title: "操作失败", description: "请稍后重试", variant: "destructive" });
|
||||
}
|
||||
};
|
||||
@@ -244,107 +254,48 @@ export default function AutoLike() {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-4 mb-4">
|
||||
<div className="text-sm text-gray-500">
|
||||
<div>执行设备:{task.deviceCount} 个</div>
|
||||
<div>目标人群:{task.targetGroup}</div>
|
||||
<div>更新时间:{task.updateTime}</div>
|
||||
|
||||
</div>
|
||||
<div className="text-sm text-gray-500">
|
||||
<div>点赞间隔:{task.likeInterval} 秒</div>
|
||||
<div>每日上限:{task.maxLikesPerDay} 次</div>
|
||||
<div>创建时间:{task.createTime}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center justify-between text-xs text-gray-500 border-t pt-4">
|
||||
<div className="flex items-center">
|
||||
<ThumbsUp className="w-4 h-4 mr-1" />今日点赞:{task.lastLikeTime}
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<ThumbsUp className="w-4 h-4 mr-1" />
|
||||
<span>总点赞数:{task.createTime}</span>
|
||||
<Button variant="ghost" size="sm" className="ml-2 p-0 h-6 w-6" onClick={() => toggleExpand(task.id)}>
|
||||
{expandedTaskId === task.id ? <ChevronUp className="h-4 w-4" /> : <ChevronDown className="h-4 w-4" />}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
{expandedTaskId === task.id && (
|
||||
<div className="mt-4 pt-4 border-t border-dashed">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center">
|
||||
<Settings className="h-5 w-5 mr-2 text-gray-500" />
|
||||
<h4 className="font-medium">基本设置</h4>
|
||||
</div>
|
||||
<div className="space-y-2 pl-7">
|
||||
<div className="flex justify-between text-sm">
|
||||
<span className="text-gray-500">点赞间隔:</span>
|
||||
<span>{task.likeInterval} 秒</span>
|
||||
</div>
|
||||
<div className="flex justify-between text-sm">
|
||||
<span className="text-gray-500">每日最大点赞数:</span>
|
||||
<span>{task.maxLikesPerDay} 次</span>
|
||||
</div>
|
||||
<div className="flex justify-between text-sm">
|
||||
<span className="text-gray-500">执行时间段:</span>
|
||||
<span>
|
||||
{task.timeRange.start} - {task.timeRange.end}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center">
|
||||
<Users className="h-5 w-5 mr-2 text-gray-500" />
|
||||
<h4 className="font-medium">目标人群</h4>
|
||||
</div>
|
||||
<div className="space-y-2 pl-7">
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{task.targetTags.map((tag) => (
|
||||
<Badge key={tag} variant="outline" className="bg-gray-50">
|
||||
{tag}
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center">
|
||||
<ThumbsUp className="h-5 w-5 mr-2 text-gray-500" />
|
||||
<h4 className="font-medium">点赞内容类型</h4>
|
||||
</div>
|
||||
<div className="space-y-2 pl-7">
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{task.contentTypes.map((type) => (
|
||||
<Badge key={type} variant="outline" className="bg-gray-50">
|
||||
{type === "text" ? "文字" : type === "image" ? "图片" : "视频"}
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center">
|
||||
<Calendar className="h-5 w-5 mr-2 text-gray-500" />
|
||||
<h4 className="font-medium">执行进度</h4>
|
||||
</div>
|
||||
<div className="space-y-2 pl-7">
|
||||
<div className="flex justify-between text-sm mb-1">
|
||||
<span className="text-gray-500">今日已点赞:</span>
|
||||
<span>
|
||||
{task.likeCount} / {task.maxLikesPerDay}
|
||||
</span>
|
||||
</div>
|
||||
<Progress
|
||||
value={(task.likeCount / task.maxLikesPerDay) * 100}
|
||||
className="h-2"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-6 mb-6">
|
||||
<div className="space-y-3">
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm text-gray-500 font-medium">执行设备</span>
|
||||
<span className="text-sm text-gray-900 font-semibold">{task.deviceCount} 个</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm text-gray-500 font-medium">目标人群</span>
|
||||
<span className="text-sm text-gray-900 font-semibold">{task.targetGroup}</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm text-gray-500 font-medium">更新时间</span>
|
||||
<span className="text-sm text-gray-900 font-semibold">{task.updateTime}</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="space-y-3">
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm text-gray-500 font-medium">点赞间隔</span>
|
||||
<span className="text-sm text-gray-900 font-semibold">{task.likeInterval} 秒</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm text-gray-500 font-medium">每日上限</span>
|
||||
<span className="text-sm text-gray-900 font-semibold">{task.maxLikesPerDay} 次</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm text-gray-500 font-medium">创建时间</span>
|
||||
<span className="text-sm text-gray-900 font-semibold">{task.createTime}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center justify-between text-sm text-gray-500 border-t pt-5">
|
||||
<div className="flex items-center space-x-2">
|
||||
<ThumbsUp className="w-4 h-4 text-blue-500" />
|
||||
<span className="font-medium">今日点赞:</span>
|
||||
<span className="text-gray-900 font-semibold">{task.lastLikeTime}</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<ThumbsUp className="w-4 h-4 text-green-500" />
|
||||
<span className="font-medium">总点赞数:</span>
|
||||
<span className="text-gray-900 font-semibold">{task.totalLikeCount || 0}</span>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -96,15 +96,20 @@ export default function AutoLikeDetail() {
|
||||
const handleToggleStatus = async () => {
|
||||
if (!task) return;
|
||||
|
||||
// 先更新本地状态
|
||||
const newStatus = (Number(task.status) === 1 ? 2 : 1) as 1 | 2;
|
||||
const originalStatus = Number(task.status) as 1 | 2;
|
||||
setTask(prev => prev ? { ...prev, status: newStatus } : null);
|
||||
|
||||
try {
|
||||
// status: 1(开启)-> 2(要关闭),2(关闭)-> 1(要开启)
|
||||
const newStatus = task.status === 1 ? 2 : 1;
|
||||
const response = await toggleAutoLikeTask(task.id, String(newStatus));
|
||||
|
||||
if (response.code === 200) {
|
||||
setTask(prev => prev ? { ...prev, status: newStatus } : null);
|
||||
toast({ title: '操作成功' });
|
||||
// 成功时保持本地状态,不重新获取数据
|
||||
} else {
|
||||
// 请求失败,回退本地状态
|
||||
setTask(prev => prev ? { ...prev, status: originalStatus } : null);
|
||||
toast({
|
||||
title: '操作失败',
|
||||
description: response.msg || '请稍后重试',
|
||||
@@ -113,6 +118,8 @@ export default function AutoLikeDetail() {
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('操作失败:', error);
|
||||
// 请求异常,回退本地状态
|
||||
setTask(prev => prev ? { ...prev, status: originalStatus } : null);
|
||||
toast({
|
||||
title: '操作失败',
|
||||
description: '请稍后重试',
|
||||
@@ -267,7 +274,6 @@ export default function AutoLikeDetail() {
|
||||
<Switch
|
||||
checked={Number(task.status) === 1}
|
||||
onCheckedChange={handleToggleStatus}
|
||||
disabled={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user