refactor: 清理废弃业务模块并更新全栈配置
- 移除后端产品、目的地、活动专题等废弃模块的数据库表与业务代码,删除冗余API接口 - 删除小程序端详情页、线路组件等冗余代码,移除搜索工具与测试用例,调整导航逻辑 - 清理管理端废弃的类型定义、编辑器与测试代码 - 更新项目文档,修正模块维护说明与接口文档内容
This commit is contained in:
1 parent
72e6071bb1
commit
548f91c37f
80 files changed
+953
-12702
No files matched your search
@@ -1,61 +1,48 @@
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { Blocks, Home, LogOut, MapPin, Package, UserRoundCheck } from "lucide-react";
|
||||
import { useMemo, useState } from "react";
|
||||
import { BriefcaseBusiness, Home, LogOut, MapPin } from "lucide-react";
|
||||
|
||||
import { clearToken, getDestinations } from "@/api";
|
||||
import type { Destination } from "@/api";
|
||||
import { clearToken } from "@/api";
|
||||
import { EmptyState } from "@/components/admin/EmptyState";
|
||||
import { ToastStack } from "@/components/admin/ToastStack";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { LeadsPage } from "@/pages/leads/LeadsPage";
|
||||
import { ProductsPage } from "@/pages/products/ProductsPage";
|
||||
import { StructurePage } from "@/pages/structure/StructurePage";
|
||||
import type { Tab, Toast } from "@/types/admin";
|
||||
|
||||
const sidebarGroups: { id: string; label: string; items: { id: Tab; label: string; icon: typeof Home; description: string }[] }[] = [
|
||||
{
|
||||
id: "workspace",
|
||||
label: "工作台",
|
||||
items: [{ id: "structure", label: "维护地图", icon: Blocks, description: "前台结构总览" }],
|
||||
},
|
||||
const sidebarGroups: {
|
||||
id: string;
|
||||
label: string;
|
||||
items: { id: Tab; label: string; icon: typeof Home; description: string }[];
|
||||
}[] = [
|
||||
{
|
||||
id: "frontend",
|
||||
label: "前台页面",
|
||||
items: [
|
||||
{ id: "home", label: "小程序首页", icon: Home, description: "轮播、主题、CTA" },
|
||||
{ id: "destinations", label: "目的地页", icon: MapPin, description: "主视觉、热门、省内" },
|
||||
{ id: "products", label: "商品维护", icon: Package, description: "列表、卡片、详情" },
|
||||
{ id: "home", label: "首页", icon: Home, description: "" },
|
||||
{ id: "play", label: "玩法", icon: MapPin, description: "" },
|
||||
{ id: "butler", label: "管家", icon: BriefcaseBusiness, description: "" },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "operations",
|
||||
label: "业务处理",
|
||||
items: [{ id: "leads", label: "需求线索", icon: UserRoundCheck, description: "表单和跟进" }],
|
||||
},
|
||||
];
|
||||
|
||||
const tabs = sidebarGroups.flatMap((group) => group.items);
|
||||
const hiddenTabs: Partial<Record<Tab, { label: string; description: string }>> = {
|
||||
leadList: { label: "线索查询跟进", description: "表单查询和状态流转" },
|
||||
};
|
||||
|
||||
export function AdminShell({ onLogout }: { onLogout: () => void }) {
|
||||
const [activeTab, setActiveTab] = useState<Tab>("structure");
|
||||
const [destinations, setDestinations] = useState<Destination[]>([]);
|
||||
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
|
||||
const [activeTab, setActiveTab] = useState<Tab>("home");
|
||||
const [toasts, setToasts] = useState<Toast[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
getDestinations()
|
||||
.then((result) => setDestinations(result.items))
|
||||
.catch(() => setDestinations([]));
|
||||
}, [activeTab]);
|
||||
|
||||
useEffect(() => {
|
||||
setHasUnsavedChanges(false);
|
||||
}, [activeTab]);
|
||||
|
||||
const activeMeta = useMemo(() => tabs.find((tab) => tab.id === activeTab) ?? hiddenTabs[activeTab], [activeTab]);
|
||||
const activeMeta = useMemo(
|
||||
() => tabs.find((tab) => tab.id === activeTab),
|
||||
[activeTab],
|
||||
);
|
||||
const activeLabel = activeMeta?.label ?? "";
|
||||
const activeDescription = activeMeta?.description ?? "";
|
||||
const activeTopbarDescription = [
|
||||
activeDescription,
|
||||
"结构化维护",
|
||||
"内存开发模式",
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" · ");
|
||||
|
||||
const notify = (toast: Omit<Toast, "id">) => {
|
||||
const id = `toast-${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
||||
@@ -74,12 +61,15 @@ export function AdminShell({ onLogout }: { onLogout: () => void }) {
|
||||
<main className="admin-shell">
|
||||
<aside className="sidebar">
|
||||
<div className="brand-block">
|
||||
<b>万趣小程序管理端</b>
|
||||
<span>按前台结构管理</span>
|
||||
<b>万趣管理端</b>
|
||||
</div>
|
||||
<nav>
|
||||
{sidebarGroups.map((group) => (
|
||||
<section className="sidebar-group" key={group.id} aria-label={group.label}>
|
||||
<section
|
||||
className="sidebar-group"
|
||||
key={group.id}
|
||||
aria-label={group.label}
|
||||
>
|
||||
<span>{group.label}</span>
|
||||
{group.items.map((tab) => {
|
||||
const Icon = tab.icon;
|
||||
@@ -95,7 +85,6 @@ export function AdminShell({ onLogout }: { onLogout: () => void }) {
|
||||
<Icon size={18} />
|
||||
<span>
|
||||
<b>{tab.label}</b>
|
||||
<small>{tab.description}</small>
|
||||
</span>
|
||||
</Button>
|
||||
);
|
||||
@@ -103,7 +92,13 @@ export function AdminShell({ onLogout }: { onLogout: () => void }) {
|
||||
</section>
|
||||
))}
|
||||
</nav>
|
||||
<Button variant="ghost" aria-label="退出登录" className="logout-button" onClick={logout} title="退出登录">
|
||||
<Button
|
||||
variant="ghost"
|
||||
aria-label="退出登录"
|
||||
className="logout-button"
|
||||
onClick={logout}
|
||||
title="退出登录"
|
||||
>
|
||||
<LogOut size={17} />
|
||||
退出登录
|
||||
</Button>
|
||||
@@ -112,29 +107,25 @@ export function AdminShell({ onLogout }: { onLogout: () => void }) {
|
||||
<header className="topbar">
|
||||
<div>
|
||||
<span>{activeLabel}</span>
|
||||
<small>{activeDescription} · 结构化维护 · 内存开发模式</small>
|
||||
</div>
|
||||
<div className="topbar-actions">
|
||||
<span className={hasUnsavedChanges ? "admin-dirty-chip is-dirty" : "admin-dirty-chip"}>
|
||||
{hasUnsavedChanges ? "有未提交修改" : "内容已同步"}
|
||||
</span>
|
||||
<small>{activeTopbarDescription}</small>
|
||||
</div>
|
||||
</header>
|
||||
{activeTab === "structure" ? (
|
||||
<StructurePage onJump={setActiveTab} onDirtyChange={setHasUnsavedChanges} notify={notify} />
|
||||
) : activeTab === "home" ? (
|
||||
<StructurePage key="home-workbench" fixedPage="home" onJump={setActiveTab} onDirtyChange={setHasUnsavedChanges} notify={notify} />
|
||||
) : activeTab === "destinations" ? (
|
||||
<StructurePage key="destination-workbench" fixedPage="destination" onJump={setActiveTab} onDirtyChange={setHasUnsavedChanges} notify={notify} />
|
||||
) : activeTab === "products" ? (
|
||||
<ProductsPage destinations={destinations} onDirtyChange={setHasUnsavedChanges} notify={notify} />
|
||||
) : activeTab === "leads" ? (
|
||||
<StructurePage key="demand-workbench" fixedPage="demand" onJump={setActiveTab} onDirtyChange={setHasUnsavedChanges} notify={notify} />
|
||||
) : (
|
||||
<LeadsPage notify={notify} />
|
||||
)}
|
||||
{activeTab === "home" ? (
|
||||
<StructurePage key="home-page" fixedPage="home" notify={notify} />
|
||||
) : activeTab === "play" ? (
|
||||
<StructurePage key="play-page" fixedPage="play" notify={notify} />
|
||||
) : activeTab === "butler" ? (
|
||||
<section className="work-area">
|
||||
<EmptyState text="管家页面内容待配置" />
|
||||
</section>
|
||||
) : null}
|
||||
</section>
|
||||
<ToastStack toasts={toasts} onClose={(id) => setToasts((items) => items.filter((item) => item.id !== id))} />
|
||||
<ToastStack
|
||||
toasts={toasts}
|
||||
onClose={(id) =>
|
||||
setToasts((items) => items.filter((item) => item.id !== id))
|
||||
}
|
||||
/>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user