feat: 本次提交更新内容如下
新版本样式完成
This commit is contained in:
@@ -1,19 +1,26 @@
|
|||||||
import React, { useState, useEffect, useCallback } from 'react';
|
import React, { useState, useEffect, useCallback } from "react";
|
||||||
import { useParams, useNavigate } from 'react-router-dom';
|
import { useParams, useNavigate } from "react-router-dom";
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from "@/components/ui/button";
|
||||||
import { Card } from '@/components/ui/card';
|
import { Card } from "@/components/ui/card";
|
||||||
import { Badge } from '@/components/ui/badge';
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { Switch } from '@/components/ui/switch';
|
import { Switch } from "@/components/ui/switch";
|
||||||
import { useToast } from '@/components/ui/toast';
|
import { useToast } from "@/components/ui/toast";
|
||||||
import {
|
import {
|
||||||
fetchMomentsSyncTaskDetail,
|
fetchMomentsSyncTaskDetail,
|
||||||
toggleMomentsSyncTask,
|
toggleMomentsSyncTask,
|
||||||
syncMoments
|
syncMoments,
|
||||||
} from '@/api/momentsSync';
|
} from "@/api/momentsSync";
|
||||||
import { MomentsSyncTask } from '@/types/moments-sync';
|
import { MomentsSyncTask } from "@/types/moments-sync";
|
||||||
import { ChevronLeft, Edit2, RefreshCw, Clock, Database, Smartphone } from 'lucide-react';
|
import {
|
||||||
import Layout from '@/components/Layout';
|
ChevronLeft,
|
||||||
import BottomNav from '@/components/BottomNav';
|
Edit2,
|
||||||
|
RefreshCw,
|
||||||
|
Clock,
|
||||||
|
Database,
|
||||||
|
Smartphone,
|
||||||
|
} from "lucide-react";
|
||||||
|
import Layout from "@/components/Layout";
|
||||||
|
import BottomNav from "@/components/BottomNav";
|
||||||
|
|
||||||
export default function MomentsSyncDetail() {
|
export default function MomentsSyncDetail() {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
@@ -31,7 +38,7 @@ export default function MomentsSyncDetail() {
|
|||||||
setTask(taskData);
|
setTask(taskData);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast({ title: '获取任务详情失败', variant: 'destructive' });
|
toast({ title: "获取任务详情失败", variant: "destructive" });
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
@@ -49,9 +56,9 @@ export default function MomentsSyncDetail() {
|
|||||||
const newStatus = task.status === 1 ? 2 : 1;
|
const newStatus = task.status === 1 ? 2 : 1;
|
||||||
await toggleMomentsSyncTask(id, newStatus.toString());
|
await toggleMomentsSyncTask(id, newStatus.toString());
|
||||||
setTask({ ...task, status: newStatus });
|
setTask({ ...task, status: newStatus });
|
||||||
toast({ title: newStatus === 1 ? '任务已开启' : '任务已暂停' });
|
toast({ title: newStatus === 1 ? "任务已开启" : "任务已暂停" });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast({ title: '操作失败', variant: 'destructive' });
|
toast({ title: "操作失败", variant: "destructive" });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -59,10 +66,10 @@ export default function MomentsSyncDetail() {
|
|||||||
if (!id) return;
|
if (!id) return;
|
||||||
try {
|
try {
|
||||||
await syncMoments(id);
|
await syncMoments(id);
|
||||||
toast({ title: '同步任务已启动' });
|
toast({ title: "同步任务已启动" });
|
||||||
fetchTaskDetail(); // 刷新任务详情
|
fetchTaskDetail(); // 刷新任务详情
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast({ title: '同步失败', variant: 'destructive' });
|
toast({ title: "同步失败", variant: "destructive" });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -91,7 +98,10 @@ export default function MomentsSyncDetail() {
|
|||||||
<div className="flex-1 bg-gray-50 min-h-screen flex items-center justify-center">
|
<div className="flex-1 bg-gray-50 min-h-screen flex items-center justify-center">
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<p className="text-gray-600">任务不存在</p>
|
<p className="text-gray-600">任务不存在</p>
|
||||||
<Button onClick={() => navigate('/workspace/moments-sync')} className="mt-4">
|
<Button
|
||||||
|
onClick={() => navigate("/workspace/moments-sync")}
|
||||||
|
className="mt-4"
|
||||||
|
>
|
||||||
返回列表
|
返回列表
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@@ -106,7 +116,11 @@ export default function MomentsSyncDetail() {
|
|||||||
<div className="bg-white border-b">
|
<div className="bg-white border-b">
|
||||||
<div className="flex items-center justify-between p-4">
|
<div className="flex items-center justify-between p-4">
|
||||||
<div className="flex items-center space-x-3">
|
<div className="flex items-center space-x-3">
|
||||||
<Button variant="ghost" size="icon" onClick={() => navigate('/workspace/moments-sync')}>
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="icon"
|
||||||
|
onClick={() => navigate("/workspace/moments-sync")}
|
||||||
|
>
|
||||||
<ChevronLeft className="h-5 w-5" />
|
<ChevronLeft className="h-5 w-5" />
|
||||||
</Button>
|
</Button>
|
||||||
<h1 className="text-lg font-medium">朋友圈同步任务详情</h1>
|
<h1 className="text-lg font-medium">朋友圈同步任务详情</h1>
|
||||||
@@ -116,10 +130,10 @@ export default function MomentsSyncDetail() {
|
|||||||
<Edit2 className="h-4 w-4 mr-2" />
|
<Edit2 className="h-4 w-4 mr-2" />
|
||||||
编辑
|
编辑
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="outline" size="sm" onClick={handleSync}>
|
{/* <Button variant="outline" size="sm" onClick={handleSync}>
|
||||||
<RefreshCw className="h-4 w-4 mr-2" />
|
<RefreshCw className="h-4 w-4 mr-2" />
|
||||||
立即同步
|
立即同步
|
||||||
</Button>
|
</Button> */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -137,7 +151,10 @@ export default function MomentsSyncDetail() {
|
|||||||
{task.status === 1 ? "进行中" : "已暂停"}
|
{task.status === 1 ? "进行中" : "已暂停"}
|
||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
<Switch checked={task.status === 1} onCheckedChange={handleToggleStatus} />
|
<Switch
|
||||||
|
checked={task.status === 1}
|
||||||
|
onCheckedChange={handleToggleStatus}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
@@ -154,7 +171,9 @@ export default function MomentsSyncDetail() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<span className="text-gray-600">内容库</span>
|
<span className="text-gray-600">内容库</span>
|
||||||
<span className="font-medium">{task.contentLib || '未设置'}</span>
|
<span className="font-medium">
|
||||||
|
{task.contentLib || "未设置"}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<span className="text-gray-600">已同步</span>
|
<span className="text-gray-600">已同步</span>
|
||||||
@@ -180,11 +199,15 @@ export default function MomentsSyncDetail() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<span className="text-gray-600">上次同步</span>
|
<span className="text-gray-600">上次同步</span>
|
||||||
<span className="font-medium">{task.lastSyncTime || '暂无'}</span>
|
<span className="font-medium">
|
||||||
|
{task.lastSyncTime || "暂无"}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<span className="text-gray-600">更新时间</span>
|
<span className="text-gray-600">更新时间</span>
|
||||||
<span className="font-medium">{task.updateTime || '暂无'}</span>
|
<span className="font-medium">
|
||||||
|
{task.updateTime || "暂无"}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -205,33 +228,49 @@ export default function MomentsSyncDetail() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<span className="text-gray-600">每日最大</span>
|
<span className="text-gray-600">每日最大</span>
|
||||||
<span className="font-medium">{task.maxSyncPerDay || 100} 条</span>
|
<span className="font-medium">
|
||||||
|
{task.maxSyncPerDay || 100} 条
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<span className="text-gray-600">时间范围</span>
|
<span className="text-gray-600">时间范围</span>
|
||||||
<span className="font-medium">{task.timeRange.start} - {task.timeRange.end}</span>
|
<span className="font-medium">
|
||||||
|
{task.timeRange?.start && task.timeRange?.end
|
||||||
|
? `${task.timeRange.start} - ${task.timeRange.end}`
|
||||||
|
: "未设置"}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<span className="text-gray-600">同步模式</span>
|
<span className="text-gray-600">同步模式</span>
|
||||||
<span className="font-medium">{task.syncMode === 'auto' ? '自动' : '手动'}</span>
|
<span className="font-medium">
|
||||||
|
{task.syncMode === "auto" ? "自动" : "手动"}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-3 text-sm">
|
<div className="space-y-3 text-sm">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<span className="text-gray-600">今日同步</span>
|
<span className="text-gray-600">今日同步</span>
|
||||||
<span className="font-medium">{task.todaySyncCount || 0} 条</span>
|
<span className="font-medium">
|
||||||
|
{task.todaySyncCount || 0} 条
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<span className="text-gray-600">总同步数</span>
|
<span className="text-gray-600">总同步数</span>
|
||||||
<span className="font-medium">{task.totalSyncCount || task.syncCount || 0} 条</span>
|
<span className="font-medium">
|
||||||
|
{task.totalSyncCount || task.syncCount || 0} 条
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<span className="text-gray-600">目标标签</span>
|
<span className="text-gray-600">目标标签</span>
|
||||||
<span className="font-medium">{task.targetTags.length} 个</span>
|
<span className="font-medium">
|
||||||
|
{task.targetTags?.length || 0} 个
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<span className="text-gray-600">内容类型</span>
|
<span className="text-gray-600">内容类型</span>
|
||||||
<span className="font-medium">{task.contentTypes.join(', ')}</span>
|
<span className="font-medium">
|
||||||
|
{task.contentTypes?.join(", ") || "未设置"}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -242,7 +281,9 @@ export default function MomentsSyncDetail() {
|
|||||||
<h3 className="text-lg font-semibold mb-4">最近同步记录</h3>
|
<h3 className="text-lg font-semibold mb-4">最近同步记录</h3>
|
||||||
<div className="text-center py-8">
|
<div className="text-center py-8">
|
||||||
<p className="text-gray-500">暂无同步记录</p>
|
<p className="text-gray-500">暂无同步记录</p>
|
||||||
<p className="text-sm text-gray-400 mt-2">任务开始执行后将显示同步记录</p>
|
<p className="text-sm text-gray-400 mt-2">
|
||||||
|
任务开始执行后将显示同步记录
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -26,17 +26,17 @@ export interface MomentsSyncTask {
|
|||||||
creatorName: string;
|
creatorName: string;
|
||||||
syncInterval: number;
|
syncInterval: number;
|
||||||
maxSyncPerDay: number;
|
maxSyncPerDay: number;
|
||||||
timeRange: { start: string; end: string };
|
timeRange?: { start: string; end: string };
|
||||||
contentTypes: ContentType[];
|
contentTypes?: ContentType[];
|
||||||
targetTags: string[];
|
targetTags?: string[];
|
||||||
syncMode: SyncMode;
|
syncMode: SyncMode;
|
||||||
filterKeywords: string[];
|
filterKeywords?: string[];
|
||||||
contentLib?: string;
|
contentLib?: string;
|
||||||
devices: string[];
|
devices?: string[];
|
||||||
friends: string[];
|
friends?: string[];
|
||||||
todaySyncCount: number;
|
todaySyncCount?: number;
|
||||||
totalSyncCount: number;
|
totalSyncCount?: number;
|
||||||
updateTime: string;
|
updateTime?: string;
|
||||||
config?: MomentsSyncConfig;
|
config?: MomentsSyncConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -131,6 +131,14 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin: 0 auto 6px;
|
margin: 0 auto 6px;
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scene-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scene-value {
|
.scene-value {
|
||||||
|
|||||||
@@ -16,33 +16,6 @@ import style from "./index.module.scss";
|
|||||||
import LineChart from "@/components/LineChart";
|
import LineChart from "@/components/LineChart";
|
||||||
import { getPlanStats } from "./api";
|
import { getPlanStats } from "./api";
|
||||||
|
|
||||||
const sceneStats = [
|
|
||||||
{
|
|
||||||
label: "公众号",
|
|
||||||
value: 234,
|
|
||||||
icon: <ShopbagOutline style={{ fontSize: 20, color: "white" }} />,
|
|
||||||
gradient: "linear-gradient(135deg, #4caf50 0%, #45a049 100%)",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "海报",
|
|
||||||
value: 167,
|
|
||||||
icon: <AppOutline style={{ fontSize: 20, color: "white" }} />,
|
|
||||||
gradient: "linear-gradient(135deg, #ff9800 0%, #f57c00 100%)",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "抖音",
|
|
||||||
value: 156,
|
|
||||||
icon: <PieOutline style={{ fontSize: 20, color: "white" }} />,
|
|
||||||
gradient: "linear-gradient(135deg, #2196f3 0%, #1976d2 100%)",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "小红书",
|
|
||||||
value: 89,
|
|
||||||
icon: <UserOutline style={{ fontSize: 20, color: "white" }} />,
|
|
||||||
gradient: "linear-gradient(135deg, #e91e63 0%, #c2185b 100%)",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const todayStats = [
|
const todayStats = [
|
||||||
{
|
{
|
||||||
label: "朋友圈",
|
label: "朋友圈",
|
||||||
@@ -71,9 +44,11 @@ const todayStats = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const Home: React.FC = () => {
|
const Home: React.FC = () => {
|
||||||
|
const [sceneStats, setSceneStats] = useState<any[]>([]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getPlanStats({ num: 4 }).then((res: any) => {
|
getPlanStats({ num: 4 }).then((res: any) => {
|
||||||
console.log(res);
|
// console.log(res);
|
||||||
|
setSceneStats(res);
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -133,15 +108,16 @@ const Home: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className={style["scene-grid"]}>
|
<div className={style["scene-grid"]}>
|
||||||
{sceneStats.map((item) => (
|
{sceneStats.map((item) => (
|
||||||
<div key={item.label} className={style["scene-item"]}>
|
<div key={item.id} className={style["scene-item"]}>
|
||||||
<div
|
<div className={style["scene-icon"]}>
|
||||||
className={style["scene-icon"]}
|
<img
|
||||||
style={{ background: item.gradient }}
|
src={item.image}
|
||||||
>
|
alt={item.name}
|
||||||
{item.icon}
|
className={style["scene-image"]}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className={style["scene-value"]}>{item.value}</div>
|
<div className={style["scene-value"]}>{item.allNum}</div>
|
||||||
<div className={style["scene-label"]}>{item.label}</div>
|
<div className={style["scene-label"]}>{item.name}</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user