diff --git a/.superpowers/brainstorm/team-building-20260819-visual/content/team-building-layout.html b/.superpowers/brainstorm/team-building-20260819-visual/content/team-building-layout.html new file mode 100644 index 0000000..be8d6fd --- /dev/null +++ b/.superpowers/brainstorm/team-building-20260819-visual/content/team-building-layout.html @@ -0,0 +1,52 @@ + + +

团队共创详情页视觉方向

+

参考“野呀旅行”长文详情图,选择更适合团队共创内容的阅读结构

+ +
+
+
+
关于我们••• — ◎
+
+ 山野团队共创 +
ABOUT YEKA

野呀旅行

越过山丘 向来处去

+
+
户外挑战

真正的贵州,从未被写进攻略里的山野故事,适合团队一起出发。

一段连续阅读的长文,保留参考图的沉浸感。

+
+

A · 沉浸长文

首屏大图后直接连续阅读,最贴近参考图,适合品牌故事与完整叙事。

+
+ +
+
+
团队共创••• — ◎
+
+ 峡谷团队共创 +
TEAM BUILDING

峡谷溯溪

并肩探索,共创默契

+
+
为什么一起出发

把自然、挑战和团队协作写成可阅读的故事。

适合怎样的团队

清晰分段,方便快速浏览与了解活动亮点。

我们如何同行

保留长图沉浸感,同时提升信息层次。

+
+

B · 分段阅读

在保留首屏视觉的基础上,将正文按小标题分段,适合多条团队共创产品扩展。

+
+
diff --git a/.superpowers/brainstorm/team-building-20260819-visual/state/server-info b/.superpowers/brainstorm/team-building-20260819-visual/state/server-info new file mode 100644 index 0000000..496ad36 --- /dev/null +++ b/.superpowers/brainstorm/team-building-20260819-visual/state/server-info @@ -0,0 +1 @@ +{"type":"server-started","port":63862,"host":"0.0.0.0","url_host":"127.0.0.1","url":"http://127.0.0.1:63862","screen_dir":"D:\\www\\znkj\\WonderQ-Project\\.superpowers\\brainstorm\\team-building-20260819-visual\\content","state_dir":"D:\\www\\znkj\\WonderQ-Project\\.superpowers\\brainstorm\\team-building-20260819-visual\\state"} diff --git a/WonderQ-Admin-UI/src/api.ts b/WonderQ-Admin-UI/src/api.ts index 6127ed6..ab49cd5 100644 --- a/WonderQ-Admin-UI/src/api.ts +++ b/WonderQ-Admin-UI/src/api.ts @@ -86,6 +86,151 @@ export type SiteModule = | "demandFeatureCards" | "demandForm" | "vehicleOptions"; + +export type WanfaRoute = { + id: string; + title: string; + subtitle: string; + image: string; + routeCount: number; + demandKeyword: string; +}; + +export type WanfaCategory = { + id: string; + label: string; + routes: WanfaRoute[]; +}; + +export type WanfaCategoryCreate = { + label: string; +}; + +export type WanfaCategoryPatch = { + label?: string; +}; + +export type WanfaRouteCreate = { + title: string; + subtitle: string; + image: string; + routeCount: number; + demandKeyword: string; +}; + +export type WanfaRoutePatch = Partial; + +export type ConciergeDetail = { + icon: string; + label: string; +}; + +export type ConciergeAdvisor = { + id: string; + avatar: string; + name: string; + role: string; + details: ConciergeDetail[]; + qrImage: string; + isActive: boolean; + sortOrder: number; + createdAt?: string; + updatedAt?: string; +}; + +export type ConciergeAdvisorCreate = { + avatar: string; + name: string; + role: string; + details: ConciergeDetail[]; + qrImage: string; + isActive?: boolean; + sortOrder?: number; +}; + +export type ConciergeAdvisorPatch = Partial; + +export type HomeExperience = { + id: string; + badge: string; + category: string; + title: string; + englishTitle: string; + image: string; + demandKeyword: string; + isActive: boolean; + sortOrder: number; + createdAt?: string; + updatedAt?: string; +}; + +export type HomeExperienceCreate = Omit & { + isActive?: boolean; + sortOrder?: number; +}; + +export type HomeExperiencePatch = Partial; + +export type HomeTeamBuilding = { + id: string; + tag: string; + title: string; + description: string; + image: string; + demandKeyword: string; + detailSubtitle: string; + detailParagraphs: string[]; + isActive: boolean; + sortOrder: number; + createdAt?: string; + updatedAt?: string; +}; + +export type HomeTeamBuildingCreate = Omit & { + isActive?: boolean; + sortOrder?: number; +}; + +export type HomeTeamBuildingPatch = Partial; + +export type HomeWildArchive = { + id: string; + title: string; + image: string; + images: string[]; + demandKeyword: string; + isActive: boolean; + sortOrder: number; + createdAt?: string; + updatedAt?: string; +}; + +export type HomeWildArchiveCreate = Omit & { + isActive?: boolean; + sortOrder?: number; +}; + +export type HomeWildArchivePatch = Partial; + +export type HomeWanfaRecommendation = { + id: string; + categoryId: string; + categoryLabel: string; + routeCount: number; + isActive: boolean; + sortOrder: number; + createdAt?: string; + updatedAt?: string; +}; + +export type HomeWanfaRecommendationCreate = { + categoryId: string; + isActive?: boolean; + sortOrder?: number; +}; + +export type HomeWanfaRecommendationPatch = Partial; + export type SiteConfigItem = SiteConfig[SiteModule][number]; type SiteConfigItemResponse = SiteConfigItem | { item: SiteConfigItem }; @@ -188,6 +333,211 @@ export async function getSiteConfig() { return request("/api/admin/site-config"); } +export async function getWanfaCategories() { + return request<{ categories: WanfaCategory[] }>("/api/admin/wanfa/categories"); +} + +export async function createWanfaCategory(input: WanfaCategoryCreate) { + return request("/api/admin/wanfa/categories", { + method: "POST", + body: JSON.stringify(input), + }); +} + +export async function updateWanfaCategory(categoryId: string, input: WanfaCategoryPatch) { + return request(`/api/admin/wanfa/categories/${categoryId}`, { + method: "PATCH", + body: JSON.stringify(input), + }); +} + +export async function deleteWanfaCategory(categoryId: string) { + return request<{ id: string }>(`/api/admin/wanfa/categories/${categoryId}`, { + method: "DELETE", + }); +} + +export async function reorderWanfaCategories(itemIds: string[]) { + return request<{ items: WanfaCategory[] }>("/api/admin/wanfa/categories/reorder", { + method: "PATCH", + body: JSON.stringify({ itemIds }), + }); +} + +export async function createWanfaRoute(categoryId: string, input: WanfaRouteCreate) { + return request(`/api/admin/wanfa/categories/${categoryId}/routes`, { + method: "POST", + body: JSON.stringify(input), + }); +} + +export async function updateWanfaRoute(categoryId: string, routeId: string, input: WanfaRoutePatch) { + return request(`/api/admin/wanfa/categories/${categoryId}/routes/${routeId}`, { + method: "PATCH", + body: JSON.stringify(input), + }); +} + +export async function deleteWanfaRoute(categoryId: string, routeId: string) { + return request<{ id: string }>(`/api/admin/wanfa/categories/${categoryId}/routes/${routeId}`, { + method: "DELETE", + }); +} + +export async function reorderWanfaRoutes(categoryId: string, itemIds: string[]) { + return request<{ items: WanfaRoute[] }>(`/api/admin/wanfa/categories/${categoryId}/routes/reorder`, { + method: "PATCH", + body: JSON.stringify({ itemIds }), + }); +} + +export async function getConciergeAdvisors() { + return request<{ advisors: ConciergeAdvisor[] }>('/api/admin/concierge/advisors'); +} + +export async function createConciergeAdvisor(input: ConciergeAdvisorCreate) { + return request('/api/admin/concierge/advisors', { + method: 'POST', + body: JSON.stringify(input), + }); +} + +export async function updateConciergeAdvisor(advisorId: string, input: ConciergeAdvisorPatch) { + return request(`/api/admin/concierge/advisors/${advisorId}`, { + method: 'PATCH', + body: JSON.stringify(input), + }); +} + +export async function deleteConciergeAdvisor(advisorId: string) { + return request<{ id: string }>(`/api/admin/concierge/advisors/${advisorId}`, { + method: 'DELETE', + }); +} + +export async function reorderConciergeAdvisors(itemIds: string[]) { + return request<{ items: ConciergeAdvisor[] }>('/api/admin/concierge/advisors/reorder', { + method: 'PATCH', + body: JSON.stringify({ itemIds }), + }); +} + +export async function getHomeExperiences() { + return request<{ items: HomeExperience[] }>("/api/admin/home/experiences"); +} + +export async function createHomeExperience(input: HomeExperienceCreate) { + return request("/api/admin/home/experiences", { + method: "POST", + body: JSON.stringify(input), + }); +} + +export async function updateHomeExperience(itemId: string, input: HomeExperiencePatch) { + return request(`/api/admin/home/experiences/${itemId}`, { + method: "PATCH", + body: JSON.stringify(input), + }); +} + +export async function deleteHomeExperience(itemId: string) { + return request<{ id: string }>(`/api/admin/home/experiences/${itemId}`, { method: "DELETE" }); +} + +export async function reorderHomeExperiences(itemIds: string[]) { + return request<{ items: HomeExperience[] }>("/api/admin/home/experiences/reorder", { + method: "PATCH", + body: JSON.stringify({ itemIds }), + }); +} + +export async function getHomeTeamBuildings() { + return request<{ items: HomeTeamBuilding[] }>("/api/admin/home/team-buildings"); +} + +export async function createHomeTeamBuilding(input: HomeTeamBuildingCreate) { + return request("/api/admin/home/team-buildings", { + method: "POST", + body: JSON.stringify(input), + }); +} + +export async function updateHomeTeamBuilding(itemId: string, input: HomeTeamBuildingPatch) { + return request(`/api/admin/home/team-buildings/${itemId}`, { + method: "PATCH", + body: JSON.stringify(input), + }); +} + +export async function deleteHomeTeamBuilding(itemId: string) { + return request<{ id: string }>(`/api/admin/home/team-buildings/${itemId}`, { method: "DELETE" }); +} + +export async function reorderHomeTeamBuildings(itemIds: string[]) { + return request<{ items: HomeTeamBuilding[] }>("/api/admin/home/team-buildings/reorder", { + method: "PATCH", + body: JSON.stringify({ itemIds }), + }); +} + +export async function getHomeWildArchives() { + return request<{ items: HomeWildArchive[] }>("/api/admin/home/wild-archives"); +} + +export async function createHomeWildArchive(input: HomeWildArchiveCreate) { + return request("/api/admin/home/wild-archives", { + method: "POST", + body: JSON.stringify(input), + }); +} + +export async function updateHomeWildArchive(itemId: string, input: HomeWildArchivePatch) { + return request(`/api/admin/home/wild-archives/${itemId}`, { + method: "PATCH", + body: JSON.stringify(input), + }); +} + +export async function deleteHomeWildArchive(itemId: string) { + return request<{ id: string }>(`/api/admin/home/wild-archives/${itemId}`, { method: "DELETE" }); +} + +export async function reorderHomeWildArchives(itemIds: string[]) { + return request<{ items: HomeWildArchive[] }>("/api/admin/home/wild-archives/reorder", { + method: "PATCH", + body: JSON.stringify({ itemIds }), + }); +} + +export async function getHomeWanfaRecommendations() { + return request<{ items: HomeWanfaRecommendation[] }>('/api/admin/home/play-recommendations'); +} + +export async function createHomeWanfaRecommendation(input: HomeWanfaRecommendationCreate) { + return request('/api/admin/home/play-recommendations', { + method: 'POST', + body: JSON.stringify(input), + }); +} + +export async function updateHomeWanfaRecommendation(itemId: string, input: HomeWanfaRecommendationPatch) { + return request(`/api/admin/home/play-recommendations/${itemId}`, { + method: 'PATCH', + body: JSON.stringify(input), + }); +} + +export async function deleteHomeWanfaRecommendation(itemId: string) { + return request<{ id: string }>(`/api/admin/home/play-recommendations/${itemId}`, { method: 'DELETE' }); +} + +export async function reorderHomeWanfaRecommendations(itemIds: string[]) { + return request<{ items: HomeWanfaRecommendation[] }>('/api/admin/home/play-recommendations/reorder', { + method: 'PATCH', + body: JSON.stringify({ itemIds }), + }); +} + function unwrapSiteConfigItem(response: SiteConfigItemResponse) { return "item" in response ? response.item : response; } diff --git a/WonderQ-Admin-UI/src/components/admin/AdminShell.tsx b/WonderQ-Admin-UI/src/components/admin/AdminShell.tsx index 35caaa3..d93e1bd 100644 --- a/WonderQ-Admin-UI/src/components/admin/AdminShell.tsx +++ b/WonderQ-Admin-UI/src/components/admin/AdminShell.tsx @@ -1,11 +1,12 @@ import { useMemo, useState } from "react"; -import { BriefcaseBusiness, Home, LogOut, MapPin } from "lucide-react"; +import { Headset, Home, List, LogOut } from "lucide-react"; import { clearToken } from "@/api"; -import { EmptyState } from "@/components/admin/EmptyState"; import { ToastStack } from "@/components/admin/ToastStack"; import { Button } from "@/components/ui/button"; -import { StructurePage } from "@/pages/structure/StructurePage"; +import { ConciergePage } from "@/pages/structure/ConciergePage"; +import { HomePage } from "@/pages/structure/HomePage"; +import { WanfaPage } from "@/pages/structure/WanfaPage"; import type { Tab, Toast } from "@/types/admin"; const sidebarGroups: { @@ -18,8 +19,8 @@ const sidebarGroups: { label: "前台页面", items: [ { id: "home", label: "首页", icon: Home, description: "" }, - { id: "play", label: "玩法", icon: MapPin, description: "" }, - { id: "butler", label: "管家", icon: BriefcaseBusiness, description: "" }, + { id: "play", label: "玩法", icon: List, description: "" }, + { id: "butler", label: "管家", icon: Headset, description: "" }, ], }, ]; @@ -61,6 +62,7 @@ export function AdminShell({ onLogout }: { onLogout: () => void }) {