refactor(pc): 从 Gi Admin Pro + Arco 重搭为纯 Vue 3 + Naive UI

旧模板的 193 个文件整体删除,换成纯 Vue 3.5 + Naive UI 2.42 的树。

- 去掉 auto-import(组件与 API 全显式 import)、v-hasPerm(改 user.has('码'),全库 8 处)、
  Stylelint;n-tag 的 type 统一过 utils/tag.ts 转换(Arco 色词直接透传会静默变灰)
- 图标改为构建期抽取:scripts/extract-pc-icons.py -> icons/icon-data.ts(37 个),
  内网离线部署不会白屏
- 重搭后修掉 6 类"编译 / lint / typecheck 全绿、界面上就是坏的"故障:
  ① NGrid 的 cols 写成像素值(不是断点名 -> 永远只 1 列,工作台因此错乱)
  ② n-tab-pane 用 tab 属性(只渲染空注释节点,整排 tab 一个字都不显示)
  ③ 漏 import 被当未知自定义元素(样式整块丢) ④ .n-card__content 类名不存在
  (高度链第一环失效,表格行在 DOM 里但屏幕上没有) ⑤ 填报单状态映射错位一格
  ⑥ 有标题的卡片没有上内边距(naive 的 padding-top 只给"内容区是长子"的卡片)
- 卡片式版面提成全局基线:styles/index.scss 的 xt-* 令牌 + .page-card / .toolbar /
  .section-title,页面只引用、不再各写一套
- 品牌:改名「深学在线」,文字标换成几何标(方 = 卷宗 / 环 = 在线,不用文字字形);
  index.html 的页签图标从 404 的 /favicon.ico 改指真实存在的 /favicon.svg
This commit is contained in:
2026-10-10 16:48:46 +08:00
parent 0bbac7d228
commit 5b877451eb
270 changed files with 12964 additions and 25889 deletions
+23 -20
View File
@@ -1,38 +1,41 @@
---
name: code-ts
description: Vue 3 + TypeScript 命名、导入顺序、目录组织与 Lint 约定。编写或修改 .ts/.js 代码、新增 composable 或工具函数时加载本技能。
description: Vue 3 + TypeScript 命名、导入顺序、显式 import 与目录组织。编写或修改 .ts/.js 代码、新增 composable 或工具函数时加载本技能。
---
# TypeScript 规范(Vue 3)
# TypeScript 规范(Vue 3 + Naive UI)
Vue SFC 见 [code-vue](../code-vue/SKILL.md),样式见 [code-css](../code-css/SKILL.md)。
## 命名
- 组件 / 文件名:**PascalCase**;变量 / 函数:**camelCase**(事件处理推荐 `handle` 前缀)。
- 常量:需要时 **UPPER_SNAKE_CASE**;Composables:`use` 前缀。
- Props camelCase;模板事件名与 emits 定义 **kebab-case**。
- 样式 class:**kebab-case** + BEM(见 [code-css](../code-css/SKILL.md));全局组件前缀遵循项目统一约定。
- 组件文件:**PascalCase**(`AppIcon.vue`、`AuditDetailDrawer.vue`);工具/接口模块:**kebab-case 或小写**(`export-task.ts`、`acting-tenant.ts`)。
- 变量 / 函数:**camelCase**;事件处理用 `handle` 前缀;Composables 用 `use` 前缀。
- 常量:`UPPER_SNAKE_CASE`(如 `TENANT_STATUS`);展示映射放在 `src/apis/xt/<域>.ts` 里与接口同处。
- 样式 class:kebab-case(见 [code-css](../code-css/SKILL.md))。
## TypeScript
- `import type` 与值导入分离;对象结构优先 `interface`,联合/工具类型用 `type`。
- `import type { ... }` 与值导入**分开写**(ESLint `@antfu` 会强制)。
- 对象结构优先 `interface`;联合/工具类型用 `type`。
- Props 默认值:`withDefaults(defineProps<Type>(), { ... })`;避免 `any`。
- 公共类型集中管理;领域类型靠近业务模块。
- **接口出入参类型直接复用 `src/apis/xt/` 里的契约类型**,不要手写一份字段。
## 导入顺序
## 导入顺序(ESLint 会排)
1. 类型导入 → 2. 第三方 → 3. Vue/官方库 → 4. 项目内部(composables、组件、utils、样式)
1. 类型导入(`import type`) → 2. 第三方(`vue` / `naive-ui` / `axios`) → 3. 项目内部(`@/apis`、`@/stores`、`@/utils`、`@/icons`、`@/composables`)
不要重复 import 已自动注册的符号(类型除外)。
⚠️ **本仓库没有 auto-import**:naive-ui 组件、Vue API(`ref`/`computed`/`h`…)、工具函数**必须显式 import**。
不要写"为已自动导入的 API 写冗余 import"这类旧规范 —— 那是上一版(Gi 模板)的约定,现在写了才不报错。
## 组织
## 常用内部模块
- 遵循项目现有目录划分;单文件建议不超过 400 行,超出应拆分。
- 可复用 UI 放组件目录;跨页面逻辑抽 composables;纯函数抽 utils。
- 路径别名遵循项目配置,避免 `../../../` 穿越。
## Lint
- 遵循项目 ESLint、Stylelint、tsconfig,不擅自关闭规则。
- 必要的 `eslint-disable` / `@ts-expect-error` 须注释说明原因。
| 模块 | 用途 |
|---|---|
| `@/utils/http.ts` | axios 实例:成功直接 resolve `data`、失败弹提示、带 `Authorization` 与 `X-Tenant-Id` |
| `@/utils/naive.ts` | 全局 `message`(在组件外用,如 http 拦截器) |
| `@/utils/tag.ts` | `tagOf()`:状态色词 → `n-tag` 的 `type`(**必须过这一层**) |
| `@/utils/format.ts` | `fmtDate` 等格式化 |
| `@/composables/pagination.ts` | `listPagination()`:列表页分页器统一参数 |
| `@/stores/user.ts` | `useUserStore()`:`has('码')` / `hasAny(...)` / `menus` / `isPlatform` |
| `@/stores/acting-tenant.ts` | 平台运营的「当前学校」(请求头 `X-Tenant-Id`) |