Files
xiaotutongxue/frontend-pc/.agents/skills/project-guide/SKILL.md
T
lovife 87ece5a971 feat(frontend): 管理端改用 Gi Admin Pro 框架 + 腾讯云主题
前端此前只有本地实现、从未入库,本次首次纳入版本管理。

框架切换
  · 以 Gi Admin Pro(Vue3 + Vite + TS + Arco Design Vue + Pinia)为底
  · 剥离 14 个演示页面目录 / 121 个文件(demo 28、file 20、form 19、system 18…)
  · 依赖 dependencies 35 → 19,devDependencies 31 → 27
  · 保留框架核心:layout、Gi* 组件库、hooks、权限指令、错误页、登录页

主题:腾讯云 / TDesign 官方色板
  · 主色 #0052D9(腾讯蓝)、成功 #00A870、警告 #ED7B2F、危险 #E34D59
  · 页面底色 #f3f3f3、文字 rgba(0,0,0,90/60/40/26%)
  · 覆盖 Arco 底层色板 + 显式语义别名(primary/success/warning/danger/link/neutral)
  · 三个改了不生效也不报错的坑已记入注释:
      1) Arco 色值是逗号分隔 RGB 三元组,不是 #RRGGBB
      2) Arco 把色板定义在 body 而非 :root,必须写 `:root, body`
      3) setting.json 的 themeColor 会以内联样式写进 body,优先级高于样式表

对接后端(三处契约差异在 @/utils/http 统一适配)
  · 响应信封 {code,msg,data} → {code,success,message,data}
  · Token 头 token → Authorization: Bearer
  · 分页 {list,total} → 补一份 records,list 原样保留
  · 40101 → 登录页;登录密码 RSA 加密(公钥走 /auth/public-key,轮换无需重建前端)
  · 路由:后端只下发菜单键,前端在本地路由表上过滤(有哪些页面归代码,谁能看归后端)

已实现页面(浏览器实测通过)
  · 登录:RSA 加密 + 自适应验证码/租户码 + 账号锁定提示
  · 工作台:真实数据(组织 6 个 / 角色 1 个 / 权限 25 项)
  · 组织架构:三级树 + CRUD + 占用校验
  · 租户管理:开通租户 + 初始密码只显示一次的强确认
  · 待建页:未实现菜单显示所属里程碑
  · 权限菜单:学校管理员看不到「租户管理」

视觉资产按腾讯云主题重做
  · logo.svg(渐变圆角方 + 填)、favicon.svg(小尺寸做减法)、login-hero.svg(材料归集)
  · 登录页点阵纹理走主题变量,换主色自动跟随
  · 文案改为产品实际能力:自动改名 / 强制压缩 / 隐私保护

清理模板遗留(约 17MB + 三处外部依赖)
  · 百度统计脚本(上报到 gi-demo 作者的统计账号)
  · 用户菜单「项目地址」(跳转模板作者的 Gitee 仓库)
  · 两份 8.8MB mp3、388KB favicon.ico、57KB 模板插画、未引用字体与 loading.gif
  · 「个人中心」指向已删除的 /system/account(点了 404)
  · 头部头像在无 avatarUrl 时渲染成裂图 → 改为姓名首字兜底

后端修复
  · 新增 GET /auth/public-key(前端加密登录密码用)
  · DataSeeder.ancestor_path 生成错误:子节点本该是 /16/17/ 却写成 /17/
    该字段是「按院系统计」的索引,错了会漏人/多人且不报错 —— 改为从库里读父节点路径
  · seedDemoOrgs 曾放在租户作用域外 + admin 早退分支之后,导致启动失败 / 永不执行
  · 示范租户补一套三级组织树(1 学校 / 2 院系 / 3 班级),供界面演示
2026-09-28 20:49:55 +08:00

7.6 KiB
Raw Blame History

name, description
name description
project-guide 后台管理模板的项目总览与前端强制规范。涵盖 Vue 3 + Arco Design + Gi 组件库、目录结构、自动导入、CRUD/API 约定与代码风格。在当前仓库内开发、新增页面、查阅架构或不确定项目规范时使用。

项目开发指南

适用范围:本仓库 src/**、mock/** 规范来源:AGENTS.md 常驻行为准则 + 本 skill(项目细节);编码规范按需读 code-vue / code-css / code-ts skill

本项目 Agent 约定

  • 优先复用 Gi*、hooks、getBaseApi、现有 mock 工具;新增页面/接口对齐参考页与 getBaseApi 约定。
  • API / Mock 以 src/apis、mock 与类型定义为准,不要猜测路径。
  • 涉及 CRUD、API、Mock 时按需读取对应 skill;写 .vue / 样式 / TS 前读取 code-vue、code-css、code-ts。
  • 改动后视情况运行 pnpm typecheck、pnpm lint、pnpm lint:style。

技术栈

类别 选型
框架 Vue 3.5 + TypeScript + <script setup lang="ts">
构建 Vite 7
UI Arco Design Vue(按需自动导入)+ 本地 Gi* 组件
状态 Pinia + pinia-plugin-persistedstate
路由 Vue Router 4(Hash 模式)
HTTP @/utils/http,统一响应类型 ApiRes<T>、PageRes<T>
工具 @vueuse/core、lodash-es、dayjs、xe-utils
Mock vite-plugin-mock + mockjs(开发默认启用)

每个 SFC 必须 defineOptions({ name: 'XxxYyy' });通用 Vue 规范见 code-vue,本项目补充见下文「本项目 Vue 约定」。

路径别名

  • @ → src/
  • ~ → 项目根目录

目录约定

src/
├── apis/          # 接口(按业务模块分文件,标准 CRUD 用 getBaseApi)
├── components/    # Gi* 业务组件 + 部分通用组件
├── hooks/         # 组合式函数(useTable、useDict 等)
├── hooks/app/     # 业务域 hooks(useDept、useRole)
├── stores/        # Pinia
├── views/         # 页面(按模块分子目录)
├── router/        # 路由与守卫
├── utils/         # http、auth、regexp、deepClone 等
├── types/         # 全局类型(global.d.ts、api.d.ts)
mock/              # vite-plugin-mock 模拟数据

页面文件命名:

src/views/{module}/index.vue           # 列表页
src/views/{module}/XxxFormModal.vue    # 新增/编辑弹窗(有表单时必建)
src/apis/{module}/{name}.ts            # 类型定义 + CRUD API(或 apis/system/user.ts)
mock/{module}/{name}.ts                # 与 API 路径一致的 Mock

全局类型(src/types/)

  • Status:'0' | '1'(禁用/启用,与字典 STATUS 一致)
  • Gender:'1' | '2' | '3'
  • Pagination:{ page, size }
  • ApiRes<T>、PageRes<T>:统一接口响应(分页 data 为 { records, total })

CRUD 列表页(强制遵循)

新建/修改表格页时,必须参考并遵循:

  • 参考实现:src/views/system/user/index.vue、UserFormModal.vue
  • Hook:@/hooks/useTable
  • API 模板:src/apis/system/user.ts + getBaseApi
  • 详细步骤:读取并遵循 project-crud

核心结构:

  1. GiPageLayout 布局(可选 #left 树/分类)
  2. queryParams(reactive)+ 搜索区 + GiButton(search/reset)
  3. tableColumns(TableColumnData[],复杂列用 lang="tsx" + render)
  4. useTable 绑定 listAPI 与 deleteAPI
  5. XxxFormModal ref,defineExpose({ add, edit }),@save-success="search"

分页类型:PageRes<T>(records + total)。Mock 与接口详见 project-api。

API 层模板

import { getBaseApi } from '@/apis/base'
import http from '@/utils/http'

export interface ListItem {
  id: string
  name: string
  status: Status
}

/** 标准 CRUD */
export const baseAPI = getBaseApi<ListItem>({ baseUrl: '/system/xxx' })

/** 非标准接口 */
export function customAction(params: Pagination) {
  return http.get<PageRes<Item[]>>('/system/xxx/customAction', params)
}
  • 开发环境 VITE_API_PREFIX = '/mock'(.env.development)
  • 禁止绕过 @/utils/http 裸用 axios

代码风格

  • 遵循 @antfu/eslint-config(eslint.config.js):箭头参数括号、1TBS、无尾随逗号;Vue block 顺序 [['script', 'template'], 'style'];宏顺序 defineOptions/defineModel/defineProps/defineEmits/defineSlots,defineExpose 最后。
  • 布局放 src/layout/,Gi 组件放 src/components/Gi*,业务 Hook 放 hooks/ 或 hooks/app/。
  • 空字符串查询条件传 API 前建议转为 undefined。
  • 通用编码规范见 code-ts、code-vue、code-css;本项目补充见下文。

本项目编码约定

  • 路径别名:@ → src/,~ → 项目根;禁止 ../../../ 穿越。
  • 组件全局前缀 Gi 仅用于 src/components/Gi* 全局组件。
  • 目录:src/views 页面、src/components 组件、src/apis/<domain>/ + type.ts 接口类型、src/types 公共类型、src/hooks composables。
  • API 统一 @/utils/http;状态 Pinia + pinia-plugin-persistedstate。
  • 图标 @iconify/vue;样式从 scss/less 导入,避免内联。
  • 业务注释中文,标识符英文。
  • 检查:pnpm lint、pnpm lint:style、pnpm typecheck。

本项目 Vue 约定

  • 每个 SFC 必须 defineOptions({ name: 'XxxYyy' }),名称与路由/模块对应,并与路由表 name 一致以支持缓存。
  • 自动导入(vite.config.ts,勿重复 import):
    • Vue API:ref、reactive、computed、watch、useTemplateRef 等
    • Gi 组件:src/components/Gi*(如 GiPageLayout、GiButton、GiForm)
    • Arco 组件:a-table、a-modal、a-select 等
    • 图标:icon-*(Iconify icon-park-outline)
  • Gi 组件模板用 PascalCase;Arco 用 a-* 前缀;禁止手动 import Gi/Arco(类型除外)。
  • 表格列复杂时用 lang="tsx" + TableColumnData[] 的 render;字典字段用 useDict(['STATUS']) 等。
  • dayjs 默认导入变量名必须为 Dayjs(大写),禁止小写 dayjs。
  • 深拷贝使用 @/utils 的 deepClone,禁止 JSON.parse(JSON.stringify())。
  • Vue 参考页:src/views/system/user/index.vue、UserFormModal.vue、src/views/table/custom3/index.vue

本项目样式

  • 全局样式:src/styles/index.scss(变量 var.scss、混入 mixin.scss、Arco 主题 arco-ui/)
  • Stylelint:pnpm lint:style
  • 列表页常用工具类:g-row-tool(工具栏行)、g-table(表格)、g-full-column(左栏撑满)、g-mb(下边距)
  • BEM 示例:src/views/login/LoginLeft.vue

子技能(按需阅读)

场景 技能
Vue SFC、Emits、Ref code-vue
样式、BEM code-css
TS 命名、导入 code-ts
新建 CRUD 列表页、表格、弹窗表单 project-crud
新增接口、Mock、baseAPI project-api

参考页面

  • 标准 CRUD + 左树:src/views/system/user/index.vue
  • 左右分栏 + 字典:src/views/system/dict/index.vue
  • GiTableSetting + a-table:src/views/table/custom3/index.vue
  • 表单弹窗:src/views/system/user/UserFormModal.vue

禁止事项

  • ❌ 绕过 @/utils/http 直接裸用 axios
  • ❌ 表格页自行实现分页/删除逻辑,而不使用 useTable
  • ❌ 新建列表页不参考 system/user 与 project-crud 约定