|
|
12 ساعت پیش | |
|---|---|---|
| public | 1 روز پیش | |
| src | 12 ساعت پیش | |
| .env.development | 1 روز پیش | |
| .env.production | 1 روز پیش | |
| .gitignore | 1 روز پیش | |
| README.md | 1 روز پیش | |
| index.html | 1 روز پیش | |
| package-lock.json | 1 روز پیش | |
| package.json | 14 ساعت پیش | |
| tsconfig.app.json | 1 روز پیش | |
| tsconfig.json | 1 روز پیش | |
| tsconfig.node.json | 1 روز پیش | |
| vite.config.ts | 1 روز پیش |
上海闵行仓一期前端工程。Vue 3、TypeScript、Vite、Element Plus、Pinia、Axios、MSW。原始 PRD、交互说明及 HTML 原型保留在上级目录。
建议 Node.js 22.13+。已在 Node 22.12 下通过构建及测试,但部分开发依赖提示更高版本要求。
在本目录执行:
npm install
npm run dev
打开终端打印的地址,通常是 http://localhost:5173/。演示账号 demo,密码 123,仅用于本地 Mock。
npm test
npm run build
npm run preview
开发模式默认开启 Mock。生产构建默认关闭 Mock,preview 需要配套后端,不会自动使用演示数据。构建有大 chunk 警告,不影响运行;正式发布前建议进行路由和组件按需拆包。
工作台当日笔数按上海时区的完成时间统计,包含冲销产生的对应方向流水,不跨 SKU 汇总数量。
Mock 数据保存在当前浏览器、当前站点的 IndexedDB(idb-keyval 默认数据库内的 warehouse-db-v1 键),刷新后保留。图片以 data URL 存储,单张支持 5MB 内 PNG/JPEG/WebP,不适合真实大量附件。会话放在 sessionStorage。不要录入敏感或正式业务数据,也不要多标签页并发写入;Mock 不提供跨标签页事务一致性。
首次使用自动载入原型 Mock 数据:9 项基础资料、5 个 SKU、8 条已完成流水及 2 条草稿,含内部订单、外部订单、快递、闪送和部分冲销场景。SKU000001 至 SKU000005 的库存依次为 1 个、1 盒、3 个、2 盒、10 包。示例凭证可预览,明确标记 Mock,不是真实订单或物流凭证。
种子数据保留原型的 2026-09-05 至 2026-09-07 日期,其他日期查看工作台时,当日出入库笔数不会包含这些历史流水。仅新库或基础资料完全未修改的原始空库会自动初始化,已有业务记录或基础资料修改不会被覆盖。清理站点数据会删除全部本地业务记录,请先确认无需要保留的数据。
真实认证模式下,业务接口返回 HTTP 401 时自动清理认证态,生成新的 PKCE 会话并跳转认证中心;同一页面跳转期间的并发 401 只处理一次。Mock 模式仍返回本地登录页,403 不触发认证跳转。授权配置错误或跳转失败时回退到登录页手动重试;主动退出仍暂停自动认证。此并发保护不限制跨页面的重新认证次数,若后端持续拒绝新令牌,可能反复跳转,需排查认证与业务后端配置。
src/store/index.ts 统一导出仓储 useWarehouse 和认证 useStore(默认导出)。认证工具通过 Pinia 读写令牌、显示名称、角色与 PKCE 临时会话,并同步持久化到当前标签页的 sessionStorage,刷新或授权跳转后可恢复;退出或认证失效时清理相应缓存。PKCE 会话不设置本地过期时间,保留一次性消费校验;重新发起授权会覆盖旧会话,缓存仍受 sessionStorage 生命周期约束。仓储数据不重复缓存到认证 Store,仍由原 API 和 Mock IndexedDB 管理。
src/views/Login/index.vue 为登录入口。VITE_USE_MOCK=true 时保留本地账号登录;关闭 Mock 后使用 OAuth 授权码 + PKCE S256 登录,认证失败不会自动循环跳转。
在本地环境文件或构建环境中配置以下变量(示例域名需替换为实际认证服务):
VITE_USE_MOCK=false
VITE_OAUTH_REDIRECT_URI=http://localhost:5175/
VITE_OAUTH_RESPONSE_MODE=query
授权服务地址 VITE_API_AUTH_URL;系统自动拼接 /oauth2/authorize 和 /oauth2/token,单独配置的完整接口地址优先。客户端 ID 默认 client,实际值必须与认证中心注册信息一致。
认证中心需注册支持 PKCE 的公共客户端,并将回调地址加入白名单。回调地址必须与配置完全一致且不含 #,未配置时默认使用当前站点 origin + /login,部署服务需将该路径回退到应用入口。默认采用 response_mode=query,应用读取地址栏中的 code/state 后清除临时参数,再进入 Hash 路由。只有接入服务端 POST 回调转发后,才可将 VITE_OAUTH_RESPONSE_MODE 改为 form_post。
Token 接口使用表单编码,需允许前端跨域访问或配置同源代理,返回标准 access_token 和 token_type=Bearer。不在前端配置 client_secret;若认证中心强制要求客户端密钥或 form_post,应由后端代理完成回调与令牌交换。未接入权限接口,不将未经验证的 JWT 内容作为权限依据;可选的令牌响应字段 displayName 仅用于界面显示。
PKCE 使用 CryptoJS 同步计算 SHA-256/Base64URL,随机值仍由 crypto.getRandomValues 生成。授权链接包含随机 state 和 nonce,临时会话使用 sessionStorage 持久化,不设置本地过期时间,保留 state、回调地址和一次性消费校验;认证中心仍决定授权码和令牌的有效期。目前不消费 ID Token,nonce 发送和缓存不代表已完成 ID Token 校验。生产环境应使用 HTTPS。现有本地退出只清除本应用会话,不会注销认证中心的 SSO 会话。环境变量修改后需重启开发服务或重新构建。
页面通过 src/api/index.ts 中的统一接口方法请求;src/http/index.ts 配置 Axios 实例、请求 Token 注入和响应 401 拦截;src/mock.ts 在启用 Mock 时拦截接口并返回模拟数据;src/domain.ts 定义数据模型及库存规则。
在部署环境配置 VITE_USE_MOCK=false 和 VITE_API_BASE_URL,并为跨域或同源 /api 配置真实服务。所有 VITE 变量都会进入前端,不能存储秘密。
SKU 管理统一使用 /api/wms/sku/page 服务端分页,请求类型为 WmsSkuQueryPageRequest,支持 keyword、spec、status、categoryId、sportTypeId、brandId 筛选。keyword 同时匹配 SKU 编码和商品名称,不再发送旧的 skuId、productName 查询字段,也不使用下拉搜索接口替代管理查询。列表按响应 stock 展示库存,0 正常显示,字段缺失显示占位符,不在前端计算或跨 SKU 汇总。详情展示 recentFlows 字符串列表;契约注明库存仅分页返回,详情不展示未经重新查询的列表库存。
库存台账顶部统计独立请求 /api/wms/ledger/adminSummary:优先使用实际接口的 warehouseName 展示仓库名称,兼容生成契约中的 queryScope;兼容类型定义在应用层,不修改生成文件。totalStockCount 为启用 SKU 数,todayFlowCount 为按创建时间统计的当日入库、出库、冲销/更正流水数。统计不由当前页或筛选结果推算,冲销成功后重新获取;零值正常展示,加载或失败时显示占位符。
台账普通流水详情同时传递 flowNo、flowType、recordId。冲销方向按 reversalDirection 数字值处理(1=入库、2=出库);台账详情缺少方向时回退到原流水类型,列表缺少方向时回退到带符号数量。首页轨迹同时兼容旧的 IN / OUT 方向值。
当前 WmsSkuUpdateRequest 包含分类、运动类型、品牌、规格字段,但生成服务说明仍限定仅修改商品名称、配置明细、备注。前端保留原编辑限制,待后端明确规则后再同步,避免仅依据可选字段扩展业务权限。
WMS 接口通过 api.wmsApi 调用。应用使用的接口模型保存在 src/api/types,由 src/api/indexType.ts 统一转出;这些类型文件需要提交到 Git。automation/apiType 仅是临时接口契约,不参与应用编译,也不需要提交。接口更新后需将相关模型同步到 src/api/types,再核对 API 封装与页面用法。基础资料 dataType 使用数字:1=产品种类、2=运动类型、3=品牌。
出入库分页分别使用 WmsInboundPageRequest / WmsOutboundPageRequest,与草稿保存请求分离。列表与详情使用新版 Response 模型;响应附件从 attachments 读取,提交时仍使用 fileUrls / fileNames / fileTypes。操作人优先显示 updateUser,为空时使用 createUser。分页继续读取顶层 rows / total,业务成功码兼容 0 和 200。生成目录仅作为接口契约,运行时仍经 Axios 实例发送请求,不直接使用生成客户端的固定地址。
services.wms 使用独立的 VITE_API_WMS_URL,只配置服务根地址,不要追加 /api 或 /api/wms,接口封装已包含 /api/wms/... 前缀。开发环境配置为 http://192.168.32.159:8096;生产环境配置为 /,由部署代理转发同源 /api/wms 请求;未配置时也使用同源请求。该实例始终请求真实 WMS,不受 Mock 开关控制,本地 Mock 不代表真实接口已完成联调。
页面继续调用 api,由 API 层选择服务。src/http/index.ts 中的 services.warehouse 和 services.files 是独立 Axios 实例,共享 Token 注入和全局并发 401 跳转保护;http 保留为仓储实例的兼容别名。认证实例 authHttp 不注入业务 Token,也不触发业务 401 跳转。
VITE_USE_MOCK=false
VITE_API_BASE_URL=/api
VITE_API_WAREHOUSE_URL=https://warehouse.example.com/api
VITE_API_FILES_URL=https://files.example.com/api
两个服务地址未配置时分别回退到 VITE_API_BASE_URL,该变量未配置时使用 /api。现有业务接口使用仓储服务,上传接口使用文件服务,路径仍为 /files。Mock 模式下两者固定使用本地 /api,数据仍由 MSW 和 IndexedDB 模拟,不代表已接入真实服务。
后续新增服务,在 services 中注册实例,然后在 API 方法中选择该实例:
// services 中新增一项,地址应配置为可信后端。
orders: createServiceHttp(import.meta.env.VITE_API_ORDERS_URL || defaultBaseURL)
// API 方法中调用;响应类型定义在 src/api/indexType.ts。
orders: async () => (await services.orders.get<Order[]>('/orders')).data
默认服务工厂会发送当前业务 Bearer Token,仅用于接受同一认证体系令牌的可信服务。无需业务认证的服务使用 createServiceHttp(baseURL, false);不同认证体系需要单独设计令牌获取与失效处理,不能直接复用当前 Token。配置跨域地址时需由后端允许当前站点、Authorization 请求头及对应请求方法;相对地址需由开发或部署代理转发,本项目不会根据这些变量自动创建代理。修改环境变量后需要重启开发服务或重新构建。
| 方法 | 路径 | 用途 |
|---|---|---|
| POST | /login | {username,password},返回 {username,token} |
| GET | /state | 返回 {masters,skus,entries,sequence} |
| POST | /masters | 新增或更新基础资料 |
| DELETE | /masters/:id | 删除未使用资料 |
| POST | /skus | 新增或更新 SKU |
| POST | /entries | {data,submit},保存草稿或提交 |
| DELETE | /entries/:id | 删除草稿 |
| POST | /entries/:id/reverse | {quantity,evidence,remark},冲销 |
| POST | /files | multipart file,返回 {id,name,url} |
除登录外使用 Authorization: Bearer <token>。字段错误返回 HTTP 422 {message,fields},未登录返回 401。完整实体字段见 domain 类型;当前聚合 state 接口服务于原型联调,真实数据量增长后应改为后端分页查询。
真实后端必须独立实现鉴权、权限、库存事务、并发校验、幂等提交、附件存储及审计,不能将前端校验或 Mock 会话当作安全保证。