|
|
658fc28b9b
|
feat: 管理看板全面改版 — 增强可读性 + 填充空白区域
后端增强:
- DashboardStats 新增 tasks_rejected, tasks_rework, unread_notifications
- 新增 GET /dashboard/recent-activity 最近动态端点
- 关联 Task + Product 表返回完整动态信息
前端改版 (AdminDashboard.tsx):
- 4 张概览卡片: 产品流转 | 任务状态 | 品质通知 | 完成率
- 每张卡片含进度条(百分比标注) + 中文说明
- SVG 环形图展示任务完成率
- 最近流转动态时间线 (8条)
- 快捷入口: 创建产品/任务管理/打印配置/扫码干活
- 底部说明卡片解释"产品 vs 任务"的区别
- 响应式网格填满全屏, 无空白区域
|
2026-08-12 13:25:49 +08:00 |
|
|
|
d59f732a0e
|
fix: 数据库会话事务安全兜底
get_db() 依赖注入增加 try/except/rollback/finally:
- 请求处理中发生异常时自动 rollback
- 无论成功或异常,finally 中确保 close 释放连接
- 防止异常导致连接泄漏或脏事务残留
|
2026-08-12 12:04:45 +08:00 |
|
|
|
3a6ab7d756
|
security: 补全剩余端点鉴权 + 移除硬编码管理员后门
1. 鉴权补全
- orders.py: create_order 补全 Depends(get_current_user)
- print.py: print_execute 和 update_printer_config 补全鉴权
- records.py: update_record 和 delete_record 补全鉴权
2. 安全加固
- auth_service.py: 移除硬编码超级管理员(IRIS/123321)后门
- 所有用户统一通过MOM sys_user scrypt密码验证登录
|
2026-08-12 12:04:40 +08:00 |
|
|
|
8c54a38f55
|
security: API鉴权补全 + SQL拼接隐患消除
1. materials.py
- get_material_groups和get_material_items补全Depends(get_current_user)
- 移除TYPE_FILTER="1=1"死代码及4处f-string SQL拼接
- 全部SQL改为纯参数化text()查询
2. notifications.py
- list_notifications废弃user_id查询参数(越权漏洞)
- user_id强制从JWT Token解析,防止篡改参数偷看他人通知
- mark_notification_read补全鉴权
|
2026-08-12 12:03:12 +08:00 |
|
|
|
69f3e35d14
|
fix: Dashboard统计数据修复 + 生产环境SECRET_KEY强制校验
1. Dashboard统计Bug修复
- Task统计改用TASK_STATUS_PENDING/WIP/COMPLETED大写常量
- 旧代码使用小写"pending"/"in_progress"永远匹配不到数据
- 修复后tasks_pending/tasks_in_progress/tasks_completed返回真实值
2. 生产环境SECRET_KEY强制校验
- 新增model_validator:DEBUG=False且SECRET_KEY为默认值时抛出ValueError
- 阻止使用默认密钥部署到生产环境
|
2026-08-12 12:03:07 +08:00 |
|
|
|
cc199081f9
|
perf: CTE任务树加载器 + MOM跨库查询缓存
消除两个核心N+1性能瓶颈:
1. CTE任务树加载器 (task_tree_loader.py)
- PostgreSQL Recursive CTE一次性加载完整任务树
- 无论树深度多大,仅2条SQL(CTE + records selectinload)
- set_committed_value安全注入,避免Session脏数据
- 修复add_task_record双重加载问题
- 移除get_all_tasks中冗余的selectinload(child_tasks)
2. MOM跨库查询缓存 (mom_cache.py)
- 零依赖TTL内存缓存(threading.RLock + time.monotonic)
- 参数化ANY(:user_ids)替代OR拼接LIKE(防注入)
- get_all_products中3次调用共享缓存,2h TTL内零跨库查询
|
2026-08-12 12:03:02 +08:00 |
|
|
|
991d713777
|
feat(backend): 新增留言通知 — add_task_record 自动推送给任务负责人
触发条件:
- 有人对任务添加流转记录(留言/备注)
- 任务有 assignee_id
- 留言人 != 任务负责人 (不给自己发通知)
通知内容:
- title: 💬 收到新留言
- content: 产品[SN]的「任务名」有新留言:{前30字摘要}
- type: COMMENT
额外:
- Notification 模型新增 NOTIFY_COMMENT 常量
- 前端 notify 页新增 COMMENT 图标(💬)和标题(收到新留言)
|
2026-08-11 18:17:52 +08:00 |
|
|
|
b97dfaa95d
|
fix(backend): 宏观状态权限校验 — 根除 current_user 空值绕过漏洞
Bug: if current_user: 在 Python 中 None/空dict均为falsy,
一旦 current_user 为空则整个权限块被跳过直接放行。
修复:
1. if not current_user → 直接 raise 401
2. 反转 SUPER_ADMIN 判断: if user_role != 'SUPER_ADMIN' 进入校验
(避免 if/else/pass 空分支带来的逻辑歧义)
3. main_task is not None 显式判断 (替代隐式 truthy)
|
2026-08-11 17:39:30 +08:00 |
|
|
|
40a2d87345
|
fix: 消息通知页不能点进详情 — 补全 product_serial_number
问题: 点击通知卡片跳转 detail?taskId=xxx,但 detail.vue onLoad 只认 serial 参数导致空白页
修复:
1. 后端 NotificationResponse 新增 product_serial_number 字段
2. 后端 notifications API 联表 tasks+products 批量填充 serial
3. 前端 notify/index.vue handleCardTap 优先用 product_serial_number 跳转,兜底从 content 正则解析
4. 前端 detail.vue onLoad 新增 taskId 兜底 → doQueryByTask 反查 product_sn
|
2026-08-11 15:56:25 +08:00 |
|
|
|
88dc7381f6
|
fix(backend): 权限漏洞修复 + 业务逻辑审查修复
1. 宏观状态越权修复 (products.py + product_service.py):
- update_overall_status 增加权限校验:仅 SUPER_ADMIN 或当前操作该产品主线任务的人可修改,否则 403
2. 任务撤回越权修复 (task_service.py + tasks.py):
- recall_task 增加校验:操作人必须等于上游任务负责人(谁发出的谁撤回),否则 403
- 管理员 (SUPER_ADMIN/SUPERVISOR) 直接放行
3. 驳回上游溯源修复 (task_service.py - reject_task):
- 将 TaskLog (action_type=create) 提升为优先溯源方式,解决协助分支转交后驳回找不到正确发起人的 Bug
- 保留 parent_task.assignee_id + task.assignee_id 两级兜底
4. complete_task 父节点继承修复:
- 修复 task_type == 'MAIN' 永不匹配的 Bug(模型无此值)
- 改为 not parent_task_id or task_type in (TRANSFER, RECOVERY)
|
2026-08-11 15:05:30 +08:00 |
|
|
|
d40a8d480e
|
fix(backend): end_task 和 complete_task 补齐权限校验
- end_task 新增 operator_role 参数 + _check_permission 调用
- complete_task 新增 operator_role 参数 + _check_permission 调用
- 两个端点均注入 current_user Depends(get_current_user)
- 非任务负责人且非管理员/主管调用时返回 403
|
2026-08-11 10:13:40 +08:00 |
|
|
|
de47d27cfb
|
fix(backend): _recalc_product_location 修复 func.or_() → or_()
func 是 SQL 函数调用(如 func.now()),不能替代 WHERE 条件中的 or_ 运算符。
这会导致结束协助分支时 SQL 抛错 500。
|
2026-08-11 10:05:13 +08:00 |
|
|
|
718e205f53
|
feat(backend): 完工转交智能父节点继承算法
- complete_task: MAIN转交保持平级(parent_task_id),SPAWN转交认当前为父(task.id)
- 基因严格继承: task_type不会篡位成MAIN
|
2026-08-11 10:02:01 +08:00 |
|
|
|
1fe9c3d59d
|
feat: 留言板 API + 零信任安全:后端 Token 鉴权强制覆写 operator_id
- 新增 GET/POST /products/{id}/messages 端点
- POST 创建留言时注入 current_user = Depends(get_current_user)
- operator_id 优先取 Token 中的 username,防止前端越权伪造发言身份
- 同时将 product.current_location_id 显示改为 formatUserName 映射
|
2026-08-10 17:37:10 +08:00 |
|
|
|
b14773f81b
|
feat: 产品协同留言板 — ProductMessage 模型 + API + 迁移
- 新增 ProductMessage 模型,挂载在 products.id(ON DELETE CASCADE)
- GET/POST /products/{id}/messages 接口
- 注册到 Alembic 自动发现
|
2026-08-10 17:37:01 +08:00 |
|
|
|
e326f8d311
|
fix: 修复任务完工/结束 500 + 后端基因继承
- 移除 task.child_tasks 的 ORM 属性直接赋值(导致 SQLAlchemy 状态机崩溃)
- complete_task 创建 next_task 时补上 task_type=task.task_type 基因继承
|
2026-08-10 17:36:54 +08:00 |
|
|
|
2440e9bdaa
|
fix: 修复产品删除 500 — ImportError + FK 自引用约束
- 修正 TaskLog 导入路径:app.models.task → app.models.task_log
- 删除任务前先切断 parent_task_id 自引用外键
- 删除产品前先切断 parent_product_id 自引用外键
- 真正执行 delete(TaskRecord) 和 delete(TaskLog) 替代空 select
|
2026-08-10 17:36:48 +08:00 |
|
|
|
34724e478c
|
fix: SQL语法错误—func.and_()/or_()改为sqlalchemy.and_()/or_()
|
2026-08-10 11:41:10 +08:00 |
|
|
|
e447de6cfa
|
feat: 当前位置100%动态主干化—与宏观状态同源,只跟主分支,静态字段仅兜底
|
2026-08-10 11:32:07 +08:00 |
|
|
|
b43bded0ef
|
feat: 宏观状态动态从主干任务获取+任务树assignee中文姓名映射(后端+前端)
|
2026-08-10 11:25:44 +08:00 |
|
|
|
60af3b9998
|
feat: 物料选择全量展示(移除成品/半成品限制)
|
2026-08-10 11:02:22 +08:00 |
|
|
|
2880ea6df7
|
fix: Grid回退grid-cols-12精确对齐+分组标题按device/order切换+宏观状态receive/transfer只主线
|
2026-08-10 10:58:33 +08:00 |
|
|
|
4854eb626e
|
feat: 宏观状态只同步主线+删除5s倒计时+序列号确认+分组切换(订单/设备)+序列号列
|
2026-08-10 10:37:56 +08:00 |
|
|
|
ad9fb8d37e
|
refactor: 位置回溯极简—只跟主干任务(WIP>PENDING>COMPLETED),无视协助分支
|
2026-08-09 18:49:59 +08:00 |
|
|
|
45b5376537
|
fix: 三致命Bug—macro_status预计算+排除已完工脏读+flush落盘+递归深度限制10
|
2026-08-09 18:23:55 +08:00 |
|
|
|
f33396b9f1
|
fix: 位置回溯父任务优先 + Tab筛选改为本地calcProductStatus过滤
|
2026-08-09 18:10:13 +08:00 |
|
|
|
3c4c16a1cc
|
fix: 四Bug—权限互斥+中文姓名+记录弹窗+后端位置回溯(含RecordsModal)
|
2026-08-09 17:55:40 +08:00 |
|
|
|
65ff05fb2f
|
feat: 状态渲染修复+中文姓名映射+SUPERVISOR/SUPER_ADMIN权限控制(前端+后端)
|
2026-08-07 17:26:14 +08:00 |
|
|
|
beea543fbd
|
fix: 创建产品时自动将当前位置设为当前登录用户(谁创建谁持有)
|
2026-08-07 15:42:10 +08:00 |
|
|
|
bc43b5a732
|
feat: 产品管理 — 当前位置显示真实姓名 + 编辑弹窗 + 删除确认
|
2026-08-07 15:38:01 +08:00 |
|
|
|
0de981ea81
|
fix: OTA检测闭环 — 新增GET /check-update + App端uni.getSystemInfoSync版本对比
|
2026-08-07 12:35:00 +08:00 |
|
|
|
bff8787e62
|
feat: OTA热更新 — 版本检测API + App端WGT下载安装 + app_versions表
|
2026-08-07 11:49:59 +08:00 |
|
|
|
b71c5a2d07
|
feat: 双Token认证(Access 2h/Refresh 7d) + 通知系统(转交/驳回自动推送)
|
2026-08-07 11:44:04 +08:00 |
|
|
|
6a79e21302
|
闭环修复: transfer/spawn/receive补TaskRecord + reject加task_type + branchLabel只对SPAWN编号
|
2026-08-06 13:14:26 +08:00 |
|
|
|
0d323e8181
|
血缘锚定法: task_type字段+迁移+三大接口写入+TreeCanvas基于task_type布局
|
2026-08-06 13:03:25 +08:00 |
|
|
|
e5e2a395e7
|
撤回链式接力: CANCELED后生成WIP子任务还给操作人+TreeCanvas CANCELED视为串行换行
|
2026-08-06 12:53:23 +08:00 |
|
|
|
616638a6c8
|
撤回改为CANCELED状态标记+TaskRecord留痕+TreeCanvas灰度渲染+全部状态映射更新
|
2026-08-06 12:51:40 +08:00 |
|
|
|
eb97c12bed
|
修复撤回: 移除parent_task_id空校验+兼容无父任务场景(仅删除)
|
2026-08-06 12:39:47 +08:00 |
|
|
|
58cb9a23ef
|
修复撤回: transfer新任务parent_task_id=task.id(溯源链) + canRecall放宽(兼容旧数据)
|
2026-08-06 12:38:26 +08:00 |
|
|
|
67755c7847
|
修复撤回500: 先删task_logs+task_records再删task,加delete import
|
2026-08-06 11:41:45 +08:00 |
|
|
|
57884d7baa
|
撤回转交: recall接口删除子任务恢复父WIP + 前端canRecall判断 + 红色撤回按钮
|
2026-08-06 11:39:22 +08:00 |
|
|
|
b2cfa3871e
|
取消转交的协助分支阻塞: transfer_task移除_check_children_done,仅end_task保留
|
2026-08-06 11:29:58 +08:00 |
|
|
|
ef9e5bbae5
|
修复get_all_tasks: 改用_to_flat_response(不递归children)彻底消除MissingGreenlet
|
2026-08-06 11:19:19 +08:00 |
|
|
|
9846dd6c8f
|
修复: MissingGreenlet_product访问try/catch + spawn_subtask不再覆盖overall_status
|
2026-08-06 11:16:07 +08:00 |
|
|
|
999f8c2f3e
|
IRIS过滤容错: 后端SQL失败时降级全量+前端严格过滤department===IRIS
|
2026-08-06 10:08:18 +08:00 |
|
|
|
eccf79b8d1
|
IRIS部门过滤: 后端users接口按department=IRIS过滤 + 前端双重兜底
|
2026-08-06 10:07:47 +08:00 |
|
|
|
e183ea5583
|
工业级重构: 用户Grid选择+工序由接收人定+隐藏结束按钮(次分支卡片内结束)+蓝图网格背景
|
2026-08-06 09:52:21 +08:00 |
|
|
|
eb52e2fd48
|
修复: create_task同步current_location_id到接收人 + receive_task兜底同步产品位置
|
2026-08-06 09:12:07 +08:00 |
|
|
|
f3fb000bda
|
产品宏观状态自动同步: create_task/transfer_task/spawn_subtask均更新overall_status
|
2026-08-06 09:06:07 +08:00 |
|
|
|
f665cf7e24
|
紧急修复: transfer中real_assignees→real_branches变量名 + SpawnRequest BaseModel导入
|
2026-08-05 18:16:07 +08:00 |
|