Compare commits

...

8 Commits

Author SHA1 Message Date
HuangHuiKang 000aa526e8 fix:修改采集设备产能 1 week ago
HuangHuiKang 4dc54fcbc8 fix:添加报工产能回显 1 week ago
HuangHuiKang 5ca9c9112a fix:添加报工数、数据采集的产量排产的算法 1 week ago
HuangHuiKang 999dd4f12e Merge remote-tracking branch 'origin/main' into main
# Conflicts:
#	yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceService.java
#	yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java
2 weeks ago
HuangHuiKang b67ff2879c fix:优化采集设备分页查询接口 3 weeks ago
HuangHuiKang fcc3cf46c0 feat:新增库区和库位页面 3 weeks ago
HuangHuiKang ec455718f1 fix:app扫码查询相关接口添加编码过滤条件 3 weeks ago
HuangHuiKang c2ec3f0dbf fix:优化app统计报表查询速度 3 weeks ago

@ -90,6 +90,12 @@ public interface ErrorCodeConstants {
// ========== ERP 仓库 1-030-400-000 ==========
ErrorCode WAREHOUSE_NOT_EXISTS = new ErrorCode(1_030_400_000, "仓库不存在");
ErrorCode WAREHOUSE_NOT_ENABLE = new ErrorCode(1_030_400_001, "仓库({})未启用");
ErrorCode WAREHOUSE_AREA_CODE_EXISTS = new ErrorCode(1_030_400_002, "仓库库区编码不存在");
ErrorCode WAREHOUSE_AREA_DELETE_FAIL_EXISTS_LOCATION = new ErrorCode(1_030_400_003, "仓库库区删除失败,请先删除对应库位信息");
ErrorCode WAREHOUSE_AREA_NOT_EXISTS = new ErrorCode(1_030_400_004, "仓库库区不存在");
ErrorCode WAREHOUSE_LOCATION_CODE_EXISTS = new ErrorCode(1_030_400_005, "库位编码不存在");
ErrorCode WAREHOUSE_LOCATION_NOT_EXISTS = new ErrorCode(1_030_400_006, "库位不存在");
ErrorCode WAREHOUSE_LOCATION_WAREHOUSE_AREA_NOT_MATCH = new ErrorCode(1_030_400_007, "暂无匹配库位信息");
// ========== ERP 其它入库单 1-030-401-000 ==========
ErrorCode STOCK_IN_NOT_EXISTS = new ErrorCode(1_030_401_000, "其它入库单不存在");

@ -167,10 +167,10 @@ public class MoldBrandController {
@GetMapping("/mold/get")
@Operation(summary = "获得模具")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('erp:mold-brand:query')")
public CommonResult<MoldDO> getMold(@RequestParam("id") Long id) {
return success(moldBrandService.getMold(id));
public CommonResult<MoldDO> getMold(@RequestParam(value = "id", required = false) Long id,
@RequestParam(value = "code", required = false) String code) {
return success(moldBrandService.getMold(id, code));
}
@GetMapping("/mold/export-excel")
@ -241,4 +241,4 @@ public class MoldBrandController {
return success(moldBrandService.getMoldBrandProduct(id));
}
}
}

@ -104,10 +104,10 @@ public class ErpProductController {
@GetMapping("/get")
@Operation(summary = "获得产品")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('erp:product:query')")
public CommonResult<ErpProductRespVO> getProduct(@RequestParam("id") Long id) {
return success(productService.getProduct(id));
public CommonResult<ErpProductRespVO> getProduct(@RequestParam(value = "id", required = false) Long id,
@RequestParam(value = "code", required = false) String code) {
return success(productService.getProduct(id, code));
}
@GetMapping("/page")

@ -5,11 +5,11 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse.ErpWarehousePageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse.ErpWarehouseRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse.ErpWarehouseSaveReqVO;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO;
import cn.iocoder.yudao.module.erp.service.stock.ErpWarehouseService;
import io.swagger.v3.oas.annotations.Operation;
@ -80,8 +80,7 @@ public class ErpWarehouseController {
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('erp:warehouse:query')")
public CommonResult<ErpWarehouseRespVO> getWarehouse(@RequestParam("id") Long id) {
ErpWarehouseDO warehouse = warehouseService.getWarehouse(id);
return success(BeanUtils.toBean(warehouse, ErpWarehouseRespVO.class));
return success(warehouseService.getWarehouseDetail(id));
}
@GetMapping("/page")
@ -113,4 +112,4 @@ public class ErpWarehouseController {
BeanUtils.toBean(list, ErpWarehouseRespVO.class));
}
}
}

@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.module.erp.controller.admin.warehousearea.vo.WarehouseAreaRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.warehouselocation.vo.WarehouseLocationRespVO;
import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
@ -10,6 +12,7 @@ import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - ERP 仓库 Response VO")
@Data
@ -20,7 +23,7 @@ public class ErpWarehouseRespVO {
@ExcelProperty("仓库编号")
private Long id;
@Schema(description = "仓库名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
@Schema(description = "仓库名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "成品仓")
@ExcelProperty("仓库名称")
private String name;
@ -32,11 +35,11 @@ public class ErpWarehouseRespVO {
@ExcelProperty("排序")
private Long sort;
@Schema(description = "备注", example = "随便")
@Schema(description = "备注", example = "主仓")
@ExcelProperty("备注")
private String remark;
@Schema(description = "负责人", example = "芋头")
@Schema(description = "负责人", example = "张三")
@ExcelProperty("负责人")
private String principal;
@ -57,8 +60,23 @@ public class ErpWarehouseRespVO {
@ExcelProperty("是否默认")
private Boolean defaultStatus;
@Schema(description = "库区数量", example = "2")
@ExcelProperty("库区数量")
private Long areaCount;
@Schema(description = "库位数量", example = "10")
@ExcelProperty("库位数量")
private Long locationCount;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}
@Schema(description = "库区列表")
private List<WarehouseAreaRespVO> areaList;
@Schema(description = "库位列表")
private List<WarehouseLocationRespVO> locationList;
}

@ -3,10 +3,10 @@ package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
@Schema(description = "管理后台 - ERP 仓库新增/修改 Request VO")
@ -16,7 +16,7 @@ public class ErpWarehouseSaveReqVO {
@Schema(description = "仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11614")
private Long id;
@Schema(description = "仓库名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
@Schema(description = "仓库名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "成品仓")
@NotEmpty(message = "仓库名称不能为空")
private String name;
@ -27,10 +27,10 @@ public class ErpWarehouseSaveReqVO {
@NotNull(message = "排序不能为空")
private Long sort;
@Schema(description = "备注", example = "随便")
@Schema(description = "备注", example = "主仓")
private String remark;
@Schema(description = "负责人", example = "芋头")
@Schema(description = "负责人", example = "张三")
private String principal;
@Schema(description = "仓储费,单位:元", example = "13973")
@ -39,9 +39,9 @@ public class ErpWarehouseSaveReqVO {
@Schema(description = "搬运费,单位:元", example = "9903")
private BigDecimal truckagePrice;
@Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "开启状态不能为空")
@InEnum(CommonStatusEnum.class)
private Integer status;
}
}

@ -0,0 +1,114 @@
package cn.iocoder.yudao.module.erp.controller.admin.warehousearea;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse.ErpWarehouseRespVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import cn.iocoder.yudao.module.erp.controller.admin.warehousearea.vo.*;
import cn.iocoder.yudao.module.erp.dal.dataobject.warehousearea.WarehouseAreaDO;
import cn.iocoder.yudao.module.erp.service.warehousearea.WarehouseAreaService;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
@Tag(name = "管理后台 - ERP 库区信息")
@RestController
@RequestMapping("/erp/warehouse-area")
@Validated
public class WarehouseAreaController {
@Resource
private WarehouseAreaService warehouseAreaService;
@PostMapping("/create")
@Operation(summary = "创建ERP 库区信息")
@PreAuthorize("@ss.hasPermission('erp:warehouse-area:create')")
public CommonResult<Long> createWarehouseArea(@Valid @RequestBody WarehouseAreaSaveReqVO createReqVO) {
return success(warehouseAreaService.createWarehouseArea(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新ERP 库区信息")
@PreAuthorize("@ss.hasPermission('erp:warehouse-area:update')")
public CommonResult<Boolean> updateWarehouseArea(@Valid @RequestBody WarehouseAreaSaveReqVO updateReqVO) {
warehouseAreaService.updateWarehouseArea(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除ERP 库区信息")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('erp:warehouse-area:delete')")
public CommonResult<Boolean> deleteWarehouseArea(@RequestParam("id") Long id) {
warehouseAreaService.deleteWarehouseArea(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得ERP 库区信息")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('erp:warehouse-area:query')")
public CommonResult<WarehouseAreaRespVO> getWarehouseArea(@RequestParam("id") Long id) {
WarehouseAreaDO warehouseArea = warehouseAreaService.getWarehouseArea(id);
return success(BeanUtils.toBean(warehouseArea, WarehouseAreaRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得ERP 库区信息分页")
@PreAuthorize("@ss.hasPermission('erp:warehouse-area:query')")
public CommonResult<PageResult<WarehouseAreaRespVO>> getWarehouseAreaPage(@Valid WarehouseAreaPageReqVO pageReqVO) {
PageResult<WarehouseAreaDO> pageResult = warehouseAreaService.getWarehouseAreaPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, WarehouseAreaRespVO.class));
}
@GetMapping("/simple-list")
@Operation(summary = "获得库区精简列表", description = "只包含被开启的仓库库区,主要用于前端的下拉选项")
public CommonResult<List<WarehouseAreaRespVO>> getWarehouseSimpleList(@RequestParam(value = "warehouseId", required = false) Long warehouseId) {
List<WarehouseAreaDO> list = warehouseAreaService.getWarehouseListByStatusAndWarehouseId(CommonStatusEnum.ENABLE.getStatus(), warehouseId);
return success(convertList(list, area -> new WarehouseAreaRespVO()
.setId(area.getId())
.setWarehouseId(area.getWarehouseId())
.setAreaCode(area.getAreaCode())
.setAreaName(area.getAreaName())
.setStatus(area.getStatus())));
}
@GetMapping("/export-excel")
@Operation(summary = "导出ERP 库区信息 Excel")
@PreAuthorize("@ss.hasPermission('erp:warehouse-area:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportWarehouseAreaExcel(@Valid WarehouseAreaPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<WarehouseAreaDO> list = warehouseAreaService.getWarehouseAreaPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "ERP 库区信息.xls", "数据", WarehouseAreaRespVO.class,
BeanUtils.toBean(list, WarehouseAreaRespVO.class));
}
}

@ -0,0 +1,41 @@
package cn.iocoder.yudao.module.erp.controller.admin.warehousearea.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import java.math.BigDecimal;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - ERP 库区信息分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class WarehouseAreaPageReqVO extends PageParam {
@Schema(description = "所属仓库id", example = "19404")
private Long warehouseId;
@Schema(description = "库区编码")
private String areaCode;
@Schema(description = "库区名称", example = "赵六")
private String areaName;
@Schema(description = "面积(平方米)")
private BigDecimal areaSize;
@Schema(description = "库区描述", example = "你说的对")
private String description;
@Schema(description = "开启状态", example = "2")
private Integer status;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -0,0 +1,48 @@
package cn.iocoder.yudao.module.erp.controller.admin.warehousearea.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import java.math.BigDecimal;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - ERP 库区信息 Response VO")
@Data
@ExcelIgnoreUnannotated
public class WarehouseAreaRespVO {
@Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1157")
@ExcelProperty("id")
private Long id;
@Schema(description = "所属仓库id", requiredMode = Schema.RequiredMode.REQUIRED, example = "19404")
@ExcelProperty("所属仓库id")
private Long warehouseId;
@Schema(description = "库区编码", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("库区编码")
private String areaCode;
@Schema(description = "库区名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
@ExcelProperty("库区名称")
private String areaName;
@Schema(description = "面积(平方米)")
@ExcelProperty("面积(平方米)")
private BigDecimal areaSize;
@Schema(description = "库区描述", example = "你说的对")
@ExcelProperty("库区描述")
private String description;
@Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@ExcelProperty("开启状态")
private Integer status;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

@ -0,0 +1,38 @@
package cn.iocoder.yudao.module.erp.controller.admin.warehousearea.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
@Schema(description = "管理后台 - ERP 库区信息新增/修改 Request VO")
@Data
public class WarehouseAreaSaveReqVO {
@Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1157")
private Long id;
@Schema(description = "所属仓库id", example = "19404")
private Long warehouseId;
@Schema(description = "库区编码", requiredMode = Schema.RequiredMode.REQUIRED)
// @NotEmpty(message = "库区编码不能为空")
private String areaCode;
@Schema(description = "库区名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "A区")
@NotEmpty(message = "库区名称不能为空")
private String areaName;
@Schema(description = "面积(平方米)")
private BigDecimal areaSize;
@Schema(description = "库区描述", example = "常温区")
private String description;
@Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "开启状态不能为空")
private Integer status;
}

@ -0,0 +1,110 @@
package cn.iocoder.yudao.module.erp.controller.admin.warehouselocation;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import cn.iocoder.yudao.module.erp.controller.admin.warehouselocation.vo.*;
import cn.iocoder.yudao.module.erp.dal.dataobject.warehouselocation.WarehouseLocationDO;
import cn.iocoder.yudao.module.erp.service.warehouselocation.WarehouseLocationService;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
@Tag(name = "管理后台 - ERP 库位信息")
@RestController
@RequestMapping("/erp/warehouse-location")
@Validated
public class WarehouseLocationController {
@Resource
private WarehouseLocationService warehouseLocationService;
@PostMapping("/create")
@Operation(summary = "创建ERP 库位信息")
@PreAuthorize("@ss.hasPermission('erp:warehouse-location:create')")
public CommonResult<Long> createWarehouseLocation(@Valid @RequestBody WarehouseLocationSaveReqVO createReqVO) {
return success(warehouseLocationService.createWarehouseLocation(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新ERP 库位信息")
@PreAuthorize("@ss.hasPermission('erp:warehouse-location:update')")
public CommonResult<Boolean> updateWarehouseLocation(@Valid @RequestBody WarehouseLocationSaveReqVO updateReqVO) {
warehouseLocationService.updateWarehouseLocation(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除ERP 库位信息")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('erp:warehouse-location:delete')")
public CommonResult<Boolean> deleteWarehouseLocation(@RequestParam("id") Long id) {
warehouseLocationService.deleteWarehouseLocation(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得ERP 库位信息")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('erp:warehouse-location:query')")
public CommonResult<WarehouseLocationRespVO> getWarehouseLocation(@RequestParam("id") Long id) {
WarehouseLocationDO warehouseLocation = warehouseLocationService.getWarehouseLocation(id);
return success(BeanUtils.toBean(warehouseLocation, WarehouseLocationRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得ERP 库位信息分页")
@PreAuthorize("@ss.hasPermission('erp:warehouse-location:query')")
public CommonResult<PageResult<WarehouseLocationRespVO>> getWarehouseLocationPage(@Valid WarehouseLocationPageReqVO pageReqVO) {
PageResult<WarehouseLocationDO> pageResult = warehouseLocationService.getWarehouseLocationPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, WarehouseLocationRespVO.class));
}
@GetMapping("/simple-list")
@Operation(summary = "获得ERP 库位信息精简列表", description = "只包含已启用的库位,主要用于前端下拉选项")
public CommonResult<List<WarehouseLocationRespVO>> getWarehouseLocationSimpleList() {
List<WarehouseLocationDO> list = warehouseLocationService.getWarehouseLocationListByStatus(CommonStatusEnum.ENABLE.getStatus());
return success(convertList(list, item -> new WarehouseLocationRespVO()
.setId(item.getId())
.setWarehouseId(item.getWarehouseId())
.setAreaId(item.getAreaId())
.setCode(item.getCode())
.setName(item.getName())
.setStatus(item.getStatus())));
}
@GetMapping("/export-excel")
@Operation(summary = "导出ERP 库位信息 Excel")
@PreAuthorize("@ss.hasPermission('erp:warehouse-location:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportWarehouseLocationExcel(@Valid WarehouseLocationPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<WarehouseLocationDO> list = warehouseLocationService.getWarehouseLocationPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "ERP 库位信息.xls", "数据", WarehouseLocationRespVO.class,
BeanUtils.toBean(list, WarehouseLocationRespVO.class));
}
}

@ -0,0 +1,59 @@
package cn.iocoder.yudao.module.erp.controller.admin.warehouselocation.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import java.math.BigDecimal;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - ERP 库位信息分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class WarehouseLocationPageReqVO extends PageParam {
@Schema(description = "所属仓库ID", example = "19287")
private Long warehouseId;
@Schema(description = "所属库区ID", example = "513")
private Long areaId;
@Schema(description = "库位编码")
private String code;
@Schema(description = "库位名称", example = "张三")
private String name;
@Schema(description = "面积")
private BigDecimal areaSize;
@Schema(description = "最大载重量")
private BigDecimal maxLoadWeight;
@Schema(description = "库位位置X")
private Integer positionX;
@Schema(description = "库位位置Y")
private Integer positionY;
@Schema(description = "库位位置Z")
private Integer positionZ;
@Schema(description = "是否允许产品混放")
private Boolean allowProductMix;
@Schema(description = "是否允许批次混放")
private Boolean allowBatchMix;
@Schema(description = "开启状态", example = "1")
private Integer status;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -0,0 +1,72 @@
package cn.iocoder.yudao.module.erp.controller.admin.warehouselocation.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import java.math.BigDecimal;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - ERP 库位信息 Response VO")
@Data
@ExcelIgnoreUnannotated
public class WarehouseLocationRespVO {
@Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "7300")
@ExcelProperty("id")
private Long id;
@Schema(description = "所属仓库ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "19287")
@ExcelProperty("所属仓库ID")
private Long warehouseId;
@Schema(description = "所属库区ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "513")
@ExcelProperty("所属库区ID")
private Long areaId;
@Schema(description = "库位编码", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("库位编码")
private String code;
@Schema(description = "库位名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
@ExcelProperty("库位名称")
private String name;
@Schema(description = "面积")
@ExcelProperty("面积")
private BigDecimal areaSize;
@Schema(description = "最大载重量")
@ExcelProperty("最大载重量")
private BigDecimal maxLoadWeight;
@Schema(description = "库位位置X")
@ExcelProperty("库位位置X")
private Integer positionX;
@Schema(description = "库位位置Y")
@ExcelProperty("库位位置Y")
private Integer positionY;
@Schema(description = "库位位置Z")
@ExcelProperty("库位位置Z")
private Integer positionZ;
@Schema(description = "是否允许产品混放", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("是否允许产品混放")
private Boolean allowProductMix;
@Schema(description = "是否允许批次混放", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("是否允许批次混放")
private Boolean allowBatchMix;
@Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty("开启状态")
private Integer status;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

@ -0,0 +1,59 @@
package cn.iocoder.yudao.module.erp.controller.admin.warehouselocation.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
@Schema(description = "管理后台 - ERP 库位信息新增/修改 Request VO")
@Data
public class WarehouseLocationSaveReqVO {
@Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "7300")
private Long id;
@Schema(description = "所属仓库ID", example = "19287")
private Long warehouseId;
@Schema(description = "所属库区ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "513")
@NotNull(message = "所属库区ID不能为空")
private Long areaId;
@Schema(description = "库位编码", requiredMode = Schema.RequiredMode.REQUIRED)
// @NotEmpty(message = "库位编码不能为空")
private String code;
@Schema(description = "库位名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "A-01-01")
@NotEmpty(message = "库位名称不能为空")
private String name;
@Schema(description = "面积")
private BigDecimal areaSize;
@Schema(description = "最大载重量")
private BigDecimal maxLoadWeight;
@Schema(description = "库位位置X")
private Integer positionX;
@Schema(description = "库位位置Y")
private Integer positionY;
@Schema(description = "库位位置Z")
private Integer positionZ;
@Schema(description = "是否允许产品混放", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "是否允许产品混放不能为空")
private Boolean allowProductMix;
@Schema(description = "是否允许批次混放", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "是否允许批次混放不能为空")
private Boolean allowBatchMix;
@Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "开启状态不能为空")
private Integer status;
}

@ -0,0 +1,56 @@
package cn.iocoder.yudao.module.erp.dal.dataobject.warehousearea;
import lombok.*;
import java.util.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* ERP DO
*
* @author
*/
@TableName("erp_warehouse_area")
@KeySequence("erp_warehouse_area_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class WarehouseAreaDO extends BaseDO {
/**
* id
*/
@TableId
private Long id;
/**
* id
*/
private Long warehouseId;
/**
*
*/
private String areaCode;
/**
*
*/
private String areaName;
/**
* ()
*/
private BigDecimal areaSize;
/**
*
*/
private String description;
/**
*
*/
private Integer status;
}

@ -0,0 +1,81 @@
package cn.iocoder.yudao.module.erp.dal.dataobject.warehouselocation;
import lombok.*;
import java.util.*;
import java.math.BigDecimal;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* ERP DO
*
* @author
*/
@TableName("erp_warehouse_location")
@KeySequence("erp_warehouse_location_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class WarehouseLocationDO extends BaseDO {
/**
* id
*/
@TableId
private Long id;
/**
* ID
*/
private Long warehouseId;
/**
* ID
*/
private Long areaId;
/**
*
*/
private String code;
/**
*
*/
private String name;
/**
*
*/
private BigDecimal areaSize;
/**
*
*/
private BigDecimal maxLoadWeight;
/**
* X
*/
private Integer positionX;
/**
* Y
*/
private Integer positionY;
/**
* Z
*/
private Integer positionZ;
/**
*
*/
private Boolean allowProductMix;
/**
*
*/
private Boolean allowBatchMix;
/**
*
*/
private Integer status;
}

@ -0,0 +1,53 @@
package cn.iocoder.yudao.module.erp.dal.mysql.warehousearea;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.erp.dal.dataobject.warehousearea.WarehouseAreaDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.erp.controller.admin.warehousearea.vo.*;
/**
* ERP Mapper
*
* @author
*/
@Mapper
public interface WarehouseAreaMapper extends BaseMapperX<WarehouseAreaDO> {
default PageResult<WarehouseAreaDO> selectPage(WarehouseAreaPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<WarehouseAreaDO>()
.eqIfPresent(WarehouseAreaDO::getWarehouseId, reqVO.getWarehouseId())
.eqIfPresent(WarehouseAreaDO::getAreaCode, reqVO.getAreaCode())
.likeIfPresent(WarehouseAreaDO::getAreaName, reqVO.getAreaName())
.eqIfPresent(WarehouseAreaDO::getAreaSize, reqVO.getAreaSize())
.eqIfPresent(WarehouseAreaDO::getDescription, reqVO.getDescription())
.eqIfPresent(WarehouseAreaDO::getStatus, reqVO.getStatus())
.betweenIfPresent(WarehouseAreaDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(WarehouseAreaDO::getId));
}
default WarehouseAreaDO selectByNo(String no) {
return selectOne(WarehouseAreaDO::getAreaCode, no);
}
default List<WarehouseAreaDO> selectListByStatus(Integer status) {
return selectList(WarehouseAreaDO::getStatus, status);
}
default List<WarehouseAreaDO> selectListByWarehouseId(Long warehouseId) {
return selectList(WarehouseAreaDO::getWarehouseId, warehouseId);
}
default void deleteByWarehouseId(Long warehouseId) {
delete(WarehouseAreaDO::getWarehouseId, warehouseId);
}
default Long selectCountByWarehouseId(Long warehouseId) {
return selectCount(WarehouseAreaDO::getWarehouseId, warehouseId);
}
}

@ -0,0 +1,61 @@
package cn.iocoder.yudao.module.erp.dal.mysql.warehouselocation;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.erp.dal.dataobject.warehouselocation.WarehouseLocationDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.erp.controller.admin.warehouselocation.vo.*;
/**
* ERP Mapper
*
* @author
*/
@Mapper
public interface WarehouseLocationMapper extends BaseMapperX<WarehouseLocationDO> {
default PageResult<WarehouseLocationDO> selectPage(WarehouseLocationPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<WarehouseLocationDO>()
.eqIfPresent(WarehouseLocationDO::getWarehouseId, reqVO.getWarehouseId())
.eqIfPresent(WarehouseLocationDO::getAreaId, reqVO.getAreaId())
.eqIfPresent(WarehouseLocationDO::getCode, reqVO.getCode())
.likeIfPresent(WarehouseLocationDO::getName, reqVO.getName())
.eqIfPresent(WarehouseLocationDO::getAreaSize, reqVO.getAreaSize())
.eqIfPresent(WarehouseLocationDO::getMaxLoadWeight, reqVO.getMaxLoadWeight())
.eqIfPresent(WarehouseLocationDO::getPositionX, reqVO.getPositionX())
.eqIfPresent(WarehouseLocationDO::getPositionY, reqVO.getPositionY())
.eqIfPresent(WarehouseLocationDO::getPositionZ, reqVO.getPositionZ())
.eqIfPresent(WarehouseLocationDO::getAllowProductMix, reqVO.getAllowProductMix())
.eqIfPresent(WarehouseLocationDO::getAllowBatchMix, reqVO.getAllowBatchMix())
.eqIfPresent(WarehouseLocationDO::getStatus, reqVO.getStatus())
.betweenIfPresent(WarehouseLocationDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(WarehouseLocationDO::getId));
}
default WarehouseLocationDO selectByNo(String no) {
return selectOne(WarehouseLocationDO::getCode, no);
}
default List<WarehouseLocationDO> selectListByWarehouseId(Long warehouseId) {
return selectList(WarehouseLocationDO::getWarehouseId, warehouseId);
}
default void deleteByWarehouseId(Long warehouseId) {
delete(WarehouseLocationDO::getWarehouseId, warehouseId);
}
default List<WarehouseLocationDO> selectListByStatus(Integer status) {
return selectList(WarehouseLocationDO::getStatus, status);
}
default List<WarehouseLocationDO> selectListByAreaId(Long areaId) {
return selectList(WarehouseLocationDO::getAreaId, areaId);
}
default Long selectCountByWarehouseId(Long warehouseId) {
return selectCount(WarehouseLocationDO::getWarehouseId, warehouseId);
}
}

@ -120,6 +120,8 @@ public interface MoldBrandService {
* @return
*/
MoldDO getMold(Long id);
MoldDO getMold(Long id, String code);
List<MoldDO> selectBy(MoldDO reqVO);
// ==================== 子表(模具产品) ====================
@ -187,4 +189,4 @@ public interface MoldBrandService {
List<MoldBrandTreeRespVO> getMoldBrandTree();
void regenerateCode(Long id, String code) throws UnsupportedEncodingException;
}
}

@ -256,6 +256,7 @@ public class MoldBrandServiceImpl implements MoldBrandService {
@Override
public MoldDO getMold(Long id) {
validateMoldExists(id);
MoldDO moldDO = moldMapper.selectById(id);
Map<String,List<MoldRepairLineDO>> moldRepairDOMap=new HashMap<>();
@ -308,6 +309,24 @@ public class MoldBrandServiceImpl implements MoldBrandService {
moldDO.setQrcodeUrl(qrcodeUrl);
return moldDO;
}
@Override
public MoldDO getMold(Long id, String code) {
if (id != null) {
return getMold(id);
}
if (StrUtil.isNotBlank(code)) {
MoldDO moldDO = moldMapper.selectOne(new LambdaQueryWrapperX<MoldDO>()
.like(MoldDO::getCode, code)
.orderByDesc(MoldDO::getId)
.last("LIMIT 1"));
if (moldDO == null) {
throw exception(MOLD_NOT_EXISTS);
}
return getMold(moldDO.getId());
}
throw exception(MOLD_NOT_EXISTS);
}
@Override
public List<MoldDO> selectBy(MoldDO reqVO){
return moldMapper.selectBy(reqVO);
@ -445,4 +464,4 @@ public class MoldBrandServiceImpl implements MoldBrandService {
return respVO;
}
}
}

@ -102,4 +102,8 @@ public interface MoldService {
List<MoldDO> getInTransitMoldAllList();
List<MoldDO> getMoldListByStatus(Long status);
List<MoldDO> getMoldListByIds(Collection<Long> ids);
}

@ -136,4 +136,11 @@ public class MoldServiceImpl implements MoldService {
.eqIfPresent(MoldDO::getStatus, status);
return moldMapper.selectList(queryWrapper);
}
@Override
public List<MoldDO> getMoldListByIds(Collection<Long> ids) {
if (ids == null || ids.isEmpty()) {
return Collections.emptyList();
}
return moldMapper.selectBatchIds(ids); }
}

@ -64,6 +64,8 @@ public interface ErpProductService {
*/
ErpProductRespVO getProduct(Long id);
ErpProductRespVO getProduct(Long id, String code);
/**
* VO
*
@ -138,4 +140,4 @@ public interface ErpProductService {
ErpProductImportRespVO importProductList(List<ErpProductImportExcelVO> importProducts, boolean isUpdateSupport);
void regenerateCode(Long id, String code) throws UnsupportedEncodingException;
}
}

@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldDO;
import cn.iocoder.yudao.module.common.enums.CodeTypeEnum;
@ -325,6 +326,24 @@ public class ErpProductServiceImpl implements ErpProductService {
return respVO;
}
@Override
public ErpProductRespVO getProduct(Long id, String code) {
if (id != null) {
return getProduct(id);
}
if (StringUtils.isNotBlank(code)) {
ErpProductDO product = productMapper.selectOne(new LambdaQueryWrapperX<ErpProductDO>()
.like(ErpProductDO::getBarCode, code)
.orderByDesc(ErpProductDO::getId)
.last("LIMIT 1"));
if (product == null) {
throw exception(PRODUCT_NOT_EXISTS);
}
return getProduct(product.getId());
}
throw exception(PRODUCT_NOT_EXISTS);
}

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.erp.service.stock;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse.ErpWarehouseRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse.ErpWarehouseSaveReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse.ErpWarehousePageReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO;
@ -58,6 +59,8 @@ public interface ErpWarehouseService {
*/
ErpWarehouseDO getWarehouse(Long id);
ErpWarehouseRespVO getWarehouseDetail(Long id);
/**
*
*
@ -101,4 +104,4 @@ public interface ErpWarehouseService {
*/
PageResult<ErpWarehouseDO> getWarehousePage(ErpWarehousePageReqVO pageReqVO);
}
}

@ -4,10 +4,17 @@ import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse.ErpWarehouseSaveReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse.ErpWarehousePageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse.ErpWarehouseRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse.ErpWarehouseSaveReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.warehousearea.vo.WarehouseAreaRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.warehouselocation.vo.WarehouseLocationRespVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.warehousearea.WarehouseAreaDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.warehouselocation.WarehouseLocationDO;
import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpWarehouseMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.warehousearea.WarehouseAreaMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.warehouselocation.WarehouseLocationMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@ -23,11 +30,6 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.WAREHOUSE_NOT_ENABLE;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.WAREHOUSE_NOT_EXISTS;
/**
* ERP Service
*
* @author
*/
@Service
@Validated
public class ErpWarehouseServiceImpl implements ErpWarehouseService {
@ -35,20 +37,22 @@ public class ErpWarehouseServiceImpl implements ErpWarehouseService {
@Resource
private ErpWarehouseMapper warehouseMapper;
@Resource
private WarehouseAreaMapper warehouseAreaMapper;
@Resource
private WarehouseLocationMapper warehouseLocationMapper;
@Override
public Long createWarehouse(ErpWarehouseSaveReqVO createReqVO) {
// 插入
ErpWarehouseDO warehouse = BeanUtils.toBean(createReqVO, ErpWarehouseDO.class);
warehouseMapper.insert(warehouse);
// 返回
return warehouse.getId();
}
@Override
public void updateWarehouse(ErpWarehouseSaveReqVO updateReqVO) {
// 校验存在
validateWarehouseExists(updateReqVO.getId());
// 更新
ErpWarehouseDO updateObj = BeanUtils.toBean(updateReqVO, ErpWarehouseDO.class);
warehouseMapper.updateById(updateObj);
}
@ -56,25 +60,22 @@ public class ErpWarehouseServiceImpl implements ErpWarehouseService {
@Override
@Transactional(rollbackFor = Exception.class)
public void updateWarehouseDefaultStatus(Long id, Boolean defaultStatus) {
// 1. 校验存在
validateWarehouseExists(id);
// 2.1 如果开启,则需要关闭所有其它的默认
if (defaultStatus) {
ErpWarehouseDO warehouse = warehouseMapper.selectByDefaultStatus();
if (warehouse != null) {
warehouseMapper.updateById(new ErpWarehouseDO().setId(warehouse.getId()).setDefaultStatus(false));
}
}
// 2.2 更新对应的默认状态
warehouseMapper.updateById(new ErpWarehouseDO().setId(id).setDefaultStatus(defaultStatus));
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteWarehouse(Long id) {
// 校验存在
validateWarehouseExists(id);
// 删除
warehouseLocationMapper.deleteByWarehouseId(id);
warehouseAreaMapper.deleteByWarehouseId(id);
warehouseMapper.deleteById(id);
}
@ -89,6 +90,24 @@ public class ErpWarehouseServiceImpl implements ErpWarehouseService {
return warehouseMapper.selectById(id);
}
@Override
public ErpWarehouseRespVO getWarehouseDetail(Long id) {
ErpWarehouseDO warehouse = warehouseMapper.selectById(id);
if (warehouse == null) {
return null;
}
ErpWarehouseRespVO respVO = BeanUtils.toBean(warehouse, ErpWarehouseRespVO.class);
List<WarehouseAreaDO> areaList = warehouseAreaMapper.selectListByWarehouseId(id);
List<WarehouseLocationDO> locationList = warehouseLocationMapper.selectListByWarehouseId(id);
respVO.setAreaCount((long) areaList.size());
respVO.setLocationCount((long) locationList.size());
respVO.setAreaList(BeanUtils.toBean(areaList, WarehouseAreaRespVO.class));
respVO.setLocationList(BeanUtils.toBean(locationList, WarehouseLocationRespVO.class));
return respVO;
}
@Override
public List<ErpWarehouseDO> validWarehouseList(Collection<Long> ids) {
if (CollUtil.isEmpty(ids)) {
@ -98,7 +117,7 @@ public class ErpWarehouseServiceImpl implements ErpWarehouseService {
Map<Long, ErpWarehouseDO> warehouseMap = convertMap(list, ErpWarehouseDO::getId);
for (Long id : ids) {
ErpWarehouseDO warehouse = warehouseMap.get(id);
if (warehouseMap.get(id) == null) {
if (warehouse == null) {
throw exception(WAREHOUSE_NOT_EXISTS);
}
if (CommonStatusEnum.isDisable(warehouse.getStatus())) {
@ -123,4 +142,4 @@ public class ErpWarehouseServiceImpl implements ErpWarehouseService {
return warehouseMapper.selectPage(pageReqVO);
}
}
}

@ -0,0 +1,59 @@
package cn.iocoder.yudao.module.erp.service.warehousearea;
import java.util.*;
import cn.iocoder.yudao.module.erp.controller.admin.warehousearea.vo.*;
import cn.iocoder.yudao.module.erp.dal.dataobject.warehousearea.WarehouseAreaDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import javax.validation.Valid;
/**
* ERP Service
*
* @author
*/
public interface WarehouseAreaService {
/**
* ERP
*
* @param createReqVO
* @return
*/
Long createWarehouseArea(@Valid WarehouseAreaSaveReqVO createReqVO);
/**
* ERP
*
* @param updateReqVO
*/
void updateWarehouseArea(@Valid WarehouseAreaSaveReqVO updateReqVO);
/**
* ERP
*
* @param id
*/
void deleteWarehouseArea(Long id);
/**
* ERP
*
* @param id
* @return ERP
*/
WarehouseAreaDO getWarehouseArea(Long id);
/**
* ERP
*
* @param pageReqVO
* @return ERP
*/
PageResult<WarehouseAreaDO> getWarehouseAreaPage(WarehouseAreaPageReqVO pageReqVO);
List<WarehouseAreaDO> getWarehouseListByStatus(Integer status);
List<WarehouseAreaDO> getWarehouseListByStatusAndWarehouseId(Integer status, Long warehouseId);
}

@ -0,0 +1,100 @@
package cn.iocoder.yudao.module.erp.service.warehousearea;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.erp.controller.admin.autocode.util.AutoCodeUtil;
import cn.iocoder.yudao.module.erp.controller.admin.warehousearea.vo.WarehouseAreaPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.warehousearea.vo.WarehouseAreaSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.warehousearea.WarehouseAreaDO;
import cn.iocoder.yudao.module.erp.dal.mysql.warehousearea.WarehouseAreaMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.warehouselocation.WarehouseLocationMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.WAREHOUSE_AREA_CODE_EXISTS;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.WAREHOUSE_AREA_DELETE_FAIL_EXISTS_LOCATION;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.WAREHOUSE_AREA_NOT_EXISTS;
@Service
@Validated
public class WarehouseAreaServiceImpl implements WarehouseAreaService {
@Resource
private WarehouseAreaMapper warehouseAreaMapper;
@Resource
private WarehouseLocationMapper warehouseLocationMapper;
@Resource
private AutoCodeUtil autoCodeUtil;
@Override
public Long createWarehouseArea(WarehouseAreaSaveReqVO createReqVO) {
WarehouseAreaDO warehouseArea = BeanUtils.toBean(createReqVO, WarehouseAreaDO.class);
if (StringUtils.isEmpty(warehouseArea.getAreaCode())) {
warehouseArea.setAreaCode(autoCodeUtil.genSerialCode("RESERVOIR_AREA_GENERATE", null));
} else if (warehouseAreaMapper.selectByNo(warehouseArea.getAreaCode()) != null) {
throw exception(WAREHOUSE_AREA_CODE_EXISTS);
}
warehouseAreaMapper.insert(warehouseArea);
return warehouseArea.getId();
}
@Override
public void updateWarehouseArea(WarehouseAreaSaveReqVO updateReqVO) {
validateWarehouseAreaExists(updateReqVO.getId());
warehouseAreaMapper.updateById(BeanUtils.toBean(updateReqVO, WarehouseAreaDO.class));
}
@Override
public void deleteWarehouseArea(Long id) {
validateWarehouseAreaExists(id);
if (!warehouseLocationMapper.selectListByAreaId(id).isEmpty()) {
throw exception(WAREHOUSE_AREA_DELETE_FAIL_EXISTS_LOCATION);
}
warehouseAreaMapper.deleteById(id);
}
private void validateWarehouseAreaExists(Long id) {
if (warehouseAreaMapper.selectById(id) == null) {
throw exception(WAREHOUSE_AREA_NOT_EXISTS);
}
}
@Override
public WarehouseAreaDO getWarehouseArea(Long id) {
return warehouseAreaMapper.selectById(id);
}
@Override
public PageResult<WarehouseAreaDO> getWarehouseAreaPage(WarehouseAreaPageReqVO pageReqVO) {
return warehouseAreaMapper.selectPage(pageReqVO);
}
@Override
public List<WarehouseAreaDO> getWarehouseListByStatus(Integer status) {
return warehouseAreaMapper.selectListByStatus(status);
}
@Override
public List<WarehouseAreaDO> getWarehouseListByStatusAndWarehouseId(Integer status, Long warehouseId) {
List<WarehouseAreaDO> list = warehouseAreaMapper.selectListByStatus(status);
if (warehouseId == null) {
return list;
}
List<WarehouseAreaDO> result = new ArrayList<>();
for (WarehouseAreaDO item : list) {
if (warehouseId.equals(item.getWarehouseId())) {
result.add(item);
}
}
return result;
}
}

@ -0,0 +1,58 @@
package cn.iocoder.yudao.module.erp.service.warehouselocation;
import java.util.*;
import cn.iocoder.yudao.module.erp.controller.admin.warehouselocation.vo.*;
import cn.iocoder.yudao.module.erp.dal.dataobject.warehouselocation.WarehouseLocationDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import javax.validation.Valid;
/**
* ERP Service
*
* @author
*/
public interface WarehouseLocationService {
/**
* ERP
*
* @param createReqVO
* @return
*/
Long createWarehouseLocation(@Valid WarehouseLocationSaveReqVO createReqVO);
/**
* ERP
*
* @param updateReqVO
*/
void updateWarehouseLocation(@Valid WarehouseLocationSaveReqVO updateReqVO);
/**
* ERP
*
* @param id
*/
void deleteWarehouseLocation(Long id);
/**
* ERP
*
* @param id
* @return ERP
*/
WarehouseLocationDO getWarehouseLocation(Long id);
List<WarehouseLocationDO> getWarehouseLocationListByStatus(Integer status);
/**
* ERP
*
* @param pageReqVO
* @return ERP
*/
PageResult<WarehouseLocationDO> getWarehouseLocationPage(WarehouseLocationPageReqVO pageReqVO);
}

@ -0,0 +1,95 @@
package cn.iocoder.yudao.module.erp.service.warehouselocation;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.erp.controller.admin.autocode.util.AutoCodeUtil;
import cn.iocoder.yudao.module.erp.controller.admin.warehouselocation.vo.WarehouseLocationPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.warehouselocation.vo.WarehouseLocationSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.warehousearea.WarehouseAreaDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.warehouselocation.WarehouseLocationDO;
import cn.iocoder.yudao.module.erp.dal.mysql.warehousearea.WarehouseAreaMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.warehouselocation.WarehouseLocationMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.WAREHOUSE_AREA_NOT_EXISTS;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.WAREHOUSE_LOCATION_CODE_EXISTS;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.WAREHOUSE_LOCATION_NOT_EXISTS;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.WAREHOUSE_LOCATION_WAREHOUSE_AREA_NOT_MATCH;
@Service
@Validated
public class WarehouseLocationServiceImpl implements WarehouseLocationService {
@Resource
private WarehouseLocationMapper warehouseLocationMapper;
@Resource
private WarehouseAreaMapper warehouseAreaMapper;
@Resource
private AutoCodeUtil autoCodeUtil;
@Override
public Long createWarehouseLocation(WarehouseLocationSaveReqVO createReqVO) {
validateWarehouseAreaMatch(createReqVO.getWarehouseId(), createReqVO.getAreaId());
WarehouseLocationDO warehouseLocation = BeanUtils.toBean(createReqVO, WarehouseLocationDO.class);
if (StringUtils.isEmpty(warehouseLocation.getCode())) {
warehouseLocation.setCode(autoCodeUtil.genSerialCode("RESERVOIR_AREA_GENERATE", null));
} else if (warehouseLocationMapper.selectByNo(warehouseLocation.getCode()) != null) {
throw exception(WAREHOUSE_LOCATION_CODE_EXISTS);
}
warehouseLocationMapper.insert(warehouseLocation);
return warehouseLocation.getId();
}
@Override
public void updateWarehouseLocation(WarehouseLocationSaveReqVO updateReqVO) {
validateWarehouseLocationExists(updateReqVO.getId());
validateWarehouseAreaMatch(updateReqVO.getWarehouseId(), updateReqVO.getAreaId());
warehouseLocationMapper.updateById(BeanUtils.toBean(updateReqVO, WarehouseLocationDO.class));
}
@Override
public void deleteWarehouseLocation(Long id) {
validateWarehouseLocationExists(id);
warehouseLocationMapper.deleteById(id);
}
private void validateWarehouseLocationExists(Long id) {
if (warehouseLocationMapper.selectById(id) == null) {
throw exception(WAREHOUSE_LOCATION_NOT_EXISTS);
}
}
private void validateWarehouseAreaMatch(Long warehouseId, Long areaId) {
WarehouseAreaDO area = warehouseAreaMapper.selectById(areaId);
if (area == null) {
throw exception(WAREHOUSE_AREA_NOT_EXISTS);
}
if (warehouseId == null || !warehouseId.equals(area.getWarehouseId())) {
throw exception(WAREHOUSE_LOCATION_WAREHOUSE_AREA_NOT_MATCH);
}
}
@Override
public WarehouseLocationDO getWarehouseLocation(Long id) {
return warehouseLocationMapper.selectById(id);
}
@Override
public List<WarehouseLocationDO> getWarehouseLocationListByStatus(Integer status) {
return warehouseLocationMapper.selectListByStatus(status);
}
@Override
public PageResult<WarehouseLocationDO> getWarehouseLocationPage(WarehouseLocationPageReqVO pageReqVO) {
return warehouseLocationMapper.selectPage(pageReqVO);
}
}

@ -24,8 +24,8 @@
SELECT DISTINCT
rel.device_id AS id,
CASE
WHEN d.id IS NULL THEN CONCAT('设备[', rel.device_id, ']【已删除】')
WHEN d.deleted = b'1' THEN CONCAT(d.device_name, '(', d.device_code, ')【已删除】')
WHEN d.id IS NULL THEN CONCAT('设备[', rel.device_id, '](已被删除)')
WHEN d.deleted = b'1' THEN CONCAT(d.device_name, '(', d.device_code, ')(已被删除)')
ELSE CONCAT(d.device_name, '(', d.device_code, ')')
END AS name
FROM erp_product_device_rel rel

@ -0,0 +1,12 @@
<?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="cn.iocoder.yudao.module.erp.dal.mysql.warehousearea.WarehouseAreaMapper">
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
</mapper>

@ -0,0 +1,12 @@
<?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="cn.iocoder.yudao.module.erp.dal.mysql.warehouselocation.WarehouseLocationMapper">
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
</mapper>

@ -137,9 +137,9 @@ public class DeviceController {
}
@GetMapping("/deviceList")
// @PreAuthorize("@ss.hasPermission('iot:device:query')")
public CommonResult<List<DeviceRespVO>> deviceList(@Valid DevicePageReqVO pageReqVO) {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<DeviceRespVO> list = deviceService.getDevicePage(pageReqVO).getList();
public CommonResult<List<DeviceDO>> deviceList(@Valid DevicePageReqVO pageReqVO) {
// List<DeviceRespVO> list = deviceService.getDevicePage(pageReqVO).getList();
List<DeviceDO> list = deviceService.deviceList(pageReqVO);
return success(list);
}

@ -9,6 +9,10 @@ import java.time.temporal.TemporalAdjusters;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.DEVICE_RATE_TREND_PERIOD_INVALID;
/**
*/
@Getter
@AllArgsConstructor
public enum DeviceRateTrendPeriodEnum {

@ -111,10 +111,11 @@ public class DeviceOperationRecordController {
}
@GetMapping("/deviceRateTrendByDeviceId")
@Operation(summary = "根据设备ID查询某个设备近7日开机率和稼动率")
@Operation(summary = "根据设备ID查询某个设备开机率和稼动率")
@PreAuthorize("@ss.hasPermission('iot:device-operation-record:query')")
public CommonResult<List<DeviceOperationRateTrendRespVO>> getDeviceRateTrendByDeviceId(@RequestParam("deviceId") Long deviceId) {
return success(deviceOperationRecordService.getDeviceRateTrendByDeviceId(deviceId));
public CommonResult<List<DeviceOperationRateTrendRespVO>> getDeviceRateTrendByDeviceId(@RequestParam("deviceId") Long deviceId,
@RequestParam(value = "period", required = false) String period) {
return success(deviceOperationRecordService.getDeviceRateTrendByDeviceId(deviceId, period));
}

@ -14,6 +14,9 @@ import lombok.ToString;
@ToString(callSuper = true)
public class DeviceTotalTimeRecordReqVO extends PageParam{
@Schema(description = "时间区间LAST_WEEK/THIS_WEEK/LAST_7_DAYS/LAST_MONTH/THIS_MONTH")
private String period;
@Schema(description = "设备编码")
private String deviceCode;

@ -140,6 +140,9 @@ public interface DeviceMapper extends BaseMapperX<DeviceDO> {
List<Date> selectHolidayDays(@Param("startDay") Date startDay, @Param("endDay") Date endDay);
List<DeviceSelectRespVO> getAvailableDevicePage(@Param("page") Page<DeviceSelectRespVO> page,@Param("param") DevicePageReqVO pageReqVO);
List<Date> selectHolidayDaysInRange(@Param("startDay") Date startDay, @Param("endDayExclusive") Date endDayExclusive);
}

@ -158,6 +158,8 @@ public interface DeviceService {
PageResult<DeviceSelectRespVO> getAvailableDevicePage(DevicePageReqVO pageReqVO);
List<DeviceDO> deviceList(@Valid DevicePageReqVO pageReqVO);
List<Map<String, Object>> singleDeviceFrom(Long deviceId);
List<Map<String, Object>> getDeviceAttributeGroupList(DeviceContactModelPageReqVO deviceModelAttributePageReqVO);

@ -17,6 +17,7 @@ import cn.iocoder.yudao.module.iot.controller.admin.device.scheduled.scheduler.T
import cn.iocoder.yudao.module.iot.controller.admin.device.utils.DataTypeParseUtil;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.*;
import cn.iocoder.yudao.module.iot.controller.admin.devicecontactmodel.vo.DeviceContactModelPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.deviceoperationrecord.utils.TimeConverterUtil;
import cn.iocoder.yudao.module.iot.controller.admin.deviceoperationrecord.vo.DeviceTotalTimeRecordReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.deviceoperationrecord.vo.DeviceTotalTimeRecordRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.mqttdatarecord.vo.MqttDataRecordPageReqVO;
@ -71,6 +72,7 @@ import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
@ -372,7 +374,7 @@ public class DeviceServiceImpl implements DeviceService {
// .orderByDesc(DeviceOperationRecordDO::getCreateTime)
// );
List<DeviceOperationRecordDO> operationRecords = tdengineService.selectLatestByDeviceAndRuleMinimal(deviceIds,ruleCodes);
List<DeviceOperationRecordDO> operationRecords = tdengineService.selectLatestByDeviceAndRuleMinimal(deviceIds,null);
// 按 deviceId 分组,取最新一条
Map<Long, DeviceOperationRecordDO> latestRecordMap = operationRecords.stream()
@ -1946,41 +1948,98 @@ public class DeviceServiceImpl implements DeviceService {
return new PageResult<>(availableDeviceList, page.getTotal());
}
@Override
public List<DeviceDO> deviceList(DevicePageReqVO pageReqVO) {
return deviceMapper.selectList(pageReqVO);
}
/**
*
* deviceOperationPage
*
*
*/
@Override
public List<DeviceRateTrendPointRespVO> getDeviceRateTrend(DeviceRateTrendReqVO reqVO) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND);
// 根据 period 解析查询日期范围,不包含当天
DeviceRateTrendPeriodEnum.DateRange dateRange = DeviceRateTrendPeriodEnum.valueOfCode(reqVO.getPeriod()).resolve(LocalDate.now());
LocalDateTime startDateTime = dateRange.getStart().atStartOfDay();
LocalDateTime endDateTime = dateRange.getEnd().atTime(LocalTime.MAX).withNano(0);
// 默认只统计排产设备,这里先得到最终参与统计的设备集合
DeviceRateTrendPeriodEnum.DateRange dateRange =
DeviceRateTrendPeriodEnum.valueOfCode(reqVO.getPeriod()).resolve(LocalDate.now());
LocalDate startDate = dateRange.getStart();
LocalDate endDate = dateRange.getEnd();
LocalDateTime startDateTime = startDate.atStartOfDay();
LocalDateTime endDateTime = endDate.atTime(LocalTime.MAX).withNano(0);
String filteredIds = buildFilteredDeviceIds(reqVO);
if (StringUtils.isBlank(filteredIds)) {
return Collections.emptyList();
}
List<Long> deviceIds = Arrays.stream(filteredIds.split(","))
.filter(StringUtils::isNotBlank)
.map(Long::valueOf)
.distinct()
.collect(Collectors.toList());
List<Map<String, Object>> statsList = tdengineService.selectDeviceStatsTrendFromTD(
deviceIds,
startDateTime.format(formatter),
endDateTime.format(formatter)
);
// day -> (deviceId -> record)
Map<LocalDate, Map<Long, DeviceTotalTimeRecordRespVO>> dayDeviceRecordMap = convertTrendStatsToMap(statsList);
// skipHoliday 时,区间一次查出所有节假日,避免按天查库
Set<LocalDate> holidaySet = Collections.emptySet();
if (Boolean.TRUE.equals(reqVO.getSkipHoliday())) {
List<Date> holidays = deviceMapper.selectHolidayDaysInRange(
java.sql.Timestamp.valueOf(startDate.atStartOfDay()),
java.sql.Timestamp.valueOf(endDate.plusDays(1).atStartOfDay())
);
holidaySet = holidays == null ? Collections.emptySet() : holidays.stream()
.filter(Objects::nonNull)
.map(this::toLocalDateSafe)
.collect(Collectors.toSet());
}
int deviceCount = deviceIds.size();
List<DeviceRateTrendPointRespVO> result = new ArrayList<>();
for (LocalDate day = startDateTime.toLocalDate(); !day.isAfter(endDateTime.toLocalDate()); day = day.plusDays(1)) {
// 跳过节假日时,这一天不查询,也不返回
if (Boolean.TRUE.equals(reqVO.getSkipHoliday()) && isHoliday(day)) {
for (LocalDate day = startDate; !day.isAfter(endDate); day = day.plusDays(1)) {
if (Boolean.TRUE.equals(reqVO.getSkipHoliday()) && holidaySet.contains(day)) {
continue;
}
LocalDateTime dayStart = day.atStartOfDay();
LocalDateTime dayEnd = day.atTime(LocalTime.MAX).withNano(0);
// 复用现有 deviceOperationPage查出当天每台设备的开机率、稼动率基础数据
List<DeviceTotalTimeRecordRespVO> deviceDayList = queryDeviceDayList(reqVO, filteredIds, dayStart.format(formatter), dayEnd.format(formatter));
Map<Long, DeviceTotalTimeRecordRespVO> dayMap =
dayDeviceRecordMap.getOrDefault(day, Collections.emptyMap());
double powerOnRateSum = 0D;
double utilizationRateSum = 0D;
int deviceCount = deviceDayList.size();
for (DeviceTotalTimeRecordRespVO record : deviceDayList) {
powerOnRateSum += parsePercentValue(record.getPowerOnRate());
utilizationRateSum += parsePercentValue(record.getUtilizationRate());
}
for (Long deviceId : deviceIds) {
DeviceTotalTimeRecordRespVO record = dayMap.get(deviceId);
if (record == null) {
// 无数据按 0
continue;
}
// 直接按秒计算,不走字符串百分比解析
double offlineSec = record.getTotalOfflineTime();
double runningSec = record.getTotalRunningTime();
double standbySec = record.getTotalStandbyTime();
double faultSec = record.getTotalFaultTime();
double onlineSec = runningSec + standbySec + faultSec;
double totalSec = offlineSec + onlineSec;
double powerOnRate = totalSec > 0 ? (onlineSec / totalSec) : 0D;
double utilizationRate = onlineSec > 0 ? (runningSec / onlineSec) : 0D;
powerOnRateSum += powerOnRate * 100D;
utilizationRateSum += utilizationRate * 100D;
}
DeviceRateTrendPointRespVO point = new DeviceRateTrendPointRespVO();
point.setDay(day.toString());
@ -1988,11 +2047,101 @@ public class DeviceServiceImpl implements DeviceService {
point.setPowerOnRate(formatPercentValue(deviceCount > 0 ? powerOnRateSum / deviceCount : 0D));
point.setUtilizationRate(formatPercentValue(deviceCount > 0 ? utilizationRateSum / deviceCount : 0D));
result.add(point);
}
return result;
}
private Map<LocalDate, Map<Long, DeviceTotalTimeRecordRespVO>> convertTrendStatsToMap(List<Map<String, Object>> statsList) {
Map<LocalDate, Map<Long, DeviceTotalTimeRecordRespVO>> result = new LinkedHashMap<>();
if (statsList == null || statsList.isEmpty()) {
return result;
}
for (Map<String, Object> row : statsList) {
Object statDayObj = row.get("statDay");
if (statDayObj == null) {
statDayObj = row.get("statday");
}
if (statDayObj == null || row.get("deviceId") == null) {
continue;
}
LocalDate statDay;
if (statDayObj instanceof Timestamp) {
statDay = ((Timestamp) statDayObj).toLocalDateTime().toLocalDate();
} else if (statDayObj instanceof LocalDateTime) {
statDay = ((LocalDateTime) statDayObj).toLocalDate();
} else {
statDay = LocalDateTime.parse(statDayObj.toString().replace(" ", "T")).toLocalDate();
}
Long deviceId = ((Number) row.get("deviceId")).longValue();
DeviceTotalTimeRecordRespVO vo = new DeviceTotalTimeRecordRespVO();
vo.setId(deviceId);
vo.setTotalOfflineTime(getDoubleValue(row, "totalOfflineTime"));
vo.setTotalRunningTime(getDoubleValue(row, "totalRunningTime"));
vo.setTotalStandbyTime(getDoubleValue(row, "totalStandbyTime"));
vo.setTotalFaultTime(getDoubleValue(row, "totalFaultTime"));
result.computeIfAbsent(statDay, key -> new HashMap<>()).put(deviceId, vo);
}
return result;
}
/**
* day -> device stats
*/
private Map<LocalDate, List<DeviceTotalTimeRecordRespVO>> convertTrendStats(List<Map<String, Object>> statsList) {
Map<LocalDate, List<DeviceTotalTimeRecordRespVO>> result = new LinkedHashMap<>();
if (statsList == null || statsList.isEmpty()) {
return result;
}
for (Map<String, Object> row : statsList) {
Object statDayObj = row.get("statDay");
if (statDayObj == null) {
statDayObj = row.get("statday");
}
if (statDayObj == null) {
continue;
}
LocalDate statDay;
if (statDayObj instanceof Timestamp) {
statDay = ((Timestamp) statDayObj).toLocalDateTime().toLocalDate();
} else if (statDayObj instanceof LocalDateTime) {
statDay = ((LocalDateTime) statDayObj).toLocalDate();
} else {
statDay = LocalDateTime.parse(statDayObj.toString().replace(" ", "T")).toLocalDate();
}
DeviceTotalTimeRecordRespVO vo = new DeviceTotalTimeRecordRespVO();
vo.setId(((Number) row.get("deviceId")).longValue());
vo.setTotalOfflineTime(getDoubleValue(row, "totalOfflineTime"));
vo.setTotalRunningTime(getDoubleValue(row, "totalRunningTime"));
vo.setTotalStandbyTime(getDoubleValue(row, "totalStandbyTime"));
vo.setTotalFaultTime(getDoubleValue(row, "totalFaultTime"));
result.computeIfAbsent(statDay, key -> new ArrayList<>()).add(vo);
}
return result;
}
private DeviceTotalTimeRecordReqVO buildTrendReqVO(LocalDate day) {
DeviceTotalTimeRecordReqVO reqVO = new DeviceTotalTimeRecordReqVO();
reqVO.setStartTime(day.atStartOfDay().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
reqVO.setEndTime(day.atTime(LocalTime.MAX).withNano(0).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
return reqVO;
}
private double parsePercentValue(String percent) {
if (StringUtils.isBlank(percent)) {
return 0D;
@ -2011,37 +2160,57 @@ public class DeviceServiceImpl implements DeviceService {
return String.format("%.2f%%", value);
}
private LocalDate toLocalDateSafe(Date date) {
if (date instanceof java.sql.Date) {
return ((java.sql.Date) date).toLocalDate();
}
if (date instanceof java.sql.Timestamp) {
return ((java.sql.Timestamp) date).toLocalDateTime().toLocalDate();
}
return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
}
private List<DeviceTotalTimeRecordRespVO> queryDeviceDayList(DeviceRateTrendReqVO reqVO, String ids, String startTime, String endTime) {
DeviceTotalTimeRecordReqVO pageReqVO =
new DeviceTotalTimeRecordReqVO();
pageReqVO.setDeviceCode(reqVO.getDeviceCode());
pageReqVO.setDeviceName(reqVO.getDeviceName());
pageReqVO.setIds(ids);
pageReqVO.setStartTime(startTime);
pageReqVO.setEndTime(endTime);
return deviceOperationRecordService.deviceOperationPageList(pageReqVO);
}
private String buildFilteredDeviceIds(DeviceRateTrendReqVO reqVO) {
boolean onlyScheduled = reqVO.getOnlyScheduled() == null || reqVO.getOnlyScheduled();
// 不只看排产设备时:
// 1. 如果前端传了 ids就按传入 ids 查询
// 2. 如果前端没传 ids就查询全部设备 id
if (!onlyScheduled) {
return reqVO.getIds();
if (StringUtils.isNotBlank(reqVO.getIds())) {
return reqVO.getIds();
}
List<Long> allDeviceIds = deviceMapper.getAllDeviceIds();
if (CollectionUtils.isEmpty(allDeviceIds)) {
return "-1";
}
return allDeviceIds.stream()
.map(String::valueOf)
.collect(Collectors.joining(","));
}
// 只统计排产设备
Collection<Long> requestIds = parseIds(reqVO.getIds());
List<Long> filteredDvIds = deviceMapper.selectScheduledDvIds(requestIds);
// 如果前端传了 ids则在排产设备中再次过滤
if (StringUtils.isNotBlank(reqVO.getIds())) {
Set<Long> requestIdSet = new HashSet<>(requestIds);
filteredDvIds = filteredDvIds.stream().filter(requestIdSet::contains).collect(Collectors.toList());
filteredDvIds = filteredDvIds.stream()
.filter(requestIdSet::contains)
.collect(Collectors.toList());
}
if (filteredDvIds.isEmpty()) {
return "-1";
}
return filteredDvIds.stream().map(String::valueOf).collect(Collectors.joining(","));
return filteredDvIds.stream()
.map(String::valueOf)
.collect(Collectors.joining(","));
}
private boolean isHoliday(LocalDate day) {
@ -2049,10 +2218,6 @@ public class DeviceServiceImpl implements DeviceService {
return !CollectionUtils.isEmpty(holidays);
}
private String toPercent(double value) {
return String.format("%.2f%%", value * 100);
}
private Collection<Long> parseIds(String ids) {
if (StringUtils.isBlank(ids)) {
return Collections.emptyList();
@ -2066,5 +2231,71 @@ public class DeviceServiceImpl implements DeviceService {
/**
*
* calculateAndSetConvertedValues
* = 线 /
* = / 线
*/
private void calculateRate(DeviceTotalTimeRecordRespVO record) {
if (record == null) {
return;
}
double offlineSec = record.getTotalOfflineTime();
double runningSec = record.getTotalRunningTime();
double standbySec = record.getTotalStandbyTime();
double faultSec = record.getTotalFaultTime();
// 在线时间 = 运行 + 待机 + 故障
double onlineSec = runningSec + standbySec + faultSec;
double totalSec = offlineSec + onlineSec;
// 防止异常值
if (totalSec < 0) {
totalSec = 0;
}
// 开机率 = 在线时间 / 总时间
double powerOnRate = 0D;
if (totalSec > 0) {
powerOnRate = onlineSec / totalSec;
}
// 稼动率 = 运行时间 / 在线时间
double utilizationRate = 0D;
if (onlineSec > 0) {
utilizationRate = runningSec / onlineSec;
}
record.setPowerOnRate(TimeConverterUtil.getPercentString(powerOnRate));
record.setUtilizationRate(TimeConverterUtil.getPercentString(utilizationRate));
}
private Double getDoubleValue(Map<String, Object> row, String key) {
if (row == null || key == null) {
return 0D;
}
Object value = row.get(key);
if (value == null) {
value = row.get(key.toLowerCase());
}
if (value == null) {
return 0D;
}
if (value instanceof Number) {
return ((Number) value).doubleValue();
}
try {
return Double.parseDouble(value.toString());
} catch (Exception e) {
return 0D;
}
}
}

@ -2009,7 +2009,8 @@ public class TDengineService {
/**
*
* 使TDengineLAST
* GROUP BY device_id
*/
@DS("tdengine")
public List<DeviceOperationRecordDO> selectLatestByDeviceAndRuleMinimal(
@ -2020,59 +2021,84 @@ public class TDengineService {
return Collections.emptyList();
}
// 优化:分组查询每个设备的最新记录
List<DeviceOperationRecordDO> allResults = new ArrayList<>();
for (Long deviceId : deviceIds) {
StringBuilder sql = new StringBuilder(
"SELECT * FROM besure_server.iot_device_operation_record " +
"WHERE deleted = 0 AND device_id = ? "
);
// 构建SQL查询使用TDengine的LAST函数
StringBuilder sql = new StringBuilder(
"SELECT device_id, " +
"LAST(device_id) as last_device_id, " +
"LAST(rule) as rule, " +
"LAST(address_value) as address_value, " +
"LAST(create_time) as create_time, " +
"LAST(model_id) as model_id, " +
"LAST(creator) as creator, " +
"LAST(updater) as updater, " +
"LAST(update_time) as update_time, " +
"LAST(deleted) as deleted, " +
"LAST(tenant_id) as tenant_id, " +
"LAST(rule_id) as rule_id " +
"FROM besure_server.iot_device_operation_record " +
"WHERE deleted = 0 "
);
// 添加设备ID条件
sql.append("AND device_id IN (");
List<Object> params = new ArrayList<>();
List<Object> params = new ArrayList<>();
params.add(deviceId);
for (int i = 0; i < deviceIds.size(); i++) {
if (i > 0) {
sql.append(", ");
}
sql.append("?");
params.add(deviceIds.get(i));
}
sql.append(") ");
if (CollectionUtils.isNotEmpty(ruleCodes)) {
sql.append("AND rule IN (");
for (int i = 0; i < ruleCodes.size(); i++) {
if (i > 0) sql.append(", ");
sql.append("?");
params.add(ruleCodes.get(i));
// 添加规则代码条件
if (CollectionUtils.isNotEmpty(ruleCodes)) {
sql.append("AND rule IN (");
for (int i = 0; i < ruleCodes.size(); i++) {
if (i > 0) {
sql.append(", ");
}
sql.append(") ");
sql.append("?");
params.add(ruleCodes.get(i));
}
sql.append(") ");
}
sql.append("ORDER BY create_time DESC LIMIT 1"); // 每个设备只取最新1条
// 使用GROUP BY device_id获取每个设备的最新记录
sql.append("GROUP BY device_id ");
try {
List<DeviceOperationRecordDO> deviceResults = jdbcTemplate.query(
sql.toString(),
params.toArray(),
(rs, rowNum) -> {
DeviceOperationRecordDO d = new DeviceOperationRecordDO();
d.setDeviceId(rs.getLong("device_id"));
d.setModelId(rs.getLong("model_id"));
d.setRule(rs.getString("rule"));
d.setAddressValue(rs.getString("address_value"));
d.setCreator(rs.getString("creator"));
d.setCreateTime(rs.getTimestamp("create_time") != null ? rs.getTimestamp("create_time").toLocalDateTime() : null);
d.setUpdater(rs.getString("updater"));
d.setUpdateTime(rs.getTimestamp("update_time") != null ? rs.getTimestamp("update_time").toLocalDateTime() : null);
d.setDeleted(rs.getBoolean("deleted"));
d.setTenantId(String.valueOf(rs.getLong("tenant_id")));
d.setRuleId(rs.getLong("rule_id"));
return d;
});
allResults.addAll(deviceResults);
// // 添加INTERVAL(0)确保正确处理时间窗口
// sql.append("INTERVAL(0) ");
} catch (Exception e) {
log.error("查询设备{}的最新记录失败", deviceId, e);
}
// 按设备ID排序
sql.append("ORDER BY device_id");
try {
return jdbcTemplate.query(
sql.toString(),
params.toArray(),
(rs, rowNum) -> {
DeviceOperationRecordDO d = new DeviceOperationRecordDO();
d.setDeviceId(rs.getLong("device_id"));
d.setModelId(rs.getLong("model_id"));
d.setRule(rs.getString("rule"));
d.setAddressValue(rs.getString("address_value"));
d.setCreator(rs.getString("creator"));
d.setCreateTime(rs.getTimestamp("create_time") != null ?
rs.getTimestamp("create_time").toLocalDateTime() : null);
d.setUpdater(rs.getString("updater"));
d.setUpdateTime(rs.getTimestamp("update_time") != null ?
rs.getTimestamp("update_time").toLocalDateTime() : null);
d.setDeleted(rs.getBoolean("deleted"));
d.setTenantId(String.valueOf(rs.getLong("tenant_id")));
d.setRuleId(rs.getLong("rule_id"));
return d;
});
} catch (Exception e) {
log.error("查询设备最新记录失败设备ID: {}, 错误: {}", deviceIds, e.getMessage(), e);
return Collections.emptyList();
}
return allResults;
}
/**
@ -2573,4 +2599,150 @@ public class TDengineService {
}
}
}
@DS("tdengine")
public Map<Long, Map<LocalDate, Double>> queryDailyLatestCapacityValues(Collection<Long> deviceIds,
LocalDateTime beginTime,
LocalDateTime endTime) {
Map<Long, Map<LocalDate, Double>> result = new HashMap<>();
if (deviceIds == null || deviceIds.isEmpty() || beginTime == null || endTime == null || !endTime.isAfter(beginTime)) {
return result;
}
try {
StringBuilder sql = new StringBuilder();
sql.append("SELECT _wstart AS day_key, device_id, LAST(capacity_value) AS capacityvalue ")
.append("FROM besure_server.iot_device_capacity_record ")
.append("WHERE ts >= ? AND ts < ? AND device_id IN (")
.append(deviceIds.stream().map(id -> "?").collect(Collectors.joining(",")))
.append(") PARTITION BY device_id INTERVAL(1d)");
List<Object> params = new ArrayList<>();
params.add(Timestamp.valueOf(beginTime));
params.add(Timestamp.valueOf(endTime));
params.addAll(deviceIds);
jdbcTemplate.query(sql.toString(), params.toArray(), rs -> {
Long deviceId = rs.getLong("device_id");
Timestamp dayTs = rs.getTimestamp("day_key");
Double capacityValue = rs.getDouble("capacityvalue");
if (rs.wasNull() || dayTs == null) {
return;
}
LocalDate day = dayTs.toLocalDateTime().toLocalDate();
result.computeIfAbsent(deviceId, key -> new HashMap<>())
.put(day, capacityValue);
});
} catch (Exception e) {
log.error("TDengine查询每日最新容量值失败, deviceIds: {}, beginTime: {}, endTime: {}",
deviceIds, beginTime, endTime, e);
}
return result;
}
// ========================= app报表相关接口 ===================
@DS("tdengine")
public List<Map<String, Object>> selectDeviceStatsTrendFromTD(List<Long> deviceIds, String startTime, String endTime) {
StringBuilder sql = new StringBuilder();
List<Object> params = new ArrayList<>();
sql.append("SELECT ")
.append("_wstart AS statDay, ")
.append("device_id AS deviceId, ")
.append("SUM(CASE WHEN rule = '0' THEN 1 ELSE 0 END) * 60 AS totalOfflineTime, ")
.append("SUM(CASE WHEN rule = '1' THEN 1 ELSE 0 END) * 60 AS totalRunningTime, ")
.append("SUM(CASE WHEN rule = '2' THEN 1 ELSE 0 END) * 60 AS totalStandbyTime, ")
.append("SUM(CASE WHEN rule = '3' THEN 1 ELSE 0 END) * 60 AS totalFaultTime ")
.append("FROM besure_server.iot_device_operation_record ")
.append("WHERE deleted = 0 ");
if (startTime != null && !startTime.trim().isEmpty()) {
sql.append("AND create_time >= ? ");
params.add(startTime);
}
if (endTime != null && !endTime.trim().isEmpty()) {
sql.append("AND create_time <= ? ");
params.add(endTime);
}
// deviceIds 不为空时才加过滤
if (deviceIds != null && !deviceIds.isEmpty()) {
sql.append("AND device_id IN (");
for (int i = 0; i < deviceIds.size(); i++) {
if (i > 0) {
sql.append(", ");
}
sql.append("?");
params.add(deviceIds.get(i));
}
sql.append(") ");
}
sql.append("PARTITION BY device_id ")
.append("INTERVAL(1d) ")
.append("ORDER BY statDay ASC");
try {
return jdbcTemplate.queryForList(sql.toString(), params.toArray());
} catch (Exception e) {
log.error("TDengine 查询设备日趋势统计失败sql={}, params={}", sql, params, e);
return Collections.emptyList();
}
}
@DS("tdengine")
public List<Map<String, Object>> queryDeviceDayTrend(Long deviceId, String startTime, String endTime) {
StringBuilder sql = new StringBuilder();
List<Object> params = new ArrayList<>();
sql.append("SELECT ")
.append("_wstart AS statDay, ")
.append("device_id AS deviceId, ")
.append("SUM(CASE WHEN rule = '0' THEN 1 ELSE 0 END) * 60 AS totalOfflineTime, ")
.append("SUM(CASE WHEN rule = '1' THEN 1 ELSE 0 END) * 60 AS totalRunningTime, ")
.append("SUM(CASE WHEN rule = '2' THEN 1 ELSE 0 END) * 60 AS totalStandbyTime, ")
.append("SUM(CASE WHEN rule = '3' THEN 1 ELSE 0 END) * 60 AS totalFaultTime ")
.append("FROM besure_server.iot_device_operation_record ")
.append("WHERE deleted = 0 ")
.append("AND device_id = ? ");
params.add(deviceId);
if (startTime != null && !startTime.trim().isEmpty()) {
sql.append("AND create_time >= ? ");
params.add(startTime);
}
if (endTime != null && !endTime.trim().isEmpty()) {
sql.append("AND create_time <= ? ");
params.add(endTime);
}
sql.append("PARTITION BY device_id ")
.append("INTERVAL(1d) ")
.append("ORDER BY statDay ASC");
try {
List<Map<String, Object>> list = jdbcTemplate.queryForList(sql.toString(), params.toArray());
for (Map<String, Object> row : list) {
Object statDay = row.get("statDay");
if (statDay instanceof java.sql.Timestamp) {
row.put("day", ((java.sql.Timestamp) statDay).toLocalDateTime().toLocalDate().toString());
} else if (statDay != null) {
String text = String.valueOf(statDay);
row.put("day", text.length() >= 10 ? text.substring(0, 10) : text);
} else {
row.put("day", null);
}
}
return list;
} catch (Exception e) {
log.error("TDengine 查询单设备日趋势失败sql={}, params={}", sql, params, e);
return Collections.emptyList();
}
}
}

@ -56,7 +56,7 @@ public interface DeviceOperationRecordService {
List<DeviceTotalTimeRecordRespVO> deviceOperationPageList(@Valid DeviceTotalTimeRecordReqVO pageReqVO);
List<DeviceOperationRateTrendRespVO> getDeviceRateTrendByDeviceId(Long deviceId);
List<DeviceOperationRateTrendRespVO> getDeviceRateTrendByDeviceId(Long deviceId, String period);
List<DeviceTotalTimeRecordRespVO> deviceOperationList(@Valid DeviceTotalTimeRecordReqVO pageReqVO);
}

@ -1,5 +1,7 @@
package cn.iocoder.yudao.module.iot.service.deviceoperationrecord;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.module.iot.controller.admin.device.enums.DeviceRateTrendPeriodEnum;
import cn.iocoder.yudao.module.iot.controller.admin.deviceoperationrecord.utils.TimeConverterUtil;
import cn.iocoder.yudao.module.iot.service.device.TDengineService;
import com.baomidou.mybatisplus.core.metadata.IPage;
@ -12,11 +14,9 @@ import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;
@ -92,6 +92,8 @@ public class DeviceOperationRecordServiceImpl implements DeviceOperationRecordSe
@Override
public PageResult<DeviceTotalTimeRecordRespVO> deviceOperationPage(DeviceTotalTimeRecordReqVO pageReqVO) {
applyPeriodIfNecessary(pageReqVO);
// 1. 先从 MySQL 查询设备分页信息
Page<DeviceTotalTimeRecordRespVO> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
IPage<DeviceTotalTimeRecordRespVO> mysqlDevicePage =
@ -106,6 +108,9 @@ public class DeviceOperationRecordServiceImpl implements DeviceOperationRecordSe
.map(DeviceTotalTimeRecordRespVO::getId)
.collect(Collectors.toList());
log.info("deviceOperationPage mysql设备ID列表 pageReqVO.startTime={}, pageReqVO.endTime={}, deviceIds={}",
pageReqVO.getStartTime(), pageReqVO.getEndTime(), deviceIds);
// 3. 从 TDengine 批量查询统计数据
List<Map<String, Object>> statsList =
deviceOperationRecordMapper.selectDeviceStatsFromTD(
@ -114,6 +119,9 @@ public class DeviceOperationRecordServiceImpl implements DeviceOperationRecordSe
pageReqVO.getEndTime()
);
log.info("deviceOperationPage TD原始统计 startTime={}, endTime={}, statsList={}",
pageReqVO.getStartTime(), pageReqVO.getEndTime(), statsList);
// 4. 转换为 Map<设备ID, 统计数据>
Map<Long, DeviceTotalTimeRecordRespVO> tdStatsMap = convertStatsListToMap(statsList);
@ -122,6 +130,10 @@ public class DeviceOperationRecordServiceImpl implements DeviceOperationRecordSe
List<DeviceTotalTimeRecordRespVO> result = new ArrayList<>();
for (DeviceTotalTimeRecordRespVO device : mysqlDevicePage.getRecords()) {
DeviceTotalTimeRecordRespVO stats = tdStatsMap.get(device.getId());
log.info("deviceOperationPage 合并前 deviceId={}, deviceCode={}, deviceName={}, stats={}",
device.getId(), device.getDeviceCode(), device.getDeviceName(), stats);
if (stats != null) {
// 设置统计数据
device.setTotalOfflineTime(stats.getTotalOfflineTime());
@ -137,6 +149,7 @@ public class DeviceOperationRecordServiceImpl implements DeviceOperationRecordSe
}
result.add(device);
}
log.info("deviceOperationPage mysql设备ID列表: {}", deviceIds);
// 5. 计算和转换
calculateAndSetConvertedValues(result, pageReqVO);
@ -148,6 +161,8 @@ public class DeviceOperationRecordServiceImpl implements DeviceOperationRecordSe
@Override
public List<DeviceTotalTimeRecordRespVO> deviceOperationPageList(DeviceTotalTimeRecordReqVO pageReqVO) {
applyPeriodIfNecessary(pageReqVO);
List<DeviceTotalTimeRecordRespVO> deviceList =
deviceOperationRecordMapper.selectDeviceListFromMySQL(pageReqVO);
@ -191,33 +206,153 @@ public class DeviceOperationRecordServiceImpl implements DeviceOperationRecordSe
}
@Override
public List<DeviceOperationRateTrendRespVO> getDeviceRateTrendByDeviceId(Long deviceId) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
List<DeviceOperationRateTrendRespVO> result = new ArrayList<>();
public List<DeviceOperationRateTrendRespVO> getDeviceRateTrendByDeviceId(Long deviceId, String period) {
DeviceRateTrendPeriodEnum.DateRange dateRange = resolvePeriodRange(period);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND);
for (int offset = 6; offset >= 0; offset--) {
LocalDate day = LocalDate.now().minusDays(offset);
LocalDateTime dayStart = day.atStartOfDay();
LocalDateTime dayEnd = day.atTime(LocalTime.MAX).withNano(0);
String startTime = dateRange.getStart().atStartOfDay().format(formatter);
String endTime = dateRange.getEnd().atTime(LocalTime.MAX).withNano(0).format(formatter);
DeviceTotalTimeRecordReqVO reqVO = new DeviceTotalTimeRecordReqVO();
reqVO.setIds(String.valueOf(deviceId));
reqVO.setStartTime(dayStart.format(formatter));
reqVO.setEndTime(dayEnd.format(formatter));
log.info("getDeviceRateTrendByDeviceId 开始 deviceId={}, period={}, startTime={}, endTime={}",
deviceId, period, startTime, endTime);
// queryDeviceDayTrend 改成“按 create_time 的日期分组”,
// 则这里每一天的结果就等价于 deviceOperationPage 单独查当天
List<Map<String, Object>> dayRows = tDengineService.queryDeviceDayTrend(deviceId, startTime, endTime);
log.info("getDeviceRateTrendByDeviceId TD原始结果 deviceId={}, dayRows={}", deviceId, dayRows);
Map<LocalDate, Map<String, Object>> dayMap = new HashMap<>();
if (CollectionUtils.isNotEmpty(dayRows)) {
for (Map<String, Object> row : dayRows) {
Object dayObj = row.get("day");
if (dayObj == null) {
continue;
}
try {
dayMap.put(LocalDate.parse(String.valueOf(dayObj)), row);
} catch (Exception e) {
log.warn("解析设备日趋势日期失败deviceId={}, day={}", deviceId, dayObj);
}
}
}
List<DeviceTotalTimeRecordRespVO> dayList = deviceOperationPageList(reqVO);
DeviceTotalTimeRecordRespVO record = CollectionUtils.isNotEmpty(dayList) ? dayList.get(0) : null;
List<DeviceOperationRateTrendRespVO> result = new ArrayList<>();
for (LocalDate day = dateRange.getStart(); !day.isAfter(dateRange.getEnd()); day = day.plusDays(1)) {
Map<String, Object> row = dayMap.get(day);
DeviceOperationRateTrendRespVO trend = new DeviceOperationRateTrendRespVO();
trend.setDay(day.toString());
trend.setPowerOnRate(record != null ? record.getPowerOnRate() : "0%");
trend.setUtilizationRate(record != null ? record.getUtilizationRate() : "0%");
if (row == null) {
trend.setPowerOnRate("0%");
trend.setUtilizationRate("0%");
result.add(trend);
continue;
}
try {
// 与 calculateAndSetConvertedValues 完全一致
double offlineSec = toDouble(row, "totalOfflineTime");
double runningSec = toDouble(row, "totalRunningTime");
double standbySec = toDouble(row, "totalStandbyTime");
double faultSec = toDouble(row, "totalFaultTime");
double onlineSec = runningSec + standbySec + faultSec;
double totalSec = offlineSec + onlineSec;
if (totalSec < 0) {
totalSec = 0;
}
double powerOnRate = 0D;
if (totalSec > 0D) {
powerOnRate = onlineSec / totalSec;
}
double utilizationRate = 0D;
if (onlineSec > 0D) {
utilizationRate = runningSec / onlineSec;
}
trend.setPowerOnRate(TimeConverterUtil.getPercentString(powerOnRate));
trend.setUtilizationRate(TimeConverterUtil.getPercentString(utilizationRate));
log.info("getDeviceRateTrendByDeviceId 每日计算 deviceId={}, day={}, row={}, " +
"offlineSec={}, runningSec={}, standbySec={}, faultSec={}, onlineSec={}, totalSec={}, " +
"powerOnRateRaw={}, utilizationRateRaw={}, powerOnRateStr={}, utilizationRateStr={}",
deviceId,
day,
row,
offlineSec,
runningSec,
standbySec,
faultSec,
onlineSec,
totalSec,
powerOnRate,
utilizationRate,
TimeConverterUtil.getPercentString(powerOnRate),
TimeConverterUtil.getPercentString(utilizationRate)
);
} catch (Exception e) {
log.error("计算设备日趋势失败deviceId={}, day={}", deviceId, day, e);
trend.setPowerOnRate("0%");
trend.setUtilizationRate("0%");
}
result.add(trend);
}
return result;
}
private static double toDouble(Map<String, Object> row, String key) {
if (row == null || row.get(key) == null) {
return 0D;
}
Object value = row.get(key);
if (value instanceof Number) {
return ((Number) value).doubleValue();
}
try {
return Double.parseDouble(String.valueOf(value));
} catch (Exception e) {
return 0D;
}
}
private void applyPeriodIfNecessary(DeviceTotalTimeRecordReqVO reqVO) {
if (StringUtils.isNotBlank(reqVO.getStartTime()) && StringUtils.isNotBlank(reqVO.getEndTime())) {
return;
}
String period = StringUtils.defaultIfBlank(
reqVO.getPeriod(),
DeviceRateTrendPeriodEnum.LAST_7_DAYS.getCode()
);
DeviceRateTrendPeriodEnum.DateRange dateRange = DeviceRateTrendPeriodEnum
.valueOfCode(period)
.resolve(LocalDate.now());
LocalDateTime startDateTime = dateRange.getStart().atStartOfDay();
LocalDateTime endDateTime = dateRange.getEnd().atTime(LocalTime.MAX).withNano(0);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND);
reqVO.setStartTime(startDateTime.format(formatter));
reqVO.setEndTime(endDateTime.format(formatter));
}
private DeviceRateTrendPeriodEnum.DateRange resolvePeriodRange(String period) {
String actualPeriod = StringUtils.defaultIfBlank(period, DeviceRateTrendPeriodEnum.LAST_7_DAYS.getCode());
return DeviceRateTrendPeriodEnum.valueOfCode(actualPeriod).resolve(LocalDate.now());
}
@Override
public List<DeviceTotalTimeRecordRespVO> deviceOperationList(DeviceTotalTimeRecordReqVO deviceTotalTimeRecordReqVO) {
@ -391,6 +526,25 @@ public class DeviceOperationRecordServiceImpl implements DeviceOperationRecordSe
record.setPowerOnRate(TimeConverterUtil.getPercentString(powerOnRate));
record.setUtilizationRate(TimeConverterUtil.getPercentString(utilizationRate));
log.info("calculateAndSetConvertedValues deviceId={}, deviceCode={}, startTime={}, endTime={}, " +
"offlineSec={}, runningSec={}, standbySec={}, faultSec={}, onlineSec={}, totalSec={}, " +
"powerOnRateRaw={}, utilizationRateRaw={}, powerOnRateStr={}, utilizationRateStr={}",
record.getId(),
record.getDeviceCode(),
startTimeStr,
endTimeStr,
offlineSec,
runningSec,
standbySec,
faultSec,
onlineSec,
totalSec,
powerOnRate,
utilizationRate,
TimeConverterUtil.getPercentString(powerOnRate),
TimeConverterUtil.getPercentString(utilizationRate)
);
} catch (Exception e) {
log.error("计算设备{}时间统计出错: {}", record.getDeviceCode(), e.getMessage());
setDefaultValues(record);

@ -299,5 +299,13 @@
ORDER BY d.id DESC
</select>
<select id="selectHolidayDaysInRange" resultType="java.util.Date">
SELECT DISTINCT the_day
FROM mes_cal_holiday
WHERE deleted = b'0'
AND the_day &gt;= #{startDay}
AND the_day &lt; #{endDayExclusive}
AND holiday_type = 'HOLIDAY'
</select>
</mapper>

@ -194,6 +194,10 @@ public interface ErrorCodeConstants {
ErrorCode SCHEDULE_WORK_HOURS_INVALID = new ErrorCode(100_301_0014, "排产工时非法start={}, end={}可用工时必须大于0");
ErrorCode WAREHOUSE_NOT_EXISTS= new ErrorCode(100_301_0014, "仓库Id不能为空");
ErrorCode PLAN_RECORD_NOT_EXISTS = new ErrorCode(100_301_0015, "生产计划操作记录不存在");
ErrorCode SCHEDULE_PRODUCT_DAILY_AVERAGE_ZERO = new ErrorCode(100_301_0016, "产品最近半年平均报工值为0productId={}productCode={}productName={}");
ErrorCode SCHEDULE_DEVICE_COLLECTION_CAPACITY_ZERO = new ErrorCode(100_301_0017, "{}-{}设备最近半年数据采集产能为0deviceId={}deviceName={}");
ErrorCode SCHEDULE_DEVICE_ORGANIZATION_NOT_FOUND = new ErrorCode(100_301_0018, "{}-{}设备未关联产线工位deviceId={}deviceName={}");
ErrorCode SCHEDULE_DEVICE_COLLECTION_MAPPING_MISSING = new ErrorCode(100_301_0019, "{}-{}设备未关联采集设备deviceId={}deviceName={}");

@ -77,10 +77,10 @@ public class CriticalComponentController {
@GetMapping("/get")
@Operation(summary = "获得设备关键件")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('mes:critical-component:query')")
public CommonResult<CriticalComponentRespVO> getCriticalComponent(@RequestParam("id") Long id) {
CriticalComponentDO criticalComponent = criticalComponentService.getCriticalComponent(id);
public CommonResult<CriticalComponentRespVO> getCriticalComponent(@RequestParam(value = "id", required = false) Long id,
@RequestParam(value = "code", required = false) String code) {
CriticalComponentDO criticalComponent = criticalComponentService.getCriticalComponent(id, code);
return success(BeanUtils.toBean(criticalComponent, CriticalComponentRespVO.class));
}
@ -179,4 +179,4 @@ public class CriticalComponentController {
return success(true);
}
}
}

@ -139,39 +139,6 @@ public class DashboardController {
item.setValue(taskMapper.selectCount(new LambdaQueryWrapperX<TaskDO>()
.betweenIfPresent(TaskDO::getCreateTime, taskReqVO.getStartTime()))); // 创建时间
taskItems.add(item);
// // 未开工任务数
// item = new TaskRespVO.Item();
// item.setKey("2");
// item.setLabel("未开工任务数");
// Collection<Long> count1 = new ArrayList<>();
// count1.add(1L);
// count1.add(2L);
// count1.add(3L);
// item.setValue(taskMapper.selectCount(new LambdaQueryWrapperX<TaskDO>()
// .in(TaskDO::getStatus, count1)
// .betweenIfPresent(TaskDO::getOrderDate, taskReqVO.getStartTime()))); // 下达时间
// taskItems.add(item);
// // 生产中任务数
// item = new TaskRespVO.Item();
// item.setKey("3");
// item.setLabel("生产中任务数");
// Collection<Long> count2 = new ArrayList<>();
// count2.add(4L);
// item.setValue(taskMapper.selectCount(new LambdaQueryWrapperX<TaskDO>()
// .in(TaskDO::getStatus, count2)
// .betweenIfPresent(TaskDO::getOrderDate, taskReqVO.getStartTime())));
// taskItems.add(item);
// // 完工任务数
// item = new TaskRespVO.Item();
// item.setKey("4");
// item.setLabel("完工任务数");
// Collection<Long> count3 = new ArrayList<>();
// count3.add(5L);
// count3.add(6L);
// item.setValue(taskMapper.selectCount(new LambdaQueryWrapperX<TaskDO>()
// .in(TaskDO::getStatus, count3)
// .betweenIfPresent(TaskDO::getOrderDate, taskReqVO.getStartTime())));
// taskItems.add(item);
// 生产计划总数
@ -347,66 +314,108 @@ public class DashboardController {
@GetMapping("/getTodoList")
@Operation(summary = "获得待办任务")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
// @PreAuthorize("@ss.hasPermission('mes:bom:query')")
// @PreAuthorize("@ss.hasPermission('mes:bom:query')")
public CommonResult<List<TodoRespVO>> getTodoList() {
// 待办结果集
List<TodoRespVO> todoRespVOList = new ArrayList<>();
// 设备维修
// 1. 查询各类待办数据
List<DvRepairDO> dvRepairDOList = dvRepairService.getDvRepairDOListByStatus();
List<TicketManagementDO> ticketManagementDOList = ticketManagementService.getListByJobStatus();
List<MoldRepairDO> moldRepairDOList = moldRepairService.getMoldRepairDOListByStatus();
List<MoldTicketManagementDO> moldTicketManagementDOList = moldTicketManagementService.getListByJobStatus();
// 2. 批量查询设备名称,避免循环中逐条查库
Map<Long, String> deviceNameMap = new HashMap<>();
if (dvRepairDOList != null && !dvRepairDOList.isEmpty()) {
List<Long> deviceIds = dvRepairDOList.stream()
.map(DvRepairDO::getDeviceId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
if (!deviceIds.isEmpty()) {
List<DeviceLedgerDO> deviceLedgerList = deviceLedgerService.getDeviceLedgerListByIds(deviceIds);
deviceNameMap = deviceLedgerList.stream()
.collect(Collectors.toMap(
DeviceLedgerDO::getId,
DeviceLedgerDO::getDeviceName,
(a, b) -> a
));
}
}
// 3. 批量查询模具名称,避免循环中逐条查库
Map<Long, String> moldNameMap = new HashMap<>();
if (moldRepairDOList != null && !moldRepairDOList.isEmpty()) {
List<Long> moldIds = moldRepairDOList.stream()
.map(MoldRepairDO::getMoldId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
if (!moldIds.isEmpty()) {
List<MoldDO> moldList = moldService.getMoldListByIds(moldIds);
moldNameMap = moldList.stream()
.collect(Collectors.toMap(
MoldDO::getId,
MoldDO::getName,
(a, b) -> a
));
}
}
// 4. 组装设备维修待办
for (DvRepairDO dvRepairDO : dvRepairDOList) {
TodoRespVO todoRespVO = new TodoRespVO();
TodoRespVO todoRespVO = new TodoRespVO();
todoRespVO.setCode(dvRepairDO.getRepairCode());
todoRespVO.setName(dvRepairDO.getRepairName());
todoRespVO.setType("设备维修");
todoRespVO.setDeviceName(deviceLedgerService.getDeviceLedger(dvRepairDO.getDeviceId()).getDeviceName());
todoRespVO.setDeviceName(deviceNameMap.getOrDefault(dvRepairDO.getDeviceId(), "未知设备"));
todoRespVO.setCreateTime(dvRepairDO.getCreateTime());
todoRespVOList.add(todoRespVO);
}
// 设备保养 点检
List<TicketManagementDO> ticketManagementDOList = ticketManagementService.getListByJobStatus();
for (TicketManagementDO ticketManagementDO : ticketManagementDOList) {
TodoRespVO todoRespVO = new TodoRespVO();
// 5. 组装设备保养 / 点检待办
for (TicketManagementDO ticketManagementDO : ticketManagementDOList) {
TodoRespVO todoRespVO = new TodoRespVO();
todoRespVO.setCode(ticketManagementDO.getPlanNo());
todoRespVO.setName(ticketManagementDO.getConfigName());
if (ticketManagementDO.getPlanType() == 2) {
todoRespVO.setType("设备保养");
} else {
todoRespVO.setType("设备点检");
}
todoRespVO.setType(ticketManagementDO.getPlanType() == 2 ? "设备保养" : "设备点检");
todoRespVO.setDeviceName(ticketManagementDO.getDeviceName());
todoRespVO.setCreateTime(ticketManagementDO.getCreateTime());
todoRespVOList.add(todoRespVO);
}
// 模具维修
List<MoldRepairDO> moldRepairDOList = moldRepairService.getMoldRepairDOListByStatus();
for (MoldRepairDO moldRepairDO : moldRepairDOList) {
TodoRespVO todoRespVO = new TodoRespVO();
// 6. 组装模具维修待办
for (MoldRepairDO moldRepairDO : moldRepairDOList) {
TodoRespVO todoRespVO = new TodoRespVO();
todoRespVO.setCode(moldRepairDO.getRepairCode());
todoRespVO.setName(moldRepairDO.getRepairName());
todoRespVO.setType("模具维修");
todoRespVO.setDeviceName( moldRepairDO.getMoldId() != null && moldService.getMold(moldRepairDO.getMoldId()) != null
? moldService.getMold(moldRepairDO.getMoldId()).getName()
: "未知设备");
todoRespVO.setDeviceName(moldNameMap.getOrDefault(moldRepairDO.getMoldId(), "未知设备"));
todoRespVO.setCreateTime(moldRepairDO.getCreateTime());
todoRespVOList.add(todoRespVO);
}
// 模具保养 点检
List<MoldTicketManagementDO> moldTicketManagementDOList = moldTicketManagementService.getListByJobStatus();
for (MoldTicketManagementDO moldTicketManagementDO : moldTicketManagementDOList) {
TodoRespVO todoRespVO = new TodoRespVO();
// 7. 组装模具保养 / 点检待办
for (MoldTicketManagementDO moldTicketManagementDO : moldTicketManagementDOList) {
TodoRespVO todoRespVO = new TodoRespVO();
todoRespVO.setCode(moldTicketManagementDO.getPlanNo());
todoRespVO.setName(moldTicketManagementDO.getConfigName());
if (moldTicketManagementDO.getPlanType() == 2) {
todoRespVO.setType("模具保养");
} else {
todoRespVO.setType("模具点检");
}
todoRespVO.setType(moldTicketManagementDO.getPlanType() == 2 ? "模具保养" : "模具点检");
todoRespVO.setDeviceName(moldTicketManagementDO.getMoldName());
todoRespVO.setCreateTime(moldTicketManagementDO.getCreateTime());
todoRespVOList.add(todoRespVO);
}
return success(todoRespVOList);
// 8. 按创建时间倒序排序,最近的待办排前面
todoRespVOList.sort(Comparator.comparing(
TodoRespVO::getCreateTime,
Comparator.nullsLast(Comparator.reverseOrder())
));
return success(todoRespVOList);
}
@GetMapping("/getDeviceRepairLineOptions")

@ -100,10 +100,10 @@ public class DeviceLedgerController {
@GetMapping("/get")
@Operation(summary = "获得设备台账")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('mes:device-ledger:query')")
public CommonResult<DeviceLedgerRespVO> getDeviceLedger(@RequestParam("id") Long id) {
DeviceLedgerDO deviceLedger = deviceLedgerService.getDeviceLedger(id);
public CommonResult<DeviceLedgerRespVO> getDeviceLedger(@RequestParam(value = "id", required = false) Long id,
@RequestParam(value = "code", required = false) String code) {
DeviceLedgerDO deviceLedger = deviceLedgerService.getDeviceLedger(id, code);
DeviceLedgerRespVO respVO = BeanUtils.toBean(deviceLedger, DeviceLedgerRespVO.class);
String qrcodeUrl = qrcodeService.selectQrcodeUrlByIdAndCode(QrcodeBizTypeEnum.EQUIPMENT.getCode(),id,respVO.getDeviceCode());
@ -279,4 +279,4 @@ public class DeviceLedgerController {
}
}

@ -8,19 +8,19 @@ import lombok.Getter;
@AllArgsConstructor
public enum CapacityTypeEnum {
RATED(1, "额定产能") {
RATED(1, "计划产能") {
@Override
public Integer getCapacity(DeviceLedgerDO device) {
return device.getRatedCapacity();
}
},
DAILY_AVERAGE(2, "每日报工平均值") {
DAILY_AVERAGE(2, "报工产能") {
@Override
public Integer getCapacity(DeviceLedgerDO device) {
return device.getDailyAverageValue();
}
},
DATA_COLLECTION(3, "数据采集产能") {
DATA_COLLECTION(3, "实际产能") {
@Override
public Integer getCapacity(DeviceLedgerDO device) {
return device.getDataCollectionCapacity();

@ -174,12 +174,13 @@ public class DvRepairController {
@GetMapping("/getRepairListByDeviceId")
@Operation(summary = "根据设备Id获得维修历史记录")
@Parameter(name = "deviceId", description = "设备Id", required = true, example = "1024")
@Parameter(name = "deviceId", description = "设备Id", required = false, example = "1024")
@PreAuthorize("@ss.hasPermission('mes:ticket-management:query')")
public CommonResult<List<DvRepairLineRespVO>> getRepairListByDeviceId(@RequestParam("deviceId") Long deviceId,
public CommonResult<List<DvRepairLineRespVO>> getRepairListByDeviceId(@RequestParam(value = "deviceId", required = false) Long deviceId,
@RequestParam(value = "code", required = false) String code,
@RequestParam(name = "startTime",required = false) String startTime,
@RequestParam(name = "endTime",required = false) String endTime) {
List<DvRepairLineRespVO> dvRepairDOList = dvRepairService.getRepairListByDeviceId(deviceId,startTime,endTime,null);
List<DvRepairLineRespVO> dvRepairDOList = dvRepairService.getRepairListByDeviceId(deviceId, code, startTime, endTime, null);
return success(dvRepairDOList);
}
@ -196,7 +197,7 @@ public class DvRepairController {
HttpServletResponse response) throws IOException {
// 查询数据
List<DvRepairLineRespVO> dvRepairDOList = dvRepairService.getRepairListByDeviceId(deviceId,startTime,endTime,ids);
List<DvRepairLineRespVO> dvRepairDOList = dvRepairService.getRepairListByDeviceId(deviceId, null, startTime, endTime, ids);
// 设置响应头
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
@ -227,4 +228,4 @@ public class DvRepairController {
return dvSubjectRespVOPageResult;
}
}
}

@ -167,12 +167,13 @@ public class MoldRepairController {
@GetMapping("/getRepairListByMoldId")
@Operation(summary = "根据模具Id获得维修历史记录")
@Parameter(name = "moldId", description = "模具Id", required = true, example = "1024")
@Parameter(name = "moldId", description = "模具Id", required = false, example = "1024")
@PreAuthorize("@ss.hasPermission('mes:mold_ticket-management:query')")
public CommonResult<List<MoldRepairLineRespVO>> getRepairListByMoldId(@RequestParam("moldId") Long moldId,
public CommonResult<List<MoldRepairLineRespVO>> getRepairListByMoldId(@RequestParam(value = "moldId", required = false) Long moldId,
@RequestParam(value = "code", required = false) String code,
@RequestParam(name = "startTime",required = false) String startTime,
@RequestParam(name = "endTime",required = false) String endTime) {
List<MoldRepairLineRespVO> moldRepairDOList = moldRepairService.getRepairListByMoldId(moldId,startTime,endTime,null);
List<MoldRepairLineRespVO> moldRepairDOList = moldRepairService.getRepairListByMoldId(moldId, code, startTime, endTime, null);
return success(moldRepairDOList);
}
@ -189,7 +190,7 @@ public class MoldRepairController {
HttpServletResponse response) throws IOException {
// 查询数据
List<MoldRepairLineRespVO> moldRepairDOList = moldRepairService.getRepairListByMoldId(moldId,startTime,endTime,ids);
List<MoldRepairLineRespVO> moldRepairDOList = moldRepairService.getRepairListByMoldId(moldId, null, startTime, endTime, ids);
// 设置响应头
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
@ -221,4 +222,4 @@ public class MoldRepairController {
return moldSubjectRespVOPageResult;
}
}
}

@ -140,12 +140,13 @@ public class MoldTicketManagementController {
@GetMapping("/getInspectionByMoldId")
@Operation(summary = "根据模具Id获得点检历史记录")
@Parameter(name = "moldId", description = "模具Id", required = true, example = "1024")
@Parameter(name = "moldId", description = "模具Id", required = false, example = "1024")
@PreAuthorize("@ss.hasPermission('mes:mold-ticket-management:query')")
public CommonResult< List<MoldTicketResultsDO>> getInspectionByMoldId(@RequestParam("moldId") Long moldId,
public CommonResult< List<MoldTicketResultsDO>> getInspectionByMoldId(@RequestParam(value = "moldId", required = false) Long moldId,
@RequestParam(value = "code", required = false) String code,
@RequestParam(name = "startTime",required = false) String startTime,
@RequestParam(name = "endTime",required = false) String endTime) {
List<MoldTicketResultsDO> moldTicketResultsDOList = moldticketManagementService.getInspectionByMoldId(moldId,startTime,endTime,"");
List<MoldTicketResultsDO> moldTicketResultsDOList = moldticketManagementService.getInspectionByMoldId(moldId, code, startTime, endTime, "");
return success(moldTicketResultsDOList);
}
@ -160,7 +161,7 @@ public class MoldTicketManagementController {
HttpServletResponse response) throws IOException {
// 查询数据
List<MoldTicketResultsDO> results = moldticketManagementService.getInspectionByMoldId(moldId, startTime, endTime, ids);
List<MoldTicketResultsDO> results = moldticketManagementService.getInspectionByMoldId(moldId, null, startTime, endTime, ids);
// 转换为VO并处理数据
List<MoldTicketInspectionExportVO> exportVos = results.stream()
@ -179,12 +180,13 @@ public class MoldTicketManagementController {
@GetMapping("/getMaintenanceByMoldId")
@Operation(summary = "根据模具Id获得保养历史记录")
@Parameter(name = "moldId", description = "模具Id", required = true, example = "1024")
@Parameter(name = "moldId", description = "模具Id", required = false, example = "1024")
@PreAuthorize("@ss.hasPermission('mes:mold_ticket-management:query')")
public CommonResult<List<MoldTicketResultsDO>> getMaintenanceByMoldId(@RequestParam("moldId") Long moldId,
public CommonResult<List<MoldTicketResultsDO>> getMaintenanceByMoldId(@RequestParam(value = "moldId", required = false) Long moldId,
@RequestParam(value = "code", required = false) String code,
@RequestParam(name = "startTime",required = false) String startTime,
@RequestParam(name = "endTime",required = false) String endTime) {
List<MoldTicketResultsDO> moldticketResultsDOList = moldticketManagementService.getMaintenanceByMoldId(moldId,startTime,endTime,"");
List<MoldTicketResultsDO> moldticketResultsDOList = moldticketManagementService.getMaintenanceByMoldId(moldId, code, startTime, endTime, "");
return success(moldticketResultsDOList);
}
@ -200,7 +202,7 @@ public class MoldTicketManagementController {
HttpServletResponse response) throws IOException {
// 查询数据
List<MoldTicketResultsDO> results = moldticketManagementService.getMaintenanceByMoldId(moldId, startTime, endTime, ids);
List<MoldTicketResultsDO> results = moldticketManagementService.getMaintenanceByMoldId(moldId, null, startTime, endTime, ids);
// 转换为VO并处理数据
List<MoldTicketInspectionExportVO> exportVos = results.stream()
@ -276,4 +278,4 @@ public class MoldTicketManagementController {
return vo;
}
}
}

@ -0,0 +1,30 @@
package cn.iocoder.yudao.module.mes.controller.admin.task.vo;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.deviceledger.DeviceLedgerDO;
import lombok.Data;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Data
public class CapacityContext {
private List<LocalDate> statDays = new ArrayList<>();
private Integer statDayCount = 0;
private Map<Long, Integer> productDailyAverageMap = new HashMap<>();
private Map<Long, Integer> deviceCollectionAverageMap = new HashMap<>();
private Map<Long, ErpProductDO> productCache = new HashMap<>();
private Map<Long, DeviceDO> deviceCache = new HashMap<>();
public Integer getProductDailyAverageCapacity(Long productId) {
return productDailyAverageMap.get(productId);
}
public Integer getDeviceCollectionAverageCapacity(Long deviceId) {
return deviceCollectionAverageMap.get(deviceId);
}
}

@ -29,7 +29,7 @@ public class TaskOneClickScheduleReqVO {
@NotNull(message = "排序规则不能为空")
private Integer sortRule;
@Schema(description = "产能来源1-额定产能 2-每日报工平均值 3-数据采集产能", requiredMode = Schema.RequiredMode.REQUIRED)
@Schema(description = "产能来源1-计划产能 2-报工产能 3-实际产能", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "产能来源不能为空")
private Integer capacityType;

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.mes.controller.admin.task.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.List;
@ -16,9 +17,12 @@ public class TaskOneClickScheduleRespVO {
@Schema(description = "设备名称")
private String deviceName;
@Schema(description = "设备额定产能")
@Schema(description = "产能")
private Integer ratedCapacity;
@Schema(description = "产能来源1-计划产能 2-报工产能 3-实际产能")
private Integer capacityType;
@Schema(description = "该设备排产计划")
private List<PlanRespItem> plans;
@ -44,6 +48,12 @@ public class TaskOneClickScheduleRespVO {
@Schema(description = "计划数量", example = "1200")
private Long planNumber;
@Schema(description = "产能")
private Integer ratedCapacity;
@Schema(description = "产能来源1-计划产能 2-报工产能 3-实际产能")
private Integer capacityType;
// @Schema(description = "计划开始时间")
// private LocalDateTime planStartTime;
//

@ -22,11 +22,11 @@ public class TaskPageReqVO extends PageParam {
private String code;
@Schema(description = "下达日期")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] orderDate;
@Schema(description = "交货日期")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] deliveryDate;
@Schema(description = "状态", example = "2")

@ -160,12 +160,13 @@ public class TicketManagementController {
@GetMapping("/getInspectionByDeviceId")
@Operation(summary = "根据设备Id获得点检历史记录")
@Parameter(name = "deviceId", description = "设备Id", required = true, example = "1024")
@Parameter(name = "deviceId", description = "设备Id", required = false, example = "1024")
@PreAuthorize("@ss.hasPermission('mes:ticket-management:query')")
public CommonResult< List<TicketResultsDO>> getInspectionByDeviceId(@RequestParam("deviceId") Long deviceId,
public CommonResult< List<TicketResultsDO>> getInspectionByDeviceId(@RequestParam(value = "deviceId", required = false) Long deviceId,
@RequestParam(value = "code", required = false) String code,
@RequestParam(name = "startTime",required = false) String startTime,
@RequestParam(name = "endTime",required = false) String endTime) {
List<TicketResultsDO> ticketResultsDOList = ticketManagementService.getInspectionByDeviceId(deviceId,startTime,endTime,"");
List<TicketResultsDO> ticketResultsDOList = ticketManagementService.getInspectionByDeviceId(deviceId, code, startTime, endTime, "");
return success(ticketResultsDOList);
}
@ -180,7 +181,7 @@ public class TicketManagementController {
HttpServletResponse response) throws IOException {
// 查询数据
List<TicketResultsDO> results = ticketManagementService.getInspectionByDeviceId(deviceId, startTime, endTime, ids);
List<TicketResultsDO> results = ticketManagementService.getInspectionByDeviceId(deviceId, null, startTime, endTime, ids);
// 转换为VO并处理数据
List<TicketInspectionExportVO> exportVos = results.stream()
@ -202,12 +203,13 @@ public class TicketManagementController {
@GetMapping("/getMaintenanceByDeviceId")
@Operation(summary = "根据设备Id获得保养历史记录")
@Parameter(name = "deviceId", description = "设备Id", required = true, example = "1024")
@Parameter(name = "deviceId", description = "设备Id", required = false, example = "1024")
@PreAuthorize("@ss.hasPermission('mes:ticket-management:query')")
public CommonResult<List<TicketResultsDO>> getMaintenanceByDeviceId(@RequestParam("deviceId") Long deviceId,
public CommonResult<List<TicketResultsDO>> getMaintenanceByDeviceId(@RequestParam(value = "deviceId", required = false) Long deviceId,
@RequestParam(value = "code", required = false) String code,
@RequestParam(name = "startTime",required = false) String startTime,
@RequestParam(name = "endTime",required = false) String endTime) {
List<TicketResultsDO> ticketResultsDOList = ticketManagementService.getMaintenanceByDeviceId(deviceId,startTime,endTime,"");
List<TicketResultsDO> ticketResultsDOList = ticketManagementService.getMaintenanceByDeviceId(deviceId, code, startTime, endTime, "");
return success(ticketResultsDOList);
}
@ -223,7 +225,7 @@ public class TicketManagementController {
HttpServletResponse response) throws IOException {
// 查询数据
List<TicketResultsDO> results = ticketManagementService.getMaintenanceByDeviceId(deviceId, startTime, endTime, ids);
List<TicketResultsDO> results = ticketManagementService.getMaintenanceByDeviceId(deviceId, null, startTime, endTime, ids);
// 转换为VO并处理数据
List<TicketInspectionExportVO> exportVos = results.stream()
@ -299,4 +301,4 @@ public class TicketManagementController {
return vo;
}
}
}

@ -11,6 +11,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.mes.controller.admin.baogongrecord.vo.*;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
/**
* Mapper
@ -43,4 +44,8 @@ public interface BaogongRecordMapper extends BaseMapperX<BaogongRecordDO> {
List<BaogongRecordTrendDayRespVO> selectTrendByHour(@Param("reqVO") BaogongRecordTrendReqVO reqVO);
List<Map<String, Object>> selectProductDailyReportTotals(@Param("productIds") Collection<Long> productIds,
@Param("beginTime") LocalDateTime beginTime,
@Param("endTime") LocalDateTime endTime);
}

@ -45,6 +45,8 @@ public interface CriticalComponentService {
*/
CriticalComponentDO getCriticalComponent(Long id);
CriticalComponentDO getCriticalComponent(Long id, String code);
/**
*
*
@ -63,4 +65,4 @@ public interface CriticalComponentService {
CriticalComponentImportRespVO importCriticalComponentList(List<CriticalComponentImportExcelVO> importComponents, boolean isUpdateSupport);
void regenerateCode(Long id, String code) throws UnsupportedEncodingException;
}
}

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.mes.service.criticalcomponent;
import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldDO;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.common.enums.CodeTypeEnum;
import cn.iocoder.yudao.module.common.enums.QrcodeBizTypeEnum;
import cn.iocoder.yudao.module.common.service.qrcordrecord.QrcodeRecordService;
@ -197,6 +198,7 @@ public class CriticalComponentServiceImpl implements CriticalComponentService {
@Override
public CriticalComponentDO getCriticalComponent(Long id) {
validateCriticalComponentExists(id);
CriticalComponentDO criticalComponentDO = criticalComponentMapper.selectById(id);
String qrcodeUrl = qrcodeService.selectQrcodeUrlByIdAndCode(QrcodeBizTypeEnum.KEY_PART.getCode(),id,criticalComponentDO.getCode());
criticalComponentDO.setQrcodeUrl(qrcodeUrl);
@ -204,6 +206,24 @@ public class CriticalComponentServiceImpl implements CriticalComponentService {
}
@Override
public CriticalComponentDO getCriticalComponent(Long id, String code) {
if (id != null) {
return getCriticalComponent(id);
}
if (StringUtils.isNotBlank(code)) {
CriticalComponentDO criticalComponentDO = criticalComponentMapper.selectOne(new LambdaQueryWrapperX<CriticalComponentDO>()
.like(CriticalComponentDO::getCode, code)
.orderByDesc(CriticalComponentDO::getId)
.last("LIMIT 1"));
if (criticalComponentDO == null) {
throw exception(CRITICAL_COMPONENT_NOT_EXISTS);
}
return getCriticalComponent(criticalComponentDO.getId());
}
throw exception(CRITICAL_COMPONENT_NOT_EXISTS);
}
@Override
public PageResult<CriticalComponentDO> getCriticalComponentPage(CriticalComponentPageReqVO pageReqVO) {
return criticalComponentMapper.selectPage(pageReqVO);
@ -338,4 +358,4 @@ public class CriticalComponentServiceImpl implements CriticalComponentService {
);
}
}
}

@ -47,6 +47,8 @@ public interface DeviceLedgerService {
*/
DeviceLedgerDO getDeviceLedger(Long id);
DeviceLedgerDO getDeviceLedger(Long id, String code);
/**
*
*
@ -83,5 +85,7 @@ public interface DeviceLedgerService {
Map<Long, DeviceLedgerDO> getDeviceMap(Set<Long> longs);
List<DeviceLedgerDO> getDeviceLedgerListByIds(Collection<Long> ids);
}
}

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.mes.service.deviceledger;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.common.enums.CodeTypeEnum;
import cn.iocoder.yudao.module.common.enums.QrcodeBizTypeEnum;
import cn.iocoder.yudao.module.common.service.qrcordrecord.QrcodeRecordService;
@ -207,6 +208,7 @@ public class DeviceLedgerServiceImpl implements DeviceLedgerService {
@Override
public DeviceLedgerDO getDeviceLedger(Long id) {
validateDeviceLedgerExists(id);
DeviceLedgerDO deviceLedgerDO = deviceLedgerMapper.selectById(id);
@ -298,6 +300,24 @@ public class DeviceLedgerServiceImpl implements DeviceLedgerService {
return deviceLedgerDO;
}
@Override
public DeviceLedgerDO getDeviceLedger(Long id, String code) {
if (id != null) {
return getDeviceLedger(id);
}
if (StringUtils.isNotBlank(code)) {
DeviceLedgerDO deviceLedgerDO = deviceLedgerMapper.selectOne(new LambdaQueryWrapperX<DeviceLedgerDO>()
.like(DeviceLedgerDO::getDeviceCode, code)
.orderByDesc(DeviceLedgerDO::getId)
.last("LIMIT 1"));
if (deviceLedgerDO == null) {
throw exception(DEVICE_LEDGER_NOT_EXISTS);
}
return getDeviceLedger(deviceLedgerDO.getId());
}
throw exception(DEVICE_LEDGER_NOT_EXISTS);
}
@Override
public PageResult<DeviceLedgerDO> getDeviceLedgerPage(DeviceLedgerPageReqVO pageReqVO) {
@ -431,4 +451,11 @@ public class DeviceLedgerServiceImpl implements DeviceLedgerService {
return deviceLedgerMapper.selectListByIds(ids).stream()
.collect(Collectors.toMap(DeviceLedgerDO::getId, Function.identity(), (a, b) -> a));
}
}
@Override
public List<DeviceLedgerDO> getDeviceLedgerListByIds(Collection<Long> ids) {
if (ids == null || ids.isEmpty()) {
return Collections.emptyList();
}
return deviceLedgerMapper.selectBatchIds(ids); }
}

@ -71,7 +71,7 @@ public interface DvRepairService {
void updateDvRepairStatus(@Valid DvRepirUpdateReqVO updateReqVO);
List<DvRepairLineRespVO> getRepairListByDeviceId(Long deviceId, String startTime, String endTime,String ids);
List<DvRepairLineRespVO> getRepairListByDeviceId(Long deviceId, String code, String startTime, String endTime, String ids);
Long getRepairListCountByRepairStatus();
@ -82,4 +82,4 @@ public interface DvRepairService {
List<DvRepairDO> getList();
List<DvRepairDO> getLatestList();
}
}

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.mes.service.dvrepair;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.erp.controller.admin.autocode.util.AutoCodeUtil;
import cn.iocoder.yudao.module.mes.controller.admin.dashboard.vo.dashboard.EventStatisticsVO;
@ -8,8 +9,10 @@ import cn.iocoder.yudao.module.mes.controller.admin.dvrepair.enums.RepairResultE
import cn.iocoder.yudao.module.mes.controller.admin.dvrepair.enums.RepairStatusEnum;
import cn.iocoder.yudao.module.mes.controller.admin.dvrepair.vo.*;
import cn.iocoder.yudao.module.mes.controller.admin.ticketresults.enums.JobResultEnum;
import cn.iocoder.yudao.module.mes.dal.dataobject.deviceledger.DeviceLedgerDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.dvrepair.DvRepairDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.dvrepair.DvRepairLineDO;
import cn.iocoder.yudao.module.mes.dal.mysql.deviceledger.DeviceLedgerMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.dvrepair.DvRepairLineMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.dvrepair.DvRepairMapper;
import com.alibaba.excel.util.StringUtils;
@ -44,6 +47,8 @@ public class DvRepairServiceImpl implements DvRepairService {
@Resource
private DvRepairMapper dvRepairMapper;
@Resource
private DeviceLedgerMapper deviceLedgerMapper;
@Resource
private DvRepairLineMapper dvRepairLineMapper;
@Resource
@ -196,12 +201,13 @@ public class DvRepairServiceImpl implements DvRepairService {
}
@Override
public List<DvRepairLineRespVO> getRepairListByDeviceId(Long deviceId, String startTime, String endTime,String ids) {
public List<DvRepairLineRespVO> getRepairListByDeviceId(Long deviceId, String code, String startTime, String endTime, String ids) {
DeviceLedgerDO deviceLedgerDO = getDeviceByIdOrCode(deviceId, code);
List<DvRepairLineRespVO> dvRepairLineRespVOS = new ArrayList<>();
LambdaQueryWrapper<DvRepairDO> wrapper = Wrappers.<DvRepairDO>lambdaQuery()
.eq(DvRepairDO::getDeviceId, deviceId);
.eq(DvRepairDO::getDeviceId, deviceLedgerDO.getId());
@ -270,6 +276,22 @@ public class DvRepairServiceImpl implements DvRepairService {
return dvRepairLineRespVOS;
}
private DeviceLedgerDO getDeviceByIdOrCode(Long deviceId, String code) {
DeviceLedgerDO deviceLedgerDO = null;
if (deviceId != null) {
deviceLedgerDO = deviceLedgerMapper.selectById(deviceId);
} else if (StringUtils.isNotBlank(code)) {
deviceLedgerDO = deviceLedgerMapper.selectOne(new LambdaQueryWrapperX<DeviceLedgerDO>()
.like(DeviceLedgerDO::getDeviceCode, code)
.orderByDesc(DeviceLedgerDO::getId)
.last("LIMIT 1"));
}
if (deviceLedgerDO == null) {
throw exception(TICKET_MANAGEMENT_NOT_EXISTS);
}
return deviceLedgerDO;
}
@Override
public Long getRepairListCountByRepairStatus() {
return dvRepairMapper.selectCount(Wrappers.<DvRepairDO>lambdaQuery()
@ -419,4 +441,4 @@ public class DvRepairServiceImpl implements DvRepairService {
dvRepairLineMapper.deleteByRepairId(repairId);
}
}
}

@ -74,7 +74,7 @@ public interface MoldRepairService {
void updateMoldRepairStatus(@Valid MoldRepairUpdateReqVO updateReqVO);
List<MoldRepairLineRespVO> getRepairListByMoldId(Long moldId, String startTime, String endTime, String ids);
List<MoldRepairLineRespVO> getRepairListByMoldId(Long moldId, String code, String startTime, String endTime, String ids);
Long getRepairListCountByRepairStatus();

@ -1,7 +1,9 @@
package cn.iocoder.yudao.module.mes.service.moldrepair;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldDO;
import cn.iocoder.yudao.module.erp.controller.admin.autocode.util.AutoCodeUtil;
import cn.iocoder.yudao.module.mes.controller.admin.dashboard.vo.dashboard.EventStatisticsVO;
import cn.iocoder.yudao.module.common.controller.admin.moldrepair.enums.RepairResultEnum;
@ -15,6 +17,7 @@ import cn.iocoder.yudao.module.common.dal.dataobject.moldrepair.MoldRepairDO;
import cn.iocoder.yudao.module.common.dal.dataobject.moldrepair.MoldRepairLineDO;
import cn.iocoder.yudao.module.common.dal.mysql.moldrepair.MoldRepairLineMapper;
import cn.iocoder.yudao.module.common.dal.mysql.moldrepair.MoldRepairMapper;
import cn.iocoder.yudao.module.common.dal.mysql.mold.MoldMapper;
import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@ -32,6 +35,7 @@ import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.MOLD_NOT_EXISTS;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
import org.springframework.util.CollectionUtils;
@ -51,6 +55,8 @@ public class MoldRepairServiceImpl implements MoldRepairService {
@Resource
private MoldRepairMapper moldRepairMapper;
@Resource
private MoldMapper moldMapper;
@Resource
private MoldRepairLineMapper moldRepairLineMapper;
@Resource
@ -250,12 +256,13 @@ public class MoldRepairServiceImpl implements MoldRepairService {
}
@Override
public List<MoldRepairLineRespVO> getRepairListByMoldId(Long moldId, String startTime, String endTime, String ids) {
public List<MoldRepairLineRespVO> getRepairListByMoldId(Long moldId, String code, String startTime, String endTime, String ids) {
MoldDO moldDO = getMoldByIdOrCode(moldId, code);
List<MoldRepairLineRespVO> moldRepairLineRespVOS = new ArrayList<>();
LambdaQueryWrapper<MoldRepairDO> wrapper = Wrappers.<MoldRepairDO>lambdaQuery()
.eq(MoldRepairDO::getMoldId, moldId);
.eq(MoldRepairDO::getMoldId, moldDO.getId());
@ -324,6 +331,22 @@ public class MoldRepairServiceImpl implements MoldRepairService {
return moldRepairLineRespVOS;
}
private MoldDO getMoldByIdOrCode(Long moldId, String code) {
MoldDO moldDO = null;
if (moldId != null) {
moldDO = moldMapper.selectById(moldId);
} else if (StringUtils.isNotBlank(code)) {
moldDO = moldMapper.selectOne(new LambdaQueryWrapperX<MoldDO>()
.like(MoldDO::getCode, code)
.orderByDesc(MoldDO::getId)
.last("LIMIT 1"));
}
if (moldDO == null) {
throw exception(MOLD_NOT_EXISTS);
}
return moldDO;
}
private LocalDateTime parseToLocalDateTime(String timeStr) {
if (StringUtils.isBlank(timeStr)) {
@ -455,4 +478,4 @@ public class MoldRepairServiceImpl implements MoldRepairService {
.last("LIMIT 100")
);
}
}
}

@ -58,9 +58,9 @@ public interface MoldTicketManagementService {
void batchUpdateJobStatus(@Valid MoldTicketManagementBatchUpdateReqVO reqVO);
List<MoldTicketResultsDO> getInspectionByMoldId(Long id, String startTime, String endTime, String ids);
List<MoldTicketResultsDO> getInspectionByMoldId(Long id, String code, String startTime, String endTime, String ids);
List<MoldTicketResultsDO> getMaintenanceByMoldId(Long id, String startTime, String endTime, String ids);
List<MoldTicketResultsDO> getMaintenanceByMoldId(Long id, String code, String startTime, String endTime, String ids);
Long getBaoyangListCountByJobStatus();
@ -75,4 +75,4 @@ public interface MoldTicketManagementService {
List<MoldTicketManagementDO> getList();
List<MoldTicketManagementDO> getLatestList();
}
}

@ -9,6 +9,7 @@ import cn.iocoder.yudao.module.common.dal.dataobject.moldticketresults.MoldTicke
import cn.iocoder.yudao.module.common.dal.mysql.moldticketresults.MoldTicketResultsMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.deviceledger.DeviceLedgerMapper;
import com.alibaba.excel.util.StringUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@ -30,6 +31,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.common.dal.mysql.moldticketmanagement.MoldTicketManagementMapper;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.MOLD_NOT_EXISTS;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
/**
@ -107,10 +109,10 @@ public class MoldTicketManagementServiceImpl implements MoldTicketManagementServ
@Override
public List<MoldTicketResultsDO> getInspectionByMoldId(Long id, String startTime, String endTime, String ids) {
MoldDO moldDO = moldMapper.selectById(id);
public List<MoldTicketResultsDO> getInspectionByMoldId(Long id, String code, String startTime, String endTime, String ids) {
MoldDO moldDO = getMoldByIdOrCode(id, code);
//点检列表
List<MoldTicketResultsDO> inspectionList = moldTicketResultsMapper.findByMoldIdAndPlanType(id, MoldPlanTypeEnum.INSPECTION.getCode(),startTime,endTime,ids);
List<MoldTicketResultsDO> inspectionList = moldTicketResultsMapper.findByMoldIdAndPlanType(moldDO.getId(), MoldPlanTypeEnum.INSPECTION.getCode(),startTime,endTime,ids);
if(CollectionUtils.isNotEmpty(inspectionList)){
moldDO.setInspectionList(inspectionList);
}
@ -119,11 +121,11 @@ public class MoldTicketManagementServiceImpl implements MoldTicketManagementServ
}
@Override
public List<MoldTicketResultsDO> getMaintenanceByMoldId(Long id,String startTime,String endTime,String ids) {
MoldDO moldDO = moldMapper.selectById(id);
public List<MoldTicketResultsDO> getMaintenanceByMoldId(Long id, String code, String startTime, String endTime, String ids) {
MoldDO moldDO = getMoldByIdOrCode(id, code);
//保养列表
List<MoldTicketResultsDO> inspectionList = moldTicketResultsMapper.findByMoldIdAndPlanType(id, MoldPlanTypeEnum.MAINTENANCE.getCode(),startTime,endTime,ids);
List<MoldTicketResultsDO> inspectionList = moldTicketResultsMapper.findByMoldIdAndPlanType(moldDO.getId(), MoldPlanTypeEnum.MAINTENANCE.getCode(),startTime,endTime,ids);
if(CollectionUtils.isNotEmpty(inspectionList)){
moldDO.setInspectionList(inspectionList);
}
@ -131,6 +133,22 @@ public class MoldTicketManagementServiceImpl implements MoldTicketManagementServ
return inspectionList;
}
private MoldDO getMoldByIdOrCode(Long id, String code) {
MoldDO moldDO = null;
if (id != null) {
moldDO = moldMapper.selectById(id);
} else if (StringUtils.isNotBlank(code)) {
moldDO = moldMapper.selectOne(new LambdaQueryWrapperX<MoldDO>()
.like(MoldDO::getCode, code)
.orderByDesc(MoldDO::getId)
.last("LIMIT 1"));
}
if (moldDO == null) {
throw exception(MOLD_NOT_EXISTS);
}
return moldDO;
}
/**
* ID
*/
@ -200,4 +218,4 @@ public class MoldTicketManagementServiceImpl implements MoldTicketManagementServ
);
}
}
}

@ -1,7 +1,6 @@
package cn.iocoder.yudao.module.mes.service.task;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
@ -15,24 +14,29 @@ import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.productdevicerel.ProductDeviceRelMapper;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
import cn.iocoder.yudao.module.erp.service.product.ErpProductUnitService;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO;
import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceMapper;
import cn.iocoder.yudao.module.mes.controller.admin.deviceledger.enums.CapacityTypeEnum;
import cn.iocoder.yudao.module.mes.controller.admin.plan.vo.PlanSaveReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.plan.vo.PlanStatusEnum;
import cn.iocoder.yudao.module.mes.controller.admin.task.vo.*;
import cn.iocoder.yudao.module.mes.dal.dataobject.calholiday.CalHolidayDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.deviceledger.DeviceLedgerDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.organization.OrganizationDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.plan.PlanDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.task.TaskDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.task.TaskDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.task.ViewTaskProductSummary;
import cn.iocoder.yudao.module.mes.dal.mysql.baogongrecord.BaogongRecordMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.calholiday.CalHolidayMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.deviceledger.DeviceLedgerMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.organization.OrganizationMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.plan.PlanMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.task.TaskDetailMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.task.TaskMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.task.ViewTaskProductSummaryMapper;
import cn.iocoder.yudao.module.mes.dal.redis.no.MesNoRedisDAO;
import cn.iocoder.yudao.module.mes.enums.BaogongTrendTypeEnum;
import cn.iocoder.yudao.module.iot.service.device.TDengineService;
import cn.iocoder.yudao.module.mes.service.deviceledger.DeviceLedgerService;
import cn.iocoder.yudao.module.mes.strategy.task.ScheduleSortStrategyFactory;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@ -84,6 +88,13 @@ public class TaskServiceImpl implements TaskService {
@Resource
private DeviceLedgerMapper deviceLedgerMapper;
@Resource
private OrganizationMapper organizationMapper;
@Resource
@Lazy
private DeviceMapper deviceMapper;
@Resource
private ProductDeviceRelMapper productDeviceRelMapper;
@ -93,6 +104,13 @@ public class TaskServiceImpl implements TaskService {
@Resource
private CalHolidayMapper calHolidayMapper;
@Resource
private BaogongRecordMapper baogongRecordMapper;
@Resource
private TDengineService tdengineService;
@Resource
private AutoCodeUtil autoCodeUtil;
@Resource
@ -450,7 +468,6 @@ public class TaskServiceImpl implements TaskService {
}
@Override
@Transactional(rollbackFor = Exception.class)
public List<TaskOneClickScheduleRespVO> oneClickSchedule(TaskOneClickScheduleReqVO reqVO) {
if (reqVO == null || CollUtil.isEmpty(reqVO.getCreateReqVO())) {
return Collections.emptyList();
@ -515,6 +532,8 @@ public class TaskServiceImpl implements TaskService {
throw exception(UNSUPPORTED_CAPACITY_TYPE, reqVO.getCapacityType());
}
CapacityContext capacityContext = buildCapacityContext(sortedPlans, skipHoliday, capacityType);
DateTimeFormatter DATETIME_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
DateTimeFormatter DATE_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
@ -538,7 +557,7 @@ public class TaskServiceImpl implements TaskService {
List<DeviceCandidate> candidates = new ArrayList<>();
for (ProductRelationRespVO rel : deviceRels) {
DeviceLedgerDO device = deviceLedgerMapper.selectById(rel.getId());
Integer dailyCapacity = capacityType.getCapacity(device); // 每日产能
Integer dailyCapacity = resolveCapacityValue(capacityType, device, item.getProductId(), rel.getId(), item.getPlanNumber(), capacityContext);
if (dailyCapacity == null || dailyCapacity <= 0) {
continue;
}
@ -554,7 +573,8 @@ public class TaskServiceImpl implements TaskService {
c.setDeviceName(rel.getName());
c.setCapacityValue(dailyCapacity);
c.setNextAvailableTime(nextAvailable);
candidates.add(c); }
candidates.add(c);
}
if (CollUtil.isEmpty(candidates)) {
throw exception(SCHEDULE_PRODUCT_DEVICE_UNAVAILABLE, item.getProductId());
@ -592,6 +612,7 @@ public class TaskServiceImpl implements TaskService {
vo.setDeviceId(chosen.getDeviceId());
vo.setDeviceName(chosen.getDeviceName());
vo.setRatedCapacity(chosen.getCapacityValue());
vo.setCapacityType(reqVO.getCapacityType());
vo.setPlans(new ArrayList<>());
return vo;
});
@ -605,6 +626,8 @@ public class TaskServiceImpl implements TaskService {
p.setTaskDetailId(item.getTaskDetailId());
p.setPlanNumber(item.getPlanNumber());
p.setSourceType("CURRENT");
p.setRatedCapacity(chosen.getCapacityValue());
p.setCapacityType(reqVO.getCapacityType());
p.setTaskCode(taskDO == null ? null : taskDO.getCode());
p.setProductCode(productDO == null ? null : productDO.getBarCode());
p.setProductName(productDO == null ? null : productDO.getName());
@ -633,7 +656,8 @@ public class TaskServiceImpl implements TaskService {
TaskOneClickScheduleRespVO vo = new TaskOneClickScheduleRespVO();
vo.setDeviceId(deviceId);
vo.setDeviceName(device == null ? null : device.getDeviceName());
vo.setRatedCapacity(capacityType.getCapacity(device)); // device为空时注意判空
// vo.setRatedCapacity(resolveCapacityValue(capacityType, device, null, deviceId, capacityContext));
// vo.setCapacityType(reqVO.getCapacityType());
vo.setPlans(new ArrayList<>());
return vo;
});
@ -854,6 +878,205 @@ public class TaskServiceImpl implements TaskService {
return d;
}
private Integer resolveCapacityValue(CapacityTypeEnum capacityType, DeviceLedgerDO device,
Long productId, Long deviceId, Long planNumber, CapacityContext capacityContext) {
if (capacityType == CapacityTypeEnum.RATED) {
return device == null ? null : capacityType.getCapacity(device);
}
if (capacityContext == null) {
return null;
}
if (capacityType == CapacityTypeEnum.DAILY_AVERAGE) {
if (productId == null) {
return null;
}
Integer value = capacityContext.getProductDailyAverageCapacity(productId);
if (value == null || value <= 0) {
ErpProductDO product = capacityContext.getProductCache().get(productId);
throw exception(SCHEDULE_PRODUCT_DAILY_AVERAGE_ZERO, productId,
product == null ? null : product.getBarCode(),
product == null ? null : product.getName());
}
return value;
}
if (capacityType == CapacityTypeEnum.DATA_COLLECTION) {
if (deviceId == null) {
return null;
}
DeviceLedgerDO ledger = device != null ? device : deviceLedgerMapper.selectById(deviceId);
String deviceName = ledger == null ? null : ledger.getDeviceName();
Long collectDeviceId = resolveCollectDeviceId(deviceId, deviceName, productId, planNumber);
Integer value = capacityContext.getDeviceCollectionAverageCapacity(collectDeviceId);
if (value == null || value <= 0) {
DeviceDO deviceInfo = queryCollectDeviceWithDeleted(collectDeviceId);
ErpProductDO product = productId == null ? null : erpProductMapper.selectById(productId);
throw exception(SCHEDULE_DEVICE_COLLECTION_CAPACITY_ZERO,
product == null ? null : product.getName(),
planNumber,
collectDeviceId,
buildCollectDeviceName(deviceInfo));
}
return value;
}
return device == null ? null : capacityType.getCapacity(device);
}
private Long resolveCollectDeviceId(Long machineId, String deviceName, Long productId, Long planNumber) {
OrganizationDO organization = organizationMapper.selectOne(
new LambdaQueryWrapper<OrganizationDO>()
.eq(OrganizationDO::getMachineId, machineId)
.last("limit 1"));
ErpProductDO product = productId == null ? null : erpProductMapper.selectById(productId);
if (organization == null) {
throw exception(SCHEDULE_DEVICE_ORGANIZATION_NOT_FOUND,
product == null ? null : product.getName(),
planNumber,
machineId,
deviceName);
}
if (organization.getDvId() == null) {
throw exception(SCHEDULE_DEVICE_COLLECTION_MAPPING_MISSING,
product == null ? null : product.getName(),
planNumber,
machineId,
deviceName);
}
return organization.getDvId();
}
private DeviceDO queryCollectDeviceWithDeleted(Long collectDeviceId) {
if (collectDeviceId == null) {
return null;
}
return deviceMapper.selectByIdWithDeleted(collectDeviceId);
}
private String buildCollectDeviceName(DeviceDO deviceInfo) {
if (deviceInfo == null) {
return null;
}
String deviceName = deviceInfo.getDeviceName();
if (Boolean.TRUE.equals(deviceInfo.getDeleted())) {
return StringUtils.defaultString(deviceName) + "(已被删除)";
}
return deviceName;
}
private CapacityContext buildCapacityContext(List<PlanSaveReqVO> sortedPlans, boolean skipHoliday,
CapacityTypeEnum capacityType) {
CapacityContext context = new CapacityContext();
if (CollUtil.isEmpty(sortedPlans)) {
return context;
}
LocalDate endDate = LocalDate.now();
LocalDate startDate = endDate.minusMonths(6).plusDays(1);
List<LocalDate> statDays = listStatDays(startDate, endDate, skipHoliday);
context.setStatDays(statDays);
context.setStatDayCount(statDays.size());
if (CollUtil.isEmpty(statDays)) {
return context;
}
LocalDateTime beginTime = statDays.get(0).atStartOfDay();
LocalDateTime endTime = statDays.get(statDays.size() - 1).plusDays(1).atStartOfDay();
if (capacityType == CapacityTypeEnum.DAILY_AVERAGE) {
Set<Long> productIds = sortedPlans.stream().map(PlanSaveReqVO::getProductId)
.filter(Objects::nonNull).collect(Collectors.toSet());
if (CollUtil.isNotEmpty(productIds)) {
context.setProductCache(productIds.stream().collect(Collectors.toMap(
id -> id,
erpProductMapper::selectById,
(a, b) -> a
)));
}
context.setProductDailyAverageMap(queryProductDailyAverageMap(productIds, statDays, beginTime, endTime));
} else if (capacityType == CapacityTypeEnum.DATA_COLLECTION) {
Set<Long> deviceIds = deviceMapper.selectList(new LambdaQueryWrapper<DeviceDO>()
.select(DeviceDO::getId))
.stream()
.map(DeviceDO::getId)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
if (CollUtil.isNotEmpty(deviceIds)) {
context.setDeviceCache(deviceMapper.selectBatchIds(deviceIds).stream()
.filter(Objects::nonNull)
.collect(Collectors.toMap(
DeviceDO::getId,
device -> device,
(a, b) -> a
)));
}
context.setDeviceCollectionAverageMap(queryDeviceCollectionAverageMap(deviceIds, statDays, beginTime, endTime));
}
return context;
}
private Map<Long, Integer> queryProductDailyAverageMap(Set<Long> productIds, List<LocalDate> statDays,
LocalDateTime beginTime, LocalDateTime endTime) {
Map<Long, Integer> result = new HashMap<>();
if (CollUtil.isEmpty(productIds) || CollUtil.isEmpty(statDays)) {
return result;
}
Set<LocalDate> validDays = new HashSet<>(statDays);
List<Map<String, Object>> rows = baogongRecordMapper.selectProductDailyReportTotals(productIds, beginTime, endTime);
Map<Long, BigDecimal> productTotalMap = new HashMap<>();
for (Map<String, Object> row : rows) {
Long productId = row.get("productId") == null ? null : Long.valueOf(String.valueOf(row.get("productId")));
LocalDate day = row.get("day") == null ? null : LocalDate.parse(String.valueOf(row.get("day")));
if (productId == null || day == null || !validDays.contains(day)) {
continue;
}
BigDecimal totalNum = new BigDecimal(String.valueOf(row.get("totalNum")));
productTotalMap.merge(productId, totalNum, BigDecimal::add);
}
BigDecimal divisor = BigDecimal.valueOf(statDays.size());
for (Long productId : productIds) {
BigDecimal total = productTotalMap.getOrDefault(productId, BigDecimal.ZERO);
result.put(productId, total.divide(divisor, 0, RoundingMode.HALF_UP).intValue());
}
return result;
}
private Map<Long, Integer> queryDeviceCollectionAverageMap(Set<Long> deviceIds, List<LocalDate> statDays,
LocalDateTime beginTime, LocalDateTime endTime) {
Map<Long, Integer> result = new HashMap<>();
if (CollUtil.isEmpty(deviceIds) || CollUtil.isEmpty(statDays)) {
return result;
}
Set<LocalDate> validDays = new HashSet<>(statDays);
Map<Long, Map<LocalDate, Double>> rawMap = tdengineService.queryDailyLatestCapacityValues(deviceIds, beginTime, endTime);
BigDecimal divisor = BigDecimal.valueOf(statDays.size());
for (Long deviceId : deviceIds) {
Map<LocalDate, Double> dayMap = rawMap.getOrDefault(deviceId, Collections.emptyMap());
BigDecimal total = BigDecimal.ZERO;
for (Map.Entry<LocalDate, Double> entry : dayMap.entrySet()) {
if (entry.getKey() == null || entry.getValue() == null || !validDays.contains(entry.getKey())) {
continue;
}
total = total.add(BigDecimal.valueOf(entry.getValue()));
}
result.put(deviceId, total.divide(divisor, 0, RoundingMode.HALF_UP).intValue());
}
return result;
}
private List<LocalDate> listStatDays(LocalDate startDate, LocalDate endDate, boolean skipHoliday) {
List<LocalDate> days = new ArrayList<>();
LocalDate cursor = startDate;
while (!cursor.isAfter(endDate)) {
if (!skipHoliday || isWorkingDay(cursor)) {
days.add(cursor);
}
cursor = cursor.plusDays(1);
}
return days;
}
private Set<Long> queryDeviceIdsFromCurrentMonth() {
LocalDateTime monthStart = LocalDate.now().withDayOfMonth(1).atStartOfDay();
List<PlanDO> plans = planMapper.selectList(new LambdaQueryWrapper<PlanDO>()

@ -59,9 +59,9 @@ public interface TicketManagementService {
void batchUpdateJobStatus(@Valid TicketManagementBatchUpdateReqVO reqVO);
List<TicketResultsDO> getInspectionByDeviceId(Long id,String startTime,String endTime,String ids);
List<TicketResultsDO> getInspectionByDeviceId(Long id, String code, String startTime, String endTime, String ids);
List<TicketResultsDO> getMaintenanceByDeviceId(Long id,String startTime,String endTime,String ids);
List<TicketResultsDO> getMaintenanceByDeviceId(Long id, String code, String startTime, String endTime, String ids);
Long getBaoyangListCountByJobStatus();
@ -76,4 +76,4 @@ public interface TicketManagementService {
List<TicketManagementDO> getList();
List<TicketManagementDO> getLatestList();
}
}

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.mes.service.ticketmanagement;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.mes.controller.admin.dashboard.vo.dashboard.EventStatisticsVO;
import cn.iocoder.yudao.module.mes.controller.admin.ticketmanagement.enums.JobStatusEnum;
import cn.iocoder.yudao.module.mes.controller.admin.ticketmanagement.enums.PlanTypeEnum;
@ -108,10 +109,10 @@ public class TicketManagementServiceImpl implements TicketManagementService {
}
@Override
public List<TicketResultsDO> getInspectionByDeviceId(Long id,String startTime,String endTime,String ids) {
DeviceLedgerDO deviceLedgerDO = deviceLedgerMapper.selectById(id);
public List<TicketResultsDO> getInspectionByDeviceId(Long id, String code, String startTime, String endTime, String ids) {
DeviceLedgerDO deviceLedgerDO = getDeviceByIdOrCode(id, code);
//点检列表
List<TicketResultsDO> inspectionList = ticketResultsMapper.findByDeviceIdAndPlanType(id, PlanTypeEnum.INSPECTION.getCode(),startTime,endTime,ids);
List<TicketResultsDO> inspectionList = ticketResultsMapper.findByDeviceIdAndPlanType(deviceLedgerDO.getId(), PlanTypeEnum.INSPECTION.getCode(),startTime,endTime,ids);
if(CollectionUtils.isNotEmpty(inspectionList)){
deviceLedgerDO.setInspectionList(inspectionList);
}
@ -120,11 +121,11 @@ public class TicketManagementServiceImpl implements TicketManagementService {
}
@Override
public List<TicketResultsDO> getMaintenanceByDeviceId(Long id,String startTime,String endTime,String ids) {
DeviceLedgerDO deviceLedgerDO = deviceLedgerMapper.selectById(id);
public List<TicketResultsDO> getMaintenanceByDeviceId(Long id, String code, String startTime, String endTime, String ids) {
DeviceLedgerDO deviceLedgerDO = getDeviceByIdOrCode(id, code);
//保养列表
List<TicketResultsDO> inspectionList = ticketResultsMapper.findByDeviceIdAndPlanType(id, PlanTypeEnum.MAINTENANCE.getCode(),startTime,endTime,ids);
List<TicketResultsDO> inspectionList = ticketResultsMapper.findByDeviceIdAndPlanType(deviceLedgerDO.getId(), PlanTypeEnum.MAINTENANCE.getCode(),startTime,endTime,ids);
if(CollectionUtils.isNotEmpty(inspectionList)){
deviceLedgerDO.setInspectionList(inspectionList);
}
@ -132,6 +133,22 @@ public class TicketManagementServiceImpl implements TicketManagementService {
return inspectionList;
}
private DeviceLedgerDO getDeviceByIdOrCode(Long id, String code) {
DeviceLedgerDO deviceLedgerDO = null;
if (id != null) {
deviceLedgerDO = deviceLedgerMapper.selectById(id);
} else if (StringUtils.isNotBlank(code)) {
deviceLedgerDO = deviceLedgerMapper.selectOne(new LambdaQueryWrapperX<DeviceLedgerDO>()
.like(DeviceLedgerDO::getDeviceCode, code)
.orderByDesc(DeviceLedgerDO::getId)
.last("LIMIT 1"));
}
if (deviceLedgerDO == null) {
throw exception(DEVICE_LEDGER_NOT_EXISTS);
}
return deviceLedgerDO;
}
@Override
public Long getBaoyangListCountByJobStatus() {
return ticketManagementMapper.selectCount(Wrappers.<TicketManagementDO>lambdaQuery()
@ -204,4 +221,4 @@ public class TicketManagementServiceImpl implements TicketManagementService {
.collect(Collectors.toList());
}
}
}

@ -195,4 +195,27 @@
ORDER BY h.day ASC
</select>
<select id="selectProductDailyReportTotals" resultType="java.util.HashMap">
SELECT
p.product_id AS productId,
DATE_FORMAT(r.baogong_time, '%Y-%m-%d') AS day,
IFNULL(SUM(IFNULL(r.num, 0) + IFNULL(r.no_pass_num, 0)), 0) AS totalNum
FROM mes_baogong_record r
INNER JOIN mes_plan p ON p.id = r.plan_id AND p.deleted = b'0'
WHERE r.deleted = b'0'
<if test="productIds != null and productIds.size() > 0">
AND p.product_id IN
<foreach collection="productIds" item="productId" open="(" separator="," close=")">
#{productId}
</foreach>
</if>
<if test="beginTime != null">
AND r.baogong_time &gt;= #{beginTime}
</if>
<if test="endTime != null">
AND r.baogong_time &lt; #{endTime}
</if>
GROUP BY p.product_id, DATE_FORMAT(r.baogong_time, '%Y-%m-%d')
</select>
</mapper>

Loading…
Cancel
Save