liding
3 天以前 18d292f1091b8b86ad29ba76e3cbe8ffaf2c222e
1.正式库合并以及优化 2.销售模块
已修改16个文件
已添加9个文件
852 ■■■■ 文件已修改
basic-server/src/main/java/com/ruoyi/basic/entity/CoalInfo.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/java/com/ruoyi/basic/entity/CoalValue.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/java/com/ruoyi/basic/service/impl/CoalInfoServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/controller/OfficialInventoryController.java 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/controller/SalesRecordController.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/dto/OfficialInventoryDto.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/dto/SalesRecordDto.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/entity/File.java 94 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/entity/OfficialInventory.java 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/entity/PendingInventory.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/entity/Production.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/entity/PurchaseRegistration.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/entity/SalesRecord.java 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/mapper/SalesRecordMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/service/OfficialInventoryService.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/service/SalesRecordService.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/service/impl/OfficialInventoryServiceImpl.java 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/service/impl/PurchaseRegistrationServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/service/impl/SalesRecordServiceImpl.java 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/vo/OfficialInventoryVo.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/resources/db/migration/postgresql/V20250611160300__create_table_sales_record.sql 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/resources/mapper/OfficialInventoryMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/resources/mapper/PendingInventoryMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/resources/mapper/SalesRecordMapper.xml 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/init/MyStartupRunner.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/java/com/ruoyi/basic/entity/CoalInfo.java
@@ -1,11 +1,14 @@
package com.ruoyi.basic.entity;
import com.baomidou.mybatisplus.annotation.*;
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 com.ruoyi.common.core.domain.MyBaseEntity;
import lombok.Data;
import java.util.Date;
import java.time.LocalDate;
/**
 * ç…¤ç§ä¿¡æ¯è¡¨ å®žä½“ç±»
@@ -39,5 +42,5 @@
     */
    @TableField(value = "maintenance_date")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date maintenanceDate;
    private LocalDate maintenanceDate;
}
basic-server/src/main/java/com/ruoyi/basic/entity/CoalValue.java
@@ -17,8 +17,7 @@
 */
@Data
@TableName("coal_value")
public class
CoalValue extends MyBaseEntity {
public class CoalValue extends MyBaseEntity {
    private static final long serialVersionUID = 1L;
@@ -30,7 +29,7 @@
    private Long id;
    /**
     * å…³è”采购入库主键ID
     * å…³è”采购/正式入库主键ID
     */
    @TableField(value = "plan_id")
    private Long planId;
@@ -50,4 +49,10 @@
    @TableField(value = "field_name")
    private String fieldName;
    /**
     * 1 é‡‡è´­/ 2 æ­£å¼   å…¥åº“
     */
    @TableField(value = "type")
    private String type;
}
basic-server/src/main/java/com/ruoyi/basic/service/impl/CoalInfoServiceImpl.java
@@ -9,13 +9,13 @@
import com.ruoyi.basic.entity.CoalInfo;
import com.ruoyi.basic.mapper.CoalInfoMapper;
import com.ruoyi.basic.service.CoalInfoService;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.time.LocalDate;
import java.util.Objects;
/**
@@ -47,7 +47,7 @@
        CoalInfo coalInfo = new CoalInfo();
        BeanUtils.copyProperties(coalInfoDto, coalInfo);
        coalInfo.setMaintainerId(SecurityUtils.getUserId());
        coalInfo.setMaintenanceDate(DateUtils.getNowDate());
        coalInfo.setMaintenanceDate(LocalDate.now());
        if (Objects.isNull(coalInfoDto.getId())) {
            return coalInfoMapper.insert(coalInfo);
        } else {
main-business/src/main/java/com/ruoyi/business/controller/OfficialInventoryController.java
@@ -4,11 +4,12 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.business.dto.OfficialInventoryDto;
import com.ruoyi.business.service.OfficialInventoryService;
import com.ruoyi.business.vo.OfficialInventoryVo;
import com.ruoyi.common.core.domain.R;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * <p>
@@ -31,8 +32,32 @@
     */
    @GetMapping("/list")
    public R<IPage<OfficialInventoryDto>> list(Page page, OfficialInventoryDto officialInventoryDto) {
        IPage<OfficialInventoryDto> list = officialInventoryService.selectOfficialInventoryList(page,officialInventoryDto);
        IPage<OfficialInventoryDto> list = officialInventoryService.selectOfficialInventoryList(page, officialInventoryDto);
        return R.ok(list);
    }
    /**
     * æ­£å¼åº“煤种部分信息list
     */
    @GetMapping("/OfficialList")
    public R<List<OfficialInventoryVo>> officialList(OfficialInventoryVo officialInventoryVo) {
        return R.ok(officialInventoryService.selectOfficialList(officialInventoryVo));
    }
    /**
     * æ­£å¼åº“修改
     */
    @PostMapping("/editOfficial")
    public R editOfficial(@RequestBody OfficialInventoryDto officialInventoryDto) {
        return R.ok(officialInventoryService.editOfficial(officialInventoryDto));
    }
    /**
     * åˆå¹¶
     */
    @PostMapping("/merge")
    public R merge(@RequestBody OfficialInventoryDto officialInventoryDto) {
        return R.ok(officialInventoryService.mergeAll(officialInventoryDto));
    }
}
main-business/src/main/java/com/ruoyi/business/controller/SalesRecordController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,52 @@
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.SalesRecordDto;
import com.ruoyi.business.entity.SalesRecord;
import com.ruoyi.business.service.SalesRecordService;
import com.ruoyi.common.core.domain.R;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
/**
 * <p>
 * é”€å”®è®°å½•表 å‰ç«¯æŽ§åˆ¶å™¨
 * </p>
 *
 * @author ruoyi
 * @since 2025-06-11
 */
@RestController
@AllArgsConstructor
@RequestMapping("/salesRecord")
public class SalesRecordController {
    private SalesRecordService salesRecordService;
    /**
     * é”€å”®è®°å½•表查询
     */
    @GetMapping("/list")
    public R<IPage<SalesRecord>> list(Page page, SalesRecordDto salesRecordDto) {
        IPage<SalesRecord> list = salesRecordService.selectSalesRecordList(page,salesRecordDto);
        return R.ok(list);
    }
    /**
     * é”€å”®è®°å½•表新增修改
     */
    @PostMapping("/addOrEditSalesRecord")
    public R addOrEditSalesRecord(@RequestBody SalesRecordDto salesRecordDto) {
        return R.ok(salesRecordService.addOrEditSalesRecord(salesRecordDto));
    }
    /**
     * é”€å”®è®°å½•表删除
     */
    @DeleteMapping("/delSalesRecord")
    public R remove(@RequestBody Long[] ids) {
        return R.ok(salesRecordService.delByIds(ids));
    }
}
main-business/src/main/java/com/ruoyi/business/dto/OfficialInventoryDto.java
@@ -10,4 +10,7 @@
public class OfficialInventoryDto extends OfficialInventory {
    private List<Map<String, String>> fields;
    private List<Long> ids;
}
main-business/src/main/java/com/ruoyi/business/dto/SalesRecordDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,8 @@
package com.ruoyi.business.dto;
import com.ruoyi.business.entity.SalesRecord;
import lombok.Data;
@Data
public class SalesRecordDto extends SalesRecord {
}
main-business/src/main/java/com/ruoyi/business/entity/File.java
@@ -2,58 +2,58 @@
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
    import com.ruoyi.common.core.domain.MyBaseEntity;
import com.ruoyi.common.core.domain.MyBaseEntity;
/**
* ä¸Šä¼ æ–‡ä»¶çš„基本信息 å®žä½“ç±»
*
* @author ruoyi
* @date 2025-06-10
*/
 * ä¸Šä¼ æ–‡ä»¶çš„基本信息 å®žä½“ç±»
 *
 * @author ruoyi
 * @date 2025-06-10
 */
@Data
@TableName("file")
public class File extends MyBaseEntity {
private static final long serialVersionUID = 1L;
    private static final long serialVersionUID = 1L;
        /**
        * ä¸»é”®ID
        */
            @TableId(value = "id", type = IdType.AUTO)
        private Long id;
        /**
        * å…³è”的档案ID,外键引用 archive.id
        */
            @TableField(value = "archive_id")
        private Long archiveId;
        /**
        * åŽŸå§‹æ–‡ä»¶åï¼ˆç”¨æˆ·ä¸Šä¼ æ—¶çš„åç§°ï¼‰
        */
            @TableField(value = "original_name")
        private String originalName;
        /**
        * é¢„览地址
        */
            @TableField(value = "preview_url")
        private String previewUrl;
        /**
        * ç³»ç»Ÿå­˜å‚¨çš„唯一文件名
        */
            @TableField(value = "file_name")
        private String fileName;
        /**
        * æ–‡ä»¶åœ¨æœåŠ¡å™¨ä¸Šçš„å­˜å‚¨è·¯å¾„æˆ–è®¿é—®URL
        */
            @TableField(value = "file_path")
        private String filePath;
        /**
        * æ–‡ä»¶MIME类型,例如 image/png、application/pdf
        */
            @TableField(value = "file_type")
        private String fileType;
        /**
        * æ–‡ä»¶å¤§å°ï¼Œå•位为字节
        */
            @TableField(value = "file_size")
        private String fileSize;
    /**
     * ä¸»é”®ID
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * å…³è”的档案ID,外键引用 archive.id
     */
    @TableField(value = "archive_id")
    private Long archiveId;
    /**
     * åŽŸå§‹æ–‡ä»¶åï¼ˆç”¨æˆ·ä¸Šä¼ æ—¶çš„åç§°ï¼‰
     */
    @TableField(value = "original_name")
    private String originalName;
    /**
     * é¢„览地址
     */
    @TableField(value = "preview_url")
    private String previewUrl;
    /**
     * ç³»ç»Ÿå­˜å‚¨çš„唯一文件名
     */
    @TableField(value = "file_name")
    private String fileName;
    /**
     * æ–‡ä»¶åœ¨æœåŠ¡å™¨ä¸Šçš„å­˜å‚¨è·¯å¾„æˆ–è®¿é—®URL
     */
    @TableField(value = "file_path")
    private String filePath;
    /**
     * æ–‡ä»¶MIME类型,例如 image/png、application/pdf
     */
    @TableField(value = "file_type")
    private String fileType;
    /**
     * æ–‡ä»¶å¤§å°ï¼Œå•位为字节
     */
    @TableField(value = "file_size")
    private String fileSize;
}
main-business/src/main/java/com/ruoyi/business/entity/OfficialInventory.java
@@ -8,7 +8,7 @@
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
import java.time.LocalDate;
/**
 * æ­£å¼åº“存表 å®žä½“ç±»
@@ -63,10 +63,15 @@
    @TableField(value = "total_price_including_tax")
    private BigDecimal totalPriceIncludingTax;
    /**
     * æˆæœ¬å•ä»·
     * ä¸å«ç¨Žå•ä»·
     */
    @TableField(value = "cost_per_unit")
    private BigDecimal costPerUnit;
    @TableField(value = "price_excluding_tax")
    private BigDecimal priceExcludingTax;
    /**
     * ä¸å«ç¨Žæ€»ä»·
     */
    @TableField(value = "total_price_excluding_tax")
    private BigDecimal totalPriceExcludingTax;
    /**
     * å¾…补库
     */
@@ -81,5 +86,11 @@
     * ç™»è®°æ—¥æœŸ
     */
    @TableField(value = "registration_date")
    private Date registrationDate;
    private LocalDate registrationDate;
    /**
     * åˆå¹¶id
     */
    @TableField(value = "merge_id")
    private String mergeId;
}
main-business/src/main/java/com/ruoyi/business/entity/PendingInventory.java
@@ -8,7 +8,7 @@
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
import java.time.LocalDate;
/**
 * å¾…入库表 å®žä½“ç±»
@@ -56,18 +56,23 @@
    @TableField(value = "total_price_including_tax")
    private BigDecimal totalPriceIncludingTax;
    /**
     * æˆæœ¬å•ä»·
     * ä¸å«ç¨Žå•ä»·
     */
    @TableField(value = "cost_per_unit")
    private BigDecimal costPerUnit;
    @TableField(value = "price_excluding_tax")
    private BigDecimal priceExcludingTax;
    /**
     * ä¸å«ç¨Žæ€»ä»·
     */
    @TableField(value = "total_price_excluding_tax")
    private BigDecimal totalPriceExcludingTax;
    /**
     * ç™»è®°äºº
     */
    @TableField(value = "registrant_id")
    private String registrantId;
    /**
     * ç™»è®°æ—¶é—´
     * ç™»è®°æ—¥æœŸ
     */
    @TableField(value = "registration_time")
    private Date registrationTime;
    @TableField(value = "registration_date")
    private LocalDate registrationDate;
}
main-business/src/main/java/com/ruoyi/business/entity/Production.java
@@ -8,7 +8,7 @@
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
import java.time.LocalDate;
/**
 * ç”Ÿäº§æ˜Žç»†è¡¨ å®žä½“ç±»
@@ -81,5 +81,5 @@
     * ç”Ÿäº§æ—¥æœŸ
     */
    @TableField(value = "production_date")
    private Date productionDate;
    private LocalDate productionDate;
}
main-business/src/main/java/com/ruoyi/business/entity/PurchaseRegistration.java
@@ -8,7 +8,7 @@
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
import java.time.LocalDate;
/**
 * é‡‡è´­ç™»è®°è¡¨ å®žä½“ç±»
@@ -91,5 +91,5 @@
     * ç™»è®°æ—¥æœŸ
     */
    @TableField(value = "registration_date")
    private Date registrationDate;
    private LocalDate registrationDate;
}
main-business/src/main/java/com/ruoyi/business/entity/SalesRecord.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,120 @@
package com.ruoyi.business.entity;
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.ruoyi.common.core.domain.MyBaseEntity;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
/**
 * é”€å”®è®°å½•表 å®žä½“ç±»
 *
 * @author ruoyi
 * @date 2025-06-11
 */
@Data
@TableName("sales_record")
public class SalesRecord extends MyBaseEntity {
    private static final long serialVersionUID = 1L;
    /**
     * ä¸»é”®ID
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * é”€å”®æ—¥æœŸ
     */
    @TableField(value = "sale_date")
    private LocalDate saleDate;
    /**
     * å®¢æˆ·id
     */
    @TableField(value = "customer_id")
    private Long customerId;
    /**
     * å®¢æˆ·
     */
    @TableField(value = "customer")
    private String customer;
    /**
     * ç…¤ç§id
     */
    @TableField(value = "coal_id")
    private String coalId;
    /**
     * ç…¤ç§
     */
    @TableField(value = "coal")
    private String coal;
    /**
     * å•价(含税)
     */
    @TableField(value = "price_including_tax")
    private BigDecimal priceIncludingTax;
    /**
     * åº“存数量
     */
    @TableField(value = "inventory_quantity")
    private Long inventoryQuantity;
    /**
     * å•位
     */
    @TableField(value = "unit")
    private String unit;
    /**
     * é”€å”®æ•°é‡
     */
    @TableField(value = "sale_quantity")
    private BigDecimal saleQuantity;
    /**
     * é”€å”®å•ä»· (含税)
     */
    @TableField(value = "sale_price")
    private BigDecimal salePrice;
    /**
     * é”€å”®æ€»ä»· (含税)
     */
    @TableField(value = "total_amount")
    private BigDecimal totalAmount;
    /**
     * è´­é”€ç…¤ç¨Žçއ13%
     */
    @TableField(value = "tax_coal")
    private String taxCoal;
    /**
     * è¿è¾“税率9%
     */
    @TableField(value = "tax_trans")
    private String taxTrans;
    /**
     * æ¯›åˆ©æ¶¦
     */
    @TableField(value = "gross_profit")
    private BigDecimal grossProfit;
    /**
     * å‡€åˆ©æ¶¦
     */
    @TableField(value = "net_profit")
    private BigDecimal netProfit;
    /**
     * ç™»è®°äººid
     */
    @TableField(value = "registrant_id")
    private Long registrantId;
    /**
     * ç™»è®°äºº
     */
    @TableField(value = "registrant")
    private String registrant;
    /**
     * ç™»è®°æ—¥æœŸ
     */
    @TableField(value = "registration_date")
    private LocalDate registrationDate;
}
main-business/src/main/java/com/ruoyi/business/mapper/SalesRecordMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.business.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.business.entity.SalesRecord;
import org.apache.ibatis.annotations.Mapper;
/**
 * <p>
 * é”€å”®è®°å½•表 Mapper æŽ¥å£
 * </p>
 *
 * @author ruoyi
 * @since 2025-06-11
 */
@Mapper
public interface SalesRecordMapper extends BaseMapper<SalesRecord> {
}
main-business/src/main/java/com/ruoyi/business/service/OfficialInventoryService.java
@@ -5,6 +5,9 @@
import com.ruoyi.business.dto.OfficialInventoryDto;
import com.ruoyi.business.entity.OfficialInventory;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.business.vo.OfficialInventoryVo;
import java.util.List;
/**
 * <p>
@@ -17,4 +20,10 @@
public interface OfficialInventoryService extends IService<OfficialInventory> {
    IPage<OfficialInventoryDto> selectOfficialInventoryList(Page page, OfficialInventoryDto officialInventoryDto);
    int mergeAll(OfficialInventoryDto officialInventoryDto);
    int editOfficial(OfficialInventoryDto officialInventoryDto);
    List<OfficialInventoryVo> selectOfficialList(OfficialInventoryVo officialInventoryVo);
}
main-business/src/main/java/com/ruoyi/business/service/SalesRecordService.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.SalesRecordDto;
import com.ruoyi.business.entity.SalesRecord;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * é”€å”®è®°å½•表 æœåŠ¡ç±»
 * </p>
 *
 * @author ruoyi
 * @since 2025-06-11
 */
public interface SalesRecordService extends IService<SalesRecord> {
    IPage<SalesRecord> selectSalesRecordList(Page page, SalesRecordDto salesRecordDto);
    int addOrEditSalesRecord(SalesRecordDto salesRecordDto);
    int delByIds(Long[] ids);
}
main-business/src/main/java/com/ruoyi/business/service/impl/OfficialInventoryServiceImpl.java
@@ -1,7 +1,9 @@
package com.ruoyi.business.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.basic.entity.CoalField;
@@ -11,16 +13,16 @@
import com.ruoyi.business.dto.OfficialInventoryDto;
import com.ruoyi.business.entity.OfficialInventory;
import com.ruoyi.business.mapper.OfficialInventoryMapper;
import com.ruoyi.business.mapper.PendingInventoryMapper;
import com.ruoyi.business.service.OfficialInventoryService;
import com.ruoyi.business.vo.OfficialInventoryVo;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
/**
@@ -41,7 +43,6 @@
    private final CoalFieldMapper coalFieldMapper;
    private final PendingInventoryMapper pendingInventoryMapper;
    @Override
    public IPage<OfficialInventoryDto> selectOfficialInventoryList(Page page, OfficialInventoryDto officialInventoryDto) {
@@ -66,14 +67,19 @@
        //  éåŽ†æ¯æ¡è®°å½•ï¼Œè¿›è¡Œè½¬æ¢å¹¶å¡«å…… fields
        for (OfficialInventory entity : entityPage.getRecords()) {
            OfficialInventoryDto dto = new OfficialInventoryDto();
            BeanUtils.copyProperties(entity, dto);
            Long pendingId = entity.getPendingId();
            //  æŸ¥è¯¢è¯¥ pendingId å¯¹åº”çš„ CoalValue æ•°æ®
            List<CoalValue> coalValues = coalValueMapper.selectList(
                    new LambdaQueryWrapper<CoalValue>().eq(CoalValue::getPlanId, pendingId)
            );
            BeanUtils.copyProperties(entity, dto);
            List<CoalValue> coalValues;
            if (entity.getMergeId() == null) {
                coalValues = coalValueMapper.selectList(new LambdaQueryWrapper<CoalValue>()
                        .eq(CoalValue::getPlanId, entity.getPendingId())
                        .and(wrapper -> wrapper.ne(CoalValue::getType, "2").or().isNull(CoalValue::getType))
                );
            } else {
                coalValues = coalValueMapper.selectList(new LambdaQueryWrapper<CoalValue>()
                        .eq(CoalValue::getPlanId, entity.getId())
                        .eq(CoalValue::getType, "2")
                );
            }
            //  æž„建 Map<fieldName, value>
            Map<String, String> fieldValueMap = coalValues.stream()
@@ -99,4 +105,110 @@
        dtoPage.setRecords(dtoList); // è®¾ç½®è½¬æ¢åŽçš„ DtoList
        return dtoPage;
    }
    @Override
    public int editOfficial(OfficialInventoryDto officialInventoryDto) {
        OfficialInventory officialInventory = new OfficialInventory();
        BeanUtils.copyProperties(officialInventoryDto, officialInventory);
        return officialInventoryMapper.updateById(officialInventory);
    }
    @Override
    public List<OfficialInventoryVo> selectOfficialList(OfficialInventoryVo officialInventoryVo) {
        List<OfficialInventory> officialInventories = officialInventoryMapper.selectList(null);
        return officialInventories.stream()
                .map(OI -> {
                    OfficialInventoryVo vo = new OfficialInventoryVo();
                    BeanUtils.copyProperties(OI, vo);
                    return vo;
                })
                .collect(Collectors.toList());
    }
    @Transactional
    @Override
    public int mergeAll(OfficialInventoryDto officialInventoryDto) {
        List<Long> ids = officialInventoryDto.getIds();
        // æ ¡éªŒå‚æ•°
        if (CollectionUtils.isEmpty(ids) || ids.size() < 2) {
            throw new BaseException("请选中至少两条数据");
        }
        if (CollectionUtils.isEmpty(officialInventoryDto.getFields())) {
            throw new BaseException("字段值不能为空");
        }
        // 1. æ‰¹é‡æ ‡è®°åˆ é™¤æ—§æ•°æ®
        LambdaUpdateWrapper<OfficialInventory> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(OfficialInventory::getId, ids)
                .set(OfficialInventory::getDeleted, 1);
        int rowsAffected = officialInventoryMapper.update(null, updateWrapper);
        if (rowsAffected == 0) {
            throw new BaseException("未找到匹配的数据,请确认选择是否正确");
        }
        // 2. æ’入新库存记录
        OfficialInventory officialInventory = new OfficialInventory();
        BeanUtils.copyProperties(officialInventoryDto, officialInventory);
        officialInventory.setMergeId(ids.toString());
        officialInventory.setRegistrantId(SecurityUtils.getLoginUser().getUser().getUserName());
        if (officialInventoryMapper.insert(officialInventory) <= 0) {
            throw new BaseException("库存记录创建失败");
        }
        // 3. æ‰¹é‡å¤„理字段值
        batchProcessCoalValues(officialInventory.getId(), officialInventoryDto.getFields());
        return rowsAffected;
    }
    private void batchProcessCoalValues(Long planId, List<Map<String, String>> fields) {
        // 1. æå–所有唯一字段标识
        Set<String> allFields = fields.stream()
                .flatMap(map -> map.keySet().stream())
                .collect(Collectors.toSet());
        // 2. æŸ¥è¯¢å­—段映射关系
        List<CoalField> coalFields = coalFieldMapper.selectList(
                new LambdaQueryWrapper<CoalField>().in(CoalField::getFields, allFields)
        );
        Map<String, String> fieldMap = coalFields.stream()
                .collect(Collectors.toMap(
                        CoalField::getFields,
                        CoalField::getFieldName
                ));
        // 3. æž„造并插入每条记录
        CoalValue coalValueTemplate = new CoalValue();
        coalValueTemplate.setPlanId(planId);
        coalValueTemplate.setType("2");
        for (Map<String, String> fieldMapEntry : fields) {
            for (Map.Entry<String, String> entry : fieldMapEntry.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                String fieldName = fieldMap.get(key);
                if (fieldName == null) {
                    throw new BaseException("字段名不存在: " + key);
                }
                CoalValue coalValue = new CoalValue();
                BeanUtils.copyProperties(coalValueTemplate, coalValue); // å¤ç”¨æ¨¡æ¿å±žæ€§
                coalValue.setId(null);
                coalValue.setCoalValue(value);
                coalValue.setType("2");
                coalValue.setPlanId(planId);
                coalValue.setFields(key);
                coalValue.setFieldName(fieldName);
                // å•条插入
                int result = coalValueMapper.insert(coalValue);
                if (result <= 0) {
                    throw new BaseException("字段值保存失败,字段:" + key);
                }
            }
        }
    }
}
main-business/src/main/java/com/ruoyi/business/service/impl/PurchaseRegistrationServiceImpl.java
@@ -17,7 +17,7 @@
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Objects;
/**
@@ -55,6 +55,7 @@
        BeanUtils.copyProperties(purchaseRegistrationDto, purchaseRegistration);
        if (Objects.isNull(purchaseRegistrationDto.getId())) {
            // æ–°å¢žé‡‡è´­ç™»è®°
            purchaseRegistration.setRegistrationDate(LocalDate.now());
            int insertCount = purchaseRegistrationMapper.insert(purchaseRegistration);
            if (insertCount > 0) {
                // é‡‡è´­ç™»è®°æˆåŠŸï¼ŒåŒæ­¥åˆ›å»ºå¾…å…¥åº“è®°å½•
@@ -80,7 +81,6 @@
        // è®¾ç½®å¾…入库记录特有的属性(如果有)
         pendingInventory.setInventoryQuantity(purchaseRegistration.getPurchaseQuantity());
         pendingInventory.setCostPerUnit(new BigDecimal(22));
        return pendingInventory;
    }
main-business/src/main/java/com/ruoyi/business/service/impl/SalesRecordServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,144 @@
package com.ruoyi.business.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
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.entity.Customer;
import com.ruoyi.basic.mapper.CustomerMapper;
import com.ruoyi.business.dto.SalesRecordDto;
import com.ruoyi.business.entity.SalesRecord;
import com.ruoyi.business.mapper.SalesRecordMapper;
import com.ruoyi.business.service.SalesRecordService;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.system.mapper.SysUserMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
/**
 * <p>
 * é”€å”®è®°å½•表 æœåŠ¡å®žçŽ°ç±»
 * </p>
 *
 * @author ruoyi
 * @since 2025-06-11
 */
@Service
@RequiredArgsConstructor
public class SalesRecordServiceImpl extends ServiceImpl<SalesRecordMapper, SalesRecord> implements SalesRecordService {
    private final SalesRecordMapper salesRecordMapper;
    private final SysUserMapper userMapper;
    private final CustomerMapper customerMapper;
    @Override
    public IPage<SalesRecord> selectSalesRecordList(Page page, SalesRecordDto salesRecordDto) {
        LambdaQueryWrapper<SalesRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(SalesRecord::getCreateTime);
        return salesRecordMapper.selectPage(page, queryWrapper);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addOrEditSalesRecord(SalesRecordDto salesRecordDto) {
        // å‚数校验
        validateSalesRecordDto(salesRecordDto);
        // æž„建销售记录实体
        SalesRecord salesRecord = buildSalesRecord(salesRecordDto);
        // å¤„理新增/更新逻辑
        if (salesRecordDto.getId() == null) {
            return insertSalesRecord(salesRecord);
        } else {
            return updateSalesRecord(salesRecord);
        }
    }
    private void validateSalesRecordDto(SalesRecordDto dto) {
        if (dto == null) {
            throw new BaseException("销售记录数据不能为空");
        }
        if (dto.getRegistrantId() == null) {
            throw new BaseException("登记人ID不能为空");
        }
        if (dto.getCustomerId() == null) {
            throw new BaseException("客户ID不能为空");
        }
    }
    private SalesRecord buildSalesRecord(SalesRecordDto dto) {
        SalesRecord record = new SalesRecord();
        BeanUtils.copyProperties(dto, record);
        // è®¾ç½®ç™»è®°äººä¿¡æ¯
        SysUser registrant = userMapper.selectUserById(dto.getRegistrantId());
        if (registrant == null) {
            throw new BaseException("登记人信息不存在");
        }
        record.setRegistrant(registrant.getUserName());
        // è®¾ç½®å®¢æˆ·ä¿¡æ¯
        Customer customer = customerMapper.selectById(dto.getCustomerId());
        if (customer == null) {
            throw new BaseException("客户信息不存在");
        }
        record.setCustomer(customer.getCustomerName());
        // è®¾ç½®æ—¥æœŸä¿¡æ¯
        LocalDate now = LocalDate.now();
        if (record.getId() == null) {
            // æ–°å¢žæ—¶è®¾ç½®æ—¥æœŸ
            record.setSaleDate(now);
            record.setRegistrationDate(now);
        } else {
            // æ›´æ–°æ—¶ä¸è¦†ç›–原有日期
            SalesRecord existing = salesRecordMapper.selectById(record.getId());
            if (existing == null) {
                throw new BaseException("销售记录不存在");
            }
            record.setSaleDate(existing.getSaleDate());
            record.setRegistrationDate(existing.getRegistrationDate());
        }
        return record;
    }
    private int insertSalesRecord(SalesRecord record) {
        int result = salesRecordMapper.insert(record);
        if (result <= 0) {
            throw new BaseException("销售记录创建失败");
        }
        return result;
    }
    private int updateSalesRecord(SalesRecord record) {
        int result = salesRecordMapper.updateById(record);
        if (result <= 0) {
            throw new BaseException("销售记录更新失败");
        }
        return result;
    }
    @Override
    public int delByIds(Long[] ids) {
        // æ£€æŸ¥å‚æ•°
        if (ids == null || ids.length == 0) {
            return 0;
        }
        // æž„造更新条件
        UpdateWrapper<SalesRecord> updateWrapper = new UpdateWrapper<>();
        updateWrapper.in("id", ids)
                .set("deleted", 1);  // è®¾ç½® deleted ä¸º 1 è¡¨ç¤ºå·²åˆ é™¤
        // æ‰§è¡Œæ‰¹é‡é€»è¾‘删除
        return salesRecordMapper.update(null, updateWrapper);
    }
}
main-business/src/main/java/com/ruoyi/business/vo/OfficialInventoryVo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.business.vo;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class OfficialInventoryVo {
    private Long id;  // ä¸»é”®ID
    private String coal;   // ç…¤ç§
    private String unit;   // å•位
    private BigDecimal inventoryQuantity;  // åº“存数量
    private BigDecimal priceIncludingTax; // å•价(含税)
}
main-business/src/main/resources/db/migration/postgresql/V20250611160300__create_table_sales_record.sql
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
-- åˆ›å»ºé”€å”®è®°å½•表
CREATE TABLE sales_record
(
    id                  BIGSERIAL PRIMARY KEY,                              -- ä¸»é”®ID
    sale_date           DATE           NOT NULL,                            -- é”€å”®æ—¥æœŸ
    customer_id         BIGINT,                                             -- å®¢æˆ·id
    customer            VARCHAR(255)   NOT NULL,                            -- å®¢æˆ·
    coal_id             VARCHAR(255)   NOT NULL,                            -- ç…¤ç§ id
    coal                VARCHAR(255)   NOT NULL,                            -- ç…¤ç§
    price_including_tax DECIMAL(10, 2) NOT NULL,                            -- å•价(含税)
    inventory_quantity  DECIMAL(10, 0) NOT NULL,                            -- åº“存数量
    unit                VARCHAR(100)   NOT NULL,                            -- å•位
    sale_quantity       DECIMAL(10, 2) NOT NULL,                            -- é”€å”®æ•°é‡
    sale_price          DECIMAL(10, 2) NOT NULL,                            -- é”€å”®å•ä»· (含税)
    total_amount        DECIMAL(10, 2) NOT NULL,                            -- é”€å”®æ€»ä»· (含税)
    tax_coal            VARCHAR(36),                                        -- è´­é”€ç…¤ç¨Žçއ13%
    tax_trans           VARCHAR(36),                                        -- è¿è¾“税率9%
    gross_profit        DECIMAL(10, 2),                                     -- æ¯›åˆ©æ¶¦
    net_profit          DECIMAL(10, 2),                                     -- å‡€åˆ©æ¶¦
    registrant_id       BIGINT,                                             -- ç™»è®°äººid
    registrant          VARCHAR(255)   NOT NULL,                            -- ç™»è®°äºº
    registration_date   DATE           NOT NULL,                            -- ç™»è®°æ—¥æœŸ
    create_time         TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, -- ä¸Šä¼ æ—¶é—´ï¼Œé»˜è®¤å½“前时间
    update_time         TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, -- æœ€åŽæ›´æ–°æ—¶é—´ï¼Œé»˜è®¤å½“前时间
    create_by           VARCHAR(255),                                       -- ä¸Šä¼ äººç”¨æˆ·å
    update_by           VARCHAR(255),                                       -- æœ€åŽä¿®æ”¹äººç”¨æˆ·å
    deleted             INT            NOT NULL  DEFAULT 0                  -- è½¯åˆ é™¤æ ‡å¿—:0=未删除,1=已删除
);
-- è¡¨æ³¨é‡Š
COMMENT ON TABLE sales_record IS '销售记录表';
-- æ·»åŠ å­—æ®µæ³¨é‡Š
COMMENT ON COLUMN sales_record.id IS '主键ID';
COMMENT ON COLUMN sales_record.sale_date IS '销售日期';
COMMENT ON COLUMN sales_record.customer IS '客户';
COMMENT ON COLUMN sales_record.customer_id IS '客户id';
COMMENT ON COLUMN sales_record.coal IS '煤种';
COMMENT ON COLUMN sales_record.coal_id IS '煤种id';
COMMENT ON COLUMN sales_record.unit IS '单位';
COMMENT ON COLUMN sales_record.price_including_tax IS '单价(含税)';
COMMENT ON COLUMN sales_record.inventory_quantity IS '库存数量';
COMMENT ON COLUMN sales_record.sale_quantity IS '销售数量';
COMMENT ON COLUMN sales_record.sale_price IS '销售单价 (含税)';
COMMENT ON COLUMN sales_record.total_amount IS '销售总价 (含税)';
COMMENT ON COLUMN sales_record.tax_coal IS '购销煤税率13%';
COMMENT ON COLUMN sales_record.tax_trans IS '运输税率9%';
COMMENT ON COLUMN sales_record.gross_profit IS '毛利润';
COMMENT ON COLUMN sales_record.net_profit IS '净利润';
COMMENT ON COLUMN sales_record.registrant IS '登记人';
COMMENT ON COLUMN sales_record.registrant_id IS '登记人id';
COMMENT ON COLUMN sales_record.registration_date IS '登记日期';
COMMENT ON COLUMN sales_record.deleted IS '软删除标志,0=未删除,1=已删除';
COMMENT ON COLUMN sales_record.create_by IS '创建该记录的用户';
COMMENT ON COLUMN sales_record.create_time IS '记录创建时间';
COMMENT ON COLUMN sales_record.update_by IS '最后修改该记录的用户';
COMMENT ON COLUMN sales_record.update_time IS '记录最后更新时间';
main-business/src/main/resources/mapper/OfficialInventoryMapper.xml
@@ -11,12 +11,11 @@
                <result column="update_by" property="updateBy" />
                <result column="update_time" property="updateTime" />
                    <result column="supplier_name" property="supplierName" />
                    <result column="coal_type" property="coalType" />
                    <result column="coal" property="coal" />
                    <result column="unit" property="unit" />
                    <result column="inventory_quantity" property="inventoryQuantity" />
                    <result column="price_including_tax" property="priceIncludingTax" />
                    <result column="total_price_including_tax" property="totalPriceIncludingTax" />
                    <result column="cost_per_unit" property="costPerUnit" />
                    <result column="pending_replenishment" property="pendingReplenishment" />
                    <result column="registrant_id" property="registrantId" />
                    <result column="registration_date" property="registrationDate" />
@@ -29,7 +28,7 @@
                create_time,
                update_by,
                update_time,
            id, supplier_name, coal_type, unit, inventory_quantity, price_including_tax, total_price_including_tax, cost_per_unit, pending_replenishment, registrant_id, registration_date
            id, supplier_name, coal_type, unit, inventory_quantity, price_including_tax, total_price_including_tax, pending_replenishment, registrant_id, registration_date
        </sql>
</mapper>
main-business/src/main/resources/mapper/PendingInventoryMapper.xml
@@ -16,9 +16,8 @@
                    <result column="inventory_quantity" property="inventoryQuantity" />
                    <result column="price_including_tax" property="priceIncludingTax" />
                    <result column="total_price_including_tax" property="totalPriceIncludingTax" />
                    <result column="cost_per_unit" property="costPerUnit" />
                    <result column="registrant_id" property="registrantId" />
                    <result column="registration_time" property="registrationTime" />
                    <result column="registration_date" property="registrationDate" />
        </resultMap>
        <!-- é€šç”¨æŸ¥è¯¢ç»“果列 -->
@@ -28,7 +27,7 @@
                create_time,
                update_by,
                update_time,
            id, supplier_name, coal_type, unit, inventory_quantity, price_including_tax, total_price_including_tax, cost_per_unit, registrant, registration_time
            id, supplier_name, coal_type, unit, inventory_quantity, price_including_tax, total_price_including_tax, registrant, registration_time
        </sql>
</mapper>
main-business/src/main/resources/mapper/SalesRecordMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,43 @@
<?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.SalesRecordMapper">
        <!-- é€šç”¨æŸ¥è¯¢æ˜ å°„结果 -->
        <resultMap id="BaseResultMap" type="com.ruoyi.business.entity.SalesRecord">
                    <id column="id" property="id" />
                <result column="create_time" property="createTime" />
                <result column="update_time" property="updateTime" />
                <result column="create_by" property="createBy" />
                <result column="update_by" property="updateBy" />
                <result column="deleted" property="deleted" />
                    <result column="sale_date" property="saleDate" />
                    <result column="customer_id" property="customerId" />
                    <result column="customer" property="customer" />
                    <result column="coal_id" property="coalId" />
                    <result column="coal" property="coal" />
                    <result column="price_including_tax" property="priceIncludingTax" />
                    <result column="inventory_quantity" property="inventoryQuantity" />
                    <result column="unit" property="unit" />
                    <result column="sale_quantity" property="saleQuantity" />
                    <result column="sale_price" property="salePrice" />
                    <result column="total_amount" property="totalAmount" />
                    <result column="tax_coal" property="taxCoal" />
                    <result column="tax_trans" property="taxTrans" />
                    <result column="gross_profit" property="grossProfit" />
                    <result column="net_profit" property="netProfit" />
                    <result column="registrant_id" property="registrantId" />
                    <result column="registrant" property="registrant" />
                    <result column="registration_date" property="registrationDate" />
        </resultMap>
        <!-- é€šç”¨æŸ¥è¯¢ç»“果列 -->
        <sql id="Base_Column_List">
                create_time,
                update_time,
                create_by,
                update_by,
                deleted,
            id, sale_date, customer_id, customer, coal_id, coal, price_including_tax, inventory_quantity, unit, sale_quantity, sale_price, total_amount, tax_coal, tax_trans, gross_profit, net_profit, registrant_id, registrant, registration_date
        </sql>
</mapper>
ruoyi-admin/src/main/java/com/ruoyi/web/controller/init/MyStartupRunner.java
@@ -99,7 +99,6 @@
                provinceMapper.insert(provinces);
                cityMapper.insert(cities);
                districtMapper.insert(districts);
                log.info("地区信息初始化结束");
            }
        }