This commit is contained in:
dzc committed 2025-05-14 19:36:05 +08:00
commit d592a84808
18 files changed
+409 -14

No files matched your search

@@ -11,6 +11,7 @@ import lombok.Getter;
public enum InventoryTypeEnum {
CGRK("1", "CGRK"),
SCJG("2", "SCJG"),
;
private final String type;
private final String value;
@@ -0,0 +1,121 @@
package com.bsd.pjcloud.canteen.dto.erp;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDate;
import java.util.List;
@Data
public class CanteenProductRecordSaveDTO {
// 生产时间(格式:yyyy-MM-dd)
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate productionTime;
// 加工人姓名
private String handlerUser;
// 记录编号(示例值:SCJG-2025051403005)
private String recordCode;
// 生产明细列表
private List<ProductionDetail> productionDetailList;
// 使用内部类表示明细
@Data
public static class ProductionDetail {
@Schema(description = "模板ID")
private String templateId;
// 菜品名称(示例值:"咸菜豆腐汤")
@Schema(description = "菜品名称")
private String dishName;
@Schema(description = "菜品ID")
private Long dishId;
// 原料单位(示例值:"斤")
private String materialUnit;
// 生产数量(示例值:1)
@Schema(description = "生产数量")
private Double produceQuantity;
// 是否手动修改(示例值:false)
private Boolean manualModified;
private List<MaterialDetailList> materialDetailList;
}
@Data
public static class MaterialDetailList {
/**
* id
*/
@Schema(description="id")
private Long id;
/**
* 食材id
*/
@Schema(description="食材id")
private Long materialId;
/**
* 记录item表id
*/
@Schema(description="记录item表id")
private Long recordItemId;
/**
* 食材名称
*/
@Schema(description="食材名称")
private String materialName;
/**
* 食材单位
*/
@Schema(description="食材单位")
private String unit;
/**
* 计算用量
*/
@Schema(description="计算用量")
private Double calculatedUsage;
/**
* 折损率
*/
@Schema(description="折损率")
private Double lossRate;
/**
* 基础用量
*/
@Schema(description="基础用量")
private Double baseUsage;
/**
* 实际用量
*/
@Schema(description="实际用量")
private Double actualUsage;
/**
* 实际折损率
*/
@Schema(description="实际折损率")
private Double actualLossRate;
}
}
@@ -118,4 +118,11 @@ public class CanteenProductionRecordItemEntity extends Model<CanteenProductionRe
*/
@Schema(description="租户编号")
private Long tenantId;
@Schema(description = "菜品ID")
private Long dishId;
@Schema(description = "菜品名称")
private String dishName;
}
@@ -1,6 +1,8 @@
package com.bsd.pjcloud.canteen.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@@ -10,7 +12,7 @@ import lombok.EqualsAndHashCode;
* 食材加工菜品关系表
*
* @author zjf
* @date 2025-05-08 11:05:33
* @date 2025-05-14 12:47:16
*/
@Data
@TableName("production_record_item_relation")
@@ -27,14 +29,56 @@ public class ProductionRecordItemRelationEntity extends Model<ProductionRecordIt
private Long id;
/**
* 菜品id
* 食材id
*/
@Schema(description="菜品id")
private Long dishId;
@Schema(description="食材id")
private Long materialId;
/**
* 记录item表id
*/
@Schema(description="记录item表id")
private Long recordItemId;
/**
* 食材名称
*/
@Schema(description="食材名称")
private String materialName;
/**
* 食材单位
*/
@Schema(description="食材单位")
private String unit;
/**
* 计算用量
*/
@Schema(description="计算用量")
private Double calculatedUsage;
/**
* 折损率
*/
@Schema(description="折损率")
private Double lossRate;
/**
* 基础用量
*/
@Schema(description="基础用量")
private Double baseUsage;
/**
* 实际用量
*/
@Schema(description="实际用量")
private Double actualUsage;
/**
* 实际折损率
*/
@Schema(description="实际折损率")
private Double actualLossRate;
}
@@ -6,6 +6,7 @@ import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsd.pjcloud.canteen.dto.erp.CanteenProductRecordSaveDTO;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.log.annotation.SysLog;
import com.bsd.pjcloud.canteen.entity.CanteenProductionRecordEntity;
@@ -69,15 +70,14 @@ public class CanteenProductionRecordController {
/**
* 新增食材加工记录表
* @param canteenProductionRecord 食材加工记录表
* @return R
*/
@Operation(summary = "新增食材加工记录表" , description = "新增食材加工记录表" )
@SysLog("新增食材加工记录表" )
@PostMapping
@PreAuthorize("@pms.hasPermission('canteen_canteenProductionRecord_add')" )
public R save(@RequestBody CanteenProductionRecordEntity canteenProductionRecord) {
return R.ok(canteenProductionRecordService.save(canteenProductionRecord));
public R save(@RequestBody CanteenProductRecordSaveDTO canteenProductRecordSaveDTO) {
return R.ok(canteenProductionRecordService.saveCanteenProductRecordSaveDTO(canteenProductRecordSaveDTO));
}
/**
@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsd.pjcloud.canteen.dto.CanteenDailySpuDTO;
import com.bsd.pjcloud.canteen.dto.CanteenSpuUpdateStockReqDTO;
import com.bsd.pjcloud.canteen.entity.CanteenErpMaterialEntity;
import com.bsd.pjcloud.canteen.entity.CanteenOnlineSpuEntity;
import com.bsd.pjcloud.canteen.vo.erp.CanteenSpuSimpleVO;
import com.bsd.pjcloud.common.core.util.R;
@@ -208,4 +209,7 @@ public class CanteenSpuController {
}
return R.ok();
}
}
@@ -5,6 +5,9 @@ import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsd.pjcloud.canteen.entity.CanteenErpMaterialEntity;
import com.bsd.pjcloud.canteen.entity.CanteenSpuEntity;
import com.bsd.pjcloud.canteen.service.CanteenSpuService;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.log.annotation.SysLog;
import com.bsd.pjcloud.canteen.entity.CanteenStockEntity;
@@ -37,6 +40,8 @@ public class CanteenStockController {
private final CanteenStockService canteenStockService;
private final CanteenSpuService canteenSpuService;
/**
* 分页查询
* @param page 分页对象
@@ -116,4 +121,38 @@ public class CanteenStockController {
public List<CanteenStockEntity> export(CanteenStockEntity canteenStock,Long[] ids) {
return canteenStockService.list(Wrappers.lambdaQuery(canteenStock).in(ArrayUtil.isNotEmpty(ids), CanteenStockEntity::getId, ids));
}
@PostMapping("/canteen/ansync")
@PreAuthorize("@pms.hasPermission('canteen_canteenSpu_add')")
public R ansyncStock() {
List<CanteenSpuEntity> list = canteenSpuService.list();
for (CanteenSpuEntity canteenSpuEntity : list) {
CanteenStockEntity canteenStockEntity = new CanteenStockEntity();
canteenStockEntity.setCurrentStock(0D);
canteenStockEntity.setBaseStock(0D);
canteenStockEntity.setItemType("2");
canteenStockEntity.setItemId(canteenSpuEntity.getId());
canteenStockEntity.setInventoryUpperLimit(0);
canteenStockEntity.setInventoryLowerLimit(0);
canteenStockService.save(canteenStockEntity);
}
return R.ok();
}
// /**
// * 分页查询
// * @param page 分页对象
// * @return
// */
// @Operation(summary = "分页查询" , description = "分页查询" )
// @GetMapping("/dishStockPage" )
// @PreAuthorize("@pms.hasPermission('canteen_canteenErpMaterial_view')" )
// public R getDishStockPage(@ParameterObject Page page, @ParameterObject CanteenSpuEntity canteenSpuEntity) {
// return R.ok(canteenErpMaterialService.pageScope(page, canteenErpMaterial));
// }
}
@@ -26,7 +26,7 @@ import java.util.Objects;
* 食材加工菜品关系表
*
* @author zjf
* @date 2025-05-08 11:05:33
* @date 2025-05-14 12:47:16
*/
@RestController
@RequiredArgsConstructor
@@ -0,0 +1,82 @@
package com.bsd.pjcloud.canteen.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 食材加工菜品关系表
*
* @author zjf
* @date 2025-05-14 12:47:16
*/
@Data
@TableName("production_record_item_relation")
@EqualsAndHashCode(callSuper = true)
@Schema(description = "食材加工菜品关系表")
public class ProductionRecordItemRelationEntity extends Model<ProductionRecordItemRelationEntity> {
/**
* id
*/
@TableId(type = IdType.ASSIGN_ID)
@Schema(description="id")
private Long id;
/**
* 食材id
*/
@Schema(description="食材id")
private Long materialId;
/**
* 记录item表id
*/
@Schema(description="记录item表id")
private Long recordItemId;
/**
* 食材名称
*/
@Schema(description="食材名称")
private String materialName;
/**
* 食材单位
*/
@Schema(description="食材单位")
private String unit;
/**
* 计算用量
*/
@Schema(description="计算用量")
private Double calculatedUsage;
/**
* 折损率
*/
@Schema(description="折损率")
private Double lossRate;
/**
* 基础用量
*/
@Schema(description="基础用量")
private Double baseUsage;
/**
* 实际用量
*/
@Schema(description="实际用量")
private Double actualUsage;
/**
* 实际折损率
*/
@Schema(description="实际折损率")
private Double actualLossRate;
}
@@ -3,6 +3,7 @@ package com.bsd.pjcloud.canteen.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.bsd.pjcloud.canteen.dto.erp.CanteenProductRecordSaveDTO;
import com.bsd.pjcloud.canteen.entity.CanteenProductionRecordEntity;
public interface CanteenProductionRecordService extends IService<CanteenProductionRecordEntity> {
@@ -15,4 +16,12 @@ public interface CanteenProductionRecordService extends IService<CanteenProducti
* @return
*/
Object pageScope(Page page, LambdaQueryWrapper<CanteenProductionRecordEntity> wrapper);
/**
* 保存
* @param canteenProductRecordSaveDTO
* @return
*/
Object saveCanteenProductRecordSaveDTO(CanteenProductRecordSaveDTO canteenProductRecordSaveDTO);
}
@@ -3,11 +3,27 @@ package com.bsd.pjcloud.canteen.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bsd.pjcloud.canteen.dto.erp.CanteenProductRecordSaveDTO;
import com.bsd.pjcloud.canteen.dto.erp.UpdateStockDTO;
import com.bsd.pjcloud.canteen.entity.CanteenProductionRecordEntity;
import com.bsd.pjcloud.canteen.entity.CanteenProductionRecordItemEntity;
import com.bsd.pjcloud.canteen.entity.ProductionRecordItemRelationEntity;
import com.bsd.pjcloud.canteen.mapper.CanteenProductionRecordItemMapper;
import com.bsd.pjcloud.canteen.mapper.CanteenProductionRecordMapper;
import com.bsd.pjcloud.canteen.mapper.ProductionRecordItemRelationMapper;
import com.bsd.pjcloud.canteen.service.CanteenProductionRecordService;
import com.bsd.pjcloud.canteen.service.CanteenStockService;
import com.bsd.pjcloud.common.core.util.BeanUtils;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.common.security.util.SecurityUtils;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
/**
* 食材加工记录表
*
@@ -15,9 +31,57 @@ import org.springframework.stereotype.Service;
* @date 2025-05-08 11:02:09
*/
@Service
@AllArgsConstructor
public class CanteenProductionRecordServiceImpl extends ServiceImpl<CanteenProductionRecordMapper, CanteenProductionRecordEntity> implements CanteenProductionRecordService {
private final CanteenProductionRecordItemMapper canteenProductionRecordItemMapper;
private final ProductionRecordItemRelationMapper productionRecordItemRelationMapper;
private final CanteenStockService canteenStockService;
@Override
public Object pageScope(Page page, LambdaQueryWrapper<CanteenProductionRecordEntity> wrapper) {
return baseMapper.selectPageByScope(page, wrapper, DataScope.of());
}
@Override
@Transactional
public Object saveCanteenProductRecordSaveDTO(CanteenProductRecordSaveDTO canteenProductRecordSaveDTO) {
CanteenProductionRecordEntity canteenProductionRecord = BeanUtils.toBean(canteenProductRecordSaveDTO, CanteenProductionRecordEntity.class);
List<CanteenProductRecordSaveDTO.ProductionDetail> productionDetailList = canteenProductRecordSaveDTO.getProductionDetailList();
canteenProductionRecord.setDeptId(SecurityUtils.getUser().getDeptId());
int insert = baseMapper.insert(canteenProductionRecord);
List<UpdateStockDTO> materialUpdateStockDTOS = new ArrayList<>();
List<UpdateStockDTO> dishUpdateStockDTOS = new ArrayList<>();
for (CanteenProductRecordSaveDTO.ProductionDetail item: productionDetailList){
CanteenProductionRecordItemEntity canteenProductionRecordItemEntity = BeanUtils.toBean(item, CanteenProductionRecordItemEntity.class);
canteenProductionRecordItemEntity.setRecordId(canteenProductionRecord.getId());
canteenProductionRecordItemMapper.insert(canteenProductionRecordItemEntity);
UpdateStockDTO dishUpdateStockDTO = new UpdateStockDTO();
dishUpdateStockDTO.setId(item.getDishId());
dishUpdateStockDTO.setIncrCount(item.getProduceQuantity());
dishUpdateStockDTOS.add(dishUpdateStockDTO);
List<CanteenProductRecordSaveDTO.MaterialDetailList> materialDetailList = item.getMaterialDetailList();
List<ProductionRecordItemRelationEntity> productionRecordItemRelationEntities = BeanUtils.toBean(materialDetailList, ProductionRecordItemRelationEntity.class);
for (ProductionRecordItemRelationEntity materialDetailListItem: productionRecordItemRelationEntities){
materialDetailListItem.setRecordItemId(canteenProductionRecordItemEntity.getId());
UpdateStockDTO updateStockDTO = new UpdateStockDTO();
updateStockDTO.setId(materialDetailListItem.getMaterialId());
updateStockDTO.setIncrCount(-materialDetailListItem.getActualUsage());
materialUpdateStockDTOS.add(updateStockDTO);
}
productionRecordItemRelationMapper.insert(productionRecordItemRelationEntities);
}
//食材出库
canteenStockService.updateStock(materialUpdateStockDTOS);
//菜品入库
canteenStockService.updateStock(dishUpdateStockDTOS);
return insert;
}
}
@@ -1,11 +1,16 @@
package com.bsd.pjcloud.canteen.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bsd.pjcloud.canteen.dto.erp.UpdateStockDTO;
import com.bsd.pjcloud.canteen.entity.CanteenErpMaterialEntity;
import com.bsd.pjcloud.canteen.entity.CanteenSpuEntity;
import com.bsd.pjcloud.canteen.entity.CanteenStockEntity;
import com.bsd.pjcloud.canteen.mapper.CanteenErpMaterialMapper;
import com.bsd.pjcloud.canteen.mapper.CanteenStockMapper;
import com.bsd.pjcloud.canteen.service.CanteenStockService;
import lombok.AllArgsConstructor;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
@@ -20,10 +25,15 @@ import java.util.List;
* @date 2025-05-07 16:40:35
*/
@Service
@AllArgsConstructor
public class CanteenStockServiceImpl extends ServiceImpl<CanteenStockMapper, CanteenStockEntity> implements CanteenStockService {
private final CanteenErpMaterialMapper canteenErpMaterialMapper;
@Override
@Transactional
@Retryable(value = {OptimisticLockingFailureException.class}, maxAttempts = 3)
// @Retryable(value = {OptimisticLockingFailureException.class}, maxAttempts = 3)
public void updateStock(List<UpdateStockDTO> updateStockDTOS) {
// 更新库存(手动乐观锁)
for (UpdateStockDTO item : updateStockDTOS) {
@@ -36,7 +46,14 @@ public class CanteenStockServiceImpl extends ServiceImpl<CanteenStockMapper, Can
updateStockWithLockWrapper.eq(CanteenStockEntity::getItemId,item.getId());
updateStockWithLockWrapper.eq(CanteenStockEntity::getVersion,smErpStockEntity.getVersion());
CanteenStockEntity updateSmErpStockEntity = new CanteenStockEntity();
updateSmErpStockEntity.setCurrentStock(smErpStockEntity.getCurrentStock()+item.getIncrCount());
Double currentStock = smErpStockEntity.getCurrentStock();
if (currentStock<Math.abs(item.getIncrCount())){
LambdaQueryWrapper<CanteenErpMaterialEntity> canteenErpMaterialEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
canteenErpMaterialEntityLambdaQueryWrapper.eq(CanteenErpMaterialEntity::getId,item.getId());
CanteenErpMaterialEntity canteenErpMaterialEntity = canteenErpMaterialMapper.selectOne(canteenErpMaterialEntityLambdaQueryWrapper);
throw new RuntimeException(canteenErpMaterialEntity.getName()+"库存不足");
}
updateSmErpStockEntity.setCurrentStock(currentStock +item.getIncrCount());
updateSmErpStockEntity.setVersion(smErpStockEntity.getVersion()+1);
int update = baseMapper.update(updateSmErpStockEntity, updateStockWithLockWrapper);
// 3. 检查更新结果
@@ -9,7 +9,7 @@ import org.springframework.stereotype.Service;
* 食材加工菜品关系表
*
* @author zjf
* @date 2025-05-08 11:05:33
* @date 2025-05-14 12:47:16
*/
@Service
public class ProductionRecordItemRelationServiceImpl extends ServiceImpl<ProductionRecordItemRelationMapper, ProductionRecordItemRelationEntity> implements ProductionRecordItemRelationService {
@@ -5,7 +5,14 @@
<resultMap id="productionRecordItemRelationMap" type="com.bsd.pjcloud.canteen.entity.ProductionRecordItemRelationEntity">
<id property="id" column="id"/>
<result property="dishId" column="dish_id"/>
<result property="materialId" column="material_id"/>
<result property="recordItemId" column="record_item_id"/>
<result property="materialName" column="material_name"/>
<result property="unit" column="unit"/>
<result property="calculatedUsage" column="calculated_usage"/>
<result property="lossRate" column="loss_rate"/>
<result property="baseUsage" column="base_usage"/>
<result property="actualUsage" column="actual_usage"/>
<result property="actualLossRate" column="actual_loss_rate"/>
</resultMap>
</mapper>
@@ -14,7 +14,7 @@ import java.util.List;
*/
@Data
@Schema(description = "采购保存对象")
public class InventoryRecordSaveDTO {
public class InventoryRecordSaveDTO {
/**