From d75958896efd4c8a6daee9c56d048641b99cacf6 Mon Sep 17 00:00:00 2001
From: liding <756868258@qq.com>
Date: 星期二, 24 六月 2025 17:54:50 +0800
Subject: [PATCH] 1.二维码巡检记录以及文件上传记录 2.部分优化

---
 main-business/src/main/java/com/ruoyi/business/service/impl/ArchiveServiceImpl.java                            |    1 
 main-business/src/main/java/com/ruoyi/business/service/impl/QrCodeScanRecordServiceImpl.java                   |  189 ++++++++++++++
 main-business/src/main/java/com/ruoyi/business/entity/PurchaseRegistration.java                                |    6 
 main-business/src/main/resources/mapper/QrCodeScanRecordMapper.xml                                             |   28 ++
 main-business/src/main/resources/mapper/PurchaseRegistrationMapper.xml                                         |    1 
 main-business/src/main/java/com/ruoyi/business/mapper/QrCodeMapper.java                                        |   18 +
 main-business/src/main/resources/db/migration/postgresql/V20250624092400__create_table_qr_code_scan_record.sql |   29 ++
 main-business/src/main/java/com/ruoyi/business/service/QrCodeScanRecordService.java                            |   24 +
 main-business/src/main/resources/db/migration/postgresql/V20250604111200__create_table_official_inventory.sql  |    6 
 ruoyi-common/src/main/java/com/ruoyi/common/enums/StorageAttachmentRecordType.java                             |   12 
 main-business/src/main/java/com/ruoyi/business/controller/QrCodeScanRecordController.java                      |   56 ++++
 main-business/src/main/java/com/ruoyi/business/entity/PendingInventory.java                                    |    5 
 main-business/src/main/java/com/ruoyi/business/service/impl/PurchaseRegistrationServiceImpl.java               |    5 
 main-business/src/main/resources/mapper/QrCodeMapper.xml                                                       |   27 ++
 main-business/src/main/resources/db/migration/postgresql/V20250604104500__create_table_pending_inventory.sql   |   42 +-
 main-business/src/main/resources/mapper/PendingInventoryMapper.xml                                             |    4 
 main-business/src/main/java/com/ruoyi/business/controller/QrCodeController.java                                |   55 ++++
 main-business/src/main/java/com/ruoyi/business/service/impl/QrCodeServiceImpl.java                             |   56 ++++
 main-business/src/main/java/com/ruoyi/business/service/impl/SalesRecordServiceImpl.java                        |    6 
 main-business/src/main/java/com/ruoyi/business/dto/QrCodeDto.java                                              |    8 
 main-business/src/main/java/com/ruoyi/business/dto/QrCodeScanRecordDto.java                                    |   19 +
 main-business/src/main/java/com/ruoyi/business/mapper/QrCodeScanRecordMapper.java                              |   18 +
 main-business/src/main/resources/db/migration/postgresql/V20250624092100__create_table_qr_code.sql             |   26 ++
 main-business/src/main/java/com/ruoyi/business/service/QrCodeService.java                                      |   24 +
 main-business/src/main/java/com/ruoyi/business/entity/OfficialInventory.java                                   |    4 
 main-business/src/main/java/com/ruoyi/business/entity/QrCodeScanRecord.java                                    |   43 +++
 main-business/src/main/java/com/ruoyi/business/entity/QrCode.java                                              |   34 ++
 27 files changed, 700 insertions(+), 46 deletions(-)

diff --git a/main-business/src/main/java/com/ruoyi/business/controller/QrCodeController.java b/main-business/src/main/java/com/ruoyi/business/controller/QrCodeController.java
new file mode 100644
index 0000000..b5f313c
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/controller/QrCodeController.java
@@ -0,0 +1,55 @@
+package com.ruoyi.business.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.business.dto.ProductionDto;
+import com.ruoyi.business.dto.QrCodeDto;
+import com.ruoyi.business.entity.Production;
+import com.ruoyi.business.entity.QrCode;
+import com.ruoyi.business.service.QrCodeService;
+import com.ruoyi.common.core.domain.R;
+import org.springframework.web.bind.annotation.*;
+import lombok.AllArgsConstructor;
+
+/**
+ * <p>
+ * 浜岀淮鐮佺鐞嗚〃 鍓嶇鎺у埗鍣�
+ * </p>
+ *
+ * @author ld
+ * @since 2025-06-24
+ */
+
+@RestController
+@AllArgsConstructor
+@RequestMapping("/qrCode")
+public class QrCodeController {
+    
+    private QrCodeService qrCodeService;
+
+    /**
+     * 浜岀淮鐮佺鐞嗚〃鏌ヨ
+     */
+    @GetMapping("/list")
+    public R<IPage<QrCode>> list(Page page, QrCodeDto qrCodeDto) {
+        IPage<QrCode> list = qrCodeService.selectQrCodeList(page, qrCodeDto);
+        return R.ok(list);
+    }
+
+    /**
+     * 浜岀淮鐮佺鐞嗚〃鏂板淇敼
+     */
+    @PostMapping("/addOrEditQrCode")
+    public R<Long> addOrEditQrCode(@RequestBody QrCodeDto qrCodeDto) {
+        return R.ok(qrCodeService.addOrEditQrCode(qrCodeDto));
+    }
+
+    /**
+     * 浜岀淮鐮佺鐞嗚〃鍒犻櫎
+     */
+    @DeleteMapping("/delQrCode")
+    public R remove(@RequestBody Long[] ids) {
+        return R.ok(qrCodeService.delByIds(ids));
+    }
+
+}
diff --git a/main-business/src/main/java/com/ruoyi/business/controller/QrCodeScanRecordController.java b/main-business/src/main/java/com/ruoyi/business/controller/QrCodeScanRecordController.java
new file mode 100644
index 0000000..540b6c9
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/controller/QrCodeScanRecordController.java
@@ -0,0 +1,56 @@
+package com.ruoyi.business.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.business.dto.QrCodeDto;
+import com.ruoyi.business.dto.QrCodeScanRecordDto;
+import com.ruoyi.business.entity.QrCode;
+import com.ruoyi.business.entity.QrCodeScanRecord;
+import com.ruoyi.business.service.QrCodeScanRecordService;
+import com.ruoyi.business.service.QrCodeService;
+import com.ruoyi.common.core.domain.R;
+import org.springframework.web.bind.annotation.*;
+import lombok.AllArgsConstructor;
+
+/**
+ * <p>
+ * 浜岀淮鐮佹壂鐮佽褰曡〃 鍓嶇鎺у埗鍣�
+ * </p>
+ *
+ * @author ld
+ * @since 2025-06-24
+ */
+
+@RestController
+@AllArgsConstructor
+@RequestMapping("/qrCodeScanRecord")
+public class QrCodeScanRecordController {
+
+    private final QrCodeScanRecordService qrCodeScanRecordService;
+
+    /**
+     * 浜岀淮鐮佹壂鐮佽褰曡〃鏌ヨ
+     */
+    @GetMapping("/list")
+    public R<IPage<QrCodeScanRecordDto>> list(Page<QrCodeScanRecord> page, QrCodeScanRecordDto qrCodeScanRecordDto) {
+        IPage<QrCodeScanRecordDto> list = qrCodeScanRecordService.selectQrCodeScanRecordList(page, qrCodeScanRecordDto);
+        return R.ok(list);
+    }
+
+    /**
+     * 浜岀淮鐮佹壂鐮佽褰曡〃鏂板淇敼
+     */
+    @PostMapping("/addOrEditQrCodeRecord")
+    public R addOrEditQrCodeRecord(@RequestBody QrCodeScanRecordDto qrCodeScanRecordDto) {
+        return R.ok(qrCodeScanRecordService.addOrEditQrCodeRecord(qrCodeScanRecordDto));
+    }
+
+    /**
+     * 浜岀淮鐮佹壂鐮佽褰曡〃鍒犻櫎
+     */
+    @DeleteMapping("/delSalesRecord")
+    public R remove(@RequestBody Long[] ids) {
+        return R.ok(qrCodeScanRecordService.delByIds(ids));
+    }
+
+}
diff --git a/main-business/src/main/java/com/ruoyi/business/dto/QrCodeDto.java b/main-business/src/main/java/com/ruoyi/business/dto/QrCodeDto.java
new file mode 100644
index 0000000..21d23e9
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/dto/QrCodeDto.java
@@ -0,0 +1,8 @@
+package com.ruoyi.business.dto;
+
+import com.ruoyi.business.entity.QrCode;
+import lombok.Data;
+
+@Data
+public class QrCodeDto extends QrCode {
+}
diff --git a/main-business/src/main/java/com/ruoyi/business/dto/QrCodeScanRecordDto.java b/main-business/src/main/java/com/ruoyi/business/dto/QrCodeScanRecordDto.java
new file mode 100644
index 0000000..f3758ff
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/dto/QrCodeScanRecordDto.java
@@ -0,0 +1,19 @@
+package com.ruoyi.business.dto;
+
+import com.ruoyi.basic.entity.dto.StorageBlobDTO;
+import com.ruoyi.business.entity.QrCode;
+import com.ruoyi.business.entity.QrCodeScanRecord;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class QrCodeScanRecordDto extends QrCodeScanRecord {
+
+    private QrCode qrCode;
+
+    private String scanner;
+
+    private List<StorageBlobDTO> storageBlobDTO;
+
+}
diff --git a/main-business/src/main/java/com/ruoyi/business/entity/OfficialInventory.java b/main-business/src/main/java/com/ruoyi/business/entity/OfficialInventory.java
index 49fa6da..034e377 100644
--- a/main-business/src/main/java/com/ruoyi/business/entity/OfficialInventory.java
+++ b/main-business/src/main/java/com/ruoyi/business/entity/OfficialInventory.java
@@ -40,8 +40,8 @@
     /**
      * 鐓ょ
      */
-    @TableField(value = "coal")
-    private String coal;
+    @TableField(value = "coal_id")
+    private Long coalId;
     /**
      * 鍗曚綅
      */
diff --git a/main-business/src/main/java/com/ruoyi/business/entity/PendingInventory.java b/main-business/src/main/java/com/ruoyi/business/entity/PendingInventory.java
index f4210cc..ec91e00 100644
--- a/main-business/src/main/java/com/ruoyi/business/entity/PendingInventory.java
+++ b/main-business/src/main/java/com/ruoyi/business/entity/PendingInventory.java
@@ -38,6 +38,11 @@
     @TableField(value = "supplier_name")
     private String supplierName;
     /**
+     * 渚涜揣鍟嗗悕绉�
+     */
+    @TableField(value = "supplier_id")
+    private Long supplierId;
+    /**
      * 鐓ょ
      */
     @TableField(value = "coal_id")
diff --git a/main-business/src/main/java/com/ruoyi/business/entity/PurchaseRegistration.java b/main-business/src/main/java/com/ruoyi/business/entity/PurchaseRegistration.java
index 4a7c3ac..1cee4a2 100644
--- a/main-business/src/main/java/com/ruoyi/business/entity/PurchaseRegistration.java
+++ b/main-business/src/main/java/com/ruoyi/business/entity/PurchaseRegistration.java
@@ -47,11 +47,7 @@
      */
     @TableField(value = "coal_id")
     private Long coalId;
-    /**
-     * 鐓ょ绫诲瀷
-     */
-    @TableField(value = "coal")
-    private String coal;
+
     /**
      * 閲囪喘鏁伴噺
      */
diff --git a/main-business/src/main/java/com/ruoyi/business/entity/QrCode.java b/main-business/src/main/java/com/ruoyi/business/entity/QrCode.java
new file mode 100644
index 0000000..446163d
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/entity/QrCode.java
@@ -0,0 +1,34 @@
+package com.ruoyi.business.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import com.ruoyi.common.core.domain.MyBaseEntity;
+
+/**
+ * 浜岀淮鐮佺鐞嗚〃 瀹炰綋绫�
+ *
+ * @author ld
+ * @date 2025-06-24
+ */
+@Data
+@TableName("qr_code")
+public class QrCode extends MyBaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 浜岀淮鐮佸敮涓�鏍囪瘑
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+    /**
+     * 璁惧鍚嶇О
+     */
+    @TableField(value = "device_name")
+    private String deviceName;
+    /**
+     * 鎵�鍦ㄤ綅缃弿杩�
+     */
+    @TableField(value = "location")
+    private String location;
+}
\ No newline at end of file
diff --git a/main-business/src/main/java/com/ruoyi/business/entity/QrCodeScanRecord.java b/main-business/src/main/java/com/ruoyi/business/entity/QrCodeScanRecord.java
new file mode 100644
index 0000000..32a0d38
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/entity/QrCodeScanRecord.java
@@ -0,0 +1,43 @@
+package com.ruoyi.business.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import com.ruoyi.common.core.domain.MyBaseEntity;
+
+import java.time.LocalDateTime;
+
+/**
+ * 浜岀淮鐮佹壂鐮佽褰曡〃 瀹炰綋绫�
+ *
+ * @author ld
+ * @date 2025-06-24
+ */
+@Data
+@TableName("qr_code_scan_record")
+public class QrCodeScanRecord extends MyBaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鎵爜璁板綍鍞竴鏍囪瘑
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+    /**
+     * 鍏宠仈鐨勪簩缁寸爜ID
+     */
+    @TableField(value = "qr_code_id")
+    private Long qrCodeId;
+    /**
+     * 鎵爜浜虹敤鎴稩D
+     */
+    @TableField(value = "scanner_id")
+    private Long scannerId;
+    /**
+     * 瀹為檯鎵爜鏃堕棿
+     */
+    @TableField(value = "scan_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime scanTime;
+}
\ No newline at end of file
diff --git a/main-business/src/main/java/com/ruoyi/business/mapper/QrCodeMapper.java b/main-business/src/main/java/com/ruoyi/business/mapper/QrCodeMapper.java
new file mode 100644
index 0000000..436ff91
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/mapper/QrCodeMapper.java
@@ -0,0 +1,18 @@
+package com.ruoyi.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.business.entity.QrCode;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 浜岀淮鐮佺鐞嗚〃 Mapper 鎺ュ彛
+ * </p>
+ *
+ * @author ld
+ * @since 2025-06-24
+ */
+@Mapper
+public interface QrCodeMapper extends BaseMapper<QrCode> {
+
+}
diff --git a/main-business/src/main/java/com/ruoyi/business/mapper/QrCodeScanRecordMapper.java b/main-business/src/main/java/com/ruoyi/business/mapper/QrCodeScanRecordMapper.java
new file mode 100644
index 0000000..fcabe69
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/mapper/QrCodeScanRecordMapper.java
@@ -0,0 +1,18 @@
+package com.ruoyi.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.business.entity.QrCodeScanRecord;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 浜岀淮鐮佹壂鐮佽褰曡〃 Mapper 鎺ュ彛
+ * </p>
+ *
+ * @author ld
+ * @since 2025-06-24
+ */
+@Mapper
+public interface QrCodeScanRecordMapper extends BaseMapper<QrCodeScanRecord> {
+
+}
diff --git a/main-business/src/main/java/com/ruoyi/business/service/QrCodeScanRecordService.java b/main-business/src/main/java/com/ruoyi/business/service/QrCodeScanRecordService.java
new file mode 100644
index 0000000..4b1f5e5
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/service/QrCodeScanRecordService.java
@@ -0,0 +1,24 @@
+package com.ruoyi.business.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.business.dto.QrCodeScanRecordDto;
+import com.ruoyi.business.entity.QrCodeScanRecord;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 浜岀淮鐮佹壂鐮佽褰曡〃 鏈嶅姟绫�
+ * </p>
+ *
+ * @author ld
+ * @since 2025-06-24
+ */
+public interface QrCodeScanRecordService extends IService<QrCodeScanRecord> {
+
+    IPage<QrCodeScanRecordDto> selectQrCodeScanRecordList(Page<QrCodeScanRecord> page, QrCodeScanRecordDto qrCodeScanRecordDto);
+
+    int addOrEditQrCodeRecord(QrCodeScanRecordDto qrCodeScanRecordDto);
+
+    int delByIds(Long[] ids);
+}
diff --git a/main-business/src/main/java/com/ruoyi/business/service/QrCodeService.java b/main-business/src/main/java/com/ruoyi/business/service/QrCodeService.java
new file mode 100644
index 0000000..f0fcdb0
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/service/QrCodeService.java
@@ -0,0 +1,24 @@
+package com.ruoyi.business.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.business.dto.QrCodeDto;
+import com.ruoyi.business.entity.QrCode;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 浜岀淮鐮佺鐞嗚〃 鏈嶅姟绫�
+ * </p>
+ *
+ * @author ld
+ * @since 2025-06-24
+ */
+public interface QrCodeService extends IService<QrCode> {
+
+    IPage<QrCode> selectQrCodeList(Page page, QrCodeDto qrCodeDto);
+
+    Long addOrEditQrCode(QrCodeDto qrCodeDto);
+
+    int delByIds(Long[] ids);
+}
diff --git a/main-business/src/main/java/com/ruoyi/business/service/impl/ArchiveServiceImpl.java b/main-business/src/main/java/com/ruoyi/business/service/impl/ArchiveServiceImpl.java
index 7443026..d0638f9 100644
--- a/main-business/src/main/java/com/ruoyi/business/service/impl/ArchiveServiceImpl.java
+++ b/main-business/src/main/java/com/ruoyi/business/service/impl/ArchiveServiceImpl.java
@@ -48,6 +48,7 @@
     private final StorageBlobMapper storageBlobMapper;
 
     private final StorageAttachmentMapper storageAttachmentMapper;
+
     private final MinioUtils minioUtils;
 
 
diff --git a/main-business/src/main/java/com/ruoyi/business/service/impl/PurchaseRegistrationServiceImpl.java b/main-business/src/main/java/com/ruoyi/business/service/impl/PurchaseRegistrationServiceImpl.java
index ed6177c..51c2d14 100644
--- a/main-business/src/main/java/com/ruoyi/business/service/impl/PurchaseRegistrationServiceImpl.java
+++ b/main-business/src/main/java/com/ruoyi/business/service/impl/PurchaseRegistrationServiceImpl.java
@@ -52,7 +52,7 @@
         LambdaQueryWrapper<PurchaseRegistration> queryWrapper = new LambdaQueryWrapper<>();
         if (StringUtils.isNotBlank(purchaseRegistrationDto.getSearchAll())){
             queryWrapper.and(wrapper -> wrapper
-                    .like(PurchaseRegistration::getCoal, purchaseRegistrationDto.getSearchAll())
+                    .like(PurchaseRegistration::getCoalId, purchaseRegistrationDto.getSearchAll())
                     .or()
                     .like(PurchaseRegistration::getSupplierName, purchaseRegistrationDto.getSearchAll())
             );
@@ -74,7 +74,7 @@
         if (coalInfo == null) {
             throw new BaseException("鐓ょ淇℃伅涓嶅瓨鍦�");
         }
-        purchaseRegistration.setCoal(coalInfo.getCoal());
+//        purchaseRegistration.setCoal(coalInfo.getCoal());
         Supply supply = supplyMapper.selectById(purchaseRegistrationDto.getSupplierId());
         if (supply == null) {
             throw new BaseException("渚涘簲鍟嗕俊鎭笉瀛樺湪");
@@ -109,6 +109,7 @@
         BeanUtils.copyProperties(purchaseRegistration, pendingInventory);
 
         // 璁剧疆寰呭叆搴撹褰曠壒鏈夌殑灞炴�э紙濡傛灉鏈夛級
+        pendingInventory.setCoalId(purchaseRegistration.getCoalId());
         pendingInventory.setInventoryQuantity(purchaseRegistration.getPurchaseQuantity());
         return pendingInventory;
     }
diff --git a/main-business/src/main/java/com/ruoyi/business/service/impl/QrCodeScanRecordServiceImpl.java b/main-business/src/main/java/com/ruoyi/business/service/impl/QrCodeScanRecordServiceImpl.java
new file mode 100644
index 0000000..5091efa
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/service/impl/QrCodeScanRecordServiceImpl.java
@@ -0,0 +1,189 @@
+package com.ruoyi.business.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.basic.entity.StorageAttachment;
+import com.ruoyi.basic.entity.StorageBlob;
+import com.ruoyi.basic.entity.dto.StorageBlobDTO;
+import com.ruoyi.basic.mapper.StorageAttachmentMapper;
+import com.ruoyi.basic.mapper.StorageBlobMapper;
+import com.ruoyi.basic.service.StorageAttachmentService;
+import com.ruoyi.business.dto.QrCodeDto;
+import com.ruoyi.business.dto.QrCodeScanRecordDto;
+import com.ruoyi.business.entity.Archive;
+import com.ruoyi.business.entity.QrCode;
+import com.ruoyi.business.entity.QrCodeScanRecord;
+import com.ruoyi.business.mapper.QrCodeMapper;
+import com.ruoyi.business.mapper.QrCodeScanRecordMapper;
+import com.ruoyi.business.service.QrCodeScanRecordService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.utils.bean.BeanUtils;
+import com.ruoyi.common.utils.file.MinioUtils;
+import com.ruoyi.system.mapper.SysUserMapper;
+import org.springframework.stereotype.Service;
+import lombok.RequiredArgsConstructor;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import static com.ruoyi.common.constant.StorageAttachmentConstants.StorageAttachmentFile;
+import static com.ruoyi.common.enums.StorageAttachmentRecordType.Archives;
+import static com.ruoyi.common.enums.StorageAttachmentRecordType.QrCodeScanRecords;
+
+/**
+ * <p>
+ * 浜岀淮鐮佹壂鐮佽褰曡〃 鏈嶅姟瀹炵幇绫�
+ * </p>
+ *
+ * @author ld
+ * @since 2025-06-24
+ */
+@Service
+@RequiredArgsConstructor
+public class QrCodeScanRecordServiceImpl extends ServiceImpl<QrCodeScanRecordMapper, QrCodeScanRecord> implements QrCodeScanRecordService {
+
+    private final QrCodeScanRecordMapper qrCodeScanRecordMapper;
+
+    private final QrCodeMapper qrCodeMapper;
+
+    private final StorageAttachmentService storageAttachmentService;
+
+    private final StorageBlobMapper storageBlobMapper;
+
+    private final StorageAttachmentMapper storageAttachmentMapper;
+
+    private final MinioUtils minioUtils;
+
+    private final SysUserMapper sysUserMapper;
+
+    @Override
+    public IPage<QrCodeScanRecordDto> selectQrCodeScanRecordList(Page<QrCodeScanRecord> page, QrCodeScanRecordDto qrCodeScanRecordDto) {
+        // 1. 鏋勫缓鍩虹鏌ヨ鏉′欢
+        LambdaQueryWrapper<QrCodeScanRecord> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.orderByDesc(QrCodeScanRecord::getCreateTime);
+
+        // 2. 鎵ц鍒嗛〉鏌ヨ
+        IPage<QrCodeScanRecord> scanRecordIPage = qrCodeScanRecordMapper.selectPage(page, queryWrapper);
+
+        // 3. 鏃犳暟鎹彁鍓嶈繑鍥�
+        if (CollectionUtils.isEmpty(scanRecordIPage.getRecords())) {
+            return new Page<>(scanRecordIPage.getCurrent(), scanRecordIPage.getSize(), scanRecordIPage.getTotal());
+        }
+
+        // 4. 鎵归噺鑾峰彇鎵�鏈夎褰旾D鍜屼簩缁寸爜ID
+        List<Long> recordIds = scanRecordIPage.getRecords().stream()
+                .map(QrCodeScanRecord::getId)
+                .collect(Collectors.toList());
+
+        Set<Long> qrCodeIds = scanRecordIPage.getRecords().stream()
+                .map(QrCodeScanRecord::getQrCodeId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+
+        // 5. 鎵归噺鏌ヨ鍏宠仈鏁版嵁锛堜娇鐢ㄦ渶鏂癆PI锛�
+        // 5.1 鏌ヨ浜岀淮鐮佷俊鎭紙鏇挎崲selectBatchIds涓簊electByIds锛�
+        Map<Long, QrCode> qrCodeMap = qrCodeIds.isEmpty()
+                ? Collections.emptyMap()
+                : qrCodeMapper.selectByIds(qrCodeIds).stream()
+                .collect(Collectors.toMap(QrCode::getId, Function.identity()));
+
+        // 5.2 鏌ヨ闄勪欢鍏宠仈鍏崇郴
+        Map<Long, List<StorageAttachment>> attachmentsMap = storageAttachmentMapper
+                .selectList(new LambdaQueryWrapper<StorageAttachment>()
+                        .in(StorageAttachment::getRecordId, recordIds)
+                        .eq(StorageAttachment::getRecordType, QrCodeScanRecords.ordinal()))
+                .stream()
+                .collect(Collectors.groupingBy(StorageAttachment::getRecordId));
+
+        // 5.3 鏌ヨ鏂囦欢鏁版嵁锛堜娇鐢╯electByIds锛�
+        Set<Long> blobIds = attachmentsMap.values().stream()
+                .flatMap(List::stream)
+                .map(StorageAttachment::getStorageBlobId)
+                .collect(Collectors.toSet());
+
+        Map<Long, StorageBlob> blobMap = blobIds.isEmpty()
+                ? Collections.emptyMap()
+                : storageBlobMapper.selectByIds(blobIds).stream()
+                .collect(Collectors.toMap(StorageBlob::getId, Function.identity()));
+
+        // 6. 缁勮DTO鏁版嵁
+        List<QrCodeScanRecordDto> dtoList = scanRecordIPage.getRecords().stream().map(record -> {
+            QrCodeScanRecordDto dto = new QrCodeScanRecordDto();
+            BeanUtils.copyProperties(record, dto);
+
+            SysUser sysUser = sysUserMapper.selectUserById(record.getScannerId());
+            dto.setScanner(sysUser.getNickName());
+
+            // 6.1 璁剧疆浜岀淮鐮佷俊鎭�
+            Optional.ofNullable(qrCodeMap.get(record.getQrCodeId()))
+                    .ifPresent(qrCode -> {
+                        BeanUtils.copyProperties(qrCode, dto); // 澶嶅埗鍒扮埗绫�
+                        dto.setQrCode(qrCode); // 璁剧疆瀹屾暣瀵硅薄
+                    });
+
+            // 6.2 璁剧疆闄勪欢淇℃伅
+            dto.setStorageBlobDTO(
+                    Optional.ofNullable(attachmentsMap.get(record.getId()))
+                            .orElse(Collections.emptyList())
+                            .stream()
+                            .map(att -> {
+                                StorageBlobDTO blobDTO = new StorageBlobDTO();
+                                Optional.ofNullable(blobMap.get(att.getStorageBlobId()))
+                                        .ifPresent(blob -> {
+                                            BeanUtils.copyProperties(blob, blobDTO);
+                                            blobDTO.setUrl(minioUtils.getPreviewUrls(blob.getBucketFilename(), blob.getBucketName(), true));
+                                            blobDTO.setDownloadUrl(minioUtils.getDownloadUrls(blob.getBucketFilename(),blob.getBucketName(),blob.getOriginalFilename(),true));
+                                        });
+                                return blobDTO;
+                            })
+                            .filter(blobDTO -> blobDTO.getId() != null) // 杩囨护鏃犳晥闄勪欢
+                            .collect(Collectors.toList())
+            );
+            return dto;
+        }).collect(Collectors.toList());
+
+        // 7. 鏋勫缓杩斿洖鍒嗛〉瀵硅薄
+        IPage<QrCodeScanRecordDto> resultPage = new Page<>();
+        BeanUtils.copyProperties(scanRecordIPage, resultPage);
+        resultPage.setRecords(dtoList);
+
+        return resultPage;
+    }
+
+    @Override
+    public int addOrEditQrCodeRecord(QrCodeScanRecordDto qrCodeScanRecordDto) {
+        QrCodeScanRecord qrCodeScanRecord = new QrCodeScanRecord();
+        BeanUtils.copyProperties(qrCodeScanRecordDto, qrCodeScanRecord);
+        int i;
+        if (Objects.isNull(qrCodeScanRecordDto.getId())) {
+            i = qrCodeScanRecordMapper.insert(qrCodeScanRecord);
+        } else {
+            i = qrCodeScanRecordMapper.updateById(qrCodeScanRecord);
+        }
+
+        if (qrCodeScanRecordDto.getStorageBlobDTO() != null && !qrCodeScanRecordDto.getStorageBlobDTO().isEmpty()) {
+            List<StorageAttachment> attachments = new ArrayList<>();
+
+            for (StorageBlobDTO storageBlobDTO : qrCodeScanRecordDto.getStorageBlobDTO()) {
+                StorageAttachment storageAttachment = new StorageAttachment(
+                        StorageAttachmentFile,
+                        (long) QrCodeScanRecords.ordinal(),
+                        qrCodeScanRecord.getId()
+                );
+                storageAttachment.setStorageBlobDTO(storageBlobDTO);
+                attachments.add(storageAttachment);
+            }
+            storageAttachmentService.saveStorageAttachment(attachments, qrCodeScanRecord.getId(), QrCodeScanRecords, StorageAttachmentFile);
+        }
+        return i;
+    }
+
+    @Override
+    public int delByIds(Long[] ids) {
+        return qrCodeScanRecordMapper.deleteByIds(Arrays.asList(ids));
+    }
+}
diff --git a/main-business/src/main/java/com/ruoyi/business/service/impl/QrCodeServiceImpl.java b/main-business/src/main/java/com/ruoyi/business/service/impl/QrCodeServiceImpl.java
new file mode 100644
index 0000000..9f0d316
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/service/impl/QrCodeServiceImpl.java
@@ -0,0 +1,56 @@
+package com.ruoyi.business.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.ruoyi.business.dto.QrCodeDto;
+import com.ruoyi.business.entity.Production;
+import com.ruoyi.business.entity.QrCode;
+import com.ruoyi.business.mapper.QrCodeMapper;
+import com.ruoyi.business.service.QrCodeService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.utils.bean.BeanUtils;
+import org.springframework.stereotype.Service;
+import lombok.RequiredArgsConstructor;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * <p>
+ * 浜岀淮鐮佺鐞嗚〃 鏈嶅姟瀹炵幇绫�
+ * </p>
+ *
+ * @author ld
+ * @since 2025-06-24
+ */
+@Service
+@RequiredArgsConstructor
+public class QrCodeServiceImpl extends ServiceImpl<QrCodeMapper, QrCode> implements QrCodeService {
+
+    private final QrCodeMapper qrCodeMapper;
+
+    @Override
+    public IPage<QrCode> selectQrCodeList(Page page, QrCodeDto qrCodeDto) {
+        LambdaQueryWrapper<QrCode> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.orderByDesc(QrCode::getCreateTime);
+        return qrCodeMapper.selectPage(page, queryWrapper);
+    }
+
+    @Override
+    public Long addOrEditQrCode(QrCodeDto qrCodeDto) {
+        QrCode qrCode = new QrCode();
+        BeanUtils.copyProperties(qrCodeDto, qrCode);
+        if (Objects.isNull(qrCodeDto.getId())) {
+            qrCodeMapper.insert(qrCode);
+        } else {
+            qrCodeMapper.updateById(qrCode);
+        }
+        return qrCode.getId();
+    }
+
+    @Override
+    public int delByIds(Long[] ids) {
+        return qrCodeMapper.deleteByIds(Arrays.asList(ids));
+    }
+}
diff --git a/main-business/src/main/java/com/ruoyi/business/service/impl/SalesRecordServiceImpl.java b/main-business/src/main/java/com/ruoyi/business/service/impl/SalesRecordServiceImpl.java
index 118561a..8d2899c 100644
--- a/main-business/src/main/java/com/ruoyi/business/service/impl/SalesRecordServiceImpl.java
+++ b/main-business/src/main/java/com/ruoyi/business/service/impl/SalesRecordServiceImpl.java
@@ -69,7 +69,7 @@
         officialInventoryMapper.updateById(officialInventory);
 
         // 鏋勫缓閿�鍞褰曞疄浣�
-        SalesRecord salesRecord = buildSalesRecord(salesRecordDto,officialInventory.getCoal());
+        SalesRecord salesRecord = buildSalesRecord(salesRecordDto,officialInventory.getCoalId());
 
         // 澶勭悊鏂板/鏇存柊閫昏緫
         if (salesRecordDto.getId() == null) {
@@ -94,7 +94,7 @@
         }
     }
 
-    private SalesRecord buildSalesRecord(SalesRecordDto dto,String coal) {
+    private SalesRecord buildSalesRecord(SalesRecordDto dto,Long coalId) {
         SalesRecord record = new SalesRecord();
         BeanUtils.copyProperties(dto, record);
 
@@ -129,7 +129,7 @@
         }
 
         // 鐓ょ
-        record.setCoal(coal);
+        record.setCoalId(coalId);
 
         return record;
     }
diff --git a/main-business/src/main/resources/db/migration/postgresql/V20250604104500__create_table_pending_inventory.sql b/main-business/src/main/resources/db/migration/postgresql/V20250604104500__create_table_pending_inventory.sql
index 97c44c1..f686498 100644
--- a/main-business/src/main/resources/db/migration/postgresql/V20250604104500__create_table_pending_inventory.sql
+++ b/main-business/src/main/resources/db/migration/postgresql/V20250604104500__create_table_pending_inventory.sql
@@ -1,27 +1,28 @@
 -- 鍒涘缓寰呭叆搴撹〃
 CREATE TABLE pending_inventory
 (
-    id                         BIGSERIAL PRIMARY KEY,                            -- 涓婚敭ID
-    supplier_name              VARCHAR(255)               NOT NULL,              -- 渚涜揣鍟嗗悕绉�
-    coal                       VARCHAR(50)                NOT NULL,              -- 鐓ょ
-    unit                       VARCHAR(50)                NOT NULL,              -- 鍗曚綅
-    inventory_quantity         NUMERIC(10,2)              NOT NULL,              -- 搴撳瓨鏁伴噺
-    price_including_tax        NUMERIC(10,2)              NOT NULL,              -- 鍗曚环锛堝惈绋庯級
-    total_price_including_tax  NUMERIC(10,2)              NOT NULL,              -- 鎬讳环锛堝惈绋庯級
-    registrant                 VARCHAR(50),                                      -- 鐧昏浜�
-    registration_time          TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP,          -- 鐧昏鏃堕棿
-    price_excluding_tax        VARCHAR(255),                                     -- 鍗曚环锛堜笉鍚◣锛�
-    total_price_excluding_tax  VARCHAR(255),                                     -- 鎬讳环锛堜笉鍚◣锛�
-    registrant_id              VARCHAR(32),                                      -- 鐧昏浜篒D
-    registration_date          DATE,                                             -- 鐧昏鏃ユ湡
-    supplier_id                BIGINT,                                           -- 渚涜揣鍟咺D
-    coal_id                    BIGINT,                                            -- 鐓ょID
+    id                        BIGSERIAL PRIMARY KEY,                  -- 涓婚敭ID
+    supplier_name             VARCHAR(255)   NOT NULL,                -- 渚涜揣鍟嗗悕绉�
+    coal                      VARCHAR(50)    NOT NULL,                -- 鐓ょ
+    unit                      VARCHAR(50)    NOT NULL,                -- 鍗曚綅
+    inventory_quantity        NUMERIC(10, 2) NOT NULL,                -- 搴撳瓨鏁伴噺
+    price_including_tax       NUMERIC(10, 2) NOT NULL,                -- 鍗曚环锛堝惈绋庯級
+    total_price_including_tax NUMERIC(10, 2) NOT NULL,                -- 鎬讳环锛堝惈绋庯級
+    registrant                VARCHAR(50),                            -- 鐧昏浜�
+    registration_time         TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP, -- 鐧昏鏃堕棿
+    price_excluding_tax       VARCHAR(255),                           -- 鍗曚环锛堜笉鍚◣锛�
+    total_price_excluding_tax VARCHAR(255),                           -- 鎬讳环锛堜笉鍚◣锛�
+    registrant_id             VARCHAR(32),                            -- 鐧昏浜篒D
+    registration_date         DATE,                                   -- 鐧昏鏃ユ湡
+    supplier_id               BIGINT,                                 -- 渚涜揣鍟咺D
+    coal_id                   BIGINT,                                 -- 鐓ょID
+    master_id                 BIGINT,                                 -- 鐢熶骇鍔犲伐id
 
-    deleted                    INTEGER         DEFAULT 0,                        -- 杞垹闄ゆ爣蹇楋紝0=鏈垹闄わ紝1=宸插垹闄�
-    create_by                  VARCHAR(255),                                     -- 鍒涘缓璇ヨ褰曠殑鐢ㄦ埛
-    create_time                TIMESTAMP(6),                                     -- 璁板綍鍒涘缓鏃堕棿
-    update_by                  VARCHAR(255),                                     -- 鏈�鍚庝慨鏀硅璁板綍鐨勭敤鎴�
-    update_time                TIMESTAMP(6)                                     -- 璁板綍鏈�鍚庢洿鏂版椂闂�
+    deleted                   INTEGER      DEFAULT 0,                 -- 杞垹闄ゆ爣蹇楋紝0=鏈垹闄わ紝1=宸插垹闄�
+    create_by                 VARCHAR(255),                           -- 鍒涘缓璇ヨ褰曠殑鐢ㄦ埛
+    create_time               TIMESTAMP(6),                           -- 璁板綍鍒涘缓鏃堕棿
+    update_by                 VARCHAR(255),                           -- 鏈�鍚庝慨鏀硅璁板綍鐨勭敤鎴�
+    update_time               TIMESTAMP(6)                            -- 璁板綍鏈�鍚庢洿鏂版椂闂�
 
 );
 
@@ -43,6 +44,7 @@
 COMMENT ON COLUMN pending_inventory.registration_date IS '鐧昏鏃ユ湡';
 COMMENT ON COLUMN pending_inventory.supplier_id IS '渚涜揣鍟咺D';
 COMMENT ON COLUMN pending_inventory.coal_id IS '鐓ょID';
+COMMENT ON COLUMN pending_inventory.master_id IS '鐢熶骇鍔犲伐id';
 
 COMMENT ON COLUMN pending_inventory.deleted IS '杞垹闄ゆ爣蹇楋紝0=鏈垹闄わ紝1=宸插垹闄�';
 COMMENT ON COLUMN pending_inventory.create_by IS '鍒涘缓璇ヨ褰曠殑鐢ㄦ埛';
diff --git a/main-business/src/main/resources/db/migration/postgresql/V20250604111200__create_table_official_inventory.sql b/main-business/src/main/resources/db/migration/postgresql/V20250604111200__create_table_official_inventory.sql
index 433afe9..d9562f7 100644
--- a/main-business/src/main/resources/db/migration/postgresql/V20250604111200__create_table_official_inventory.sql
+++ b/main-business/src/main/resources/db/migration/postgresql/V20250604111200__create_table_official_inventory.sql
@@ -3,7 +3,7 @@
 (
     id                        BIGSERIAL PRIMARY KEY,             -- 涓婚敭ID
     supplier_name             VARCHAR(255)   NOT NULL,           -- 渚涜揣鍟嗗悕绉�
-    coal                      VARCHAR(50)    NOT NULL,           -- 鐓ょ
+    coal_id                   BIGINT         NOT NULL,           -- 鐓ょ
     unit                      VARCHAR(50)    NOT NULL,           -- 鍗曚綅
     inventory_quantity        DECIMAL(10, 0),                    -- 搴撳瓨鏁伴噺
     price_including_tax       DECIMAL(10, 2) NOT NULL,           -- 鍗曚环锛堝惈绋庯級
@@ -14,7 +14,7 @@
     registrant_id             VARCHAR(50)    NOT NULL,           -- 鐧昏浜篿d
     type                      VARCHAR(50),                       -- 绫诲瀷       1 閲囪喘/ 2 姝e紡   鍏ュ簱
     pending_id                BIGINT,                            -- 寰呭叆搴搃d
-    merge_id                  VARCHAR(255),                            -- 鍚堝苟id
+    merge_id                  VARCHAR(255),                      -- 鍚堝苟id
     registration_date         TIMESTAMP WITHOUT TIME ZONE,
 
     deleted                   INT            NOT NULL DEFAULT 0, -- 杞垹闄ゆ爣蹇楋細0=鏈垹闄わ紝1=宸插垹闄�
@@ -30,7 +30,7 @@
 -- 娣诲姞瀛楁娉ㄩ噴
 COMMENT ON COLUMN official_inventory.id IS '涓婚敭ID';
 COMMENT ON COLUMN official_inventory.supplier_name IS '渚涜揣鍟嗗悕绉�';
-COMMENT ON COLUMN official_inventory.coal IS '鐓ょ';
+COMMENT ON COLUMN official_inventory.coal_id IS '鐓ょid';
 COMMENT ON COLUMN official_inventory.unit IS '鍗曚綅';
 COMMENT ON COLUMN official_inventory.inventory_quantity IS '搴撳瓨鏁伴噺';
 COMMENT ON COLUMN official_inventory.price_including_tax IS '鍗曚环锛堝惈绋庯級';
diff --git a/main-business/src/main/resources/db/migration/postgresql/V20250624092100__create_table_qr_code.sql b/main-business/src/main/resources/db/migration/postgresql/V20250624092100__create_table_qr_code.sql
new file mode 100644
index 0000000..d7364fa
--- /dev/null
+++ b/main-business/src/main/resources/db/migration/postgresql/V20250624092100__create_table_qr_code.sql
@@ -0,0 +1,26 @@
+-- 鍒涘缓浜岀淮鐮佺鐞嗚〃
+CREATE TABLE qr_code
+(
+    id            BIGSERIAL PRIMARY KEY,       -- ID (涓婚敭锛岃嚜澧為暱)
+    device_name   VARCHAR(255),                -- 璁惧鍚嶇О
+    location      VARCHAR(255),                        -- 鍦扮偣
+
+    deleted       INT NOT NULL DEFAULT 0,      -- 杞垹闄ゆ爣蹇楋細0=鏈垹闄わ紝1=宸插垹闄�
+    create_by     VARCHAR(255),                -- 鍒涘缓浜虹敤鎴峰悕
+    create_time   TIMESTAMP WITHOUT TIME ZONE, -- 鍒涘缓鏃堕棿锛岄粯璁ゅ綋鍓嶆椂闂�
+    update_by     VARCHAR(255),                -- 鏈�鍚庢洿鏂颁汉鐢ㄦ埛鍚�
+    update_time   TIMESTAMP WITHOUT TIME ZONE  -- 鏈�鍚庢洿鏂版椂闂达紝榛樿褰撳墠鏃堕棿
+);
+-- 娣诲姞琛ㄦ敞閲�
+COMMENT ON TABLE qr_code IS '浜岀淮鐮佺鐞嗚〃';
+
+-- 娣诲姞瀛楁娉ㄩ噴
+COMMENT ON COLUMN qr_code.id IS '浜岀淮鐮佸敮涓�鏍囪瘑';
+COMMENT ON COLUMN qr_code.device_name IS '璁惧鍚嶇О';
+COMMENT ON COLUMN qr_code.location IS '鎵�鍦ㄤ綅缃弿杩�';
+
+COMMENT ON COLUMN qr_code.deleted IS '杞垹闄ゆ爣蹇楋紝0=鏈垹闄わ紝1=宸插垹闄�';
+COMMENT ON COLUMN qr_code.create_by IS '鍒涘缓璇ヨ褰曠殑鐢ㄦ埛';
+COMMENT ON COLUMN qr_code.create_time IS '璁板綍鍒涘缓鏃堕棿';
+COMMENT ON COLUMN qr_code.update_by IS '鏈�鍚庝慨鏀硅璁板綍鐨勭敤鎴�';
+COMMENT ON COLUMN qr_code.update_time IS '璁板綍鏈�鍚庢洿鏂版椂闂�';
\ No newline at end of file
diff --git a/main-business/src/main/resources/db/migration/postgresql/V20250624092400__create_table_qr_code_scan_record.sql b/main-business/src/main/resources/db/migration/postgresql/V20250624092400__create_table_qr_code_scan_record.sql
new file mode 100644
index 0000000..9de37ec
--- /dev/null
+++ b/main-business/src/main/resources/db/migration/postgresql/V20250624092400__create_table_qr_code_scan_record.sql
@@ -0,0 +1,29 @@
+-- 鍒涘缓浜岀淮鐮佹壂鐮佽褰曡〃
+CREATE TABLE qr_code_scan_record
+(
+    id            BIGSERIAL PRIMARY KEY,       -- ID (涓婚敭锛岃嚜澧為暱)
+    qr_code_id    BIGINT,                      -- 鍏宠仈鐨勪簩缁寸爜ID
+    scanner_id    BIGINT,                      -- 鎵爜浜篒D
+    scan_time     TIMESTAMP WITHOUT TIME ZONE, -- 鎵爜鏃堕棿
+
+    deleted       INT NOT NULL DEFAULT 0,      -- 杞垹闄ゆ爣蹇楋細0=鏈垹闄わ紝1=宸插垹闄�
+    create_by     VARCHAR(255),                -- 鍒涘缓浜虹敤鎴峰悕
+    create_time   TIMESTAMP WITHOUT TIME ZONE, -- 鍒涘缓鏃堕棿锛岄粯璁ゅ綋鍓嶆椂闂�
+    update_by     VARCHAR(255),                -- 鏈�鍚庢洿鏂颁汉鐢ㄦ埛鍚�
+    update_time   TIMESTAMP WITHOUT TIME ZONE -- 鏈�鍚庢洿鏂版椂闂达紝榛樿褰撳墠鏃堕棿
+
+);
+-- 娣诲姞琛ㄦ敞閲�
+COMMENT ON TABLE qr_code_scan_record IS '浜岀淮鐮佹壂鐮佽褰曡〃';
+
+-- 娣诲姞瀛楁娉ㄩ噴
+COMMENT ON COLUMN qr_code_scan_record.id IS '鎵爜璁板綍鍞竴鏍囪瘑';
+COMMENT ON COLUMN qr_code_scan_record.qr_code_id IS '鍏宠仈鐨勪簩缁寸爜ID';
+COMMENT ON COLUMN qr_code_scan_record.scanner_id IS '鎵爜浜虹敤鎴稩D';
+COMMENT ON COLUMN qr_code_scan_record.scan_time IS '瀹為檯鎵爜鏃堕棿';
+
+COMMENT ON COLUMN qr_code_scan_record.deleted IS '杞垹闄ゆ爣蹇楋紝0=鏈垹闄わ紝1=宸插垹闄�';
+COMMENT ON COLUMN qr_code_scan_record.create_by IS '鍒涘缓璇ヨ褰曠殑鐢ㄦ埛';
+COMMENT ON COLUMN qr_code_scan_record.create_time IS '璁板綍鍒涘缓鏃堕棿';
+COMMENT ON COLUMN qr_code_scan_record.update_by IS '鏈�鍚庝慨鏀硅璁板綍鐨勭敤鎴�';
+COMMENT ON COLUMN qr_code_scan_record.update_time IS '璁板綍鏈�鍚庢洿鏂版椂闂�';
\ No newline at end of file
diff --git a/main-business/src/main/resources/mapper/PendingInventoryMapper.xml b/main-business/src/main/resources/mapper/PendingInventoryMapper.xml
index 3e7b6b9..c3b7a76 100644
--- a/main-business/src/main/resources/mapper/PendingInventoryMapper.xml
+++ b/main-business/src/main/resources/mapper/PendingInventoryMapper.xml
@@ -11,7 +11,7 @@
         <result column="update_by" property="updateBy"/>
         <result column="update_time" property="updateTime"/>
         <result column="supplier_name" property="supplierName"/>
-        <result column="coal" property="coal"/>
+        <result column="coal_id" property="coalId"/>
         <result column="unit" property="unit"/>
         <result column="inventory_quantity" property="inventoryQuantity"/>
         <result column="price_including_tax" property="priceIncludingTax"/>
@@ -27,7 +27,7 @@
                 create_time,
                 update_by,
                 update_time,
-            id, supplier_name, coal, unit, inventory_quantity, price_including_tax, total_price_including_tax, registrant, registration_time
+            id, supplier_name,coal_id, unit, inventory_quantity, price_including_tax, total_price_including_tax, registrant, registration_time
         </sql>
 
     <select id="getPendingInventoryForUpdateById" resultType="com.ruoyi.business.entity.PendingInventory">
diff --git a/main-business/src/main/resources/mapper/PurchaseRegistrationMapper.xml b/main-business/src/main/resources/mapper/PurchaseRegistrationMapper.xml
index f14ea9e..d1b3ac9 100644
--- a/main-business/src/main/resources/mapper/PurchaseRegistrationMapper.xml
+++ b/main-business/src/main/resources/mapper/PurchaseRegistrationMapper.xml
@@ -14,7 +14,6 @@
                     <result column="supplier_name" property="supplierName" />
                     <result column="unit" property="unit" />
                     <result column="coal_id" property="coalId" />
-                    <result column="coal" property="coal" />
                     <result column="purchase_quantity" property="purchaseQuantity" />
                     <result column="price_including_tax" property="priceIncludingTax" />
                     <result column="total_price_including_tax" property="totalPriceIncludingTax" />
diff --git a/main-business/src/main/resources/mapper/QrCodeMapper.xml b/main-business/src/main/resources/mapper/QrCodeMapper.xml
new file mode 100644
index 0000000..2902316
--- /dev/null
+++ b/main-business/src/main/resources/mapper/QrCodeMapper.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.business.mapper.QrCodeMapper">
+
+        <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
+        <resultMap id="BaseResultMap" type="com.ruoyi.business.entity.QrCode">
+                    <id column="id" property="id" />
+                <result column="deleted" property="deleted" />
+                <result column="create_by" property="createBy" />
+                <result column="create_time" property="createTime" />
+                <result column="update_by" property="updateBy" />
+                <result column="update_time" property="updateTime" />
+                    <result column="device_name" property="deviceName" />
+                    <result column="location" property="location" />
+        </resultMap>
+
+        <!-- 閫氱敤鏌ヨ缁撴灉鍒� -->
+        <sql id="Base_Column_List">
+                deleted,
+                create_by,
+                create_time,
+                update_by,
+                update_time,
+            id, device_name, location
+        </sql>
+
+</mapper>
\ No newline at end of file
diff --git a/main-business/src/main/resources/mapper/QrCodeScanRecordMapper.xml b/main-business/src/main/resources/mapper/QrCodeScanRecordMapper.xml
new file mode 100644
index 0000000..5e2a249
--- /dev/null
+++ b/main-business/src/main/resources/mapper/QrCodeScanRecordMapper.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.business.mapper.QrCodeScanRecordMapper">
+
+        <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
+        <resultMap id="BaseResultMap" type="com.ruoyi.business.entity.QrCodeScanRecord">
+                    <id column="id" property="id" />
+                <result column="deleted" property="deleted" />
+                <result column="create_by" property="createBy" />
+                <result column="create_time" property="createTime" />
+                <result column="update_by" property="updateBy" />
+                <result column="update_time" property="updateTime" />
+                    <result column="qr_code_id" property="qrCodeId" />
+                    <result column="scanner_id" property="scannerId" />
+                    <result column="scan_time" property="scanTime" />
+        </resultMap>
+
+        <!-- 閫氱敤鏌ヨ缁撴灉鍒� -->
+        <sql id="Base_Column_List">
+                deleted,
+                create_by,
+                create_time,
+                update_by,
+                update_time,
+            id, qr_code_id, scanner_id, scan_time
+        </sql>
+
+</mapper>
\ No newline at end of file
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/StorageAttachmentRecordType.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/StorageAttachmentRecordType.java
index 74233aa..b8ed918 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/enums/StorageAttachmentRecordType.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/StorageAttachmentRecordType.java
@@ -1,27 +1,23 @@
 package com.ruoyi.common.enums;
 
 import lombok.AllArgsConstructor;
+import lombok.Getter;
 
 /**
  * 闄勪欢璁板綍绫诲瀷鏋氫妇
  *
  */
+@Getter
 @AllArgsConstructor
 public enum StorageAttachmentRecordType {
     // 渚嬪瓙 瀹為檯寮�鍙戣鍒犻櫎
     Template("Template","鑼冧緥"),
     Archives("Archives","鏂囨。绠$悊"),
-    InspectionTasks("InspectionTasks","鐢熶骇宸℃");
+    InspectionTasks("InspectionTasks","鐢熶骇宸℃"),
+    QrCodeScanRecords("QrCodeScanRecords","浜岀淮鐮佹壂鐮佽褰曟枃浠�");
 
 
     private final String code;
     private final String info;
 
-    public String getCode() {
-        return code;
-    }
-
-    public String getInfo() {
-        return info;
-    }
 }

--
Gitblit v1.9.3