feat: 本次提交更新内容如下

新版本样式完成
This commit is contained in:
笔记本里的永平
2025-07-18 21:56:03 +08:00
parent c9893b3371
commit 56a2f41aef
4 changed files with 117 additions and 92 deletions

View File

@@ -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>
@@ -203,35 +226,51 @@ export default function MomentsSyncDetail() {
<span className="text-gray-600"></span> <span className="text-gray-600"></span>
<span className="font-medium">{task.syncInterval} </span> <span className="font-medium">{task.syncInterval} </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.maxSyncPerDay || 100} </span> <span className="font-medium">
</div> {task.maxSyncPerDay || 100}
</span>
</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">
</div> {task.todaySyncCount || 0}
<div className="flex items-center justify-between"> </span>
<span className="text-gray-600"></span> </div>
<span className="font-medium">{task.totalSyncCount || task.syncCount || 0} </span> <div className="flex items-center justify-between">
</div> <span className="text-gray-600"></span>
<span className="font-medium">
{task.totalSyncCount || task.syncCount || 0}
</span>
</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>

View File

@@ -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;
} }

View File

@@ -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 {

View File

@@ -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>