From e731bf5f64d71ed93a570d505c52dc44d491175e Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期二, 22 九月 2026 11:21:33 +0800
Subject: [PATCH] fix(home): 修复首页采购品分布和出入库趋势数据统计问题
---
doc/20260922_delete_RB120260814001_rollback.sql | 13 +
doc/20260922_backfill_sales_ledger_approval_rollback.sql | 25 +++
doc/20260521_首页HomeController接口升级前端变更文档.md | 38 ++++
src/main/resources/mapper/sales/SalesLedgerProductMapper.xml | 12
src/main/resources/mapper/stock/StockOutRecordMapper.xml | 3
doc/20260922_油品出入库图片URL失效修复说明.md | 151 ++++++++++++++++++
src/main/resources/mapper/stock/StockInventoryMapper.xml | 24 ++
doc/20260922_库存详情拆分库存入库出库三接口前端联调文档.md | 185 +++++++++++++++++++++++
src/main/resources/mapper/stock/StockInRecordMapper.xml | 3
src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java | 4
10 files changed, 451 insertions(+), 7 deletions(-)
diff --git "a/doc/20260521_\351\246\226\351\241\265HomeController\346\216\245\345\217\243\345\215\207\347\272\247\345\211\215\347\253\257\345\217\230\346\233\264\346\226\207\346\241\243.md" "b/doc/20260521_\351\246\226\351\241\265HomeController\346\216\245\345\217\243\345\215\207\347\272\247\345\211\215\347\253\257\345\217\230\346\233\264\346\226\207\346\241\243.md"
index 008660f..64efd66 100644
--- "a/doc/20260521_\351\246\226\351\241\265HomeController\346\216\245\345\217\243\345\215\207\347\272\247\345\211\215\347\253\257\345\217\230\346\233\264\346\226\207\346\241\243.md"
+++ "b/doc/20260521_\351\246\226\351\241\265HomeController\346\216\245\345\217\243\345\215\207\347\272\247\345\211\215\347\253\257\345\217\230\346\233\264\346\226\207\346\241\243.md"
@@ -111,3 +111,41 @@
2. 闇�瑕佹寜鏃ユ湡澶嶇洏鐪嬫澘鏃讹紝浣跨敤 `bizDate` / `planDate`銆�
3. 鑰侀〉闈㈠彲涓嶆敼锛岀户缁部鐢ㄥ師鍙傛暟涔熻兘姝e父鑱旇皟銆�
+## 5. 閲囪喘鍝佸垎甯冨彛寰勪慨姝o紙2026-09-22锛�
+
+`GET /home/rawMaterialPurchaseAmountRatio` 涔嬪墠鎸変骇鍝佹爲銆屽師鏉愭枡銆嶅瓙绫昏繃婊ら噰璐槑缁嗭紝瀹為檯閲囪喘鍙拌处鐧昏鐨勫搧绫伙紙鏌存补銆佺伃鐏櫒锛夋寕鍦ㄣ�屾垚鍝�/鎴愬搧娌广�嶃�岃澶囪鏂�/鍏叡瀹夊叏璁惧銆嶄笅锛屽鑷存帴鍙�**鎭掕繑鍥炵┖鏁扮粍**銆佸ぇ灞忔棤鏁版嵁銆�
+
+鐜板凡鏀逛负**涓庛�屽悇浜у搧閿�鍞噾棰濆垎鏋愩�嶅悓鍙e緞**锛氬彇鍏ㄩ儴閲囪喘鏄庣粏锛坄type=2`锛夋寜鏄庣粏涓婄殑鍝佺被 `product_category` 鑱氬悎锛岄噾棰濆彇 `tax_inclusive_total_price`锛孴op5 鍊掑簭銆�
+
+| 椤� | 鍙樺寲 |
+| --- | --- |
+| 璇锋眰 | 涓嶅彉锛堟棤鍙傛暟锛� |
+| 鍝嶅簲缁撴瀯 | 涓嶅彉锛坄name` / `value` / `rate`锛� |
+| `name` 璇箟 | **鐢便�屽師鏉愭枡瀛愮被鍚嶃�嶅彉涓恒�岄噰璐槑缁嗙櫥璁扮殑鍝佺被銆�** |
+| 杩囨护 | 浠呮帓闄ゅ搧绫讳负绌虹殑琛� |
+
+娉ㄦ剰浜嬮」锛�
+
+1. 鍝嶅簲缁撴瀯娌″彉锛屽墠绔�**涓嶉渶瑕佹敼浠g爜**锛涗絾鑻ュ浘琛ㄦ爣棰樺啓姝讳簡銆屽師鏉愭枡閲囪喘閲戦鍗犳瘮銆嶏紝寤鸿鏀规垚銆岄噰璐搧鍒嗗竷銆嶄箣绫荤殑涓�у彨娉曗�斺�旂幇鍦ㄨ繑鍥炵殑鏄叏閮ㄩ噰璐搧绫伙紝涓嶅彧鏄師鏉愭枡銆�
+2. 淇敼鐨勬槸 Mapper XML锛�**闇�瑕侀噸鍚悗绔�**鎵嶇敓鏁堬紙`devtools.restart.enabled: false`锛夈��
+3. 鍚屾簮鐨� `selectRawMaterialExpense`锛堣垂鐢ㄦ瀯鎴愰噷鐨勩�屽師鏉愭枡銆嶉噾棰濓紝鍚屾牱鎸変骇鍝佹爲銆屽師鏉愭枡銆嶅瓙鏍戣繃婊わ級鐩墠**鏈敼**锛屽湪璇ョ鎴锋暟鎹笅鍚屾牱浼氱畻鎴� 0銆傛湰鍥捐〃鐨勫搧绫诲彛寰勮皟鏁翠笉娑夊強瀹冿紝鏄惁涓�骞舵斁寮�鍙﹁纭銆�
+
+## 6. 鍑哄叆搴撹秼鍔夸骇鍝佸垎绫昏繃婊や慨姝o紙2026-09-22锛�
+
+`GET /home/productInOutAnalysis?type=<1|2|3>` 涔嬪墠鍙瘮瀵逛骇鍝佸垎绫荤殑**鐩存帴瀛愯妭鐐�**锛坄p.parent_id = rootCategoryId`锛夛紝鑰屼骇鍝佹爲鏄�屽ぇ绫� 鈫� 鍝佺被 鈫� 鍏蜂綋浜у搧銆嶄笁灞傘�佷骇鍝佸瀷鍙凤紙`product_model`锛夋寕鍦�**鍙跺瓙浜у搧**涓婏紝鎵�浠ュ瀷鍙锋案杩滃懡涓笉鍒拌鏉′欢 鈫� 7 澶╄秼鍔挎亽涓哄叏 0銆�
+
+鐜板凡鏀逛负**閫掑綊鍙栨暣妫靛垎绫诲瓙鏍�**锛坄WITH RECURSIVE product_tree`锛夛紝涓庨」鐩噷鍏朵粬搴撳瓨/浜у搧鏌ヨ锛坄StockInRecordMapper`銆乣StockOutRecordMapper`銆乣StockInventoryMapper`銆乣ProductModelMapper`锛変繚鎸佸悓涓�鍐欐硶銆傞�掑綊 CTE 鍐欏湪鎷彿鍐咃紝璇彞浠嶄互 `SELECT` 寮�澶达紝鏁版嵁鏉冮檺鎷︽埅鍣ㄥ `stock_in_record` / `stock_out_record` 鐨勮繃婊ょ収甯哥敓鏁堛��
+
+| 椤� | 鍙樺寲 |
+| --- | --- |
+| 璇锋眰 | 涓嶅彉锛坄type`锛�1 鍘熸潗鏂� / 2 鎴愬搧 / 3 鍗婃垚鍝侊級 |
+| 鍝嶅簲缁撴瀯 | 涓嶅彉锛坄date` / `inCount` / `outCount`锛岃繎 7 澶╂寜鏃ワ級 |
+| `type=1`锛堝師鏉愭枡锛� | 璇ョ鎴�**浠嶄负绌�**锛氫骇鍝佸瀷鍙锋病鏈夋寕鍦ㄣ�屽師鏉愭枡銆嶅瓙鏍戜笅鐨勶紝灞炴暟鎹幇鐘惰�岄潪缂洪櫡 |
+| `type=2`锛堟垚鍝侊級 | 淇鍚庡嚭鐜版暟鎹紙鏌存补鍦ㄣ�屾垚鍝�/鎴愬搧娌�/鏌存补銆嶄笅锛� |
+
+娉ㄦ剰浜嬮」锛�
+
+1. 鍝嶅簲缁撴瀯娌″彉锛屽墠绔�**涓嶉渶瑕佹敼浠g爜**锛涗慨鏀圭殑鏄� Mapper XML锛�**闇�瑕侀噸鍚悗绔�**鎵嶇敓鏁堛��
+2. 鍒嗙被鏄犲皠鏈夌洸鍖猴細銆屽姙鍏敤鍝併�嶃�岃澶囪鏂姐�嶃�屽嵄搴熷缃鐢熷嵄搴熴�嶈繖涓夊ぇ绫讳笉鍦� `type` 鐨� 1/2/3 鏄犲皠鍐咃紝鎸傚湪瀹冧滑涓嬮潰鐨勫瀷鍙凤紙濡傜伃鐏櫒锛変换浣� `type` 閮芥煡涓嶅埌銆傝嫢澶у睆闇�瑕佽鐩栵紝闇�鎵╁睍 `type` 鍙栧�兼垨鏀规寜 `product_category` 杩囨护锛屽彟琛岀‘璁ゃ��
+3. 鍑哄簱渚ф湭鎸夊鎵圭姸鎬佽繃婊わ紝寰呭鎵癸紙`approval_status IN (0,3)`锛夌殑鍑哄簱鍗曚篃浼氳鍏ヨ秼鍔匡紱濡傞渶鍙湅宸插鎵归�氳繃鐨勯噺锛屽彟琛岀‘璁ゃ��
+
diff --git a/doc/20260922_backfill_sales_ledger_approval_rollback.sql b/doc/20260922_backfill_sales_ledger_approval_rollback.sql
new file mode 100644
index 0000000..4b93bcc
--- /dev/null
+++ b/doc/20260922_backfill_sales_ledger_approval_rollback.sql
@@ -0,0 +1,25 @@
+-- 鍥炴粴鑴氭湰锛氶攢鍞彴璐� RB120260810001(id=94) / RB120260611001(id=97) 琛ュ綍鐨勫鎵硅褰�
+-- 鐢熸垚鏃堕棿锛�2026-09-22 鏉ユ簮搴擄細36.213.90.123:11101 / product-inventory-management-rbhb
+-- 琛ュ綍鍐呭锛氬綋鏃惰繖涓ゆ潯鍙拌处鐢� Excel 瀵煎叆浜х敓锛宎pproval_status 涓虹┖銆佹棤瀹℃壒瀹炰緥銆�
+-- 鎸夊疄渚� 265锛堝彴璐� 103锛屽凡閫氳繃锛夌殑褰㈢姸琛ヤ簡 2 瀹炰緥 x (1 node + 1 task + 2 record)锛�
+-- 骞舵妸 sales_ledger.approval_status 缃负 '閫氳繃'銆�
+-- 鎵ц椤哄簭锛歳ecord -> task -> node -> instance -> sales_ledger锛堝閿涔夌敱搴旂敤缁存姢锛岃繖閲屾寜渚濊禆鍊掑簭鍒狅級
+-- 娉ㄦ剰锛氫袱涓疄渚� id 鍒嗗埆涓� 268/269锛屾崲搴撴墽琛屾椂浠� instance_no 涓哄噯
+
+delete from approval_record
+where instance_id in (select id from (
+ select id from approval_instance where instance_no in ('SP20260922001','SP20260922002')) t);
+
+delete from approval_task
+where instance_id in (select id from (
+ select id from approval_instance where instance_no in ('SP20260922001','SP20260922002')) t);
+
+delete from approval_instance_node
+where instance_id in (select id from (
+ select id from approval_instance where instance_no in ('SP20260922001','SP20260922002')) t);
+
+delete from approval_instance
+where instance_no in ('SP20260922001','SP20260922002');
+
+-- 浠呰繕鍘熸湰娆¤ˉ褰曠殑涓ゆ潯锛涜嫢鏈熼棿宸茶浜哄伐閲嶆柊璧版祦绋�/椹冲洖锛屼笉瑕佹墽琛屼笅闈㈣繖鍙�
+update sales_ledger set approval_status = null where id in (94, 97);
diff --git a/doc/20260922_delete_RB120260814001_rollback.sql b/doc/20260922_delete_RB120260814001_rollback.sql
new file mode 100644
index 0000000..9459a6f
--- /dev/null
+++ b/doc/20260922_delete_RB120260814001_rollback.sql
@@ -0,0 +1,13 @@
+-- 鍥炴粴鑴氭湰锛氶攢鍞彴璐� RB120260814001锛堟薄娉ュ缃湇鍔★級鍒犻櫎鍓嶇殑鍘熸牱鏁版嵁
+-- 鐢熸垚鏃堕棿锛�2026-09-22 09:33:22 鏉ユ簮搴擄細36.213.90.123:11101 / product-inventory-management-rbhb
+-- 鎭㈠椤哄簭锛氬厛 sales_ledger锛屽啀 sales_ledger_product锛屾渶鍚� production_plan
+
+-- 1. sales_ledger (id=95)
+INSERT INTO `sales_ledger` VALUES (95,'RB120260814001',NULL,'姹℃偿澶勭疆鏈嶅姟','2026-08-14','鏉庢垚鑺�',445,'鍏嬫媺鐜涗緷甯傞噾瀹滄案娉扮幆淇濈鎶�鏈夐檺鍏徃','鍗栨补',NULL,NULL,NULL,NULL,NULL,NULL,'320',NULL,NULL,100,75471.00,'2025-05-16 00:00:00','閾惰杞处','2026-08-14 16:00:00',320,100,75471.00);
+
+-- 2. sales_ledger_product (id=199)
+INSERT INTO `sales_ledger_product` VALUES (199,95,'姹℃偿','鎹疄','鍚�',1.00,NULL,6,75471.00,75471.00,71199.06,'澧炰笓绁�',1,NULL,429,'鍞愬姫灏�','2026-09-18 15:47:56',NULL,0,1,320,100,1,NULL);
+
+-- 3. production_plan (id=144)
+INSERT INTO `production_plan` VALUES (144,95,199,'JH202608140001','2026-08-15 00:00:00.000000',NULL,'2026-09-17 17:54:25.654946','2026-09-17 17:54:25.655131',320,320,100,429,1.000000,0,'閿�鍞�','2026-08-15 00:00:00.000000',NULL);
+
diff --git "a/doc/20260922_\345\272\223\345\255\230\350\257\246\346\203\205\346\213\206\345\210\206\345\272\223\345\255\230\345\205\245\345\272\223\345\207\272\345\272\223\344\270\211\346\216\245\345\217\243\345\211\215\347\253\257\350\201\224\350\260\203\346\226\207\346\241\243.md" "b/doc/20260922_\345\272\223\345\255\230\350\257\246\346\203\205\346\213\206\345\210\206\345\272\223\345\255\230\345\205\245\345\272\223\345\207\272\345\272\223\344\270\211\346\216\245\345\217\243\345\211\215\347\253\257\350\201\224\350\260\203\346\226\207\346\241\243.md"
new file mode 100644
index 0000000..516af73
--- /dev/null
+++ "b/doc/20260922_\345\272\223\345\255\230\350\257\246\346\203\205\346\213\206\345\210\206\345\272\223\345\255\230\345\205\245\345\272\223\345\207\272\345\272\223\344\270\211\346\216\245\345\217\243\345\211\215\347\253\257\350\201\224\350\260\203\346\226\207\346\241\243.md"
@@ -0,0 +1,185 @@
+# 搴撳瓨璇︽儏鎷嗗垎涓恒�屽簱瀛� / 鍏ュ簱璁板綍 / 鍑哄簱璁板綍銆嶄笁鎺ュ彛 鍓嶇鑱旇皟鏂囨。
+
+鏇存柊鏃堕棿锛�2026-09-22
+閫傜敤鐗堟湰锛氭湰娆″悗绔彉鏇村悗
+
+---
+
+## 1. 闂锛氫竴涓帴鍙e綋涓変釜鐢�
+
+搴撳瓨璇︽儏寮圭獥閲屽悓鏃跺睍绀�**搴撳瓨**銆�**鍏ュ簱璁板綍**銆�**鍑哄簱璁板綍**涓夊潡鍐呭锛屼絾涓夊潡閮藉彇鑷悓涓�涓帴鍙o細
+
+```
+GET /stockInventory/pageListCombinedStockInventory?topParentProductId=276¤t=1&size=100
+```
+
+鑰岃繖涓帴鍙g殑璁捐鍙e緞鏄細
+
+- **鎸夎鏍艰仛鍚�**鈥斺�斾竴琛屼竴涓� `product_model_id`锛宍batch_no` 鐢� `GROUP_CONCAT` 鎷兼垚涓�涓诧紱
+- **鍏ュ簱淇℃伅**鈥斺�斿彇璇ヨ鏍�**鏈�杩戜竴鏉�** `stock_in_record` 鐨勫瓧娈碉紙鍌ㄧ綈鍙�/瀵嗗害/杩囩绛夛級锛屼笖**涓嶅甫鎵瑰彿鏉′欢**锛�
+- **鍑哄簱淇℃伅**鈥斺�斿彇璇ヨ鏍�**鏈�杩戜竴鏉�** `stock_out_record` 鐨勫瓧娈碉紝**涓嶅甫鎵瑰彿銆佷笉甯﹀悎鏍肩被鍨嬨�佷篃涓嶇湅瀹℃牳鐘舵��**銆�
+
+浠� `topParentProductId=276`锛堟垚鍝侊級涓轰緥锛屾帴鍙e疄闄呭彧杩斿洖 **1 琛�**锛�
+
+| 瀛楁 | 杩斿洖鍊� |
+| --- | --- |
+| model / productName | `0#鏌存补` / `鏌存补` |
+| batchNo | `20260921-CY001-001,20260921-CY001-002`锛堜袱涓壒娆℃嫾鍦ㄤ竴璧凤級 |
+| qualifiedQuantity | `65.3400`锛堜袱鎵瑰悎璁★級 |
+| tankNo | `01#` |
+| netWeight | `32.8000`锛�**鍙槸鏈�鏂伴偅鎵�**鐨勫噣閲嶏紝涓嶆槸鍚堣锛� |
+| outTonnage | `7.9800` |
+| outCustomerName | `鏂扮枂鏄撴仼鐩婄幆澧冪鎶�鏈夐檺鍏徃` |
+
+闂灏卞湪杩欙細**鍏ュ簱/鍑哄簱瑕佺殑鏄�"璁板綍鍒楄〃"锛屾帴鍙g粰鐨勫嵈鏄�"鑱氬悎琛屼笂鐨勪竴涓揩鐓у��"**銆傛墍浠ュ悓涓�琛岀殑搴撳瓨鏄� 65.34锛屽叆搴撳噣閲嶅嵈鏄� 32.80锛屽涓嶄笂锛涘嚭搴撴洿鍙湁涓�鏉★紝鍘嗗彶璁板綍鍏ㄧ湅涓嶅埌銆�
+
+---
+
+## 2. 鏀规硶锛堢粨璁猴級
+
+涓変釜鍦烘櫙鍚勭敤鍚勭殑鎺ュ彛锛�
+
+| 鍦烘櫙 | 鎺ュ彛 | 鏈鏄惁鏀瑰姩 |
+| --- | --- | --- |
+| 搴撳瓨 | `GET /stockInventory/pageListCombinedStockInventory` | 涓嶅彉 |
+| 鍏ュ簱璁板綍 | `GET /stockInRecord/listPage` | **鏂板 `productModelId` 杩囨护** |
+| 鍑哄簱璁板綍 | `GET /stockOutRecord/listPage` | **鏂板 `productModelId` 杩囨护** |
+
+```
+搴撳瓨璇︽儏 GET /stockInventory/pageListCombinedStockInventory?topParentProductId=276
+鍏ュ簱璁板綍 GET /stockInRecord/listPage?topParentProductId=276&productModelId=407
+鍑哄簱璁板綍 GET /stockOutRecord/listPage?topParentProductId=276&productModelId=407
+```
+
+杩欎袱涓褰曟帴鍙f湰鏉ュ氨瀛樺湪锛堝叆搴撶鐞嗚彍鍗� 2355 / 鍑哄簱绠$悊鑿滃崟鐢ㄥ畠淇╋級锛�**涓�鐩存槸杩斿洖鍏ㄩ儴璁板綍鐨勫垎椤靛垪琛�**锛屽彧鏄師鍏堢己涓�涓�"绮剧‘鍒版煇涓鏍�"鐨勫弬鏁帮紝鍙兘闈� `model` 妯$硦鍖归厤銆傛湰娆℃妸 `productModelId` 琛ヤ笂銆�
+
+### 2.1 浜や簰鍙e緞锛氫笁涓� tab 鍚勮嚜鍒嗛〉鏌ヨ
+
+搴撳瓨璇︽儏閲岀殑銆屽簱瀛� / 鍏ュ簱璁板綍 / 鍑哄簱璁板綍銆嶆槸**涓変釜 tab锛堝尯鍧楋級锛岀偣鍝釜鏌ュ摢涓�**锛屼笉鏄墦寮�寮圭獥涓�娆℃�ф妸涓夌被鏁版嵁鍏ㄦ媺鍥炴潵銆備笁涓� tab 鍚勮嚜鐙珛浼犲垎椤靛弬鏁般�佸悇鑷淮鎶� `current` / `size`锛屽垏鎹� tab 鏃舵寜闇�璇锋眰锛�
+
+| tab | 璇锋眰 | 鍒嗛〉 |
+| --- | --- | --- |
+| 搴撳瓨 | `pageListCombinedStockInventory` | 璇ユ帴鍙f寜瑙勬牸鑱氬悎锛屼竴涓脊绐楅�氬父鍙湁鍑犺锛宍size=100` 瓒冲 |
+| 鍏ュ簱璁板綍 | `stockInRecord/listPage` | **璧版甯稿垎椤�**锛宍size` 鎸� tab 鍐呰〃鏍肩殑姣忛〉鏉℃暟浼狅紙濡� 10 / 20锛� |
+| 鍑哄簱璁板綍 | `stockOutRecord/listPage` | **璧版甯稿垎椤�**锛屽悓涓� |
+
+**涓嶈涓轰簡"瑕佸叏閮ㄦ暟鎹�"鑰屼紶瓒呭ぇ `size` 涓�娆℃媺瀹�**锛歚total` 宸茬粡鍦ㄨ繑鍥炰綋閲岋紙`data.total`锛夛紝鍓嶇鎷垮畠娓叉煋鎬绘潯鏁般�佹甯哥炕椤靛嵆鍙紱浼犺秴澶� `size` 涓�鏃﹁秴杩囪褰曟�绘暟锛岃秴鍑洪儴鍒嗗墠绔篃鎷夸笉鍒帮紙鏄垎椤典笂闄愶紝涓嶆槸鍏ㄩ噺璇箟锛夛紝璁板綍澶氫簡杩樹細鎷栨參鎺ュ彛銆�
+
+---
+
+## 3. 鏈鍚庣鏀瑰姩
+
+鍙敼浜嗕袱鏉℃煡璇紝鍚勫姞涓�涓彲閫夎繃婊ゆ潯浠讹紙涓嶄紶鏃惰涓轰笌鍘熼〉闈㈠畬鍏ㄤ竴鑷达級锛�
+
+| 鏂囦欢 | 鏀瑰姩 |
+| --- | --- |
+| `src/main/resources/mapper/stock/StockInRecordMapper.xml` | `listPage` 鏂板 `params.productModelId` 鈫� `and sir.product_model_id = #{params.productModelId}` |
+| `src/main/resources/mapper/stock/StockOutRecordMapper.xml` | `listPage` 鏂板 `params.productModelId` 鈫� `and sor.product_model_id = #{params.productModelId}` |
+
+Controller / Service / DTO 鍧囨棤闇�鏀瑰姩鈥斺�擿StockInRecordDto`銆乣StockOutRecordDto` 宸茬户鎵垮惈 `productModelId` 鐨� POJO锛孲pring 鐩存帴浠� query string 缁戝畾銆�
+
+---
+
+## 4. 璇锋眰鍙傛暟
+
+### 4.1 鍏ュ簱璁板綍 `GET /stockInRecord/listPage`
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+| --- | --- | --- | --- |
+| `topParentProductId` | Long | 鍚� | 浜у搧鏍戞牴鑺傜偣 id锛屾煡璇ヨ妭鐐�**鍙婂叾鎵�鏈夊瓙瀛�**浜у搧涓嬬殑璁板綍 |
+| `productModelId` | Long | 鍚� | **鏈鏂板**銆傜簿纭埌鏌愪釜瑙勬牸锛堜竴琛� = 涓�涓鏍硷級 |
+| `batchNo` | String | 鍚� | 鎵瑰彿锛�**妯$硦**鍖归厤 |
+| `productName` | String | 鍚� | 浜у搧鍚嶇О锛屾ā绯� |
+| `model` | String | 鍚� | 瑙勬牸锛屾ā绯� |
+| `type` | String | 鍚� | `'0'` 鍚堟牸 / `'1'` 涓嶅悎鏍� |
+| `recordType` | String | 鍚� | 鍏ュ簱鏉ユ簮绫诲瀷锛堥噰璐叆搴� / 鐢熶骇鍏ュ簱 绛夛級 |
+| `timeStr` | String | 鍚� | 鎸� `create_time` 妯$硦鍖归厤锛堝 `2026-09-21`锛� |
+| `current` / `size` | int | 鍚� | 鍒嗛〉锛岄粯璁� `current=1`銆乣size=10` |
+
+### 4.2 鍑哄簱璁板綍 `GET /stockOutRecord/listPage`
+
+鍙傛暟鍚屼笂锛坄timeStr`銆乣productName`銆乣model`銆乣batchNo`銆乣productModelId`銆乣type`銆乣recordType`銆乣topParentProductId`锛夛紝姝ゅ杩斿洖浣撹繕甯﹂攢鍞悎鍚屽彿 `salesContractNo`銆�
+
+> `topParentProductId` 涓� `productModelId` **鍙悓鏃朵紶**锛屾槸 `AND` 鍏崇郴銆傛棦鐒� `productModelId` 宸茬粡鑳藉敮涓�瀹氫綅瑙勬牸锛屽彧浼犲畠涓�涓氨澶燂紱鍚屾椂浼犵浉褰撲簬澶氫竴灞�"蹇呴』鍦ㄨ繖妫典骇鍝佹爲涓�"鐨勪繚闄┿��
+
+---
+
+## 5. 杩斿洖褰㈡��
+
+涓や釜鎺ュ彛閮借繑鍥� `AjaxResult`锛屽垎椤垫暟鎹湪 `data` 閲岋紙涓庡簱瀛樻帴鍙g殑 `R` 缁撴瀯涓�鑷达紝閮芥槸 `code` / `msg` / `data`锛夛細
+
+```
+data.records[] // 璁板綍鏁扮粍
+data.total // 鎬绘潯鏁�
+data.current / data.size / data.pages
+```
+
+`records` 閲岀殑瀛楁鏄� `sir.*`锛堟垨 `sor.*`锛�**鏁村紶琛ㄧ殑鍒�**锛屽啀鍔狅細
+
+| 鎺ュ彛 | 棰濆瀛楁 |
+| --- | --- |
+| 鍏ュ簱 | `productName`銆乣model`銆乣unit`銆乣createBy`锛堝缓鍗曚汉鏄电О锛夈�乣salesContractNo`锛堜唬鍌ㄥ叆搴撶粦瀹氱殑閿�鍞悎鍚屽彿锛夈�乣sourceOrderNo`锛堟簮鍗曞彿锛� |
+| 鍑哄簱 | `productName`銆乣model`銆乣unit`銆乣createBy`銆乣salesContractNo`锛堝彲缁戝涓彴璐︼紝閫楀彿鎷兼帴锛� |
+
+鍏ュ簱渚у睍绀哄瓧娈碉紙鍌ㄧ綈/娌瑰簱/鐗╂祦/杩囩锛変笌鍑哄簱渚у瓧娈碉紙`outCategory`銆乣outTonnage`銆乣outDate`銆佸鎴枫�佽溅杈嗐�佽繃纾呫�佺収鐗囷級閮芥槸鍘熸牱甯﹀嚭鐨勶紝**涓庡嚭搴撹褰曞垪琛ㄣ�佸叆搴撶鐞嗗垪琛ㄨ繑鍥炵殑鏄悓涓�濂楀瓧娈�**锛屽墠绔粍浠跺彲鐩存帴澶嶇敤銆�
+
+---
+
+## 6. 瀹炴祴绀轰緥锛堝簱鍐呯湡瀹炴暟鎹級
+
+### 6.1 鍏ュ簱璁板綍
+
+```
+GET /stockInRecord/listPage?topParentProductId=276&productModelId=407¤t=1&size=100
+```
+
+杩斿洖 **2 鏉�**锛堝師鏉ヨ仛鍚堟帴鍙e彧缁欎竴涓� 32.80锛夛細
+
+| id | batchNo | stockInNum | type | approvalStatus | tankNo | netWeight |
+| --- | --- | --- | --- | --- | --- | --- |
+| 236 | `20260921-CY001-002` | 32.8000 | 0 | 1 | `01#` | 32.80 |
+| 235 | `20260921-CY001-001` | 32.5400 | 0 | 1 | `01#` | 32.54 |
+
+涓ゆ潯 `stockInNum` 鐩稿姞 = 65.34锛屼笌搴撳瓨琛岀殑 `qualifiedQuantity` 瀵瑰緱涓婁簡銆�
+
+### 6.2 鍑哄簱璁板綍
+
+```
+GET /stockOutRecord/listPage?topParentProductId=276&productModelId=407¤t=1&size=100
+```
+
+杩斿洖 **1 鏉�**锛歚id=257`锛宍outTonnage=7.98`锛宍outCategory=浠e偍`锛宍customerName=鏂扮枂鏄撴仼鐩婄幆澧冪鎶�鏈夐檺鍏徃`锛宍tankNo=01#`锛宍approvalStatus=1`锛屾敞鎰忚繖鏉$殑 `batchNo` 鍜� `type` 閮芥槸 **NULL**锛堟补鍝佸嚭搴撹褰曚笉钀芥壒鍙�/绫诲瀷锛夈��
+
+---
+
+## 7. 娉ㄦ剰浜嬮」锛堣仈璋冨墠蹇呯湅锛�
+
+1. **`pageListCombinedStockInventory` 鐨� `out*` 涓庡叆搴撳瓧娈典繚鐣欎笉鍔�**銆傚簱瀛樼鐞嗗垪琛紙鑿滃崟 2352锛夊湪鐢� `tankNo`銆乣oilProduct`銆乣density`銆佽繃纾呯瓑鍒楋紝鎵�浠ユ湰娆�**娌℃湁鍒犻櫎**杩欎簺瀛楁锛屾帴鍙h繑鍥炵粨鏋勫畬鍏ㄦ病鍙樷�斺�斿彧鏄墠绔�**涓嶈鍐嶆嬁瀹冨綋鍏ュ簱/鍑哄簱鏄庣粏鐢�**銆�
+
+2. **璇ユ帴鍙g殑 `batch_no` 鏄嫾鎺ヤ覆**銆傚鎵规瑙勬牸浼氳繑鍥� `"20260921-CY001-001,20260921-CY001-002"`锛屼笉鑳藉綋鍗曚釜鎵瑰彿灞曠ず鎴栧洖浼犮�傝鎸夋壒娆$湅锛岃蛋鍏ュ簱璁板綍鎺ュ彛锛堜竴琛屼竴涓� `batch_no`锛夈�傝繖涔熸槸鏈鎷嗗垎鐨勬牳蹇冨師鍥犮��
+
+3. **鍏ュ簱/鍑哄簱鍒楄〃涓嶈繃婊ゅ鏍哥姸鎬�**锛屽緟瀹℃牳锛�0锛夈�佸鏍告湭閫氳繃锛�2锛夌殑璁板綍閮戒細杩斿洖銆傚簱瀛樿鎯呰嫢瑕佸彧灞曠ず"宸茬敓鏁�"鐨勮褰曪紝鍓嶇鎸� `approvalStatus === 1` 鑷杩囨护灞曠ず銆�**鍒楄〃鎺ュ彛鐩墠涓嶆敮鎸佹寜 `approvalStatus` 浼犲弬杩囨护**锛堜紶浜嗕細琚拷鐣ワ級鈥斺�旈渶瑕佸悗绔敮鎸佺殑璇濆崟璇淬��
+
+4. **`type` 鍙兘涓� NULL**銆傛补鍝佸嚭搴撶瓑璁板綍 `type` 鏄┖涓�/NULL锛屽墠绔笉瑕佸啓 `type === '0'` 纭垽鍚堟牸锛屽惁鍒欒繖绫昏褰曚細琚紡鎺夈�傚彧鏈夊綋 `type` 鏈夊�兼椂鎵嶅尯鍒嗭細`'0'` 鍚堟牸銆乣'1'` 涓嶅悎鏍笺��
+
+5. **瀹℃牳鐘舵�佸彇鍊�**锛坄ReviewStatusEnum`锛夛細`0` 寰呭鏍搞�乣1` 宸插鏍搞�乣2` 瀹℃牳鏈�氳繃銆傛敞鎰忚繖璺熻储鍔℃ā鍧楃殑 `ApprovalStatusEnum`锛�0 鑽夌 / 1 寰呭鎵� / 2 瀹℃壒涓� / 3 宸查�氳繃 / 4 宸查┏鍥烇級**涓嶆槸鍚屼竴濂�**锛屽埆娣风敤銆�
+
+6. **杩欎袱涓垪琛ㄦ煡璇笉鍙楁暟鎹潈闄愯繃婊�**銆傚畠浠殑 SQL 浠� `WITH RECURSIVE` 寮�澶达紝鑰屾暟鎹潈闄愭嫤鎴櫒鍙鐞嗕互 `select` 寮�澶寸殑 SQL锛屾墍浠ヤ笉浼氳拷鍔� `create_user` / `dept_id` 鏉′欢鈥斺�斾笌搴撳瓨鍒楄〃鎺ュ彛琛屼负涓�鑷达紝鎹㈣处鍙蜂笉浼氱湅涓嶅埌璁板綍銆�
+
+7. **鍌ㄧ綈鍙蜂互鍏ュ簱璁板綍涓哄噯**銆傚簱瀛樿仛鍚堣涓婄殑鍌ㄧ綈鍙锋槸"璇ヨ鏍兼渶杩戜竴娆″叆搴�"鐨勫�硷紝鍚屼竴瑙勬牸澶氱綈鏃跺彧鏄剧ず涓�涓紱鍏ュ簱璁板綍鎺ュ彛涓婄殑鏄�**鎵规绾�**鐨勫噯纭�笺��
+
+8. **鍏ュ簱/鍑哄簱涓や釜 tab 璧版甯稿垎椤碉紝鍒敤澶� `size` 鍏滄暟鎹�**銆傝 搂2.1锛沗data.total` 灏辨槸鎬绘潯鏁帮紝缈婚〉鍗冲彲銆傚簱瀛� tab 鍥犱负鏄竴琛屼竴涓鏍肩殑鑱氬悎缁撴灉锛屼繚鐣� `size=100` 娌¢棶棰樸��
+
+---
+
+## 8. 鑱旇皟鑷煡娓呭崟
+
+- [ ] 搴撳瓨璇︽儏鍒囧埌銆屽叆搴撹褰曘�峵ab 鏃舵墠璇锋眰 `/stockInRecord/listPage`锛岃兘鍒楀嚭璇ヨ鏍煎叆搴撹褰曪紙涓嶅啀鍙湁涓�鏉★級
+- [ ] 搴撳瓨璇︽儏鍒囧埌銆屽嚭搴撹褰曘�峵ab 鏃舵墠璇锋眰 `/stockOutRecord/listPage`锛岃兘鍒楀嚭璇ヨ鏍煎嚭搴撹褰�
+- [ ] 涓変釜 tab 鍚勮嚜鐙珛鍒嗛〉锛氬悇缈诲悇鐨勯〉锛屼簰涓嶅奖鍝嶏紱`data.total` 鏄剧ず鐨勬槸璇� tab 鐨勭湡瀹炴�绘潯鏁�
+- [ ] 鍒� tab 鏃跺甫 `productModelId`锛�+ `topParentProductId`锛夛紝涓嶈婕忎紶瀵艰嚧鏌ユ垚鍏ㄤ骇鍝佹爲鐨勬暟鎹�
+- [ ] 涓夊潡鍐呭浜掍笉涓诧細搴撳瓨鏁伴噺涓庡叆搴撹褰曟潯鏁�/鏁伴噺鑳藉涓婏紙276/407锛氫袱鎵� 32.54 + 32.80 = 65.34锛�
+- [ ] 鍏ュ簱璁板綍姣忚鎵瑰彿鏄崟涓壒鍙凤紝涓嶆槸閫楀彿鎷兼帴涓�
+- [ ] 浼� `productModelId` 鍚庣粨鏋滃彧鍚瑙勬牸锛涗笉浼犳椂涓庢敼鍔ㄥ墠涓�鑷达紙鍥炲綊鍏ュ簱绠$悊銆佸嚭搴撶鐞嗕袱涓垪琛ㄩ〉锛�
+- [ ] 鍏ュ簱绠$悊 / 鍑哄簱绠$悊鑿滃崟鍒楄〃椤电炕椤点�佹寜浜у搧鍚�/瑙勬牸/鎵瑰彿鎼滅储鍧囨甯革紙鏈鏀瑰姩鏈奖鍝嶏級
+- [ ] 寰呭鏍哥殑鍏ュ簱/鍑哄簱璁板綍鍦ㄨ鎯呴噷鐨勫睍绀哄彛寰勫凡涓庨渶姹傛柟纭锛堝叏灞曠ず or 鍙湅宸插鏍革級
diff --git "a/doc/20260922_\346\262\271\345\223\201\345\207\272\345\205\245\345\272\223\345\233\276\347\211\207URL\345\244\261\346\225\210\344\277\256\345\244\215\350\257\264\346\230\216.md" "b/doc/20260922_\346\262\271\345\223\201\345\207\272\345\205\245\345\272\223\345\233\276\347\211\207URL\345\244\261\346\225\210\344\277\256\345\244\215\350\257\264\346\230\216.md"
new file mode 100644
index 0000000..8698b69
--- /dev/null
+++ "b/doc/20260922_\346\262\271\345\223\201\345\207\272\345\205\245\345\272\223\345\233\276\347\211\207URL\345\244\261\346\225\210\344\277\256\345\244\215\350\257\264\346\230\216.md"
@@ -0,0 +1,151 @@
+# 娌瑰搧鍑哄叆搴撳浘鐗� URL 澶辨晥淇璇存槑
+
+鏇存柊鏃堕棿锛�2026-09-22
+閫傜敤妯″潡锛氭补鍝佸叆搴擄紙`/inventoryManagement/stockManagement` 鍏ュ簱寮圭獥锛夈�佹补鍝佸嚭搴擄紙鍑哄簱寮圭獥锛夈�佸簱瀛樿鎯呫�佸叆搴撶鐞嗐�佸嚭搴撶鐞�
+
+## 1. 鐜拌薄
+
+娌瑰搧鍑哄叆搴撳崟鎹笂鐨勭収鐗囷紙鍗告补/瑁呮补/纾呭崟锛夊湪鏂伴〉闈㈡墦寮�鏃跺叏閮ㄥ姞杞藉け璐ワ紝鎻愮ず閾炬帴澶辨晥銆�
+
+## 2. 鏍瑰洜
+
+鍑哄叆搴撶殑 4 涓浘鐗囧瓧娈碉紙`stock_out_record.loading_photos` / `pound_photos`銆乣stock_in_record.unload_photos` / `pound_photos`锛�**瀛樼殑涓嶆槸 blob id锛岃�屾槸涓婁紶鎺ュ彛杩斿洖鐨� `StorageBlobVO` JSON 蹇収**锛�
+
+```json
+[{ "id":340, "resourceKey":"42e5de...", "uidFilename":"81af99d2-..._绮.jpg",
+ "path":"2026/0922",
+ "previewURL":"http://36.213.90.123:9018/prod-api/common/preview/<uid>?token=<JWT>",
+ "url":"鈥�?token=<JWT>",
+ "downloadURL":"鈥�/download/<uid>?token=<JWT>" }]
+```
+
+`/common/upload`锛坄CommonController.java:39`锛宍isPublic=false`锛夌鍙戠殑 `?token=<JWT>` 鏈�**涓ら噸鏃舵晥**锛�
+
+| 鏃舵晥 | 鏉ユ簮 |
+| --- | --- |
+| 2 灏忔椂 | JWT `exp`锛宍FileUtil.buildSignedUrl:758` 榛樿 120 鍒嗛挓 |
+| 浣跨敤娆℃暟 | Redis 璁℃暟锛宍FileUtil.validateTokenUsage:796`锛宍useLimit` 榛樿 10 娆� |
+
+浜庢槸蹇収涓�钀藉簱灏辨垚浜嗐�屾閾炬帴銆嶏細2 灏忔椂鍚庤繃鏈燂紝鎴栭瑙� 10 娆″悗澶辨晥锛屾垨 Redis 閭f key 琚竻鐞嗗悗绔嬪埢鎶ャ�岄摼鎺ュ凡杩囨湡鎴栬揪鍒颁娇鐢ㄦ鏁板け鏁堛�嶃��
+
+鍓嶇渚х殑鐩存帴鍘熷洜锛歚AttachmentUpload/image/index.vue` 宸叉彁渚� `permanent` 寮�鍏筹紙璧� `/common/public/upload`锛屾嬁 `?publicKey=` 姘镐箙鍦板潃锛夛紝浣嗗嚭鍏ュ簱鐨� 4 涓� `ImageUpload` **閮芥病浼� `permanent`**锛岄粯璁よ蛋浜嗕細杩囨湡鐨� `/common/upload`锛�2026-09-22 宸蹭慨锛岃 搂6.1锛夛細
+
+| 鏂囦欢 | 涓婁紶鐐� |
+| --- | --- |
+| `OilStockInDialog.vue` | 鍗告补鎷嶇収锛坄unloadPhotos`锛夈�佺鍗曪紙`poundPhotos`锛� |
+| `OilStockOutDialog.vue` | 瑁呮补鎷嶇収锛坄loadingPhotos`锛夈�佺鍗曪紙`poundPhotos`锛� |
+
+## 3. 褰卞搷鑼冨洿锛堢嚎涓婂簱 `product-inventory-management-rbhb`锛�2026-09-22 鏍稿锛�
+
+鍙湁 8 涓瓧娈靛�笺�佸叡 11 寮犲浘锛�
+
+| 琛� | 鍒� | 璁板綍 id | 鍥剧墖鏁� |
+| --- | --- | --- | --- |
+| `stock_out_record` | `loading_photos` | 257 | 2 |
+| `stock_out_record` | `pound_photos` | 257 | 1 |
+| `stock_in_record` | `unload_photos` | 235 / 236 / 238 | 2 / 2 / 1 |
+| `stock_in_record` | `pound_photos` | 235 / 236 / 238 | 1 / 1 / 1 |
+
+## 4. 宸插仛鐨勬暟鎹慨澶嶏紙绾夸笂搴撳凡鎵ц锛�
+
+鎶婃瘡涓� URL 鐨� `?token=<JWT>` 灏卞湴鏀规垚 `?publicKey=<鍚屼竴涓� JSON 瀵硅薄鑷繁鐨� resourceKey>`銆俙StorageBlobServiceImpl.getPublicFile:114` 鍙牎楠� `uid_filename + resource_key` 涓ゅ垪锛屽懡涓嵆姘镐箙鍙闂細
+
+```
+鈥�/common/preview/81af99d2-鈥绮.jpg?publicKey=42e5de4cf76a49d5ba05a7021ed38eb9
+```
+
+鏀瑰啓鏂瑰紡锛氬姣忎釜鍒楀 3 杞� `REGEXP_REPLACE`锛堟瘡涓璞℃湁 `previewURL` / `url` / `downloadURL` 涓変釜 token 鍦板潃锛�3 杞濂介�愪釜鏇挎崲锛夛紝鍙鐞� `like '%?token=%'` 鐨勮锛屽彲閲嶅鎵ц锛�
+
+```sql
+update stock_in_record
+set unload_photos = regexp_replace(
+ regexp_replace(
+ regexp_replace(unload_photos,
+ '("resourceKey":"([0-9a-f]{32})")(.*?)[?]token=[A-Za-z0-9._-]+', '$1$3?publicKey=$2'),
+ '("resourceKey":"([0-9a-f]{32})")(.*?)[?]token=[A-Za-z0-9._-]+', '$1$3?publicKey=$2'),
+ '("resourceKey":"([0-9a-f]{32})")(.*?)[?]token=[A-Za-z0-9._-]+', '$1$3?publicKey=$2')
+where id > 0
+ and unload_photos is not null and unload_photos <> ''
+ and unload_photos like '%?token=%';
+-- 鍚屾硶澶勭悊 stock_in_record.pound_photos銆乻tock_out_record.loading_photos銆乻tock_out_record.pound_photos
+```
+
+**浠d环**锛氳繖浜� URL 浠庢闀挎湡鏈夋晥锛堢瓑鍚� `/common/public/upload` 鐨勫叕寮�璇箟锛夛紝鐭ラ亾閾炬帴鍗冲彲璁块棶鈥斺�斾笌椤圭洰閲屻�屼富鏁版嵁鍥剧墖銆嶇殑鏃㈡湁鍙e緞涓�鑷淬��
+
+### 4.1 澶囦唤涓庡洖婊�
+
+鏀瑰啓涓嶅彲閫嗭紙鍘� JWT 鏃犳硶閲嶅缓锛夛紝鎵ц鍓嶅凡鎶� 8 涓師鍊兼暣涓茬暀鍦ㄥ悓搴撳浠借〃 `bak_20260922_photo_token`锛�
+
+| 鍒� | 鍚箟 |
+| --- | --- |
+| `src_table` / `src_id` / `src_column` | 鏉ユ簮瀹氫綅 |
+| `orig_value` | 鏀瑰啓鍓嶇殑鍘熷鏁翠覆 |
+| `backup_time` | 澶囦唤鏃堕棿 |
+
+鍥炴粴绀轰緥锛�
+
+```sql
+update stock_in_record s
+ join bak_20260922_photo_token b
+ on b.src_table = 'stock_in_record' and b.src_id = s.id and b.src_column = 'unload_photos'
+set s.unload_photos = b.orig_value;
+```
+
+纭鏃犻渶鍥炴粴鍚庯紝鐢变笟鍔℃柟鑷 `drop table bak_20260922_photo_token;`銆�
+
+### 4.2 楠岃瘉缁撴灉
+
+| 椤� | 缁撴灉 |
+| --- | --- |
+| `?token=` 娈嬬暀 | 4 涓垪鍏ㄩ儴 0 |
+| `?publicKey=` 鏁伴噺 | 涓庡璞℃暟 脳 3 涓�鑷达紙6/3/15/9锛� |
+| 涓� `storage_blob` 鍖归厤 | 11 寮犲浘鍏ㄩ儴鎸� `uid_filename + resource_key` 鍛戒腑锛屾棤瀛ゅ効寮曠敤 |
+| 瀹炴祴鎷夊彇 | 11/11 杩斿洖 `200 image/jpeg`锛屽瓧鑺傛暟涓� `storage_blob.byte_size` 涓�鑷� |
+
+## 5. 鍓嶇娉ㄦ剰浜嬮」
+
+1. 瀛橀噺鍥剧墖**宸叉仮澶�**锛岄噸鏂版墦寮�璇︽儏/鍒楄〃鍗冲彲锛涜嫢娴忚鍣ㄧ紦瀛樿繃澶辫触缁撴灉锛屽己鍒跺埛鏂颁竴娆°��
+2. 杩斿洖鍊间粛鏄師鏉ョ殑 JSON 鏁扮粍缁撴瀯锛屽瓧娈靛悕鏈彉锛坄previewURL` / `url` / `downloadURL` / `uidFilename` 绛夛級锛�**娑堣垂绔�**锛堝垪琛ㄣ�佽鎯呫�侀瑙堬級涓嶉渶瑕佹敼浠g爜锛涗笂浼犵瑕佹敼锛岃 搂6.1銆�
+
+## 6. 浠g爜灞備慨澶嶏紙2026-09-22 宸叉敼锛�
+
+鏁版嵁淇鍙槸姝㈣鈥斺�斾笉鍫典綇涓婁紶绔紝鏂扮収鐗囩収鏍� 2 灏忔椂鍚庡彉姝婚摼銆備笂浼犵涓庤鍙栫鐨勬敹鍙i兘鍦� 2026-09-22 涓�骞舵敼鎺夈��
+
+### 6.1 鍓嶇锛堝凡鏀癸細4 涓� `ImageUpload` 琛� `permanent`锛�
+
+- `src/views/inventoryManagement/stockManagement/OilStockInDialog.vue`锛氬嵏娌规媿鐓с�佺鍗�
+- `src/views/inventoryManagement/stockManagement/OilStockOutDialog.vue`锛氳娌规媿鐓с�佺鍗�
+
+`AttachmentUpload/image/index.vue` 鐨� `permanent` 鍒嗘敮浼氾細涓婁紶鏀硅蛋 `uploadPublicFile`锛坄/common/public/upload`锛夛紝骞舵妸 `url` 鍙栨垚 `previewURL`銆傚悗绔� `getStorageBlob(..., isPublic=true)` 鐢� `expired=-1` 鐢熸垚 `previewURL` / `downloadURL`锛屼袱涓兘鏄案涔呭湴鍧�锛屼笖鍝嶅簲閲� `url` 鏈潵灏辨槸绌恒�佺敱鍓嶇琛ユ垚 `previewURL`鈥斺�旀墍浠ヨ惤搴撶殑鏁翠釜瀵硅薄涓嶅啀鍚换浣� token銆�
+
+涓ゆ潯鍐欏簱閾捐矾閮芥牳瀵硅繃锛屼笉浼氳鏀瑰啓鍥炲幓锛�
+
+- 鍏ュ簱寮圭獥鎻愪氦鍘熷鏁扮粍锛屽悗绔� `StockInventoryServiceImpl` 鐢� `JSON.toJSONString` 杞瓧绗︿覆鍏ュ簱锛�
+- 鍑哄簱寮圭獥鑷繁 `JSON.stringify`銆�
+
+鍑哄叆搴撳彧鏈夎繖 4 澶勪笂浼犵偣銆傚彟澶栦袱澶� `ImageUpload` 钀藉簱鏂瑰紡涓嶅悓銆佷笉鍙楀奖鍝嶏細`salesLedger/index.vue:1215`銆乣deliveryLedger/index.vue:250` 璧� `storageBlobDTOs` 鈫� `saveStorageAttachment` 瀛樼殑鏄� blob **id**锛孶RL 鐢辫鍙栫 `getStorageBlobVOs*` 閲嶆柊绛惧彂锛沗vehicle`銆乣ArrivalDialog` 宸茬粡鏄� `permanent`銆�
+
+### 6.2 鍚庣锛堝凡鏀� 1 澶勶紝`refreshPhotoUrls` 鍔犳案涔呭垽鏂級
+
+`StockInventoryServiceImpl.getBatchNoQty:511-521` 浼氬鐓х墖鍋氳鏃堕噸绛撅紙`refreshPhotoUrls:534`锛夈�傚畠璋� `buildSignedUrl(vo, "/preview/", null)`锛宍expired=null` 璧伴粯璁� 120 鍒嗛挓鍒嗘敮鈥斺��**浼氭妸姘镐箙 publicKey 鍦板潃閲嶆柊闄嶇骇鎴� 2 灏忔椂 token**銆傛棦鐒剁幇鍦ㄥ簱閲岀殑鍜屾柊浼犵殑閮芥槸姘镐箙鍦板潃锛岃繖涓柟娉曞繀椤诲厛鍒ゆ柇鍐嶇锛�
+
+```java
+for (StorageBlobVO vo : list) {
+ // 宸茬粡鏄� publicKey 姘镐箙鍦板潃鐨勪繚鎸佷笉鍔細閲嶇浼氭妸瀹冮檷绾у洖 2 灏忔椂澶辨晥鐨� token
+ if (StringUtils.hasText(vo.getPreviewURL()) && vo.getPreviewURL().contains("publicKey=")) {
+ continue;
+ }
+ String previewUrl = fileUtil.buildSignedUrl(vo, "/preview/", null);
+ vo.setPreviewURL(previewUrl);
+ vo.setUrl(previewUrl);
+ vo.setDownloadURL(fileUtil.buildSignedUrl(vo, "/download/", null));
+}
+```
+
+鎸夋瘡涓� VO 鍗曠嫭鍒ゆ柇锛堜笉鏄暣涓插垽鏂級锛岃繖鏍枫�岃�� token 蹇収 + 鏂版案涔呭湴鍧�銆嶆贩瀛樼殑璁板綍閲岋紝鑰佺殑閭e嚑寮犱粛浼氳閲嶇鎴愭湁鏁堝湴鍧�銆�
+
+**涓嶅啀闇�瑕佺粰 `/stockInRecord/listPage`銆乣/stockOutRecord/listPage` 鍔犻噸绛�**锛氳繖涓ゆ潯閾捐矾鍘熸牱杩斿洖搴撻噷鐨勫�硷紝鑰屽簱閲岀幇鍦紙瀛橀噺宸插埛 + 鏂板璧版案涔咃級灏辨槸姘镐箙鍦板潃锛岀洿鎺ュ彲鐢ㄣ��
+
+### 6.3 鍚庣画鍙��
+
+褰诲簳娑堥櫎銆孶RL 蹇収钀藉簱銆嶈繖涓牴鍥狅紝鍙敼鎴愬簱閲屽彧瀛� blob id銆佽鍙栨椂缁熶竴鐢� `getStorageBlobVOs*` 閲嶇锛堜笌 `storage_attachment` 閭e涓�鑷达級銆傛敼鍔ㄩ潰杈冨ぇ锛岄潪蹇呴渶锛屽彟鎺掋��
diff --git a/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java b/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
index 94f949e..2b712a5 100644
--- a/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
@@ -545,6 +545,10 @@
return photos;
}
for (StorageBlobVO vo : list) {
+ // 宸茬粡鏄� publicKey 姘镐箙鍦板潃鐨勪繚鎸佷笉鍔細閲嶇浼氭妸瀹冮檷绾у洖 2 灏忔椂澶辨晥鐨� token
+ if (StringUtils.hasText(vo.getPreviewURL()) && vo.getPreviewURL().contains("publicKey=")) {
+ continue;
+ }
String previewUrl = fileUtil.buildSignedUrl(vo, "/preview/", null);
vo.setPreviewURL(previewUrl);
vo.setUrl(previewUrl);
diff --git a/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml b/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
index 5f319a3..b23dfec 100644
--- a/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
+++ b/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
@@ -294,19 +294,21 @@
LIMIT 5
</select>
+ <!-- 閲囪喘鍝佸垎甯冿細涓庛�屽悇浜у搧閿�鍞噾棰濆垎鏋愩�嶅悓鍙e緞锛岀洿鎺ユ寜閲囪喘鏄庣粏涓婄殑鍝佺被鑱氬悎銆�
+ 涓嶈兘鍐嶆寜浜у搧鏍戙�屽師鏉愭枡銆嶅瓙鏍戣繃婊� 鈥斺�� 閲囪喘鍙拌处瀹為檯鐧昏鐨勫搧绫伙紙鏌存补銆佺伃鐏櫒锛夊垎鍒寕鍦�
+ 銆屾垚鍝�/鎴愬搧娌广�嶃�岃澶囪鏂�/鍏叡瀹夊叏璁惧銆嶄笅锛屾寜瀛愭爲杩囨护浼氭亽涓虹┖ -->
<select id="selectRawMaterialPurchaseAnalysis" resultType="java.util.Map">
SELECT
- pr.product_name AS name,
+ slp.product_category AS name,
SUM( slp.tax_inclusive_total_price ) AS value
FROM
sales_ledger_product slp
- JOIN product pr ON slp.product_id = pr.id
WHERE
slp.type = 2
- AND pr.parent_id = ( SELECT id FROM product WHERE product_name = '鍘熸潗鏂�' )
+ AND slp.product_category IS NOT NULL
+ AND slp.product_category != ''
GROUP BY
- pr.id,
- pr.product_name
+ slp.product_category
ORDER BY
value DESC
LIMIT 5
diff --git a/src/main/resources/mapper/stock/StockInRecordMapper.xml b/src/main/resources/mapper/stock/StockInRecordMapper.xml
index dfd2369..14357ef 100644
--- a/src/main/resources/mapper/stock/StockInRecordMapper.xml
+++ b/src/main/resources/mapper/stock/StockInRecordMapper.xml
@@ -125,6 +125,9 @@
<if test="params.batchNo != null and params.batchNo != ''">
and sir.batch_no like concat('%',#{params.batchNo},'%')
</if>
+ <if test="params.productModelId != null and params.productModelId > 0">
+ and sir.product_model_id = #{params.productModelId}
+ </if>
<if test="params.type != null and params.type != ''">
and sir.type = #{params.type}
</if>
diff --git a/src/main/resources/mapper/stock/StockInventoryMapper.xml b/src/main/resources/mapper/stock/StockInventoryMapper.xml
index 487000b..82709f5 100644
--- a/src/main/resources/mapper/stock/StockInventoryMapper.xml
+++ b/src/main/resources/mapper/stock/StockInventoryMapper.xml
@@ -604,13 +604,25 @@
AND create_time <= #{endDate}) AS combined_counts
</select>
+ <!-- 鍑哄叆搴撹秼鍔匡細浜у搧鍒嗙被蹇呴』閫掑綊鍙栨暣妫靛瓙鏍戙��
+ 浜у搧鏍戞槸銆屽ぇ绫� -> 鍝佺被 -> 鍏蜂綋浜у搧銆嶄笁灞傦紝浜у搧鍨嬪彿锛坧roduct_model锛夋寕鍦ㄥ彾瀛愪骇鍝佷笂锛�
+ 鍙瘮瀵圭洿鎺ュ瓙鑺傜偣锛坧.parent_id = root锛夋案杩滃懡涓笉鍒板瀷鍙凤紝瓒嬪娍鍥炬亽涓虹┖銆�
+ 閫掑綊 CTE 鍐欏湪鎷彿鍐咃紝璁╄鍙ヤ粛浠� SELECT 寮�澶达紝鏁版嵁鏉冮檺鎷︽埅鍣ㄧ収甯稿 stock_in_record 鐢熸晥 -->
<select id="selectDailyStockInCounts" resultType="java.util.Map">
SELECT DATE(sir.create_time) AS date,
SUM(sir.stock_in_num) AS count
FROM stock_in_record sir
JOIN product_model pm ON sir.product_model_id = pm.id
JOIN product p ON pm.product_id = p.id
- WHERE (p.parent_id = #{rootCategoryId} OR p.id = #{rootCategoryId})
+ WHERE p.id IN (WITH RECURSIVE product_tree AS (SELECT id
+ FROM product
+ WHERE id = #{rootCategoryId}
+ UNION ALL
+ SELECT p2.id
+ FROM product p2
+ JOIN product_tree pt ON p2.parent_id = pt.id)
+ SELECT id
+ FROM product_tree)
AND sir.create_time >= #{startDate}
AND sir.create_time <= #{endDate}
GROUP BY DATE(sir.create_time)
@@ -623,7 +635,15 @@
FROM stock_out_record sor
JOIN product_model pm ON sor.product_model_id = pm.id
JOIN product p ON pm.product_id = p.id
- WHERE (p.parent_id = #{rootCategoryId} OR p.id = #{rootCategoryId})
+ WHERE p.id IN (WITH RECURSIVE product_tree AS (SELECT id
+ FROM product
+ WHERE id = #{rootCategoryId}
+ UNION ALL
+ SELECT p2.id
+ FROM product p2
+ JOIN product_tree pt ON p2.parent_id = pt.id)
+ SELECT id
+ FROM product_tree)
AND sor.create_time >= #{startDate}
AND sor.create_time <= #{endDate}
GROUP BY DATE(sor.create_time)
diff --git a/src/main/resources/mapper/stock/StockOutRecordMapper.xml b/src/main/resources/mapper/stock/StockOutRecordMapper.xml
index dcd35e7..adcb16f 100644
--- a/src/main/resources/mapper/stock/StockOutRecordMapper.xml
+++ b/src/main/resources/mapper/stock/StockOutRecordMapper.xml
@@ -61,6 +61,9 @@
<if test="params.batchNo != null and params.batchNo != ''">
and sor.batch_no like concat('%',#{params.batchNo},'%')
</if>
+ <if test="params.productModelId != null and params.productModelId > 0">
+ and sor.product_model_id = #{params.productModelId}
+ </if>
<if test="params.type != null and params.type != ''">
and sor.type = #{params.type}
</if>
--
Gitblit v1.9.3