diff --git a/AGENTS.md b/AGENTS.md index 2b15b8f..ad8d676 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,7 +6,7 @@ - `apps/api` — Rust 后端(crate `vmall-api`)。迁移在 `apps/api/migrations/`(sqlx,启动时自动执行,只增不改)。分层约定见英文:`docs/adr/`、`docs/tech-specs/rust-api.md`、`openspec/specs/api-architecture/spec.md`。代码按限界上下文放在 `src/modules//`(handler → service → repo);HTTP 抽取器在 `src/http/`。新功能写进对应模块,不要把 SQL 堆回 handler。简单 CRUD 允许 handler 直接调 repo。Service 返回 `ApiResult`,不依赖 `Json`/`StatusCode`。Repo 接受 `&mut PgConnection` / `&mut Transaction` 以便组合事务。不引入泛型 Repository trait。 - `apps/mall` / `apps/shop-admin` / `apps/admin` — 三个 Nuxt 3 应用。端口固定 3000/3001/3002。 -- `packages/shared` — `@vmall/shared`:**唯一** API 契约(`src/types.ts` + `src/api.ts`)、en/zh 语言包、共享样式 `ui.css`。前端禁止自建 API 封装;契约变更只在这里改,且三个前端都要过构建。 +- `packages/shared` — `@vmall/shared`:**唯一** API 契约(`src/types.ts` + `src/api.ts`)、en/zh 语言包、共享 Tailwind v4 主题 `theme.css`(`@theme` tokens + `html[data-accent]` 预设)。前端禁止自建 API 封装;契约变更只在这里改,且三个前端都要过构建。共享 Vue 组件在 `packages/ui`(`@vmall/ui`:`VBtn`/`VBadge`/`VField`/`VInput`/`VCard`/`VPanel`/`VTable`/`VPage`/`VAccentSwatch` + `useAccent()`,以 Nuxt 模块自动注册)。布局用 Tailwind utilities,禁止 ` diff --git a/apps/admin/pages/index.vue b/apps/admin/pages/index.vue index 44df251..396911d 100644 --- a/apps/admin/pages/index.vue +++ b/apps/admin/pages/index.vue @@ -49,110 +49,42 @@ const cards = computed(() => [ - - diff --git a/apps/admin/pages/login.vue b/apps/admin/pages/login.vue index d0c36b4..cbcfd80 100644 --- a/apps/admin/pages/login.vue +++ b/apps/admin/pages/login.vue @@ -37,54 +37,24 @@ async function submit(): Promise { - - diff --git a/apps/admin/pages/orders.vue b/apps/admin/pages/orders.vue index f3881ef..b3ddcec 100644 --- a/apps/admin/pages/orders.vue +++ b/apps/admin/pages/orders.vue @@ -36,7 +36,7 @@ function formatDate(value: string): string { return new Date(value).toLocaleString(locale.value === "zh" ? "zh-CN" : "en-US"); } -function statusClass(status: Order["status"]): string { +function statusClass(status: Order["status"]): "green" | "red" | "orange" | "blue" { if (status === "completed") return "green"; if (status === "cancelled") return "red"; if (status === "pending_payment") return "orange"; @@ -76,53 +76,39 @@ onMounted(() => { - - diff --git a/apps/admin/pages/points-orders.vue b/apps/admin/pages/points-orders.vue index 7e5a8f2..907ce02 100644 --- a/apps/admin/pages/points-orders.vue +++ b/apps/admin/pages/points-orders.vue @@ -16,7 +16,7 @@ function rewardName(order: IntegralOrder): string { return order.items.map((line) => line.name[locale.value] ?? line.name.en).join(", "); } -function statusClass(status: IntegralOrderStatus): string { +function statusClass(status: IntegralOrderStatus): "green" | "red" | "orange" { if (status === "fulfilled") return "green"; if (status === "cancelled") return "red"; return "orange"; @@ -61,75 +61,43 @@ onMounted(() => void load()); - - diff --git a/apps/admin/pages/points-products.vue b/apps/admin/pages/points-products.vue index 4193a09..fd25551 100644 --- a/apps/admin/pages/points-products.vue +++ b/apps/admin/pages/points-products.vue @@ -127,141 +127,68 @@ onMounted(() => void load()); - - diff --git a/apps/admin/pages/shops.vue b/apps/admin/pages/shops.vue index 7dfac14..896ba48 100644 --- a/apps/admin/pages/shops.vue +++ b/apps/admin/pages/shops.vue @@ -24,7 +24,7 @@ function formatDate(value: string): string { return new Date(value).toLocaleString(locale.value === "zh" ? "zh-CN" : "en-US"); } -function statusClass(status: Shop["status"]): string { +function statusClass(status: Shop["status"]): "green" | "red" { return status === "active" ? "green" : "red"; } @@ -84,69 +84,51 @@ onMounted(() => { - - diff --git a/apps/admin/pages/users.vue b/apps/admin/pages/users.vue index e0f21a6..f25ca58 100644 --- a/apps/admin/pages/users.vue +++ b/apps/admin/pages/users.vue @@ -109,85 +109,68 @@ onMounted(() => { - - diff --git a/apps/mall/app.vue b/apps/mall/app.vue index c5d0e31..18c5ce3 100644 --- a/apps/mall/app.vue +++ b/apps/mall/app.vue @@ -1,13 +1,20 @@