liweidong
liweidong-hj 1 week ago
commit 817e1a332b
  1. 3
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/order/pojo/entity/YieldOrder.java
  2. 5
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/pojo/entity/WorkPlan.java
  3. 29
      blade-service/blade-desk/src/main/java/org/springblade/desk/efficiency/controller/BsEfficiencyTaskController.java
  4. 44
      blade-service/blade-desk/src/main/java/org/springblade/desk/efficiency/controller/BsSalaryCalculationController.java
  5. 351
      blade-service/blade-desk/src/main/java/org/springblade/desk/efficiency/controller/BsSalaryStandardController.java
  6. 1
      blade-service/blade-desk/src/main/java/org/springblade/desk/efficiency/enums/BsEfficiencyTaskEnum.java
  7. 105
      blade-service/blade-desk/src/main/java/org/springblade/desk/efficiency/enums/BsSalaryStandardEnum.java
  8. 89
      blade-service/blade-desk/src/main/java/org/springblade/desk/efficiency/excel/BsSalaryStandardExcel.java
  9. 29
      blade-service/blade-desk/src/main/java/org/springblade/desk/efficiency/mapper/BsSalaryStandardMapper.java
  10. 4
      blade-service/blade-desk/src/main/java/org/springblade/desk/efficiency/mapper/EfficiencyTaskMapper.xml
  11. 8
      blade-service/blade-desk/src/main/java/org/springblade/desk/efficiency/mapper/EfficiencyTaskReportMapper.xml
  12. 151
      blade-service/blade-desk/src/main/java/org/springblade/desk/efficiency/mapper/SalaryStandardMapper.xml
  13. 103
      blade-service/blade-desk/src/main/java/org/springblade/desk/efficiency/pojo/dto/BsSalaryCalculationDTO.java
  14. 84
      blade-service/blade-desk/src/main/java/org/springblade/desk/efficiency/pojo/entity/BsSalaryStandardEntity.java
  15. 163
      blade-service/blade-desk/src/main/java/org/springblade/desk/efficiency/pojo/vo/BsSalaryCalculationVO.java
  16. 38
      blade-service/blade-desk/src/main/java/org/springblade/desk/efficiency/pojo/vo/BsSalaryStandardVO.java
  17. 34
      blade-service/blade-desk/src/main/java/org/springblade/desk/efficiency/service/IBsSalaryStandardService.java
  18. 6
      blade-service/blade-desk/src/main/java/org/springblade/desk/efficiency/service/impl/BsEfficiencyTempServiceImpl.java
  19. 37
      blade-service/blade-desk/src/main/java/org/springblade/desk/efficiency/service/impl/BsSalaryStandardServiceImpl.java
  20. 163
      blade-service/blade-desk/src/main/java/org/springblade/desk/efficiency/util/BsSalaryUtil.java
  21. 10
      blade-service/blade-desk/src/main/java/org/springblade/desk/energy/mapper/EpciuPatrolInspectionMapper.xml
  22. 6
      blade-service/blade-desk/src/main/java/org/springblade/desk/energy/service/impl/BsEpciuPatrolInspectionServiceImpl.java
  23. 15
      blade-service/blade-desk/src/main/java/org/springblade/desk/energy/service/impl/BsSafePatrolInspectionServiceImpl.java
  24. 498
      blade-service/blade-desk/src/main/java/org/springblade/desk/energy/util/DateTools.java
  25. 4
      blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/WorkPlanMapper.java
  26. 119
      blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/WorkPlanMapper.xml
  27. 6
      blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/IWorkOrderService.java
  28. 4
      blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/IWorkPlanService.java
  29. 4
      blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/impl/PdaLoadServiceImpl.java
  30. 114
      blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/impl/WorkOrderServiceImpl.java
  31. 9
      blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/impl/WorkPlanServiceImpl.java
  32. BIN
      blade-service/blade-desk/src/main/resources/Excel/efficiency/工资维护标准.xls

@ -482,7 +482,8 @@ public class YieldOrder extends BaseEntity {
/**
* 计划部门
*/
@TableField(value = "plan_deptcode")
// @TableField(value = "plan_deptcode")
@TableField(exist = false)
private String planDeptCode;
/**

@ -344,5 +344,10 @@ public class WorkPlan extends BaseEntity {
@Schema(description = "车间计划修改记录")
private WorkPlanLog workPlanLog;
@Schema(description = "基础薪资金额")
private BigDecimal baseAmount;
@Schema(description = "补贴薪资金额")
private BigDecimal subsidyAmount;
}

@ -196,7 +196,34 @@ public class BsEfficiencyTaskController extends BladeController {
@PostMapping("/remove")
@Operation(summary = "逻辑删除", description = "传入ids")
public R remove(@Parameter(description = "主键集合", required = true) @RequestParam String ids) {
return R.status(bsEfficiencyTaskService.deleteLogic(Func.toLongList(ids)));
List<Long> idList = Func.toLongList(ids);
Set<Long> parentIds = new HashSet<>();
for (Long id : idList) {
BsEfficiencyTaskEntity bsEfficiencyTaskEntity = bsEfficiencyTaskService.getById(id);
if (bsEfficiencyTaskEntity == null || bsEfficiencyTaskEntity.getStatus() != BsEfficiencyTaskEnum.STATUS_IN_PROGRESS.getCode()) {
return R.fail("选中任务明细不能删除");
}
if (bsEfficiencyTaskEntity != null && bsEfficiencyTaskEntity.getParentId() != null && bsEfficiencyTaskEntity.getParentId() != 0) {
parentIds.add(bsEfficiencyTaskEntity.getParentId());
}
}
for (Long parentId : parentIds) {
BsEfficiencyTaskEntity entity = bsEfficiencyTaskService.getById(parentId);
if (entity != null && entity.getStatus() != BsEfficiencyTaskEnum.STATUS_IN_PROGRESS.getCode()) {
return R.fail("选中任务明细不能删除");
}
}
bsEfficiencyTaskService.deleteLogic(idList);
for (Long parentId : parentIds) {
List<BsEfficiencyTaskEntity> list = bsEfficiencyTaskService.list(new LambdaQueryWrapper<BsEfficiencyTaskEntity>().eq(BsEfficiencyTaskEntity::getParentId, parentId));
if (CollectionUtils.isEmpty(list)) {
BsEfficiencyTaskEntity upd = new BsEfficiencyTaskEntity();
upd.setId(parentId);
upd.setStatus(BsEfficiencyTaskEnum.STATUS_FAIL.getCode());
bsEfficiencyTaskService.saveOrUpdate(upd);
}
}
return R.success();
}
/**

@ -0,0 +1,44 @@
package org.springblade.desk.efficiency.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.desk.efficiency.pojo.dto.BsSalaryCalculationDTO;
import org.springblade.desk.efficiency.pojo.vo.BsSalaryCalculationVO;
import org.springblade.desk.efficiency.pojo.vo.BsSalaryStandardVO;
import org.springblade.desk.produce.service.IWorkOrderService;
import org.springblade.desk.produce.service.IWorkPlanService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 薪资计算 控制器
*
* @author BladeX
* @since 2026-04-23
*/
@RestController
@AllArgsConstructor
@RequestMapping("/bsSalaryCalculation")
@Tag(name = "薪资规则表", description = "薪资计算接口")
public class BsSalaryCalculationController {
private final IWorkPlanService workPlanService;
private final IWorkOrderService workOrderService;
/**
* 薪资计算 自定义分页
*/
@GetMapping("/page")
@Operation(summary = "分页", description = "传入bsSalaryCalculation")
public R<IPage<BsSalaryCalculationVO>> page(BsSalaryCalculationDTO bsSalaryCalculation, Query query) {
IPage<BsSalaryCalculationVO> pages = workPlanService.selectBsSalaryCalculationPage(Condition.getPage(query), bsSalaryCalculation);
return R.data(pages);
}
}

@ -0,0 +1,351 @@
package org.springblade.desk.efficiency.controller;
import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import net.logstash.logback.encoder.org.apache.commons.lang3.ObjectUtils;
import org.springblade.core.excel.util.ExcelUtil;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.desk.basic.util.ExcelExtUtil;
import org.springblade.desk.dashboard.pojo.entity.BsProcessSetEntity;
import org.springblade.desk.dashboard.service.IBsProcessSetService;
import org.springblade.desk.efficiency.enums.BsSalaryStandardEnum;
import org.springblade.desk.efficiency.excel.BsSalaryStandardExcel;
import org.springblade.desk.efficiency.pojo.entity.BsSalaryStandardEntity;
import org.springblade.desk.efficiency.pojo.vo.BsSalaryStandardVO;
import org.springblade.desk.efficiency.service.IBsSalaryStandardService;
import org.springframework.beans.BeanUtils;
import org.springframework.core.io.Resource;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 薪资规则 控制器
*
* @author BladeX
* @since 2026-04-23
*/
@RestController
@AllArgsConstructor
@RequestMapping("/bsSalaryStandard")
@Tag(name = "薪资规则表", description = "薪资规则接口")
public class BsSalaryStandardController {
private final IBsSalaryStandardService bsSalaryStandardService;
private final IBsProcessSetService bsProcessSetService;
/**
* 薪资规则表 自定义分页
*/
@GetMapping("/page")
@Operation(summary = "分页", description = "传入bsEfficiencyTemp")
public R<IPage<BsSalaryStandardVO>> page(BsSalaryStandardVO bsSalaryStandardVO, Query query) {
IPage<BsSalaryStandardVO> pages = bsSalaryStandardService.selectBsSalaryStandardPage(Condition.getPage(query), bsSalaryStandardVO);
return R.data(pages);
}
/**
* 薪资规则表 新增或修改
*/
@PostMapping("/submit")
@Operation(summary = "新增或修改", description = "传入bsEnergyTarget")
public R submit(@Valid @RequestBody BsSalaryStandardEntity bsSalaryStandard) {
LambdaQueryWrapper<BsSalaryStandardEntity> wrapper = new LambdaQueryWrapper<BsSalaryStandardEntity>().eq(BsSalaryStandardEntity::getProcessId, bsSalaryStandard.getProcessId());
if (bsSalaryStandard.getId() != null) {
wrapper.ne(BsSalaryStandardEntity::getId, bsSalaryStandard.getId());
}
List<BsSalaryStandardEntity> list = bsSalaryStandardService.list(wrapper);
if (checkExcelDuplicateData(bsSalaryStandard,list)) {
return R.fail("已存在重复的薪资规则");
}
if (BsSalaryStandardEnum.STEP_TYPE_STEP.getCode().equals(bsSalaryStandard.getStepType())) {
if (!checkStepNumber(bsSalaryStandard.getStep(), bsSalaryStandard.getStepSettlementPrice())) {
return R.fail("阶梯结算价与阶梯不一致");
}
}
return R.status(bsSalaryStandardService.saveOrUpdate(bsSalaryStandard));
}
/**
* 薪资规则表 删除
*/
@PostMapping("/remove")
@Operation(summary = "逻辑删除", description = "传入ids")
public R remove(@Parameter(description = "主键集合", required = true) @RequestParam String ids) {
return R.status(bsSalaryStandardService.deleteLogic(Func.toLongList(ids)));
}
/**
* 薪资规则表 详情
*/
@GetMapping("/detail")
@Operation(summary = "详情", description = "传入bsSalaryStandard")
public R<BsSalaryStandardVO> detail(BsSalaryStandardEntity bsSalaryStandardEntity) {
BsSalaryStandardVO vo = new BsSalaryStandardVO();
BsSalaryStandardEntity bsSalaryStandard = bsSalaryStandardService.getById(bsSalaryStandardEntity.getId());
BeanUtils.copyProperties(bsSalaryStandard, vo);
return R.data(vo);
}
/**
* 检查阶梯数据
*
* @param step
* @param stepSettlementPrice
* @return
*/
private boolean checkStepNumber(String step, String stepSettlementPrice) {
// ====================== 1、先校验 step 必须严格递增 ======================
if (step != null && !step.isBlank()) {
String[] stepArr = step.trim().split("\\s+");
if (Double.parseDouble(stepArr[0].trim()) <= 0) {
return false;
}
// 校验递增
for (int i = 1; i < stepArr.length; i++) {
try {
double prev = Double.parseDouble(stepArr[i - 1].trim());
double curr = Double.parseDouble(stepArr[i].trim());
if (curr <= prev) {
return false;
}
} catch (NumberFormatException e) {
return false;
}
}
}
// ====================== 2、校验个数:stepSettlementPrice = step + 1 ======================
int stepCount = 0;
if (step != null && !step.isBlank()) {
stepCount = step.trim().split("\\s+").length;
}
int otherCount = 0;
if (stepSettlementPrice != null && !stepSettlementPrice.isBlank()) {
otherCount = stepSettlementPrice.trim().split("\\s+").length;
}
// 必须满足:otherStep 分段数 = step 分段数 + 1
return otherCount == stepCount + 1;
}
/**
* 下载Excel模板
*
* @return
*/
@GetMapping("/download-excel-template")
@Operation(summary = "下载Excel模板", description = "")
public ResponseEntity<Resource> downloadExcelTemplate() {
return ExcelExtUtil.downloadXlsTemplate("Excel/efficiency/工资维护标准.xls", "导入模版-工资维护标准.xls");
}
/**
* 导入Excel
*
* @param file
* @return
*/
@PostMapping("/import-excel")
@Operation(summary = "导入Excel", description = "MultipartFile")
public R waterImportExcel(@RequestParam("file") MultipartFile file) {
R checkR = ExcelExtUtil.importExcelCheck(file);
if (checkR != null) {
return checkR;
}
List<BsSalaryStandardExcel> importList = ExcelUtil.read(file, 0, 1, BsSalaryStandardExcel.class);
if (checkExcelDuplicate(importList)) {
return R.fail("Excel中存在重复数据,请检查后重新导入");
}
List<BsSalaryStandardEntity> saveBatchList = new ArrayList<>();
for (BsSalaryStandardExcel excel : importList) {
BsProcessSetEntity processSet = bsProcessSetService.getOne(new LambdaQueryWrapper<BsProcessSetEntity>().eq(BsProcessSetEntity::getCode, excel.getProcessCode()).eq(BsProcessSetEntity::getName, excel.getProcessName()));
if (processSet == null) {
return R.fail(excel.getProcessCode() + "-" + excel.getProcessName() + "工序不存在");
}
List<BsSalaryStandardEntity> list = bsSalaryStandardService.list(new LambdaQueryWrapper<BsSalaryStandardEntity>().eq(BsSalaryStandardEntity::getProcessId, processSet.getId()));
BsSalaryStandardEntity bsSalaryStandard = new BsSalaryStandardEntity();
BeanUtils.copyProperties(excel, bsSalaryStandard);
bsSalaryStandard.setProcessId(processSet.getId());
bsSalaryStandard.setStandardType(BsSalaryStandardEnum.convertStandType(bsSalaryStandard.getStandardType()));
bsSalaryStandard.setStepType(BsSalaryStandardEnum.convertStepType(bsSalaryStandard.getStepType()));
bsSalaryStandard.setStepUnit(BsSalaryStandardEnum.convertStepUnit(bsSalaryStandard.getStepUnit()));
bsSalaryStandard.setStepSettlementUnit(BsSalaryStandardEnum.convertStepSettlementUnit(bsSalaryStandard.getStepSettlementUnit()));
bsSalaryStandard.setSettlementUnit(BsSalaryStandardEnum.convertSettlementUnit(bsSalaryStandard.getSettlementUnit()));
if (checkExcelDuplicateData(bsSalaryStandard, list)) {
return R.fail("已存在重复的薪资规则");
}
if (BsSalaryStandardEnum.STEP_TYPE_STEP.getCode().equals(bsSalaryStandard.getStepType())) {
if (!checkStepNumber(bsSalaryStandard.getStep(), bsSalaryStandard.getStepSettlementPrice())) {
return R.fail("阶梯结算价与阶梯不一致");
}
}
saveBatchList.add(bsSalaryStandard);
}
return R.status(bsSalaryStandardService.saveBatch(saveBatchList));
}
/**
* 校验 Excel 数据重复
*
* @param excelList
*/
private boolean checkExcelDuplicate(List<BsSalaryStandardExcel> excelList) {
// 外层:逐个检查
for (int i = 0; i < excelList.size(); i++) {
BsSalaryStandardExcel current = excelList.get(i);
// 内层:和前面所有行比较
for (int j = 0; j < i; j++) {
BsSalaryStandardExcel previous = excelList.get(j);
// 1. 先判断:processCode + processName 必须相同才可能重复
boolean sameProcess = ObjectUtils.equals(current.getProcessCode(), previous.getProcessCode()) && ObjectUtils.equals(current.getProcessName(), previous.getProcessName());
if (!sameProcess) {
continue;
}
// 2. 核心:类型冲突判断
boolean typeConflict = isTypeConflict(current.getStandardType(), previous.getStandardType());
if (!typeConflict) {
continue;
}
// 3. partNo 模糊匹配判断(支持空=%)
boolean partNoMatch = isPartNoMatch(current.getPartNo(), previous.getPartNo());
if (partNoMatch) {
return true;
}
}
}
return false;
}
private boolean checkExcelDuplicateData(BsSalaryStandardEntity current, List<BsSalaryStandardEntity> entities) {
for (int i = 0; i < entities.size(); i++) {
BsSalaryStandardEntity previous = entities.get(i);
boolean sameProcess = ObjectUtils.equals(current.getProcessId(), previous.getProcessId());
if (!sameProcess) {
continue;
}
boolean typeConflict = isTypeConflictCode(current.getStandardType(), previous.getStandardType());
if (!typeConflict) {
continue;
}
boolean partNoMatch = isPartNoMatch(current.getPartNo(), previous.getPartNo());
if (partNoMatch) {
return true;
}
}
return false;
}
/**
* 判断规则类型是否重复
*
* @param type1
* @param type2
* @return
*/
private boolean isTypeConflict(String type1, String type2) {
String COMMON = BsSalaryStandardEnum.STANDARD_TYPE_COMMON.getName();
String MILITARY = BsSalaryStandardEnum.STANDARD_TYPE_MILITARY.getName();
String NON_MILITARY = BsSalaryStandardEnum.STANDARD_TYPE_NON_MILITARY.getName();
if (COMMON.equals(type1) || COMMON.equals(type2)) {
return true;
}
if (MILITARY.equals(type1) && MILITARY.equals(type2)) {
return true;
}
if (NON_MILITARY.equals(type1) && NON_MILITARY.equals(type2)) {
return true;
}
return false;
}
private boolean isTypeConflictCode(String type1, String type2) {
String COMMON = BsSalaryStandardEnum.STANDARD_TYPE_COMMON.getCode();
String MILITARY = BsSalaryStandardEnum.STANDARD_TYPE_MILITARY.getCode();
String NON_MILITARY = BsSalaryStandardEnum.STANDARD_TYPE_NON_MILITARY.getCode();
if (COMMON.equals(type1) || COMMON.equals(type2)) {
return true;
}
if (MILITARY.equals(type1) && MILITARY.equals(type2)) {
return true;
}
if (NON_MILITARY.equals(type1) && NON_MILITARY.equals(type2)) {
return true;
}
return false;
}
/**
* partNo 匹配规则
* 1. = %
* 2. 按空格拆分
* 3. 任意一个片段匹配即返回 true
*/
private boolean isPartNoMatch(String partNo1, String partNo2) {
// 空 = % 匹配所有
List<String> list1 = splitPartNo(partNo1);
List<String> list2 = splitPartNo(partNo2);
if (StringUtils.isEmpty(partNo1) && StringUtils.isEmpty(partNo2)) {
return true;
}
// 任意片段匹配就重复
for (String p1 : list1) {
for (String p2 : list2) {
if (likeMatch(p1, p2) || likeMatch(p2, p1)) {
return true;
}
}
}
return false;
}
/**
* 拆分 partNo [%]否则按空格拆分
*/
private List<String> splitPartNo(String partNo) {
List<String> list = new ArrayList<>();
if (partNo == null || partNo.isBlank()) {
// list.add("%");
return list;
}
String[] arr = partNo.trim().split("\\s+");
for (String s : arr) {
if (!s.isBlank()) {
list.add(s.trim());
}
}
return list;
}
/**
* 实现模糊匹配支持 %
* likeMatch("100", "10%") true
*/
private boolean likeMatch(String pattern, String value) {
// 转成 Java 正则
String regex = pattern.replace("%", ".*");
return value.matches(regex);
}
}

@ -16,6 +16,7 @@ public enum BsEfficiencyTaskEnum {
STATUS_APPROVED("审批通过", 4),
STATUS_REJECTED("审批不通过", 5),
STATUS_EXPIRED("已超期", 6),
STATUS_FAIL("任务失败", 7),
;
final String name;

@ -0,0 +1,105 @@
package org.springblade.desk.efficiency.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 工资规则维护枚举
*/
@Getter
@AllArgsConstructor
public enum BsSalaryStandardEnum {
/**
* 规则类型
*/
STANDARD_TYPE_COMMON("通用", "1"),
STANDARD_TYPE_MILITARY("军品", "2"),
STANDARD_TYPE_NON_MILITARY("非军品", "3"),
/**
* 阶梯类型
*/
STEP_TYPE_NON("无补贴金额", "1"),
STEP_TYPE_FIXED("固定补贴金额", "2"),
STEP_TYPE_STEP("阶梯补贴金额", "3"),
/**
* 阶梯单位
*/
STEP_UNIT_PIECE("件", "1"),
STEP_UNIT_AREA("面积", "2"),
/**
* 阶梯结算单位
*/
STEP_SETTLEMENT_UNIT_BATCH("批", "1"),
STEP_SETTLEMENT_UNIT_MULTIPLE("倍", "2"),
/**
* 工人结算单位
*/
SETTLEMENT_UNIT_PIECE("件", "1"),
SETTLEMENT_UNIT_BATCH("批", "2"),
SETTLEMENT_UNIT_AREA("面积", "3"),
;
final String name;
final String code;
public static String convertStandType(String name){
if (BsSalaryStandardEnum.STANDARD_TYPE_COMMON.getName().equals(name)) {
return BsSalaryStandardEnum.STANDARD_TYPE_COMMON.getCode();
}
if (BsSalaryStandardEnum.STANDARD_TYPE_MILITARY.getName().equals(name)) {
return BsSalaryStandardEnum.STANDARD_TYPE_MILITARY.getCode();
}
if (BsSalaryStandardEnum.STANDARD_TYPE_NON_MILITARY.getName().equals(name)) {
return BsSalaryStandardEnum.STANDARD_TYPE_NON_MILITARY.getCode();
}
return null;
}
public static String convertStepType(String name){
if (BsSalaryStandardEnum.STEP_TYPE_NON.getName().equals(name)) {
return BsSalaryStandardEnum.STEP_TYPE_NON.getCode();
}
if (BsSalaryStandardEnum.STEP_TYPE_FIXED.getName().equals(name)) {
return BsSalaryStandardEnum.STEP_TYPE_FIXED.getCode();
}
if (BsSalaryStandardEnum.STEP_TYPE_STEP.getName().equals(name)) {
return BsSalaryStandardEnum.STEP_TYPE_STEP.getCode();
}
return null;
}
public static String convertStepUnit(String name){
if (BsSalaryStandardEnum.STEP_UNIT_PIECE.getName().equals(name)) {
return BsSalaryStandardEnum.STEP_UNIT_PIECE.getCode();
}
if (BsSalaryStandardEnum.STEP_UNIT_AREA.getName().equals(name)) {
return BsSalaryStandardEnum.STEP_UNIT_AREA.getCode();
}
return null;
}
public static String convertStepSettlementUnit(String name){
if (BsSalaryStandardEnum.STEP_SETTLEMENT_UNIT_BATCH.getName().equals(name)) {
return BsSalaryStandardEnum.STEP_SETTLEMENT_UNIT_BATCH.getCode();
}
if (BsSalaryStandardEnum.STEP_SETTLEMENT_UNIT_MULTIPLE.getName().equals(name)) {
return BsSalaryStandardEnum.STEP_SETTLEMENT_UNIT_MULTIPLE.getCode();
}
return null;
}
public static String convertSettlementUnit(String name){
if (BsSalaryStandardEnum.SETTLEMENT_UNIT_PIECE.getName().equals(name)) {
return BsSalaryStandardEnum.SETTLEMENT_UNIT_PIECE.getCode();
}
if (BsSalaryStandardEnum.SETTLEMENT_UNIT_BATCH.getName().equals(name)) {
return BsSalaryStandardEnum.SETTLEMENT_UNIT_BATCH.getCode();
}
if (BsSalaryStandardEnum.SETTLEMENT_UNIT_AREA.getName().equals(name)) {
return BsSalaryStandardEnum.SETTLEMENT_UNIT_AREA.getCode();
}
return null;
}
}

@ -0,0 +1,89 @@
package org.springblade.desk.efficiency.excel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
@Data
@ColumnWidth(25)
@HeadRowHeight(20)
@ContentRowHeight(18)
public class BsSalaryStandardExcel implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 规则类型
*/
@ExcelProperty("规则类型")
private String standardType;
/**
* 工序编码
*/
@ExcelProperty("工序编码")
private String processCode;
/**
* 工序名称
*/
@ExcelProperty("工序名称")
private String processName;
/**
* 零件号
*/
@ExcelProperty("零件号")
private String partNo;
/**
* 工人结算价
*/
@ExcelProperty("工人结算价")
private BigDecimal settlementPrice;
/**
* 工人结算单位
*/
@ExcelProperty("工人结算单位")
private String settlementUnit;
/**
* 阶梯类型
*/
@Schema(description = "阶梯类型")
private String stepType;
/**
* 阶梯上下限
*/
@Schema(description = "阶梯上下限")
private String step;
/**
* 阶梯单位
*/
@Schema(description = "阶梯单位")
private String stepUnit;
/**
* 阶梯结算价
*/
@Schema(description = "阶梯结算价")
private String stepSettlementPrice;
/**
* 阶梯结算单位
*/
@Schema(description = "阶梯结算单位")
private String stepSettlementUnit;
}

@ -0,0 +1,29 @@
package org.springblade.desk.efficiency.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.ibatis.annotations.Param;
import org.springblade.desk.efficiency.pojo.entity.BsSalaryStandardEntity;
import org.springblade.desk.efficiency.pojo.vo.BsEfficiencyTaskVO;
import org.springblade.desk.efficiency.pojo.vo.BsSalaryStandardVO;
import java.util.List;
/**
* 薪资规则参数 Mapper 接口
*
* @author BladeX
* @since 2026-04-23
*/
public interface BsSalaryStandardMapper extends BaseMapper<BsSalaryStandardEntity> {
/**
* 自定义分页
*
* @param page 分页参数
* @param bsSalaryStandard 查询参数
* @return List<BsSalaryStandardVO>
*/
List<BsSalaryStandardVO> selectBsSalaryStandardPage(IPage page, BsSalaryStandardVO bsSalaryStandard);
}

@ -26,7 +26,7 @@
SELECT t.*,
bu.real_name as reportUserName,
bu1.real_name as createUserName,
case when t.status = '1' then '进行中' when t.status = '2' then '已完成' when t.status = '3' then '待审批' when t.status = '4' then '审批通过' when t.status = '5' then '审批不通过' when t.status = '6' then '已超期' else '' end as statusName,
case when t.status = '1' then '进行中' when t.status = '2' then '已完成' when t.status = '3' then '待审批' when t.status = '4' then '审批通过' when t.status = '5' then '审批不通过' when t.status = '6' then '已超期' when t.status = '7' then '任务失败' else '' end as statusName,
ba.link as attachLink,
ba.original_name as attackName
FROM BS_EFFICIENCY_TASK t
@ -64,7 +64,7 @@
SELECT t.*,
bu.real_name as reportUserName,
bu1.real_name as createUserName,
case when t.status = '1' then '进行中' when t.status = '2' then '已完成' when t.status = '3' then '待审批' when t.status = '4' then '审批通过' when t.status = '5' then '审批不通过' when t.status = '6' then '已超期' else '' end as statusName,
case when t.status = '1' then '进行中' when t.status = '2' then '已完成' when t.status = '3' then '待审批' when t.status = '4' then '审批通过' when t.status = '5' then '审批不通过' when t.status = '6' then '已超期' when t.status = '7' then '任务失败' else '' end as statusName,
ba.link as attachLink,
ba.original_name as attackName
FROM BS_EFFICIENCY_TASK t

@ -42,10 +42,10 @@
<where>
tr.is_deleted = 0 and t.is_deleted = 0 and t.status = 4
<if test="bsEfficiencyTaskReport.employeeCode!=null">
and tr.EMPLOYEE_CODE like concat(concat('%',#{bsEfficiencyTaskReport.employeeCode},'%')
and tr.EMPLOYEE_CODE like concat(concat('%', #{bsEfficiencyTaskReport.employeeCode}),'%')
</if>
<if test="bsEfficiencyTaskReport.employeeName!=null">
and tr.EMPLOYEE_NAME like concat(concat('%',#{bsEfficiencyTaskReport.employeeName},'%')
and tr.EMPLOYEE_NAME like concat(concat('%', #{bsEfficiencyTaskReport.employeeName}),'%')
</if>
</where>
GROUP BY
@ -66,10 +66,10 @@
and tr.TASK_ID = #{taskId}
</if>
<if test="employeeCode!=null">
and tr.EMPLOYEE_CODE like concat(concat('%',#{employeeCode},'%')
and tr.EMPLOYEE_CODE like concat(concat('%', #{employeeCode}),'%')
</if>
<if test="employeeName!=null">
and tr.EMPLOYEE_NAME like concat(concat('%',#{employeeName},'%')
and tr.EMPLOYEE_NAME like concat(concat('%', #{employeeName}),'%')
</if>
<if test="employeeCodeExact!=null">
and tr.EMPLOYEE_CODE = #{employeeCodeExact}

@ -0,0 +1,151 @@
<?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="org.springblade.desk.efficiency.mapper.BsSalaryStandardMapper">
<!-- 通用查询映射结果 -->
<resultMap id="bsSalaryStandardResultMap" type="org.springblade.desk.efficiency.pojo.vo.BsSalaryStandardVO">
<result column="ID" property="id"/>
<result column="STANDARD_TYPE" property="standardType"/>
<result column="PROCESS_ID" property="processId"/>
<result column="PART_NO" property="partNo"/>
<result column="SETTLEMENT_PRICE" property="settlementPrice"/>
<result column="SETTLEMENT_UNIT" property="settlementUnit"/>
<result column="STEP_TYPE" property="stepType"/>
<result column="STEP" property="step"/>
<result column="STEP_UNIT" property="stepUnit"/>
<result column="STEP_SETTLEMENT_PRICE" property="stepSettlementPrice"/>
<result column="STEP_SETTLEMENT_UNIT" property="stepSettlementUnit"/>
<result column="CREATE_USER" property="createUser"/>
<result column="CREATE_DEPT" property="createDept"/>
<result column="CREATE_TIME" property="createTime"/>
<result column="UPDATE_USER" property="updateUser"/>
<result column="UPDATE_TIME" property="updateTime"/>
<result column="STATUS" property="status"/>
<result column="IS_DELETED" property="isDeleted"/>
<result column="PROCESS_NAME" property="processName"/>
</resultMap>
<select id="selectBsSalaryStandardPage" resultMap="bsSalaryStandardResultMap">
WITH STEP_DATA AS (
SELECT
t.ID,
t.STANDARD_TYPE,
t.PROCESS_ID,
t.PART_NO,
t.SETTLEMENT_PRICE,
t.SETTLEMENT_UNIT,
t.STEP_TYPE,
t.STEP,
t.STEP_UNIT,
t.STEP_SETTLEMENT_PRICE,
t.STEP_SETTLEMENT_UNIT,
t.CREATE_USER,
t.CREATE_DEPT,
t.CREATE_TIME,
t.UPDATE_USER,
t.UPDATE_TIME,
t.STATUS,
t.IS_DELETED,
ps.NAME as PROCESS_NAME
FROM BS_SALARY_STANDARD t
LEFT JOIN BS_PROCESS_SET ps ON t.PROCESS_ID = ps.ID and ps.is_deleted = 0
<where>
t.is_deleted = 0
<if test="bsSalaryStandard.processName!=null">
and ps.name like concat(concat('%', #{bsSalaryStandard.processName}),'%')
</if>
</where>
),
STEP_NUMBERS AS ( SELECT LEVEL AS n FROM DUAL CONNECT BY LEVEL <![CDATA[ <= ]]> 100 ) SELECT
ID,
STANDARD_TYPE,
PROCESS_ID,
PART_NO,
SETTLEMENT_PRICE,
SETTLEMENT_UNIT,
STEP_TYPE,
STEP,
STEP_UNIT,
STEP_SETTLEMENT_PRICE,
STEP_SETTLEMENT_UNIT,
CREATE_USER,
CREATE_DEPT,
CREATE_TIME,
UPDATE_USER,
UPDATE_TIME,
STATUS,
IS_DELETED,
PROCESS_NAME,
minStep,
maxStep,
PRICE
FROM
(
SELECT
ID,
STANDARD_TYPE,
PROCESS_ID,
PART_NO,
SETTLEMENT_PRICE,
SETTLEMENT_UNIT,
STEP_TYPE,
STEP,
STEP_UNIT,
STEP_SETTLEMENT_PRICE,
STEP_SETTLEMENT_UNIT,
CREATE_USER,
CREATE_DEPT,
CREATE_TIME,
UPDATE_USER,
UPDATE_TIME,
STATUS,
IS_DELETED,
PROCESS_NAME,
NULL AS minStep,
NULL AS maxStep,
TO_NUMBER(STEP_SETTLEMENT_PRICE) AS PRICE
FROM
STEP_DATA
WHERE
STEP_TYPE IN ( 1, 2 ) UNION ALL
SELECT
sd.ID,
sd.STANDARD_TYPE,
sd.PROCESS_ID,
sd.PART_NO,
sd.SETTLEMENT_PRICE,
sd.SETTLEMENT_UNIT,
sd.STEP_TYPE,
sd.STEP,
sd.STEP_UNIT,
sd.STEP_SETTLEMENT_PRICE,
sd.STEP_SETTLEMENT_UNIT,
sd.CREATE_USER,
sd.CREATE_DEPT,
sd.CREATE_TIME,
sd.UPDATE_USER,
sd.UPDATE_TIME,
sd.STATUS,
sd.IS_DELETED,
sd.PROCESS_NAME,
CASE
WHEN sn.n = 1 THEN
0 ELSE TO_NUMBER( REGEXP_SUBSTR( sd.STEP, '[^ ]+', 1, sn.n - 1 ) )
END AS minStep,
CASE
WHEN sn.n <![CDATA[ <= ]]> REGEXP_COUNT ( sd.STEP, ' ' ) + 1 THEN
TO_NUMBER( REGEXP_SUBSTR( sd.STEP, '[^ ]+', 1, sn.n ) ) ELSE NULL
END AS maxStep,
TO_NUMBER( REGEXP_SUBSTR( sd.STEP_SETTLEMENT_PRICE, '[^ ]+', 1, sn.n ) ) AS PRICE
FROM
STEP_DATA sd
JOIN STEP_NUMBERS sn ON sn.n <![CDATA[ <= ]]> REGEXP_COUNT ( sd.STEP_SETTLEMENT_PRICE, ' ' ) + 1
WHERE
sd.STEP_TYPE = 3
)
ORDER BY
ID,
minStep NULLS FIRST
</select>
</mapper>

@ -0,0 +1,103 @@
package org.springblade.desk.efficiency.pojo.dto;
import lombok.Data;
import java.io.Serial;
@Data
public class BsSalaryCalculationDTO {
@Serial
private static final long serialVersionUID = 1L;
/**
* 订单号
*/
private String woCode;
/**
* 流程卡号
*/
private String cardNo;
/**
* 开始时间
*/
private String startDate;
/**
* 结束时间
*/
private String endDate;
/**
* 产品型号
*/
private String productType;
/**
* 镀种
*/
private String plate;
/**
* 作业中心名称
*/
private String wcName;
/**
* 作业中心ID
*/
private String wcId;
/**
* 作业中心ID
*/
private String wcIds;
/**
* 工序ID
*/
private String ppsId;
/**
* 工序ID
*/
private String ppsIds;
/**
* 工序名称
*/
private String ppsName;
/**
* 生产标识
*/
private String prodIdent;
/**
* 生产标识
*/
private String prodIdents;
/**
* 最小单批数量
*/
private String minSingleBatchNo;
/**
* 最大单批数量
*/
private String maxSingleBatchNo;
/**
* 最小总面积
*/
private String minTotalArea;
/**
* 最大总面积
*/
private String maxTotalArea;
}

@ -0,0 +1,84 @@
package org.springblade.desk.efficiency.pojo.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springblade.core.mp.base.BaseEntity;
import java.math.BigDecimal;
/**
* 薪资标准 实体类
*
* @author BladeX
* @since 2026-04-23
*/
@Data
@TableName("BS_SALARY_STANDARD")
@Schema(description = "BsSalaryStandard对象")
@EqualsAndHashCode(callSuper = true)
public class BsSalaryStandardEntity extends BaseEntity {
/**
* 规则类型
*/
@Schema(description = "规则类型")
private String standardType;
/**
* 工序ID
*/
@Schema(description = "工序ID")
private Long processId;
/**
* 零件号
*/
@Schema(description = "零件号")
private String partNo;
/**
* 工人结算价
*/
@Schema(description = "工人结算价")
private BigDecimal settlementPrice;
/**
* 工人结算单位
*/
@Schema(description = "工人结算单位")
private String settlementUnit;
/**
* 阶梯类型
*/
@Schema(description = "阶梯类型")
private String stepType;
/**
* 阶梯
*/
@Schema(description = "阶梯")
private String step;
/**
* 阶梯单位
*/
@Schema(description = "阶梯单位")
private String stepUnit;
/**
* 阶梯结算价
*/
@Schema(description = "阶梯结算价")
private String stepSettlementPrice;
/**
* 阶梯结算单位
*/
@Schema(description = "阶梯结算单位")
private String stepSettlementUnit;
}

@ -0,0 +1,163 @@
package org.springblade.desk.efficiency.pojo.vo;
import lombok.Data;
import java.io.Serial;
@Data
public class BsSalaryCalculationVO {
@Serial
private static final long serialVersionUID = 1L;
/**
* 订单号
*/
private String woCode;
/**
* 零件号
*/
private String partCode;
/**
* 零件名称
*/
private String partName;
/**
* 批次号
*/
private String batchNo;
/**
* 使用部门
*/
private String useDept;
/**
* 镀种
*/
private String plate;
/**
* 作业中心
*/
private String wcName;
/**
* 班组
*/
private String team;
/**
* 工序
*/
private String ppsName;
/**
* 定额工时
*/
private String hourQuota;
/**
* 准备工时
*/
private String hourPrepar;
/**
* 工时额定单位
*/
private String hqUnit;
/**
* 报工数
*/
private String workQty;
/**
* 总工时
*/
private String hourTotal;
/**
* 责任人
*/
private String worker;
/**
* 厚度
*/
private String plateThickness;
/**
* 产品系列
*/
private String productType;
/**
* 生产标识
*/
private String prodIdent;
/**
* 单批数量
*/
private String singleBatchNo;
/**
* 入库数量
*/
private String putQuantity;
/**
* 报废数量
*/
private String scrapQty;
/**
* 消耗数量
*/
private String lossQty;
/**
* 试验数量
*/
private String testQty;
/**
* 单件面积(dm²)
*/
private String poArea;
/**
* 总面积(d)
*/
private String totalArea;
/**
* 镀后入库时间
*/
private String putStoreTime;
/**
* 金额
*/
private String wpMoney;
/**
* 基础薪资金额
*/
private String baseAmount;
/**
* 补贴薪资金额
*/
private String subsidyAmount;
/**
* 总薪资金额
*/
private String totalAmount;
}

@ -0,0 +1,38 @@
package org.springblade.desk.efficiency.pojo.vo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springblade.desk.efficiency.pojo.entity.BsSalaryStandardEntity;
import java.io.Serial;
import java.math.BigDecimal;
@Data
@EqualsAndHashCode(callSuper = true)
public class BsSalaryStandardVO extends BsSalaryStandardEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 工序名称
*/
private String processName;
/**
* 阶梯下限
*/
private BigDecimal minStep;
/**
* 阶梯上限
*/
private BigDecimal maxStep;
/**
* 阶梯价格
*/
private BigDecimal price;
}

@ -0,0 +1,34 @@
package org.springblade.desk.efficiency.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.core.mp.base.BaseService;
import org.springblade.desk.efficiency.pojo.entity.BsSalaryStandardEntity;
import org.springblade.desk.efficiency.pojo.vo.BsSalaryStandardVO;
/**
* 薪资规则 服务类
*
* @author BladeX
* @since 2026-04-20
*/
public interface IBsSalaryStandardService extends BaseService<BsSalaryStandardEntity> {
/**
* 自定义分页
*
* @param page 分页参数
* @param bsSalaryStandard 查询参数
* @return IPage<BsSalaryStandardVO>
*/
IPage<BsSalaryStandardVO> selectBsSalaryStandardPage(IPage<BsSalaryStandardVO> page, BsSalaryStandardVO bsSalaryStandard);
/**
* 查询匹配的薪资标准
*
* @param processId 工序ID
* @param partNo 零件号
* @param standardType 薪资标准类型
* @return
*/
BsSalaryStandardEntity getStandard(Long processId, String partNo, String standardType);
}

@ -61,6 +61,12 @@ public class BsEfficiencyTempServiceImpl extends BaseServiceImpl<BsEfficiencyTem
mainTask.setParentId(0L);
bsEfficiencyTaskService.save(mainTask);
} else {
if(mainTask.getStatus() == BsEfficiencyTaskEnum.STATUS_FAIL.getCode()){
BsEfficiencyTaskEntity upd = new BsEfficiencyTaskEntity();
upd.setId(mainTask.getId());
upd.setStatus(BsEfficiencyTaskEnum.STATUS_IN_PROGRESS.getCode());
bsEfficiencyTaskService.updateById(upd);
}
if (mainTask.getStatus() == BsEfficiencyTaskEnum.STATUS_PENDING_APPROVAL.getCode() || mainTask.getStatus() == BsEfficiencyTaskEnum.STATUS_APPROVED.getCode()) {
return R.fail("绩效任务已填报,不能再下发了");
}

@ -0,0 +1,37 @@
package org.springblade.desk.efficiency.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.desk.efficiency.mapper.BsSalaryStandardMapper;
import org.springblade.desk.efficiency.pojo.entity.BsSalaryStandardEntity;
import org.springblade.desk.efficiency.pojo.vo.BsSalaryStandardVO;
import org.springblade.desk.efficiency.service.IBsSalaryStandardService;
import org.springblade.desk.efficiency.util.BsSalaryUtil;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
/**
* 薪资规则 服务实现类
*
* @author BladeX
* @since 2026-04-23
*/
@Service
public class BsSalaryStandardServiceImpl extends BaseServiceImpl<BsSalaryStandardMapper, BsSalaryStandardEntity> implements IBsSalaryStandardService {
@Override
public IPage<BsSalaryStandardVO> selectBsSalaryStandardPage(IPage<BsSalaryStandardVO> page, BsSalaryStandardVO bsSalaryStandard) {
return page.setRecords(baseMapper.selectBsSalaryStandardPage(page, bsSalaryStandard));
}
@Override
public BsSalaryStandardEntity getStandard(Long processId, String partNo, String standardType) {
List<BsSalaryStandardEntity> standardList = this.list(new LambdaQueryWrapper<BsSalaryStandardEntity>().eq(BsSalaryStandardEntity::getProcessId, processId).in(BsSalaryStandardEntity::getStandardType, Arrays.asList(standardType, "1")));
BsSalaryStandardEntity bsSalaryStandardEntity = BsSalaryUtil.matchBestRule(standardList, partNo, Integer.getInteger(standardType));
return bsSalaryStandardEntity;
}
}

@ -0,0 +1,163 @@
package org.springblade.desk.efficiency.util;
import org.springblade.desk.efficiency.enums.BsSalaryStandardEnum;
import org.springblade.desk.efficiency.pojo.entity.BsSalaryStandardEntity;
import org.springframework.util.StringUtils;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class BsSalaryUtil {
/**
* 最终入口方法返回匹配到的唯一最高优先级规则
*
* @param ruleList 从数据库查出的规则按工序+类型
* @param inputPartNo 前端输入的零件号 4005
* @param standardType 2军品 3非军品
* @return 唯一匹配规则
*/
public static BsSalaryStandardEntity matchBestRule(List<BsSalaryStandardEntity> ruleList, String inputPartNo, Integer standardType) {
if (ruleList == null || ruleList.isEmpty()) return null;
return ruleList.stream()
.filter(rule -> isMatch(rule.getPartNo(), inputPartNo))
.sorted(comparator(standardType)) // 按优先级排序
.findFirst()
.orElse(null);
}
/**
* 核心零件号匹配方法
*
* @param rulePartNo 规则100 200 300 400%
* @param inputPartNo 输入4005
*/
private static boolean isMatch(String rulePartNo, String inputPartNo) {
// 规则为空 → 直接匹配(兜底)
if (!StringUtils.hasText(rulePartNo)) {
return true;
}
// 按空格拆分规则段
String[] parts = rulePartNo.split("\\s+");
for (String part : parts) {
if (matchSinglePart(part, inputPartNo)) {
return true; // 任意一段匹配就成功
}
}
return false;
}
/**
* 单段匹配支持 % 通配符
* 400% ^400.*$
*/
private static boolean matchSinglePart(String rulePart, String input) {
if (!StringUtils.hasText(rulePart) || !StringUtils.hasText(input)) {
return false;
}
// 把 % 转成正则 .* (只允许后缀%)
String regex = rulePart.replace("%", ".*");
return Pattern.matches(regex, input);
}
/**
* 优先级排序器
*/
private static Comparator<BsSalaryStandardEntity> comparator(Integer salaryType) {
return (r1, r2) -> {
int p1 = getPriority(r1, salaryType);
int p2 = getPriority(r2, salaryType);
return Integer.compare(p1, p2); // 小的在前
};
}
/**
* 计算优先级数字越小越优先
*/
private static int getPriority(BsSalaryStandardEntity rule, Integer standardType) {
boolean isEmpty = !StringUtils.hasText(rule.getPartNo());
boolean isMatch = isMatch(rule.getPartNo(), "dummy"); // 外层已过滤
if (standardType == 2) { // 军品
if (Integer.parseInt(rule.getStandardType()) == 2 && isMatch) return 1;
if (Integer.parseInt(rule.getStandardType()) == 2 && isEmpty) return 2;
if (Integer.parseInt(rule.getStandardType()) == 1 && isMatch) return 3;
if (Integer.parseInt(rule.getStandardType()) == 1 && isEmpty) return 4;
} else { // 非军品
if (Integer.parseInt(rule.getStandardType()) == 3 && isMatch) return 1;
if (Integer.parseInt(rule.getStandardType()) == 3 && isEmpty) return 2;
if (Integer.parseInt(rule.getStandardType()) == 1 && isMatch) return 3;
if (Integer.parseInt(rule.getStandardType()) == 1 && isEmpty) return 4;
}
return 99;
}
/**
* 计算阶梯价格
*
* @param stepStr
* @param stepPriceStr
* @param count
* @return
*/
public static BigDecimal calcStepAmount(String stepStr, String stepPriceStr, BigDecimal count, String stepSettlementUnit, BigDecimal settlementPrice) {
// 空值校验
if (!StringUtils.hasText(stepStr) || !StringUtils.hasText(stepPriceStr) || count == null || count.compareTo(BigDecimal.ZERO) <= 0) {
return BigDecimal.ZERO;
}
// 解析阶梯区间
List<BigDecimal> stepList = Arrays.stream(stepStr.split(" "))
.filter(StringUtils::hasText)
.map(BigDecimal::new)
.collect(Collectors.toList());
// 解析阶梯价格
List<BigDecimal> priceList = Arrays.stream(stepPriceStr.split(" "))
.filter(StringUtils::hasText)
.map(BigDecimal::new)
.collect(Collectors.toList());
// 格式非法:价格必须比阶梯多1位
if (priceList.size() != stepList.size() + 1) {
return BigDecimal.ZERO;
}
BigDecimal totalAmount = BigDecimal.ZERO;
BigDecimal remain = count;
BigDecimal preStep = BigDecimal.ZERO;
// 遍历每一档阶梯
BigDecimal one = new BigDecimal(1);
for (int i = 0; i < stepList.size() && remain.compareTo(BigDecimal.ZERO) > 0; i++) {
BigDecimal currStep = stepList.get(i).subtract(one);
BigDecimal stepDiff = currStep.subtract(preStep);
// 当前区间实际耗用数量
BigDecimal useNum = remain.min(stepDiff);
// 累加金额
if (BsSalaryStandardEnum.STEP_SETTLEMENT_UNIT_BATCH.getCode().equals(stepSettlementUnit)) {
totalAmount = totalAmount.add(priceList.get(i));
}
if (BsSalaryStandardEnum.STEP_SETTLEMENT_UNIT_MULTIPLE.getCode().equals(stepSettlementUnit)) {
totalAmount = totalAmount.add(useNum.multiply(priceList.get(i)).multiply(settlementPrice));
}
// 剩余数量
remain = remain.subtract(useNum);
// 记录上一档阶梯
preStep = currStep;
}
// 超出所有阶梯的部分,取最后一档价格
if (remain.compareTo(BigDecimal.ZERO) > 0) {
BigDecimal lastPrice = priceList.get(priceList.size() - 1);
if (BsSalaryStandardEnum.STEP_SETTLEMENT_UNIT_BATCH.getCode().equals(stepSettlementUnit)) {
totalAmount = totalAmount.add(lastPrice);
}
if (BsSalaryStandardEnum.STEP_SETTLEMENT_UNIT_MULTIPLE.getCode().equals(stepSettlementUnit)) {
totalAmount = totalAmount.add(remain.multiply(lastPrice).multiply(settlementPrice));
}
}
return totalAmount;
}
}

@ -32,7 +32,7 @@
left join blade_user u on u.id = n.INS_MAN
<where>
n.is_deleted = 0
<if test="bsEpciuPatrolInspection.taskStatus!=null">
<if test="bsEpciuPatrolInspection.taskStatus!=null and bsEpciuPatrolInspection.taskStatus!= ''">
and n.TASK_STATUS = #{bsEpciuPatrolInspection.taskStatus}
</if>
<if test="bsEpciuPatrolInspection.insNum!=null and bsEpciuPatrolInspection.insNum!=''">
@ -41,19 +41,19 @@
<if test="bsEpciuPatrolInspection.insSite!=null and bsEpciuPatrolInspection.insSite!=''">
and n.INS_SITE like '%' || #{bsEpciuPatrolInspection.insSite} || '%'
</if>
<if test="bsEpciuPatrolInspection.insType!=null">
<if test="bsEpciuPatrolInspection.insType!=null and bsEpciuPatrolInspection.insType!=''">
and n.INS_TYPE = #{bsEpciuPatrolInspection.insType}
</if>
<if test="bsEpciuPatrolInspection.insMan!=null and bsEpciuPatrolInspection.insMan!=''">
and n.INS_MAN like '%' || #{bsEpciuPatrolInspection.insMan} || '%'
</if>
<if test="bsEpciuPatrolInspection.insType!=null">
<if test="bsEpciuPatrolInspection.insType!=null and bsEpciuPatrolInspection.insType!=''">
and n.INS_TYPE = #{bsEpciuPatrolInspection.insType}
</if>
<if test="bsEpciuPatrolInspection.queryLaunchTime!=null">
<if test="bsEpciuPatrolInspection.queryLaunchTime!=null and bsEpciuPatrolInspection.queryLaunchTime!= ''">
and n.LAUNCH_TIME BETWEEN to_date(#{bsEpciuPatrolInspection.startDate},'YYYY-MM-DD HH24:MI:SS') AND to_date(#{bsEpciuPatrolInspection.endDate},'YYYY-MM-DD HH24:MI:SS')
</if>
<if test="bsEpciuPatrolInspection.queryTestTime!=null">
<if test="bsEpciuPatrolInspection.queryTestTime!=null and bsEpciuPatrolInspection.queryTestTime!=''">
and n.TEST_TIME BETWEEN to_date(#{bsEpciuPatrolInspection.startTestDate},'YYYY-MM-DD HH24:MI:SS') AND to_date(#{bsEpciuPatrolInspection.endTestDate},'YYYY-MM-DD HH24:MI:SS')
</if>
</where>

@ -124,7 +124,7 @@ public class BsEpciuPatrolInspectionServiceImpl extends BaseServiceImpl<BsEpciuP
BsEpciuPatrolInspectionEntity epPatrolInspection;
for (BsEpciuInspectionPointEntity epInspectionPoint : epInspectionPointList) {
epPatrolInspection = new BsEpciuPatrolInspectionEntity();
// 如果是整点
// 如果是整8
if (flag) {
epPatrolInspection.setEpcId(epInspectionPoint.getId());
epPatrolInspection.setInsNum(epInspectionPoint.getInsNum());
@ -150,14 +150,14 @@ public class BsEpciuPatrolInspectionServiceImpl extends BaseServiceImpl<BsEpciuP
SimpleDateFormat format = new SimpleDateFormat("HH");
String lastHours = format.format(lastInsCycle);
// 下次触发时间
Long insCycle = epInspectionPoint.getInsCycle() + Integer.valueOf(lastHours);
Long insCycle = epInspectionPoint.getInsCycle() + Integer.parseInt(lastHours);
if (insCycle < 24) {
// 如果当前时间与下次触发时间一样就生成任务
isAdd = hour == insCycle;
// 特殊情况下服务器停的时间过长
if (Integer.valueOf(lastHours) + epInspectionPoint.getInsCycle() < hour) {
if (insCycle < hour) {
isAdd = true;
}
} else {

@ -41,6 +41,7 @@ import org.springblade.desk.energy.pojo.entity.BsSafePatrolInspectionEntity;
import org.springblade.desk.energy.pojo.vo.BsSafePatrolInspectionVO;
import org.springblade.desk.energy.service.IBsSafeInspectionPointService;
import org.springblade.desk.energy.service.IBsSafePatrolInspectionService;
import org.springblade.desk.energy.util.DateTools;
import org.springframework.stereotype.Service;
import java.util.Date;
@ -89,9 +90,10 @@ public class BsSafePatrolInspectionServiceImpl extends BaseServiceImpl<BsSafePat
@Override
public void createSafPatrolTask() {
// 如果是节假日就不需要生产任务
// if (DateTools.isHoliday()) {
// return;
// }
if (DateTools.isHoliday()) {
return;
}
//查询巡检配置
List<BsSafeInspectionPointEntity> ipLiST = bsSafeInspectionPointService.list();
if (ipLiST.size() == 0) {
@ -107,13 +109,16 @@ public class BsSafePatrolInspectionServiceImpl extends BaseServiceImpl<BsSafePat
pi.setInsMemo(ip.getMemo());
pi.setLaunchTime(new Date());
pi.setTaskStatus(BsSafePatrolInspectionEntity.PREPARE_TEXT.toString());
baseMapper.insertOrUpdate(pi);
//修改insertOrUpdate为insert避免歧义
baseMapper.insert(pi);
}
}
@Override
public void handleSafPatrolTask() {
baseMapper.update(Wrappers.<BsSafePatrolInspectionEntity>update().lambda().set(BsSafePatrolInspectionEntity::getTaskStatus, BsSafePatrolInspectionEntity.NO_CHECK).eq(BsSafePatrolInspectionEntity::getTaskStatus, BsSafePatrolInspectionEntity.PREPARE_TEXT));
baseMapper.update(Wrappers.<BsSafePatrolInspectionEntity>update().lambda()
.set(BsSafePatrolInspectionEntity::getTaskStatus, BsSafePatrolInspectionEntity.NO_CHECK)
.eq(BsSafePatrolInspectionEntity::getTaskStatus, BsSafePatrolInspectionEntity.PREPARE_TEXT));
}
@Override

@ -0,0 +1,498 @@
package org.springblade.desk.energy.util;/**
* @date : 2026/4/25 11:47
*/
import com.alibaba.fastjson.JSONObject;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
/**
* 文件名称
* @module 归属项目
* @author ***
* @date 2025/11/26 10:27
*/
public class DateTools {
/**
* 查询今日是否是节假日
*
* @return
*/
public static Boolean isHoliday() {
//IBsFactoryCalDataService bsFactoryCalDataService = (IBsFactoryCalDataService) SpringContextUtil.getBean("bsFactoryCalDataService");
//
//Calendar c = Calendar.getInstance();
//c.setTime(new Date());
//
//int YY = c.get(Calendar.YEAR);
//int MM = c.get(Calendar.MONTH) + 1;
//int DD = c.get(Calendar.DATE);
//
//StringBuffer sb = new StringBuffer();
//sb.append(YY);
//sb.append(MM < 10 ? "0" : "").append(MM);
//sb.append(DD < 10 ? "0" : "").append(DD);
//BsFactoryCalData bsFactoryCalData = bsFactoryCalDataService.getByYmd(Integer.valueOf(sb.toString()));
//
//return bsFactoryCalData == null ? false : bsFactoryCalData.getDayOff() == 1 ? true : false;
return false;
}
/**
* 获取当前日期的往后day天的所有日期集合
*
* @return
*/
public static List<Date> listNextDayDates(Integer day) {
Calendar cal1 = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();
cal1.setTime(new Date());
cal2.setTime(new Date());
cal1.add(Calendar.DAY_OF_MONTH, 0);
cal2.add(Calendar.DAY_OF_MONTH, day);
Calendar cStart = Calendar.getInstance();
cStart.setTime(cal1.getTime());
List dateList = new ArrayList();
//别忘了,把起始日期加上
dateList.add(cal1.getTime());
// 此日期是否在指定日期之后
while (cal2.getTime().after(cStart.getTime())) {
// 根据日历的规则,为给定的日历字段添加或减去指定的时间量
cStart.add(Calendar.DAY_OF_MONTH, 1);
dateList.add(cStart.getTime());
}
return dateList;
}
/**
* 获取当前时 Calendar.HOUR_OF_DAY
*
* @return
*/
public static Integer getDateTime(int cal) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
int i = calendar.get(cal);
if (Calendar.MONTH == cal) {
i += 1;
}
return i;
}
/**
* 获取传入日期时 Calendar.HOUR_OF_DAY
*
* @return
*/
public static Integer getDateTime(Date date, int cal) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int i = calendar.get(cal);
if (Calendar.MONTH == cal) {
i += 1;
}
return i;
}
/**
* 补全数值类型
*
* @return
*/
public static String repairVal(Integer val) {
String valStr = null;
if (val < 10) {
valStr = "0" + val;
} else {
valStr = "" + val;
}
return valStr;
}
/**
* 获取月多少天
*
* @return
*/
public static Integer getMonthHowDay(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
}
/**
* 获取月份最小日期时间
*
* @param d
* @return
*/
public static final String getDateWithoutTime(Date d) {
if (d == null) {
return null;
} else {
Calendar c = Calendar.getInstance();
c.setTime(d);
c.set(Calendar.DATE, 1);
c.set(11, 0);
c.set(12, 0);
c.set(13, 0);
c.set(14, 0);
return DateTime.date2String(c.getTime(), true, true);
}
}
/**
* 获取月份最大日期时间
*
* @param d
* @return
*/
public static final String getDateWithMaxTime(Date d) {
Calendar c = Calendar.getInstance();
c.setTime(d);
c.set(Calendar.DATE, DateTools.getMonthHowDay(d));
c.set(11, 23);
c.set(12, 59);
c.set(13, 59);
c.set(14, 999);
return DateTime.date2String(c.getTime(), true, true);
}
/**
* 获取当年的第一天
*
* @return
*/
public static final String getCurrYearFirst() {
Calendar currCal = Calendar.getInstance();
int currentYear = currCal.get(Calendar.YEAR);
return getYearFirst(currentYear);
}
/**
* 获取当年的最后一天
*
* @return
*/
public static final String getCurrYearLast() {
Calendar currCal = Calendar.getInstance();
int currentYear = currCal.get(Calendar.YEAR);
return getYearLast(currentYear);
}
/**
* 获取某年第一天日期
*
* @param year 年份
* @return Date
*/
public static final String getYearFirst(int year) {
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(Calendar.YEAR, year);
return DateTime.date2String(calendar.getTime(), true, true);
}
/**
* 获取某年最后一天日期
*
* @param year 年份
* @return Date
*/
public static final String getYearLast(int year) {
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(Calendar.YEAR, year);
calendar.roll(Calendar.DAY_OF_YEAR, -1);
return DateTime.date2String(calendar.getTime(), true, true);
}
/**
* 获得本月的开始时间
*
* @return
*/
public static String getMonthStartTimeStr(Date date) {
Calendar c = Calendar.getInstance();
c.clear();
c.setTime(date);
c.set(Calendar.DATE, 1);
return new SimpleDateFormat("yyyy-MM-dd").format(c.getTime()) + " 00:00:00";
}
/**
* 本月的结束时间
*
* @return
*/
public static String getMonthEndTimeStr(Date date) {
Calendar c = Calendar.getInstance();
c.clear();
c.setTime(date);
c.set(Calendar.DATE, 1);
c.add(Calendar.MONTH, 1);
c.add(Calendar.DATE, -1);
return new SimpleDateFormat("yyyy-MM-dd").format(c.getTime()) + " 23:59:59";
}
/**
* 获取某年开始时间
*
* @return Date
*/
public static final String getYearStartTimeStr(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.setTime(date);
return calendar.get(Calendar.YEAR) + "-01-01 00:00:00";
}
/**
* 获取某年结束时间
*
* @return Date
*/
public static final String getYearEndTimeStr(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.setTime(date);
return calendar.get(Calendar.YEAR) + "-12-31 23:59:59";
}
/**
* <p>方法名: getTomorrow </p>
* <p>方法描述: 获取当前日期后几天 </p>
*
* @param day
* @author lyj
* @date 2022-02-19 16:59
*/
public static final String getTomorrow(int day) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, day);
return DateTime.date2String(calendar.getTime(), true, true);
}
/**
* <p>方法名: getYesterday </p>
* <p>方法描述: 获取当前日期前几天 </p>
*
* @param day
* @author lyj
* @date 2022-02-19 16:59
*/
public static final String getYesterday(int day) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, -day);
return DateTime.date2String(calendar.getTime(), true, true);
}
public static Date dateAdd(Date date, int x) {
//入参的格式
// 24小时制
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
if (date == null) {
return null;
}
Calendar cal = Calendar.getInstance();
cal.setTime(date);
// 24小时制
cal.add(Calendar.DATE, x);
//得到结算后的结果 yyyy-MM-dd HH:mm
date = cal.getTime();
return date;
}
public static Date dateAdd(Date date, int field, int x) {
//入参的格式
// 24小时制
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
if (date == null) {
return null;
}
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(field, x);
//得到结算后的结果 yyyy-MM-dd HH:mm
date = cal.getTime();
return date;
}
/**
* <p>Description: 计算间隔天数 </p>
*
* @param date
* @param remDays
* @return: int
* @Author qjh
* @Date: 2022-10-11 9:11
*/
public static int cycleDay(Date date, Integer remDays) {
int days = ((int) (System.currentTimeMillis() / 1000) - (int) (date.getTime() / 1000)) / (60 * 60 * 24);
if (remDays != null) {
days += remDays;
}
return days;
}
/**
* 根据当前日期返回日期范围
*
* @return
*/
public static JSONObject getQuantityDate() {
Calendar cal = Calendar.getInstance();
int YY = cal.get(Calendar.YEAR);
int MM = cal.get(Calendar.MONTH) + 1;
int DD = cal.get(Calendar.DATE);
JSONObject obj = new JSONObject();
String str1 = "";
String str2 = "";
String str3 = "";
String str4 = "";
// 如果当前日期大于20,返回本月21号,下月20
if (DD > 20) {
// 本月
str1 = YY + "-" + MM + "-" + "21 00:00:00";
if (MM == 12) {
str2 = (YY + 1) + "-" + 1 + "-" + "20 23:59:59";
} else {
str2 = YY + "-" + (MM + 1) + "-" + "20 23:59:59";
}
str3 = String.valueOf(MM);
str4 = String.valueOf(YY);
} else {
str3 = String.valueOf(MM);
str4 = String.valueOf(YY);
// 返回上月21号,本月20
if (MM == 1) {
str1 = (YY - 1) + "-" + 12 + "-" + "21 00:00:00";
str4 = String.valueOf(YY - 1);
} else {
str1 = YY + "-" + (MM - 1) + "-" + "21 00:00:00";
str3 = String.valueOf(MM - 1);
}
str2 = YY + "-" + MM + "-" + "20 23:59:59";
}
obj.put("YY", str4 + "-1-1 00:00:00");
obj.put("MM", str3);
obj.put("startTime", str1);
obj.put("endTime", str2);
return obj;
}
/**
* 获取传入日期的年月
*
* @return
*/
public static String getYearMonth(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int year = cal.get(Calendar.YEAR);
String month = cal.get(Calendar.MONTH) + 1 >= 10 ? String.valueOf(cal.get(Calendar.MONTH) + 1) : "0" + (cal.get(Calendar.MONTH) + 1);
return year + "-" + month;
}
/**
* 根据当前日期获取上个月减去N天的日期
*
* @return
*/
public static String getLastMonthData(Integer day) {
Calendar cal = Calendar.getInstance();
int YY = cal.get(Calendar.YEAR);
int MM = cal.get(Calendar.MONTH);
int DD = cal.get(Calendar.DATE);
String mm = MM < 10 ? "0" + MM : MM + "";
String dd = DD < 10 ? "0" + DD : DD + "";
Integer monthHowDay = DateTools.getMonthHowDay(DateTime.parse(YY + "-" + mm + "-" + dd + " 00:00:00"));
DD = monthHowDay - day + 1;
System.out.println(YY + "-" + mm + "-" + DD + " 00:00:00");
return YY + "-" + mm + "-" + DD + " 00:00:00";
}
/**
* 功能描述: 获取上一周的开始时间和结束时间
*/
public static JSONObject getLastWeekStartOrEndDayOfWeek(Integer weekNum) {
JSONObject obj = new JSONObject();
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, -7 * weekNum); // 获取上一周
calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); // 设置为周一
Date monday = calendar.getTime();
calendar.add(Calendar.DATE, 6); // 设置为周日
Date sunday = calendar.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
obj.put("monday",sdf.format(monday));
obj.put("sunday",sdf.format(sunday));
return obj;
}
//20240929 新建以下方法 获取25-25号的时间
public static JSONObject getStartEndDate() {
Calendar cal = Calendar.getInstance();
int YY = cal.get(Calendar.YEAR);
int MM = cal.get(Calendar.MONTH) + 1;
int DD = cal.get(Calendar.DATE);
JSONObject obj = new JSONObject();
String str1 = "";
String str2 = "";
// 如果当前日期大于25,返回本月25号,下月25
if (DD > 25) {
// 本月
str1 = YY + "-" + (MM > 9 ? MM : "0" + MM) + "-" + "25 00:00:00";
if (MM == 12) {
str2 = (YY + 1) + "-" + "01" + "-" + "25 23:59:59";
} else {
str2 = YY + "-" + ((MM + 1) > 9 ? (MM + 1) : "0" + (MM + 1)) + "-" + "25 23:59:59";
}
} else {
// 返回上月25号,本月25
if (MM == 1) {
str1 = (YY - 1) + "-" + 12 + "-" + "25 00:00:00";
} else {
str1 = YY + "-" + ((MM - 1) > 9 ? MM - 1 : "0" + (MM - 1)) + "-" + "25 00:00:00";
}
str2 = YY + "-" + (MM > 9 ? MM : "0" + MM) + "-" + "25 23:59:59";
}
obj.put("startTime", str1);
obj.put("endTime", str2);
System.out.println(str1);
System.out.println(str2);
return obj;
}
}

@ -5,6 +5,8 @@ import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springblade.desk.dashboard.pojo.entity.DsPartRelationEntity;
import org.springblade.desk.dashboard.pojo.entity.DsPartSub;
import org.springblade.desk.efficiency.pojo.dto.BsSalaryCalculationDTO;
import org.springblade.desk.efficiency.pojo.vo.BsSalaryCalculationVO;
import org.springblade.desk.produce.pojo.dto.MesRbFilePreserveDetailDTO;
import org.springblade.desk.produce.pojo.entity.*;
import org.springblade.desk.produce.pojo.vo.*;
@ -89,4 +91,6 @@ public interface WorkPlanMapper extends BaseMapper<WorkPlan> {
List<MesRbFilePreserveDetailEntity> getByRfpsIdMesNew(Long id);
List<WorkPlanProVO> getWorkOrderProcess(String cardNo);
List<BsSalaryCalculationVO> selectBsSalaryCalculationPage(IPage<BsSalaryCalculationVO> page, BsSalaryCalculationDTO bsSalaryCalculation);
}

@ -437,4 +437,123 @@
ORDER BY wp.ORDERS ASC
</select>
<select id="selectBsSalaryCalculationPage" resultType="org.springblade.desk.efficiency.pojo.vo.BsSalaryCalculationVO">
SELECT
f.WO_CODE AS woCode,
g.PART_CODE AS partCode,
g.PART_NAME AS partName,
f.BATCH_NO AS batchNo,
g.USE_DEPT AS useDept,
g.PLATE AS plate,
i.WC_NAME AS wcName,
e.TS_NAME AS team,
b.NAME AS ppsName,
a.HOUR_QUOTA AS hourQuota,
c.WORK_QTY AS workQty,
d.REAL_NAME AS worker,
k.PRODUCT_TYPE AS productType,
g.PRODUCT_IDENT AS prodIdent,
a.WORK_QTY AS singleBatchNo,
f.inventory_qty AS putQuantity,
f.scrap_qty AS scrapQty,
f.loss_qty AS lossQty,
f.test_qty AS testQty,
g.YP_AREA AS poArea,
a.WORK_QTY * g.YP_AREA AS totalArea,
f.put_store_time AS putStoreTime,
a.WP_MONEY AS wpMoney,
a.BASE_AMOUNT as baseAmount,
a.SUBSIDY_AMOUNT as subsidyAmount,
k.PLATE_THICKNESS as plateThickness,
CASE WHEN a.BASE_AMOUNT IS NULL AND a.SUBSIDY_AMOUNT IS NULL
THEN NULL
ELSE NVL(a.BASE_AMOUNT, 0) + NVL(a.SUBSIDY_AMOUNT, 0)
END AS totalAmount
FROM MES_WORK_PLAN a
INNER JOIN BS_PROCESS_SET b ON a.PPS_ID = b.ID AND b.IS_DELETED = 0
INNER JOIN MES_MAKE_REC c ON a.ID = c.WP_ID AND c.IS_DELETED = 0
INNER JOIN BLADE_USER d ON c.WORKER = d.ID AND d.IS_DELETED = 0
INNER JOIN BS_TEAM_SET e ON a.MAKE_TEAM = e.ID AND e.IS_DELETED = 0
INNER JOIN MES_WORK_ORDER f ON a.WO_ID = f.ID AND f.run_status != 19 AND f.IS_DELETED = 0
INNER JOIN MES_YIELD_ORDER g ON f.YO_ID = g.ID AND g.IS_DELETED = 0
INNER JOIN BS_CENTER_TEAM h ON e.ID = h.TS_ID AND e.WC_ID = h.WC_ID AND h.IS_DELETED = 0
INNER JOIN BS_WORK_CENTER i ON h.WC_ID = i.ID AND i.IS_DELETED = 0
INNER JOIN DS_PART_VERSION j on g.part_code = j.part_code and g.part_version = j.part_version and j.IS_DELETED = 0
INNER JOIN DS_PART k ON j.part_id = k.ID AND k.IS_DELETED = 0
INNER JOIN MES_QUALITY_GRADE l on g.PRODUCT_IDENT = l.QUALITY_GRADE
<where>
a.OEM = 0 AND a.WORK_QTY > 0 and a.IS_DELETED = 0
<if test="bsSalaryCalculation.woCode!=null">
and f.WO_CODE like concat(concat('%', #{bsSalaryCalculation.woCode}),'%')
</if>
<if test="bsSalaryCalculation.cardNo!=null">
and f.CARD_NO like concat(concat('%', #{bsSalaryCalculation.cardNo}),'%')
</if>
<if test="bsSalaryCalculation.startDate!=null">
and TRUNC(f.PUT_STORE_TIME) <![CDATA[ >= ]]> to_date(#{bsSalaryCalculation.startDate}, 'yyyy-mm-dd')
</if>
<if test="bsSalaryCalculation.endDate!=null">
and TRUNC(f.PUT_STORE_TIME) <![CDATA[ <= ]]> to_date(#{bsSalaryCalculation.endDate}, 'yyyy-mm-dd')
</if>
<if test="bsSalaryCalculation.productType!=null">
and g.PRODUCT_TYPE like concat(concat('%', #{bsSalaryCalculation.productType}),'%')
</if>
<if test="bsSalaryCalculation.plate!=null">
and g.plate like concat(concat('%', #{bsSalaryCalculation.plate}),'%')
</if>
<if test="bsSalaryCalculation.wcName!=null">
and i.WC_NAME like concat(concat('%', #{bsSalaryCalculation.wcName}),'%')
</if>
<if test="bsSalaryCalculation.wcId!=null">
and i.ID = #{bsSalaryCalculation.wcId}
</if>
<if test="bsSalaryCalculation.wcIds!=null">
and i.ID IN
<foreach collection="bsSalaryCalculation.wcIds.split(',')"
item="wc_id"
open="(" separator="," close=")">
#{wc_id}
</foreach>
</if>
<if test="bsSalaryCalculation.ppsIds!=null">
and a.PPS_ID IN
<foreach collection="bsSalaryCalculation.ppsIds.split(',')"
item="pps_id"
open="(" separator="," close=")">
#{pps_id}
</foreach>
</if>
<if test="bsSalaryCalculation.ppsId!=null">
and a.PPS_ID = #{bsSalaryCalculation.ppsId}
</if>
<if test="bsSalaryCalculation.ppsName!=null">
and b.NAME like concat(concat('%', #{bsSalaryCalculation.ppsName}),'%')
</if>
<if test="bsSalaryCalculation.prodIdent!=null">
and l.ID = #{bsSalaryCalculation.prodIdent}
</if>
<if test="bsSalaryCalculation.prodIdents!=null">
and l.ID IN
<foreach collection="bsSalaryCalculation.prodIdents.split(',')"
item="prod_ident"
open="(" separator="," close=")">
#{prod_ident}
</foreach>
</if>
<if test="bsSalaryCalculation.minSingleBatchNo!=null">
and a.work_qty <![CDATA[ >= ]]> #{bsSalaryCalculation.minSingleBatchNo}
</if>
<if test="bsSalaryCalculation.maxSingleBatchNo!=null">
and a.work_qty <![CDATA[ <= ]]> #{bsSalaryCalculation.maxSingleBatchNo}
</if>
<if test="bsSalaryCalculation.minTotalArea!=null">
and (a.WORK_QTY * g.YP_AREA) <![CDATA[ >= ]]> #{bsSalaryCalculation.minTotalArea}
</if>
<if test="bsSalaryCalculation.maxTotalArea!=null">
and (a.WORK_QTY * g.YP_AREA) <![CDATA[ <= ]]> #{bsSalaryCalculation.maxTotalArea}
</if>
</where>
</select>
</mapper>

@ -270,6 +270,12 @@ public interface IWorkOrderService extends BaseService<WorkOrder> {
*/
Map<String,Object> queryAllocationMess(AllocationMessPageDTO dto);
/**
* 薪资计算
* @param woId
*/
void salaryCalculation(Long woId);
/**
* 查询配套统计信息
* @param dto 查询条件

@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.common.exception.BusinessException;
import org.springblade.core.mp.base.BaseService;
import org.springblade.core.secure.BladeUser;
import org.springblade.desk.efficiency.pojo.dto.BsSalaryCalculationDTO;
import org.springblade.desk.efficiency.pojo.vo.BsSalaryCalculationVO;
import org.springblade.desk.produce.pojo.entity.WorkOrder;
import org.springblade.desk.produce.pojo.entity.WorkPlan;
import org.springblade.desk.produce.pojo.vo.ProduceMonitorWorkPlanVO;
@ -57,4 +59,6 @@ public interface IWorkPlanService extends BaseService<WorkPlan> {
void workPlanEnd(Long wpId, Date putStoreTime, Double makeQty);
List<WorkPlanProVO> getWorkOrderProcess(String cardNo);
IPage<BsSalaryCalculationVO> selectBsSalaryCalculationPage(IPage<BsSalaryCalculationVO> page, BsSalaryCalculationDTO bsSalaryCalculation);
}

@ -451,8 +451,8 @@ public class PdaLoadServiceImpl extends BaseServiceImpl<WorkPlanMapper, WorkPlan
}
//安全 - 巡检
List<BsSafePatrolInspectionEntity> piList = inspectionService.getByCode(code);
piList = piList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() ->
new TreeSet<>(Comparator.comparing(BsSafePatrolInspectionEntity::getIpId))), ArrayList::new));
//piList = piList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() ->
// new TreeSet<>(Comparator.comparing(BsSafePatrolInspectionEntity::getIpId))), ArrayList::new));
if (null == piList || piList.size() == 0) {
if (flag) {
throw new RuntimeException("未查询到安全巡检任务,product.noPatrolCheckTask");

@ -40,6 +40,10 @@ import org.springblade.desk.device.pojo.entity.RackSetEntity;
import org.springblade.desk.device.service.IEquipmentService;
import org.springblade.desk.device.service.IFeiBaSetService;
import org.springblade.desk.device.service.IRackSetService;
import org.springblade.desk.efficiency.enums.BsSalaryStandardEnum;
import org.springblade.desk.efficiency.pojo.entity.BsSalaryStandardEntity;
import org.springblade.desk.efficiency.service.IBsSalaryStandardService;
import org.springblade.desk.efficiency.util.BsSalaryUtil;
import org.springblade.desk.energy.util.HttpRequestService;
import org.springblade.desk.logistics.pojo.dto.AllocationMessPageDTO;
import org.springblade.desk.logistics.pojo.vo.AllocationMessVO;
@ -61,7 +65,9 @@ import org.springblade.desk.quality.service.*;
import org.springblade.desk.util.date.DateUtils;
import org.springblade.erpdata.feign.IErpDataLogisticsClient;
import org.springblade.erpdata.feign.IErpDataProduceClient;
import org.springblade.scheduling.pojo.entity.QualityGradeEntity;
import org.springblade.scheduling.pojo.entity.WorkOrderEntity;
import org.springblade.scheduling.pojo.entity.WorkPlanEntity;
import org.springblade.system.cache.DictCache;
import org.springblade.system.cache.UserCache;
import org.springblade.system.feign.IDictClient;
@ -184,6 +190,10 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO
@Resource
private final IDictClient dictClient;
private final IQualityGradeService qualityGradeService;
private final IBsSalaryStandardService bsSalaryStandardService;
@Override
public IPage<WorkOrderVO> selectWorkOrderPage(IPage<WorkOrderVO> page, WorkOrderDTO workOrder) {
return page.setRecords(baseMapper.selectWorkOrderPage(page, workOrder));
@ -465,7 +475,7 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO
if (count > 0) {
wpr.setReason("工序不可外协");
} else {
oemCraftAbilityService.count(Wrappers.lambdaQuery(OemCraftAbilityEntity.class).eq(OemCraftAbilityEntity::getCraftAbilityId, wp.getCaId()));
count = oemCraftAbilityService.count(Wrappers.lambdaQuery(OemCraftAbilityEntity.class).eq(OemCraftAbilityEntity::getCraftAbilityId, wp.getCaId()));
if (count == 0) {
wpr.setReason("无对应工艺能力厂商");
}
@ -2793,4 +2803,106 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO
prPlanTest.setCardNo(cardNo);
planTestService.save(prPlanTest);
}
@Override
public void salaryCalculation(Long woId) {
try {
WorkOrder workOrder = this.getById(woId);
if (workOrder == null) {
return;
}
YieldOrder yieldOrder = yieldOrderService.getById(workOrder.getYoId());
if (yieldOrder == null) {
return;
}
// 非军品
String standardType = "3";
List<QualityGradeEntity> qualityGrades = qualityGradeService.list(new LambdaQueryWrapper<QualityGradeEntity>().eq(QualityGradeEntity::getQualityGrade, yieldOrder.getProductIdent()));
if (!CollectionUtils.isEmpty(qualityGrades)) {
if (!StringUtils.isEmpty(qualityGrades.get(0).getType())) {
boolean hasOne = Arrays.asList(qualityGrades.get(0).getType().split(",")).contains("1");
if (hasOne) {
// 军品
standardType = "2";
}
}
}
List<WorkPlan> updList = new ArrayList<>();
List<WorkPlanEntity> workPlanList = workPlanService.selectByWoId(woId);
for (WorkPlanEntity workPlanEntity : workPlanList) {
if (!"0".equals(StringUtils.trim(workPlanEntity.getOem())) || workPlanEntity.getWorkQty() <= 0) {
continue;
}
BsSalaryStandardEntity standard = bsSalaryStandardService.getStandard(workPlanEntity.getPpsId(), yieldOrder.getPartCode(), standardType);
if (standard == null) {
continue;
}
// 基础薪资金额
BigDecimal baseAmount = new BigDecimal(0);
// 补贴薪资金额
BigDecimal subsidyAmount = new BigDecimal(0);
// 面积
BigDecimal ypArea = new BigDecimal(yieldOrder.getYpArea());
// 数量
BigDecimal workQty = new BigDecimal(workPlanEntity.getWorkQty());
// 计算基础薪资金额
if (BsSalaryStandardEnum.SETTLEMENT_UNIT_PIECE.getCode().equals(standard.getSettlementUnit())) {
// 件 = 工人结算价 * 数量
baseAmount = standard.getSettlementPrice().multiply(workQty);
}
if (BsSalaryStandardEnum.SETTLEMENT_UNIT_BATCH.getCode().equals(standard.getSettlementUnit())) {
// 批 = 工人结算价
baseAmount = standard.getSettlementPrice();
}
if (BsSalaryStandardEnum.SETTLEMENT_UNIT_AREA.getCode().equals(standard.getSettlementUnit())) {
// 面积 = 工人结算价 * 数量 * 面积
baseAmount = standard.getSettlementPrice().multiply(ypArea).multiply(workQty);
}
// 计算补贴薪资金额
if (BsSalaryStandardEnum.STEP_TYPE_NON.getCode().equals(standard.getStepType())) {
// 无补贴 = 0
subsidyAmount = new BigDecimal(0);
}
if (BsSalaryStandardEnum.STEP_TYPE_FIXED.getCode().equals(standard.getStepType())) {
BigDecimal stepSettlementPrice = new BigDecimal(standard.getStepSettlementPrice());
BigDecimal stepBasePrice = new BigDecimal(0);
// 固定补贴按批 = 阶梯结算价
if (BsSalaryStandardEnum.STEP_SETTLEMENT_UNIT_BATCH.getCode().equals(standard.getStepSettlementUnit())) {
subsidyAmount = stepSettlementPrice;
}
if (BsSalaryStandardEnum.STEP_SETTLEMENT_UNIT_MULTIPLE.getCode().equals(standard.getStepSettlementUnit())) {
// 固定补贴按件 = 阶梯结算价 * 数量
if (BsSalaryStandardEnum.STEP_UNIT_PIECE.getCode().equals(standard.getStepUnit())) {
stepBasePrice = stepSettlementPrice.multiply(workQty);
}
// 固定补贴按面积 = 阶梯结算价 * 数量 * 面积
if (BsSalaryStandardEnum.STEP_UNIT_AREA.getCode().equals(standard.getStepUnit())) {
stepBasePrice = stepSettlementPrice.multiply(ypArea).multiply(workQty);
}
// 固定补贴按倍 = 固定补贴金额 * 工人结算价格
subsidyAmount = stepBasePrice.multiply(standard.getSettlementPrice());
}
}
if (BsSalaryStandardEnum.STEP_TYPE_STEP.getCode().equals(standard.getStepType())) {
if (BsSalaryStandardEnum.STEP_UNIT_PIECE.getCode().equals(standard.getStepUnit())) {
subsidyAmount = BsSalaryUtil.calcStepAmount(standard.getStep(), standard.getStepSettlementPrice(), workQty, standard.getStepSettlementUnit(), standard.getSettlementPrice());
}
if (BsSalaryStandardEnum.STEP_UNIT_AREA.getCode().equals(standard.getStepUnit())) {
subsidyAmount = BsSalaryUtil.calcStepAmount(standard.getStep(), standard.getStepSettlementPrice(), workQty.multiply(ypArea), standard.getStepSettlementUnit(), standard.getSettlementPrice());
}
}
WorkPlan upd = new WorkPlan();
upd.setId(workPlanEntity.getId());
upd.setBaseAmount(baseAmount);
upd.setSubsidyAmount(subsidyAmount);
updList.add(upd);
}
if (!CollectionUtils.isEmpty(updList)) {
workPlanService.saveOrUpdateBatch(updList);
}
} catch (Exception e) {
log.error("订单:" + woId + ",薪资计算错误", e);
}
}
}

@ -21,6 +21,10 @@ import org.springblade.desk.dashboard.pojo.entity.BsTeamSetEntity;
import org.springblade.desk.dashboard.pojo.entity.DsProcessMeasuringToolEntity;
import org.springblade.desk.dashboard.pojo.entity.DsProcessProjectEntity;
import org.springblade.desk.dashboard.service.*;
import org.springblade.desk.efficiency.pojo.dto.BsSalaryCalculationDTO;
import org.springblade.desk.efficiency.pojo.vo.BsSalaryCalculationVO;
import org.springblade.desk.order.pojo.entity.YieldOrder;
import org.springblade.desk.order.service.IYieldOrderService;
import org.springblade.desk.produce.mapper.PlateAroundMapper;
import org.springblade.desk.produce.mapper.WorkPlanMapper;
import org.springblade.desk.produce.pojo.entity.*;
@ -318,4 +322,9 @@ public class WorkPlanServiceImpl extends BaseServiceImpl<WorkPlanMapper, WorkPla
public List<WorkPlanProVO> getWorkOrderProcess(String cardNo) {
return baseMapper.getWorkOrderProcess(cardNo);
}
@Override
public IPage<BsSalaryCalculationVO> selectBsSalaryCalculationPage(IPage<BsSalaryCalculationVO> page, BsSalaryCalculationDTO bsSalaryCalculation) {
return page.setRecords(baseMapper.selectBsSalaryCalculationPage(page, bsSalaryCalculation));
}
}

Loading…
Cancel
Save