Files
xiaotutongxue/frontend-pc/vite.config.ts
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

116 lines
3.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { fileURLToPath, URL } from 'node:url'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import AutoImport from 'unplugin-auto-import/vite'
import IconsResolver from 'unplugin-icons/resolver'
import Icons from 'unplugin-icons/vite'
import { ArcoResolver } from 'unplugin-vue-components/resolvers'
import Components from 'unplugin-vue-components/vite'
import { defineConfig, loadEnv } from 'vite'
import vitePluginCompression from 'vite-plugin-compression'
import VueDevTools from 'vite-plugin-vue-devtools'
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd()) as ImportMetaEnv
return {
// 开发或生产环境服务的公共基础路径
base: env.VITE_BASE,
// 路径别名
resolve: {
alias: {
'~': fileURLToPath(new URL('./', import.meta.url)),
'@': fileURLToPath(new URL('./src', import.meta.url))
},
// 确保正确解析模块
dedupe: ['vue', '@arco-design/web-vue']
},
// 依赖优化配置
optimizeDeps: {
include: ['@arco-design/color']
},
// 引入scss全局样式变量
css: {
preprocessorOptions: {
scss: {
additionalData: `@use "@/styles/var.scss" as *;`
}
}
},
server: {
// 服务启动时是否自动打开浏览器
open: false,
// 本地跨域代理 -> 代理到服务器的接口地址
proxy: {
'/api': {
target: env.VITE_API_BASE_URL, // 后台服务器地址
changeOrigin: true, // 是否允许不同源
secure: false, // 支持https
rewrite: (path) => path.replace(/^\/api/, '/api')
}
}
},
plugins: [
vue(),
vueJsx(),
VueDevTools(),
AutoImport({
// 自动导入vue相关函数,如: ref、reactive、toRef等
imports: ['vue', 'vue-router', {
// vue 3.5.x
vue: ['useTemplateRef', 'onWatcherCleanup', 'useId']
}],
dts: 'src/auto-import.d.ts'
}),
Components({
// 指定组件位置,默认是 src/components 自动导入自定义组件
dirs: ['src/components/Gi*'],
extensions: ['vue', 'tsx'],
// 配置文件生成位置
dts: 'src/components.d.ts',
// Arco Design Vue 按需导入配置(使用官方推荐的 ArcoResolver)
resolvers: [
ArcoResolver({
sideEffect: false
}),
// Iconify 图标按需导入
IconsResolver({
prefix: 'icon',
enabledCollections: ['icon-park-outline']
})
]
}),
// Iconify 图标插件配置
Icons({
compiler: 'vue3',
autoInstall: true,
defaultClass: 'iconify-icon',
defaultStyle: 'vertical-align: middle;'
}),
// Gzip 压缩配置
vitePluginCompression({
verbose: true, // 是否在控制台输出压缩结果
disable: false, // 是否禁用压缩
deleteOriginFile: false, // 压缩后是否删除原文件
threshold: 10240, // 压缩阈值,单位:字节,超过此大小的文件才会被压缩(10KB)
algorithm: 'gzip', // 压缩算法,可选 'gzip' | 'brotliCompress' | 'deflate' | 'deflateRaw'
ext: '.gz', // 压缩文件扩展名
filter: /\.(js|mjs|json|css|html|svg|ico|eot|otf|ttf|ttc|woff|woff2)$/i // 需要压缩的文件类型
})
],
// 构建
build: {
chunkSizeWarningLimit: 2000
},
// 生产环境优化
esbuild:
mode === 'development'
? undefined
: {
pure: ['console.log'],
drop: ['debugger'],
legalComments: 'none'
}
}
})