Commit Graph

860 Commits

Author SHA1 Message Date
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
d80edc961c fix: 三个模块 update endpoint 统一 Default Deny + 权限码全量对齐 sys_element 2026-07-20 14:26:22 +08:00
3dca2b9254 fix: buy.py update field_to_perm 库位权限码 inbound_buy:warehouse_location → inbound_buy:warehouse_loc,对齐 sys_element 2026-07-20 14:21:22 +08:00
f6c1dedd22 V3.62,库管权限修改内容 2026-07-17 17:06:27 +08:00
097fbb319f fix: validateUnique 编辑模式下值未变时跳过重复校验,仅值改变时才检查冲突 2026-07-17 17:04:10 +08:00
1f43de4ccc debug: buy.vue validateUnique 加详细日志——打印 form.id/row.id/value 比对过程 2026-07-17 17:02:25 +08:00
9bcd02c742 fix: update_buy perm_code=None 导致 NoneType 崩溃 + validateUnique 编辑时排除自身改用 Number() 防类型不一致 2026-07-17 16:57:46 +08:00
a8fb0cfc94 debug: validateUnique 加详细日志追踪编辑时误报重复编号问题 2026-07-17 16:53:57 +08:00
76c7e3d3dc V3.61,出库审批的可编辑即可操作 2026-07-17 16:31:33 +08:00
29de22b575 fix: crossDomain 重复收集 — 真实树中的 system_mgmt/crossDomain 与虚拟 global_privileges 冲突,从真实树中移除 crossDomain 避免双重收集 2026-07-17 16:22:59 +08:00
0e6294890c debug: crossDomain 收集逻辑加精确断点日志 2026-07-17 16:20:22 +08:00
c45e7b5a52 debug: assign_permissions 加详细日志追踪 crossDomain 删除/插入/提交后状态 2026-07-17 16:18:05 +08:00
0074d96163 fix: 权限配置页 GET 请求加 _t 防浏览器缓存 + 保存后自动刷新 UI 2026-07-17 16:13:12 +08:00
96eb56766e fix: 回退权限保存后的 auto-refresh,改为手动刷新提示 2026-07-17 16:07:54 +08:00
c9cf4e0901 fix: 权限保存后自动刷新 UI 回显,确保勾选框状态与数据库同步 2026-07-17 16:02:51 +08:00
de2d13fa68 fix: 全局权限码 crossDomain/global:cross_company_op 强制存为 company_name='',防止按公司隔离失效 2026-07-17 15:50:06 +08:00
266a0e011f fix: 防自锁 — 操作者修改自己角色时强制保留 system_permission + system_permission:operation 2026-07-17 15:42:31 +08:00
efe04c5d42 fix: assign_permissions 删除逻辑对齐 get_user_permissions 查询逻辑 — 公司定制+全局模板一起替换 2026-07-17 15:38:14 +08:00
9c3fcbca4c migration: 补齐 sys_element 缺失的 :operation 权限码 + 角色分配 SQL 2026-07-17 15:29:59 +08:00
f3c946d584 fix: 借库审批同样修复 — sys_element 补充 op_borrow_approval:operation,can_approve 增加 RBAC 权限判断 2026-07-17 15:22:54 +08:00
05832e913b fix: can_approve 增加 outbound_approval:operation RBAC 权限判断,前端按钮权限与后端审批权限统一对齐 2026-07-17 15:17:26 +08:00
686186d7d6 fix: Create/Update 成本字段分离 — Create 保留 BOM 自动计算值,Update 按 hasFormFieldPermission 剥离敏感字段 2026-07-17 14:50:06 +08:00
8b6539b976 fix: semi/product 对话框中成本字段添加 v-if 权限守卫,与 buy.vue 的 hasFormFieldPermission 模式对齐 2026-07-17 14:43:08 +08:00
1cc7d51e03 fix: semi/product submit 响应用 apply_strict_rbac 替代硬编码 resp.pop,成本字段纳入 RBAC 统一管控 2026-07-17 14:36:26 +08:00
cac8a360ec V3.60,邮件发送失败问题修复 2026-07-17 14:28:40 +08:00
fd506775c1 fix: send_email_async 主线程预取 config 传入 daemon 线程,修复异步邮件因丢失 Flask context 导致 MAIL_ENABLED=false 2026-07-17 14:27:39 +08:00
5b57895b99 fix: docker-compose 添加 MAIL_* 环境变量,确保 daemon 线程中邮件配置不丢失 2026-07-17 14:27:32 +08:00
a4a6d027fe V3.59,紧急修复出入库问题 2026-07-17 14:04:18 +08:00
036d756fbd fix: 前端 product.vue permissionMap null→显式权限码 + fetchMaterialSuggestions 改用 async/await 修复首次搜索空白 2026-07-17 13:45:38 +08:00
9fe64847a7 fix: 前端 buy/semi permissionMap 数量字段 null→显式权限码,与后端 RBAC 统一对齐 2026-07-17 13:45:32 +08:00
61b60f7aa0 fix: 修复 semi/product 物料搜索空白 — search_base 移除错误地对 MaterialBase 数据使用 Stock 表映射过滤 2026-07-17 13:45:28 +08:00
08b7674610 fix: 后端数量字段纳入RBAC — StockBuy/Semi/Product 的 in_quantity/stock_quantity/available_quantity 从 None 改为显式权限码 2026-07-17 13:45:23 +08:00
3c0954598c perf: 综合安全加固 — RBAC严格映射+异步邮件+字段权限白名单+前端对齐+导入模板
本次提交包含本会话所有修改的最终统一提交

## 权限系统重构
- permission_service.py: 添加入库/采购操作元素 + ensure_default_permissions
- field_permissions.py: 严格1-to-1 Default Deny 字段映射(StockBuy/Semi/Product/MaterialBase)
- decorators.py: _expand_operation_perms 双向粒度桥接 + prevent_double_submit
- deploy_production.sql: 修复 sys_element 别名码(qty_inbound→in_quantity)

## 采购模块
- purchase.py: 权限驱动可见性 + inbound_purchase独立权限 + 价格字段过滤
- purchase_service.py: 异步邮件 + 三阶段批量模糊匹配防N+1
- purchase/index.vue: canApprove严格操作权限 + upload重复修复

## 导出/入
- base_service.py: export_excel 流式写入防OOM + get_latest_specs 优化
- import_service.py + import_api.py: Excel批量导入(模板+预览+执行)
- ImportDialog.vue: 三步骤导入弹窗

## 异步邮件
- email_service.py: send_email_async (守护线程)
- inventory_task.py: send_email→send_email_async

## 前端对齐
- product/semi/buy.vue: 列对齐in_quantity/stock_quantity/available_quantity + localStorage缓存V2
- buyOdoo.vue: 排序修复 + 导入按钮 + 移除点击展开加载
- BomManage.vue: 懒加载分组 + 导入按钮
- list.vue: 导入按钮
- Selection.vue + borrow/apply: BOM匹配修复 + 导入按钮
- outbound/create.vue: 出库类型必选
- AppMain.vue: 移除transition白屏修复
- material_base.ts, outbound.ts, bom.ts, stock.ts: 新增API函数
2026-07-17 13:07:12 +08:00
2e903cff2c perf: 规格连号助手优化 — 流式查询+宽松regex+Redis缓存
## base_service.py get_latest_specs
- .all()全量→with_entities().limit(10000) 防OOM
- regex放宽: 支持 LICA-3000/M3x12 等格式(旧版仅匹配OPT12046)
- 移除OPT硬编码→SUB_CATEGORY_PREFIXES可配置集合
- Redis缓存(1h): 首次查询后缓存,后续命中直接返回

## base.py 缓存失效
- 新增 _invalidate_specs_cache() 辅助函数
- create/update/delete 成功后清除缓存
2026-07-16 18:15:43 +08:00
d647af6bc3 fix: Odoo页面排序失效 — 排序参数未传递+缓存未清除
## buyOdoo.vue
- handleSortChange: 排序时清除已展开分组缓存,强制重新加载
- loadGroupItems: 传递 orderByColumn + isAsc 排序参数到API
2026-07-16 17:34:30 +08:00
754c46bd59 feat: 采购申请字段级价格权限 — 库管看不到采购价格
## permission_service.py
- init_all_menus: 新增3个采购权限元素
  inbound_purchase:unit_price, :total_price, :tax_rate

## purchase.py
- _filter_purchase_prices(): 无价格权限则pop价格字段
- GET /purchase (列表): 应用价格过滤
- GET /purchase/<id> (详情): 应用价格过滤
- approved-unstocked: 保留价格(入库数据源,前端按inbound_buy权限控制)

## purchase/index.vue
- 列表: 单价/总价/税率列 v-if hasPermission
- 详情: 单价/总价 v-if hasPermission
2026-07-16 17:34:24 +08:00
6e064064d5 V3.58 2026-07-16 14:28:37 +08:00
23fc10a25f fix: Day2就绪 — 删除硬化+索引补全+全局异常处理
## base_service.py — MaterialBase删除硬化
- 新增 BomTable 引用检查(bom_usage_count)
- 物料被BOM引用时禁止删除,提示「请先解除BOM绑定」

## models/base.py + bom.py — 缺失索引补全
- material_base: company_name + is_enabled 添加 index=True
- bom_table: is_enabled 添加 index=True

## __init__.py — 全局异常处理
- @app.errorhandler(ValueError) → 400 + 自定义消息
- @app.errorhandler(404/405) → 标准错误
- @app.errorhandler(Exception) → 500 + 通用消息
  堆栈仅记录服务器日志,不泄露到前端
2026-07-16 14:14:43 +08:00
382b461b68 feat: 挂载ImportDialog + 修复路由白屏
## 页面挂载
- buyOdoo.vue: 新增「批量导入」按钮(新增旁边), ImportDialog material
- list.vue: 新增「批量导入」按钮, ImportDialog material
- BomManage.vue: 新增「导入BOM」按钮(新建BOM左边), ImportDialog bom

## 白屏修复
- AppMain.vue: 移除 transition mode=out-in 动画包裹(导致首次访问白屏)
  改为 :key=route.fullPath 强制创建新实例
2026-07-16 14:00:44 +08:00