# eams-ui **Repository Path**: lssjzmn/eams-ui ## Basic Information - **Project Name**: eams-ui - **Description**: 企业资产全生命周期管理系统前端 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-22 - **Last Updated**: 2026-11-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: eams ## README # EAMS 前端(eams-ui) EAMS 资产管理系统的前端单页应用(Vue 3 + TypeScript + Vite + TDesign)。 它同时是**标签打印链路的发起端**:二维码内容在这里组装、标签指令片段由后端产出、打印指令由浏览器直连本机 TSC PrintServer 落地。 - 后端:`../eams-control`(Spring Boot,8087,context-path `/eams`) - 打印工具:`../eams-print-server`(Python 桌面客户端,**与本前端并列**,互不通信) - 打印落地方:**本机 TSC PrintServer**(默认 `ws://127.0.0.1:8888`) --- ## 一、架构 ``` 浏览器 (Vite dev :3087 / nginx) │ ├─ HTTP /api/* ──rewrite──► 后端 :8087 /eams/* (业务数据 + 标签指令片段) │ MySQL / Redis / MinIO / XXL-JOB │ └─ WebSocket ws://127.0.0.1:8888 ──► 本机 TSC PrintServer ──► 标签打印机 (label.ws_url,浏览器直连,不过后端) ``` 分层与约定: | 层 | 位置 | 职责 | |---|---|---| | 请求层 | `src/api/request.ts` | axios 封装:注入 `Bearer` token、**解包 `result.data`**、`401` 清 token 跳登录、超时专门文案、`silent` 模式、`downloadFile()` | | 接口层 | `src/api/*.ts` | 一个业务域一个文件,导出 `xxx()` 函数;类型就地定义(无 `src/types`) | | 状态 | `src/store/` | Pinia:`user` / `theme` / `tabs` / `appText`(界面文案走 `ui.*` 参数)/ `appInfo` | | 路由 | `src/router/index.ts` | 19 条路由 + 全局守卫(未登录跳登录、无权限跳首页);`meta.permission` 与后端 `sys_menu.permission` 对齐 | | 权限 | `directives/permission.ts`、`composables/usePermission.ts` | 按钮级:`v-permission` 或 `can()` | | 业务 | `src/views/` | 19 个页面 + `asset/components/LabelPrintDialog.vue` | | 打印相关 | `src/utils/tscPrintServer.ts`、`labelPreview.ts`、`qrcodeContent.ts` | 见下节 | 技术栈:Vue 3.5 · TypeScript 5.4(`strict`)· Vite 6 · TDesign Vue Next · Pinia 2 · Less(BEM)· axios · qrcode · ECharts · xlsx。 ## 二、核心功能 - **认证授权**:登录、菜单/按钮权限(权限串如 `asset:list`)、操作日志、个人中心。 - **基础数据**:部门、资产分类、字典、**参数管理**(`bd_param`,标签打印参数 `label.*` 在这里改)。 - **资产台账**:列表/详情/履历历史、Excel 批量导入导出、二维码弹窗。 - **业务闭环**:调拨申请、维修、报废、盘点(任务/报告)、统计大屏、待办。 - **标签打印**(核心链路): - `views/asset/components/LabelPrintDialog.vue`:批量打印(去重、上限 `label.max_batch`)、**两级探活**、打印前复检、单张重打、导出指令 JSON、1:1 预览。 预览二维码**每次按当前参数重建**(只从入口复用流水号)——改了 `label.qr_mode` / `qr_password` 立刻生效,不会停留在"打开弹窗那一刻"的旧内容。 - `composables/useDirectLabelPrint.ts`:详情页一键直打(不选打印机、不探活,取不到打印机就**完全不带 openport**)。 - 二维码弹窗三条输出路径**共用同一份内容与同一个 8 位流水号**:下载 PNG / A4 打印 / 标签打印,并统一留痕(`reportQrcodeHistory`)。 ## 三、与后端、打印工具的关系与约束 | 关系 | 通路 | 硬约束 | |---|---|---| | 前端 → 后端 | HTTP `/api/*` →(dev 代理 / 生产 nginx 重写)`/eams/*` | Controller **只用 GET/POST**;分页请求 `page`/`size`,响应 `{total,list}`;数组参数要 `arr.join(',')`;token 走 `Authorization: Bearer`;版本号读 `GET /health` | | 前端 → 后端(二维码形态) | `GET /asset/qrcode/config` | 返回 `{mode, baseUrl, password}`;**会话内缓存一次**,失败回退 `simple`(宁可打文字码,也不能打不出码) | | 前端 → **本机 TSC PrintServer** | 浏览器 WebSocket 直连(`label.ws_url`,默认 `ws://127.0.0.1:8888`) | ① **站点必须保持 HTTP**:上 HTTPS 会被混合内容拦截,`ws://` 失效;② 报文是**函数调用列表** `{"functions_inorder":[{函数名:逗号参数}…]}`,收尾是**纯文本** `Finished`(不是 JSON);失败回 `{"Function_Failed":"函数名"}`,由 `functionFailureHint()` 翻成中文;③ `openport_*` 可省略(由服务按自身配置建会话),`closeport` **恒在末尾**(缓冲字节此时才真正落纸);④ USB 通道的 `USBPath` 是 Base64,**必须原值回传** | | 前端 ⇄ 打印工具 | **无通信** | 工具已于 2026-10-13 改为**打印客户端**:不再监听端口、不再接收 Web 端指令(并让出 8888,与官方 PrintServer 可同时运行);工具的「导入指令…」入口也已于 0.6.0 移除 ⇒ 现在只共享**指令契约**,运行期零耦合 | 内容与版面口径(**改一处必须三处同步**:本目录 `qrcodeContent.ts` → 后端 `LabelPrintService` → 工具 `app/webcompat.py`): | 项 | 口径 | 归属 | |---|---|---| | 二维码正文(`simple`) | **9 项**:编码/序列/名称/类型/部门/人员/原值/日期/流水;每行 `字段名:值`(**半角冒号**)、行间 `\n`、空值 `-`、金额两位小数、日期 `yyyy-MM-dd`;「人员」= **资产使用人** | 本目录 `utils/qrcodeContent.ts`(唯一数据源,A4/PNG/标签三路共用) | | 二维码正文(`api` / `html`) | 改为写入查询 URL:`{baseUrl}/open/qr/{text 或 html}/{编码}?pwd={口令}`,扫码读实时数据 | 同上;`baseUrl`/口令来自 `GET /asset/qrcode/config`,由 `composables/useQrConfig.ts` 会话内缓存,取不到或 `baseUrl` 为空**自动回落 simple** | | 指令片段 | `clearbuffer → setup → DIRECTION → CODEPAGE UTF-8 → [标题 windowsfont] → QRCODE → [文字 windowsfont ×N] → printlabel` | 后端产出;**不含** `openport/closeport`(由前端拼) | | 版面预览 | 照抄后端回传的 `layout` 坐标绘制,**前端不自算版面** | `utils/labelPreview.ts` | | 二维码模块数 | 前端用 `qrcode` 库算出 `qrModules` 一并提交,后端据此定 cell 并居中 | `labelPreview.ts` | > 两处**刻意**与后端不同(用户口径,只在工具侧生效):工具把标题按**粗体**下发、且 `DIRECTION` 默认 `1`。 ## 四、开发与构建 ```bash npm install npm run dev # :3087,/api 代理到 127.0.0.1:8087(vite.config.ts) npm run build # 产物 dist/,base = /eams/(交给 nginx) npm run preview # 本地预览构建产物 ``` - Node **≥ 18.18**;无 `.env`(接口前缀硬编码 `/api`);无 lint/test 脚本(以 IDE 诊断为准)。 - 上线检查:`dist` 必须是**新构建**(旧产物不会自动更新);nginx 需把 `/api` 重写到后端 `/eams`;站点必须 HTTP(见上)。 ## 五、目录速查 ``` src/ ├── api/ request.ts + 12 个业务域接口 ├── components/ CountUp / DrawerTitle / charts/EChart ├── composables/ usePage(分页)/ usePermission / useDirectLabelPrint / useQrConfig(二维码形态缓存) ├── directives/ permission.ts(v-permission) ├── layouts/ MainLayout.vue(侧栏+顶栏+面包屑+主题)、MultiTabs ├── router/ index.ts(19 条路由 + 守卫) ├── store/ user / theme / tabs / appText ├── styles/ global.less ├── utils/ ★ qrcodeContent.ts(二维码内容源)、labelPreview.ts(1:1 预览)、 │ tscPrintServer.ts(WS 客户端)、textLimit.ts └── views/ 19 个页面 + asset/components/LabelPrintDialog.vue + asset/assetImport.ts ``` ## 六、文档索引 | 文档 | 内容 | |---|---| | `CHANGELOG.md` | 前端变更记录(按日期倒序,含口径变更与踩坑) | | `../eams-control/README.md` | 后端架构与接口约定(本前端的数据来源) | | `../eams-print-server/README.md` | 打印工具(并列的第二个打印发起端) | | `../eams-control/deploy/DEPLOY.md` | 部署步骤与检查清单 | | `../标签打印方案_TSC-PrintServer.md` | 标签打印方案(跨三者的总体设计) |