--- title: 前端编码约定(admin/client) type: rule permalink: main/projects/d44c219a-0b31-4de1-b160-323eb34a4c6a/前端编码约定-admin-client stable_id: ada12b65-afa2-415e-98b3-2a24ff57feb9 scope: project project_id: d44c219a-0b31-4de1-b160-323eb34a4c6a memory_type: rule status: active revision: 1 restored_from_commit: 6a6a895eafcca6052e81a14fca103a42635dd1c2 created_at: '2026-09-23T15:07:39.899342+00:00' updated_at: '2026-09-23T15:07:39.899403+00:00' tags: - frontend - admin - client - vue - naive-ui --- - 后台列表页:复用 `apps/admin/src/composables/useTablePage.ts`,根容器 `class="page table-page"`,`n-data-table` 用 `class="table-fill" flex-height` 并关内置分页,底部外置 `n-pagination`;后端列表继承 `PaginationDto` 遵守 `pageSize=0` 不分页。操作列右固定,长文本省略悬停。 - 筛选:输入型检索放工具栏,枚举/下拉型放表头下拉,所有条件集中到同一 query 对象。 - 上传:单文件/少量用 `MediaUpload.vue`,多图排序用 `MediaSorter.vue`(captionable/disabled);选文件后必须立即有可见反馈。提交时存存储 key,展示时用 `utils/mediaUrl.ts` 的 `resolveMediaUrl` 解析。 - `n-data-table` 单元格内样式(如 `.cell-link`)必须用 `:deep()`(子组件渲染不带 scope 属性)。Teleport 弹窗宽度直接在 `n-modal` 上设 `style` + `max-width: 94vw`,不用 scoped 选择器。 - i18n:单 json/语言(`locales/zh-CN.json`、`en-US.json`),默认中文;新增键中英同步,后端错误按 `messageKey` 翻译。 - `@artveris/shared` 在 admin/client 的 Vite 中用 alias 指向 src(避免 rollup 读 CJS 命名导出失败)。 - 主题:Naive 官方 light/darkTheme + 青绿主色,CSS 变量 `--brand`,不硬编码颜色。admin 用 `manualChunks` 拆 naive/echarts/vendor。 - 审核/日志/用户/设置等受限路由用 `meta.roles`,菜单按角色隐藏;只读角色(`!auth.canWrite`)隐藏保存/触发按钮。 - 客户端图片/视频查看器用 PhotoSwipe v5(`composables/openMediaViewer.ts`),不再使用旧 MediaViewer。