Commit Graph

798 Commits

Author SHA1 Message Date
3cb44c8f18 fix(purchase): 申请人显示只取中文名,去掉 /账号 后缀
- 新增 formatUserName: 韩善龙/hanshanlong → 韩善龙
- 列表批次主行申请人列、详情弹窗均应用
- 避免长账号名撑高行导致行高不一致
2026-08-31 14:12:23 +08:00
74271d53bc style(purchase): 统一列表行高
- CSS 固定主表格行高 52px,行内 line-height 20px
- 状态列'待审批 N 项'改为单行 inline 显示(不再撑高)
- 物品列加 white-space: nowrap 防止换行导致高度差异
2026-08-31 14:07:02 +08:00
a6c21fd313 style(purchase): 列表宽度优化 + 物品显示名称货号
- 主表格/展开明细表格加 width:100% + fit
- 自适应列用 min-width(批次号/物品),固定列保留 width(金额/日期/操作)
- 批次主行物品列:单个显示 名称+货号,多个显示 'N 种物料'
- 展开明细物品列:名称+货号 合并显示
2026-08-31 14:05:46 +08:00
4c41e1ec13 feat(purchase): 采购列表按批次分组展示 + 批次级一键审批
- 列表按批次分组(树形展开):一个批次一行,显示物品数/批次总价/申请人/状态汇总
- 展开批次行显示批内明细(每条记录状态/价格/操作)
- 批次行提供「审批本批」「驳回本批」一键操作(按批次前缀批量处理待审批记录)
- 保留逐条展开明细内的通过/驳回,以及顶部多选批量审批
- fetchData 按批次前缀聚合当前页数据
2026-08-31 14:00:31 +08:00
1000deda2f feat(purchase): 采购单号改为 批次-批内序号 格式,显式体现同批
按用户原始逻辑还原并扩展:
- 单号格式: PUR-日期-时间-批次-批内序号
  例: PUR-20260831-1021-0001-0001(今日第1次采购的第1条)
- generate_request_no 支持 batch_seq 参数生成批次+批内序号
- 新增 GET /purchase/next-batch-seq 返回今日下一个批次号
- 前端提交时获取批次号,同批所有行共享,循环提交生成连续批内序号
- 批次识别: 单号去掉末尾 -批内序号 即为批次前缀
- 保留旧格式兼容(无 batch_seq 时回退 PUR-日期-时间-流水)
2026-08-31 13:54:03 +08:00
f499346f74 refactor(purchase): 批次概念改为基于 request_no 前缀推导,撤销数据库字段
按用户反馈:不需要新增数据库字段,现有 request_no (PUR-20260831-1021-0001)
本身就能推导批次——去掉末尾4位流水号即为批次前缀。

- 撤销 purchase_request.batch_no 字段(模型/数据库)
- 撤销 create 接口的 batch_no 参数与 generate_batch_no
- 批次标识 = request_no 去掉末尾 -XXXX 段
  getBatchKey('PUR-20260831-1021-0001') = 'PUR-20260831-1021'
- 按批次查询/批量审批接口改用 batch_key (request_no LIKE 前缀)
- 前端列表批次号列、整批弹窗、一键审批本批均基于前缀推导
- 零数据库迁移,历史数据立即可用
2026-08-31 13:49:11 +08:00
664127ee30 feat(purchase): 采购批次号支持,同一批提交的记录可分组查看/统计
背景: 循环提交把一批物品生成多条独立申请,无法识别'哪些是同一批采购'

后端:
- purchase_request 模型新增 batch_no 字段(同一批提交共享)
- create 接口接收 batch_no,无则自动生成 BATCH-yyyyMMdd-HHmm-随机
- 新增 GET /purchase/batch/<batch_no> 按批次查询所有记录
- 批量审批接口支持按 batch_no 一键审批整批

前端:
- 提交时生成 batch_no 共享给所有行
- 列表新增批次号列(可点击)
- 新增'整批查看'弹窗:显示同批次所有记录 + 一键批量通过本批
- 操作列新增'整批'按钮

数据库需执行: ALTER TABLE purchase_request ADD COLUMN batch_no VARCHAR(100);
2026-08-31 13:46:46 +08:00
4b62c81baa feat(purchase): 采购申请批量审批(解决循环提交需多次审批)
问题: 一次提交 10 个物品生成 10 条独立申请,审批人需操作 10 次

后端:
- 新增 POST /api/v1/purchase/batch-approve 批量审批接口
  接收 ids + action,循环审批,成功/失败分别返回

前端:
- 待审批列表加多选列(仅 status=0 可勾选)
- 顶部批量操作栏:批量通过 / 批量驳回 / 取消选择
- 批量驳回弹窗统一填写驳回原因
2026-08-31 13:41:25 +08:00
b68dfbf23d feat(purchase): 商家链接改为每行独立
- 明细表新增「商家链接」列,每行独立输入
- 移除公共区商家链接,公共信息区只保留审批人
- 提交时每行携带自己的 supplier_link
2026-08-31 13:35:34 +08:00
efb88c8f9c fix(purchase): 税率列加宽以完整显示两位数字+%
- 明细表税率列 80px → 100px
- 列表页税率列 70px → 80px
- 税率选项补充 3%/5%/9%
2026-08-31 13:33:58 +08:00
3a9ec81c51 fix(purchase): 照片删除加确认 + 修复同步照片跨行删除导致图片缺失
问题: 同步照片后多行共享同一物理文件 URL,删除某行照片时
deleteFile 删除了物理文件,其他行引用同一 URL 变图片缺失

修复:
- 删除前检查照片被几行引用
- 若被多行引用: 弹窗询问【全部删除】(所有行移除+删文件)
  或【仅移出此行】(只从当前行移除引用,不删服务器文件)
- 若仅当前行引用: 普通确认后删除
- 普通删除也加确认弹窗
2026-08-31 13:31:08 +08:00
25bb35e265 feat(purchase): 表格列宽优化 + 迷你上传框 + 照片同步所有
- 每列显式指定 min-width/width,输入多的列用 min-width 防挤压
- 照片列固定 90px,上传框缩小到 60x60(::v-deep 覆盖样式)
- 新增「照片同步所有」按钮:深拷贝第一行照片到所有行
- 照片列保持红星必填标记
2026-08-31 13:24:17 +08:00
f18e61a71a fix(purchase): 修复 Copy 图标不存在导致的模块加载错误
@element-plus/icons-vue 没有 Copy 图标,改为 CopyDocument
2026-08-31 13:18:44 +08:00
9e393ff998 feat(purchase): 弹窗加大 + 移除公共图片 + 每行照片必填
- 弹窗宽度 1180px → 1350px,缓解表格输入框拥挤
- 移除底部公共「图片凭证」上传区,照片统一在每行上传
- 照片列表头加红星必填标记
- 提交时逐行校验照片必填:某行无照片则阻断并提示该行名称
- 清理废弃的公共图片逻辑(fileList/customUpload/handleRemoveImage/usePasteUpload)
2026-08-31 13:16:52 +08:00
8d90b3c774 feat(purchase): 采购申请弹窗加大 + 每行独立备注/照片 + 备注一键同步
- 弹窗加大到 1180px、表格 max-height 400 减少滚动
- 明细表新增「备注」列和「照片」列(每行独立上传,最多3张)
- 新增「备注同步所有」按钮:把第一行备注复制到所有行
- 提交时行备注优先、行照片优先,无则回退公共备注/公共图片
- 图片校验改为逐行(行内或公共至少其一)
2026-08-31 13:10:59 +08:00
021c92ee8a feat(purchase): 采购申请改为动态明细表,支持一行多物料批量提交
- 新建弹窗物料区改为动态明细表格:每行独立选择物料/规格/数量/日期/单价/总价/税率
- 支持 [+ 添加一行] 动态增行、行内删除
- 审批人/商家链接/备注/图片凭证为公共信息
- 提交时 for 循环逐行调用单条 createPurchase 接口,后端无需改动
- 行内价格半联动:改单价自动算总价,手动改总价后不再覆盖
2026-08-31 13:05:29 +08:00
5abc504619 feat(outbound): 审批列表页增加完结按钮 + 优化缺货提示文案
- 去掉缺货提醒末尾的『是否查看?』(纯文案,保持强提醒但不承诺展示清单)
- approval/index.vue 对已通过(status=1)的审批单新增「完结」按钮
  库管/主管/超管可见,完结后从已通过列表移除
- 筛选区新增「已完结」状态选项,状态标签支持 status=4
2026-08-31 10:46:33 +08:00
bf104535e5 V3.69,8.31推送 2026-08-31 10:30:03 +08:00
3a07f1a272 fix(bom): BOM 详情查询改为 LEFT JOIN,子件物料被删后仍返回父件结构
- get_bom_detail 使用 outerjoin 替代 join
- 子件物料被删除后 child_name 显示 [已删除物料] 而非误报 BOM 不存在
- 修复按 BOM 出库时因子件删除导致 404 BOM 不存在
2026-08-31 10:28:22 +08:00
36e9f500aa feat(borrow): 借库未归还直接报废功能(关联报废单流程)
后端:
- trans_service 新增 scrap_borrow 方法:未归还借用标记为 scrapped,
  扣减总库存 stock_quantity(可用已在借出时冻结),生成 TransScrap 报废记录
- transactions.py 新增 POST /borrow/scrap 接口(复用 op_return:operation 权限,库管/主管可操作)
- scrap.py query_records 支持 trans_borrow 来源的物料名解析 + 行级隔离

前端:
- records.vue 未归还记录新增「报废」按钮(库管/主管可见)
- 报废弹窗:勾选明细 + 填报废原因 + 二次确认
- 状态显示新增「已报废」标签;整单所有明细报废时标记为 scrapped
2026-08-31 10:21:28 +08:00
39f3f8af45 feat(outbound): 审批单手动完结/作废功能
- 后端: outbound_service 新增 close_request 方法(状态 1-已通过 → 4-已完结)
- 后端: 新增 POST /api/v1/outbound/request/<id>/close 接口
- 模型: status_text 数组增加「已完结」
- 前端: create.vue 审批单选择区新增「强制完结此单」按钮
  完结后刷新列表,该单从已通过下拉中移除
- 权限: 超级管理员/审批人/拥有 outbound_create:operation 的用户可完结(库管可操作)
2026-08-31 10:15:33 +08:00
b6ec45a8b8 feat(outbound): 出库流程强化(缺料防漏 + 完全移除直接出库)
① BOM 清单 SKU 改为规格型号(getBomWithStock 返回 children 无 sku,只有 child_spec)
② 缺货清单自动写入出库申请备注(借鸡生蛋:历史欠料永久留存在申请单)
③ 打印单底部增加欠料待补签收区(补料人签字/日期)
④ 有缺料时阻断式二次确认,防手快漏看
⑤ 完全移除直接出库模式,所有出库必须按单出库
   - create.vue 删除 radio 切换、direct 相关逻辑
   - 提交前强制校验已选择审批申请单
2026-08-31 09:37:14 +08:00
a4bd6f54d4 feat(outbound): BOM 出库增加清单打印与缺货持久化提醒
- BOM 弹窗物料清单增加「本次结果」列(可出/缺货未出)
- 增加「打印 BOM 清单」按钮,可打印当前 BOM 的完整出库清单
- 缺货物料持久化到 localStorage,下次打开同一 BOM 时自动提示历史缺货记录
  防止重复出库或漏出
- 打印区域使用与 A4 出库单一致的 iframe 打印机制
2026-08-31 09:26:53 +08:00
fe52da77e9 feat(deploy): 部署脚本优化
- 打包时排除测试脚本/临时SQL/编译输出等垃圾文件
- 增加 SSL 证书备份
- 部署后自动验证 nginx 代理指向 inventory_api_prod
- 部署后自动验证 API 连通性(检测 404 及时报警)
2026-08-31 09:21:00 +08:00
0c3e57f5b5 fix(nginx): 生产 nginx 代理指向容器名 inventory_api_prod 避免 DNS 冲突
- 服务器上有多个 compose 项目(inventory-app / Track)都使用 backend 服务名
- nginx 中 proxy_pass http://backend:8000 会随机解析到 track_backend_prod
  导致 /api/ 请求 404
- 改为使用固定容器名 inventory_api_prod:8000
2026-08-28 16:46:02 +08:00
2ff0f92f94 fix(stocktake): 修复盘点报告导出 500 错误
- 导出盘点报告时第1126行使用了 func.sum()/func.coalesce()
  但文件未导入 sqlalchemy 的 func
- 改为 db.func.sum()/db.func.coalesce(),与文件内其他用法一致
2026-08-28 15:53:03 +08:00
57a6ab38d1 fix(outbound): 修复选单列表移除按钮排序后索引错位导致删错行
- 表格绑定 sortedSelectedItems(按库位排序),但移除按钮用 $index 操作原始 selectedItems
- 排序后索引与原始数组不一致,导致删除错误的行
- 改为按 uniqueKey 精确定位删除
2026-08-13 17:17:54 +08:00
7e4524ae42 fix(warning): 预警字段被 field_permissions Default Deny 规则错误过滤
- MaterialBase 映射中新增 warningStatus/warningEnabled/warningRed/warningYellow/warningRedEmails/warningYellowEmails 字段
- 新增 _permits() 函数支持通配符权限匹配 (material_list:* 覆盖所有 material_list:xxx)
- 修复 apply_strict_rbac 使用 _permits 替代直接 in 检查

根因: field_permissions.py 的 STOCK_FIELD_RBAC_MAPPING 中没有预警字段映射,
apply_strict_rbac 的 Default Deny 规则会删除所有不在映射中的字段,导致前端永远收不到预警数据。
2026-08-11 13:28:47 +08:00
9c0414b802 fix(outbound): 出库备注改为必填,按单出库自动填充申请原因
- 备注字段新增 required 校验规则
- placeholder 从「可选填」改为「请填写出库原因」
- 按单出库模式选择申请单后,自动将申请原因填入备注
2026-08-07 15:58:59 +08:00
7b5846b489 V3.68,8.3推送 2026-08-03 15:53:52 +08:00
d0776f1036 feat(import): 前端导入策略选择器 + 部分导入支持
- 新增导入策略单选:跳过重复行 / 覆盖更新
- 预览状态新增「将被更新」标签(橙色),区分「通过」「失败」
- 支持部分导入:有错误行时显示「忽略错误,仅导入正确的 N 条」按钮
- 预览时传递 mode 参数给后端
- 导入结果展示新增/更新/跳过数量
2026-08-03 15:53:24 +08:00
22c7d352d6 refactor(import): API 层支持导入策略参数
- /preview 端点接收 mode 参数,update 模式下 DB 重复行不视为错误
- /execute 端点接收 mode 参数传递给 service 层
- execute 仅导入 status 为 success/update 的行,error 行不再被提交
2026-08-03 15:53:15 +08:00
95057dedf5 refactor(import): 导入服务核心逻辑改造
- 预览阶段增加 Excel 内部重复检测 + 空规格去重 + 字段长度校验
- 执行阶段支持 skip 模式(跳过重复行继续导入)+ update 模式(覆盖更新已有记录)
- update 模式空值保护:Excel 空单元格不覆盖已有数据
- DB commit 异常防御:字段超长等异常优雅返回而非 500
- 去重规则改为仅依据 spec_model(货号唯一键)
- BOM 导入物料查找同步改为 spec-only
2026-08-03 15:53:10 +08:00
bc9cc18142 V3.67,8.3推送 2026-08-03 13:26:08 +08:00
6c7f8dbe61 fix: 修复搜索跳转弹窗无法打开的问题
- AppMain.vue: 将 router-view 的 key 从 route.fullPath 改为 route.path,避免 query 参数变化导致组件销毁重建
- list.vue: watch 中 router.replace 增加 query 非空判断,防止不必要的 URL 清理
- list.vue: handleEdit 的 nextTick 增加 try-catch 防御性保护
- list.vue: 添加 onUnmounted 调试探针
2026-08-03 13:25:54 +08:00
b84fffbd37 V3.66,8.3推送 2026-08-03 09:47:10 +08:00
65aba4b313 fix: token 刷新时缺少 company_name 导致多租户过滤返回空数据 2026-08-03 09:22:50 +08:00
60c6f634ce V3.65,8.3推送 2026-08-03 09:15:45 +08:00
d68ba1e987 fix: 页面刷新时主动续期 access_token,避免过期 token 触发 401 竞态导致权限空白 2026-07-23 09:48:33 +08:00
5cb1f3b24b V3.64 2026-07-21 10:21:27 +08:00
9ceb6ddc1d debug: 诊断出库审批/借库审批的 operationCode 是否被正确识别 2026-07-21 10:19:21 +08:00
d7d7d65a4f fix: inbound_summary 页面 v-if 从不存在权限码 inbound_summary:view 改为菜单权限 inbound_summary 2026-07-21 10:11:13 +08:00
01122a58f3 debug: inbound_summary 加日志确认 list.value 数据加载状态 2026-07-21 10:06:55 +08:00
63c36d1466 fix: 借库记录签名改回 null(始终可见),暂等 sys_element 补齐权限码 2026-07-21 09:59:14 +08:00
ca21294580 fix: transactions filter_item_by_permissions 只保留签名过滤,基础字段不再剥离 2026-07-21 09:56:34 +08:00
30f336779e fix: outbound filter_item_by_permissions 只过滤敏感金额字段,基础明细字段不再剥离 2026-07-21 09:53:47 +08:00
a8a0290cd8 fix: outbound total_amount 改为需权限 outbound_list:total_amount,库管无此权限则隐藏总金额 2026-07-21 09:49:46 +08:00
4ab7b6f541 fix: borrow/return/records permissionMap 基础列改为 null 始终可见,对齐 inbound 模式,移除 records alwaysVisible 硬编码 2026-07-21 09:40:58 +08:00
35690c5b8f fix: 出库列表 permissionMap 基础列改为 null(始终可见),对齐 inbound 模式;单价/小计保留权限控制 2026-07-21 09:39:16 +08:00
451d7b5719 V3.63 2026-07-20 14:33:26 +08:00