Compare commits

..

No commits in common. 'main' and 'ck' have entirely different histories.
main ... ck

@ -119,10 +119,4 @@ public class MoldDO extends BaseDO {
@TableField(exist = false)
private String qrcodeUrl;
/**
*
*/
@TableField(exist = false)
private String templateJson;
}

@ -78,6 +78,4 @@ public interface MoldMapper extends BaseMapperX<MoldDO> {
.eq(MoldDO::getBrandId, brandId)
.orderByDesc(MoldDO::getId));
}
String selectPrintTemplate();
}

@ -8,10 +8,5 @@
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
<select id="selectPrintTemplate" resultType="java.lang.String">
select template_json
from mes_print_template
where deleted = 0
and template_type = 4
</select>
</mapper>

@ -16,9 +16,9 @@
mtm.task_time,
CONCAT( '(', su.username, ')', su.nickname) as operator
from
mes_mold_ticket_results mtr
left join mes_mold_ticket_management mtm on mtm.id = mtr.management_id
left join system_users su on mtm.operator = su.id
besure.mes_mold_ticket_results mtr
left join besure.mes_mold_ticket_management mtm on mtm.id = mtr.management_id
left join besure.system_users su on mtm.operator = su.id
WHERE 1=1
<!-- ID集合过滤 -->
<if test="ids != null and ids != ''">

@ -90,12 +90,6 @@ 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(value = "id", required = false) Long id,
@RequestParam(value = "code", required = false) String code) {
return success(moldBrandService.getMold(id, code));
public CommonResult<MoldDO> getMold(@RequestParam("id") Long id) {
return success(moldBrandService.getMold(id));
}
@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(value = "id", required = false) Long id,
@RequestParam(value = "code", required = false) String code) {
return success(productService.getProduct(id, code));
public CommonResult<ErpProductRespVO> getProduct(@RequestParam("id") Long id) {
return success(productService.getProduct(id));
}
@GetMapping("/page")

@ -99,8 +99,6 @@ public class ErpProductRespVO extends ErpProductDO {
// @Schema(description = "关联模具D列表", example = "[11,15,23]")
// private List<Long> moldIds;
@Schema(description = "打印模板Json", example = "")
private String templateJson;
@Schema(description = "关联设备列表")
private List<ProductRelationRespVO> devices;

@ -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,7 +80,8 @@ 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) {
return success(warehouseService.getWarehouseDetail(id));
ErpWarehouseDO warehouse = warehouseService.getWarehouse(id);
return success(BeanUtils.toBean(warehouse, ErpWarehouseRespVO.class));
}
@GetMapping("/page")
@ -112,4 +113,4 @@ public class ErpWarehouseController {
BeanUtils.toBean(list, ErpWarehouseRespVO.class));
}
}
}

@ -2,8 +2,6 @@ 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;
@ -12,7 +10,6 @@ import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - ERP 仓库 Response VO")
@Data
@ -23,7 +20,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;
@ -35,11 +32,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;
@ -60,23 +57,8 @@ 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 lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import lombok.Data;
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 = "1")
@Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "开启状态不能为空")
@InEnum(CommonStatusEnum.class)
private Integer status;
}
}

@ -1,114 +0,0 @@
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));
}
}

@ -1,41 +0,0 @@
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;
}

@ -1,48 +0,0 @@
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;
}

@ -1,38 +0,0 @@
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;
}

@ -1,110 +0,0 @@
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));
}
}

@ -1,59 +0,0 @@
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;
}

@ -1,72 +0,0 @@
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;
}

@ -1,59 +0,0 @@
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;
}

@ -1,56 +0,0 @@
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;
}

@ -1,81 +0,0 @@
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;
}

@ -111,5 +111,4 @@ public interface ErpProductMapper extends BaseMapperX<ErpProductDO> {
List<ProductRelationRespVO> selectMoldsByProductId(@Param("productId") Long productId);
String selectPrintTemplate(@Param("templateType") Integer templateType);
}

@ -1,53 +0,0 @@
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);
}
}

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

@ -256,7 +256,6 @@ 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<>();
@ -309,29 +308,6 @@ public class MoldBrandServiceImpl implements MoldBrandService {
moldDO.setQrcodeUrl(qrcodeUrl);
return moldDO;
}
@Override
public MoldDO getMold(Long id, String code) {
if (id != null) {
MoldDO mold = getMold(id);
if(mold != null ){
String template = moldMapper.selectPrintTemplate();
mold.setTemplateJson(template);
}
return mold;
}
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);
@ -469,4 +445,4 @@ public class MoldBrandServiceImpl implements MoldBrandService {
return respVO;
}
}
}

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

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

@ -7,7 +7,6 @@ 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;
@ -326,34 +325,6 @@ public class ErpProductServiceImpl implements ErpProductService {
return respVO;
}
@Override
public ErpProductRespVO getProduct(Long id, String code) {
if (id != null) {
ErpProductRespVO product = getProduct(id);
if (product != null) {
Integer templateType = 0;
if (product.getCategoryId() == 2 ) {
templateType = 1; // 打印模板产品值
} else if(product.getCategoryId() == 5){
templateType = 5; // 打印模板备件值
}
String template = productMapper.selectPrintTemplate(templateType);
product.setTemplateJson(template);
}
return product;
}
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);
}
}
throw exception(PRODUCT_NOT_EXISTS);
}

@ -1,7 +1,6 @@
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;
@ -59,8 +58,6 @@ public interface ErpWarehouseService {
*/
ErpWarehouseDO getWarehouse(Long id);
ErpWarehouseRespVO getWarehouseDetail(Long id);
/**
*
*
@ -104,4 +101,4 @@ public interface ErpWarehouseService {
*/
PageResult<ErpWarehouseDO> getWarehousePage(ErpWarehousePageReqVO pageReqVO);
}
}

@ -4,17 +4,10 @@ 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.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.controller.admin.stock.vo.warehouse.ErpWarehousePageReqVO;
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;
@ -30,6 +23,11 @@ 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 {
@ -37,22 +35,20 @@ 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);
}
@ -60,22 +56,25 @@ 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);
}
@ -90,24 +89,6 @@ 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)) {
@ -117,7 +98,7 @@ public class ErpWarehouseServiceImpl implements ErpWarehouseService {
Map<Long, ErpWarehouseDO> warehouseMap = convertMap(list, ErpWarehouseDO::getId);
for (Long id : ids) {
ErpWarehouseDO warehouse = warehouseMap.get(id);
if (warehouse == null) {
if (warehouseMap.get(id) == null) {
throw exception(WAREHOUSE_NOT_EXISTS);
}
if (CommonStatusEnum.isDisable(warehouse.getStatus())) {
@ -142,4 +123,4 @@ public class ErpWarehouseServiceImpl implements ErpWarehouseService {
return warehouseMapper.selectPage(pageReqVO);
}
}
}

@ -1,59 +0,0 @@
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);
}

@ -1,100 +0,0 @@
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;
}
}

@ -1,58 +0,0 @@
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);
}

@ -1,95 +0,0 @@
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
@ -48,12 +48,6 @@
WHERE rel.product_id = #{productId}
AND rel.deleted = b'0'
</select>
<select id="selectPrintTemplate" resultType="java.lang.String">
select template_json
from mes_print_template
where deleted = 0
and template_type = #{templateType}
</select>
</mapper>

@ -1,12 +0,0 @@
<?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>

@ -1,12 +0,0 @@
<?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<DeviceDO>> deviceList(@Valid DevicePageReqVO pageReqVO) {
// List<DeviceRespVO> list = deviceService.getDevicePage(pageReqVO).getList();
List<DeviceDO> list = deviceService.deviceList(pageReqVO);
public CommonResult<List<DeviceRespVO>> deviceList(@Valid DevicePageReqVO pageReqVO) {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<DeviceRespVO> list = deviceService.getDevicePage(pageReqVO).getList();
return success(list);
}

@ -40,12 +40,6 @@ public enum DeviceRateTrendPeriodEnum {
return new DateRange(start, start.with(TemporalAdjusters.lastDayOfMonth()));
}
},
LAST_YEAR("LAST_YEAR", "近一年") {
@Override
public DateRange resolve(LocalDate today) {
return new DateRange(today.minusYears(1), today.minusDays(1));
}
},
THIS_MONTH("THIS_MONTH", "本月") {
@Override
public DateRange resolve(LocalDate today) {

@ -126,7 +126,4 @@ public class DeviceRespVO {
@Schema(description = "mqtt订阅主题")
@ExcelProperty("mqtt订阅主题")
private String topic;
@Schema(description = "设备图片", example = "{}")
private String images;
}

@ -81,7 +81,4 @@ public class DeviceSaveReqVO {
@Schema(description = "记录分析的条件json", example = "{}")
private String contactInfo;
@Schema(description = "设备图片", example = "{}")
private String images;
}

@ -1,46 +1,37 @@
package cn.iocoder.yudao.module.iot.controller.admin.deviceoperationrecord;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
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.iot.controller.admin.deviceoperationrecord.vo.DeviceOperationOverviewRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.deviceoperationrecord.vo.DeviceOperationRateTrendRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.deviceoperationrecord.vo.DeviceOperationRecordPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.deviceoperationrecord.vo.DeviceOperationRecordRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.deviceoperationrecord.vo.DeviceOperationRecordSaveReqVO;
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.dal.dataobject.deviceoperationrecord.DeviceOperationRecordDO;
import cn.iocoder.yudao.module.iot.service.deviceoperationrecord.DeviceOperationRecordService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
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 javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.*;
import java.io.IOException;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
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 cn.iocoder.yudao.module.iot.controller.admin.deviceoperationrecord.vo.*;
import cn.iocoder.yudao.module.iot.dal.dataobject.deviceoperationrecord.DeviceOperationRecordDO;
import cn.iocoder.yudao.module.iot.service.deviceoperationrecord.DeviceOperationRecordService;
@Tag(name = "管理后台 - 运行记录")
@RestController
@RequestMapping("/iot/device-operation-record")
@ -96,11 +87,12 @@ public class DeviceOperationRecordController {
@PreAuthorize("@ss.hasPermission('iot:device-operation-record:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportDeviceOperationRecordExcel(@Valid DeviceOperationRecordPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<DeviceOperationRecordDO> list = deviceOperationRecordService.getDeviceOperationRecordPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "运行记录.xls", "数据", DeviceOperationRecordRespVO.class,
BeanUtils.toBean(list, DeviceOperationRecordRespVO.class));
BeanUtils.toBean(list, DeviceOperationRecordRespVO.class));
}
@GetMapping("/deviceOperationPage")
@ -119,44 +111,37 @@ public class DeviceOperationRecordController {
}
@GetMapping("/deviceRateTrendByDeviceId")
@Operation(summary = "根据设备 ID 查询单设备开机率和利用率趋势")
@Operation(summary = "根据设备ID查询某个设备近7日开机率和稼动率")
@PreAuthorize("@ss.hasPermission('iot:device-operation-record:query')")
public CommonResult<List<DeviceOperationRateTrendRespVO>> getDeviceRateTrendByDeviceId(
@RequestParam("deviceId") Long deviceId,
@RequestParam(value = "period", required = false) String period) {
return success(deviceOperationRecordService.getDeviceRateTrendByDeviceId(deviceId, period));
public CommonResult<List<DeviceOperationRateTrendRespVO>> getDeviceRateTrendByDeviceId(@RequestParam("deviceId") Long deviceId) {
return success(deviceOperationRecordService.getDeviceRateTrendByDeviceId(deviceId));
}
@GetMapping("/deviceOperationList")
@Operation(summary = "产线设备运行开机率/利用率大屏")
@Operation(summary = "产线设备运行开机率/稼动率-大屏")
@PreAuthorize("@ss.hasPermission('iot:device-operation-record:query')")
public CommonResult<List<DeviceTotalTimeRecordRespVO>> deviceOperationList(@Valid DeviceTotalTimeRecordReqVO pageReqVO) {
return success(deviceOperationRecordService.deviceOperationList(pageReqVO));
List<DeviceTotalTimeRecordRespVO> deviceTotalTimeRecordRespVOList = deviceOperationRecordService.deviceOperationList(pageReqVO);
return success(deviceTotalTimeRecordRespVOList);
}
@GetMapping("/runOverview")
@Operation(
summary = "设备运行总览",
description = "根据设备 ID 集合、统计时间范围和时间轴分页参数,返回运行总览指标卡、按小时状态分布、状态汇总以及设备时间轴数据"
)
@PreAuthorize("@ss.hasPermission('iot:device-operation-record:query')")
public CommonResult<DeviceOperationOverviewRespVO> runOverview(@Valid DeviceTotalTimeRecordReqVO pageReqVO) {
return success(deviceOperationRecordService.runOverview(pageReqVO));
}
@GetMapping("/export-device-operation-report")
@Operation(summary = "导出设备运行报表记录 Excel")
@PreAuthorize("@ss.hasPermission('iot:device-operation-record:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportDeviceOperationReport(@Valid DeviceTotalTimeRecordReqVO pageReqVO,
HttpServletResponse response) throws IOException {
HttpServletResponse response) throws IOException {
PageResult<DeviceTotalTimeRecordRespVO> pageResult = deviceOperationRecordService.deviceOperationPage(pageReqVO);
// 设置响应头
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
response.setHeader("Content-Disposition",
"attachment;filename=" + URLEncoder.encode("设备运行报表记录.xls", "UTF-8"));
response.setHeader("Content-Encoding", "identity");
String fileName = String.format("设备运行报表记录_%s.xls",
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
ExcelUtils.write(response, fileName, "数据", DeviceTotalTimeRecordRespVO.class, pageResult.getList());
// 导出Excel
String fileName = String.format("设备运行报表记录_%s.xls", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
// 导出 Excel
ExcelUtils.write(response, fileName, "数据", DeviceTotalTimeRecordRespVO.class,pageResult.getList());
}
}

@ -1,127 +0,0 @@
package cn.iocoder.yudao.module.iot.controller.admin.deviceoperationrecord.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Schema(description = "管理后台 - 设备运行总览 Response VO")
@Data
public class DeviceOperationOverviewRespVO {
@Schema(description = "指标卡数据")
private List<MetricItem> metrics;
@Schema(description = "按小时统计的状态分布,单位为百分比")
private List<HourlyStatusItem> hourlyStatus;
@Schema(description = "状态汇总数据")
private List<SummaryItem> summary;
@Schema(description = "汇总总时长,单位小时")
private Double summaryTotalHours;
@Schema(description = "设备时间轴数据")
private List<TimelineRowItem> timelineRows;
@Schema(description = "设备总数")
private Integer totalDevices;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "指标卡项")
public static class MetricItem {
@Schema(description = "指标 key例如 utilizationRate、powerOnRate")
private String key;
@Schema(description = "前端图标标识")
private String icon;
@Schema(description = "指标值")
private Double value;
@Schema(description = "指标单位")
private String unit;
@Schema(description = "对比变化值,当前默认返回 0")
private Double change;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "小时状态分布项")
public static class HourlyStatusItem {
@Schema(description = "小时刻度,例如 08:00")
private String hour;
@Schema(description = "运行占比,百分比")
private Double running;
@Schema(description = "待机占比,百分比")
private Double standby;
@Schema(description = "故障占比,百分比")
private Double fault;
@Schema(description = "离线占比,百分比")
private Double offline;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "状态汇总项")
public static class SummaryItem {
@Schema(description = "状态编码running/standby/fault/offline")
private String status;
@Schema(description = "状态占比,百分比")
private Double percent;
@Schema(description = "状态累计时长,单位小时")
private Double hours;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "设备时间轴行")
public static class TimelineRowItem {
@Schema(description = "设备 ID")
private String id;
@Schema(description = "设备名称")
private String name;
@Schema(description = "设备利用率,百分比")
private Double utilizationRate;
@Schema(description = "时间轴状态段")
private List<TimelineSegmentItem> segments;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "时间轴状态段")
public static class TimelineSegmentItem {
@Schema(description = "状态编码running/standby/fault/offline")
private String status;
@Schema(description = "段开始位置,按 24 小时刻度折算")
private Double startHour;
@Schema(description = "段结束位置,按 24 小时刻度折算")
private Double endHour;
}
}

@ -1,38 +1,32 @@
package cn.iocoder.yudao.module.iot.controller.admin.deviceoperationrecord.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Schema(description = "管理后台 - 设备运行统计请求 VO")
@Schema(description = "管理后台 - 运行记录分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DeviceTotalTimeRecordReqVO extends PageParam {
@Schema(description = "快捷时间范围,支持 LAST_WEEK、THIS_WEEK、LAST_7_DAYS、LAST_MONTH、THIS_MONTH")
private String period;
public class DeviceTotalTimeRecordReqVO extends PageParam{
@Schema(description = "设备编码,模糊匹配")
@Schema(description = "设备编码")
private String deviceCode;
@Schema(description = "设备名称,模糊匹配")
@Schema(description = "设备名称")
private String deviceName;
@Schema(description = "统计开始时间,格式 yyyy-MM-dd HH:mm:ss")
@Schema(description = "开始时间")
private String startTime;
@Schema(description = "统计结束时间,格式 yyyy-MM-dd HH:mm:ss")
@Schema(description = "结束时间")
private String endTime;
@Schema(description = "设备 ID 集合,使用英文逗号分隔,例如 1,2,3")
@Schema(description = "ids导出集合用")
private String ids;
@Schema(description = "时间轴页码,默认 1")
private Integer timelinePageNo;
@Schema(description = "时间轴每页条数,默认 10")
private Integer timelinePageSize;
}

@ -122,9 +122,4 @@ public class DeviceDO extends BaseDO {
*/
private String contactInfo;
/**
*
*/
private String images;
}

@ -140,9 +140,6 @@ 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);
List<DeviceSelectRespVO> getAvailableDevicePage(@Param("page") Page<DeviceSelectRespVO> page,@Param("param") DevicePageReqVO pageReqVO);
}

@ -158,8 +158,6 @@ 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,7 +17,6 @@ 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;
@ -72,7 +71,6 @@ 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;
@ -374,7 +372,7 @@ public class DeviceServiceImpl implements DeviceService {
// .orderByDesc(DeviceOperationRecordDO::getCreateTime)
// );
List<DeviceOperationRecordDO> operationRecords = tdengineService.selectLatestByDeviceAndRuleMinimal(deviceIds,null);
List<DeviceOperationRecordDO> operationRecords = tdengineService.selectLatestByDeviceAndRuleMinimal(deviceIds,ruleCodes);
// 按 deviceId 分组,取最新一条
Map<Long, DeviceOperationRecordDO> latestRecordMap = operationRecords.stream()
@ -1080,7 +1078,7 @@ public class DeviceServiceImpl implements DeviceService {
if(CollUtil.isNotEmpty(deviceModelAttributeDOPageResult)){
List<String> typeNames = deviceModelAttributeDOPageResult.stream().map(DeviceContactModelDO::getTypeName).distinct().collect(Collectors.toList());
List<String> codes = deviceModelAttributeDOPageResult.stream().map(DeviceContactModelDO::getAttributeCode).distinct().collect(Collectors.toList());
Map<String, List<DeviceContactModelDO>> resultMap = deviceModelAttributeDOPageResult.stream().filter(d -> d.getTypeName() != null).collect(Collectors.groupingBy(DeviceContactModelDO::getTypeName));
Map<String, List<DeviceContactModelDO>> resultMap = deviceModelAttributeDOPageResult.stream().collect(Collectors.groupingBy(DeviceContactModelDO::getTypeName));
resultMap.forEach((key, value) -> {
HashMap<String, Object> objectObjectHashMap = new HashMap<>();
objectObjectHashMap.put("group", key);
@ -1948,200 +1946,53 @@ 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);
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);
// 根据 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);
// 默认只统计排产设备,这里先得到最终参与统计的设备集合
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 = startDate; !day.isAfter(endDate); day = day.plusDays(1)) {
if (Boolean.TRUE.equals(reqVO.getSkipHoliday()) && holidaySet.contains(day)) {
for (LocalDate day = startDateTime.toLocalDate(); !day.isAfter(endDateTime.toLocalDate()); day = day.plusDays(1)) {
// 跳过节假日时,这一天不查询,也不返回
if (Boolean.TRUE.equals(reqVO.getSkipHoliday()) && isHoliday(day)) {
continue;
}
Map<Long, DeviceTotalTimeRecordRespVO> dayMap =
dayDeviceRecordMap.getOrDefault(day, Collections.emptyMap());
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));
double powerOnRateSum = 0D;
double utilizationRateSum = 0D;
int deviceCount = deviceDayList.size();
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;
for (DeviceTotalTimeRecordRespVO record : deviceDayList) {
powerOnRateSum += parsePercentValue(record.getPowerOnRate());
utilizationRateSum += parsePercentValue(record.getUtilizationRate());
}
DeviceRateTrendPointRespVO point = new DeviceRateTrendPointRespVO();
point.setDay(day.toString());
point.setDeviceCount(deviceCount);
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;
@ -2160,57 +2011,37 @@ 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) {
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(","));
return reqVO.getIds();
}
// 只统计排产设备
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) {
@ -2218,6 +2049,10 @@ 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();
@ -2231,71 +2066,5 @@ 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,8 +2009,7 @@ public class TDengineService {
/**
* 使TDengineLAST
* GROUP BY device_id
*
*/
@DS("tdengine")
public List<DeviceOperationRecordDO> selectLatestByDeviceAndRuleMinimal(
@ -2021,84 +2020,59 @@ public class TDengineService {
return Collections.emptyList();
}
// 构建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<DeviceOperationRecordDO> allResults = new ArrayList<>();
for (int i = 0; i < deviceIds.size(); i++) {
if (i > 0) {
sql.append(", ");
}
sql.append("?");
params.add(deviceIds.get(i));
}
sql.append(") ");
for (Long deviceId : deviceIds) {
StringBuilder sql = new StringBuilder(
"SELECT * FROM besure_server.iot_device_operation_record " +
"WHERE deleted = 0 AND device_id = ? "
);
// 添加规则代码条件
if (CollectionUtils.isNotEmpty(ruleCodes)) {
sql.append("AND rule IN (");
for (int i = 0; i < ruleCodes.size(); i++) {
if (i > 0) {
sql.append(", ");
List<Object> params = new ArrayList<>();
params.add(deviceId);
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));
}
sql.append("?");
params.add(ruleCodes.get(i));
sql.append(") ");
}
sql.append(") ");
}
// 使用GROUP BY device_id获取每个设备的最新记录
sql.append("GROUP BY device_id ");
sql.append("ORDER BY create_time DESC LIMIT 1"); // 每个设备只取最新1条
// // 添加INTERVAL(0)确保正确处理时间窗口
// sql.append("INTERVAL(0) ");
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);
// 按设备ID排序
sql.append("ORDER BY device_id");
} catch (Exception e) {
log.error("查询设备{}的最新记录失败", deviceId, e);
}
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;
}
/**
@ -2599,245 +2573,4 @@ 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();
}
}
@DS("tdengine")
public List<Map<String, Object>> queryDeviceHourTrend(List<Long> deviceIds, String startTime, String endTime) {
StringBuilder sql = new StringBuilder();
List<Object> params = new ArrayList<>();
sql.append("SELECT ")
.append("TO_CHAR(_wstart, 'HH24') AS hourValue, ")
.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);
}
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("INTERVAL(1h) ORDER BY _wstart 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<DeviceOperationRecordDO> queryDeviceOperationTimeline(List<Long> deviceIds, String startTime, String endTime) {
if (deviceIds == null || deviceIds.isEmpty()) {
return Collections.emptyList();
}
StringBuilder sql = new StringBuilder();
List<Object> params = new ArrayList<>();
sql.append("SELECT device_id, rule, create_time ")
.append("FROM besure_server.iot_device_operation_record ")
.append("WHERE deleted = 0 ");
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(") ");
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("ORDER BY device_id ASC, create_time ASC");
try {
return jdbcTemplate.query(sql.toString(), params.toArray(), (rs, rowNum) -> {
DeviceOperationRecordDO record = new DeviceOperationRecordDO();
record.setDeviceId(rs.getLong("device_id"));
record.setRule(rs.getString("rule"));
Timestamp createTime = rs.getTimestamp("create_time");
if (createTime != null) {
record.setCreateTime(createTime.toLocalDateTime());
}
return record;
});
} catch (Exception e) {
log.error("TDengine 查询设备时间轴失败sql={}, params={}", sql, params, e);
return Collections.emptyList();
}
}
}
}

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

@ -1,7 +1,5 @@
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;
@ -14,7 +12,10 @@ import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.time.*;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
@ -91,8 +92,6 @@ 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 =
@ -107,9 +106,6 @@ 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(
@ -118,9 +114,6 @@ 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);
@ -129,10 +122,6 @@ 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());
@ -148,7 +137,6 @@ public class DeviceOperationRecordServiceImpl implements DeviceOperationRecordSe
}
result.add(device);
}
log.info("deviceOperationPage mysql设备ID列表: {}", deviceIds);
// 5. 计算和转换
calculateAndSetConvertedValues(result, pageReqVO);
@ -159,158 +147,75 @@ public class DeviceOperationRecordServiceImpl implements DeviceOperationRecordSe
@Override
public List<DeviceTotalTimeRecordRespVO> deviceOperationPageList(DeviceTotalTimeRecordReqVO pageReqVO) {
List<DeviceTotalTimeRecordRespVO> result = queryDeviceStatsRaw(pageReqVO);
calculateAndSetConvertedValues(result, pageReqVO);
result.sort(Comparator.comparingDouble(this::parsePercentValue).reversed());
return result;
}
@Override
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);
String startTime = dateRange.getStart().atStartOfDay().format(formatter);
String endTime = dateRange.getEnd().atTime(LocalTime.MAX).withNano(0).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);
List<DeviceTotalTimeRecordRespVO> deviceList =
deviceOperationRecordMapper.selectDeviceListFromMySQL(pageReqVO);
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);
}
}
if (CollectionUtils.isEmpty(deviceList)) {
return Collections.emptyList();
}
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());
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;
}
List<Long> deviceIds = deviceList.stream()
.map(DeviceTotalTimeRecordRespVO::getId)
.collect(Collectors.toList());
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)
List<Map<String, Object>> statsList =
deviceOperationRecordMapper.selectDeviceStatsFromTD(
deviceIds,
pageReqVO.getStartTime(),
pageReqVO.getEndTime()
);
Map<Long, DeviceTotalTimeRecordRespVO> tdStatsMap = convertStatsListToMap(statsList);
} catch (Exception e) {
log.error("计算设备日趋势失败deviceId={}, day={}", deviceId, day, e);
trend.setPowerOnRate("0%");
trend.setUtilizationRate("0%");
List<DeviceTotalTimeRecordRespVO> result = new ArrayList<>();
for (DeviceTotalTimeRecordRespVO device : deviceList) {
DeviceTotalTimeRecordRespVO stats = tdStatsMap.get(device.getId());
if (stats != null) {
device.setTotalOfflineTime(stats.getTotalOfflineTime());
device.setTotalRunningTime(stats.getTotalRunningTime());
device.setTotalStandbyTime(stats.getTotalStandbyTime());
device.setTotalFaultTime(stats.getTotalFaultTime());
} else {
device.setTotalOfflineTime(0);
device.setTotalRunningTime(0);
device.setTotalStandbyTime(0);
device.setTotalFaultTime(0);
}
result.add(trend);
result.add(device);
}
calculateAndSetConvertedValues(result, pageReqVO);
result.sort(Comparator.comparingDouble(this::parsePercentValue).reversed());
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;
}
@Override
public List<DeviceOperationRateTrendRespVO> getDeviceRateTrendByDeviceId(Long deviceId) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
List<DeviceOperationRateTrendRespVO> result = new ArrayList<>();
String period = StringUtils.defaultIfBlank(
reqVO.getPeriod(),
DeviceRateTrendPeriodEnum.LAST_7_DAYS.getCode()
);
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);
DeviceRateTrendPeriodEnum.DateRange dateRange = DeviceRateTrendPeriodEnum
.valueOfCode(period)
.resolve(LocalDate.now());
DeviceTotalTimeRecordReqVO reqVO = new DeviceTotalTimeRecordReqVO();
reqVO.setIds(String.valueOf(deviceId));
reqVO.setStartTime(dayStart.format(formatter));
reqVO.setEndTime(dayEnd.format(formatter));
LocalDateTime startDateTime = dateRange.getStart().atStartOfDay();
LocalDateTime endDateTime = dateRange.getEnd().atTime(LocalTime.MAX).withNano(0);
List<DeviceTotalTimeRecordRespVO> dayList = deviceOperationPageList(reqVO);
DeviceTotalTimeRecordRespVO record = CollectionUtils.isNotEmpty(dayList) ? dayList.get(0) : null;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND);
reqVO.setStartTime(startDateTime.format(formatter));
reqVO.setEndTime(endDateTime.format(formatter));
}
DeviceOperationRateTrendRespVO trend = new DeviceOperationRateTrendRespVO();
trend.setDay(day.toString());
trend.setPowerOnRate(record != null ? record.getPowerOnRate() : "0%");
trend.setUtilizationRate(record != null ? record.getUtilizationRate() : "0%");
result.add(trend);
}
private DeviceRateTrendPeriodEnum.DateRange resolvePeriodRange(String period) {
String actualPeriod = StringUtils.defaultIfBlank(period, DeviceRateTrendPeriodEnum.LAST_7_DAYS.getCode());
return DeviceRateTrendPeriodEnum.valueOfCode(actualPeriod).resolve(LocalDate.now());
return result;
}
@Override
@ -411,76 +316,6 @@ public class DeviceOperationRecordServiceImpl implements DeviceOperationRecordSe
return lineList;
}
@Override
public DeviceOperationOverviewRespVO runOverview(DeviceTotalTimeRecordReqVO pageReqVO) {
//参数构造
applyPeriodIfNecessary(pageReqVO);
List<DeviceTotalTimeRecordRespVO> records = queryDeviceStatsRaw(pageReqVO);
DeviceOperationOverviewRespVO respVO = new DeviceOperationOverviewRespVO();
double totalRunningSeconds = records.stream().mapToDouble(DeviceTotalTimeRecordRespVO::getTotalRunningTime).sum();
double totalStandbySeconds = records.stream().mapToDouble(DeviceTotalTimeRecordRespVO::getTotalStandbyTime).sum();
double totalFaultSeconds = records.stream().mapToDouble(DeviceTotalTimeRecordRespVO::getTotalFaultTime).sum();
double totalOfflineSeconds = records.stream().mapToDouble(DeviceTotalTimeRecordRespVO::getTotalOfflineTime).sum();
double onlineSeconds = totalRunningSeconds + totalStandbySeconds + totalFaultSeconds;
double totalSeconds = onlineSeconds + totalOfflineSeconds;
double utilizationRate = calculatePercent(totalRunningSeconds, onlineSeconds);
double powerOnRate = calculatePercent(onlineSeconds, totalSeconds);
double faultRate = calculatePercent(totalFaultSeconds, onlineSeconds);
double standbyRate = calculatePercent(totalStandbySeconds, onlineSeconds);
DeviceTotalTimeRecordReqVO previousReqVO = buildPreviousPeriodReqVO(pageReqVO);
List<DeviceTotalTimeRecordRespVO> previousRecords = queryDeviceStatsRaw(previousReqVO);
double previousTotalRunningSeconds = previousRecords.stream().mapToDouble(DeviceTotalTimeRecordRespVO::getTotalRunningTime).sum();
double previousTotalStandbySeconds = previousRecords.stream().mapToDouble(DeviceTotalTimeRecordRespVO::getTotalStandbyTime).sum();
double previousTotalFaultSeconds = previousRecords.stream().mapToDouble(DeviceTotalTimeRecordRespVO::getTotalFaultTime).sum();
double previousTotalOfflineSeconds = previousRecords.stream().mapToDouble(DeviceTotalTimeRecordRespVO::getTotalOfflineTime).sum();
double previousOnlineSeconds = previousTotalRunningSeconds + previousTotalStandbySeconds + previousTotalFaultSeconds;
double previousTotalSeconds = previousOnlineSeconds + previousTotalOfflineSeconds;
double previousUtilizationRate = calculatePercent(previousTotalRunningSeconds, previousOnlineSeconds);
double previousPowerOnRate = calculatePercent(previousOnlineSeconds, previousTotalSeconds);
double previousFaultRate = calculatePercent(previousTotalFaultSeconds, previousOnlineSeconds);
double previousStandbyRate = calculatePercent(previousTotalStandbySeconds, previousOnlineSeconds);
double utilizationRateChange = calculateMetricChange(utilizationRate, previousUtilizationRate);
double powerOnRateChange = calculateMetricChange(powerOnRate, previousPowerOnRate);
double faultRateChange = calculateMetricChange(faultRate, previousFaultRate);
double standbyRateChange = calculateMetricChange(standbyRate, previousStandbyRate);
double totalRunningHours = secondsToHours(totalRunningSeconds);
double totalStandbyHours = secondsToHours(totalStandbySeconds);
double totalFaultHours = secondsToHours(totalFaultSeconds);
double totalOfflineHours = secondsToHours(totalOfflineSeconds);
double totalHours = secondsToHours(totalSeconds);
respVO.setMetrics(Arrays.asList(
DeviceOperationOverviewRespVO.MetricItem.builder().key("utilizationRate").icon("ep:pie-chart").value(round2(utilizationRate)).unit("%").change(utilizationRateChange).build(),
DeviceOperationOverviewRespVO.MetricItem.builder().key("powerOnRate").icon("ep:video-play").value(round2(powerOnRate)).unit("%").change(powerOnRateChange).build(),
DeviceOperationOverviewRespVO.MetricItem.builder().key("faultRate").icon("ep:warning").value(round2(faultRate)).unit("%").change(faultRateChange).build(),
DeviceOperationOverviewRespVO.MetricItem.builder().key("standbyRate").icon("ep:timer").value(round2(standbyRate)).unit("%").change(standbyRateChange).build()
));
respVO.setSummary(Arrays.asList(
DeviceOperationOverviewRespVO.SummaryItem.builder().status("running").percent(toPercent(totalRunningHours, totalHours)).hours(round2(totalRunningHours)).build(),
DeviceOperationOverviewRespVO.SummaryItem.builder().status("standby").percent(toPercent(totalStandbyHours, totalHours)).hours(round2(totalStandbyHours)).build(),
DeviceOperationOverviewRespVO.SummaryItem.builder().status("fault").percent(toPercent(totalFaultHours, totalHours)).hours(round2(totalFaultHours)).build(),
DeviceOperationOverviewRespVO.SummaryItem.builder().status("offline").percent(toPercent(totalOfflineHours, totalHours)).hours(round2(totalOfflineHours)).build()
));
respVO.setSummaryTotalHours(round2(totalHours));
List<Long> deviceIds = parseIds(pageReqVO.getIds());
List<Map<String, Object>> hourlyRows = tDengineService.queryDeviceHourTrend(deviceIds, pageReqVO.getStartTime(), pageReqVO.getEndTime());
respVO.setHourlyStatus(buildHourlyStatus(hourlyRows));
//设备运行轨迹
List<DeviceOperationOverviewRespVO.TimelineRowItem> timelineRows =
buildTimelineRows(records, deviceIds, pageReqVO.getStartTime(), pageReqVO.getEndTime());
respVO.setTotalDevices(timelineRows.size());
respVO.setTimelineRows(paginateTimelineRows(timelineRows, pageReqVO.getTimelinePageNo(), pageReqVO.getTimelinePageSize()));
return respVO;
}
private double parsePercentValue(DeviceTotalTimeRecordRespVO record) {
if (record == null || StringUtils.isBlank(record.getUtilizationRate())) {
return 0D;
@ -488,268 +323,6 @@ public class DeviceOperationRecordServiceImpl implements DeviceOperationRecordSe
return Double.parseDouble(record.getUtilizationRate().replace("%", "").trim());
}
private List<Long> parseIds(String ids) {
if (StringUtils.isBlank(ids)) {
return Collections.emptyList();
}
return Arrays.stream(ids.split(","))
.map(String::trim)
.filter(StringUtils::isNotBlank)
.map(Long::valueOf)
.distinct()
.collect(Collectors.toList());
}
private List<DeviceOperationOverviewRespVO.HourlyStatusItem> buildHourlyStatus(List<Map<String, Object>> hourlyRows) {
Map<String, HourBucket> bucketMap = new LinkedHashMap<>();
for (int i = 0; i < 24; i++) {
String hour = String.format("%02d:00", i);
bucketMap.put(hour, new HourBucket(hour));
}
for (Map<String, Object> row : hourlyRows) {
Integer hourValue = getIntValue(row, "hourValue");
if (hourValue == null || hourValue < 0 || hourValue > 23) {
continue;
}
String hour = String.format("%02d:00", hourValue);
HourBucket bucket = bucketMap.get(hour);
if (bucket == null) {
continue;
}
bucket.offline += getDoubleValue(row, "totalofflinetime");
bucket.running += getDoubleValue(row, "totalrunningtime");
bucket.standby += getDoubleValue(row, "totalstandbytime");
bucket.fault += getDoubleValue(row, "totalfaulttime");
}
return bucketMap.values().stream().map(bucket -> {
double total = bucket.running + bucket.standby + bucket.fault + bucket.offline;
return DeviceOperationOverviewRespVO.HourlyStatusItem.builder()
.hour(bucket.hour)
.running(total > 0 ? round2(bucket.running / total * 100) : 0D)
.standby(total > 0 ? round2(bucket.standby / total * 100) : 0D)
.fault(total > 0 ? round2(bucket.fault / total * 100) : 0D)
.offline(total > 0 ? round2(bucket.offline / total * 100) : 0D)
.build();
}).collect(Collectors.toList());
}
private double toPercent(double numerator, double denominator) {
return denominator > 0 ? round2(numerator / denominator * 100) : 0D;
}
private double calculatePercent(double numerator, double denominator) {
return denominator > 0 ? numerator / denominator * 100D : 0D;
}
private double calculateUtilizationRate(DeviceTotalTimeRecordRespVO record) {
if (record == null) {
return 0D;
}
double runningSeconds = record.getTotalRunningTime();
double onlineSeconds = runningSeconds + record.getTotalStandbyTime() + record.getTotalFaultTime();
return round2(calculatePercent(runningSeconds, onlineSeconds));
}
private double secondsToHours(double seconds) {
return round2(seconds / 3600D);
}
private double round2(double value) {
return Math.round(value * 100D) / 100D;
}
private DeviceTotalTimeRecordReqVO buildPreviousPeriodReqVO(DeviceTotalTimeRecordReqVO reqVO) {
DeviceTotalTimeRecordReqVO previousReqVO = new DeviceTotalTimeRecordReqVO();
previousReqVO.setIds(reqVO.getIds());
previousReqVO.setDeviceCode(reqVO.getDeviceCode());
previousReqVO.setDeviceName(reqVO.getDeviceName());
previousReqVO.setTimelinePageNo(reqVO.getTimelinePageNo());
previousReqVO.setTimelinePageSize(reqVO.getTimelinePageSize());
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND);
LocalDateTime start = LocalDateTime.parse(reqVO.getStartTime(), formatter);
LocalDateTime end = LocalDateTime.parse(reqVO.getEndTime(), formatter);
Duration duration = Duration.between(start, end);
LocalDateTime previousStart = start.minusDays(1);
LocalDateTime previousEnd = previousStart.plus(duration);
previousReqVO.setStartTime(previousStart.format(formatter));
previousReqVO.setEndTime(previousEnd.format(formatter));
return previousReqVO;
}
private double calculateMetricChange(double current, double previous) {
return round2(current - previous);
}
private List<DeviceOperationOverviewRespVO.TimelineRowItem> buildTimelineRows(List<DeviceTotalTimeRecordRespVO> records,
List<Long> deviceIds,
String startTime,
String endTime) {
if (records == null || records.isEmpty()) {
return Collections.emptyList();
}
Map<Long, List<DeviceOperationRecordDO>> recordMap = tDengineService.queryDeviceOperationTimeline(deviceIds, startTime, endTime)
.stream()
.filter(item -> item.getDeviceId() != null)
.collect(Collectors.groupingBy(DeviceOperationRecordDO::getDeviceId, LinkedHashMap::new, Collectors.toList()));
LocalDateTime start = LocalDateTime.parse(startTime, DateTimeFormatter.ofPattern(DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
LocalDateTime end = LocalDateTime.parse(endTime, DateTimeFormatter.ofPattern(DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
double totalSeconds = Math.max(1D, Duration.between(start, end).getSeconds());
return records.stream().map(record -> {
List<DeviceOperationOverviewRespVO.TimelineSegmentItem> segments = buildTimelineSegments(
recordMap.getOrDefault(record.getId(), Collections.emptyList()),
start,
end,
totalSeconds
);
return DeviceOperationOverviewRespVO.TimelineRowItem.builder()
.id(String.valueOf(record.getId()))
.name(record.getDeviceName())
.utilizationRate(calculateUtilizationRate(record))
.segments(segments)
.build();
}).collect(Collectors.toList());
}
private List<DeviceOperationOverviewRespVO.TimelineRowItem> paginateTimelineRows(List<DeviceOperationOverviewRespVO.TimelineRowItem> rows,
Integer pageNo,
Integer pageSize) {
if (rows == null || rows.isEmpty()) {
return Collections.emptyList();
}
int actualPageNo = pageNo == null || pageNo < 1 ? 1 : pageNo;
int actualPageSize = pageSize == null || pageSize < 1 ? 10 : pageSize;
int fromIndex = Math.min((actualPageNo - 1) * actualPageSize, rows.size());
int toIndex = Math.min(fromIndex + actualPageSize, rows.size());
return rows.subList(fromIndex, toIndex);
}
private List<DeviceTotalTimeRecordRespVO> queryDeviceStatsRaw(DeviceTotalTimeRecordReqVO pageReqVO) {
applyPeriodIfNecessary(pageReqVO);
List<DeviceTotalTimeRecordRespVO> deviceList =
deviceOperationRecordMapper.selectDeviceListFromMySQL(pageReqVO);
if (CollectionUtils.isEmpty(deviceList)) {
return Collections.emptyList();
}
List<Long> deviceIds = deviceList.stream()
.map(DeviceTotalTimeRecordRespVO::getId)
.collect(Collectors.toList());
List<Map<String, Object>> statsList =
deviceOperationRecordMapper.selectDeviceStatsFromTD(
deviceIds,
pageReqVO.getStartTime(),
pageReqVO.getEndTime()
);
Map<Long, DeviceTotalTimeRecordRespVO> tdStatsMap = convertStatsListToMap(statsList);
List<DeviceTotalTimeRecordRespVO> result = new ArrayList<>();
for (DeviceTotalTimeRecordRespVO device : deviceList) {
DeviceTotalTimeRecordRespVO stats = tdStatsMap.get(device.getId());
if (stats != null) {
device.setTotalOfflineTime(stats.getTotalOfflineTime());
device.setTotalRunningTime(stats.getTotalRunningTime());
device.setTotalStandbyTime(stats.getTotalStandbyTime());
device.setTotalFaultTime(stats.getTotalFaultTime());
} else {
device.setTotalOfflineTime(0);
device.setTotalRunningTime(0);
device.setTotalStandbyTime(0);
device.setTotalFaultTime(0);
}
result.add(device);
}
return result;
}
private List<DeviceOperationOverviewRespVO.TimelineSegmentItem> buildTimelineSegments(List<DeviceOperationRecordDO> timelineRecords,
LocalDateTime start,
LocalDateTime end,
double totalSeconds) {
if (timelineRecords == null || timelineRecords.isEmpty()) {
return Collections.emptyList();
}
List<DeviceOperationOverviewRespVO.TimelineSegmentItem> segments = new ArrayList<>();
for (int i = 0; i < timelineRecords.size(); i++) {
DeviceOperationRecordDO current = timelineRecords.get(i);
LocalDateTime currentTime = current.getCreateTime();
if (currentTime == null) {
continue;
}
LocalDateTime segmentStart = currentTime.isBefore(start) ? start : currentTime;
LocalDateTime segmentEnd = i + 1 < timelineRecords.size() && timelineRecords.get(i + 1).getCreateTime() != null
? timelineRecords.get(i + 1).getCreateTime()
: end;
if (segmentEnd.isAfter(end)) {
segmentEnd = end;
}
if (!segmentEnd.isAfter(segmentStart)) {
continue;
}
double startHour = Duration.between(start, segmentStart).getSeconds() / totalSeconds * 24D;
double endHour = Duration.between(start, segmentEnd).getSeconds() / totalSeconds * 24D;
segments.add(DeviceOperationOverviewRespVO.TimelineSegmentItem.builder()
.status(mapRuleToStatus(current.getRule()))
.startHour(round2(startHour))
.endHour(round2(endHour))
.build());
}
return segments;
}
private String mapRuleToStatus(String rule) {
if ("1".equals(rule)) {
return "running";
}
if ("2".equals(rule)) {
return "standby";
}
if ("3".equals(rule)) {
return "fault";
}
return "offline";
}
private double getDoubleValue(Map<String, Object> map, String key) {
Object value = map.get(key);
if (value == null) {
return 0D;
}
if (value instanceof Number) {
return ((Number) value).doubleValue() / 3600D;
}
try {
return Double.parseDouble(String.valueOf(value)) / 3600D;
} catch (Exception e) {
return 0D;
}
}
private static class HourBucket {
private final String hour;
private double running;
private double standby;
private double fault;
private double offline;
private HourBucket(String hour) {
this.hour = hour;
}
}
private void calculateAndSetConvertedValues(
List<DeviceTotalTimeRecordRespVO> records,
DeviceTotalTimeRecordReqVO reqVO) {
@ -818,25 +391,6 @@ 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);

@ -87,14 +87,14 @@
SUM(CASE WHEN latest_status.rule = '3' THEN 1 ELSE 0 END) AS faultCount,
SUM(CASE WHEN latest_status.rule = '4' THEN 1 ELSE 0 END) AS warningCount
FROM iot_device ide
FROM besure.iot_device ide
LEFT JOIN (
-- 获取每个设备的最新状态
SELECT
device_id,
rule,
ROW_NUMBER() OVER (PARTITION BY device_id ORDER BY create_time DESC) AS rn
FROM iot_device_operation_record
FROM besure.iot_device_operation_record
WHERE rule IN ('1', '2', '3', '4')
AND deleted = 0
) latest_status ON ide.id = latest_status.device_id AND latest_status.rn = 1
@ -194,13 +194,13 @@
</select>
<select id="getTotalDeviceCount" resultType="java.lang.Integer">
SELECT COUNT(DISTINCT id)
FROM iot_device
FROM besure.iot_device
WHERE deleted = 0
</select>
<select id="getAllDeviceIds" resultType="java.lang.Long">
SELECT id
FROM iot_device
FROM besure.iot_device
WHERE deleted = 0
ORDER BY id
</select>
@ -299,13 +299,5 @@
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>

@ -24,8 +24,8 @@
-- 每条 rule=3 的记录计数 * 60 秒
SUM(CASE WHEN idor.rule = '3' THEN 1 ELSE 0 END) * 60 AS totalFaultTime
FROM iot_device ide
LEFT JOIN iot_device_operation_record idor
FROM besure.iot_device ide
LEFT JOIN besure.iot_device_operation_record idor
ON idor.device_id = ide.id
AND idor.deleted = 0
<!-- 时间筛选条件 -->
@ -129,8 +129,8 @@
-- 每条 rule=3 的记录计数 * 60 秒
SUM(CASE WHEN idor.rule = '3' THEN 1 ELSE 0 END) * 60 AS totalFaultTime
FROM iot_device ide
LEFT JOIN iot_device_operation_record idor
FROM besure.iot_device ide
LEFT JOIN besure.iot_device_operation_record idor
ON idor.device_id = ide.id
AND idor.deleted = 0
<!-- 时间筛选条件 -->
@ -165,7 +165,7 @@
ide.id,
ide.device_code AS deviceCode,
ide.device_name AS deviceName
FROM iot_device ide
FROM besure.iot_device ide
WHERE ide.deleted = 0
<!-- 设备编码筛选条件 -->
<if test="pageReqVO.deviceCode != null and pageReqVO.deviceCode != ''">
@ -216,7 +216,7 @@
ide.id,
ide.device_code AS deviceCode,
ide.device_name AS deviceName
FROM iot_device ide
FROM besure.iot_device ide
WHERE ide.deleted = 0
<!-- 设备编码筛选条件 -->
<if test="deviceTotalTimeRecordReqVO.deviceCode != null and deviceTotalTimeRecordReqVO.deviceCode != ''">

@ -13,7 +13,7 @@
SELECT
DATE_FORMAT(create_time, '%Y-%m-%d %H:00') as hour,
COUNT(*) as count
FROM iot_device_warinning_record
FROM besure.iot_device_warinning_record
WHERE create_time >= DATE_SUB(NOW(), INTERVAL 7 HOUR)
GROUP BY DATE_FORMAT(create_time, '%Y-%m-%d %H:00')
ORDER BY hour

@ -194,15 +194,7 @@ 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={}");
// ========== 打印模板 相关 100_401_0000 ==========
ErrorCode PRINT_TEMPLATE_NOT_EXISTS = new ErrorCode(100_401_0000, "打印模板不存在");
ErrorCode PRINT_TEMPLATE_CODE_EXISTS = new ErrorCode(100_401_0001, "打印模板编码已存在,请重新提交");
ErrorCode PRINT_TEMPLATE_TYPE_EXISTS = new ErrorCode(100_401_0002, "该模板类型已存在打印模板,请勿重复新增");
}

@ -77,14 +77,11 @@ 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(value = "id", required = false) Long id,
@RequestParam(value = "code", required = false) String code) {
CriticalComponentDO criticalComponent = criticalComponentService.getCriticalComponent(id, code);
CriticalComponentRespVO criticalComponentRespVO = BeanUtils.toBean(criticalComponent, CriticalComponentRespVO.class);
String template = criticalComponentService.selectPrintTemplate();
criticalComponentRespVO.setTemplateJson(template);
return success(criticalComponentRespVO);
public CommonResult<CriticalComponentRespVO> getCriticalComponent(@RequestParam("id") Long id) {
CriticalComponentDO criticalComponent = criticalComponentService.getCriticalComponent(id);
return success(BeanUtils.toBean(criticalComponent, CriticalComponentRespVO.class));
}
@GetMapping("/page")
@ -182,4 +179,4 @@ public class CriticalComponentController {
return success(true);
}
}
}

@ -51,6 +51,4 @@ public class CriticalComponentRespVO {
@Schema(description = "二维码", example = "2")
private String qrcodeUrl;
@Schema(description = "打印模板Json", example = "")
private String templateJson;
}

@ -139,6 +139,39 @@ 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);
// 生产计划总数
@ -314,108 +347,66 @@ 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(deviceNameMap.getOrDefault(dvRepairDO.getDeviceId(), "未知设备"));
todoRespVO.setDeviceName(deviceLedgerService.getDeviceLedger(dvRepairDO.getDeviceId()).getDeviceName());
todoRespVO.setCreateTime(dvRepairDO.getCreateTime());
todoRespVOList.add(todoRespVO);
}
// 设备保养 点检
// 5. 组装设备保养 / 点检待办
for (TicketManagementDO ticketManagementDO : ticketManagementDOList) {
TodoRespVO todoRespVO = new TodoRespVO();
List<TicketManagementDO> ticketManagementDOList = ticketManagementService.getListByJobStatus();
for (TicketManagementDO ticketManagementDO : ticketManagementDOList) {
TodoRespVO todoRespVO = new TodoRespVO();
todoRespVO.setCode(ticketManagementDO.getPlanNo());
todoRespVO.setName(ticketManagementDO.getConfigName());
todoRespVO.setType(ticketManagementDO.getPlanType() == 2 ? "设备保养" : "设备点检");
if (ticketManagementDO.getPlanType() == 2) {
todoRespVO.setType("设备保养");
} else {
todoRespVO.setType("设备点检");
}
todoRespVO.setDeviceName(ticketManagementDO.getDeviceName());
todoRespVO.setCreateTime(ticketManagementDO.getCreateTime());
todoRespVOList.add(todoRespVO);
}
// 6. 组装模具维修待办
for (MoldRepairDO moldRepairDO : moldRepairDOList) {
TodoRespVO todoRespVO = new TodoRespVO();
// 模具维修
List<MoldRepairDO> moldRepairDOList = moldRepairService.getMoldRepairDOListByStatus();
for (MoldRepairDO moldRepairDO : moldRepairDOList) {
TodoRespVO todoRespVO = new TodoRespVO();
todoRespVO.setCode(moldRepairDO.getRepairCode());
todoRespVO.setName(moldRepairDO.getRepairName());
todoRespVO.setType("模具维修");
todoRespVO.setDeviceName(moldNameMap.getOrDefault(moldRepairDO.getMoldId(), "未知设备"));
todoRespVO.setDeviceName( moldRepairDO.getMoldId() != null && moldService.getMold(moldRepairDO.getMoldId()) != null
? moldService.getMold(moldRepairDO.getMoldId()).getName()
: "未知设备");
todoRespVO.setCreateTime(moldRepairDO.getCreateTime());
todoRespVOList.add(todoRespVO);
}
// 7. 组装模具保养 / 点检待办
for (MoldTicketManagementDO moldTicketManagementDO : moldTicketManagementDOList) {
TodoRespVO todoRespVO = new TodoRespVO();
}
// 模具保养 点检
List<MoldTicketManagementDO> moldTicketManagementDOList = moldTicketManagementService.getListByJobStatus();
for (MoldTicketManagementDO moldTicketManagementDO : moldTicketManagementDOList) {
TodoRespVO todoRespVO = new TodoRespVO();
todoRespVO.setCode(moldTicketManagementDO.getPlanNo());
todoRespVO.setName(moldTicketManagementDO.getConfigName());
todoRespVO.setType(moldTicketManagementDO.getPlanType() == 2 ? "模具保养" : "模具点检");
if (moldTicketManagementDO.getPlanType() == 2) {
todoRespVO.setType("模具保养");
} else {
todoRespVO.setType("模具点检");
}
todoRespVO.setDeviceName(moldTicketManagementDO.getMoldName());
todoRespVO.setCreateTime(moldTicketManagementDO.getCreateTime());
todoRespVOList.add(todoRespVO);
}
// 8. 按创建时间倒序排序,最近的待办排前面
todoRespVOList.sort(Comparator.comparing(
TodoRespVO::getCreateTime,
Comparator.nullsLast(Comparator.reverseOrder())
));
return success(todoRespVOList);
return success(todoRespVOList);
}
@GetMapping("/getDeviceRepairLineOptions")

@ -100,15 +100,11 @@ 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(value = "id", required = false) Long id,
@RequestParam(value = "code", required = false) String code) {
DeviceLedgerDO deviceLedger = deviceLedgerService.getDeviceLedger(id, code);
public CommonResult<DeviceLedgerRespVO> getDeviceLedger(@RequestParam("id") Long id) {
DeviceLedgerDO deviceLedger = deviceLedgerService.getDeviceLedger(id);
DeviceLedgerRespVO respVO = BeanUtils.toBean(deviceLedger, DeviceLedgerRespVO.class);
if(respVO != null ){
String template = deviceLedgerService.selectPrintTemplate();
respVO.setTemplateJson(template);
}
String qrcodeUrl = qrcodeService.selectQrcodeUrlByIdAndCode(QrcodeBizTypeEnum.EQUIPMENT.getCode(),id,respVO.getDeviceCode());
respVO.setQrcodeUrl(qrcodeUrl);
@ -216,23 +212,6 @@ public class DeviceLedgerController {
ExcelUtils.write(response, "设备台账.xls", "数据", DeviceLedgerRespVO.class,deviceLedgerRespVOS);
}
@GetMapping("/capacity-report/page")
@Operation(summary = "获得设备产能报表分页")
@PreAuthorize("@ss.hasPermission('mes:device-ledger:query')")
public CommonResult<PageResult<DeviceCapacityReportRespVO>> getDeviceCapacityReportPage(@Valid DeviceCapacityReportPageReqVO pageReqVO) {
return success(deviceLedgerService.getDeviceCapacityReportPage(pageReqVO));
}
@GetMapping("/capacity-report/export-excel")
@Operation(summary = "导出设备产能报表 Excel")
@PreAuthorize("@ss.hasPermission('mes:device-ledger:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportDeviceCapacityReportExcel(@Valid DeviceCapacityReportPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
List<DeviceCapacityReportRespVO> list = deviceLedgerService.getDeviceCapacityReportList(pageReqVO);
ExcelUtils.write(response, "设备产能报表.xls", "数据", DeviceCapacityReportRespVO.class, list);
}
@ -300,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();

@ -1,45 +0,0 @@
package cn.iocoder.yudao.module.mes.controller.admin.deviceledger.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
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 = "管理后台 - 设备产能报表分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DeviceCapacityReportPageReqVO extends PageParam {
@Schema(description = "设备编码")
private String deviceCode;
@Schema(description = "设备名称")
private String deviceName;
@Schema(description = "设备类型")
private Long deviceType;
@Schema(description = "设备状态")
private Integer deviceStatus;
@Schema(description = "所属车间")
private String workshop;
@Schema(description = "导出 ids逗号分隔")
private String ids;
@Schema(description = "开始时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime beginTime;
@Schema(description = "结束时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime endTime;
}

@ -1,52 +0,0 @@
package cn.iocoder.yudao.module.mes.controller.admin.deviceledger.vo;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
@Schema(description = "管理后台 - 设备产能报表 Response VO")
@Data
@ExcelIgnoreUnannotated
public class DeviceCapacityReportRespVO {
@Schema(description = "设备 id")
private Long id;
@Schema(description = "设备编码")
@ExcelProperty("编码")
private String deviceCode;
@Schema(description = "设备名称")
@ExcelProperty("名称")
private String deviceName;
@Schema(description = "设备类型名称")
@ExcelProperty("类型")
private String typeName;
@Schema(description = "设备状态")
// @ExcelProperty(value = "状态", converter = DictConvert.class)
// @DictFormat("mes_tz_status")
private Integer deviceStatus;
@Schema(description = "额定产能(计划产能)")
@ExcelProperty("额定产能(计划产能)")
private BigDecimal ratedCapacity;
@Schema(description = "报工产能")
@ExcelProperty("报工产能")
private BigDecimal reportCapacity;
@Schema(description = "实际产能")
@ExcelProperty("实际产能")
private BigDecimal actualCapacity;
@Schema(description = "所属车间")
@ExcelProperty("所属车间")
private String workshopName;
}

@ -169,7 +169,4 @@ public class DeviceLedgerRespVO extends BaseDO {
@Schema(description = "数据采集产能")
private Integer dataCollectionCapacity;
@Schema(description = "打印模板")
private String templateJson;
}

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

@ -104,13 +104,6 @@ public class EnergyDeviceController {
return success(energyDeviceService.queryDataRecords(deviceConsumptionReqVO));
}
@GetMapping("/queryOverviewData")
@Operation(summary = "查询能源总览数据")
@PreAuthorize("@ss.hasPermission('mes:energy-device:queryRecords')")
public CommonResult<EnergyOverviewRespVO> queryOverviewData(@Valid EnergyOverviewReqVO reqVO) {
return success(energyDeviceService.queryOverviewData(reqVO));
}
@GetMapping("/record-export-excel")
@Operation(summary = "导出数据记录 Excel")
@PreAuthorize("@ss.hasPermission('mes:energy-device:exportRecords')")
@ -193,4 +186,4 @@ public class EnergyDeviceController {
}
}
}

@ -1,27 +0,0 @@
package cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 能源总览 Request VO")
@Data
public class EnergyOverviewReqVO {
@Schema(description = "所属区域")
private Long orgId;
@Schema(description = "能源类型 ID")
private Long energyTypeId;
@Schema(description = "开始时间")
private String startTime;
@Schema(description = "结束时间")
private String endTime;
@Schema(description = "页码", example = "1")
private Integer pageNo = 1;
@Schema(description = "每页数量", example = "10")
private Integer pageSize = 10;
}

@ -1,81 +0,0 @@
package cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Schema(description = "管理后台 - 能源总览 Response VO")
@Data
public class EnergyOverviewRespVO {
@Schema(description = "指标卡片")
private List<MetricItem> metrics;
@Schema(description = "趋势图")
private TrendChart trendChart;
@Schema(description = "区域占比")
private RegionChart regionChart;
@Schema(description = "TOP5 排行")
private List<RankItem> rankList;
@Schema(description = "明细列表总数")
private Long total;
@Schema(description = "明细列表")
private List<DetailItem> detailList;
@Data
public static class MetricItem {
private String key;
private String label;
private String value;
private String unit;
private String subLabel;
private String subValue;
private String change;
private Boolean down;
}
@Data
public static class TrendChart {
private String unit;
private List<String> xAxis;
private List<String> data;
}
@Data
public static class RegionChart {
private String unit;
private String totalValue;
private List<RegionItem> items;
}
@Data
public static class RegionItem {
private String name;
private String value;
private String percent;
}
@Data
public static class RankItem {
private Long id;
private String name;
private String region;
private String value;
}
@Data
public static class DetailItem {
private Long id;
private String name;
private String energyType;
private String region;
private String value;
private String startTime;
private String endTime;
}
}

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

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

@ -625,12 +625,6 @@ public class PlanController {
return success(vo);
}
@GetMapping("/quality-overview")
@Operation(summary = "质量概况")
public CommonResult<PlanQualityOverviewRespVO> getQualityOverview(@Valid PlanQualityOverviewReqVO reqVO) {
return success(planService.getQualityOverview(reqVO));
}
@GetMapping("/getLastDaysRate")
@ -690,13 +684,6 @@ public class PlanController {
return success(planService.getDevicePlanGantt(reqVO));
}
@GetMapping("/product-capacity-page")
@Operation(summary = "按产品分组查询近半年日报工均值产能分页")
@PreAuthorize("@ss.hasPermission('mes:plan:query')")
public CommonResult<PageResult<PlanProductCapacityRespVO>> getPlanProductCapacityPage(@Valid PlanProductCapacityPageReqVO reqVO) {
return success(planService.getPlanProductCapacityPage(reqVO));
}
}

@ -1,37 +0,0 @@
package cn.iocoder.yudao.module.mes.controller.admin.plan.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
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 = "管理后台 - 生产计划按产品分组产能分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
public class PlanProductCapacityPageReqVO extends PageParam {
@Schema(description = "设备台账 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long deviceId;
@Schema(description = "产品编码")
private String productCode;
@Schema(description = "产品名称")
private String productName;
@Schema(description = "任务编码")
private String taskCode;
@Schema(description = "报工开始时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime beginBaogongTime;
@Schema(description = "报工结束时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime endBaogongTime;
}

@ -1,24 +0,0 @@
package cn.iocoder.yudao.module.mes.controller.admin.plan.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 生产计划按产品分组产能分页 Response VO")
@Data
public class PlanProductCapacityRespVO {
@Schema(description = "产品编码")
private String productCode;
@Schema(description = "产品名称")
private String productName;
// @Schema(description = "任务编码")
// private String taskCode;
@Schema(description = "报工总数")
private Long baogongTotal;
@Schema(description = "报工均值产能,按近半年到昨天的统计天数计算,四舍五入")
private Integer avgCapacity;
}

@ -1,12 +0,0 @@
package cn.iocoder.yudao.module.mes.controller.admin.plan.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "管理后台 - 生产计划质量概况 Request VO")
public class PlanQualityOverviewReqVO {
@Schema(description = "时间区间LAST_WEEK/THIS_WEEK/LAST_7_DAYS/LAST_MONTH/THIS_MONTH/LAST_YEAR")
private String period;
}

@ -1,67 +0,0 @@
package cn.iocoder.yudao.module.mes.controller.admin.plan.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
@Data
@Schema(description = "管理后台 - 生产计划质量概况 Response VO")
public class PlanQualityOverviewRespVO {
@Schema(description = "报工总数")
private Long totalWangongNumber;
@Schema(description = "合格总数")
private Long totalPassNumber;
@Schema(description = "不合格总数")
private Long totalNoPassNumber;
@Schema(description = "总合格率")
private BigDecimal totalPassRate;
@Schema(description = "按产品合格率排行")
private List<ProductPassRateItem> productPassRateList;
@Schema(description = "双折线图数据")
private List<TrendItem> trendList;
@Data
@Schema(description = "产品合格率项")
public static class ProductPassRateItem {
@Schema(description = "产品ID")
private Long productId;
@Schema(description = "产品名称")
private String productName;
@Schema(description = "报工总数")
private Long wangongNumber;
@Schema(description = "合格数")
private Long passNumber;
@Schema(description = "不合格数")
private Long noPassNumber;
@Schema(description = "合格率")
private BigDecimal passRate;
}
@Data
@Schema(description = "趋势项")
public static class TrendItem {
@Schema(description = "日期")
private String day;
@Schema(description = "合格数")
private Long passNumber;
@Schema(description = "不合格数")
private Long noPassNumber;
}
}

@ -1,96 +0,0 @@
package cn.iocoder.yudao.module.mes.controller.admin.printtemplate;
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 cn.iocoder.yudao.module.mes.controller.admin.printtemplate.vo.*;
import cn.iocoder.yudao.module.mes.dal.dataobject.printtemplate.PrintTemplateDO;
import cn.iocoder.yudao.module.mes.service.printtemplate.PrintTemplateService;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
@Tag(name = "管理后台 - 打印模板")
@RestController
@RequestMapping("/mes/print-template")
@Validated
public class PrintTemplateController {
@Resource
private PrintTemplateService printTemplateService;
@PostMapping("/create")
@Operation(summary = "创建打印模板")
@PreAuthorize("@ss.hasPermission('mes:print-template:create')")
public CommonResult<Long> createPrintTemplate(@Valid @RequestBody PrintTemplateSaveReqVO createReqVO) {
return success(printTemplateService.createPrintTemplate(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新打印模板")
@PreAuthorize("@ss.hasPermission('mes:print-template:update')")
public CommonResult<Boolean> updatePrintTemplate(@Valid @RequestBody PrintTemplateSaveReqVO updateReqVO) {
printTemplateService.updatePrintTemplate(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除打印模板")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('mes:print-template:delete')")
public CommonResult<Boolean> deletePrintTemplate(@RequestParam("id") Long id) {
printTemplateService.deletePrintTemplate(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得打印模板")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('mes:print-template:query')")
public CommonResult<PrintTemplateRespVO> getPrintTemplate(@RequestParam("id") Long id) {
PrintTemplateDO printTemplate = printTemplateService.getPrintTemplate(id);
return success(BeanUtils.toBean(printTemplate, PrintTemplateRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得打印模板分页")
@PreAuthorize("@ss.hasPermission('mes:print-template:query')")
public CommonResult<PageResult<PrintTemplateRespVO>> getPrintTemplatePage(@Valid PrintTemplatePageReqVO pageReqVO) {
PageResult<PrintTemplateDO> pageResult = printTemplateService.getPrintTemplatePage(pageReqVO);
return success(BeanUtils.toBean(pageResult, PrintTemplateRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出打印模板 Excel")
@PreAuthorize("@ss.hasPermission('mes:print-template:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportPrintTemplateExcel(@Valid PrintTemplatePageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<PrintTemplateDO> list = printTemplateService.getPrintTemplatePage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "打印模板.xls", "数据", PrintTemplateRespVO.class,
BeanUtils.toBean(list, PrintTemplateRespVO.class));
}
}

@ -1,40 +0,0 @@
package cn.iocoder.yudao.module.mes.controller.admin.printtemplate.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
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 = "管理后台 - 打印模板分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class PrintTemplatePageReqVO extends PageParam {
@Schema(description = "模板编码")
private String templateCode;
@Schema(description = "模板名称", example = "张三")
private String templateName;
@Schema(description = "模板类型", example = "1")
private Integer templateType;
@Schema(description = "模板JSON内容布局、字段、样式等")
private String templateJson;
@Schema(description = "备注", example = "你猜")
private String remark;
@Schema(description = "是否启用")
private Boolean isEnable;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -1,47 +0,0 @@
package cn.iocoder.yudao.module.mes.controller.admin.printtemplate.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 打印模板 Response VO")
@Data
@ExcelIgnoreUnannotated
public class PrintTemplateRespVO {
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11046")
@ExcelProperty("ID")
private Long id;
@Schema(description = "模板编码", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("模板编码")
private String templateCode;
@Schema(description = "模板名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
@ExcelProperty("模板名称")
private String templateName;
@Schema(description = "模板类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty("模板类型")
private Integer templateType;
@Schema(description = "模板JSON内容布局、字段、样式等", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("模板JSON内容布局、字段、样式等")
private String templateJson;
@Schema(description = "备注", example = "你猜")
@ExcelProperty("备注")
private String remark;
@Schema(description = "是否启用")
@ExcelProperty("是否启用")
private Boolean isEnable;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

@ -1,38 +0,0 @@
package cn.iocoder.yudao.module.mes.controller.admin.printtemplate.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.*;
@Schema(description = "管理后台 - 打印模板新增/修改 Request VO")
@Data
public class PrintTemplateSaveReqVO {
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11046")
private Long id;
@Schema(description = "模板编码,为空时自动生成")
private String templateCode;
@Schema(description = "模板名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
@NotEmpty(message = "模板名称不能为空")
private String templateName;
@Schema(description = "模板类型 1-物料产品 2-设备台账 3-关键件 4-模具 5-备件", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "模板类型不能为空")
private Integer templateType;
@Schema(description = "模板JSON内容布局、字段、样式等", requiredMode = Schema.RequiredMode.REQUIRED)
// @NotEmpty(message = "模板JSON内容布局、字段、样式等不能为空")
private String templateJson;
@Schema(description = "备注", example = "你猜")
private String remark;
@Schema(description = "是否启用")
private Boolean isEnable;
}

@ -1,27 +0,0 @@
package cn.iocoder.yudao.module.mes.controller.admin.printtemplate.vo;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum PrintTemplateTypeEnum {
MATERIAL_PRODUCT(1),
EQUIPMENT_LEDGER(2),
KEY_COMPONENT(3),
MOLD(4),
SPARE_PARTS(5);
private final Integer value;
public static PrintTemplateTypeEnum fromValue(int value) {
for (PrintTemplateTypeEnum type : PrintTemplateTypeEnum.values()) {
if (type.getValue() == value) {
return type;
}
}
throw new IllegalArgumentException("Unknown value: " + value);
}
}

@ -1,30 +0,0 @@
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,7 +3,6 @@ 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;
@ -17,12 +16,9 @@ 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;
@ -48,12 +44,6 @@ 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_HOUR_MINUTE_SECOND)
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
private LocalDateTime[] orderDate;
@Schema(description = "交货日期")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
private LocalDateTime[] deliveryDate;
@Schema(description = "状态", example = "2")

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

@ -1,55 +0,0 @@
package cn.iocoder.yudao.module.mes.dal.dataobject.printtemplate;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* DO
*
* @author
*/
@TableName("mes_print_template")
@KeySequence("mes_print_template_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PrintTemplateDO extends BaseDO {
/**
* ID
*/
@TableId
private Long id;
/**
*
*/
private String templateCode;
/**
*
*/
private String templateName;
/**
*
*/
private Integer templateType;
/**
* JSON
*/
private String templateJson;
/**
*
*/
private String remark;
/**
*
*/
private Boolean isEnable;
}

@ -11,7 +11,6 @@ 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
@ -44,8 +43,4 @@ 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);
}

@ -48,5 +48,4 @@ public interface CriticalComponentMapper extends BaseMapperX<CriticalComponentDO
return selectOne(CriticalComponentDO::getCode, code);
}
String selectPrintTemplate();
}

@ -24,7 +24,7 @@ public interface DeviceLedgerMapper extends BaseMapperX<DeviceLedgerDO> {
LambdaQueryWrapperX<DeviceLedgerDO> deviceLedgerDOLambdaQueryWrapperX = new LambdaQueryWrapperX<>();
deviceLedgerDOLambdaQueryWrapperX
.likeIfPresent(DeviceLedgerDO::getDeviceCode, reqVO.getDeviceCode())
.eqIfPresent(DeviceLedgerDO::getDeviceCode, reqVO.getDeviceCode())
.likeIfPresent(DeviceLedgerDO::getDeviceName, reqVO.getDeviceName())
.eqIfPresent(DeviceLedgerDO::getDeviceStatus, reqVO.getDeviceStatus())
.eqIfPresent(DeviceLedgerDO::getDeviceBrand, reqVO.getDeviceBrand())
@ -59,5 +59,4 @@ public interface DeviceLedgerMapper extends BaseMapperX<DeviceLedgerDO> {
DeviceLedgerDO selectByIdWithDeleted(@Param("id") Long id);
String selectPrintTemplate();
}

@ -6,14 +6,9 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.mes.controller.admin.plan.vo.PlanPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.plan.vo.PlanProductCapacityPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.plan.vo.PlanProductCapacityRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.plan.vo.PlanQualityOverviewRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.plan.vo.PlanStatusEnum;
import cn.iocoder.yudao.module.mes.dal.dataobject.plan.PlanDO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
@ -148,19 +143,4 @@ public interface PlanMapper extends BaseMapperX<PlanDO> {
}
List<Map<String, Object>> getLastSevenDaysCompletedCount();
PlanQualityOverviewRespVO selectQualityOverviewSummary(@Param("startTime") LocalDateTime startTime,
@Param("endTime") LocalDateTime endTime);
List<PlanQualityOverviewRespVO.ProductPassRateItem> selectQualityOverviewProductStats(@Param("startTime") LocalDateTime startTime,
@Param("endTime") LocalDateTime endTime);
List<PlanQualityOverviewRespVO.TrendItem> selectQualityOverviewTrendStats(@Param("startTime") LocalDateTime startTime,
@Param("endTime") LocalDateTime endTime);
IPage<PlanProductCapacityRespVO> selectProductCapacityPage(Page<PlanProductCapacityRespVO> page,
@Param("reqVO") PlanProductCapacityPageReqVO reqVO,
@Param("beginTime") LocalDateTime beginTime,
@Param("endTime") LocalDateTime endTime,
@Param("statDays") Integer statDays);
}
}

@ -1,40 +0,0 @@
package cn.iocoder.yudao.module.mes.dal.mysql.printtemplate;
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.mes.dal.dataobject.printtemplate.PrintTemplateDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.mes.controller.admin.printtemplate.vo.*;
/**
* Mapper
*
* @author
*/
@Mapper
public interface PrintTemplateMapper extends BaseMapperX<PrintTemplateDO> {
default PrintTemplateDO selectByNo(String no) {
return selectOne(PrintTemplateDO::getTemplateCode, no);
}
default PrintTemplateDO selectByTemplateType(Integer templateType) {
return selectOne(PrintTemplateDO::getTemplateType, templateType);
}
default PageResult<PrintTemplateDO> selectPage(PrintTemplatePageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<PrintTemplateDO>()
.eqIfPresent(PrintTemplateDO::getTemplateCode, reqVO.getTemplateCode())
.likeIfPresent(PrintTemplateDO::getTemplateName, reqVO.getTemplateName())
.eqIfPresent(PrintTemplateDO::getTemplateType, reqVO.getTemplateType())
.eqIfPresent(PrintTemplateDO::getTemplateJson, reqVO.getTemplateJson())
.eqIfPresent(PrintTemplateDO::getRemark, reqVO.getRemark())
.eqIfPresent(PrintTemplateDO::getIsEnable, reqVO.getIsEnable())
.betweenIfPresent(PrintTemplateDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(PrintTemplateDO::getId));
}
}

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

@ -1,7 +1,6 @@
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;
@ -198,7 +197,6 @@ 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);
@ -206,24 +204,6 @@ 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);
@ -358,9 +338,4 @@ public class CriticalComponentServiceImpl implements CriticalComponentService {
);
}
@Override
public String selectPrintTemplate() {
return criticalComponentMapper.selectPrintTemplate();
}
}
}

@ -47,8 +47,6 @@ public interface DeviceLedgerService {
*/
DeviceLedgerDO getDeviceLedger(Long id);
DeviceLedgerDO getDeviceLedger(Long id, String code);
/**
*
*
@ -57,10 +55,6 @@ public interface DeviceLedgerService {
*/
PageResult<DeviceLedgerDO> getDeviceLedgerPage(DeviceLedgerPageReqVO pageReqVO);
PageResult<DeviceCapacityReportRespVO> getDeviceCapacityReportPage(DeviceCapacityReportPageReqVO pageReqVO);
List<DeviceCapacityReportRespVO> getDeviceCapacityReportList(DeviceCapacityReportPageReqVO pageReqVO);
List<DeviceLedgerDO> getDeviceLedgerList();
/**
* VO
@ -89,8 +83,5 @@ public interface DeviceLedgerService {
Map<Long, DeviceLedgerDO> getDeviceMap(Set<Long> longs);
List<DeviceLedgerDO> getDeviceLedgerListByIds(Collection<Long> ids);
String selectPrintTemplate();
}
}

@ -1,39 +1,42 @@
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;
import cn.iocoder.yudao.module.erp.controller.admin.autocode.util.AutoCodeUtil;
import cn.iocoder.yudao.module.erp.controller.admin.mold.vo.MoldRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldBrandDO;
import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldDO;
import cn.iocoder.yudao.module.common.dal.mysql.mold.MoldMapper;
import cn.iocoder.yudao.module.erp.dal.dataobject.productdevicerel.ProductDeviceRelDO;
import cn.iocoder.yudao.module.erp.dal.mysql.productdevicerel.ProductDeviceRelMapper;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DeviceRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DeviceSaveReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO;
import cn.iocoder.yudao.module.iot.service.device.DeviceService;
import cn.iocoder.yudao.module.iot.service.device.TDengineService;
import cn.iocoder.yudao.module.mes.dal.dataobject.devicetype.DeviceTypeDO;
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.erp.dal.dataobject.product.ErpProductDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO;
import cn.iocoder.yudao.module.common.dal.mysql.mold.MoldMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.devicetype.DeviceTypeMapper;
import cn.iocoder.yudao.module.common.dal.mysql.mold.MoldMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductMapper;
import cn.iocoder.yudao.module.erp.service.product.ErpProductUnitService;
import cn.iocoder.yudao.module.mes.controller.admin.ticketmanagement.enums.PlanTypeEnum;
import cn.iocoder.yudao.module.mes.dal.dataobject.criticalcomponent.CriticalComponentDO;
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.dataobject.ticketresults.TicketResultsDO;
import cn.iocoder.yudao.module.mes.dal.mysql.criticalcomponent.CriticalComponentMapper;
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.producereport.ProduceReportDetailMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.dvrepair.DvRepairLineMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.dvrepair.DvRepairMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.ticketresults.TicketResultsMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.workreportplan.ReportPlanSummaryMapper;
import cn.iocoder.yudao.module.mes.service.organization.OrganizationService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
@ -44,15 +47,9 @@ import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceMapper;
import cn.iocoder.yudao.module.mes.controller.admin.deviceledger.vo.*;
import cn.iocoder.yudao.module.mes.dal.dataobject.deviceledger.DeviceLedgerDO;
@ -63,6 +60,7 @@ import cn.iocoder.yudao.module.mes.dal.mysql.deviceledger.DeviceLedgerMapper;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
/**
@ -100,27 +98,6 @@ public class DeviceLedgerServiceImpl implements DeviceLedgerService {
@Resource
private ProductDeviceRelMapper productDeviceRelMapper;
@Resource
@Lazy
private DeviceMapper deviceMapper;
@Resource
private PlanMapper planMapper;
@Resource
private ProduceReportDetailMapper produceReportDetailMapper;
@Resource
private ReportPlanSummaryMapper reportPlanSummaryMapper;
@Resource
@Lazy
private OrganizationService organizationService;
@Resource
@Lazy
private OrganizationMapper organizationMapper;
@Resource
private ErpProductUnitService productUnitService;
@ -136,9 +113,6 @@ public class DeviceLedgerServiceImpl implements DeviceLedgerService {
@Autowired
private AutoCodeUtil autoCodeUtil;
@Resource
private TDengineService tdengineService;
@Override
public Long createDeviceLedger(DeviceLedgerSaveReqVO createReqVO) throws UnsupportedEncodingException {
DeviceLedgerDO deviceLedger = BeanUtils.toBean(createReqVO, DeviceLedgerDO.class);
@ -233,7 +207,6 @@ public class DeviceLedgerServiceImpl implements DeviceLedgerService {
@Override
public DeviceLedgerDO getDeviceLedger(Long id) {
validateDeviceLedgerExists(id);
DeviceLedgerDO deviceLedgerDO = deviceLedgerMapper.selectById(id);
@ -325,24 +298,6 @@ 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) {
@ -372,171 +327,6 @@ public class DeviceLedgerServiceImpl implements DeviceLedgerService {
return deviceLedgerDOPageResult;
}
@Override
public PageResult<DeviceCapacityReportRespVO> getDeviceCapacityReportPage(DeviceCapacityReportPageReqVO pageReqVO) {
DeviceLedgerPageReqVO queryReqVO = buildDeviceCapacityQuery(pageReqVO);
PageResult<DeviceLedgerDO> pageResult = deviceLedgerMapper.selectPage(queryReqVO);
List<DeviceCapacityReportRespVO> reportList = buildDeviceCapacityReportList(pageResult.getList(),pageReqVO.getBeginTime(), pageReqVO.getEndTime());
return new PageResult<>(reportList, pageResult.getTotal());
}
@Override
public List<DeviceCapacityReportRespVO> getDeviceCapacityReportList(DeviceCapacityReportPageReqVO pageReqVO) {
DeviceLedgerPageReqVO queryReqVO = buildDeviceCapacityQuery(pageReqVO);
List<DeviceLedgerDO> list = deviceLedgerMapper.selectPage(queryReqVO).getList();
return buildDeviceCapacityReportList(list,pageReqVO.getBeginTime(), pageReqVO.getEndTime());
}
private DeviceLedgerPageReqVO buildDeviceCapacityQuery(DeviceCapacityReportPageReqVO pageReqVO) {
DeviceLedgerPageReqVO queryReqVO = new DeviceLedgerPageReqVO();
queryReqVO.setPageNo(pageReqVO.getPageNo());
queryReqVO.setPageSize(pageReqVO.getPageSize());
queryReqVO.setDeviceCode(pageReqVO.getDeviceCode());
queryReqVO.setDeviceName(pageReqVO.getDeviceName());
queryReqVO.setDeviceType(pageReqVO.getDeviceType());
queryReqVO.setDeviceStatus(pageReqVO.getDeviceStatus() == null ? null : String.valueOf(pageReqVO.getDeviceStatus()));
queryReqVO.setWorkshop(pageReqVO.getWorkshop());
queryReqVO.setIds(pageReqVO.getIds());
queryReqVO.setIsScheduled(1);
return queryReqVO;
}
private List<DeviceCapacityReportRespVO> buildDeviceCapacityReportList(List<DeviceLedgerDO> deviceList, LocalDateTime beginTimeParam, LocalDateTime endTimeParam) {
if (CollUtil.isEmpty(deviceList)) {
return Collections.emptyList();
}
Set<Long> deviceIds = deviceList.stream().map(DeviceLedgerDO::getId).filter(Objects::nonNull).collect(Collectors.toSet());
Set<Long> deviceTypeIds = deviceList.stream().map(DeviceLedgerDO::getDeviceType).filter(Objects::nonNull).collect(Collectors.toSet());
Set<Long> workshopIds = deviceList.stream()
.map(DeviceLedgerDO::getWorkshop)
.filter(StringUtils::isNotBlank)
.map(String::trim)
.filter(item -> item.matches("\\d+"))
.map(Long::valueOf)
.collect(Collectors.toSet());
Map<Long, DeviceTypeDO> deviceTypeMap = deviceTypeIds.isEmpty() ? Collections.emptyMap()
: deviceTypeMapper.selectBatchIds(deviceTypeIds).stream()
.collect(Collectors.toMap(DeviceTypeDO::getId, Function.identity(), (a, b) -> a));
Map<Long, OrganizationDO> organizationMap = workshopIds.isEmpty() ? Collections.emptyMap()
: organizationService.getMapWithDeleted(workshopIds);
List<PlanDO> planList = planMapper.selectList(new LambdaQueryWrapperX<PlanDO>()
.in(PlanDO::getDeviceId, deviceIds));
Map<Long, BigDecimal> reportCapacityMap = planList.stream()
.filter(item -> item.getDeviceId() != null)
.collect(Collectors.groupingBy(
PlanDO::getDeviceId,
Collectors.mapping(
item -> BigDecimal.valueOf(Optional.ofNullable(item.getWangongNumber()).orElse(0L)),
Collectors.reducing(BigDecimal.ZERO, BigDecimal::add)
)
));
Map<Long, Long> machineDvMap = organizationMapper.selectList(
new LambdaQueryWrapper<OrganizationDO>()
.in(OrganizationDO::getMachineId, deviceIds)
.select(OrganizationDO::getMachineId, OrganizationDO::getDvId))
.stream()
.filter(item -> item.getMachineId() != null && item.getDvId() != null)
.collect(Collectors.toMap(
OrganizationDO::getMachineId,
OrganizationDO::getDvId,
(a, b) -> a
));
LocalDate endDate = endTimeParam != null
? endTimeParam.toLocalDate()
: LocalDate.now().minusDays(1);
LocalDate startDate = beginTimeParam != null
? beginTimeParam.toLocalDate()
: endDate.minusMonths(6);
List<LocalDate> statDays = listStatDays(startDate, endDate);
Map<Long, Integer> actualCapacityMap = new HashMap<>();
if (CollUtil.isNotEmpty(statDays)) {
LocalDateTime beginTime = statDays.get(0).atStartOfDay();
LocalDateTime endTime = statDays.get(statDays.size() - 1).plusDays(1).atStartOfDay();
Set<Long> collectDeviceIds = deviceMapper.selectList(new LambdaQueryWrapper<DeviceDO>()
.select(DeviceDO::getId))
.stream()
.map(DeviceDO::getId)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
actualCapacityMap = queryDeviceCollectionAverageMap(collectDeviceIds, statDays, beginTime, endTime);
}
List<DeviceCapacityReportRespVO> result = new ArrayList<>();
for (DeviceLedgerDO device : deviceList) {
DeviceCapacityReportRespVO respVO = new DeviceCapacityReportRespVO();
respVO.setId(device.getId());
respVO.setDeviceCode(device.getDeviceCode());
respVO.setDeviceName(device.getDeviceName());
respVO.setDeviceStatus(device.getDeviceStatus());
respVO.setRatedCapacity(BigDecimal.valueOf(Optional.ofNullable(device.getRatedCapacity()).orElse(0)));
MapUtils.findAndThen(deviceTypeMap, device.getDeviceType(), item -> respVO.setTypeName(item.getName()));
if (StringUtils.isNotBlank(device.getWorkshop()) && device.getWorkshop().trim().matches("\\d+")) {
MapUtils.findAndThen(organizationMap, Long.valueOf(device.getWorkshop().trim()), item -> {
String workshopName = item.getName();
if (Boolean.TRUE.equals(item.getDeleted())) {
workshopName += "(已被删除)";
}
respVO.setWorkshopName(workshopName);
});
}
respVO.setReportCapacity(reportCapacityMap.getOrDefault(device.getId(), BigDecimal.ZERO));
Long collectDeviceId = machineDvMap.get(device.getId());
respVO.setActualCapacity(BigDecimal.valueOf(actualCapacityMap.getOrDefault(collectDeviceId, 0)));
result.add(respVO);
}
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) || beginTime == null || endTime == null) {
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) {
List<LocalDate> days = new ArrayList<>();
if (startDate == null || endDate == null || startDate.isAfter(endDate)) {
return days;
}
LocalDate cursor = startDate;
while (!cursor.isAfter(endDate)) {
days.add(cursor);
cursor = cursor.plusDays(1);
}
return days;
}
@Override
public List<DeviceLedgerDO> getDeviceLedgerList() {
return deviceLedgerMapper.selectList();
@ -641,16 +431,4 @@ 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); }
@Override
public String selectPrintTemplate() {
return deviceLedgerMapper.selectPrintTemplate();
}
}
}

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

@ -1,7 +1,6 @@
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;
@ -9,10 +8,8 @@ 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;
@ -47,8 +44,6 @@ public class DvRepairServiceImpl implements DvRepairService {
@Resource
private DvRepairMapper dvRepairMapper;
@Resource
private DeviceLedgerMapper deviceLedgerMapper;
@Resource
private DvRepairLineMapper dvRepairLineMapper;
@Resource
@ -201,13 +196,12 @@ public class DvRepairServiceImpl implements DvRepairService {
}
@Override
public List<DvRepairLineRespVO> getRepairListByDeviceId(Long deviceId, String code, String startTime, String endTime, String ids) {
DeviceLedgerDO deviceLedgerDO = getDeviceByIdOrCode(deviceId, code);
public List<DvRepairLineRespVO> getRepairListByDeviceId(Long deviceId, String startTime, String endTime,String ids) {
List<DvRepairLineRespVO> dvRepairLineRespVOS = new ArrayList<>();
LambdaQueryWrapper<DvRepairDO> wrapper = Wrappers.<DvRepairDO>lambdaQuery()
.eq(DvRepairDO::getDeviceId, deviceLedgerDO.getId());
.eq(DvRepairDO::getDeviceId, deviceId);
@ -276,22 +270,6 @@ 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()
@ -441,4 +419,4 @@ public class DvRepairServiceImpl implements DvRepairService {
dvRepairLineMapper.deleteByRepairId(repairId);
}
}
}

@ -108,9 +108,8 @@ public interface EnergyDeviceService {
List<EnergyDeviceRespVO> queryDataRecords(EnergyDeviceConsumptionReqVO deviceConsumptionReqVO);
EnergyOverviewRespVO queryOverviewData(EnergyOverviewReqVO reqVO);
List<HourEnergyValueVO> lastEnergyStatistics(Long deviceTypeId,Long orgId);
List<DayEnergyValueVO> latestSevenDaysStatistics(Long deviceTypeId, Long orgId);
}
}

@ -630,39 +630,6 @@ public class EnergyDeviceServiceImpl implements EnergyDeviceService {
return result;
}
@Override
public EnergyOverviewRespVO queryOverviewData(EnergyOverviewReqVO reqVO) {
EnergyOverviewRespVO respVO = new EnergyOverviewRespVO();
List<EnergyDeviceDO> devices = queryDevices(null, reqVO.getOrgId(), reqVO.getEnergyTypeId(), null);
if (devices.isEmpty()) {
respVO.setMetrics(buildOverviewMetrics(Collections.emptyList(), Collections.emptyList(), reqVO));
respVO.setTrendChart(buildEmptyTrendChart(reqVO));
respVO.setRegionChart(buildRegionChart(Collections.emptyList()));
respVO.setRankList(Collections.emptyList());
respVO.setTotal(0L);
respVO.setDetailList(Collections.emptyList());
return respVO;
}
EnergyDeviceConsumptionReqVO consumptionReqVO = new EnergyDeviceConsumptionReqVO();
consumptionReqVO.setOrgId(reqVO.getOrgId());
consumptionReqVO.setStartTime(reqVO.getStartTime());
consumptionReqVO.setEndTime(reqVO.getEndTime());
consumptionReqVO.setIds(devices.stream().map(item -> String.valueOf(item.getId())).collect(Collectors.joining(",")));
List<EnergyDeviceRespVO> records = queryDataRecords(consumptionReqVO);
records.sort(Comparator.comparing((EnergyDeviceRespVO item) -> parseEnergyValue(item.getEnergyConsumption())).reversed());
respVO.setMetrics(buildOverviewMetrics(records, devices, reqVO));
respVO.setTrendChart(buildTrendChart(devices, reqVO));
respVO.setRegionChart(buildRegionChart(records));
respVO.setRankList(buildRankList(records));
respVO.setTotal((long) records.size());
respVO.setDetailList(paginateDetails(records, devices, reqVO));
return respVO;
}
private Map<Long, TimePointCache> buildCacheFromRow(
List<EnergyDeviceDO> devices,
Map<Long, Map<String, Object>> rowMap,
@ -752,353 +719,19 @@ public class EnergyDeviceServiceImpl implements EnergyDeviceService {
/** 查询设备列表 */
private List<EnergyDeviceDO> queryDevices(EnergyDeviceConsumptionReqVO req) {
return queryDevices(req.getName(), req.getOrgId(), null, req.getIds());
}
private List<EnergyDeviceDO> queryDevices(String name, Long orgId, Long deviceTypeId, String ids) {
return energyDeviceMapper.selectList(
Wrappers.<EnergyDeviceDO>lambdaQuery()
.in(StringUtils.isNotBlank(ids),
.in(StringUtils.isNotBlank(req.getIds()),
EnergyDeviceDO::getId,
StringUtils.isNotBlank(ids)
? Arrays.asList(ids.split(","))
StringUtils.isNotBlank(req.getIds())
? Arrays.asList(req.getIds().split(","))
: null)
.like(StringUtils.isNotBlank(name), EnergyDeviceDO::getName, name)
.eq(orgId != null, EnergyDeviceDO::getOrgId, orgId)
.eq(deviceTypeId != null, EnergyDeviceDO::getDeviceTypeId, deviceTypeId)
.like(StringUtils.isNotBlank(req.getName()), EnergyDeviceDO::getName, req.getName())
.eq(req.getOrgId() != null, EnergyDeviceDO::getOrgId, req.getOrgId())
.orderByDesc(EnergyDeviceDO::getCreateTime)
);
}
private List<EnergyOverviewRespVO.MetricItem> buildOverviewMetrics(List<EnergyDeviceRespVO> records,
List<EnergyDeviceDO> devices,
EnergyOverviewReqVO reqVO) {
double totalValue = records.stream().mapToDouble(item -> parseEnergyValue(item.getEnergyConsumption())).sum();
EnergyDeviceRespVO topRecord = records.stream().findFirst().orElse(null);
Map<String, Double> regionTotals = new LinkedHashMap<>();
for (EnergyDeviceRespVO record : records) {
regionTotals.merge(StringUtils.defaultIfBlank(record.getOrgName(), "-"),
parseEnergyValue(record.getEnergyConsumption()), Double::sum);
}
Map.Entry<String, Double> maxRegion = regionTotals.entrySet().stream()
.max(Map.Entry.comparingByValue())
.orElse(null);
List<EnergyOverviewRespVO.MetricItem> metrics = new ArrayList<>();
metrics.add(buildMetric("total", "总用量", formatDouble(totalValue), "", "设备数", String.valueOf(devices.size()), null, null));
metrics.add(buildMetric("deviceCount", "统计设备", String.valueOf(records.size()), "台", "区域数", String.valueOf(regionTotals.size()), null, null));
metrics.add(buildMetric("topDevice", "最高能耗设备",
topRecord != null ? topRecord.getName() : "-",
"",
"用量",
topRecord != null ? formatDouble(parseEnergyValue(topRecord.getEnergyConsumption())) : "0",
null,
null));
metrics.add(buildMetric("topRegion", "最高能耗区域",
maxRegion != null ? maxRegion.getKey() : "-",
"",
"用量",
maxRegion != null ? formatDouble(maxRegion.getValue()) : "0",
null,
null));
metrics.add(buildMetric("range", "统计时段",
buildRangeLabel(reqVO),
"",
"开始",
StringUtils.defaultIfBlank(reqVO.getStartTime(), "-"),
null,
null));
return metrics;
}
private EnergyOverviewRespVO.MetricItem buildMetric(String key, String label, String value, String unit,
String subLabel, String subValue, String change, Boolean down) {
EnergyOverviewRespVO.MetricItem item = new EnergyOverviewRespVO.MetricItem();
item.setKey(key);
item.setLabel(label);
item.setValue(value);
item.setUnit(unit);
item.setSubLabel(subLabel);
item.setSubValue(subValue);
item.setChange(change);
item.setDown(down);
return item;
}
private EnergyOverviewRespVO.TrendChart buildTrendChart(List<EnergyDeviceDO> devices, EnergyOverviewReqVO reqVO) {
EnergyOverviewRespVO.TrendChart chart = new EnergyOverviewRespVO.TrendChart();
chart.setUnit("");
if (StringUtils.isBlank(reqVO.getStartTime()) || StringUtils.isBlank(reqVO.getEndTime())) {
chart.setXAxis(Collections.emptyList());
chart.setData(Collections.emptyList());
return chart;
}
try {
LocalDateTime start = LocalDateTime.parse(reqVO.getStartTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LocalDateTime end = LocalDateTime.parse(reqVO.getEndTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
Map<Long, List<OperationRulesVO>> deviceRulesMap = buildDeviceRulesMap(devices);
Set<Long> sourceDeviceIds = collectRuleDeviceIds(deviceRulesMap);
Map<Long, DeviceContactModelDO> pointInfoMap = batchGetPointInfoFromLocalDB(new ArrayList<>(collectPointIds(deviceRulesMap)));
if (sourceDeviceIds.isEmpty()) {
chart.setXAxis(Collections.emptyList());
chart.setData(Collections.emptyList());
return chart;
}
boolean sameDay = start.toLocalDate().equals(end.toLocalDate()) && !start.equals(end);
if (sameDay) {
return buildHourTrendChart(chart, deviceRulesMap, sourceDeviceIds, pointInfoMap, start, end);
}
return buildDayTrendChart(chart, deviceRulesMap, sourceDeviceIds, pointInfoMap, start.toLocalDate(), end.toLocalDate());
} catch (Exception e) {
log.warn("构建能源总览趋势数据失败, req={}", reqVO, e);
chart.setXAxis(Collections.emptyList());
chart.setData(Collections.emptyList());
return chart;
}
}
private EnergyOverviewRespVO.TrendChart buildHourTrendChart(EnergyOverviewRespVO.TrendChart chart,
Map<Long, List<OperationRulesVO>> deviceRulesMap,
Set<Long> sourceDeviceIds,
Map<Long, DeviceContactModelDO> pointInfoMap,
LocalDateTime start,
LocalDateTime end) {
DateTimeFormatter hourKeyFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH");
DateTimeFormatter displayFormatter = DateTimeFormatter.ofPattern("HH:00");
List<Map<String, Object>> allRows = tDengineService.newQueryLastDataByHourBatch(sourceDeviceIds, start, end);
Map<String, Map<Long, TimePointCache>> hourCacheMap = buildTimeCacheByHour(allRows, pointInfoMap, deviceRulesMap);
List<String> xAxis = new ArrayList<>();
List<String> data = new ArrayList<>();
LocalDateTime cursor = start.withMinute(0).withSecond(0);
LocalDateTime limit = end.withMinute(0).withSecond(0);
while (!cursor.isAfter(limit)) {
String hourKey = cursor.format(hourKeyFormatter);
double total = sumGroupedEnergy(deviceRulesMap, hourCacheMap.getOrDefault(hourKey, Collections.emptyMap()));
xAxis.add(cursor.format(displayFormatter));
data.add(formatDouble(total));
cursor = cursor.plusHours(1);
}
chart.setXAxis(xAxis);
chart.setData(data);
return chart;
}
private EnergyOverviewRespVO.TrendChart buildDayTrendChart(EnergyOverviewRespVO.TrendChart chart,
Map<Long, List<OperationRulesVO>> deviceRulesMap,
Set<Long> sourceDeviceIds,
Map<Long, DeviceContactModelDO> pointInfoMap,
LocalDate startDate,
LocalDate endDate) {
int days = (int) (endDate.toEpochDay() - startDate.toEpochDay()) + 1;
List<Map<String, Object>> allRows = tDengineService.queryLastDataByDayBatch(sourceDeviceIds, startDate, days);
Map<String, Map<Long, TimePointCache>> dayCacheMap = buildTimeCacheByDay(allRows, pointInfoMap, deviceRulesMap);
List<String> xAxis = new ArrayList<>();
List<String> data = new ArrayList<>();
LocalDate cursor = startDate;
while (!cursor.isAfter(endDate)) {
String dayKey = cursor.toString();
double total = sumGroupedEnergy(deviceRulesMap, dayCacheMap.getOrDefault(dayKey, Collections.emptyMap()));
xAxis.add(dayKey);
data.add(formatDouble(total));
cursor = cursor.plusDays(1);
}
chart.setXAxis(xAxis);
chart.setData(data);
return chart;
}
private Map<String, Map<Long, TimePointCache>> buildTimeCacheByHour(List<Map<String, Object>> allRows,
Map<Long, DeviceContactModelDO> pointInfoMap,
Map<Long, List<OperationRulesVO>> deviceRulesMap) {
Map<String, Map<Long, TimePointCache>> cacheMap = new LinkedHashMap<>();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH");
for (Map<String, Object> row : allRows) {
LocalDateTime ts = (LocalDateTime) row.get("timestamp");
Long deviceId = (Long) row.get("deviceId");
if (ts == null || deviceId == null) {
continue;
}
String key = ts.format(formatter);
cacheMap.computeIfAbsent(key, item -> new HashMap<>()).put(deviceId,
buildTimePointCache(deviceId, ts, row, pointInfoMap, deviceRulesMap));
}
return cacheMap;
}
private Map<String, Map<Long, TimePointCache>> buildTimeCacheByDay(List<Map<String, Object>> allRows,
Map<Long, DeviceContactModelDO> pointInfoMap,
Map<Long, List<OperationRulesVO>> deviceRulesMap) {
Map<String, Map<Long, TimePointCache>> cacheMap = new LinkedHashMap<>();
for (Map<String, Object> row : allRows) {
String dayKey = (String) row.get("day");
LocalDateTime ts = (LocalDateTime) row.get("timestamp");
Long deviceId = (Long) row.get("deviceId");
if (StringUtils.isBlank(dayKey) || ts == null || deviceId == null) {
continue;
}
cacheMap.computeIfAbsent(dayKey, item -> new HashMap<>()).put(deviceId,
buildTimePointCache(deviceId, ts, row, pointInfoMap, deviceRulesMap));
}
return cacheMap;
}
private TimePointCache buildTimePointCache(Long deviceId,
LocalDateTime ts,
Map<String, Object> row,
Map<Long, DeviceContactModelDO> pointInfoMap,
Map<Long, List<OperationRulesVO>> deviceRulesMap) {
TimePointCache cache = new TimePointCache();
cache.setTimestamp(ts);
Map<Long, Double> pointValueMap = new HashMap<>();
List<OperationRulesVO> rules = deviceRulesMap.values().stream()
.flatMap(List::stream)
.filter(item -> deviceId.equals(item.getDeviceId()))
.collect(Collectors.toList());
for (OperationRulesVO rule : rules) {
DeviceContactModelDO pointInfo = pointInfoMap.get(rule.getPointId());
if (pointInfo == null || StringUtils.isBlank(pointInfo.getAttributeCode())) {
continue;
}
Object value = row.get(pointInfo.getAttributeCode().toLowerCase());
if (value == null) {
continue;
}
try {
pointValueMap.put(rule.getPointId(), new BigDecimal(value.toString()).setScale(2, RoundingMode.HALF_UP).doubleValue());
} catch (Exception e) {
log.warn("解析趋势点位值失败, deviceId={}, pointId={}, value={}", deviceId, rule.getPointId(), value, e);
}
}
cache.setPointValueMap(pointValueMap);
return cache;
}
private double sumGroupedEnergy(Map<Long, List<OperationRulesVO>> deviceRulesMap, Map<Long, TimePointCache> cacheMap) {
double total = 0D;
for (Map.Entry<Long, List<OperationRulesVO>> entry : deviceRulesMap.entrySet()) {
total += calculateByRules(entry.getKey(), entry.getValue(), cacheMap);
}
return total;
}
private EnergyOverviewRespVO.TrendChart buildEmptyTrendChart(EnergyOverviewReqVO reqVO) {
EnergyOverviewRespVO.TrendChart chart = new EnergyOverviewRespVO.TrendChart();
chart.setUnit("");
chart.setXAxis(Collections.emptyList());
chart.setData(Collections.emptyList());
return chart;
}
private EnergyOverviewRespVO.RegionChart buildRegionChart(List<EnergyDeviceRespVO> records) {
EnergyOverviewRespVO.RegionChart chart = new EnergyOverviewRespVO.RegionChart();
chart.setUnit("");
Map<String, Double> regionMap = new LinkedHashMap<>();
double total = 0D;
for (EnergyDeviceRespVO record : records) {
double value = parseEnergyValue(record.getEnergyConsumption());
total += value;
regionMap.merge(StringUtils.defaultIfBlank(record.getOrgName(), "-"), value, Double::sum);
}
List<EnergyOverviewRespVO.RegionItem> items = new ArrayList<>();
for (Map.Entry<String, Double> entry : regionMap.entrySet()) {
EnergyOverviewRespVO.RegionItem item = new EnergyOverviewRespVO.RegionItem();
item.setName(entry.getKey());
item.setValue(formatDouble(entry.getValue()));
item.setPercent(total <= 0 ? "0" : formatDouble(entry.getValue() * 100 / total));
items.add(item);
}
items.sort(Comparator.comparing((EnergyOverviewRespVO.RegionItem item) -> parseEnergyValue(item.getValue())).reversed());
chart.setTotalValue(formatDouble(total));
chart.setItems(items);
return chart;
}
private List<EnergyOverviewRespVO.RankItem> buildRankList(List<EnergyDeviceRespVO> records) {
return records.stream().limit(5).map(item -> {
EnergyOverviewRespVO.RankItem rankItem = new EnergyOverviewRespVO.RankItem();
rankItem.setId(item.getId());
rankItem.setName(item.getName());
rankItem.setRegion(item.getOrgName());
rankItem.setValue(item.getEnergyConsumption());
return rankItem;
}).collect(Collectors.toList());
}
private List<EnergyOverviewRespVO.DetailItem> paginateDetails(List<EnergyDeviceRespVO> records,
List<EnergyDeviceDO> devices,
EnergyOverviewReqVO reqVO) {
Map<Long, EnergyDeviceDO> deviceMap = devices.stream().collect(Collectors.toMap(EnergyDeviceDO::getId, Function.identity(), (a, b) -> a));
int pageNo = reqVO.getPageNo() == null || reqVO.getPageNo() < 1 ? 1 : reqVO.getPageNo();
int pageSize = reqVO.getPageSize() == null || reqVO.getPageSize() < 1 ? 10 : reqVO.getPageSize();
int fromIndex = Math.min((pageNo - 1) * pageSize, records.size());
int toIndex = Math.min(fromIndex + pageSize, records.size());
List<EnergyOverviewRespVO.DetailItem> details = new ArrayList<>();
for (EnergyDeviceRespVO item : records.subList(fromIndex, toIndex)) {
EnergyOverviewRespVO.DetailItem detailItem = new EnergyOverviewRespVO.DetailItem();
detailItem.setId(item.getId());
detailItem.setName(item.getName());
detailItem.setEnergyType(Optional.ofNullable(deviceMap.get(item.getId())).map(EnergyDeviceDO::getDeviceTypeName).orElse(item.getDeviceTypeName()));
detailItem.setRegion(item.getOrgName());
detailItem.setValue(item.getEnergyConsumption());
detailItem.setStartTime(reqVO.getStartTime());
detailItem.setEndTime(reqVO.getEndTime());
details.add(detailItem);
}
return details;
}
private Map<Long, List<OperationRulesVO>> buildDeviceRulesMap(List<EnergyDeviceDO> devices) {
Map<Long, List<OperationRulesVO>> result = new LinkedHashMap<>();
for (EnergyDeviceDO device : devices) {
List<OperationRulesVO> rules = parseRules(device);
if (!rules.isEmpty()) {
result.put(device.getId(), rules);
}
}
return result;
}
private Set<Long> collectRuleDeviceIds(Map<Long, List<OperationRulesVO>> deviceRulesMap) {
return deviceRulesMap.values().stream()
.flatMap(List::stream)
.map(OperationRulesVO::getDeviceId)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
}
private Set<Long> collectPointIds(Map<Long, List<OperationRulesVO>> deviceRulesMap) {
return deviceRulesMap.values().stream()
.flatMap(List::stream)
.map(OperationRulesVO::getPointId)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
}
private String buildRangeLabel(EnergyOverviewReqVO reqVO) {
if (StringUtils.isBlank(reqVO.getStartTime()) || StringUtils.isBlank(reqVO.getEndTime())) {
return "-";
}
return reqVO.getStartTime() + " ~ " + reqVO.getEndTime();
}
private double parseEnergyValue(String value) {
if (StringUtils.isBlank(value)) {
return 0D;
}
try {
return Double.parseDouble(value.replace(",", ""));
} catch (Exception e) {
return 0D;
}
}
/** 解析设备规则 */
private List<OperationRulesVO> parseRules(EnergyDeviceDO device) {
if (device == null || StringUtils.isBlank(device.getRules())) return Collections.emptyList();
@ -1336,4 +969,4 @@ public class EnergyDeviceServiceImpl implements EnergyDeviceService {
}
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save