From d8c86797adaef6c416efae16586f350ae77bde4b Mon Sep 17 00:00:00 2001
From: 吴羡 <16976746+Xian-TT3@user.noreply.gitee.com>
Date: 星期六, 12 九月 2026 12:43:08 +0800
Subject: [PATCH] feat: 库存入库/出库字段全链路、采购台账申请提交时间、储罐租客信息、油库储罐模块

---
 src/main/java/com/ruoyi/stock/service/StockInventoryService.java             |    3 
 src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java |   11 
 src/main/java/com/ruoyi/basic/controller/TankInfoController.java             |   85 ++
 src/main/java/com/ruoyi/stock/pojo/StockOutRecord.java                       |   85 ++
 src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml                  |   10 
 src/main/java/com/ruoyi/basic/service/impl/OilDepotServiceImpl.java          |   59 +
 doc/20260909_add_pickup_method_to_purchase_ledger.sql                        |    4 
 doc/20260911_add_tenant_info_to_tank_info.sql                                |    4 
 src/main/java/com/ruoyi/basic/service/ITankInfoService.java                  |   65 ++
 src/main/java/com/ruoyi/basic/service/IOilDepotService.java                  |   65 ++
 src/main/java/com/ruoyi/basic/pojo/OilDepot.java                             |   92 ++
 doc/20260911_add_unload_and_weighing_fields_to_stock_in_record.sql           |   13 
 bin/run-file-service.bat                                                     |   19 
 src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java    |  107 +++
 doc/20260911_add_oil_out_fields_to_stock_out_record.sql                      |   31 +
 src/main/java/com/ruoyi/basic/service/impl/TankInfoServiceImpl.java          |   59 +
 src/main/java/com/ruoyi/purchase/pojo/PurchaseLedger.java                    |   72 ++
 src/main/java/com/ruoyi/stock/dto/StockInventoryDto.java                     |   67 ++
 src/main/java/com/ruoyi/stock/pojo/StockInRecord.java                        |   86 ++
 src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java                  |   31 +
 src/main/resources/mapper/stock/StockInventoryMapper.xml                     |  458 ++++++++++++++
 src/main/java/com/ruoyi/stock/dto/StockUninventoryDto.java                   |   41 +
 src/main/java/com/ruoyi/stock/controller/StockInventoryController.java       |    9 
 doc/20260911_add_application_submit_time_to_purchase_ledger.sql              |    4 
 doc/20260909_add_purchase_oil_product_to_purchase_ledger.sql                 |    4 
 src/main/java/com/ruoyi/basic/mapper/OilDepotMapper.java                     |   15 
 src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java  |  106 +++
 src/main/java/com/ruoyi/basic/mapper/TankInfoMapper.java                     |   15 
 src/main/java/com/ruoyi/basic/controller/OilDepotController.java             |   85 ++
 doc/20260909_add_logistics_method_to_purchase_ledger.sql                     |    4 
 src/main/java/com/ruoyi/basic/pojo/TankInfo.java                             |   95 +++
 31 files changed, 1,800 insertions(+), 4 deletions(-)

diff --git a/bin/run-file-service.bat b/bin/run-file-service.bat
new file mode 100644
index 0000000..e7b00e7
--- /dev/null
+++ b/bin/run-file-service.bat
@@ -0,0 +1,19 @@
+@echo off
+echo.
+echo [INFO] Starting file service with embedded Tomcat on port 7006 (same app, dev profile).
+echo [INFO] Business backend stays on 7005; file preview/download URLs point to this instance.
+echo.
+
+%~d0
+cd %~dp0
+
+cd ..
+title %cd% - file service (7006)
+
+rem Project targets Java 25; use JDK 25 if present, otherwise rely on global JAVA_HOME.
+if exist "D:\develop\JDK.25\bin\java.exe" set JAVA_HOME=D:\develop\JDK.25
+
+set MAVEN_OPTS=%MAVEN_OPTS% -Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
+call mvn spring-boot:run -Dmaven.test.skip=true -Dspring-boot.run.arguments="--server.port=7006"
+
+pause
diff --git a/doc/20260909_add_logistics_method_to_purchase_ledger.sql b/doc/20260909_add_logistics_method_to_purchase_ledger.sql
new file mode 100644
index 0000000..a883d0c
--- /dev/null
+++ b/doc/20260909_add_logistics_method_to_purchase_ledger.sql
@@ -0,0 +1,4 @@
+-- 閲囪喘鍙拌处鏂板鈥滅墿娴佹柟寮忊�濆瓧娈碉紙鍘傚閰嶉�併�佸澶栫墿娴併�佸鎴疯嚜鎻愶級
+-- 鎵ц搴擄細product-inventory-management锛堝悇绉熸埛搴撳悓锛�
+ALTER TABLE `purchase_ledger`
+    ADD COLUMN `logistics_method` varchar(20) DEFAULT NULL COMMENT '鐗╂祦鏂瑰紡锛氬巶瀹堕厤閫併�佸澶栫墿娴併�佸鎴疯嚜鎻�' AFTER `purchase_oil_product`;
diff --git a/doc/20260909_add_pickup_method_to_purchase_ledger.sql b/doc/20260909_add_pickup_method_to_purchase_ledger.sql
new file mode 100644
index 0000000..ea9f7f8
--- /dev/null
+++ b/doc/20260909_add_pickup_method_to_purchase_ledger.sql
@@ -0,0 +1,4 @@
+-- 閲囪喘鍙拌处鏂板鈥滄彁璐ф柟寮忊�濆瓧娈碉紙鏆備笉鎻愯揣銆佹彁璐э級
+-- 鎵ц搴擄細product-inventory-management锛堝悇绉熸埛搴撳悓锛�
+ALTER TABLE `purchase_ledger`
+    ADD COLUMN `pickup_method` varchar(20) DEFAULT NULL COMMENT '鎻愯揣鏂瑰紡锛氭殏涓嶆彁璐с�佹彁璐�' AFTER `logistics_method`;
diff --git a/doc/20260909_add_purchase_oil_product_to_purchase_ledger.sql b/doc/20260909_add_purchase_oil_product_to_purchase_ledger.sql
new file mode 100644
index 0000000..586bfcd
--- /dev/null
+++ b/doc/20260909_add_purchase_oil_product_to_purchase_ledger.sql
@@ -0,0 +1,4 @@
+-- 閲囪喘鍙拌处鏂板鈥滈噰璐补鍝佲�濆瓧娈碉紙姹�#92銆佹苯#95銆佹煷#0銆佹煷#-35锛�
+-- 鎵ц搴擄細product-inventory-management锛堝悇绉熸埛搴撳悓锛�
+ALTER TABLE `purchase_ledger`
+    ADD COLUMN `purchase_oil_product` varchar(20) DEFAULT NULL COMMENT '閲囪喘娌瑰搧锛氭苯#92銆佹苯#95銆佹煷#0銆佹煷#-35' AFTER `purchase_category`;
diff --git a/doc/20260911_add_application_submit_time_to_purchase_ledger.sql b/doc/20260911_add_application_submit_time_to_purchase_ledger.sql
new file mode 100644
index 0000000..72bc81e
--- /dev/null
+++ b/doc/20260911_add_application_submit_time_to_purchase_ledger.sql
@@ -0,0 +1,4 @@
+-- 閲囪喘鍙拌处鏂板鈥滅敵璇锋彁浜ゆ椂闂粹�濆瓧娈�
+-- 鎵ц搴擄細product-inventory-management锛堝悇绉熸埛搴撳悓锛�
+ALTER TABLE `purchase_ledger`
+    ADD COLUMN `application_submit_time` datetime DEFAULT NULL COMMENT '鐢宠鎻愪氦鏃堕棿' AFTER `purchase_order_status`;
diff --git a/doc/20260911_add_oil_out_fields_to_stock_out_record.sql b/doc/20260911_add_oil_out_fields_to_stock_out_record.sql
new file mode 100644
index 0000000..e31d2f4
--- /dev/null
+++ b/doc/20260911_add_oil_out_fields_to_stock_out_record.sql
@@ -0,0 +1,31 @@
+-- 鍑哄簱璁板綍鏂板鈥滄补鍝佸嚭搴撯�濊〃鍗曞瓧娈碉紙鍑哄簱淇℃伅/瑁呮补鎿嶄綔淇℃伅/杩囩鏁版嵁/鐗╂祦淇℃伅锛�
+-- 鎵ц搴擄細product-inventory-management锛堝悇绉熸埛搴撳悓锛�
+ALTER TABLE `stock_out_record`
+    ADD COLUMN `out_category` varchar(20) DEFAULT NULL COMMENT '鍑哄簱绫诲埆锛氬瀛�/浠e偍/閿�鍞�' AFTER `record_type`,
+    ADD COLUMN `oil_depot_id` bigint DEFAULT NULL COMMENT '鍌ㄥ簱id' AFTER `out_category`,
+    ADD COLUMN `oil_depot_name` varchar(100) DEFAULT NULL COMMENT '鍌ㄥ簱鍚嶇О' AFTER `oil_depot_id`,
+    ADD COLUMN `tank_id` bigint DEFAULT NULL COMMENT '鍌ㄧ綈id' AFTER `oil_depot_name`,
+    ADD COLUMN `tank_no` varchar(50) DEFAULT NULL COMMENT '鍌ㄧ綈鍙�' AFTER `tank_id`,
+    ADD COLUMN `out_date` date DEFAULT NULL COMMENT '鍑哄簱鏃ユ湡' AFTER `tank_no`,
+    ADD COLUMN `oil_product` varchar(20) DEFAULT NULL COMMENT '娌瑰搧' AFTER `out_date`,
+    ADD COLUMN `out_tonnage` decimal(14,2) DEFAULT NULL COMMENT '鍑哄簱鍚ㄤ綅(鍚�)' AFTER `oil_product`,
+    ADD COLUMN `customer_id` bigint DEFAULT NULL COMMENT '瀹㈡埛id' AFTER `out_tonnage`,
+    ADD COLUMN `customer_name` varchar(100) DEFAULT NULL COMMENT '瀹㈡埛鍚嶇О' AFTER `customer_id`,
+    ADD COLUMN `contact_person` varchar(50) DEFAULT NULL COMMENT '瀹㈡埛瀵规帴浜�' AFTER `customer_name`,
+    ADD COLUMN `contact_phone` varchar(20) DEFAULT NULL COMMENT '瀵规帴浜虹數璇�' AFTER `contact_person`,
+    ADD COLUMN `loading_inspection_status` varchar(20) DEFAULT NULL COMMENT '杞︿綋/閾呭皝妫�楠屾槸鍚︽甯�' AFTER `contact_phone`,
+    ADD COLUMN `loading_crane_position` varchar(20) DEFAULT NULL COMMENT '瑁呰溅楣や綅' AFTER `loading_inspection_status`,
+    ADD COLUMN `loading_photos` text COMMENT '瑁呮补鍏抽敭鐜妭涓庤溅杈嗗叧閿綅缃媿鐓э紙JSON鏁扮粍锛�' AFTER `loading_crane_position`,
+    ADD COLUMN `density` varchar(20) DEFAULT NULL COMMENT '瀵嗗害锛坘g/L锛�' AFTER `loading_photos`,
+    ADD COLUMN `gross_weight` decimal(14,2) DEFAULT NULL COMMENT '姣涢噸(鍚�)' AFTER `density`,
+    ADD COLUMN `tare_weight` decimal(14,2) DEFAULT NULL COMMENT '鐨噸(鍚�)' AFTER `gross_weight`,
+    ADD COLUMN `net_weight` decimal(14,2) DEFAULT NULL COMMENT '鍑�閲�(鍚�)' AFTER `tare_weight`,
+    ADD COLUMN `loss_quantity` decimal(14,2) DEFAULT NULL COMMENT '浜忛噺(鍚�)' AFTER `net_weight`,
+    ADD COLUMN `actual_volume` decimal(14,2) DEFAULT NULL COMMENT '瀹為檯鍏ュ簱浣撶Н(鍗�)' AFTER `loss_quantity`,
+    ADD COLUMN `pound_photos` text COMMENT '纾呭崟涓婁紶锛圝SON鏁扮粍锛�' AFTER `actual_volume`,
+    ADD COLUMN `driver_name` varchar(50) DEFAULT NULL COMMENT '鍙告満濮撳悕' AFTER `pound_photos`,
+    ADD COLUMN `driver_phone` varchar(20) DEFAULT NULL COMMENT '鍙告満鐢佃瘽' AFTER `driver_name`,
+    ADD COLUMN `escort_name` varchar(50) DEFAULT NULL COMMENT '鎶艰繍鍛樺鍚�' AFTER `driver_phone`,
+    ADD COLUMN `escort_phone` varchar(20) DEFAULT NULL COMMENT '鎶艰繍鍛樼數璇�' AFTER `escort_name`,
+    ADD COLUMN `truck_plate_no` varchar(20) DEFAULT NULL COMMENT '杞︾墝鍙�' AFTER `escort_phone`,
+    ADD COLUMN `trailer_plate_no` varchar(20) DEFAULT NULL COMMENT '杞︽寕鐗屽彿' AFTER `truck_plate_no`;
diff --git a/doc/20260911_add_tenant_info_to_tank_info.sql b/doc/20260911_add_tenant_info_to_tank_info.sql
new file mode 100644
index 0000000..10e41ad
--- /dev/null
+++ b/doc/20260911_add_tenant_info_to_tank_info.sql
@@ -0,0 +1,4 @@
+-- 鍌ㄧ綈淇℃伅琛ㄦ柊澧炩�滅瀹俊鎭�濆瓧娈�
+-- 鎵ц搴擄細product-inventory-management锛堝悇绉熸埛搴撳悓锛�
+ALTER TABLE `tank_info`
+    ADD COLUMN `tenant_info` varchar(255) DEFAULT NULL COMMENT '绉熷淇℃伅' AFTER `remaining`;
diff --git a/doc/20260911_add_unload_and_weighing_fields_to_stock_in_record.sql b/doc/20260911_add_unload_and_weighing_fields_to_stock_in_record.sql
new file mode 100644
index 0000000..b25c1bc
--- /dev/null
+++ b/doc/20260911_add_unload_and_weighing_fields_to_stock_in_record.sql
@@ -0,0 +1,13 @@
+-- 鍏ュ簱璁板綍鏂板鈥滃嵏娌规搷浣滀俊鎭�濅笌鈥滆繃纾呮暟鎹�濆瓧娈�
+-- 鎵ц搴擄細product-inventory-management锛堝悇绉熸埛搴撳悓锛�
+ALTER TABLE `stock_in_record`
+    ADD COLUMN `tank_inspection_status` varchar(20) DEFAULT NULL COMMENT '杞︿綋/閾呭皝妫�楠屾槸鍚︽甯革細姝e父/寮傚父' AFTER `trailer_plate_no`,
+    ADD COLUMN `unloading_crane_position` varchar(20) DEFAULT NULL COMMENT '鍗歌溅楣や綅锛�1#鎾/2#鎾/涓存椂娉�' AFTER `tank_inspection_status`,
+    ADD COLUMN `density` varchar(20) DEFAULT NULL COMMENT '瀵嗗害锛坘g/L锛�' AFTER `unloading_crane_position`,
+    ADD COLUMN `unload_photos` text COMMENT '鍗告补鍏抽敭鐜妭涓庤溅杈嗗叧閿綅缃媿鐓э紙JSON鏁扮粍锛�' AFTER `density`,
+    ADD COLUMN `gross_weight` decimal(14,2) DEFAULT NULL COMMENT '姣涢噸(鍚�)' AFTER `unload_photos`,
+    ADD COLUMN `tare_weight` decimal(14,2) DEFAULT NULL COMMENT '鐨噸(鍚�)' AFTER `gross_weight`,
+    ADD COLUMN `net_weight` decimal(14,2) DEFAULT NULL COMMENT '鍑�閲�(鍚�)' AFTER `tare_weight`,
+    ADD COLUMN `loss_quantity` decimal(14,2) DEFAULT NULL COMMENT '浜忛噺(鍚�)' AFTER `net_weight`,
+    ADD COLUMN `actual_volume` decimal(14,2) DEFAULT NULL COMMENT '瀹為檯鍏ュ簱浣撶Н(鍗�)' AFTER `loss_quantity`,
+    ADD COLUMN `pound_photos` text COMMENT '纾呭崟涓婁紶锛圝SON鏁扮粍锛�' AFTER `actual_volume`;
diff --git a/src/main/java/com/ruoyi/basic/controller/OilDepotController.java b/src/main/java/com/ruoyi/basic/controller/OilDepotController.java
new file mode 100644
index 0000000..b1cbeae
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/controller/OilDepotController.java
@@ -0,0 +1,85 @@
+package com.ruoyi.basic.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.basic.pojo.OilDepot;
+import com.ruoyi.basic.service.IOilDepotService;
+import com.ruoyi.framework.aspectj.lang.annotation.Log;
+import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
+import com.ruoyi.framework.web.domain.R;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 娌瑰簱淇℃伅Controller
+ *
+ * @author ruoyi
+ * @date 2026-09-10
+ */
+@RestController
+@RequestMapping("/basic/oilDepot")
+@AllArgsConstructor
+public class OilDepotController {
+    private IOilDepotService oilDepotService;
+
+    /**
+     * 鍒嗛〉鏌ヨ娌瑰簱淇℃伅鍒楄〃
+     */
+    @GetMapping("/list")
+    public R list(Page<OilDepot> page, OilDepot oilDepot) {
+        IPage<OilDepot> result = oilDepotService.selectOilDepotList(page, oilDepot);
+        return R.ok(result);
+    }
+
+    /**
+     * 鏌ヨ鍏ㄩ儴娌瑰簱淇℃伅锛堜緵涓嬫媺閫夋嫨锛�
+     */
+    @GetMapping("/all")
+    public R all() {
+        return R.ok(oilDepotService.selectAll());
+    }
+
+    /**
+     * 鑾峰彇娌瑰簱淇℃伅璇︾粏淇℃伅
+     */
+    @GetMapping(value = "/{id}")
+    public R getInfo(@PathVariable("id") Long id) {
+        return R.ok(oilDepotService.selectOilDepotById(id));
+    }
+
+    /**
+     * 鏂板娌瑰簱淇℃伅
+     */
+    @Log(title = "娌瑰簱淇℃伅", businessType = BusinessType.INSERT)
+    @PostMapping("/add")
+    public R add(@RequestBody OilDepot oilDepot) {
+        return R.ok(oilDepotService.insertOilDepot(oilDepot));
+    }
+
+    /**
+     * 淇敼娌瑰簱淇℃伅
+     */
+    @Log(title = "娌瑰簱淇℃伅", businessType = BusinessType.UPDATE)
+    @PostMapping("/update")
+    public R edit(@RequestBody OilDepot oilDepot) {
+        return R.ok(oilDepotService.updateOilDepot(oilDepot));
+    }
+
+    /**
+     * 鍒犻櫎娌瑰簱淇℃伅
+     */
+    @Log(title = "娌瑰簱淇℃伅", businessType = BusinessType.DELETE)
+    @DeleteMapping("/del")
+    public R remove(@RequestBody Long[] ids) {
+        if (ids == null || ids.length == 0) {
+            return R.fail("璇蜂紶鍏ヨ鍒犻櫎鐨処D");
+        }
+        return R.ok(oilDepotService.deleteOilDepotByIds(ids));
+    }
+}
diff --git a/src/main/java/com/ruoyi/basic/controller/TankInfoController.java b/src/main/java/com/ruoyi/basic/controller/TankInfoController.java
new file mode 100644
index 0000000..3bf6ae6
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/controller/TankInfoController.java
@@ -0,0 +1,85 @@
+package com.ruoyi.basic.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.basic.pojo.TankInfo;
+import com.ruoyi.basic.service.ITankInfoService;
+import com.ruoyi.framework.aspectj.lang.annotation.Log;
+import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
+import com.ruoyi.framework.web.domain.R;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 鍌ㄧ綈淇℃伅Controller
+ *
+ * @author ruoyi
+ * @date 2026-09-10
+ */
+@RestController
+@RequestMapping("/basic/tankInfo")
+@AllArgsConstructor
+public class TankInfoController {
+    private ITankInfoService tankInfoService;
+
+    /**
+     * 鍒嗛〉鏌ヨ鍌ㄧ綈淇℃伅鍒楄〃
+     */
+    @GetMapping("/list")
+    public R list(Page<TankInfo> page, TankInfo tankInfo) {
+        IPage<TankInfo> result = tankInfoService.selectTankInfoList(page, tankInfo);
+        return R.ok(result);
+    }
+
+    /**
+     * 鏌ヨ鍏ㄩ儴鍌ㄧ綈淇℃伅锛堜緵涓嬫媺閫夋嫨锛�
+     */
+    @GetMapping("/all")
+    public R all() {
+        return R.ok(tankInfoService.selectAll());
+    }
+
+    /**
+     * 鑾峰彇鍌ㄧ綈淇℃伅璇︾粏淇℃伅
+     */
+    @GetMapping(value = "/{id}")
+    public R getInfo(@PathVariable("id") Long id) {
+        return R.ok(tankInfoService.selectTankInfoById(id));
+    }
+
+    /**
+     * 鏂板鍌ㄧ綈淇℃伅
+     */
+    @Log(title = "鍌ㄧ綈淇℃伅", businessType = BusinessType.INSERT)
+    @PostMapping("/add")
+    public R add(@RequestBody TankInfo tankInfo) {
+        return R.ok(tankInfoService.insertTankInfo(tankInfo));
+    }
+
+    /**
+     * 淇敼鍌ㄧ綈淇℃伅
+     */
+    @Log(title = "鍌ㄧ綈淇℃伅", businessType = BusinessType.UPDATE)
+    @PostMapping("/update")
+    public R edit(@RequestBody TankInfo tankInfo) {
+        return R.ok(tankInfoService.updateTankInfo(tankInfo));
+    }
+
+    /**
+     * 鍒犻櫎鍌ㄧ綈淇℃伅
+     */
+    @Log(title = "鍌ㄧ綈淇℃伅", businessType = BusinessType.DELETE)
+    @DeleteMapping("/del")
+    public R remove(@RequestBody Long[] ids) {
+        if (ids == null || ids.length == 0) {
+            return R.fail("璇蜂紶鍏ヨ鍒犻櫎鐨処D");
+        }
+        return R.ok(tankInfoService.deleteTankInfoByIds(ids));
+    }
+}
diff --git a/src/main/java/com/ruoyi/basic/mapper/OilDepotMapper.java b/src/main/java/com/ruoyi/basic/mapper/OilDepotMapper.java
new file mode 100644
index 0000000..04b3060
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/mapper/OilDepotMapper.java
@@ -0,0 +1,15 @@
+package com.ruoyi.basic.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.basic.pojo.OilDepot;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 娌瑰簱淇℃伅Mapper鎺ュ彛
+ *
+ * @author ruoyi
+ * @date 2026-09-10
+ */
+@Mapper
+public interface OilDepotMapper extends BaseMapper<OilDepot> {
+}
diff --git a/src/main/java/com/ruoyi/basic/mapper/TankInfoMapper.java b/src/main/java/com/ruoyi/basic/mapper/TankInfoMapper.java
new file mode 100644
index 0000000..00d2498
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/mapper/TankInfoMapper.java
@@ -0,0 +1,15 @@
+package com.ruoyi.basic.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.basic.pojo.TankInfo;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 鍌ㄧ綈淇℃伅Mapper鎺ュ彛
+ *
+ * @author ruoyi
+ * @date 2026-09-10
+ */
+@Mapper
+public interface TankInfoMapper extends BaseMapper<TankInfo> {
+}
diff --git a/src/main/java/com/ruoyi/basic/pojo/OilDepot.java b/src/main/java/com/ruoyi/basic/pojo/OilDepot.java
new file mode 100644
index 0000000..2afbe20
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/pojo/OilDepot.java
@@ -0,0 +1,92 @@
+package com.ruoyi.basic.pojo;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+/**
+ * 娌瑰簱淇℃伅瀵硅薄 oil_depot
+ *
+ * @author ruoyi
+ * @date 2026-09-10
+ */
+@TableName(value = "oil_depot")
+@Data
+public class OilDepot implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 娌瑰簱id
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 娌瑰簱鍚嶇О
+     */
+    private String depotName;
+
+    /**
+     * 璐熻矗浜�
+     */
+    private String chargePerson;
+
+    /**
+     * 鑱旂郴鐢佃瘽
+     */
+    private String phone;
+
+    /**
+     * 鍚敤鏃ユ湡
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private LocalDate enableDate;
+
+    /**
+     * 鎵�灞炲叕鍙�
+     */
+    private String company;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    /**
+     * 鍒涘缓浜�
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Long createUser;
+
+    /**
+     * 鏇存柊鏃堕棿
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime updateTime;
+
+    /**
+     * 鏇存柊浜�
+     */
+    private Long updateUser;
+
+    /**
+     * 绉熸埛id
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+
+    /**
+     * 閮ㄩ棬id
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Long deptId;
+}
diff --git a/src/main/java/com/ruoyi/basic/pojo/TankInfo.java b/src/main/java/com/ruoyi/basic/pojo/TankInfo.java
new file mode 100644
index 0000000..86dd410
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/pojo/TankInfo.java
@@ -0,0 +1,95 @@
+package com.ruoyi.basic.pojo;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 鍌ㄧ綈淇℃伅瀵硅薄 tank_info
+ *
+ * @author ruoyi
+ * @date 2026-09-10
+ */
+@TableName(value = "tank_info")
+@Data
+public class TankInfo implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鍌ㄧ綈id
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 鍌ㄧ綈鍙�
+     */
+    private String tankNo;
+
+    /**
+     * 澶х被
+     */
+    private String category;
+
+    /**
+     * 娌瑰搧
+     */
+    private String oilProduct;
+
+    /**
+     * 缃愬
+     */
+    private BigDecimal capacity;
+
+    /**
+     * 搴撳瓨浣欓噺(m3)
+     */
+    private BigDecimal remaining;
+
+    /**
+     * 绉熷淇℃伅
+     */
+    private String tenantInfo;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    /**
+     * 鍒涘缓浜�
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Long createUser;
+
+    /**
+     * 鏇存柊鏃堕棿
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime updateTime;
+
+    /**
+     * 鏇存柊浜�
+     */
+    private Long updateUser;
+
+    /**
+     * 绉熸埛id
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+
+    /**
+     * 閮ㄩ棬id
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Long deptId;
+}
diff --git a/src/main/java/com/ruoyi/basic/service/IOilDepotService.java b/src/main/java/com/ruoyi/basic/service/IOilDepotService.java
new file mode 100644
index 0000000..7830556
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/service/IOilDepotService.java
@@ -0,0 +1,65 @@
+package com.ruoyi.basic.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.basic.pojo.OilDepot;
+
+import java.util.List;
+
+/**
+ * 娌瑰簱淇℃伅Service鎺ュ彛
+ *
+ * @author ruoyi
+ * @date 2026-09-10
+ */
+public interface IOilDepotService extends IService<OilDepot> {
+
+    /**
+     * 鍒嗛〉鏌ヨ娌瑰簱淇℃伅鍒楄〃
+     *
+     * @param page 鍒嗛〉鍙傛暟
+     * @param oilDepot 鏌ヨ鏉′欢
+     * @return 娌瑰簱淇℃伅闆嗗悎
+     */
+    IPage<OilDepot> selectOilDepotList(Page<OilDepot> page, OilDepot oilDepot);
+
+    /**
+     * 鏌ヨ鍏ㄩ儴娌瑰簱淇℃伅锛堜緵涓嬫媺閫夋嫨锛�
+     *
+     * @return 娌瑰簱淇℃伅闆嗗悎
+     */
+    List<OilDepot> selectAll();
+
+    /**
+     * 鏌ヨ娌瑰簱淇℃伅
+     *
+     * @param id 娌瑰簱淇℃伅涓婚敭
+     * @return 娌瑰簱淇℃伅
+     */
+    OilDepot selectOilDepotById(Long id);
+
+    /**
+     * 鏂板娌瑰簱淇℃伅
+     *
+     * @param oilDepot 娌瑰簱淇℃伅
+     * @return 缁撴灉
+     */
+    boolean insertOilDepot(OilDepot oilDepot);
+
+    /**
+     * 淇敼娌瑰簱淇℃伅
+     *
+     * @param oilDepot 娌瑰簱淇℃伅
+     * @return 缁撴灉
+     */
+    boolean updateOilDepot(OilDepot oilDepot);
+
+    /**
+     * 鎵归噺鍒犻櫎娌瑰簱淇℃伅
+     *
+     * @param ids 闇�瑕佸垹闄ょ殑娌瑰簱淇℃伅涓婚敭闆嗗悎
+     * @return 缁撴灉
+     */
+    boolean deleteOilDepotByIds(Long[] ids);
+}
diff --git a/src/main/java/com/ruoyi/basic/service/ITankInfoService.java b/src/main/java/com/ruoyi/basic/service/ITankInfoService.java
new file mode 100644
index 0000000..7835e4a
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/service/ITankInfoService.java
@@ -0,0 +1,65 @@
+package com.ruoyi.basic.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.basic.pojo.TankInfo;
+
+import java.util.List;
+
+/**
+ * 鍌ㄧ綈淇℃伅Service鎺ュ彛
+ *
+ * @author ruoyi
+ * @date 2026-09-10
+ */
+public interface ITankInfoService extends IService<TankInfo> {
+
+    /**
+     * 鍒嗛〉鏌ヨ鍌ㄧ綈淇℃伅鍒楄〃
+     *
+     * @param page 鍒嗛〉鍙傛暟
+     * @param tankInfo 鏌ヨ鏉′欢
+     * @return 鍌ㄧ綈淇℃伅闆嗗悎
+     */
+    IPage<TankInfo> selectTankInfoList(Page<TankInfo> page, TankInfo tankInfo);
+
+    /**
+     * 鏌ヨ鍏ㄩ儴鍌ㄧ綈淇℃伅锛堜緵涓嬫媺閫夋嫨锛�
+     *
+     * @return 鍌ㄧ綈淇℃伅闆嗗悎
+     */
+    List<TankInfo> selectAll();
+
+    /**
+     * 鏌ヨ鍌ㄧ綈淇℃伅
+     *
+     * @param id 鍌ㄧ綈淇℃伅涓婚敭
+     * @return 鍌ㄧ綈淇℃伅
+     */
+    TankInfo selectTankInfoById(Long id);
+
+    /**
+     * 鏂板鍌ㄧ綈淇℃伅
+     *
+     * @param tankInfo 鍌ㄧ綈淇℃伅
+     * @return 缁撴灉
+     */
+    boolean insertTankInfo(TankInfo tankInfo);
+
+    /**
+     * 淇敼鍌ㄧ綈淇℃伅
+     *
+     * @param tankInfo 鍌ㄧ綈淇℃伅
+     * @return 缁撴灉
+     */
+    boolean updateTankInfo(TankInfo tankInfo);
+
+    /**
+     * 鎵归噺鍒犻櫎鍌ㄧ綈淇℃伅
+     *
+     * @param ids 闇�瑕佸垹闄ょ殑鍌ㄧ綈淇℃伅涓婚敭闆嗗悎
+     * @return 缁撴灉
+     */
+    boolean deleteTankInfoByIds(Long[] ids);
+}
diff --git a/src/main/java/com/ruoyi/basic/service/impl/OilDepotServiceImpl.java b/src/main/java/com/ruoyi/basic/service/impl/OilDepotServiceImpl.java
new file mode 100644
index 0000000..8d15c7d
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/service/impl/OilDepotServiceImpl.java
@@ -0,0 +1,59 @@
+package com.ruoyi.basic.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.basic.mapper.OilDepotMapper;
+import com.ruoyi.basic.pojo.OilDepot;
+import com.ruoyi.basic.service.IOilDepotService;
+import com.ruoyi.common.utils.StringUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 娌瑰簱淇℃伅Service涓氬姟灞傚鐞�
+ *
+ * @author ruoyi
+ * @date 2026-09-10
+ */
+@Service
+public class OilDepotServiceImpl extends ServiceImpl<OilDepotMapper, OilDepot> implements IOilDepotService {
+
+    @Override
+    public IPage<OilDepot> selectOilDepotList(Page<OilDepot> page, OilDepot oilDepot) {
+        LambdaQueryWrapper<OilDepot> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.like(StringUtils.isNotBlank(oilDepot.getDepotName()), OilDepot::getDepotName, oilDepot.getDepotName())
+                .like(StringUtils.isNotBlank(oilDepot.getCompany()), OilDepot::getCompany, oilDepot.getCompany())
+                .orderByAsc(OilDepot::getId);
+        return this.page(page, queryWrapper);
+    }
+
+    @Override
+    public List<OilDepot> selectAll() {
+        LambdaQueryWrapper<OilDepot> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.orderByAsc(OilDepot::getId);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public OilDepot selectOilDepotById(Long id) {
+        return this.getById(id);
+    }
+
+    @Override
+    public boolean insertOilDepot(OilDepot oilDepot) {
+        return this.save(oilDepot);
+    }
+
+    @Override
+    public boolean updateOilDepot(OilDepot oilDepot) {
+        return this.updateById(oilDepot);
+    }
+
+    @Override
+    public boolean deleteOilDepotByIds(Long[] ids) {
+        return this.removeByIds(List.of(ids));
+    }
+}
diff --git a/src/main/java/com/ruoyi/basic/service/impl/TankInfoServiceImpl.java b/src/main/java/com/ruoyi/basic/service/impl/TankInfoServiceImpl.java
new file mode 100644
index 0000000..fa909e7
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/service/impl/TankInfoServiceImpl.java
@@ -0,0 +1,59 @@
+package com.ruoyi.basic.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.basic.mapper.TankInfoMapper;
+import com.ruoyi.basic.pojo.TankInfo;
+import com.ruoyi.basic.service.ITankInfoService;
+import com.ruoyi.common.utils.StringUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 鍌ㄧ綈淇℃伅Service涓氬姟灞傚鐞�
+ *
+ * @author ruoyi
+ * @date 2026-09-10
+ */
+@Service
+public class TankInfoServiceImpl extends ServiceImpl<TankInfoMapper, TankInfo> implements ITankInfoService {
+
+    @Override
+    public IPage<TankInfo> selectTankInfoList(Page<TankInfo> page, TankInfo tankInfo) {
+        LambdaQueryWrapper<TankInfo> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.like(StringUtils.isNotBlank(tankInfo.getTankNo()), TankInfo::getTankNo, tankInfo.getTankNo())
+                .like(StringUtils.isNotBlank(tankInfo.getCategory()), TankInfo::getCategory, tankInfo.getCategory())
+                .orderByAsc(TankInfo::getId);
+        return this.page(page, queryWrapper);
+    }
+
+    @Override
+    public List<TankInfo> selectAll() {
+        LambdaQueryWrapper<TankInfo> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.orderByAsc(TankInfo::getId);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public TankInfo selectTankInfoById(Long id) {
+        return this.getById(id);
+    }
+
+    @Override
+    public boolean insertTankInfo(TankInfo tankInfo) {
+        return this.save(tankInfo);
+    }
+
+    @Override
+    public boolean updateTankInfo(TankInfo tankInfo) {
+        return this.updateById(tankInfo);
+    }
+
+    @Override
+    public boolean deleteTankInfoByIds(Long[] ids) {
+        return this.removeByIds(List.of(ids));
+    }
+}
diff --git a/src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java b/src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java
index ee089a5..93812e2 100644
--- a/src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java
+++ b/src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java
@@ -98,6 +98,13 @@
     private Date entryDate;
 
     /**
+     * 鐢宠鎻愪氦鏃堕棿
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date applicationSubmitTime;
+
+    /**
      * 绛捐鏃ユ湡
      */
     @JsonFormat(pattern = "yyyy-MM-dd")
@@ -194,6 +201,30 @@
 
     @Schema(description = "浠樻鏂瑰紡")
     private String paymentMethod;
+    @Schema(description = "閲囪喘绫诲埆锛氬瀛樸�佷唬鍌ㄣ�侀噰璐叆搴撱�侀噰璐洿閿�")
+    private String purchaseCategory;
+
+    @Schema(description = "閲囪喘娌瑰搧锛氭苯#92銆佹苯#95銆佹煷#0銆佹煷#-35")
+    private String purchaseOilProduct;
+
+    @Schema(description = "鐗╂祦鏂瑰紡锛氬巶瀹堕厤閫併�佸澶栫墿娴併�佸鎴疯嚜鎻�")
+    private String logisticsMethod;
+
+    @Schema(description = "鎻愯揣鏂瑰紡锛氭殏涓嶆彁璐с�佹彁璐�")
+    private String pickupMethod;
+    @Schema(description = "閲囪喘娌瑰簱id")
+    private Long oilDepotId;
+    @Schema(description = "閲囪喘娌瑰簱鍚嶇О")
+    private String oilDepotName;
+    @Schema(description = "瀹㈡埛鍚嶇О")
+    private String customerName;
+    @Schema(description = "鏈�浣冲埌绔欐棩鏈�")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date bestArrivalDate;
+    @Schema(description = "閲囪喘鏁伴噺锛堝惃锛�")
+    private Integer purchaseQuantity;
+    @Schema(description = "閲囪喘鐢宠璁㈠崟鐘舵��")
+    private String purchaseOrderStatus;
     @Schema(description = "瀹℃壒鐘舵��")
     private Integer approvalStatus;
     @Schema(description = "妯℃澘鍚嶇О")
diff --git a/src/main/java/com/ruoyi/purchase/pojo/PurchaseLedger.java b/src/main/java/com/ruoyi/purchase/pojo/PurchaseLedger.java
index ec96643..cdcfcd9 100644
--- a/src/main/java/com/ruoyi/purchase/pojo/PurchaseLedger.java
+++ b/src/main/java/com/ruoyi/purchase/pojo/PurchaseLedger.java
@@ -73,6 +73,12 @@
     @Excel(name = "褰曞叆鏃ユ湡", width = 30, dateFormat = "yyyy-MM-dd")
     private Date entryDate;
 
+    /**
+     * 鐢宠鎻愪氦鏃堕棿
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date applicationSubmitTime;
+
 
     /**
      * 绛捐鏃ユ湡
@@ -148,6 +154,72 @@
 
     @Schema(description = "浠樻鏂瑰紡")
     private String paymentMethod;
+
+    /**
+     * 閲囪喘绫诲埆锛氬瀛樸�佷唬鍌ㄣ�侀噰璐叆搴撱�侀噰璐洿閿�
+     */
+    @Schema(description = "閲囪喘绫诲埆")
+    @Excel(name = "閲囪喘绫诲埆")
+    private String purchaseCategory;
+
+    /**
+     * 閲囪喘娌瑰搧锛氭苯#92銆佹苯#95銆佹煷#0銆佹煷#-35
+     */
+    @Schema(description = "閲囪喘娌瑰搧")
+    @Excel(name = "閲囪喘娌瑰搧")
+    private String purchaseOilProduct;
+
+    /**
+     * 鐗╂祦鏂瑰紡锛氬巶瀹堕厤閫併�佸澶栫墿娴併�佸鎴疯嚜鎻�
+     */
+    @Schema(description = "鐗╂祦鏂瑰紡")
+    @Excel(name = "鐗╂祦鏂瑰紡")
+    private String logisticsMethod;
+
+    /**
+     * 鎻愯揣鏂瑰紡锛氭殏涓嶆彁璐с�佹彁璐�
+     */
+    @Schema(description = "鎻愯揣鏂瑰紡")
+    @Excel(name = "鎻愯揣鏂瑰紡")
+    private String pickupMethod;
+
+    /**
+     * 閲囪喘娌瑰簱id
+     */
+    @Schema(description = "閲囪喘娌瑰簱id")
+    private Long oilDepotId;
+
+    /**
+     * 閲囪喘娌瑰簱鍚嶇О
+     */
+    @Schema(description = "閲囪喘娌瑰簱鍚嶇О")
+    @Excel(name = "閲囪喘娌瑰簱")
+    private String oilDepotName;
+
+    /**
+     * 瀹㈡埛鍚嶇О
+     */
+    @Schema(description = "瀹㈡埛鍚嶇О")
+    private String customerName;
+
+    /**
+     * 鏈�浣冲埌绔欐棩鏈�
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Schema(description = "鏈�浣冲埌绔欐棩鏈�")
+    private Date bestArrivalDate;
+
+    /**
+     * 閲囪喘鏁伴噺锛堝惃锛�
+     */
+    @Schema(description = "閲囪喘鏁伴噺锛堝惃锛�")
+    private Integer purchaseQuantity;
+
+    /**
+     * 閲囪喘鐢宠璁㈠崟鐘舵�侊細宸茬敵璇凤紝鏈杞� / 浠ュ嚭鍘傦紝鏈叆搴� / 宸插叆搴�
+     */
+    @Schema(description = "閲囪喘鐢宠璁㈠崟鐘舵��")
+    private String purchaseOrderStatus;
     @Schema(description = "瀹℃壒鐘舵��  1-寰呭鏍革紝2-瀹℃壒涓紝3-瀹℃壒閫氳繃锛�4-瀹℃壒澶辫触,5琛ㄧず鏄ā鏉�")
     @Excel(name = "瀹℃壒鐘舵��", readConverterExp = "1=寰呭鏍�,2=瀹℃壒涓�,3=瀹℃壒閫氳繃,4=瀹℃壒澶辫触")
     private Integer approvalStatus;
diff --git a/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java b/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
index 7c25815..5a80184 100644
--- a/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
@@ -16,9 +16,11 @@
 import com.ruoyi.approve.service.impl.ApproveProcessServiceImpl;
 import com.ruoyi.basic.enums.ApplicationTypeEnum;
 import com.ruoyi.basic.enums.RecordTypeEnum;
+import com.ruoyi.basic.mapper.OilDepotMapper;
 import com.ruoyi.basic.mapper.ProductMapper;
 import com.ruoyi.basic.mapper.ProductModelMapper;
 import com.ruoyi.basic.mapper.SupplierManageMapper;
+import com.ruoyi.basic.pojo.OilDepot;
 import com.ruoyi.basic.pojo.Product;
 import com.ruoyi.basic.pojo.ProductModel;
 import com.ruoyi.basic.pojo.SupplierManage;
@@ -118,6 +120,7 @@
     private final StockInRecordService stockInRecordService;
     private final StockUtils stockUtils;
     private final ApprovalTemplateMapper approvalTemplateMapper;
+    private final OilDepotMapper oilDepotMapper;
 
     @Override
     public List<PurchaseLedger> selectPurchaseLedgerList(PurchaseLedger purchaseLedger) {
@@ -171,6 +174,14 @@
         purchaseLedger.setSupplierName(supplierManage.getSupplierName());
         purchaseLedger.setRecorderId(purchaseLedgerDto.getRecorderId());
 
+        // 閲囪喘娌瑰簱锛氭牴鎹补搴搃d鍥炲~娌瑰簱鍚嶇О
+        if (purchaseLedgerDto.getOilDepotId() != null) {
+            OilDepot oilDepot = oilDepotMapper.selectById(purchaseLedgerDto.getOilDepotId());
+            if (oilDepot != null) {
+                purchaseLedger.setOilDepotName(oilDepot.getDepotName());
+            }
+        }
+
         purchaseLedger.setApprovalStatus(1);
         // 瀹為檯鍚堝悓閲戦濮嬬粓绛変簬鍚堝悓閲戦
         purchaseLedger.setNetContractAmount(purchaseLedger.getContractAmount());
diff --git a/src/main/java/com/ruoyi/stock/controller/StockInventoryController.java b/src/main/java/com/ruoyi/stock/controller/StockInventoryController.java
index a0a9fa5..776447e 100644
--- a/src/main/java/com/ruoyi/stock/controller/StockInventoryController.java
+++ b/src/main/java/com/ruoyi/stock/controller/StockInventoryController.java
@@ -9,6 +9,7 @@
 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
 import com.ruoyi.framework.web.domain.R;
 import com.ruoyi.stock.dto.StockInventoryDto;
+import com.ruoyi.stock.dto.StockOutRecordDto;
 import com.ruoyi.stock.execl.StockInventoryExportData;
 import com.ruoyi.stock.service.StockInventoryService;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -97,6 +98,14 @@
         return R.ok(stockInventoryService.addStockOutRecordOnly(stockInventoryDto));
     }
 
+    @PostMapping("/addOilOutRecordOnly")
+    @Operation(summary = "鏂板娌瑰搧鍑哄簱璁板綍锛堜粎鍒涘缓璁板綍锛屼笉璋冩暣搴撳瓨锛�")
+    public R addOilOutRecordOnly(@RequestBody StockOutRecordDto stockOutRecordDto) {
+        stockOutRecordDto.setRecordType(String.valueOf(StockOutQualifiedRecordTypeEnum.CUSTOMIZATION_STOCK_OUT.getCode()));
+        stockOutRecordDto.setRecordId(0L);
+        return R.ok(stockInventoryService.addOilOutRecordOnly(stockOutRecordDto));
+    }
+
 
     @PostMapping("/importStockInventory")
     @Operation(summary = "瀵煎叆搴撳瓨")
diff --git a/src/main/java/com/ruoyi/stock/dto/StockInventoryDto.java b/src/main/java/com/ruoyi/stock/dto/StockInventoryDto.java
index 33b7599..32a95aa 100644
--- a/src/main/java/com/ruoyi/stock/dto/StockInventoryDto.java
+++ b/src/main/java/com/ruoyi/stock/dto/StockInventoryDto.java
@@ -8,6 +8,7 @@
 
 import java.math.BigDecimal;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 
 @Data
 public class StockInventoryDto extends StockInventory {
@@ -16,6 +17,44 @@
     private String model;
     private String unit;
     private String batchNo;
+    private Long oilDepotId;
+    private String oilDepotName;
+    private String inboundCategory;
+    private Long tankId;
+    private String tankNo;
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime inboundTime;
+    private String oilProduct;
+    private BigDecimal originalQuantity;
+    private Long customerId;
+    private String customerName;
+    private String contactPerson;
+    private String contactPhone;
+
+    //鐗╂祦淇℃伅
+    private String driverName;
+    private String driverPhone;
+    private String escortName;
+    private String escortPhone;
+    private String truckPlateNo;
+    private String trailerPlateNo;
+
+    //鍗告补鎿嶄綔淇℃伅
+    private String tankInspectionStatus;
+    private String unloadingCranePosition;
+    private String density;
+    // 鍏ュ弬涓烘暟缁勶紝鍒楄〃杩斿洖涓篔SON瀛楃涓�
+    private Object unloadPhotos;
+
+    //杩囩鏁版嵁
+    private BigDecimal grossWeight;
+    private BigDecimal tareWeight;
+    private BigDecimal netWeight;
+    private BigDecimal lossQuantity;
+    private BigDecimal actualVolume;
+    // 鍏ュ弬涓烘暟缁勶紝鍒楄〃杩斿洖涓篔SON瀛楃涓�
+    private Object poundPhotos;
 
 
     //鍏ュ簱绫诲瀷
@@ -80,4 +119,32 @@
 
     @Schema(description = "浜у搧id")
     private Long productId;
+
+    //娌瑰搧鍑哄簱璁板綍灞曠ず瀛楁锛堣鎯呮帴鍙f寜浜у搧鍏宠仈鏈�鏂板嚭搴撹褰曪級
+    private String outCategory;
+    private LocalDate outDate;
+    private BigDecimal outTonnage;
+    private String outCustomerName;
+    private String loadingInspectionStatus;
+    private String loadingCranePosition;
+    private String outDensity;
+    private String outDriverName;
+    private String outTruckPlateNo;
+    private String outOilDepotName;
+    private String outTankNo;
+    private String outOilProduct;
+    private String outContactPerson;
+    private String outContactPhone;
+    private BigDecimal outGrossWeight;
+    private BigDecimal outTareWeight;
+    private BigDecimal outNetWeight;
+    private BigDecimal outLossQuantity;
+    private BigDecimal outActualVolume;
+    private String outDriverPhone;
+    private String outEscortName;
+    private String outEscortPhone;
+    private String outTrailerPlateNo;
+    // 鍒楄〃杩斿洖涓篔SON瀛楃涓�
+    private Object loadingPhotos;
+    private Object outPoundPhotos;
 }
diff --git a/src/main/java/com/ruoyi/stock/dto/StockUninventoryDto.java b/src/main/java/com/ruoyi/stock/dto/StockUninventoryDto.java
index 404c58a..cff31ed 100644
--- a/src/main/java/com/ruoyi/stock/dto/StockUninventoryDto.java
+++ b/src/main/java/com/ruoyi/stock/dto/StockUninventoryDto.java
@@ -1,15 +1,56 @@
 package com.ruoyi.stock.dto;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import com.ruoyi.stock.pojo.StockUninventory;
 import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
 
 import java.math.BigDecimal;
+import java.time.LocalDateTime;
 
 @Data
 public class StockUninventoryDto  extends StockUninventory {
     private String productName;
     private String model;
     private String unit;
+    private Long oilDepotId;
+    private String oilDepotName;
+    private String inboundCategory;
+    private Long tankId;
+    private String tankNo;
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime inboundTime;
+    private String oilProduct;
+    private BigDecimal originalQuantity;
+    private Long customerId;
+    private String customerName;
+    private String contactPerson;
+    private String contactPhone;
+
+    //鐗╂祦淇℃伅
+    private String driverName;
+    private String driverPhone;
+    private String escortName;
+    private String escortPhone;
+    private String truckPlateNo;
+    private String trailerPlateNo;
+
+    //鍗告补鎿嶄綔淇℃伅
+    private String tankInspectionStatus;
+    private String unloadingCranePosition;
+    private String density;
+    // 鍏ュ弬涓烘暟缁勶紝鍒楄〃杩斿洖涓篔SON瀛楃涓�
+    private Object unloadPhotos;
+
+    //杩囩鏁版嵁
+    private BigDecimal grossWeight;
+    private BigDecimal tareWeight;
+    private BigDecimal netWeight;
+    private BigDecimal lossQuantity;
+    private BigDecimal actualVolume;
+    // 鍏ュ弬涓烘暟缁勶紝鍒楄〃杩斿洖涓篔SON瀛楃涓�
+    private Object poundPhotos;
 
 
     //鍏ュ簱绫诲瀷
diff --git a/src/main/java/com/ruoyi/stock/pojo/StockInRecord.java b/src/main/java/com/ruoyi/stock/pojo/StockInRecord.java
index d020761..905e702 100644
--- a/src/main/java/com/ruoyi/stock/pojo/StockInRecord.java
+++ b/src/main/java/com/ruoyi/stock/pojo/StockInRecord.java
@@ -46,6 +46,92 @@
     @Schema(description = "棰勮鏁伴噺")
     private BigDecimal warnNum;
 
+    @Schema(description = "鍏ュ簱娌瑰簱id")
+    private Long oilDepotId;
+
+    @Schema(description = "鍏ュ簱鍚嶇О锛堟补搴撳悕绉帮級")
+    private String oilDepotName;
+
+    @Schema(description = "鍏ュ簱绫诲埆锛氳嚜璐叆搴�/浠e偍鍏ュ簱")
+    private String inboundCategory;
+
+    @Schema(description = "鍌ㄧ綈id")
+    private Long tankId;
+
+    @Schema(description = "鍌ㄧ綈鍙�")
+    private String tankNo;
+
+    @Schema(description = "鍏ュ簱鏃堕棿")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime inboundTime;
+
+    @Schema(description = "娌瑰搧锛氭苯#92銆佹苯#95銆佹煷#0銆佹煷#-35")
+    private String oilProduct;
+
+    @Schema(description = "鍘熷巶鏁伴噺(鍚�)")
+    private BigDecimal originalQuantity;
+
+    @Schema(description = "瀹㈡埛id")
+    private Long customerId;
+
+    @Schema(description = "瀹㈡埛鍚嶇О")
+    private String customerName;
+
+    @Schema(description = "瀹㈡埛瀵规帴浜�")
+    private String contactPerson;
+
+    @Schema(description = "瀵规帴浜虹數璇�")
+    private String contactPhone;
+
+    @Schema(description = "鍙告満濮撳悕")
+    private String driverName;
+
+    @Schema(description = "鍙告満鐢佃瘽")
+    private String driverPhone;
+
+    @Schema(description = "鎶艰繍鍛樺鍚�")
+    private String escortName;
+
+    @Schema(description = "鎶艰繍鍛樼數璇�")
+    private String escortPhone;
+
+    @Schema(description = "杞︾墝鍙�")
+    private String truckPlateNo;
+
+    @Schema(description = "杞︽寕鐗屽彿")
+    private String trailerPlateNo;
+
+    @Schema(description = "杞︿綋/閾呭皝妫�楠屾槸鍚︽甯革細姝e父/寮傚父")
+    private String tankInspectionStatus;
+
+    @Schema(description = "鍗歌溅楣や綅锛�1#鎾/2#鎾/涓存椂娉�")
+    private String unloadingCranePosition;
+
+    @Schema(description = "瀵嗗害锛坘g/L锛�")
+    private String density;
+
+    @Schema(description = "鍗告补鍏抽敭鐜妭涓庤溅杈嗗叧閿綅缃媿鐓э紙JSON鏁扮粍锛�")
+    private String unloadPhotos;
+
+    @Schema(description = "姣涢噸(鍚�)")
+    private BigDecimal grossWeight;
+
+    @Schema(description = "鐨噸(鍚�)")
+    private BigDecimal tareWeight;
+
+    @Schema(description = "鍑�閲�(鍚�)")
+    private BigDecimal netWeight;
+
+    @Schema(description = "浜忛噺(鍚�)")
+    private BigDecimal lossQuantity;
+
+    @Schema(description = "瀹為檯鍏ュ簱浣撶Н(鍗�)")
+    private BigDecimal actualVolume;
+
+    @Schema(description = "纾呭崟涓婁紶锛圝SON鏁扮粍锛�")
+    private String poundPhotos;
+
     @Schema(description = "绫诲瀷  0鍚堟牸鍏ュ簱 1涓嶅悎鏍煎叆搴�")
     private String type;
 
diff --git a/src/main/java/com/ruoyi/stock/pojo/StockOutRecord.java b/src/main/java/com/ruoyi/stock/pojo/StockOutRecord.java
index 5a35020..2379658 100644
--- a/src/main/java/com/ruoyi/stock/pojo/StockOutRecord.java
+++ b/src/main/java/com/ruoyi/stock/pojo/StockOutRecord.java
@@ -10,6 +10,7 @@
 
 import java.io.Serializable;
 import java.math.BigDecimal;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
 
 /**
@@ -46,6 +47,90 @@
     @Schema(description = "鍏ュ簱绫诲瀷")
     private String recordType;
 
+    @Schema(description = "鍑哄簱绫诲埆锛氬瀛�/浠e偍/閿�鍞�")
+    private String outCategory;
+
+    @Schema(description = "鍌ㄥ簱id")
+    private Long oilDepotId;
+
+    @Schema(description = "鍌ㄥ簱鍚嶇О")
+    private String oilDepotName;
+
+    @Schema(description = "鍌ㄧ綈id")
+    private Long tankId;
+
+    @Schema(description = "鍌ㄧ綈鍙�")
+    private String tankNo;
+
+    @Schema(description = "鍑哄簱鏃ユ湡")
+    private LocalDate outDate;
+
+    @Schema(description = "娌瑰搧")
+    private String oilProduct;
+
+    @Schema(description = "鍑哄簱鍚ㄤ綅(鍚�)")
+    private BigDecimal outTonnage;
+
+    @Schema(description = "瀹㈡埛id")
+    private Long customerId;
+
+    @Schema(description = "瀹㈡埛鍚嶇О")
+    private String customerName;
+
+    @Schema(description = "瀹㈡埛瀵规帴浜�")
+    private String contactPerson;
+
+    @Schema(description = "瀵规帴浜虹數璇�")
+    private String contactPhone;
+
+    @Schema(description = "杞︿綋/閾呭皝妫�楠屾槸鍚︽甯�")
+    private String loadingInspectionStatus;
+
+    @Schema(description = "瑁呰溅楣や綅")
+    private String loadingCranePosition;
+
+    @Schema(description = "瑁呮补鍏抽敭鐜妭涓庤溅杈嗗叧閿綅缃媿鐓э紙JSON鏁扮粍锛�")
+    private String loadingPhotos;
+
+    @Schema(description = "瀵嗗害锛坘g/L锛�")
+    private String density;
+
+    @Schema(description = "姣涢噸(鍚�)")
+    private BigDecimal grossWeight;
+
+    @Schema(description = "鐨噸(鍚�)")
+    private BigDecimal tareWeight;
+
+    @Schema(description = "鍑�閲�(鍚�)")
+    private BigDecimal netWeight;
+
+    @Schema(description = "浜忛噺(鍚�)")
+    private BigDecimal lossQuantity;
+
+    @Schema(description = "瀹為檯鍏ュ簱浣撶Н(鍗�)")
+    private BigDecimal actualVolume;
+
+    @Schema(description = "纾呭崟涓婁紶锛圝SON鏁扮粍锛�")
+    private String poundPhotos;
+
+    @Schema(description = "鍙告満濮撳悕")
+    private String driverName;
+
+    @Schema(description = "鍙告満鐢佃瘽")
+    private String driverPhone;
+
+    @Schema(description = "鎶艰繍鍛樺鍚�")
+    private String escortName;
+
+    @Schema(description = "鎶艰繍鍛樼數璇�")
+    private String escortPhone;
+
+    @Schema(description = "杞︾墝鍙�")
+    private String truckPlateNo;
+
+    @Schema(description = "杞︽寕鐗屽彿")
+    private String trailerPlateNo;
+
     @Schema(description = "浜у搧瑙勬牸id")
     private Long productModelId;
 
diff --git a/src/main/java/com/ruoyi/stock/service/StockInventoryService.java b/src/main/java/com/ruoyi/stock/service/StockInventoryService.java
index 5d534d5..0176b53 100644
--- a/src/main/java/com/ruoyi/stock/service/StockInventoryService.java
+++ b/src/main/java/com/ruoyi/stock/service/StockInventoryService.java
@@ -6,6 +6,7 @@
 import com.ruoyi.framework.web.domain.R;
 import com.ruoyi.stock.dto.StockInRecordDto;
 import com.ruoyi.stock.dto.StockInventoryDto;
+import com.ruoyi.stock.dto.StockOutRecordDto;
 import com.ruoyi.stock.pojo.StockInventory;
 import jakarta.servlet.http.HttpServletResponse;
 import org.springframework.web.multipart.MultipartFile;
@@ -34,6 +35,8 @@
 
     Boolean addStockOutRecordOnly(StockInventoryDto stockInventoryDto);
 
+    Boolean addOilOutRecordOnly(StockOutRecordDto stockOutRecordDto);
+
     R importStockInventory(MultipartFile file);
 
     void exportStockInventory(HttpServletResponse response, StockInventoryDto stockInventoryDto);
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 07d70a5..0f70cfe 100644
--- a/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
@@ -7,8 +7,17 @@
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.alibaba.fastjson2.JSON;
+import com.ruoyi.basic.dto.StorageBlobVO;
+import com.ruoyi.basic.mapper.CustomerMapper;
+import com.ruoyi.basic.mapper.OilDepotMapper;
 import com.ruoyi.basic.mapper.ProductModelMapper;
+import com.ruoyi.basic.mapper.TankInfoMapper;
+import com.ruoyi.basic.pojo.Customer;
+import com.ruoyi.basic.pojo.OilDepot;
 import com.ruoyi.basic.pojo.ProductModel;
+import com.ruoyi.basic.pojo.TankInfo;
+import com.ruoyi.basic.utils.FileUtil;
 import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.StringUtils;
@@ -60,6 +69,10 @@
     private final StockUninventoryService stockUninventoryService;
     private final SalesLedgerProductMapper salesLedgerProductMapper;
     private final ProductModelMapper productModelMapper;
+    private final OilDepotMapper oilDepotMapper;
+    private final TankInfoMapper tankInfoMapper;
+    private final CustomerMapper customerMapper;
+    private final FileUtil fileUtil;
 
     @Override
     public IPage<StockInventoryDto> pagestockInventory(Page page, StockInventoryDto stockInventoryDto) {
@@ -173,6 +186,54 @@
         stockInRecordDto.setType("0");
         stockInRecordDto.setRemark(stockInventoryDto.getRemark());
         stockInRecordDto.setWarnNum(stockInventoryDto.getWarnNum());
+        stockInRecordDto.setOilDepotId(stockInventoryDto.getOilDepotId());
+        stockInRecordDto.setOilDepotName(stockInventoryDto.getOilDepotName());
+        stockInRecordDto.setInboundCategory(stockInventoryDto.getInboundCategory());
+        if (stockInventoryDto.getOilDepotId() != null && StringUtils.isEmpty(stockInRecordDto.getOilDepotName())) {
+            OilDepot oilDepot = oilDepotMapper.selectById(stockInventoryDto.getOilDepotId());
+            if (oilDepot != null) {
+                stockInRecordDto.setOilDepotName(oilDepot.getDepotName());
+            }
+        }
+        stockInRecordDto.setTankId(stockInventoryDto.getTankId());
+        stockInRecordDto.setTankNo(stockInventoryDto.getTankNo());
+        if (stockInventoryDto.getTankId() != null && StringUtils.isEmpty(stockInRecordDto.getTankNo())) {
+            TankInfo tankInfo = tankInfoMapper.selectById(stockInventoryDto.getTankId());
+            if (tankInfo != null) {
+                stockInRecordDto.setTankNo(tankInfo.getTankNo());
+            }
+        }
+        stockInRecordDto.setInboundTime(stockInventoryDto.getInboundTime());
+        stockInRecordDto.setOilProduct(stockInventoryDto.getOilProduct());
+        stockInRecordDto.setOriginalQuantity(stockInventoryDto.getOriginalQuantity());
+        stockInRecordDto.setCustomerId(stockInventoryDto.getCustomerId());
+        stockInRecordDto.setCustomerName(stockInventoryDto.getCustomerName());
+        stockInRecordDto.setContactPerson(stockInventoryDto.getContactPerson());
+        stockInRecordDto.setContactPhone(stockInventoryDto.getContactPhone());
+        stockInRecordDto.setDriverName(stockInventoryDto.getDriverName());
+        stockInRecordDto.setDriverPhone(stockInventoryDto.getDriverPhone());
+        stockInRecordDto.setEscortName(stockInventoryDto.getEscortName());
+        stockInRecordDto.setEscortPhone(stockInventoryDto.getEscortPhone());
+        stockInRecordDto.setTruckPlateNo(stockInventoryDto.getTruckPlateNo());
+        stockInRecordDto.setTrailerPlateNo(stockInventoryDto.getTrailerPlateNo());
+        stockInRecordDto.setTankInspectionStatus(stockInventoryDto.getTankInspectionStatus());
+        stockInRecordDto.setUnloadingCranePosition(stockInventoryDto.getUnloadingCranePosition());
+        stockInRecordDto.setDensity(stockInventoryDto.getDensity());
+        stockInRecordDto.setUnloadPhotos(stockInventoryDto.getUnloadPhotos() == null
+                ? null : JSON.toJSONString(stockInventoryDto.getUnloadPhotos()));
+        stockInRecordDto.setGrossWeight(stockInventoryDto.getGrossWeight());
+        stockInRecordDto.setTareWeight(stockInventoryDto.getTareWeight());
+        stockInRecordDto.setNetWeight(stockInventoryDto.getNetWeight());
+        stockInRecordDto.setLossQuantity(stockInventoryDto.getLossQuantity());
+        stockInRecordDto.setActualVolume(stockInventoryDto.getActualVolume());
+        stockInRecordDto.setPoundPhotos(stockInventoryDto.getPoundPhotos() == null
+                ? null : JSON.toJSONString(stockInventoryDto.getPoundPhotos()));
+        if (stockInventoryDto.getCustomerId() != null && StringUtils.isEmpty(stockInRecordDto.getCustomerName())) {
+            Customer customer = customerMapper.selectById(stockInventoryDto.getCustomerId());
+            if (customer != null) {
+                stockInRecordDto.setCustomerName(customer.getCustomerName());
+            }
+        }
         stockInRecordService.add(stockInRecordDto);
         return true;
     }
@@ -442,6 +503,50 @@
 
     @Override
     public IPage<StockInventoryDto> getBatchNoQty(Page page, StockInventoryDto stockInventoryDto) {
-        return stockInventoryMapper.getBatchNoQty(page, stockInventoryDto);
+        IPage<StockInventoryDto> result = stockInventoryMapper.getBatchNoQty(page, stockInventoryDto);
+        // 鐓х墖搴撻噷瀛樼殑鏄笂浼犳椂鐨勭鍚峌RL锛堥粯璁�2灏忔椂杩囨湡锛夛紝杩斿洖鍓嶉噸鏂扮鍙戯紝閬垮厤鍓嶇鍥剧墖鍔犺浇澶辫触
+        for (StockInventoryDto record : result.getRecords()) {
+            record.setUnloadPhotos(refreshPhotoUrls(record.getUnloadPhotos()));
+            record.setPoundPhotos(refreshPhotoUrls(record.getPoundPhotos()));
+            record.setLoadingPhotos(refreshPhotoUrls(record.getLoadingPhotos()));
+            record.setOutPoundPhotos(refreshPhotoUrls(record.getOutPoundPhotos()));
+        }
+        return result;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean addOilOutRecordOnly(StockOutRecordDto stockOutRecordDto) {
+        stockOutRecordDto.setStockOutNum(stockOutRecordDto.getOutTonnage());
+        stockOutRecordDto.setApprovalStatus(0);
+        return stockOutRecordService.add(stockOutRecordDto) > 0;
+    }
+
+    /**
+     * 閲嶆柊绛惧彂鐓х墖棰勮/涓嬭浇URL
+     */
+    private Object refreshPhotoUrls(Object photos) {
+        if (!(photos instanceof String)) {
+            return photos;
+        }
+        String json = (String) photos;
+        if (StringUtils.isEmpty(json)) {
+            return photos;
+        }
+        try {
+            List<StorageBlobVO> list = JSON.parseArray(json, StorageBlobVO.class);
+            if (list == null || list.isEmpty()) {
+                return photos;
+            }
+            for (StorageBlobVO vo : list) {
+                String previewUrl = fileUtil.buildSignedUrl(vo, "/preview/", null);
+                vo.setPreviewURL(previewUrl);
+                vo.setUrl(previewUrl);
+                vo.setDownloadURL(fileUtil.buildSignedUrl(vo, "/download/", null));
+            }
+            return JSON.toJSONString(list);
+        } catch (Exception e) {
+            return photos;
+        }
     }
 }
diff --git a/src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java b/src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java
index 47f7d34..f30fd88 100644
--- a/src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java
@@ -7,8 +7,15 @@
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.alibaba.fastjson2.JSON;
+import com.ruoyi.basic.mapper.CustomerMapper;
+import com.ruoyi.basic.mapper.OilDepotMapper;
 import com.ruoyi.basic.mapper.ProductModelMapper;
+import com.ruoyi.basic.mapper.TankInfoMapper;
+import com.ruoyi.basic.pojo.Customer;
+import com.ruoyi.basic.pojo.OilDepot;
 import com.ruoyi.basic.pojo.ProductModel;
+import com.ruoyi.basic.pojo.TankInfo;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.exception.base.BaseException;
 import com.ruoyi.common.utils.StringUtils;
@@ -54,6 +61,9 @@
     private final StockInRecordService stockInRecordService;
     private final ProductModelMapper productModelMapper;
     private final StockInventoryMapper stockInventoryMapper;
+    private final OilDepotMapper oilDepotMapper;
+    private final TankInfoMapper tankInfoMapper;
+    private final CustomerMapper customerMapper;
 
     @Override
     public IPage<StockUninventoryDto> pageStockUninventory(Page page, StockUninventoryDto stockUninventoryDto) {
@@ -79,6 +89,54 @@
         stockInRecordDto.setBatchNo(stockUninventoryDto.getBatchNo());
         stockInRecordDto.setProductModelId(stockUninventoryDto.getProductModelId());
         stockInRecordDto.setType("1");
+        stockInRecordDto.setOilDepotId(stockUninventoryDto.getOilDepotId());
+        stockInRecordDto.setOilDepotName(stockUninventoryDto.getOilDepotName());
+        stockInRecordDto.setInboundCategory(stockUninventoryDto.getInboundCategory());
+        if (stockUninventoryDto.getOilDepotId() != null && StringUtils.isEmpty(stockInRecordDto.getOilDepotName())) {
+            OilDepot oilDepot = oilDepotMapper.selectById(stockUninventoryDto.getOilDepotId());
+            if (oilDepot != null) {
+                stockInRecordDto.setOilDepotName(oilDepot.getDepotName());
+            }
+        }
+        stockInRecordDto.setTankId(stockUninventoryDto.getTankId());
+        stockInRecordDto.setTankNo(stockUninventoryDto.getTankNo());
+        if (stockUninventoryDto.getTankId() != null && StringUtils.isEmpty(stockInRecordDto.getTankNo())) {
+            TankInfo tankInfo = tankInfoMapper.selectById(stockUninventoryDto.getTankId());
+            if (tankInfo != null) {
+                stockInRecordDto.setTankNo(tankInfo.getTankNo());
+            }
+        }
+        stockInRecordDto.setInboundTime(stockUninventoryDto.getInboundTime());
+        stockInRecordDto.setOilProduct(stockUninventoryDto.getOilProduct());
+        stockInRecordDto.setOriginalQuantity(stockUninventoryDto.getOriginalQuantity());
+        stockInRecordDto.setCustomerId(stockUninventoryDto.getCustomerId());
+        stockInRecordDto.setCustomerName(stockUninventoryDto.getCustomerName());
+        stockInRecordDto.setContactPerson(stockUninventoryDto.getContactPerson());
+        stockInRecordDto.setContactPhone(stockUninventoryDto.getContactPhone());
+        stockInRecordDto.setDriverName(stockUninventoryDto.getDriverName());
+        stockInRecordDto.setDriverPhone(stockUninventoryDto.getDriverPhone());
+        stockInRecordDto.setEscortName(stockUninventoryDto.getEscortName());
+        stockInRecordDto.setEscortPhone(stockUninventoryDto.getEscortPhone());
+        stockInRecordDto.setTruckPlateNo(stockUninventoryDto.getTruckPlateNo());
+        stockInRecordDto.setTrailerPlateNo(stockUninventoryDto.getTrailerPlateNo());
+        stockInRecordDto.setTankInspectionStatus(stockUninventoryDto.getTankInspectionStatus());
+        stockInRecordDto.setUnloadingCranePosition(stockUninventoryDto.getUnloadingCranePosition());
+        stockInRecordDto.setDensity(stockUninventoryDto.getDensity());
+        stockInRecordDto.setUnloadPhotos(stockUninventoryDto.getUnloadPhotos() == null
+                ? null : JSON.toJSONString(stockUninventoryDto.getUnloadPhotos()));
+        stockInRecordDto.setGrossWeight(stockUninventoryDto.getGrossWeight());
+        stockInRecordDto.setTareWeight(stockUninventoryDto.getTareWeight());
+        stockInRecordDto.setNetWeight(stockUninventoryDto.getNetWeight());
+        stockInRecordDto.setLossQuantity(stockUninventoryDto.getLossQuantity());
+        stockInRecordDto.setActualVolume(stockUninventoryDto.getActualVolume());
+        stockInRecordDto.setPoundPhotos(stockUninventoryDto.getPoundPhotos() == null
+                ? null : JSON.toJSONString(stockUninventoryDto.getPoundPhotos()));
+        if (stockUninventoryDto.getCustomerId() != null && StringUtils.isEmpty(stockInRecordDto.getCustomerName())) {
+            Customer customer = customerMapper.selectById(stockUninventoryDto.getCustomerId());
+            if (customer != null) {
+                stockInRecordDto.setCustomerName(customer.getCustomerName());
+            }
+        }
         stockInRecordService.add(stockInRecordDto);
         //瀹℃壒鍐嶆坊鍔�
         return 1;
@@ -121,6 +179,54 @@
         stockInRecordDto.setProductModelId(stockUninventoryDto.getProductModelId());
         stockInRecordDto.setType("1");
         stockInRecordDto.setRemark(stockUninventoryDto.getRemark());
+        stockInRecordDto.setOilDepotId(stockUninventoryDto.getOilDepotId());
+        stockInRecordDto.setOilDepotName(stockUninventoryDto.getOilDepotName());
+        stockInRecordDto.setInboundCategory(stockUninventoryDto.getInboundCategory());
+        if (stockUninventoryDto.getOilDepotId() != null && StringUtils.isEmpty(stockInRecordDto.getOilDepotName())) {
+            OilDepot oilDepot = oilDepotMapper.selectById(stockUninventoryDto.getOilDepotId());
+            if (oilDepot != null) {
+                stockInRecordDto.setOilDepotName(oilDepot.getDepotName());
+            }
+        }
+        stockInRecordDto.setTankId(stockUninventoryDto.getTankId());
+        stockInRecordDto.setTankNo(stockUninventoryDto.getTankNo());
+        if (stockUninventoryDto.getTankId() != null && StringUtils.isEmpty(stockInRecordDto.getTankNo())) {
+            TankInfo tankInfo = tankInfoMapper.selectById(stockUninventoryDto.getTankId());
+            if (tankInfo != null) {
+                stockInRecordDto.setTankNo(tankInfo.getTankNo());
+            }
+        }
+        stockInRecordDto.setInboundTime(stockUninventoryDto.getInboundTime());
+        stockInRecordDto.setOilProduct(stockUninventoryDto.getOilProduct());
+        stockInRecordDto.setOriginalQuantity(stockUninventoryDto.getOriginalQuantity());
+        stockInRecordDto.setCustomerId(stockUninventoryDto.getCustomerId());
+        stockInRecordDto.setCustomerName(stockUninventoryDto.getCustomerName());
+        stockInRecordDto.setContactPerson(stockUninventoryDto.getContactPerson());
+        stockInRecordDto.setContactPhone(stockUninventoryDto.getContactPhone());
+        stockInRecordDto.setDriverName(stockUninventoryDto.getDriverName());
+        stockInRecordDto.setDriverPhone(stockUninventoryDto.getDriverPhone());
+        stockInRecordDto.setEscortName(stockUninventoryDto.getEscortName());
+        stockInRecordDto.setEscortPhone(stockUninventoryDto.getEscortPhone());
+        stockInRecordDto.setTruckPlateNo(stockUninventoryDto.getTruckPlateNo());
+        stockInRecordDto.setTrailerPlateNo(stockUninventoryDto.getTrailerPlateNo());
+        stockInRecordDto.setTankInspectionStatus(stockUninventoryDto.getTankInspectionStatus());
+        stockInRecordDto.setUnloadingCranePosition(stockUninventoryDto.getUnloadingCranePosition());
+        stockInRecordDto.setDensity(stockUninventoryDto.getDensity());
+        stockInRecordDto.setUnloadPhotos(stockUninventoryDto.getUnloadPhotos() == null
+                ? null : JSON.toJSONString(stockUninventoryDto.getUnloadPhotos()));
+        stockInRecordDto.setGrossWeight(stockUninventoryDto.getGrossWeight());
+        stockInRecordDto.setTareWeight(stockUninventoryDto.getTareWeight());
+        stockInRecordDto.setNetWeight(stockUninventoryDto.getNetWeight());
+        stockInRecordDto.setLossQuantity(stockUninventoryDto.getLossQuantity());
+        stockInRecordDto.setActualVolume(stockUninventoryDto.getActualVolume());
+        stockInRecordDto.setPoundPhotos(stockUninventoryDto.getPoundPhotos() == null
+                ? null : JSON.toJSONString(stockUninventoryDto.getPoundPhotos()));
+        if (stockUninventoryDto.getCustomerId() != null && StringUtils.isEmpty(stockInRecordDto.getCustomerName())) {
+            Customer customer = customerMapper.selectById(stockUninventoryDto.getCustomerId());
+            if (customer != null) {
+                stockInRecordDto.setCustomerName(customer.getCustomerName());
+            }
+        }
         stockInRecordService.add(stockInRecordDto);
         return 1;
     }
diff --git a/src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml b/src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml
index 8b94eb7..fd78a05 100644
--- a/src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml
+++ b/src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml
@@ -39,6 +39,16 @@
                 pl.approval_status,
                 pl.payment_method,
                 pl.remarks,
+                pl.purchase_category,
+                pl.pickup_method,
+                pl.purchase_oil_product,
+                pl.logistics_method,
+                pl.oil_depot_name,
+                pl.customer_name,
+                pl.best_arrival_date,
+                pl.purchase_quantity,
+                pl.purchase_order_status,
+                pl.application_submit_time,
                 CASE
                     WHEN IFNULL(ls.total_product_count, 0) = 0 THEN '寰呭叆搴�'
                     WHEN IFNULL(ls.full_product_count, 0) &gt;= IFNULL(ls.total_product_count, 0) THEN '瀹屽叏鍏ュ簱'
diff --git a/src/main/resources/mapper/stock/StockInventoryMapper.xml b/src/main/resources/mapper/stock/StockInventoryMapper.xml
index ac9c49b..fac5842 100644
--- a/src/main/resources/mapper/stock/StockInventoryMapper.xml
+++ b/src/main/resources/mapper/stock/StockInventoryMapper.xml
@@ -120,7 +120,84 @@
         unit,
         product_name,
         product_id,
-        'combined' as stockType
+        'combined' as stockType,
+        (
+        select sir.oil_product
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        order by sir.id desc
+        limit 1
+        ) as oil_product,
+        (
+        select sir.tank_inspection_status
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        order by sir.id desc
+        limit 1
+        ) as tank_inspection_status,
+        (
+        select sir.unloading_crane_position
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        order by sir.id desc
+        limit 1
+        ) as unloading_crane_position,
+        (
+        select sir.density
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        order by sir.id desc
+        limit 1
+        ) as density,
+        (
+        select sir.unload_photos
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        order by sir.id desc
+        limit 1
+        ) as unload_photos,
+        (
+        select sir.gross_weight
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        order by sir.id desc
+        limit 1
+        ) as gross_weight,
+        (
+        select sir.tare_weight
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        order by sir.id desc
+        limit 1
+        ) as tare_weight,
+        (
+        select sir.net_weight
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        order by sir.id desc
+        limit 1
+        ) as net_weight,
+        (
+        select sir.loss_quantity
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        order by sir.id desc
+        limit 1
+        ) as loss_quantity,
+        (
+        select sir.actual_volume
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        order by sir.id desc
+        limit 1
+        ) as actual_volume,
+        (
+        select sir.pound_photos
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        order by sir.id desc
+        limit 1
+        ) as pound_photos
         from (
         select
         si.batch_no,
@@ -222,7 +299,7 @@
         unit,
         product_name,
         product_id
-        order by combined.create_time desc
+        order by create_time desc
     </select>
 
     <select id="listStockInventoryExportData" resultType="com.ruoyi.stock.execl.StockInventoryExportData">
@@ -573,7 +650,382 @@
         MAX(version) as version,
         MAX(remark) as remark,
 
-        'combined' as stockType
+        'combined' as stockType,
+        (
+        select sir.oil_product
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as oil_product,
+        (
+        select sir.tank_inspection_status
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as tank_inspection_status,
+        (
+        select sir.unloading_crane_position
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as unloading_crane_position,
+        (
+        select sir.density
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as density,
+        (
+        select sir.unload_photos
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as unload_photos,
+        (
+        select sir.gross_weight
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as gross_weight,
+        (
+        select sir.tare_weight
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as tare_weight,
+        (
+        select sir.net_weight
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as net_weight,
+        (
+        select sir.loss_quantity
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as loss_quantity,
+        (
+        select sir.actual_volume
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as actual_volume,
+        (
+        select sir.pound_photos
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as pound_photos,
+        (
+        select sor.out_category
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as out_category,
+        (
+        select sor.out_date
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as out_date,
+        (
+        select sor.out_tonnage
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as out_tonnage,
+        (
+        select sor.customer_name
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as out_customer_name,
+        (
+        select sor.loading_inspection_status
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as loading_inspection_status,
+        (
+        select sor.loading_crane_position
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as loading_crane_position,
+        (
+        select sor.density
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as out_density,
+        (
+        select sor.driver_name
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as out_driver_name,
+        (
+        select sor.truck_plate_no
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as out_truck_plate_no,
+        (
+        select sor.loading_photos
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as loading_photos,
+        (
+        select sor.pound_photos
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as out_pound_photos,
+        (
+        select sor.oil_depot_name
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as out_oil_depot_name,
+        (
+        select sor.tank_no
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as out_tank_no,
+        (
+        select sor.oil_product
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as out_oil_product,
+        (
+        select sor.contact_person
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as out_contact_person,
+        (
+        select sor.contact_phone
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as out_contact_phone,
+        (
+        select sor.gross_weight
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as out_gross_weight,
+        (
+        select sor.tare_weight
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as out_tare_weight,
+        (
+        select sor.net_weight
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as out_net_weight,
+        (
+        select sor.loss_quantity
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as out_loss_quantity,
+        (
+        select sor.actual_volume
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as out_actual_volume,
+        (
+        select sor.driver_phone
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as out_driver_phone,
+        (
+        select sor.escort_name
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as out_escort_name,
+        (
+        select sor.escort_phone
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as out_escort_phone,
+        (
+        select sor.trailer_plate_no
+        from stock_out_record sor
+        where sor.product_model_id = combined.product_model_id
+        order by sor.id desc
+        limit 1
+        ) as out_trailer_plate_no,
+        (
+        select sir.oil_depot_name
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as oil_depot_name,
+        (
+        select sir.inbound_category
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as inbound_category,
+        (
+        select sir.tank_no
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as tank_no,
+        (
+        select sir.inbound_time
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as inbound_time,
+        (
+        select sir.original_quantity
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as original_quantity,
+        (
+        select sir.customer_name
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as customer_name,
+        (
+        select sir.contact_person
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as contact_person,
+        (
+        select sir.contact_phone
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as contact_phone,
+        (
+        select sir.driver_name
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as driver_name,
+        (
+        select sir.driver_phone
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as driver_phone,
+        (
+        select sir.escort_name
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as escort_name,
+        (
+        select sir.escort_phone
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as escort_phone,
+        (
+        select sir.truck_plate_no
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as truck_plate_no,
+        (
+        select sir.trailer_plate_no
+        from stock_in_record sir
+        where sir.product_model_id = combined.product_model_id
+        and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null))
+        order by sir.id desc
+        limit 1
+        ) as trailer_plate_no
         from (
         select
         si.batch_no,

--
Gitblit v1.9.3