Commit Graph

26 Commits

Author SHA1 Message Date
263f7ba3a1 feat(borrow): 前端适配整单转交与双向握手
· 转交弹窗由「选择明细」改为**整单**:列出该单全部未还物品(只读),
  明确告知「发起后对方确认,责任才转移」。原先让用户挑一行,挑中就只转
  那一行 —— 正是单内撕裂的入口,现从 UI 上根除。
· 操作栏新增【接收转交】【拒绝】:仅对 pending_transfer.is_mine 的行显示,
  即「待我接收」的转交。已有 PENDING 时不再显示【转交】,避免重复发起。
· 状态列新增「转交待确认」:此时主表 current_holder 未变(东西还在原持有人
  手上),必须用状态列把「责任正在转移中」显式表达出来,否则界面上看不出
  任何变化。
· 新增 acceptBorrowTransfer / rejectBorrowTransfer API;
  拒绝时用 prompt 收集可选原因,写入转交流水备注。

错误提示仍交由 request 拦截器统一 toast,不在本地重复弹出。
2026-09-17 10:04:16 +08:00
0eca1805b6 style(borrow): 当前持有人列改为常亮蓝色,转交时加浅蓝底与细边框
背景
----
上一轮按「只有发生过转交才高亮」实现后,业务方反馈「当前持有人那里也应该
高亮才对」—— 该列回答的是「东西现在在谁手上」,比「当初谁借的」更需要一眼
看到,不该只在转交时才着色。本轮按新要求调整。

改动
----
· 基础态:当前持有人一律主题色加粗(不再区分是否转交);
· 转交态:额外加浅蓝底 + 细边框(--el-color-primary-light-9 / light-5),
  强调「经手人已变更,归还时必须由他本人来还」。
  用浅蓝而非实心色块,保持上一轮确立的降噪基调,只做一层轻标记。

覆盖三处「当前持有人」:借还记录列表、还库页、转交弹窗(弹窗按单条明细比对,
故新增 isRowTransferred;组行仍用 currentHolderList)。

★ 数据侧的事实(供验收参考):trans_borrow_transfer 目前 0 笔,34 条未还
  记录的「当前持有人 = 借用人」、53 条已还记录的持有人为空。
  也就是说转交态(浅蓝框)在产生第一笔真实转交前不会出现。
2026-09-17 09:53:31 +08:00
b1f39acb97 style(borrow): 持有人高亮统一为条件蓝色,姓名按两字补全角空格等宽
一、当前持有人高亮策略统一
----
还库页(return.vue)该列原为橙色标签(type="warning"),与列表页在上一轮
已完成的条件高亮不一致。现统一为:
  · 当前持有人 ≠ 借用人(确曾转交)→ 主题色 var(--el-color-primary) 加粗
  · 两者同一人(常态)→ 普通深色文本,不做任何高亮

比对前把两侧都归一化到「斜杠前段」:历史数据可能混入「姓名/拼音」的完整
username 写法,不归一化会把同一人误判成转交,让整列无故飘蓝。

(records.vue 该列在 ba5394f 已是此策略,本轮仅同步调用 formatName。)

二、姓名两字补全角空格,实现等宽对齐
----
新增 formatName()(放在 src/utils/format.ts,而非各组件内复制 —— 列表页与
还库页都要用,规则改动只需改一处):

  '高雪'     -> '高 雪'    U+3000 全角空格,占一个汉字宽
  '郭俊玥'   -> '郭俊玥'
  '欧阳娜娜' -> '欧阳娜娜'
  'AB'       -> 'AB'        纯拉丁不补,否则渲染出 'A B' 怪相
  null/'测试01'/混合字符 -> 原样

★ 纯展示层:只在模板 {{ formatName(row.borrower_name) }} 中调用,
  row.borrower_name 等底层对象**一个字节都没动**。
  姓名是转交/归还责任链的匹配键(records.vue 的 currentHolderList、
  return.vue 的 isTransferred),往数据里插不可见字符会让比对、检索、
  导出、复制全部带上它 —— 这正是上一轮拒绝「插空格」的原因,本轮改用
  渲染期格式化,视觉要求与数据纯洁性同时满足。

★ 为什么用 U+3000 而非普通空格:普通空格宽度随字体浮动(约半个汉字),
  补进去反而难对齐;U+3000 稳定占一个汉字宽,与「1 汉字 ≈ 1em」一致。

三、配套
----
· 归还人 / 当前持有人 / 借用人三列(含转交弹窗的持有人列)统一走 formatName;
· .name-fixed 增加 margin-right,避免同一格内多个姓名(同一单持有人/归还人
  不同)紧贴成「高 雪张 三」。
2026-09-17 09:45:34 +08:00
ba5394f70c style(borrow): 借还记录页视觉降噪、移除前端假排序、主行改按整单汇总
一、视觉降噪
----
· 「当前持有人」由橙色标签改为纯文本:
    未转交 → 普通文本;发生过转交(当前持有人 ≠ 借用人)→ 主题色加粗。
  原先一律用色块,一屏几十个标签会把真正需要关注的「已转交」淹没。
· 「无限期」由蓝色标签改为灰色小字:它不是异常,不该和红色的「已逾期」抢
  视觉重心。(沿用系统既有术语「无限期」,与借出页「无限期/长期借用」一致)
· 转交弹窗内的持有人列同步降噪,保持同一表达。

二、移除前端假排序
----
「借出时间」列的 sortable 是 Element Plus 的**前端排序**,只会重排当前页的
10 条,反而打乱后端按单号聚合的「逾期优先」排序(有限期在前、按最早应还
升序、无限期按最早借出升序)。已移除。若将来需要按其他字段排序,应改用
sortable="custom" 并由后端接管。

三、主行改按整单汇总
----
主行字段原样取「首条明细」(groupMap 首次遇到即定型),多明细单会失真。
现对四项做整单聚合:
  · 状态     —— 全部报废→已报废;全部结清→已还;仍有未还且已还过一部分→
                部分归还;全部未还→未还。
                修复「首条已还清、其余未还 → 主行显示已还,却仍出现在未归还
                页签」的口径矛盾(该页签由后端按整单聚合过滤)。
  · 归还人   —— 去重汇总(原只显示首条明细的经手人)
  · 归还时间 —— 取**最晚**(整单结清的那一刻;原显示最早那笔)
  · 应还时间 —— 取**最早**(与后端排序键 min(expected_return_time) 对齐)

四、姓名定宽对齐
----
中文 1 字 ≈ 1em,故姓名统一占 3em(.name-fixed):「石利」与「郭俊玥」占同样
横向空间,一列名字纵向对齐。
★ 刻意用 CSS 而非往数据里插全角空格:插字符会污染真实数据(复制、导出、检索、
  姓名比对全带着它),而转交/归还的责任链恰恰依赖姓名比对。

★ 如实说明:上述聚合里,状态/归还人/应还时间三项在当前数据上**尚无可见变化**
  —— 实测单号内状态完全一致、归还人同为一人、应还时间因同批发货天然相同。
  它们是防住「部分归还 + 多明细」组合的前瞻性修正。真正改变显示的只有「归还
  时间取最晚」:BOR-20260616-0001(21 条明细、21 个不同归还时间)等 2 张单。
2026-09-17 09:38:19 +08:00
ece5dd8d72 feat(borrow): 前端转交/流转明细 UI 与借用人选人适配
转交 UI(借还记录页)
----
· 操作列新增【转交】,v-permission="'borrow_transfer'" + 按钮 loading 防抖
· 弹窗明示「仅支持整单全部转交」与「转交后须由接收人本人归还」,并在确认框
  复述接收人与转交数量
· 列表是 borrow_no 主子表结构,trans_borrow.id 在**明细行**上,而一张单的明细
  可各有不同持有人(转交是逐条明细进行的),故弹窗先让用户选定明细;单条明细
  时自动选中(实测 54/60 的单号只有 1 条,等于零额外点击)。
  该「单号按钮 → 弹窗选明细」范式沿用本页既有的「申请报废」。

流转明细时间线
----
· 操作列新增【流转记录】,无特殊权限要求(页面本身已由 op_records 把守)
· Drawer + el-timeline 倒序展示 借出 → 转交(可多次) → 归还 → 报废,
  每节点显示时间、动作、当事人(借用人 / 转出→接收 / 实际归还人)与经手库管,
  转交备注一并展示
· 主列表新增「当前持有人」列:转交后可能与「借用人」不是同一人;一张单的明细
  持有人可能不同,去重后逐个展示,已全部回库显示「已回库」

身份锚点适配
----
· 借出页:借用人由「自由输入姓名」改为「用户下拉」,提交 borrower_id
  (姓名无法唯一锚定一个人,重名即责任链断裂)
· 归还页:新增「实际归还人」下拉,默认取首件物品的当前持有人,提交 returner_id;
  主表新增「当前持有人」列提示库管该由谁来还
· 错误提示不再本地重复弹出 —— request 拦截器已按后端 msg 全局 toast,
  再弹一次会双份

验证:vite build 通过;接口契约经后端回归用例校验。
2026-09-17 09:18:06 +08:00
6520f1c97c feat(scrap): 前端适配报废审批收口
配合后端把三条报废旁路收口到审批流。

【删除】api/scrap.ts 的 createScrap()
  对应后端已删的 POST /api/v1/scrap。该函数此前已是死代码(全仓无调用方),
  页面早已切换到申请-审批-按单执行流程。

【改造】不良品看板 views/stock/defective/index.vue
  「报废销毁」→「申请报废」:弹窗新增「指定审批人」(必填,复用
  getApproversList)。API 由 scrapDefective 改为 submitDefectiveScrapRequest。
  ★ 弹窗与成功提示都明确写出「在管数量不会立即扣减,待审批通过并执行后才
    扣减」—— 申请不预占 remaining_qty,行数据看起来毫无变化,不说明会诱发
    重复提交。

【改造】借还记录页 views/transaction/records.vue
  「报废」→「申请报废」:弹窗新增「指定审批人」(必填)。原先内联的
  request() 调用挪到 api/transaction.ts 成为 submitBorrowScrapRequest,
  与全仓 API 分层一致。确认框文案改为「提交后进入审批流程」。
  顺带清理 canScrap 里硬编码的 `username === 'IRIS'` 后门 —— 该账号在
  sys_user 表中根本不存在,属死代码。

【改造】按单报废执行页 views/operation/scrap/create.vue
  按 scrap_mode 把批准明细分流:
    · scan 项(库存行 / 在管不良品)—— 走原有扫码购物车,逻辑不变
    · auto 项(借出未还)—— 实物在借用人手上、无法扫码,放入**只读区块**
      展示,不进购物车(购物车语义是「扫码证据」,混入会让扫码校验失效)
  纯 auto 单隐藏整个扫码区并提示「本单无可扫码物料,将按批准数量直接执行」;
  扫码进度只统计 scan 项(否则进度条永远满不了,会让操作员误以为没扫完);
  提交守卫放宽为「购物车与 auto 项都为空才拦」;确认框追加
  「另有 N 项将按批准数量自动执行」,避免操作员误以为只报废了扫到的那些。
  matchKey 同步加入来源表(与后端 _match_key 保持逐字同口径),
  sourceLabel 补两种新来源的中文名。

存量单据没有 scrap_mode 字段,前端回落为 scan,行为与改造前完全一致。
2026-09-16 17:14:29 +08:00
fd0bfd3d9c feat(records): 借还记录接入高级筛选
复用 app/utils/advanced_filter.py 的解析与谓词逻辑:
  · 父级字段(单号 borrow_no、借用人 borrower_name)走标准 SQL 谓词
  · 子级字段(SKU、物料名称)经单号子查询过滤,否定操作符走 NOT IN 整单排除
  · 物料名经三表联查(buy/semi/product JOIN material_base)

借还的单号维度查询基于 order_subq 子查询分页,故此处把过滤条件施加在
order_subq.c.borrow_no 上,与既有的状态/日期/公司隔离过滤保持同一层次。

前端 records.vue 新增「高级筛选」el-popover(字段/操作符/值 + 添加条件/
应用筛选/重置),序列化为 advancedFilters JSON 字符串随查询下发。

验证:sku ne 0000000002 → 52 单(库中无单含该 SKU,正确不减);
      sku contains 0000 → 52 单(52 单的 SKU 全部含 0000,数据巧合)。
2026-09-10 13:06:03 +08:00
c35ec9a659 feat(records): 出库/借还记录统一高级搜索版式
三个记录页(出库/借还/报废)此前搜索区形态各异:出库用裸 div + 分散样式,
借还缺日期范围,报废只有 SKU 输入框。现统一为 el-form :inline="true" +
.filter-form 版式,并补齐缺失的过滤维度。

借还记录(新增日期范围能力):
  · 后端 get_records 增加 start_date/end_date 参数,按「借出时间」过滤;
  · 边界补全时分秒(YYYY-MM-DD → 当日 00:00:00 / 23:59:59),
    与出库记录同口径,解决零点截断导致当天记录漏查的问题;
  · API 层透传两个新参数。

出库记录:
  · 版式统一为 inline 表单,日期选择器加 label;
  · 新增「重置」按钮;
  · 搜索类型切换由 500ms 防抖改为立即查询。

借还记录:
  · 新增「重置」按钮;搜索类型/状态切换改为立即查询(取消防抖)。

实测(SUPER_ADMIN):
  报废 全部/单号/SKU/操作人/物料名/日期 六类过滤均 200 且命中正确;
  借还 无过滤 52 单 / 本月 18 单 / 空区间 0 单(日期过滤生效);
  出库 无过滤 395 单 / SKU 277 / 姓名 7 / 物料名 16 / 单号 OUT-2026 命中 395。
2026-09-10 12:06:08 +08:00
1527d552d4 feat: 出库/借库记录记录并展示库位快照(DB加列+后端写入+记录页展示) 2026-09-04 11:42:44 +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
63c36d1466 fix: 借库记录签名改回 null(始终可见),暂等 sys_element 补齐权限码 2026-07-21 09:59:14 +08:00
4ab7b6f541 fix: borrow/return/records permissionMap 基础列改为 null 始终可见,对齐 inbound 模式,移除 records alwaysVisible 硬编码 2026-07-21 09:40:58 +08:00
DXC
6ad00884ba 借库列表:主子表聚合 + 展开行内嵌明细 2026-06-12 11:07:23 +08:00
DXC
d736d5d4a9 fix: 彻底移除 op_records 字段级权限过滤,所有字段对普通角色可见 2026-05-15 10:40:53 +08:00
dxc
1e341ab6aa 版本变更3.20 2026-05-15 10:07:12 +08:00
DXC
a8119dd577 fix(permission): force inject view-level permission checks for all unprotected root nodes 2026-03-25 10:21:28 +08:00
DXC
71e5f075d2 feat: implement composite debounced search with prepended select and wipe out duplicate root permission nodes 2026-03-20 10:26:45 +08:00
DXC
990399a408 feat: implement cross-table search and debounced dynamic search for borrow and return records 2026-03-20 09:58:42 +08:00
DXC
7a4717ce21 fix: restrict overdue warning color strictly to the countdown text and remove row-level style pollution 2026-03-19 11:50:04 +08:00
DXC
8db1015f99 fix: implement traffic-light color warning and correct ascending sort for overdue borrow records 2026-03-19 11:45:27 +08:00
DXC
b74464df6b feat: add descending sort by return date and color-coded warning for impending returns 2026-03-19 11:40:38 +08:00
DXC
1e38696e68 feat: support indefinite borrow period for long-term asset allocation 2026-03-18 10:57:21 +08:00
DXC
79d4a365e0 feat: add partial return support with returned_quantity tracking 2026-03-18 10:41:19 +08:00
dxc
42b0cddd3e feat: add column permission checks to transaction records table
Co-authored-by: aider (openai/DeepSeek-V3.2-Thinking) <aider@aider.chat>
2026-02-27 14:07:48 +08:00
dxc
a2b1a62132 feat: add RBAC and field masking for borrow/return/records pages
Co-authored-by: aider (openai/DeepSeek-V3.2-Thinking) <aider@aider.chat>
2026-02-27 14:05:52 +08:00
dxc
04ee938cd1 借库逻辑实现 2026-02-06 17:11:47 +08:00