Skip to content

常见问题

本章按问题链路组织排查入口。遇到问题时先看浏览器 Network 和 Console,再看相关源码,不要先通过删除校验、放开权限或回退到 Mock 来掩盖错误。

安装与启动

依赖安装失败怎么办?

依次确认:

bash
node --version
pnpm --version

项目要求 Node.js >= 20.19.0、pnpm >= 8.8.0。确认使用 pnpm install,没有混用 npm 或 Yarn。CI 中建议使用:

bash
pnpm install --frozen-lockfile

端口 3000 被占用怎么办?

修改 .env

ini
VITE_PORT = 3001

重新运行 pnpm dev

修改环境变量为什么没生效?

Vite 在启动时读取环境文件。停止开发服务并重新运行 pnpm dev。同时确认变量以 VITE_ 开头,且修改的是当前模式对应文件。

登录与会话

项目是否完全不需要后端?

不是。登录、退出和当前用户使用真实 API。业务页面可以暂时读取预置数据,但系统至少需要:

text
POST /api/v1/auth/signin
POST /api/v1/auth/logout
GET  /api/v1/user/info

登录接口成功,为什么仍提示登录失败?

检查统一响应是否为:

json
{
  "code": 200,
  "msg": "登录成功",
  "data": {
    "accessToken": "non-empty-token"
  }
}

accessToken 必须是非空字符串。检查 Network 中返回值,不要只看 HTTP 200。

登录后为什么进入 500 页面?

常见原因:

  • /api/v1/user/info 缺少 idusernameemail
  • rolesbuttons 不是字符串数组。
  • buttons 同时包含 * 和其他权限码。
  • 远程菜单结构不合法。

Console 会输出更具体的校验错误。

刷新页面后为什么回到登录页?

项目会恢复本地 Access Token,然后重新请求 /api/v1/user/info。检查:

  • Token 是否写入应用 LocalStorage。
  • 请求是否携带 Authorization: Bearer <token>
  • 当前用户接口是否接受该 Token。
  • Token 是否已经过期。

当前没有 Refresh Token 协议,过期后返回登录页是预期行为。

如何接入 Refresh Token?

需要在 src/api/auth.ts 中增加刷新接口,并修改请求层和用户 Store,集中处理令牌保存、并发失败请求和刷新失败登出。不要在页面或 Service 中定义刷新接口,也不要让每个 API 分别刷新 Token。

接口与代理

开发环境接口 404 怎么排查?

检查 .env.development

ini
VITE_API_URL = /
VITE_API_PROXY_URL = http://localhost:13000

确认后端真实路径包含 /api/...,并检查 vite.config.ts 的代理是否符合后端路径。修改环境变量后重启开发服务。

为什么出现 CORS 错误?

开发环境优先使用相对路径和 Vite 代理。生产环境优先使用同源网关。如果必须直接跨域,后端需要正确返回允许源、方法和请求头。

使用 Bearer Token 时通常保持:

ini
VITE_WITH_CREDENTIALS = false

只有使用跨域 Cookie 会话且后端已正确配置时才开启。

接口返回了数据,页面为什么拿不到?

统一请求层会从 { code, msg, data } 中返回 data。如果后端使用其他格式,需要在 src/utils/http 统一适配。不要让页面再读取 response.data.data

能否让接口失败时自动显示预置数据?

不建议。这样会掩盖生产接口故障,让用户看到与服务端不一致的数据。页面必须显式选择 src/mocksrc/api

菜单与权限

本地菜单和远程菜单怎么选?

  • 菜单结构跟随前端版本发布:使用 local
  • 后端需要按账号、租户动态下发完整菜单:使用 remote

配置:

ini
VITE_MENU_SOURCE = local

本地菜单为什么少了一部分?

检查当前用户 roles 与路由 meta.roles。未声明角色的路由默认可见,非空数组要求至少匹配一项,空数组表示不允许任何用户访问。

远程菜单为什么注册失败?

检查:

  • data 是否为数组。
  • name 是否非空且全局唯一。
  • 子路由是否误用 / 开头。
  • component 是否为 src/views 下的安全路径。
  • meta.title 是否存在。
  • 外链是否为 HTTP(S)。
  • 空目录是否没有页面、子节点、外链或 iframe。

菜单能看到,按钮为什么不显示?

确认路由配置:

ts
meta: {
  permissionPrefix: 'system:user',
  authList: [{ title: '新增', authMark: 'add' }]
}

用户接口应返回:

json
{
  "buttons": ["system:user:add"]
}

页面再使用 v-auth="'add'"hasAuth('add')

隐藏按钮是否已经足够安全?

不够。用户可以手工请求接口。后端必须重新检查身份、权限、数据范围和资源归属。

本地数据与写操作

为什么新增、编辑、删除后没有保存?

这是未接后端页面的预期行为。项目明确提示“当前不会写入服务端”,避免浏览器伪持久化掩盖接口缺失。按接口接入迁移对应写接口。

能否用 LocalStorage 保存业务表数据?

不建议。LocalStorage 不具备服务端鉴权、事务、审计、备份和多用户一致性,也不适合保存敏感业务数据。

什么时候可以删除 src/mock

当对应业务域的查询和写操作都已迁移,项目中不再导入该目录,并完成空状态、错误和权限验收后再删除。按业务域逐步清理,不要一次删除全部预置数据。

表格与页面

替换 API 后表格为空怎么办?

检查列表和总数字段是否能被适配。常见列表字段有 recordslistitemsrows,总数字段有 totalcount。单页差异使用 responseAdapter

搜索后页码为什么没有回到第一页?

使用 useTablereplaceSearchParams,不要直接修改查询参数后执行普通刷新。

页面为什么出现两个滚动条?

标准列表页使用 art-full-heightart-table-card。检查是否额外添加固定高度、多层卡片或外层 overflow

表头搜索历史可以保存手机号吗?

不可以默认保存。手机号、证件号、邮箱、账号、订单号等敏感或可识别信息不应进入搜索历史。搜索历史默认关闭。

主题与配置

修改 SETTING_DEFAULT_CONFIG 后为什么界面没变化?

浏览器恢复了已持久化的 setting Store。通过设置面板重置,或清理本应用命名空间下的设置键。不要执行 localStorage.clear()

暗色模式为什么还有白色区块?

搜索页面中硬编码的 #fffwhite 和只支持亮色的第三方样式。替换为项目表面 Token,并检查 Element Plus 是否误导入默认 CSS。

如何修改 Logo、系统名称和登录欢迎语?

系统基础名称位于 src/config/index.ts,站点公共信息由 siteSettingsStore 获取,默认数据在 src/mock/system/site-setting.ts。需要后台管理时迁移到真实 API,不要在多个页面分别硬编码。

构建与部署

pnpm build 为什么失败?

pnpm build 先执行 vue-tsc --noEmit。先查看最前面的 TypeScript 错误,再处理 Vite 构建问题。正式发布建议直接执行:

bash
pnpm release:check

部署后页面空白怎么排查?

重点检查:

  • Console 中的 JS 错误。
  • index.html 中静态资源路径。
  • 动态 Chunk 是否 404。
  • VITE_BASE_URL 是否与部署目录一致。
  • 服务器是否返回了错误的 MIME 类型或 HTML 错误页。

子目录部署为什么资源 404?

构建前设置:

ini
VITE_BASE_URL = /admin/

重新构建,并让服务器把 /admin/ 正确映射到整个 dist 目录。不能只移动已经按根路径构建的产物。

为什么新版本发布后用户仍看到旧页面?

检查 index.htmlversion.json 是否被长期缓存。带 Hash 的静态资源可以 immutable 缓存,但入口 HTML 和版本文件应使用短缓存或 no-store

Hash 路由还需要 Nginx 回退吗?

Hash 后的业务路径不会发送给服务器,通常不依赖每条业务路由的回退。保留 try_files $uri $uri/ /index.html 有助于处理站点入口和其他静态路径。

安全与交付

可以把 API Key 放进 .env.production 吗?

不可以。所有 VITE_ 环境变量都会进入浏览器构建产物。AI、对象存储、支付和签名密钥必须放在服务端。

为什么安全检查禁止直接使用 v-html

动态 HTML 可能带来 XSS。业务页面应通过 ArtSafeHtml 和 DOMPurify 白名单渲染,后端也需要在写入和输出阶段校验内容。

交付前最少执行什么?

bash
pnpm release:check

然后按构建部署完成生产预览、权限账号、业务写操作、移动端、暗色主题和发布后验收。

根据 MIT 许可证发布