diff --git a/pom.xml b/pom.xml index ceefaaf86..dd007f4d2 100644 --- a/pom.xml +++ b/pom.xml @@ -24,6 +24,7 @@ yudao-module-crm yudao-module-erp yudao-module-mes + yudao-module-iot ${project.artifactId} diff --git a/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java b/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java index 1acd4d78b..afbcc133e 100644 --- a/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java +++ b/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java @@ -10,6 +10,17 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode; public interface ErrorCodeConstants { // ========== GoView 模块 1-003-000-000 ========== - ErrorCode GO_VIEW_PROJECT_NOT_EXISTS = new ErrorCode(1_003_000_000, "GoView 项目不存在"); + ErrorCode DEVICE_NOT_EXISTS = new ErrorCode(1_003_000_000, "设备不存在"); + ErrorCode DEVICE_ATTRIBUTE_NOT_EXISTS = new ErrorCode(1_003_000_000, "设备属性不存在"); + ErrorCode FORMULA_NOT_EXISTS = new ErrorCode(1_003_000_000, "公式不存在"); + ErrorCode FORMULA_DETAIL_NOT_EXISTS = new ErrorCode(1_003_000_000, "公式明细不存在"); + ErrorCode GATEWAY_NOT_EXISTS = new ErrorCode(1_003_000_000, "网关不存在"); + ErrorCode KANBAN_NOT_EXISTS = new ErrorCode(1_003_000_000, "看板不存在"); + ErrorCode ORGANIZATION_EXITS_CHILDREN = new ErrorCode(1_003_000_000, "GoView 项目不存在"); + ErrorCode ORGANIZATION_NOT_EXISTS = new ErrorCode(1_003_000_000, "GoView 项目不存在"); + ErrorCode ORGANIZATION_PARENT_ERROR = new ErrorCode(1_003_000_000, "GoView 项目不存在"); + ErrorCode ORGANIZATION_PARENT_NOT_EXITS = new ErrorCode(1_003_000_000, "GoView 项目不存在"); + ErrorCode ORGANIZATION_PARENT_IS_CHILD = new ErrorCode(1_003_000_000, "GoView 项目不存在"); + ErrorCode ORGANIZATION_NAME_DUPLICATE = new ErrorCode(1_003_000_000, "GoView 项目不存在"); } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/DeviceController.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/DeviceController.java new file mode 100644 index 000000000..f6b59df8e --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/DeviceController.java @@ -0,0 +1,138 @@ +package cn.iocoder.yudao.module.iot.controller.admin.device; + +import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO; +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 javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +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.iot.controller.admin.device.vo.*; +import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceAttributeDO; +import cn.iocoder.yudao.module.iot.service.device.DeviceService; + +@Tag(name = "管理后台 - 物联设备") +@RestController +@RequestMapping("/iot/device") +@Validated +public class DeviceController { + + @Resource + private DeviceService deviceService; + + @PostMapping("/create") + @Operation(summary = "创建物联设备") + @PreAuthorize("@ss.hasPermission('iot:device:create')") + public CommonResult createDevice(@Valid @RequestBody DeviceSaveReqVO createReqVO) { + return success(deviceService.createDevice(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新物联设备") + @PreAuthorize("@ss.hasPermission('iot:device:update')") + public CommonResult updateDevice(@Valid @RequestBody DeviceSaveReqVO updateReqVO) { + deviceService.updateDevice(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除物联设备") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('iot:device:delete')") + public CommonResult deleteDevice(@RequestParam("id") Long id) { + deviceService.deleteDevice(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得物联设备") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('iot:device:query')") + public CommonResult getDevice(@RequestParam("id") Long id) { + DeviceDO device = deviceService.getDevice(id); + return success(BeanUtils.toBean(device, DeviceRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得物联设备分页") + @PreAuthorize("@ss.hasPermission('iot:device:query')") + public CommonResult> getDevicePage(@Valid DevicePageReqVO pageReqVO) { + PageResult pageResult = deviceService.getDevicePage(pageReqVO); + return success(BeanUtils.toBean(pageResult, DeviceRespVO.class)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出物联设备 Excel") + @PreAuthorize("@ss.hasPermission('iot:device:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportDeviceExcel(@Valid DevicePageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = deviceService.getDevicePage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "物联设备.xls", "数据", DeviceRespVO.class, + BeanUtils.toBean(list, DeviceRespVO.class)); + } + + // ==================== 子表(设备属性) ==================== + + @GetMapping("/device-attribute/page") + @Operation(summary = "获得设备属性分页") + @Parameter(name = "deviceId", description = "设备id") + @PreAuthorize("@ss.hasPermission('iot:device:query')") + public CommonResult> getDeviceAttributePage(PageParam pageReqVO, + @RequestParam("deviceId") Long deviceId) { + return success(deviceService.getDeviceAttributePage(pageReqVO, deviceId)); + } + + @PostMapping("/device-attribute/create") + @Operation(summary = "创建设备属性") + @PreAuthorize("@ss.hasPermission('iot:device:create')") + public CommonResult createDeviceAttribute(@Valid @RequestBody DeviceAttributeDO deviceAttribute) { + return success(deviceService.createDeviceAttribute(deviceAttribute)); + } + + @PutMapping("/device-attribute/update") + @Operation(summary = "更新设备属性") + @PreAuthorize("@ss.hasPermission('iot:device:update')") + public CommonResult updateDeviceAttribute(@Valid @RequestBody DeviceAttributeDO deviceAttribute) { + deviceService.updateDeviceAttribute(deviceAttribute); + return success(true); + } + + @DeleteMapping("/device-attribute/delete") + @Parameter(name = "id", description = "编号", required = true) + @Operation(summary = "删除设备属性") + @PreAuthorize("@ss.hasPermission('iot:device:delete')") + public CommonResult deleteDeviceAttribute(@RequestParam("id") Long id) { + deviceService.deleteDeviceAttribute(id); + return success(true); + } + + @GetMapping("/device-attribute/get") + @Operation(summary = "获得设备属性") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('iot:device:query')") + public CommonResult getDeviceAttribute(@RequestParam("id") Long id) { + return success(deviceService.getDeviceAttribute(id)); + } + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/DevicePageReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/DevicePageReqVO.java new file mode 100644 index 000000000..741c8c931 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/DevicePageReqVO.java @@ -0,0 +1,103 @@ +package cn.iocoder.yudao.module.iot.controller.admin.device.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 DevicePageReqVO extends PageParam { + + @Schema(description = "设备配置id", example = "14050") + private String deviceConfigId; + + @Schema(description = "设备编号") + private String deviceCode; + + @Schema(description = "设备名称", example = "李四") + private String deviceName; + + @Schema(description = "设备类型", example = "2") + private String deviceType; + + @Schema(description = "Siemens系列(S7-300、S7-1500)") + private String siemensSeries; + + @Schema(description = "连接参数(波特率,数据位,停止位,校验位 例如:9600,8,1,N)") + private String siemensConnectParam; + + @Schema(description = "读取任务方式(0无,1有)", example = "2") + private String readCronType; + + @Schema(description = "读取任务时间间隔") + private Integer readRepeatValue; + + @Schema(description = "读取任务时间间隔单位") + private String readRepeatUnit; + + @Schema(description = "读取任务时间表达式") + private String readCron; + + @Schema(description = "写入任务时间间隔", example = "1") + private String writeCronType; + + @Schema(description = "写入任务时间间隔") + private Integer writeRepeatValue; + + @Schema(description = "写入任务时间间隔单位") + private String writeRepeatUnit; + + @Schema(description = "写入任务时间表达式") + private String writeCron; + + @Schema(description = "是否持久化(0不持久化,1持久化)") + private String localPersistent; + + @Schema(description = "上传方式(1实时,2自定义)") + private String uploadRate; + + @Schema(description = "上传频率", example = "19796") + private Integer rateCount; + + @Schema(description = "modbus协议类型(serial-rtu)") + private String modbusProtocol; + + @Schema(description = "modbus模式(client)") + private String modbusPattern; + + @Schema(description = "modbus串口号", example = "李四") + private String portName; + + @Schema(description = "连接参数(波特率,数据位,停止位,校验位 例如:9600,8,1,N)") + private String modbusConnectParam; + + @Schema(description = "读地址是否连续(0否,1是)") + private String modbusReadAddrGap; + + @Schema(description = "是否已下发(0下,1没下)") + private String isUpload; + + @Schema(description = "网关id", example = "6304") + private Long gatewayId; + + @Schema(description = "组织设备id", example = "23150") + private Long orgId; + + @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; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/DeviceRespVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/DeviceRespVO.java new file mode 100644 index 000000000..22cb56850 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/DeviceRespVO.java @@ -0,0 +1,144 @@ +package cn.iocoder.yudao.module.iot.controller.admin.device.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.util.*; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; +import com.alibaba.excel.annotation.*; +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; + +@Schema(description = "管理后台 - 物联设备 Response VO") +@Data +@ExcelIgnoreUnannotated +public class DeviceRespVO { + + @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "8540") + @ExcelProperty("ID") + private Long id; + + @Schema(description = "设备配置id", example = "14050") + @ExcelProperty("设备配置id") + private String deviceConfigId; + + @Schema(description = "设备编号") + @ExcelProperty("设备编号") + private String deviceCode; + + @Schema(description = "设备名称", example = "李四") + @ExcelProperty("设备名称") + private String deviceName; + + @Schema(description = "设备类型", example = "2") + @ExcelProperty("设备类型") + private String deviceType; + + @Schema(description = "Siemens系列(S7-300、S7-1500)") + @ExcelProperty(value = "Siemens系列(S7-300、S7-1500)", converter = DictConvert.class) + @DictFormat("iot_siemens_type") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 + private String siemensSeries; + + @Schema(description = "连接参数(波特率,数据位,停止位,校验位 例如:9600,8,1,N)") + @ExcelProperty("连接参数(波特率,数据位,停止位,校验位 例如:9600,8,1,N)") + private String siemensConnectParam; + + @Schema(description = "读取任务方式(0无,1有)", example = "2") + @ExcelProperty(value = "读取任务方式(0无,1有)", converter = DictConvert.class) + @DictFormat("iot_1_or_0") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 + private String readCronType; + + @Schema(description = "读取任务时间间隔") + @ExcelProperty("读取任务时间间隔") + private Integer readRepeatValue; + + @Schema(description = "读取任务时间间隔单位") + @ExcelProperty(value = "读取任务时间间隔单位", converter = DictConvert.class) + @DictFormat("iot_device_data_unit") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 + private String readRepeatUnit; + + @Schema(description = "读取任务时间表达式") + @ExcelProperty("读取任务时间表达式") + private String readCron; + + @Schema(description = "写入任务时间间隔", example = "1") + @ExcelProperty("写入任务时间间隔") + private String writeCronType; + + @Schema(description = "写入任务时间间隔") + @ExcelProperty("写入任务时间间隔") + private Integer writeRepeatValue; + + @Schema(description = "写入任务时间间隔单位") + @ExcelProperty("写入任务时间间隔单位") + private String writeRepeatUnit; + + @Schema(description = "写入任务时间表达式") + @ExcelProperty("写入任务时间表达式") + private String writeCron; + + @Schema(description = "是否持久化(0不持久化,1持久化)") + @ExcelProperty(value = "是否持久化(0不持久化,1持久化)", converter = DictConvert.class) + @DictFormat("iot_1_or_0") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 + private String localPersistent; + + @Schema(description = "上传方式(1实时,2自定义)") + @ExcelProperty(value = "上传方式(1实时,2自定义)", converter = DictConvert.class) + @DictFormat("iot_device_uploading_type") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 + private String uploadRate; + + @Schema(description = "上传频率", example = "19796") + @ExcelProperty("上传频率") + private Integer rateCount; + + @Schema(description = "modbus协议类型(serial-rtu)") + @ExcelProperty(value = "modbus协议类型(serial-rtu)", converter = DictConvert.class) + @DictFormat("iot_modbus_type") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 + private String modbusProtocol; + + @Schema(description = "modbus模式(client)") + @ExcelProperty(value = "modbus模式(client)", converter = DictConvert.class) + @DictFormat("iot_modbus_mold") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 + private String modbusPattern; + + @Schema(description = "modbus串口号", example = "李四") + @ExcelProperty(value = "modbus串口号", converter = DictConvert.class) + @DictFormat("iot_modbus_port") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 + private String portName; + + @Schema(description = "连接参数(波特率,数据位,停止位,校验位 例如:9600,8,1,N)") + @ExcelProperty("连接参数(波特率,数据位,停止位,校验位 例如:9600,8,1,N)") + private String modbusConnectParam; + + @Schema(description = "读地址是否连续(0否,1是)") + @ExcelProperty(value = "读地址是否连续(0否,1是)", converter = DictConvert.class) + @DictFormat("iot_1_or_0") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 + private String modbusReadAddrGap; + + @Schema(description = "是否已下发(0下,1没下)") + @ExcelProperty(value = "是否已下发(0下,1没下)", converter = DictConvert.class) + @DictFormat("iot_1_or_0") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 + private String isUpload; + + @Schema(description = "网关id", requiredMode = Schema.RequiredMode.REQUIRED, example = "6304") + @ExcelProperty("网关id") + private Long gatewayId; + + @Schema(description = "组织设备id", requiredMode = Schema.RequiredMode.REQUIRED, example = "23150") + @ExcelProperty("组织设备id") + private Long orgId; + + @Schema(description = "备注", example = "你猜") + @ExcelProperty("备注") + private String remark; + + @Schema(description = "是否启用", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("是否启用") + private Boolean isEnable; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/DeviceSaveReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/DeviceSaveReqVO.java new file mode 100644 index 000000000..6a8fbae18 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/DeviceSaveReqVO.java @@ -0,0 +1,99 @@ +package cn.iocoder.yudao.module.iot.controller.admin.device.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - 物联设备新增/修改 Request VO") +@Data +public class DeviceSaveReqVO { + + @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "8540") + private Long id; + + @Schema(description = "设备配置id", example = "14050") + private String deviceConfigId; + + @Schema(description = "设备编号") + private String deviceCode; + + @Schema(description = "设备名称", example = "李四") + private String deviceName; + + @Schema(description = "设备类型", example = "2") + private String deviceType; + + @Schema(description = "Siemens系列(S7-300、S7-1500)") + private String siemensSeries; + + @Schema(description = "连接参数(波特率,数据位,停止位,校验位 例如:9600,8,1,N)") + private String siemensConnectParam; + + @Schema(description = "读取任务方式(0无,1有)", example = "2") + private String readCronType; + + @Schema(description = "读取任务时间间隔") + private Integer readRepeatValue; + + @Schema(description = "读取任务时间间隔单位") + private String readRepeatUnit; + + @Schema(description = "读取任务时间表达式") + private String readCron; + + @Schema(description = "写入任务时间间隔", example = "1") + private String writeCronType; + + @Schema(description = "写入任务时间间隔") + private Integer writeRepeatValue; + + @Schema(description = "写入任务时间间隔单位") + private String writeRepeatUnit; + + @Schema(description = "写入任务时间表达式") + private String writeCron; + + @Schema(description = "是否持久化(0不持久化,1持久化)") + private String localPersistent; + + @Schema(description = "上传方式(1实时,2自定义)") + private String uploadRate; + + @Schema(description = "上传频率", example = "19796") + private Integer rateCount; + + @Schema(description = "modbus协议类型(serial-rtu)") + private String modbusProtocol; + + @Schema(description = "modbus模式(client)") + private String modbusPattern; + + @Schema(description = "modbus串口号", example = "李四") + private String portName; + + @Schema(description = "连接参数(波特率,数据位,停止位,校验位 例如:9600,8,1,N)") + private String modbusConnectParam; + + @Schema(description = "读地址是否连续(0否,1是)") + private String modbusReadAddrGap; + + @Schema(description = "是否已下发(0下,1没下)") + private String isUpload; + + @Schema(description = "网关id", requiredMode = Schema.RequiredMode.REQUIRED, example = "6304") + @NotNull(message = "网关id不能为空") + private Long gatewayId; + + @Schema(description = "组织设备id", requiredMode = Schema.RequiredMode.REQUIRED, example = "23150") + @NotNull(message = "组织设备id不能为空") + private Long orgId; + + @Schema(description = "备注", example = "你猜") + private String remark; + + @Schema(description = "是否启用", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "是否启用不能为空") + private Boolean isEnable; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/formula/FormulaController.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/formula/FormulaController.java new file mode 100644 index 000000000..daf75f696 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/formula/FormulaController.java @@ -0,0 +1,138 @@ +package cn.iocoder.yudao.module.iot.controller.admin.formula; + +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 javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +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.iot.controller.admin.formula.vo.*; +import cn.iocoder.yudao.module.iot.dal.dataobject.formula.FormulaDO; +import cn.iocoder.yudao.module.iot.dal.dataobject.formula.FormulaDetailDO; +import cn.iocoder.yudao.module.iot.service.formula.FormulaService; + +@Tag(name = "管理后台 - 计算公式") +@RestController +@RequestMapping("/iot/formula") +@Validated +public class FormulaController { + + @Resource + private FormulaService formulaService; + + @PostMapping("/create") + @Operation(summary = "创建计算公式") + @PreAuthorize("@ss.hasPermission('iot:formula:create')") + public CommonResult createFormula(@Valid @RequestBody FormulaSaveReqVO createReqVO) { + return success(formulaService.createFormula(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新计算公式") + @PreAuthorize("@ss.hasPermission('iot:formula:update')") + public CommonResult updateFormula(@Valid @RequestBody FormulaSaveReqVO updateReqVO) { + formulaService.updateFormula(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除计算公式") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('iot:formula:delete')") + public CommonResult deleteFormula(@RequestParam("id") Long id) { + formulaService.deleteFormula(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得计算公式") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('iot:formula:query')") + public CommonResult getFormula(@RequestParam("id") Long id) { + FormulaDO formula = formulaService.getFormula(id); + return success(BeanUtils.toBean(formula, FormulaRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得计算公式分页") + @PreAuthorize("@ss.hasPermission('iot:formula:query')") + public CommonResult> getFormulaPage(@Valid FormulaPageReqVO pageReqVO) { + PageResult pageResult = formulaService.getFormulaPage(pageReqVO); + return success(BeanUtils.toBean(pageResult, FormulaRespVO.class)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出计算公式 Excel") + @PreAuthorize("@ss.hasPermission('iot:formula:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportFormulaExcel(@Valid FormulaPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = formulaService.getFormulaPage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "计算公式.xls", "数据", FormulaRespVO.class, + BeanUtils.toBean(list, FormulaRespVO.class)); + } + + // ==================== 子表(计算公式明细) ==================== + + @GetMapping("/formula-detail/page") + @Operation(summary = "获得计算公式明细分页") + @Parameter(name = "formulaId", description = "计算公式ID") + @PreAuthorize("@ss.hasPermission('iot:formula:query')") + public CommonResult> getFormulaDetailPage(PageParam pageReqVO, + @RequestParam("formulaId") Long formulaId) { + return success(formulaService.getFormulaDetailPage(pageReqVO, formulaId)); + } + + @PostMapping("/formula-detail/create") + @Operation(summary = "创建计算公式明细") + @PreAuthorize("@ss.hasPermission('iot:formula:create')") + public CommonResult createFormulaDetail(@Valid @RequestBody FormulaDetailDO formulaDetail) { + return success(formulaService.createFormulaDetail(formulaDetail)); + } + + @PutMapping("/formula-detail/update") + @Operation(summary = "更新计算公式明细") + @PreAuthorize("@ss.hasPermission('iot:formula:update')") + public CommonResult updateFormulaDetail(@Valid @RequestBody FormulaDetailDO formulaDetail) { + formulaService.updateFormulaDetail(formulaDetail); + return success(true); + } + + @DeleteMapping("/formula-detail/delete") + @Parameter(name = "id", description = "编号", required = true) + @Operation(summary = "删除计算公式明细") + @PreAuthorize("@ss.hasPermission('iot:formula:delete')") + public CommonResult deleteFormulaDetail(@RequestParam("id") Long id) { + formulaService.deleteFormulaDetail(id); + return success(true); + } + + @GetMapping("/formula-detail/get") + @Operation(summary = "获得计算公式明细") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('iot:formula:query')") + public CommonResult getFormulaDetail(@RequestParam("id") Long id) { + return success(formulaService.getFormulaDetail(id)); + } + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/formula/vo/FormulaPageReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/formula/vo/FormulaPageReqVO.java new file mode 100644 index 000000000..7285bb28a --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/formula/vo/FormulaPageReqVO.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.module.iot.controller.admin.formula.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 FormulaPageReqVO extends PageParam { + + @Schema(description = "公式名称", example = "王五") + private String name; + + @Schema(description = "公式编号") + private String formulaCode; + + @Schema(description = "公式") + private String formula; + + @Schema(description = "结果类型(产量,电耗,浆耗,水耗,气耗,参数)", example = "1") + private String resultType; + + @Schema(description = "机台ID", example = "12374") + private Long machineId; + + @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; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/formula/vo/FormulaRespVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/formula/vo/FormulaRespVO.java new file mode 100644 index 000000000..ea16cf237 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/formula/vo/FormulaRespVO.java @@ -0,0 +1,55 @@ +package cn.iocoder.yudao.module.iot.controller.admin.formula.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.util.*; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; +import com.alibaba.excel.annotation.*; +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; + +@Schema(description = "管理后台 - 计算公式 Response VO") +@Data +@ExcelIgnoreUnannotated +public class FormulaRespVO { + + @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "31788") + @ExcelProperty("ID") + private Long id; + + @Schema(description = "公式名称", example = "王五") + @ExcelProperty("公式名称") + private String name; + + @Schema(description = "公式编号") + @ExcelProperty("公式编号") + private String formulaCode; + + @Schema(description = "公式") + @ExcelProperty("公式") + private String formula; + + @Schema(description = "结果类型(产量,电耗,浆耗,水耗,气耗,参数)", example = "1") + @ExcelProperty(value = "结果类型(产量,电耗,浆耗,水耗,气耗,参数)", converter = DictConvert.class) + @DictFormat("mes_data_type") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 + private String resultType; + + @Schema(description = "机台ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "12374") + @ExcelProperty("机台ID") + private Long machineId; + + @Schema(description = "备注", example = "你猜") + @ExcelProperty("备注") + private String remark; + + @Schema(description = "是否启用", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("是否启用") + private Boolean isEnable; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/formula/vo/FormulaSaveReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/formula/vo/FormulaSaveReqVO.java new file mode 100644 index 000000000..e1ab0e7ff --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/formula/vo/FormulaSaveReqVO.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.iot.controller.admin.formula.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - 计算公式新增/修改 Request VO") +@Data +public class FormulaSaveReqVO { + + @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "31788") + private Long id; + + @Schema(description = "公式名称", example = "王五") + private String name; + + @Schema(description = "公式编号") + private String formulaCode; + + @Schema(description = "公式") + private String formula; + + @Schema(description = "结果类型(产量,电耗,浆耗,水耗,气耗,参数)", example = "1") + private String resultType; + + @Schema(description = "机台ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "12374") + @NotNull(message = "机台ID不能为空") + private Long machineId; + + @Schema(description = "备注", example = "你猜") + private String remark; + + @Schema(description = "是否启用", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "是否启用不能为空") + private Boolean isEnable; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/gateway/GatewayController.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/gateway/GatewayController.java new file mode 100644 index 000000000..1a4310e16 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/gateway/GatewayController.java @@ -0,0 +1,138 @@ +package cn.iocoder.yudao.module.iot.controller.admin.gateway; + +import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO; +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 javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +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.iot.controller.admin.gateway.vo.*; +import cn.iocoder.yudao.module.iot.dal.dataobject.gateway.GatewayDO; +import cn.iocoder.yudao.module.iot.service.gateway.GatewayService; + +@Tag(name = "管理后台 - 网关") +@RestController +@RequestMapping("/iot/gateway") +@Validated +public class GatewayController { + + @Resource + private GatewayService gatewayService; + + @PostMapping("/create") + @Operation(summary = "创建网关") + @PreAuthorize("@ss.hasPermission('iot:gateway:create')") + public CommonResult createGateway(@Valid @RequestBody GatewaySaveReqVO createReqVO) { + return success(gatewayService.createGateway(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新网关") + @PreAuthorize("@ss.hasPermission('iot:gateway:update')") + public CommonResult updateGateway(@Valid @RequestBody GatewaySaveReqVO updateReqVO) { + gatewayService.updateGateway(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除网关") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('iot:gateway:delete')") + public CommonResult deleteGateway(@RequestParam("id") Long id) { + gatewayService.deleteGateway(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得网关") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('iot:gateway:query')") + public CommonResult getGateway(@RequestParam("id") Long id) { + GatewayDO gateway = gatewayService.getGateway(id); + return success(BeanUtils.toBean(gateway, GatewayRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得网关分页") + @PreAuthorize("@ss.hasPermission('iot:gateway:query')") + public CommonResult> getGatewayPage(@Valid GatewayPageReqVO pageReqVO) { + PageResult pageResult = gatewayService.getGatewayPage(pageReqVO); + return success(BeanUtils.toBean(pageResult, GatewayRespVO.class)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出网关 Excel") + @PreAuthorize("@ss.hasPermission('iot:gateway:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportGatewayExcel(@Valid GatewayPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = gatewayService.getGatewayPage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "网关.xls", "数据", GatewayRespVO.class, + BeanUtils.toBean(list, GatewayRespVO.class)); + } + + // ==================== 子表(物联设备) ==================== + + @GetMapping("/device/page") + @Operation(summary = "获得物联设备分页") + @Parameter(name = "gatewayId", description = "网关id") + @PreAuthorize("@ss.hasPermission('iot:gateway:query')") + public CommonResult> getDevicePage(PageParam pageReqVO, + @RequestParam("gatewayId") Long gatewayId) { + return success(gatewayService.getDevicePage(pageReqVO, gatewayId)); + } + + @PostMapping("/device/create") + @Operation(summary = "创建物联设备") + @PreAuthorize("@ss.hasPermission('iot:gateway:create')") + public CommonResult createDevice(@Valid @RequestBody DeviceDO device) { + return success(gatewayService.createDevice(device)); + } + + @PutMapping("/device/update") + @Operation(summary = "更新物联设备") + @PreAuthorize("@ss.hasPermission('iot:gateway:update')") + public CommonResult updateDevice(@Valid @RequestBody DeviceDO device) { + gatewayService.updateDevice(device); + return success(true); + } + + @DeleteMapping("/device/delete") + @Parameter(name = "id", description = "编号", required = true) + @Operation(summary = "删除物联设备") + @PreAuthorize("@ss.hasPermission('iot:gateway:delete')") + public CommonResult deleteDevice(@RequestParam("id") Long id) { + gatewayService.deleteDevice(id); + return success(true); + } + + @GetMapping("/device/get") + @Operation(summary = "获得物联设备") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('iot:gateway:query')") + public CommonResult getDevice(@RequestParam("id") Long id) { + return success(gatewayService.getDevice(id)); + } + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/gateway/vo/GatewayPageReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/gateway/vo/GatewayPageReqVO.java new file mode 100644 index 000000000..506d32eeb --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/gateway/vo/GatewayPageReqVO.java @@ -0,0 +1,49 @@ +package cn.iocoder.yudao.module.iot.controller.admin.gateway.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 GatewayPageReqVO extends PageParam { + + @Schema(description = "管理地址") + private String adminIp; + + @Schema(description = "管理账号", example = "芋艿") + private String username; + + @Schema(description = "管理密码") + private String password; + + @Schema(description = "网关名字", example = "赵六") + private String gatewayName; + + @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; + + @Schema(description = "网关编码") + private String gatewayCode; + + @Schema(description = "网关状态", example = "1") + private String gatewayStatus; + + @Schema(description = "订阅主题") + private String topic; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/gateway/vo/GatewayRespVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/gateway/vo/GatewayRespVO.java new file mode 100644 index 000000000..e6bdf5b77 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/gateway/vo/GatewayRespVO.java @@ -0,0 +1,63 @@ +package cn.iocoder.yudao.module.iot.controller.admin.gateway.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.util.*; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; +import com.alibaba.excel.annotation.*; +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; + +@Schema(description = "管理后台 - 网关 Response VO") +@Data +@ExcelIgnoreUnannotated +public class GatewayRespVO { + + @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "28060") + @ExcelProperty("ID") + private Long id; + + @Schema(description = "管理地址") + @ExcelProperty("管理地址") + private String adminIp; + + @Schema(description = "管理账号", example = "芋艿") + @ExcelProperty("管理账号") + private String username; + + @Schema(description = "管理密码") + @ExcelProperty("管理密码") + private String password; + + @Schema(description = "网关名字", example = "赵六") + @ExcelProperty("网关名字") + private String gatewayName; + + @Schema(description = "备注", example = "随便") + @ExcelProperty("备注") + private String remark; + + @Schema(description = "是否启用", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("是否启用") + private Boolean isEnable; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + + @Schema(description = "网关编码") + @ExcelProperty("网关编码") + private String gatewayCode; + + @Schema(description = "网关状态", example = "1") + @ExcelProperty(value = "网关状态", converter = DictConvert.class) + @DictFormat("iot_gateway_status") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 + private String gatewayStatus; + + @Schema(description = "订阅主题") + @ExcelProperty("订阅主题") + private String topic; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/gateway/vo/GatewaySaveReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/gateway/vo/GatewaySaveReqVO.java new file mode 100644 index 000000000..d4b15462d --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/gateway/vo/GatewaySaveReqVO.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.module.iot.controller.admin.gateway.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - 网关新增/修改 Request VO") +@Data +public class GatewaySaveReqVO { + + @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "28060") + private Long id; + + @Schema(description = "管理地址") + private String adminIp; + + @Schema(description = "管理账号", example = "芋艿") + private String username; + + @Schema(description = "管理密码") + private String password; + + @Schema(description = "网关名字", example = "赵六") + private String gatewayName; + + @Schema(description = "备注", example = "随便") + private String remark; + + @Schema(description = "是否启用", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "是否启用不能为空") + private Boolean isEnable; + + @Schema(description = "网关编码") + private String gatewayCode; + + @Schema(description = "网关状态", example = "1") + private String gatewayStatus; + + @Schema(description = "订阅主题") + private String topic; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/iotorganization/IotOrganizationController.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/iotorganization/IotOrganizationController.java new file mode 100644 index 000000000..4bd7cbb9d --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/iotorganization/IotOrganizationController.java @@ -0,0 +1,93 @@ +package cn.iocoder.yudao.module.iot.controller.admin.iotorganization; + +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 javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +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.iot.controller.admin.iotorganization.vo.*; +import cn.iocoder.yudao.module.iot.dal.dataobject.iotorganization.IotOrganizationDO; +import cn.iocoder.yudao.module.iot.service.iotorganization.IotOrganizationService; + +@Tag(name = "管理后台 - IOT组织") +@RestController +@RequestMapping("/iot/organization") +@Validated +public class IotOrganizationController { + + @Resource + private IotOrganizationService organizationService; + + @PostMapping("/create") + @Operation(summary = "创建IOT组织") + @PreAuthorize("@ss.hasPermission('iot:organization:create')") + public CommonResult createOrganization(@Valid @RequestBody IotOrganizationSaveReqVO createReqVO) { + return success(organizationService.createOrganization(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新IOT组织") + @PreAuthorize("@ss.hasPermission('iot:organization:update')") + public CommonResult updateOrganization(@Valid @RequestBody IotOrganizationSaveReqVO updateReqVO) { + organizationService.updateOrganization(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除IOT组织") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('iot:organization:delete')") + public CommonResult deleteOrganization(@RequestParam("id") Long id) { + organizationService.deleteOrganization(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得IOT组织") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('iot:organization:query')") + public CommonResult getOrganization(@RequestParam("id") Long id) { + IotOrganizationDO organization = organizationService.getOrganization(id); + return success(BeanUtils.toBean(organization, IotOrganizationRespVO.class)); + } + + @GetMapping("/list") + @Operation(summary = "获得IOT组织列表") + @PreAuthorize("@ss.hasPermission('iot:organization:query')") + public CommonResult> getOrganizationList(@Valid IotOrganizationListReqVO listReqVO) { + List list = organizationService.getOrganizationList(listReqVO); + return success(BeanUtils.toBean(list, IotOrganizationRespVO.class)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出IOT组织 Excel") + @PreAuthorize("@ss.hasPermission('iot:organization:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportOrganizationExcel(@Valid IotOrganizationListReqVO listReqVO, + HttpServletResponse response) throws IOException { + List list = organizationService.getOrganizationList(listReqVO); + // 导出 Excel + ExcelUtils.write(response, "IOT组织.xls", "数据", IotOrganizationRespVO.class, + BeanUtils.toBean(list, IotOrganizationRespVO.class)); + } + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/iotorganization/vo/IotOrganizationListReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/iotorganization/vo/IotOrganizationListReqVO.java new file mode 100644 index 000000000..10ee5f7ff --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/iotorganization/vo/IotOrganizationListReqVO.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.module.iot.controller.admin.iotorganization.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import java.time.LocalDateTime; +import org.springframework.format.annotation.DateTimeFormat; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - IOT组织列表 Request VO") +@Data +public class IotOrganizationListReqVO { + + @Schema(description = "显示顺序") + private Integer sort; + + @Schema(description = "负责人/工人", example = "11964") + private Long workerUserId; + + @Schema(description = "绑定工位id", example = "21787") + private Long orgId; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + + @Schema(description = "组织名称", example = "赵六") + private String name; + + @Schema(description = "父组织id", example = "10729") + private Long parentId; + + @Schema(description = "组织状态", example = "2") + private Integer status; + + @Schema(description = "设备类型", example = "2") + private String deviceType; + + @Schema(description = "组织等级") + private String orgClass; + + @Schema(description = "机台类型", example = "2") + private String machineType; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/iotorganization/vo/IotOrganizationRespVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/iotorganization/vo/IotOrganizationRespVO.java new file mode 100644 index 000000000..379b4eb87 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/iotorganization/vo/IotOrganizationRespVO.java @@ -0,0 +1,66 @@ +package cn.iocoder.yudao.module.iot.controller.admin.iotorganization.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.util.*; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; +import com.alibaba.excel.annotation.*; +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; + +@Schema(description = "管理后台 - IOT组织 Response VO") +@Data +@ExcelIgnoreUnannotated +public class IotOrganizationRespVO { + + @Schema(description = "组织id", requiredMode = Schema.RequiredMode.REQUIRED, example = "24521") + @ExcelProperty("组织id") + private Long id; + + @Schema(description = "显示顺序") + @ExcelProperty("显示顺序") + private Integer sort; + + @Schema(description = "负责人/工人", example = "11964") + @ExcelProperty("负责人/工人") + private Long workerUserId; + + @Schema(description = "绑定工位id", example = "21787") + @ExcelProperty("绑定工位id") + private Long orgId; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + + @Schema(description = "组织名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") + @ExcelProperty("组织名称") + private String name; + + @Schema(description = "父组织id", requiredMode = Schema.RequiredMode.REQUIRED, example = "10729") + @ExcelProperty("父组织id") + private Long parentId; + + @Schema(description = "组织状态", example = "2") + @ExcelProperty(value = "组织状态", converter = DictConvert.class) + @DictFormat("mes_machine_status") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 + private Integer status; + + @Schema(description = "设备类型", example = "2") + @ExcelProperty(value = "设备类型", converter = DictConvert.class) + @DictFormat("iot_device_type") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 + private String deviceType; + + @Schema(description = "组织等级") + @ExcelProperty(value = "组织等级", converter = DictConvert.class) + @DictFormat("iot_org_class") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 + private String orgClass; + + @Schema(description = "机台类型", example = "2") + @ExcelProperty(value = "机台类型", converter = DictConvert.class) + @DictFormat("mes_org_type") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 + private String machineType; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/iotorganization/vo/IotOrganizationSaveReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/iotorganization/vo/IotOrganizationSaveReqVO.java new file mode 100644 index 000000000..8bcebeac3 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/iotorganization/vo/IotOrganizationSaveReqVO.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.module.iot.controller.admin.iotorganization.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +@Schema(description = "管理后台 - IOT组织新增/修改 Request VO") +@Data +public class IotOrganizationSaveReqVO { + + @Schema(description = "组织id", requiredMode = Schema.RequiredMode.REQUIRED, example = "24521") + private Long id; + + @Schema(description = "显示顺序") + private Integer sort; + + @Schema(description = "负责人/工人", example = "11964") + private Long workerUserId; + + @Schema(description = "绑定工位id", example = "21787") + private Long orgId; + + @Schema(description = "组织名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") + @NotEmpty(message = "组织名称不能为空") + private String name; + + @Schema(description = "父组织id", requiredMode = Schema.RequiredMode.REQUIRED, example = "10729") + @NotNull(message = "父组织id不能为空") + private Long parentId; + + @Schema(description = "组织状态", example = "2") + private Integer status; + + @Schema(description = "设备类型", example = "2") + private String deviceType; + + @Schema(description = "组织等级") + private String orgClass; + + @Schema(description = "机台类型", example = "2") + private String machineType; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/kanban/KanbanController.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/kanban/KanbanController.java new file mode 100644 index 000000000..6deda1064 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/kanban/KanbanController.java @@ -0,0 +1,94 @@ +package cn.iocoder.yudao.module.iot.controller.admin.kanban; + +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 javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +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.iot.controller.admin.kanban.vo.*; +import cn.iocoder.yudao.module.iot.dal.dataobject.kanban.KanbanDO; +import cn.iocoder.yudao.module.iot.service.kanban.KanbanService; + +@Tag(name = "管理后台 - 物联看板") +@RestController +@RequestMapping("/iot/kanban") +@Validated +public class KanbanController { + + @Resource + private KanbanService kanbanService; + + @PostMapping("/create") + @Operation(summary = "创建物联看板") + @PreAuthorize("@ss.hasPermission('iot:kanban:create')") + public CommonResult createKanban(@Valid @RequestBody KanbanSaveReqVO createReqVO) { + return success(kanbanService.createKanban(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新物联看板") + @PreAuthorize("@ss.hasPermission('iot:kanban:update')") + public CommonResult updateKanban(@Valid @RequestBody KanbanSaveReqVO updateReqVO) { + kanbanService.updateKanban(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除物联看板") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('iot:kanban:delete')") + public CommonResult deleteKanban(@RequestParam("id") Long id) { + kanbanService.deleteKanban(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得物联看板") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('iot:kanban:query')") + public CommonResult getKanban(@RequestParam("id") Long id) { + KanbanDO kanban = kanbanService.getKanban(id); + return success(BeanUtils.toBean(kanban, KanbanRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得物联看板分页") + @PreAuthorize("@ss.hasPermission('iot:kanban:query')") + public CommonResult> getKanbanPage(@Valid KanbanPageReqVO pageReqVO) { + PageResult pageResult = kanbanService.getKanbanPage(pageReqVO); + return success(BeanUtils.toBean(pageResult, KanbanRespVO.class)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出物联看板 Excel") + @PreAuthorize("@ss.hasPermission('iot:kanban:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportKanbanExcel(@Valid KanbanPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = kanbanService.getKanbanPage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "物联看板.xls", "数据", KanbanRespVO.class, + BeanUtils.toBean(list, KanbanRespVO.class)); + } + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/kanban/vo/KanbanPageReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/kanban/vo/KanbanPageReqVO.java new file mode 100644 index 000000000..1bc4a8643 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/kanban/vo/KanbanPageReqVO.java @@ -0,0 +1,42 @@ +package cn.iocoder.yudao.module.iot.controller.admin.kanban.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 KanbanPageReqVO extends PageParam { + + @Schema(description = "编码") + private String code; + + @Schema(description = "标题") + private String title; + + @Schema(description = "缩略图") + private String img; + @Schema(description = "访问地址", example = "https://www.iocoder.cn") + private String viewUrl; + + @Schema(description = "标签") + private String tags; + + @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; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/kanban/vo/KanbanRespVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/kanban/vo/KanbanRespVO.java new file mode 100644 index 000000000..d92888ad2 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/kanban/vo/KanbanRespVO.java @@ -0,0 +1,54 @@ +package cn.iocoder.yudao.module.iot.controller.admin.kanban.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.util.*; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; +import com.alibaba.excel.annotation.*; +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; + +@Schema(description = "管理后台 - 物联看板 Response VO") +@Data +@ExcelIgnoreUnannotated +public class KanbanRespVO { + + @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "22557") + @ExcelProperty("ID") + private Long id; + + @Schema(description = "编码", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("编码") + private String code; + + @Schema(description = "标题", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("标题") + private String title; + + @Schema(description = "缩略图") + @ExcelProperty("缩略图") + private String img; + @Schema(description = "访问地址", example = "https://www.iocoder.cn") + @ExcelProperty("访问地址") + private String viewUrl; + + @Schema(description = "标签") + @ExcelProperty("标签") + private String tags; + + @Schema(description = "备注", example = "你猜") + @ExcelProperty("备注") + private String remark; + + @Schema(description = "是否启用", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty(value = "是否启用", converter = DictConvert.class) + @DictFormat("infra_boolean_string") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 + private Boolean isEnable; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/kanban/vo/KanbanSaveReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/kanban/vo/KanbanSaveReqVO.java new file mode 100644 index 000000000..8ce25ff59 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/kanban/vo/KanbanSaveReqVO.java @@ -0,0 +1,36 @@ +package cn.iocoder.yudao.module.iot.controller.admin.kanban.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +@Schema(description = "管理后台 - 物联看板新增/修改 Request VO") +@Data +public class KanbanSaveReqVO { + + @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "22557") + private Long id; + + @Schema(description = "编码", requiredMode = Schema.RequiredMode.REQUIRED) + @NotEmpty(message = "编码不能为空") + private String code; + + @Schema(description = "标题", requiredMode = Schema.RequiredMode.REQUIRED) + @NotEmpty(message = "标题不能为空") + private String title; + + @Schema(description = "缩略图") + private String img; + @Schema(description = "访问地址", example = "https://www.iocoder.cn") + private String viewUrl; + + @Schema(description = "标签") + private String tags; + @Schema(description = "备注", example = "你猜") + private String remark; + + @Schema(description = "是否启用", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "是否启用不能为空") + private Boolean isEnable; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/DeviceAttributeDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/DeviceAttributeDO.java new file mode 100644 index 000000000..6ea281530 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/DeviceAttributeDO.java @@ -0,0 +1,177 @@ +package cn.iocoder.yudao.module.iot.dal.dataobject.device; + +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("iot_device_attribute") +@KeySequence("iot_device_attribute_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DeviceAttributeDO extends BaseDO { + + /** + * ID + */ + @TableId + private Long id; + /** + * 地址编码 + */ + private String attributeCode; + /** + * 地址 + */ + private String address; + /** + * 地址名称 + */ + private String attributeName; + /** + * 地址描述 + */ + private String description; + /** + * 地址类型 + */ + private String addressType; + /** + * 地址偏移 + */ + private String addressOffset; + /** + * 地址2类型 + */ + private String address2Type; + /** + * 地址2偏移 + */ + private String address2Offset; + /** + * 所属组 + */ + private String groupName; + /** + * 所属组id + */ + private Integer groupId; + /** + * 安全类别 + */ + private String securityType; + /** + * 读写状态 + */ + private String ioStatus; + /** + * 是否线性换算(0是,1否) + * + * 枚举 {@link TODO iot_1_or_0 对应的类} + */ + private String isLinearTransfer; + /** + * 数据类型 + * + * 枚举 {@link TODO iot_device_data_type 对应的类} + */ + private String dataType; + /** + * 单位 + */ + private String unit; + /** + * 输入最小值 + */ + private String inMinValue; + /** + * 输入最大值 + */ + private String inMaxValue; + /** + * 输出最小值 + */ + private String outMinValue; + /** + * 输出最大值 + */ + private String outMaxValue; + /** + * 输出数据类型 + */ + private String outDataType; + /** + * 精度 + */ + private Integer siemensFieldPrecision; + /** + * 站号 + */ + private String modbusSlaveId; + /** + * 寄存器地址 + */ + private String modbusFieldAddress; + /** + * 寄存器类型 + */ + private String modbusAddressType; + /** + * 个数 + */ + private String modbusFieldSize; + /** + * 缩放因子(默认值为1,大于0的小数 + */ + private String modbusFieldPrecision; + /** + * 字节顺序 + */ + private String modbusFieldOrder; + /** + * mqtt进制类型binary,octal,hexadecimal,decimal + */ + private String sourceDataType; + /** + * 转化进制类型binary,octal,hexadecimal,decimal + * + * 枚举 {@link TODO iot_device_data_transfer_type 对应的类} + */ + private String transferDataType; + /** + * 系数 + */ + private String factor; + /** + * 网关id + */ + private Long gatewayId; + /** + * 设备id + */ + private Long deviceId; + /** + * 组织设备id + */ + private Long orgId; + /** + * 备注 + */ + private String remark; + /** + * 是否启用 + */ + private Boolean isEnable; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/DeviceDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/DeviceDO.java new file mode 100644 index 000000000..f08e1e4f8 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/DeviceDO.java @@ -0,0 +1,159 @@ +package cn.iocoder.yudao.module.iot.dal.dataobject.device; + +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("iot_device") +@KeySequence("iot_device_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DeviceDO extends BaseDO { + + /** + * ID + */ + @TableId + private Long id; + /** + * 设备配置id + */ + private String deviceConfigId; + /** + * 设备编号 + */ + private String deviceCode; + /** + * 设备名称 + */ + private String deviceName; + /** + * 设备类型 + */ + private String deviceType; + /** + * Siemens系列(S7-300、S7-1500) + * + * 枚举 {@link TODO iot_siemens_type 对应的类} + */ + private String siemensSeries; + /** + * 连接参数(波特率,数据位,停止位,校验位 例如:9600,8,1,N) + */ + private String siemensConnectParam; + /** + * 读取任务方式(0无,1有) + * + * 枚举 {@link TODO iot_1_or_0 对应的类} + */ + private String readCronType; + /** + * 读取任务时间间隔 + */ + private Integer readRepeatValue; + /** + * 读取任务时间间隔单位 + * + * 枚举 {@link TODO iot_device_data_unit 对应的类} + */ + private String readRepeatUnit; + /** + * 读取任务时间表达式 + */ + private String readCron; + /** + * 写入任务时间间隔 + */ + private String writeCronType; + /** + * 写入任务时间间隔 + */ + private Integer writeRepeatValue; + /** + * 写入任务时间间隔单位 + */ + private String writeRepeatUnit; + /** + * 写入任务时间表达式 + */ + private String writeCron; + /** + * 是否持久化(0不持久化,1持久化) + * + * 枚举 {@link TODO iot_1_or_0 对应的类} + */ + private String localPersistent; + /** + * 上传方式(1实时,2自定义) + * + * 枚举 {@link TODO iot_device_uploading_type 对应的类} + */ + private String uploadRate; + /** + * 上传频率 + */ + private Integer rateCount; + /** + * modbus协议类型(serial-rtu) + * + * 枚举 {@link TODO iot_modbus_type 对应的类} + */ + private String modbusProtocol; + /** + * modbus模式(client) + * + * 枚举 {@link TODO iot_modbus_mold 对应的类} + */ + private String modbusPattern; + /** + * modbus串口号 + * + * 枚举 {@link TODO iot_modbus_port 对应的类} + */ + private String portName; + /** + * 连接参数(波特率,数据位,停止位,校验位 例如:9600,8,1,N) + */ + private String modbusConnectParam; + /** + * 读地址是否连续(0否,1是) + * + * 枚举 {@link TODO iot_1_or_0 对应的类} + */ + private String modbusReadAddrGap; + /** + * 是否已下发(0下,1没下) + * + * 枚举 {@link TODO iot_1_or_0 对应的类} + */ + private String isUpload; + /** + * 网关id + */ + private Long gatewayId; + /** + * 组织设备id + */ + private Long orgId; + /** + * 备注 + */ + private String remark; + /** + * 是否启用 + */ + private Boolean isEnable; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/formula/FormulaDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/formula/FormulaDO.java new file mode 100644 index 000000000..390395092 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/formula/FormulaDO.java @@ -0,0 +1,61 @@ +package cn.iocoder.yudao.module.iot.dal.dataobject.formula; + +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("iot_formula") +@KeySequence("iot_formula_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FormulaDO extends BaseDO { + + /** + * ID + */ + @TableId + private Long id; + /** + * 公式名称 + */ + private String name; + /** + * 公式编号 + */ + private String formulaCode; + /** + * 公式 + */ + private String formula; + /** + * 结果类型(产量,电耗,浆耗,水耗,气耗,参数) + * + * 枚举 {@link TODO mes_data_type 对应的类} + */ + private String resultType; + /** + * 机台ID + */ + private Long machineId; + /** + * 备注 + */ + private String remark; + /** + * 是否启用 + */ + private Boolean isEnable; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/formula/FormulaDetailDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/formula/FormulaDetailDO.java new file mode 100644 index 000000000..5cffae85a --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/formula/FormulaDetailDO.java @@ -0,0 +1,83 @@ +package cn.iocoder.yudao.module.iot.dal.dataobject.formula; + +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("iot_formula_detail") +@KeySequence("iot_formula_detail_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FormulaDetailDO extends BaseDO { + + /** + * ID + */ + @TableId + private Long id; + /** + * 计算公式ID + */ + private Long formulaId; + /** + * 公式编号 + */ + private String formulaCode; + /** + * 变量名称 + */ + private String name; + /** + * 设备ID + */ + private Long deviceId; + /** + * 地址ID + */ + private Long attributeId; + /** + * 地址名称 + */ + private String attributeName; + /** + * 地址 + */ + private String address; + /** + * 示例值 + */ + private String demoValue; + /** + * 累积量类型sum:累加,max-min:最大值-最小值 + * + * 枚举 {@link TODO iot_formula_var_type 对应的类} + */ + private String sumType; + /** + * 计算范围,为空则不计算day:当天,week:当周,month:当月 + * + * 枚举 {@link TODO iot_formula_cal_rang 对应的类} + */ + private String sumRange; + /** + * 备注 + */ + private String remark; + /** + * 是否启用 + */ + private Boolean isEnable; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/gateway/GatewayDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/gateway/GatewayDO.java new file mode 100644 index 000000000..9db9a3ad2 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/gateway/GatewayDO.java @@ -0,0 +1,69 @@ +package cn.iocoder.yudao.module.iot.dal.dataobject.gateway; + +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("iot_gateway") +@KeySequence("iot_gateway_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class GatewayDO extends BaseDO { + + /** + * ID + */ + @TableId + private Long id; + /** + * 管理地址 + */ + private String adminIp; + /** + * 管理账号 + */ + private String username; + /** + * 管理密码 + */ + private String password; + /** + * 网关名字 + */ + private String gatewayName; + /** + * 备注 + */ + private String remark; + /** + * 是否启用 + */ + private Boolean isEnable; + /** + * 网关编码 + */ + private String gatewayCode; + /** + * 网关状态 + * + * 枚举 {@link TODO iot_gateway_status 对应的类} + */ + private String gatewayStatus; + /** + * 订阅主题 + */ + private String topic; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/iotorganization/IotOrganizationDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/iotorganization/IotOrganizationDO.java new file mode 100644 index 000000000..56abd6113 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/iotorganization/IotOrganizationDO.java @@ -0,0 +1,77 @@ +package cn.iocoder.yudao.module.iot.dal.dataobject.iotorganization; + +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; + +/** + * IOT组织 DO + * + * @author 内蒙必硕 + */ +@TableName("iot_iot_organization") +@KeySequence("iot_iot_organization_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class IotOrganizationDO extends BaseDO { + + public static final Long PARENT_ID_ROOT = 0L; + + /** + * 组织id + */ + @TableId + private Long id; + /** + * 显示顺序 + */ + private Integer sort; + /** + * 负责人/工人 + */ + private Long workerUserId; + /** + * 绑定工位id + */ + private Long orgId; + /** + * 组织名称 + */ + private String name; + /** + * 父组织id + */ + private Long parentId; + /** + * 组织状态 + * + * 枚举 {@link TODO mes_machine_status 对应的类} + */ + private Integer status; + /** + * 设备类型 + * + * 枚举 {@link TODO iot_device_type 对应的类} + */ + private String deviceType; + /** + * 组织等级 + * + * 枚举 {@link TODO iot_org_class 对应的类} + */ + private String orgClass; + /** + * 机台类型 + * + * 枚举 {@link TODO mes_org_type 对应的类} + */ + private String machineType; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/kanban/KanbanDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/kanban/KanbanDO.java new file mode 100644 index 000000000..79900fb57 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/kanban/KanbanDO.java @@ -0,0 +1,61 @@ +package cn.iocoder.yudao.module.iot.dal.dataobject.kanban; + +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("iot_kanban") +@KeySequence("iot_kanban_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class KanbanDO extends BaseDO { + + /** + * ID + */ + @TableId + private Long id; + /** + * 编码 + */ + private String code; + /** + * 标题 + */ + private String title; + /** + * 缩略图 + */ + private String img; + /** + * 访问地址 + */ + private String viewUrl; + /** + * 标签 + */ + private String tags; + /** + * 备注 + */ + private String remark; + /** + * 是否启用 + * + * 枚举 {@link TODO infra_boolean_string 对应的类} + */ + private Boolean isEnable; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/DeviceAttributeMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/DeviceAttributeMapper.java new file mode 100644 index 000000000..4ac64c706 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/DeviceAttributeMapper.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.iot.dal.mysql.device; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceAttributeDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * 设备属性 Mapper + * + * @author 内蒙必硕 + */ +@Mapper +public interface DeviceAttributeMapper extends BaseMapperX { + + default PageResult selectPage(PageParam reqVO, Long deviceId) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eq(DeviceAttributeDO::getDeviceId, deviceId) + .orderByDesc(DeviceAttributeDO::getId)); + } + + default int deleteByDeviceId(Long deviceId) { + return delete(DeviceAttributeDO::getDeviceId, deviceId); + } + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/DeviceMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/DeviceMapper.java new file mode 100644 index 000000000..7ad141f04 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/DeviceMapper.java @@ -0,0 +1,60 @@ +package cn.iocoder.yudao.module.iot.dal.mysql.device; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +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.iot.dal.dataobject.device.DeviceDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.*; + +/** + * 物联设备 Mapper + * + * @author 内蒙必硕 + */ +@Mapper +public interface DeviceMapper extends BaseMapperX { + + default PageResult selectPage(DevicePageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(DeviceDO::getDeviceConfigId, reqVO.getDeviceConfigId()) + .eqIfPresent(DeviceDO::getDeviceCode, reqVO.getDeviceCode()) + .likeIfPresent(DeviceDO::getDeviceName, reqVO.getDeviceName()) + .eqIfPresent(DeviceDO::getDeviceType, reqVO.getDeviceType()) + .eqIfPresent(DeviceDO::getSiemensSeries, reqVO.getSiemensSeries()) + .eqIfPresent(DeviceDO::getSiemensConnectParam, reqVO.getSiemensConnectParam()) + .eqIfPresent(DeviceDO::getReadCronType, reqVO.getReadCronType()) + .eqIfPresent(DeviceDO::getReadRepeatValue, reqVO.getReadRepeatValue()) + .eqIfPresent(DeviceDO::getReadRepeatUnit, reqVO.getReadRepeatUnit()) + .eqIfPresent(DeviceDO::getReadCron, reqVO.getReadCron()) + .eqIfPresent(DeviceDO::getWriteCronType, reqVO.getWriteCronType()) + .eqIfPresent(DeviceDO::getWriteRepeatValue, reqVO.getWriteRepeatValue()) + .eqIfPresent(DeviceDO::getWriteRepeatUnit, reqVO.getWriteRepeatUnit()) + .eqIfPresent(DeviceDO::getWriteCron, reqVO.getWriteCron()) + .eqIfPresent(DeviceDO::getLocalPersistent, reqVO.getLocalPersistent()) + .eqIfPresent(DeviceDO::getUploadRate, reqVO.getUploadRate()) + .eqIfPresent(DeviceDO::getRateCount, reqVO.getRateCount()) + .eqIfPresent(DeviceDO::getModbusProtocol, reqVO.getModbusProtocol()) + .eqIfPresent(DeviceDO::getModbusPattern, reqVO.getModbusPattern()) + .eqIfPresent(DeviceDO::getPortName, reqVO.getPortName()) + .eqIfPresent(DeviceDO::getModbusConnectParam, reqVO.getModbusConnectParam()) + .eqIfPresent(DeviceDO::getModbusReadAddrGap, reqVO.getModbusReadAddrGap()) + .eqIfPresent(DeviceDO::getIsUpload, reqVO.getIsUpload()) + .eqIfPresent(DeviceDO::getGatewayId, reqVO.getGatewayId()) + .eqIfPresent(DeviceDO::getOrgId, reqVO.getOrgId()) + .eqIfPresent(DeviceDO::getRemark, reqVO.getRemark()) + .eqIfPresent(DeviceDO::getIsEnable, reqVO.getIsEnable()) + .betweenIfPresent(DeviceDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(DeviceDO::getId)); + } + default PageResult selectPage(PageParam reqVO, Long gatewayId) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eq(DeviceDO::getGatewayId, gatewayId) + .orderByDesc(DeviceDO::getId)); + } + + default int deleteByGatewayId(Long gatewayId) { + return delete(DeviceDO::getGatewayId, gatewayId); + } +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/formula/FormulaDetailMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/formula/FormulaDetailMapper.java new file mode 100644 index 000000000..b6be8d092 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/formula/FormulaDetailMapper.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.iot.dal.mysql.formula; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.iot.dal.dataobject.formula.FormulaDetailDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * 计算公式明细 Mapper + * + * @author 内蒙必硕 + */ +@Mapper +public interface FormulaDetailMapper extends BaseMapperX { + + default PageResult selectPage(PageParam reqVO, Long formulaId) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eq(FormulaDetailDO::getFormulaId, formulaId) + .orderByDesc(FormulaDetailDO::getId)); + } + + default int deleteByFormulaId(Long formulaId) { + return delete(FormulaDetailDO::getFormulaId, formulaId); + } + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/formula/FormulaMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/formula/FormulaMapper.java new file mode 100644 index 000000000..967d27151 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/formula/FormulaMapper.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.iot.dal.mysql.formula; + +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.iot.dal.dataobject.formula.FormulaDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.iot.controller.admin.formula.vo.*; + +/** + * 计算公式 Mapper + * + * @author 内蒙必硕 + */ +@Mapper +public interface FormulaMapper extends BaseMapperX { + + default PageResult selectPage(FormulaPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(FormulaDO::getName, reqVO.getName()) + .eqIfPresent(FormulaDO::getFormulaCode, reqVO.getFormulaCode()) + .eqIfPresent(FormulaDO::getFormula, reqVO.getFormula()) + .eqIfPresent(FormulaDO::getResultType, reqVO.getResultType()) + .eqIfPresent(FormulaDO::getMachineId, reqVO.getMachineId()) + .eqIfPresent(FormulaDO::getRemark, reqVO.getRemark()) + .eqIfPresent(FormulaDO::getIsEnable, reqVO.getIsEnable()) + .betweenIfPresent(FormulaDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(FormulaDO::getId)); + } + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/gateway/GatewayMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/gateway/GatewayMapper.java new file mode 100644 index 000000000..28a8a16bd --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/gateway/GatewayMapper.java @@ -0,0 +1,35 @@ +package cn.iocoder.yudao.module.iot.dal.mysql.gateway; + +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.iot.dal.dataobject.gateway.GatewayDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.iot.controller.admin.gateway.vo.*; + +/** + * 网关 Mapper + * + * @author 内蒙必硕 + */ +@Mapper +public interface GatewayMapper extends BaseMapperX { + + default PageResult selectPage(GatewayPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(GatewayDO::getAdminIp, reqVO.getAdminIp()) + .likeIfPresent(GatewayDO::getUsername, reqVO.getUsername()) + .eqIfPresent(GatewayDO::getPassword, reqVO.getPassword()) + .likeIfPresent(GatewayDO::getGatewayName, reqVO.getGatewayName()) + .eqIfPresent(GatewayDO::getRemark, reqVO.getRemark()) + .eqIfPresent(GatewayDO::getIsEnable, reqVO.getIsEnable()) + .betweenIfPresent(GatewayDO::getCreateTime, reqVO.getCreateTime()) + .eqIfPresent(GatewayDO::getGatewayCode, reqVO.getGatewayCode()) + .eqIfPresent(GatewayDO::getGatewayStatus, reqVO.getGatewayStatus()) + .eqIfPresent(GatewayDO::getTopic, reqVO.getTopic()) + .orderByDesc(GatewayDO::getId)); + } + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/iotorganization/IotOrganizationMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/iotorganization/IotOrganizationMapper.java new file mode 100644 index 000000000..ed78b4a49 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/iotorganization/IotOrganizationMapper.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.module.iot.dal.mysql.iotorganization; + +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.iot.dal.dataobject.iotorganization.IotOrganizationDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.iot.controller.admin.iotorganization.vo.*; + +/** + * IOT组织 Mapper + * + * @author 内蒙必硕 + */ +@Mapper +public interface IotOrganizationMapper extends BaseMapperX { + + default List selectList(IotOrganizationListReqVO reqVO) { + return selectList(new LambdaQueryWrapperX() + .eqIfPresent(IotOrganizationDO::getSort, reqVO.getSort()) + .eqIfPresent(IotOrganizationDO::getWorkerUserId, reqVO.getWorkerUserId()) + .eqIfPresent(IotOrganizationDO::getOrgId, reqVO.getOrgId()) + .betweenIfPresent(IotOrganizationDO::getCreateTime, reqVO.getCreateTime()) + .likeIfPresent(IotOrganizationDO::getName, reqVO.getName()) + .eqIfPresent(IotOrganizationDO::getParentId, reqVO.getParentId()) + .eqIfPresent(IotOrganizationDO::getStatus, reqVO.getStatus()) + .eqIfPresent(IotOrganizationDO::getDeviceType, reqVO.getDeviceType()) + .eqIfPresent(IotOrganizationDO::getOrgClass, reqVO.getOrgClass()) + .eqIfPresent(IotOrganizationDO::getMachineType, reqVO.getMachineType()) + .orderByDesc(IotOrganizationDO::getId)); + } + + default IotOrganizationDO selectByParentIdAndName(Long parentId, String name) { + return selectOne(IotOrganizationDO::getParentId, parentId, IotOrganizationDO::getName, name); + } + + default Long selectCountByParentId(Long parentId) { + return selectCount(IotOrganizationDO::getParentId, parentId); + } + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/kanban/KanbanMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/kanban/KanbanMapper.java new file mode 100644 index 000000000..aa7a8f2fc --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/kanban/KanbanMapper.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.iot.dal.mysql.kanban; + +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.iot.dal.dataobject.kanban.KanbanDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.iot.controller.admin.kanban.vo.*; + +/** + * 物联看板 Mapper + * + * @author 内蒙必硕 + */ +@Mapper +public interface KanbanMapper extends BaseMapperX { + + default PageResult selectPage(KanbanPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(KanbanDO::getCode, reqVO.getCode()) + .eqIfPresent(KanbanDO::getTitle, reqVO.getTitle()) + .eqIfPresent(KanbanDO::getImg, reqVO.getImg()) + .eqIfPresent(KanbanDO::getRemark, reqVO.getRemark()) + .eqIfPresent(KanbanDO::getIsEnable, reqVO.getIsEnable()) + .betweenIfPresent(KanbanDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(KanbanDO::getId)); + } + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/security/config/SecurityConfiguration.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/security/config/SecurityConfiguration.java index bd59c82a6..74a05e6b2 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/security/config/SecurityConfiguration.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/security/config/SecurityConfiguration.java @@ -24,7 +24,7 @@ public class SecurityConfiguration { @Override public void customize(ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry registry) { - registry.antMatchers("/iot/**").permitAll(); // 积木报表 + registry.antMatchers("/iot/open/**").permitAll(); // 积木报表 } }; diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/web/config/IotWebConfiguration.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/web/config/IotWebConfiguration.java new file mode 100644 index 000000000..40052d0c7 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/web/config/IotWebConfiguration.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.iot.framework.web.config; + +import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration; +import org.springdoc.core.GroupedOpenApi; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * mes 模块的 web 组件的 Configuration + * + * @author 芋道源码 + */ +@Configuration(proxyBeanMethods = false) +public class IotWebConfiguration { + + /** + * crm 模块的 API 分组 + */ + @Bean + public GroupedOpenApi iotGroupedOpenApi() { + return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("iot"); + } + +} diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/web/package-info.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/web/package-info.java new file mode 100644 index 000000000..755d12d4f --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/web/package-info.java @@ -0,0 +1,4 @@ +/** + * crm 模块的 web 拓展封装 + */ +package cn.iocoder.yudao.module.iot.framework.web; diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceService.java new file mode 100644 index 000000000..aaf89ee20 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceService.java @@ -0,0 +1,98 @@ +package cn.iocoder.yudao.module.iot.service.device; + + +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.*; +import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceAttributeDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO; + +import javax.validation.Valid; + +/** + * 物联设备 Service 接口 + * + * @author 内蒙必硕 + */ +public interface DeviceService { + + /** + * 创建物联设备 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createDevice(@Valid DeviceSaveReqVO createReqVO); + + /** + * 更新物联设备 + * + * @param updateReqVO 更新信息 + */ + void updateDevice(@Valid DeviceSaveReqVO updateReqVO); + + /** + * 删除物联设备 + * + * @param id 编号 + */ + void deleteDevice(Long id); + + /** + * 获得物联设备 + * + * @param id 编号 + * @return 物联设备 + */ + DeviceDO getDevice(Long id); + + /** + * 获得物联设备分页 + * + * @param pageReqVO 分页查询 + * @return 物联设备分页 + */ + PageResult getDevicePage(DevicePageReqVO pageReqVO); + + // ==================== 子表(设备属性) ==================== + + /** + * 获得设备属性分页 + * + * @param pageReqVO 分页查询 + * @param deviceId 设备id + * @return 设备属性分页 + */ + PageResult getDeviceAttributePage(PageParam pageReqVO, Long deviceId); + + /** + * 创建设备属性 + * + * @param deviceAttribute 创建信息 + * @return 编号 + */ + Long createDeviceAttribute(@Valid DeviceAttributeDO deviceAttribute); + + /** + * 更新设备属性 + * + * @param deviceAttribute 更新信息 + */ + void updateDeviceAttribute(@Valid DeviceAttributeDO deviceAttribute); + + /** + * 删除设备属性 + * + * @param id 编号 + */ + void deleteDeviceAttribute(Long id); + + /** + * 获得设备属性 + * + * @param id 编号 + * @return 设备属性 + */ + DeviceAttributeDO getDeviceAttribute(Long id); + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java new file mode 100644 index 000000000..005f5b587 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java @@ -0,0 +1,127 @@ +package cn.iocoder.yudao.module.iot.service.device; + +import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO; +import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceMapper; +import org.springframework.stereotype.Service; + +import org.springframework.validation.annotation.Validated; +import org.springframework.transaction.annotation.Transactional; + +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.*; +import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceAttributeDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; + +import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceAttributeMapper; + +import javax.annotation.Resource; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; + +/** + * 物联设备 Service 实现类 + * + * @author 内蒙必硕 + */ +@Service +@Validated +public class DeviceServiceImpl implements DeviceService { + + @Resource + private DeviceMapper deviceMapper; + @Resource + private DeviceAttributeMapper deviceAttributeMapper; + + @Override + public Long createDevice(DeviceSaveReqVO createReqVO) { + // 插入 + DeviceDO device = BeanUtils.toBean(createReqVO, DeviceDO.class); + deviceMapper.insert(device); + // 返回 + return device.getId(); + } + + @Override + public void updateDevice(DeviceSaveReqVO updateReqVO) { + // 校验存在 + validateDeviceExists(updateReqVO.getId()); + // 更新 + DeviceDO updateObj = BeanUtils.toBean(updateReqVO, DeviceDO.class); + deviceMapper.updateById(updateObj); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteDevice(Long id) { + // 校验存在 + validateDeviceExists(id); + // 删除 + deviceMapper.deleteById(id); + + // 删除子表 + deleteDeviceAttributeByDeviceId(id); + } + + private void validateDeviceExists(Long id) { + if (deviceMapper.selectById(id) == null) { + throw exception(DEVICE_NOT_EXISTS); + } + } + + @Override + public DeviceDO getDevice(Long id) { + return deviceMapper.selectById(id); + } + + @Override + public PageResult getDevicePage(DevicePageReqVO pageReqVO) { + return deviceMapper.selectPage(pageReqVO); + } + + // ==================== 子表(设备属性) ==================== + + @Override + public PageResult getDeviceAttributePage(PageParam pageReqVO, Long deviceId) { + return deviceAttributeMapper.selectPage(pageReqVO, deviceId); + } + + @Override + public Long createDeviceAttribute(DeviceAttributeDO deviceAttribute) { + deviceAttributeMapper.insert(deviceAttribute); + return deviceAttribute.getId(); + } + + @Override + public void updateDeviceAttribute(DeviceAttributeDO deviceAttribute) { + // 校验存在 + validateDeviceAttributeExists(deviceAttribute.getId()); + // 更新 + deviceAttributeMapper.updateById(deviceAttribute); + } + + @Override + public void deleteDeviceAttribute(Long id) { + // 校验存在 + validateDeviceAttributeExists(id); + // 删除 + deviceAttributeMapper.deleteById(id); + } + + @Override + public DeviceAttributeDO getDeviceAttribute(Long id) { + return deviceAttributeMapper.selectById(id); + } + + private void validateDeviceAttributeExists(Long id) { + if (deviceAttributeMapper.selectById(id) == null) { + throw exception(DEVICE_ATTRIBUTE_NOT_EXISTS); + } + } + + private void deleteDeviceAttributeByDeviceId(Long deviceId) { + deviceAttributeMapper.deleteByDeviceId(deviceId); + } + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/formula/FormulaService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/formula/FormulaService.java new file mode 100644 index 000000000..833e1ef87 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/formula/FormulaService.java @@ -0,0 +1,97 @@ +package cn.iocoder.yudao.module.iot.service.formula; + +import javax.validation.Valid; +import cn.iocoder.yudao.module.iot.controller.admin.formula.vo.*; +import cn.iocoder.yudao.module.iot.dal.dataobject.formula.FormulaDO; +import cn.iocoder.yudao.module.iot.dal.dataobject.formula.FormulaDetailDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; + + +/** + * 计算公式 Service 接口 + * + * @author 内蒙必硕 + */ +public interface FormulaService { + + /** + * 创建计算公式 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createFormula(@Valid FormulaSaveReqVO createReqVO); + + /** + * 更新计算公式 + * + * @param updateReqVO 更新信息 + */ + void updateFormula(@Valid FormulaSaveReqVO updateReqVO); + + /** + * 删除计算公式 + * + * @param id 编号 + */ + void deleteFormula(Long id); + + /** + * 获得计算公式 + * + * @param id 编号 + * @return 计算公式 + */ + FormulaDO getFormula(Long id); + + /** + * 获得计算公式分页 + * + * @param pageReqVO 分页查询 + * @return 计算公式分页 + */ + PageResult getFormulaPage(FormulaPageReqVO pageReqVO); + + // ==================== 子表(计算公式明细) ==================== + + /** + * 获得计算公式明细分页 + * + * @param pageReqVO 分页查询 + * @param formulaId 计算公式ID + * @return 计算公式明细分页 + */ + PageResult getFormulaDetailPage(PageParam pageReqVO, Long formulaId); + + /** + * 创建计算公式明细 + * + * @param formulaDetail 创建信息 + * @return 编号 + */ + Long createFormulaDetail(@Valid FormulaDetailDO formulaDetail); + + /** + * 更新计算公式明细 + * + * @param formulaDetail 更新信息 + */ + void updateFormulaDetail(@Valid FormulaDetailDO formulaDetail); + + /** + * 删除计算公式明细 + * + * @param id 编号 + */ + void deleteFormulaDetail(Long id); + + /** + * 获得计算公式明细 + * + * @param id 编号 + * @return 计算公式明细 + */ + FormulaDetailDO getFormulaDetail(Long id); + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/formula/FormulaServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/formula/FormulaServiceImpl.java new file mode 100644 index 000000000..851806a82 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/formula/FormulaServiceImpl.java @@ -0,0 +1,126 @@ +package cn.iocoder.yudao.module.iot.service.formula; + +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import cn.iocoder.yudao.module.iot.controller.admin.formula.vo.*; +import cn.iocoder.yudao.module.iot.dal.dataobject.formula.FormulaDO; +import cn.iocoder.yudao.module.iot.dal.dataobject.formula.FormulaDetailDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; + +import cn.iocoder.yudao.module.iot.dal.mysql.formula.FormulaMapper; +import cn.iocoder.yudao.module.iot.dal.mysql.formula.FormulaDetailMapper; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; + +/** + * 计算公式 Service 实现类 + * + * @author 内蒙必硕 + */ +@Service +@Validated +public class FormulaServiceImpl implements FormulaService { + + @Resource + private FormulaMapper formulaMapper; + @Resource + private FormulaDetailMapper formulaDetailMapper; + + @Override + public Long createFormula(FormulaSaveReqVO createReqVO) { + // 插入 + FormulaDO formula = BeanUtils.toBean(createReqVO, FormulaDO.class); + formulaMapper.insert(formula); + // 返回 + return formula.getId(); + } + + @Override + public void updateFormula(FormulaSaveReqVO updateReqVO) { + // 校验存在 + validateFormulaExists(updateReqVO.getId()); + // 更新 + FormulaDO updateObj = BeanUtils.toBean(updateReqVO, FormulaDO.class); + formulaMapper.updateById(updateObj); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteFormula(Long id) { + // 校验存在 + validateFormulaExists(id); + // 删除 + formulaMapper.deleteById(id); + + // 删除子表 + deleteFormulaDetailByFormulaId(id); + } + + private void validateFormulaExists(Long id) { + if (formulaMapper.selectById(id) == null) { + throw exception(FORMULA_NOT_EXISTS); + } + } + + @Override + public FormulaDO getFormula(Long id) { + return formulaMapper.selectById(id); + } + + @Override + public PageResult getFormulaPage(FormulaPageReqVO pageReqVO) { + return formulaMapper.selectPage(pageReqVO); + } + + // ==================== 子表(计算公式明细) ==================== + + @Override + public PageResult getFormulaDetailPage(PageParam pageReqVO, Long formulaId) { + return formulaDetailMapper.selectPage(pageReqVO, formulaId); + } + + @Override + public Long createFormulaDetail(FormulaDetailDO formulaDetail) { + formulaDetailMapper.insert(formulaDetail); + return formulaDetail.getId(); + } + + @Override + public void updateFormulaDetail(FormulaDetailDO formulaDetail) { + // 校验存在 + validateFormulaDetailExists(formulaDetail.getId()); + // 更新 + formulaDetailMapper.updateById(formulaDetail); + } + + @Override + public void deleteFormulaDetail(Long id) { + // 校验存在 + validateFormulaDetailExists(id); + // 删除 + formulaDetailMapper.deleteById(id); + } + + @Override + public FormulaDetailDO getFormulaDetail(Long id) { + return formulaDetailMapper.selectById(id); + } + + private void validateFormulaDetailExists(Long id) { + if (formulaDetailMapper.selectById(id) == null) { + throw exception(FORMULA_DETAIL_NOT_EXISTS); + } + } + + private void deleteFormulaDetailByFormulaId(Long formulaId) { + formulaDetailMapper.deleteByFormulaId(formulaId); + } + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/gateway/GatewayService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/gateway/GatewayService.java new file mode 100644 index 000000000..6cc34110c --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/gateway/GatewayService.java @@ -0,0 +1,96 @@ +package cn.iocoder.yudao.module.iot.service.gateway; + +import javax.validation.Valid; +import cn.iocoder.yudao.module.iot.controller.admin.gateway.vo.*; +import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO; +import cn.iocoder.yudao.module.iot.dal.dataobject.gateway.GatewayDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; + +/** + * 网关 Service 接口 + * + * @author 内蒙必硕 + */ +public interface GatewayService { + + /** + * 创建网关 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createGateway(@Valid GatewaySaveReqVO createReqVO); + + /** + * 更新网关 + * + * @param updateReqVO 更新信息 + */ + void updateGateway(@Valid GatewaySaveReqVO updateReqVO); + + /** + * 删除网关 + * + * @param id 编号 + */ + void deleteGateway(Long id); + + /** + * 获得网关 + * + * @param id 编号 + * @return 网关 + */ + GatewayDO getGateway(Long id); + + /** + * 获得网关分页 + * + * @param pageReqVO 分页查询 + * @return 网关分页 + */ + PageResult getGatewayPage(GatewayPageReqVO pageReqVO); + + // ==================== 子表(物联设备) ==================== + + /** + * 获得物联设备分页 + * + * @param pageReqVO 分页查询 + * @param gatewayId 网关id + * @return 物联设备分页 + */ + PageResult getDevicePage(PageParam pageReqVO, Long gatewayId); + + /** + * 创建物联设备 + * + * @param device 创建信息 + * @return 编号 + */ + Long createDevice(@Valid DeviceDO device); + + /** + * 更新物联设备 + * + * @param device 更新信息 + */ + void updateDevice(@Valid DeviceDO device); + + /** + * 删除物联设备 + * + * @param id 编号 + */ + void deleteDevice(Long id); + + /** + * 获得物联设备 + * + * @param id 编号 + * @return 物联设备 + */ + DeviceDO getDevice(Long id); + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/gateway/GatewayServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/gateway/GatewayServiceImpl.java new file mode 100644 index 000000000..25ec07302 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/gateway/GatewayServiceImpl.java @@ -0,0 +1,125 @@ +package cn.iocoder.yudao.module.iot.service.gateway; + +import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO; +import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceMapper; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.transaction.annotation.Transactional; + +import cn.iocoder.yudao.module.iot.controller.admin.gateway.vo.*; +import cn.iocoder.yudao.module.iot.dal.dataobject.gateway.GatewayDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; + +import cn.iocoder.yudao.module.iot.dal.mysql.gateway.GatewayMapper; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; + +/** + * 网关 Service 实现类 + * + * @author 内蒙必硕 + */ +@Service +@Validated +public class GatewayServiceImpl implements GatewayService { + + @Resource + private GatewayMapper gatewayMapper; + @Resource + private DeviceMapper deviceMapper; + + @Override + public Long createGateway(GatewaySaveReqVO createReqVO) { + // 插入 + GatewayDO gateway = BeanUtils.toBean(createReqVO, GatewayDO.class); + gatewayMapper.insert(gateway); + // 返回 + return gateway.getId(); + } + + @Override + public void updateGateway(GatewaySaveReqVO updateReqVO) { + // 校验存在 + validateGatewayExists(updateReqVO.getId()); + // 更新 + GatewayDO updateObj = BeanUtils.toBean(updateReqVO, GatewayDO.class); + gatewayMapper.updateById(updateObj); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteGateway(Long id) { + // 校验存在 + validateGatewayExists(id); + // 删除 + gatewayMapper.deleteById(id); + + // 删除子表 + deleteDeviceByGatewayId(id); + } + + private void validateGatewayExists(Long id) { + if (gatewayMapper.selectById(id) == null) { + throw exception(GATEWAY_NOT_EXISTS); + } + } + + @Override + public GatewayDO getGateway(Long id) { + return gatewayMapper.selectById(id); + } + + @Override + public PageResult getGatewayPage(GatewayPageReqVO pageReqVO) { + return gatewayMapper.selectPage(pageReqVO); + } + + // ==================== 子表(物联设备) ==================== + + @Override + public PageResult getDevicePage(PageParam pageReqVO, Long gatewayId) { + return deviceMapper.selectPage(pageReqVO, gatewayId); + } + + @Override + public Long createDevice(DeviceDO device) { + deviceMapper.insert(device); + return device.getId(); + } + + @Override + public void updateDevice(DeviceDO device) { + // 校验存在 + validateDeviceExists(device.getId()); + // 更新 + deviceMapper.updateById(device); + } + + @Override + public void deleteDevice(Long id) { + // 校验存在 + validateDeviceExists(id); + // 删除 + deviceMapper.deleteById(id); + } + + @Override + public DeviceDO getDevice(Long id) { + return deviceMapper.selectById(id); + } + + private void validateDeviceExists(Long id) { + if (deviceMapper.selectById(id) == null) { + throw exception(DEVICE_NOT_EXISTS); + } + } + + private void deleteDeviceByGatewayId(Long gatewayId) { + deviceMapper.deleteByGatewayId(gatewayId); + } + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/iotorganization/IotOrganizationService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/iotorganization/IotOrganizationService.java new file mode 100644 index 000000000..c9de1e93a --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/iotorganization/IotOrganizationService.java @@ -0,0 +1,55 @@ +package cn.iocoder.yudao.module.iot.service.iotorganization; + +import java.util.*; +import javax.validation.Valid; +import cn.iocoder.yudao.module.iot.controller.admin.iotorganization.vo.*; +import cn.iocoder.yudao.module.iot.dal.dataobject.iotorganization.IotOrganizationDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; + +/** + * IOT组织 Service 接口 + * + * @author 内蒙必硕 + */ +public interface IotOrganizationService { + + /** + * 创建IOT组织 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createOrganization(@Valid IotOrganizationSaveReqVO createReqVO); + + /** + * 更新IOT组织 + * + * @param updateReqVO 更新信息 + */ + void updateOrganization(@Valid IotOrganizationSaveReqVO updateReqVO); + + /** + * 删除IOT组织 + * + * @param id 编号 + */ + void deleteOrganization(Long id); + + /** + * 获得IOT组织 + * + * @param id 编号 + * @return IOT组织 + */ + IotOrganizationDO getOrganization(Long id); + + /** + * 获得IOT组织列表 + * + * @param listReqVO 查询条件 + * @return IOT组织列表 + */ + List getOrganizationList(IotOrganizationListReqVO listReqVO); + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/iotorganization/IotOrganizationServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/iotorganization/IotOrganizationServiceImpl.java new file mode 100644 index 000000000..3feb860a0 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/iotorganization/IotOrganizationServiceImpl.java @@ -0,0 +1,133 @@ +package cn.iocoder.yudao.module.iot.service.iotorganization; + +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; + +import java.util.*; +import cn.iocoder.yudao.module.iot.controller.admin.iotorganization.vo.*; +import cn.iocoder.yudao.module.iot.dal.dataobject.iotorganization.IotOrganizationDO; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; + +import cn.iocoder.yudao.module.iot.dal.mysql.iotorganization.IotOrganizationMapper; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; + +/** + * IOT组织 Service 实现类 + * + * @author 内蒙必硕 + */ +@Service +@Validated +public class IotOrganizationServiceImpl implements IotOrganizationService { + + @Resource + private IotOrganizationMapper iotOrganizationMapper; + + @Override + public Long createOrganization(IotOrganizationSaveReqVO createReqVO) { + // 校验父组织id的有效性 + validateParentOrganization(null, createReqVO.getParentId()); + // 校验组织名称的唯一性 + validateOrganizationNameUnique(null, createReqVO.getParentId(), createReqVO.getName()); + + // 插入 + IotOrganizationDO organization = BeanUtils.toBean(createReqVO, IotOrganizationDO.class); + iotOrganizationMapper.insert(organization); + // 返回 + return organization.getId(); + } + + @Override + public void updateOrganization(IotOrganizationSaveReqVO updateReqVO) { + // 校验存在 + validateOrganizationExists(updateReqVO.getId()); + // 校验父组织id的有效性 + validateParentOrganization(updateReqVO.getId(), updateReqVO.getParentId()); + // 校验组织名称的唯一性 + validateOrganizationNameUnique(updateReqVO.getId(), updateReqVO.getParentId(), updateReqVO.getName()); + + // 更新 + IotOrganizationDO updateObj = BeanUtils.toBean(updateReqVO, IotOrganizationDO.class); + iotOrganizationMapper.updateById(updateObj); + } + + @Override + public void deleteOrganization(Long id) { + // 校验存在 + validateOrganizationExists(id); + // 校验是否有子IOT组织 + if (iotOrganizationMapper.selectCountByParentId(id) > 0) { + throw exception(ORGANIZATION_EXITS_CHILDREN); + } + // 删除 + iotOrganizationMapper.deleteById(id); + } + + private void validateOrganizationExists(Long id) { + if (iotOrganizationMapper.selectById(id) == null) { + throw exception(ORGANIZATION_NOT_EXISTS); + } + } + + private void validateParentOrganization(Long id, Long parentId) { + if (parentId == null || IotOrganizationDO.PARENT_ID_ROOT.equals(parentId)) { + return; + } + // 1. 不能设置自己为父IOT组织 + if (Objects.equals(id, parentId)) { + throw exception(ORGANIZATION_PARENT_ERROR); + } + // 2. 父IOT组织不存在 + IotOrganizationDO parentOrganization = iotOrganizationMapper.selectById(parentId); + if (parentOrganization == null) { + throw exception(ORGANIZATION_PARENT_NOT_EXITS); + } + // 3. 递归校验父IOT组织,如果父IOT组织是自己的子IOT组织,则报错,避免形成环路 + if (id == null) { // id 为空,说明新增,不需要考虑环路 + return; + } + for (int i = 0; i < Short.MAX_VALUE; i++) { + // 3.1 校验环路 + parentId = parentOrganization.getParentId(); + if (Objects.equals(id, parentId)) { + throw exception(ORGANIZATION_PARENT_IS_CHILD); + } + // 3.2 继续递归下一级父IOT组织 + if (parentId == null || IotOrganizationDO.PARENT_ID_ROOT.equals(parentId)) { + break; + } + parentOrganization = iotOrganizationMapper.selectById(parentId); + if (parentOrganization == null) { + break; + } + } + } + + private void validateOrganizationNameUnique(Long id, Long parentId, String name) { + IotOrganizationDO organization = iotOrganizationMapper.selectByParentIdAndName(parentId, name); + if (organization == null) { + return; + } + // 如果 id 为空,说明不用比较是否为相同 id 的IOT组织 + if (id == null) { + throw exception(ORGANIZATION_NAME_DUPLICATE); + } + if (!Objects.equals(organization.getId(), id)) { + throw exception(ORGANIZATION_NAME_DUPLICATE); + } + } + + @Override + public IotOrganizationDO getOrganization(Long id) { + return iotOrganizationMapper.selectById(id); + } + + @Override + public List getOrganizationList(IotOrganizationListReqVO listReqVO) { + return iotOrganizationMapper.selectList(listReqVO); + } + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/kanban/KanbanService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/kanban/KanbanService.java new file mode 100644 index 000000000..be6821858 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/kanban/KanbanService.java @@ -0,0 +1,54 @@ +package cn.iocoder.yudao.module.iot.service.kanban; + +import javax.validation.Valid; +import cn.iocoder.yudao.module.iot.controller.admin.kanban.vo.*; +import cn.iocoder.yudao.module.iot.dal.dataobject.kanban.KanbanDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; + +/** + * 物联看板 Service 接口 + * + * @author 内蒙必硕 + */ +public interface KanbanService { + + /** + * 创建物联看板 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createKanban(@Valid KanbanSaveReqVO createReqVO); + + /** + * 更新物联看板 + * + * @param updateReqVO 更新信息 + */ + void updateKanban(@Valid KanbanSaveReqVO updateReqVO); + + /** + * 删除物联看板 + * + * @param id 编号 + */ + void deleteKanban(Long id); + + /** + * 获得物联看板 + * + * @param id 编号 + * @return 物联看板 + */ + KanbanDO getKanban(Long id); + + /** + * 获得物联看板分页 + * + * @param pageReqVO 分页查询 + * @return 物联看板分页 + */ + PageResult getKanbanPage(KanbanPageReqVO pageReqVO); + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/kanban/KanbanServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/kanban/KanbanServiceImpl.java new file mode 100644 index 000000000..83f76d6fb --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/kanban/KanbanServiceImpl.java @@ -0,0 +1,76 @@ +package cn.iocoder.yudao.module.iot.service.kanban; + +import org.springframework.stereotype.Service; + +import org.springframework.validation.annotation.Validated; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import cn.iocoder.yudao.module.iot.controller.admin.kanban.vo.*; +import cn.iocoder.yudao.module.iot.dal.dataobject.kanban.KanbanDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; + +import cn.iocoder.yudao.module.iot.dal.mysql.kanban.KanbanMapper; + +import javax.annotation.Resource; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; + +/** + * 物联看板 Service 实现类 + * + * @author 内蒙必硕 + */ +@Service +@Validated +public class KanbanServiceImpl implements KanbanService { + + @Resource + private KanbanMapper kanbanMapper; + + @Override + public Long createKanban(KanbanSaveReqVO createReqVO) { + // 插入 + KanbanDO kanban = BeanUtils.toBean(createReqVO, KanbanDO.class); + kanbanMapper.insert(kanban); + // 返回 + return kanban.getId(); + } + + @Override + public void updateKanban(KanbanSaveReqVO updateReqVO) { + // 校验存在 + validateKanbanExists(updateReqVO.getId()); + // 更新 + KanbanDO updateObj = BeanUtils.toBean(updateReqVO, KanbanDO.class); + kanbanMapper.updateById(updateObj); + } + + @Override + public void deleteKanban(Long id) { + // 校验存在 + validateKanbanExists(id); + // 删除 + kanbanMapper.deleteById(id); + } + + private void validateKanbanExists(Long id) { + if (kanbanMapper.selectById(id) == null) { + throw exception(KANBAN_NOT_EXISTS); + } + } + + @Override + public KanbanDO getKanban(Long id) { + return kanbanMapper.selectById(id); + } + + @Override + public PageResult getKanbanPage(KanbanPageReqVO pageReqVO) { + return kanbanMapper.selectPage(pageReqVO); + } + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/DeviceMapper.xml b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/DeviceMapper.xml new file mode 100644 index 000000000..548b593d6 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/DeviceMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/formula/FormulaMapper.xml b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/formula/FormulaMapper.xml new file mode 100644 index 000000000..40ee6dc37 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/formula/FormulaMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/gateway/GatewayMapper.xml b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/gateway/GatewayMapper.xml new file mode 100644 index 000000000..a6dd8190f --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/gateway/GatewayMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/iotorganization/IotOrganizationMapper.xml b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/iotorganization/IotOrganizationMapper.xml new file mode 100644 index 000000000..2afab458a --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/iotorganization/IotOrganizationMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/kanban/KanbanMapper.xml b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/kanban/KanbanMapper.xml new file mode 100644 index 000000000..209bce2b2 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/kanban/KanbanMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImplTest.java b/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImplTest.java new file mode 100644 index 000000000..a3d889112 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImplTest.java @@ -0,0 +1,231 @@ +package cn.iocoder.yudao.module.iot.service.device; + +import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO; +import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceMapper; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; + +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.*; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; + +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; +import static org.junit.jupiter.api.Assertions.*; + +/** + * {@link DeviceServiceImpl} 的单元测试类 + * + * @author 内蒙必硕 + */ +@Import(DeviceServiceImpl.class) +public class DeviceServiceImplTest extends BaseDbUnitTest { + + @Resource + private DeviceServiceImpl deviceService; + + @Resource + private DeviceMapper deviceMapper; + + @Test + public void testCreateDevice_success() { + // 准备参数 + DeviceSaveReqVO createReqVO = randomPojo(DeviceSaveReqVO.class).setId(null); + + // 调用 + Long deviceId = deviceService.createDevice(createReqVO); + // 断言 + assertNotNull(deviceId); + // 校验记录的属性是否正确 + DeviceDO device = deviceMapper.selectById(deviceId); + assertPojoEquals(createReqVO, device, "id"); + } + + @Test + public void testUpdateDevice_success() { + // mock 数据 + DeviceDO dbDevice = randomPojo(DeviceDO.class); + deviceMapper.insert(dbDevice);// @Sql: 先插入出一条存在的数据 + // 准备参数 + DeviceSaveReqVO updateReqVO = randomPojo(DeviceSaveReqVO.class, o -> { + o.setId(dbDevice.getId()); // 设置更新的 ID + }); + + // 调用 + deviceService.updateDevice(updateReqVO); + // 校验是否更新正确 + DeviceDO device = deviceMapper.selectById(updateReqVO.getId()); // 获取最新的 + assertPojoEquals(updateReqVO, device); + } + + @Test + public void testUpdateDevice_notExists() { + // 准备参数 + DeviceSaveReqVO updateReqVO = randomPojo(DeviceSaveReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> deviceService.updateDevice(updateReqVO), DEVICE_NOT_EXISTS); + } + + @Test + public void testDeleteDevice_success() { + // mock 数据 + DeviceDO dbDevice = randomPojo(DeviceDO.class); + deviceMapper.insert(dbDevice);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbDevice.getId(); + + // 调用 + deviceService.deleteDevice(id); + // 校验数据不存在了 + assertNull(deviceMapper.selectById(id)); + } + + @Test + public void testDeleteDevice_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> deviceService.deleteDevice(id), DEVICE_NOT_EXISTS); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetDevicePage() { + // mock 数据 + DeviceDO dbDevice = randomPojo(DeviceDO.class, o -> { // 等会查询到 + o.setDeviceConfigId(null); + o.setDeviceCode(null); + o.setDeviceName(null); + o.setDeviceType(null); + o.setSiemensSeries(null); + o.setSiemensConnectParam(null); + o.setReadCronType(null); + o.setReadRepeatValue(null); + o.setReadRepeatUnit(null); + o.setReadCron(null); + o.setWriteCronType(null); + o.setWriteRepeatValue(null); + o.setWriteRepeatUnit(null); + o.setWriteCron(null); + o.setLocalPersistent(null); + o.setUploadRate(null); + o.setRateCount(null); + o.setModbusProtocol(null); + o.setModbusPattern(null); + o.setPortName(null); + o.setModbusConnectParam(null); + o.setModbusReadAddrGap(null); + o.setIsUpload(null); + o.setGatewayId(null); + o.setOrgId(null); + o.setRemark(null); + o.setIsEnable(null); + o.setCreateTime(null); + }); + deviceMapper.insert(dbDevice); + // 测试 deviceConfigId 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setDeviceConfigId(null))); + // 测试 deviceCode 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setDeviceCode(null))); + // 测试 deviceName 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setDeviceName(null))); + // 测试 deviceType 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setDeviceType(null))); + // 测试 siemensSeries 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setSiemensSeries(null))); + // 测试 siemensConnectParam 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setSiemensConnectParam(null))); + // 测试 readCronType 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setReadCronType(null))); + // 测试 readRepeatValue 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setReadRepeatValue(null))); + // 测试 readRepeatUnit 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setReadRepeatUnit(null))); + // 测试 readCron 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setReadCron(null))); + // 测试 writeCronType 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setWriteCronType(null))); + // 测试 writeRepeatValue 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setWriteRepeatValue(null))); + // 测试 writeRepeatUnit 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setWriteRepeatUnit(null))); + // 测试 writeCron 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setWriteCron(null))); + // 测试 localPersistent 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setLocalPersistent(null))); + // 测试 uploadRate 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setUploadRate(null))); + // 测试 rateCount 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setRateCount(null))); + // 测试 modbusProtocol 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setModbusProtocol(null))); + // 测试 modbusPattern 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setModbusPattern(null))); + // 测试 portName 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setPortName(null))); + // 测试 modbusConnectParam 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setModbusConnectParam(null))); + // 测试 modbusReadAddrGap 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setModbusReadAddrGap(null))); + // 测试 isUpload 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setIsUpload(null))); + // 测试 gatewayId 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setGatewayId(null))); + // 测试 orgId 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setOrgId(null))); + // 测试 remark 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setRemark(null))); + // 测试 isEnable 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setIsEnable(null))); + // 测试 createTime 不匹配 + deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setCreateTime(null))); + // 准备参数 + DevicePageReqVO reqVO = new DevicePageReqVO(); + reqVO.setDeviceConfigId(null); + reqVO.setDeviceCode(null); + reqVO.setDeviceName(null); + reqVO.setDeviceType(null); + reqVO.setSiemensSeries(null); + reqVO.setSiemensConnectParam(null); + reqVO.setReadCronType(null); + reqVO.setReadRepeatValue(null); + reqVO.setReadRepeatUnit(null); + reqVO.setReadCron(null); + reqVO.setWriteCronType(null); + reqVO.setWriteRepeatValue(null); + reqVO.setWriteRepeatUnit(null); + reqVO.setWriteCron(null); + reqVO.setLocalPersistent(null); + reqVO.setUploadRate(null); + reqVO.setRateCount(null); + reqVO.setModbusProtocol(null); + reqVO.setModbusPattern(null); + reqVO.setPortName(null); + reqVO.setModbusConnectParam(null); + reqVO.setModbusReadAddrGap(null); + reqVO.setIsUpload(null); + reqVO.setGatewayId(null); + reqVO.setOrgId(null); + reqVO.setRemark(null); + reqVO.setIsEnable(null); + reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); + + // 调用 + PageResult pageResult = deviceService.getDevicePage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbDevice, pageResult.getList().get(0)); + } + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/formula/FormulaServiceImplTest.java b/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/formula/FormulaServiceImplTest.java new file mode 100644 index 000000000..07e315e6c --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/formula/FormulaServiceImplTest.java @@ -0,0 +1,160 @@ +package cn.iocoder.yudao.module.iot.service.formula; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; + + + +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; + +import cn.iocoder.yudao.module.iot.controller.admin.formula.vo.*; +import cn.iocoder.yudao.module.iot.dal.dataobject.formula.FormulaDO; +import cn.iocoder.yudao.module.iot.dal.mysql.formula.FormulaMapper; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + + +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.util.*; +import java.time.LocalDateTime; + +import static cn.hutool.core.util.RandomUtil.*; +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +/** + * {@link FormulaServiceImpl} 的单元测试类 + * + * @author 内蒙必硕 + */ +@Import(FormulaServiceImpl.class) +public class FormulaServiceImplTest extends BaseDbUnitTest { + + @Resource + private FormulaServiceImpl formulaService; + + @Resource + private FormulaMapper formulaMapper; + + @Test + public void testCreateFormula_success() { + // 准备参数 + FormulaSaveReqVO createReqVO = randomPojo(FormulaSaveReqVO.class).setId(null); + + // 调用 + Long formulaId = formulaService.createFormula(createReqVO); + // 断言 + assertNotNull(formulaId); + // 校验记录的属性是否正确 + FormulaDO formula = formulaMapper.selectById(formulaId); + assertPojoEquals(createReqVO, formula, "id"); + } + + @Test + public void testUpdateFormula_success() { + // mock 数据 + FormulaDO dbFormula = randomPojo(FormulaDO.class); + formulaMapper.insert(dbFormula);// @Sql: 先插入出一条存在的数据 + // 准备参数 + FormulaSaveReqVO updateReqVO = randomPojo(FormulaSaveReqVO.class, o -> { + o.setId(dbFormula.getId()); // 设置更新的 ID + }); + + // 调用 + formulaService.updateFormula(updateReqVO); + // 校验是否更新正确 + FormulaDO formula = formulaMapper.selectById(updateReqVO.getId()); // 获取最新的 + assertPojoEquals(updateReqVO, formula); + } + + @Test + public void testUpdateFormula_notExists() { + // 准备参数 + FormulaSaveReqVO updateReqVO = randomPojo(FormulaSaveReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> formulaService.updateFormula(updateReqVO), FORMULA_NOT_EXISTS); + } + + @Test + public void testDeleteFormula_success() { + // mock 数据 + FormulaDO dbFormula = randomPojo(FormulaDO.class); + formulaMapper.insert(dbFormula);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbFormula.getId(); + + // 调用 + formulaService.deleteFormula(id); + // 校验数据不存在了 + assertNull(formulaMapper.selectById(id)); + } + + @Test + public void testDeleteFormula_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> formulaService.deleteFormula(id), FORMULA_NOT_EXISTS); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetFormulaPage() { + // mock 数据 + FormulaDO dbFormula = randomPojo(FormulaDO.class, o -> { // 等会查询到 + o.setName(null); + o.setFormulaCode(null); + o.setFormula(null); + o.setResultType(null); + o.setMachineId(null); + o.setRemark(null); + o.setIsEnable(null); + o.setCreateTime(null); + }); + formulaMapper.insert(dbFormula); + // 测试 name 不匹配 + formulaMapper.insert(cloneIgnoreId(dbFormula, o -> o.setName(null))); + // 测试 formulaCode 不匹配 + formulaMapper.insert(cloneIgnoreId(dbFormula, o -> o.setFormulaCode(null))); + // 测试 formula 不匹配 + formulaMapper.insert(cloneIgnoreId(dbFormula, o -> o.setFormula(null))); + // 测试 resultType 不匹配 + formulaMapper.insert(cloneIgnoreId(dbFormula, o -> o.setResultType(null))); + // 测试 machineId 不匹配 + formulaMapper.insert(cloneIgnoreId(dbFormula, o -> o.setMachineId(null))); + // 测试 remark 不匹配 + formulaMapper.insert(cloneIgnoreId(dbFormula, o -> o.setRemark(null))); + // 测试 isEnable 不匹配 + formulaMapper.insert(cloneIgnoreId(dbFormula, o -> o.setIsEnable(null))); + // 测试 createTime 不匹配 + formulaMapper.insert(cloneIgnoreId(dbFormula, o -> o.setCreateTime(null))); + // 准备参数 + FormulaPageReqVO reqVO = new FormulaPageReqVO(); + reqVO.setName(null); + reqVO.setFormulaCode(null); + reqVO.setFormula(null); + reqVO.setResultType(null); + reqVO.setMachineId(null); + reqVO.setRemark(null); + reqVO.setIsEnable(null); + reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); + + // 调用 + PageResult pageResult = formulaService.getFormulaPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbFormula, pageResult.getList().get(0)); + } + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/gateway/GatewayServiceImplTest.java b/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/gateway/GatewayServiceImplTest.java new file mode 100644 index 000000000..9c78970cc --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/gateway/GatewayServiceImplTest.java @@ -0,0 +1,168 @@ +package cn.iocoder.yudao.module.iot.service.gateway; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; + + + +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; + +import cn.iocoder.yudao.module.iot.controller.admin.gateway.vo.*; +import cn.iocoder.yudao.module.iot.dal.dataobject.gateway.GatewayDO; +import cn.iocoder.yudao.module.iot.dal.mysql.gateway.GatewayMapper; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + + +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.util.*; +import java.time.LocalDateTime; + +import static cn.hutool.core.util.RandomUtil.*; +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +/** + * {@link GatewayServiceImpl} 的单元测试类 + * + * @author 内蒙必硕 + */ +@Import(GatewayServiceImpl.class) +public class GatewayServiceImplTest extends BaseDbUnitTest { + + @Resource + private GatewayServiceImpl gatewayService; + + @Resource + private GatewayMapper gatewayMapper; + + @Test + public void testCreateGateway_success() { + // 准备参数 + GatewaySaveReqVO createReqVO = randomPojo(GatewaySaveReqVO.class).setId(null); + + // 调用 + Long gatewayId = gatewayService.createGateway(createReqVO); + // 断言 + assertNotNull(gatewayId); + // 校验记录的属性是否正确 + GatewayDO gateway = gatewayMapper.selectById(gatewayId); + assertPojoEquals(createReqVO, gateway, "id"); + } + + @Test + public void testUpdateGateway_success() { + // mock 数据 + GatewayDO dbGateway = randomPojo(GatewayDO.class); + gatewayMapper.insert(dbGateway);// @Sql: 先插入出一条存在的数据 + // 准备参数 + GatewaySaveReqVO updateReqVO = randomPojo(GatewaySaveReqVO.class, o -> { + o.setId(dbGateway.getId()); // 设置更新的 ID + }); + + // 调用 + gatewayService.updateGateway(updateReqVO); + // 校验是否更新正确 + GatewayDO gateway = gatewayMapper.selectById(updateReqVO.getId()); // 获取最新的 + assertPojoEquals(updateReqVO, gateway); + } + + @Test + public void testUpdateGateway_notExists() { + // 准备参数 + GatewaySaveReqVO updateReqVO = randomPojo(GatewaySaveReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> gatewayService.updateGateway(updateReqVO), GATEWAY_NOT_EXISTS); + } + + @Test + public void testDeleteGateway_success() { + // mock 数据 + GatewayDO dbGateway = randomPojo(GatewayDO.class); + gatewayMapper.insert(dbGateway);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbGateway.getId(); + + // 调用 + gatewayService.deleteGateway(id); + // 校验数据不存在了 + assertNull(gatewayMapper.selectById(id)); + } + + @Test + public void testDeleteGateway_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> gatewayService.deleteGateway(id), GATEWAY_NOT_EXISTS); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetGatewayPage() { + // mock 数据 + GatewayDO dbGateway = randomPojo(GatewayDO.class, o -> { // 等会查询到 + o.setAdminIp(null); + o.setUsername(null); + o.setPassword(null); + o.setGatewayName(null); + o.setRemark(null); + o.setIsEnable(null); + o.setCreateTime(null); + o.setGatewayCode(null); + o.setGatewayStatus(null); + o.setTopic(null); + }); + gatewayMapper.insert(dbGateway); + // 测试 adminIp 不匹配 + gatewayMapper.insert(cloneIgnoreId(dbGateway, o -> o.setAdminIp(null))); + // 测试 username 不匹配 + gatewayMapper.insert(cloneIgnoreId(dbGateway, o -> o.setUsername(null))); + // 测试 password 不匹配 + gatewayMapper.insert(cloneIgnoreId(dbGateway, o -> o.setPassword(null))); + // 测试 gatewayName 不匹配 + gatewayMapper.insert(cloneIgnoreId(dbGateway, o -> o.setGatewayName(null))); + // 测试 remark 不匹配 + gatewayMapper.insert(cloneIgnoreId(dbGateway, o -> o.setRemark(null))); + // 测试 isEnable 不匹配 + gatewayMapper.insert(cloneIgnoreId(dbGateway, o -> o.setIsEnable(null))); + // 测试 createTime 不匹配 + gatewayMapper.insert(cloneIgnoreId(dbGateway, o -> o.setCreateTime(null))); + // 测试 gatewayCode 不匹配 + gatewayMapper.insert(cloneIgnoreId(dbGateway, o -> o.setGatewayCode(null))); + // 测试 gatewayStatus 不匹配 + gatewayMapper.insert(cloneIgnoreId(dbGateway, o -> o.setGatewayStatus(null))); + // 测试 topic 不匹配 + gatewayMapper.insert(cloneIgnoreId(dbGateway, o -> o.setTopic(null))); + // 准备参数 + GatewayPageReqVO reqVO = new GatewayPageReqVO(); + reqVO.setAdminIp(null); + reqVO.setUsername(null); + reqVO.setPassword(null); + reqVO.setGatewayName(null); + reqVO.setRemark(null); + reqVO.setIsEnable(null); + reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); + reqVO.setGatewayCode(null); + reqVO.setGatewayStatus(null); + reqVO.setTopic(null); + + // 调用 + PageResult pageResult = gatewayService.getGatewayPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbGateway, pageResult.getList().get(0)); + } + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/iotorganization/IotOrganizationServiceImplTest.java b/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/iotorganization/IotOrganizationServiceImplTest.java new file mode 100644 index 000000000..a4058ae0f --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/iotorganization/IotOrganizationServiceImplTest.java @@ -0,0 +1,165 @@ +package cn.iocoder.yudao.module.iot.service.iotorganization; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; + +import javax.annotation.Resource;; + +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; + +import cn.iocoder.yudao.module.iot.controller.admin.iotorganization.vo.*; +import cn.iocoder.yudao.module.iot.dal.dataobject.iotorganization.IotOrganizationDO; +import cn.iocoder.yudao.module.iot.dal.mysql.iotorganization.IotOrganizationMapper; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + + +import org.springframework.context.annotation.Import; +import java.util.*; +import java.time.LocalDateTime; + +import static cn.hutool.core.util.RandomUtil.*; +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +/** + * {@link IotOrganizationServiceImpl} 的单元测试类 + * + * @author 内蒙必硕 + */ +@Import(IotOrganizationServiceImpl.class) +public class IotOrganizationServiceImplTest extends BaseDbUnitTest { + + @Resource + private IotOrganizationServiceImpl organizationService; + + @Resource + private IotOrganizationMapper organizationMapper; + + @Test + public void testCreateOrganization_success() { + // 准备参数 + IotOrganizationSaveReqVO createReqVO = randomPojo(IotOrganizationSaveReqVO.class).setId(null); + + // 调用 + Long organizationId = organizationService.createOrganization(createReqVO); + // 断言 + assertNotNull(organizationId); + // 校验记录的属性是否正确 + IotOrganizationDO organization = organizationMapper.selectById(organizationId); + assertPojoEquals(createReqVO, organization, "id"); + } + + @Test + public void testUpdateOrganization_success() { + // mock 数据 + IotOrganizationDO dbOrganization = randomPojo(IotOrganizationDO.class); + organizationMapper.insert(dbOrganization);// @Sql: 先插入出一条存在的数据 + // 准备参数 + IotOrganizationSaveReqVO updateReqVO = randomPojo(IotOrganizationSaveReqVO.class, o -> { + o.setId(dbOrganization.getId()); // 设置更新的 ID + }); + + // 调用 + organizationService.updateOrganization(updateReqVO); + // 校验是否更新正确 + IotOrganizationDO organization = organizationMapper.selectById(updateReqVO.getId()); // 获取最新的 + assertPojoEquals(updateReqVO, organization); + } + + @Test + public void testUpdateOrganization_notExists() { + // 准备参数 + IotOrganizationSaveReqVO updateReqVO = randomPojo(IotOrganizationSaveReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> organizationService.updateOrganization(updateReqVO), ORGANIZATION_NOT_EXISTS); + } + + @Test + public void testDeleteOrganization_success() { + // mock 数据 + IotOrganizationDO dbOrganization = randomPojo(IotOrganizationDO.class); + organizationMapper.insert(dbOrganization);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbOrganization.getId(); + + // 调用 + organizationService.deleteOrganization(id); + // 校验数据不存在了 + assertNull(organizationMapper.selectById(id)); + } + + @Test + public void testDeleteOrganization_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> organizationService.deleteOrganization(id), ORGANIZATION_NOT_EXISTS); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetOrganizationList() { + // mock 数据 + IotOrganizationDO dbOrganization = randomPojo(IotOrganizationDO.class, o -> { // 等会查询到 + o.setSort(null); + o.setWorkerUserId(null); + o.setOrgId(null); + o.setCreateTime(null); + o.setName(null); + o.setParentId(null); + o.setStatus(null); + o.setDeviceType(null); + o.setOrgClass(null); + o.setMachineType(null); + }); + organizationMapper.insert(dbOrganization); + // 测试 sort 不匹配 + organizationMapper.insert(cloneIgnoreId(dbOrganization, o -> o.setSort(null))); + // 测试 workerUserId 不匹配 + organizationMapper.insert(cloneIgnoreId(dbOrganization, o -> o.setWorkerUserId(null))); + // 测试 orgId 不匹配 + organizationMapper.insert(cloneIgnoreId(dbOrganization, o -> o.setOrgId(null))); + // 测试 createTime 不匹配 + organizationMapper.insert(cloneIgnoreId(dbOrganization, o -> o.setCreateTime(null))); + // 测试 name 不匹配 + organizationMapper.insert(cloneIgnoreId(dbOrganization, o -> o.setName(null))); + // 测试 parentId 不匹配 + organizationMapper.insert(cloneIgnoreId(dbOrganization, o -> o.setParentId(null))); + // 测试 status 不匹配 + organizationMapper.insert(cloneIgnoreId(dbOrganization, o -> o.setStatus(null))); + // 测试 deviceType 不匹配 + organizationMapper.insert(cloneIgnoreId(dbOrganization, o -> o.setDeviceType(null))); + // 测试 orgClass 不匹配 + organizationMapper.insert(cloneIgnoreId(dbOrganization, o -> o.setOrgClass(null))); + // 测试 machineType 不匹配 + organizationMapper.insert(cloneIgnoreId(dbOrganization, o -> o.setMachineType(null))); + // 准备参数 + IotOrganizationListReqVO reqVO = new IotOrganizationListReqVO(); + reqVO.setSort(null); + reqVO.setWorkerUserId(null); + reqVO.setOrgId(null); + reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); + reqVO.setName(null); + reqVO.setParentId(null); + reqVO.setStatus(null); + reqVO.setDeviceType(null); + reqVO.setOrgClass(null); + reqVO.setMachineType(null); + + // 调用 + List list = organizationService.getOrganizationList(reqVO); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(dbOrganization, list.get(0)); + } + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/kanban/KanbanServiceImplTest.java b/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/kanban/KanbanServiceImplTest.java new file mode 100644 index 000000000..51aaef1fe --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/kanban/KanbanServiceImplTest.java @@ -0,0 +1,150 @@ +package cn.iocoder.yudao.module.iot.service.kanban; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; + +import javax.annotation.Resource; + +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; + +import cn.iocoder.yudao.module.iot.controller.admin.kanban.vo.*; +import cn.iocoder.yudao.module.iot.dal.dataobject.kanban.KanbanDO; +import cn.iocoder.yudao.module.iot.dal.mysql.kanban.KanbanMapper; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + + +import org.springframework.context.annotation.Import; +import java.util.*; +import java.time.LocalDateTime; + +import static cn.hutool.core.util.RandomUtil.*; +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +/** + * {@link KanbanServiceImpl} 的单元测试类 + * + * @author 内蒙必硕 + */ +@Import(KanbanServiceImpl.class) +public class KanbanServiceImplTest extends BaseDbUnitTest { + + @Resource + private KanbanServiceImpl kanbanService; + + @Resource + private KanbanMapper kanbanMapper; + + @Test + public void testCreateKanban_success() { + // 准备参数 + KanbanSaveReqVO createReqVO = randomPojo(KanbanSaveReqVO.class).setId(null); + + // 调用 + Long kanbanId = kanbanService.createKanban(createReqVO); + // 断言 + assertNotNull(kanbanId); + // 校验记录的属性是否正确 + KanbanDO kanban = kanbanMapper.selectById(kanbanId); + assertPojoEquals(createReqVO, kanban, "id"); + } + + @Test + public void testUpdateKanban_success() { + // mock 数据 + KanbanDO dbKanban = randomPojo(KanbanDO.class); + kanbanMapper.insert(dbKanban);// @Sql: 先插入出一条存在的数据 + // 准备参数 + KanbanSaveReqVO updateReqVO = randomPojo(KanbanSaveReqVO.class, o -> { + o.setId(dbKanban.getId()); // 设置更新的 ID + }); + + // 调用 + kanbanService.updateKanban(updateReqVO); + // 校验是否更新正确 + KanbanDO kanban = kanbanMapper.selectById(updateReqVO.getId()); // 获取最新的 + assertPojoEquals(updateReqVO, kanban); + } + + @Test + public void testUpdateKanban_notExists() { + // 准备参数 + KanbanSaveReqVO updateReqVO = randomPojo(KanbanSaveReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> kanbanService.updateKanban(updateReqVO), KANBAN_NOT_EXISTS); + } + + @Test + public void testDeleteKanban_success() { + // mock 数据 + KanbanDO dbKanban = randomPojo(KanbanDO.class); + kanbanMapper.insert(dbKanban);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbKanban.getId(); + + // 调用 + kanbanService.deleteKanban(id); + // 校验数据不存在了 + assertNull(kanbanMapper.selectById(id)); + } + + @Test + public void testDeleteKanban_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> kanbanService.deleteKanban(id), KANBAN_NOT_EXISTS); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetKanbanPage() { + // mock 数据 + KanbanDO dbKanban = randomPojo(KanbanDO.class, o -> { // 等会查询到 + o.setCode(null); + o.setTitle(null); + o.setImg(null); + o.setRemark(null); + o.setIsEnable(null); + o.setCreateTime(null); + }); + kanbanMapper.insert(dbKanban); + // 测试 code 不匹配 + kanbanMapper.insert(cloneIgnoreId(dbKanban, o -> o.setCode(null))); + // 测试 title 不匹配 + kanbanMapper.insert(cloneIgnoreId(dbKanban, o -> o.setTitle(null))); + // 测试 img 不匹配 + kanbanMapper.insert(cloneIgnoreId(dbKanban, o -> o.setImg(null))); + // 测试 remark 不匹配 + kanbanMapper.insert(cloneIgnoreId(dbKanban, o -> o.setRemark(null))); + // 测试 isEnable 不匹配 + kanbanMapper.insert(cloneIgnoreId(dbKanban, o -> o.setIsEnable(null))); + // 测试 createTime 不匹配 + kanbanMapper.insert(cloneIgnoreId(dbKanban, o -> o.setCreateTime(null))); + // 准备参数 + KanbanPageReqVO reqVO = new KanbanPageReqVO(); + reqVO.setCode(null); + reqVO.setTitle(null); + reqVO.setImg(null); + reqVO.setRemark(null); + reqVO.setIsEnable(null); + reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); + + // 调用 + PageResult pageResult = kanbanService.getKanbanPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbKanban, pageResult.getList().get(0)); + } + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/test/resources/sql/clean.sql b/yudao-module-iot/yudao-module-iot-biz/src/test/resources/sql/clean.sql index 152915143..3e1936e76 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/test/resources/sql/clean.sql +++ b/yudao-module-iot/yudao-module-iot-biz/src/test/resources/sql/clean.sql @@ -1 +1,23 @@ -DELETE FROM "report_go_view_project"; \ No newline at end of file + +-- 将该删表 SQL 语句,添加到 yudao-module-iot-biz 模块的 test/resources/sql/clean.sql 文件里 +DELETE FROM "iot_device"; + +-- 将该删表 SQL 语句,添加到 yudao-module-iot-biz 模块的 test/resources/sql/clean.sql 文件里 +DELETE FROM "iot_formula"; + +-- 将该删表 SQL 语句,添加到 yudao-module-iot-biz 模块的 test/resources/sql/clean.sql 文件里 +DELETE FROM "iot_device_attribute"; + +-- 将该删表 SQL 语句,添加到 yudao-module-iot-biz 模块的 test/resources/sql/clean.sql 文件里 +DELETE FROM "iot_formula_detail"; + +-- 将该删表 SQL 语句,添加到 yudao-module-iot-biz 模块的 test/resources/sql/clean.sql 文件里 +DELETE FROM "iot_gateway"; + +-- 将该删表 SQL 语句,添加到 yudao-module-iot-biz 模块的 test/resources/sql/clean.sql 文件里 +DELETE FROM "iot_iot_organization"; +-- 将该删表 SQL 语句,添加到 yudao-module-iot-biz 模块的 test/resources/sql/clean.sql 文件里 +DELETE FROM "iot_kanban"; + +-- 将该删表 SQL 语句,添加到 yudao-module-mes-biz 模块的 test/resources/sql/clean.sql 文件里 +DELETE FROM "mes_machine_component"; \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/test/resources/sql/create_tables.sql b/yudao-module-iot/yudao-module-iot-biz/src/test/resources/sql/create_tables.sql index a77397fea..575033d30 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/test/resources/sql/create_tables.sql +++ b/yudao-module-iot/yudao-module-iot-biz/src/test/resources/sql/create_tables.sql @@ -1,14 +1,209 @@ -CREATE TABLE IF NOT EXISTS "report_go_view_project" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "name" varchar NOT NULL, - "pic_url" varchar, - "content" varchar, - "status" varchar NOT NULL, - "remark" varchar, - "creator" varchar DEFAULT '', +CREATE TABLE IF NOT EXISTS "iot_device" +( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "device_config_id" varchar, + "device_code" varchar, + "device_name" varchar, + "device_type" varchar, + "siemens_series" varchar, + "siemens_connect_param" varchar, + "read_cron_type" varchar, + "read_repeat_value" int, + "read_repeat_unit" varchar, + "read_cron" varchar, + "write_cron_type" varchar, + "write_repeat_value" int, + "write_repeat_unit" varchar, + "write_cron" varchar, + "local_persistent" varchar, + "upload_rate" varchar, + "rate_count" int, + "modbus_protocol" varchar, + "modbus_pattern" varchar, + "port_name" varchar, + "modbus_connect_param" varchar, + "modbus_read_addr_gap" varchar, + "is_upload" varchar, + "gateway_id" bigint NOT NULL, + "org_id" bigint NOT NULL, + "remark" varchar, + "is_enable" bit NOT NULL, + "creator" varchar DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint, + PRIMARY KEY ("id") +) COMMENT '物联设备表'; +CREATE TABLE IF NOT EXISTS "iot_formula" +( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "name" varchar, + "formula_code" varchar, + "formula" varchar, + "result_type" varchar, + "machine_id" bigint NOT NULL, + "remark" varchar, + "is_enable" bit NOT NULL, + "creator" varchar DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint, + PRIMARY KEY ("id") +) COMMENT '计算公式'; +CREATE TABLE IF NOT EXISTS "iot_device_attribute" +( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "attribute_code" varchar NOT NULL, + "address" varchar, + "attribute_name" varchar NOT NULL, + "description" varchar, + "address_type" varchar, + "address_offset" varchar, + "address2_type" varchar, + "address2_offset" varchar, + "group_name" varchar, + "group_id" int, + "security_type" varchar, + "io_status" varchar, + "is_linear_transfer" varchar, + "data_type" varchar, + "unit" varchar, + "in_min_value" varchar, + "in_max_value" varchar, + "out_min_value" varchar, + "out_max_value" varchar, + "out_data_type" varchar, + "siemens_field_precision" int, + "modbus_slave_id" varchar, + "modbus_field_address" varchar, + "modbus_address_type" varchar, + "modbus_field_size" varchar, + "modbus_field_precision" varchar, + "modbus_field_order" varchar, + "source_data_type" varchar, + "transfer_data_type" varchar, + "factor" varchar, + "gateway_id" bigint NOT NULL, + "device_id" bigint NOT NULL, + "org_id" bigint NOT NULL, + "remark" varchar, + "is_enable" bit NOT NULL, + "creator" varchar DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint, + PRIMARY KEY ("id") +) COMMENT '设备属性表'; +CREATE TABLE IF NOT EXISTS "iot_formula_detail" +( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "formula_id" bigint NOT NULL, + "formula_code" varchar, + "name" varchar, + "device_id" bigint NOT NULL, + "attribute_id" bigint NOT NULL, + "attribute_name" varchar NOT NULL, + "address" varchar, + "demo_value" varchar, + "sum_type" varchar, + "sum_range" varchar, + "remark" varchar, + "is_enable" bit NOT NULL, + "creator" varchar DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint, + PRIMARY KEY ("id") +) COMMENT '计算公式明细'; + +CREATE TABLE IF NOT EXISTS "iot_gateway" +( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "admin_ip" varchar, + "username" varchar, + "password" varchar, + "gateway_name" varchar, + "remark" varchar, + "is_enable" bit NOT NULL, + "creator" varchar DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint, + "gateway_code" varchar, + "gateway_status" varchar, + "topic" varchar, + PRIMARY KEY ("id") +) COMMENT '网关表'; +CREATE TABLE IF NOT EXISTS "iot_iot_organization" +( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "sort" int, + "worker_user_id" bigint, + "org_id" bigint, + "creator" varchar DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint NOT NULL, + "name" varchar NOT NULL, + "parent_id" bigint NOT NULL, + "status" int, + "device_type" varchar, + "org_class" varchar, + "machine_type" varchar, + PRIMARY KEY ("id") +) COMMENT 'IOT组织表'; +CREATE TABLE IF NOT EXISTS "iot_kanban" +( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "code" varchar NOT NULL, + "title" varchar NOT NULL, + "view_url" varchar, + "tags" varchar, + "img" varchar, + "remark" varchar, + "is_enable" bit NOT NULL, + "creator" varchar DEFAULT '', "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar DEFAULT '', + "updater" varchar DEFAULT '', "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint, + PRIMARY KEY ("id") +) COMMENT '物联看板'; + +CREATE TABLE IF NOT EXISTS "mes_machine_component" +( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "name" varchar NOT NULL, + "parent_id" bigint NOT NULL, + "sort" int NOT NULL, + "org_id" bigint NOT NULL, + "serial_code" varchar, + "outgoing_time" varchar, + "outgoing_report" varchar, + "position" varchar, + "standard" varchar, + "remark" varchar, + "creator" varchar DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint NOT NULL, + "status" int NOT NULL, + "component_type" int NOT NULL, + "machine_type" varchar, PRIMARY KEY ("id") -) COMMENT 'GoView 项目表'; +) COMMENT '机台组织表'; diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java index 0c9f084dc..e7d402108 100644 --- a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java +++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java @@ -38,4 +38,10 @@ public interface ErrorCodeConstants { ErrorCode WORK_TEAM_DETAIL_NOT_EXISTS = new ErrorCode(5_0071, "班组成员不存在"); ErrorCode PRODUCE_REPORT_NOT_EXISTS = new ErrorCode(5_008, "生产报工单不存在"); ErrorCode PRODUCE_REPORT_DETAIL_NOT_EXISTS = new ErrorCode(5_0081, "生产报工明细不存在"); + ErrorCode MACHINE_COMPONENT_EXITS_CHILDREN = new ErrorCode(5_008, "生产报工单不存在"); + ErrorCode MACHINE_COMPONENT_NOT_EXISTS = new ErrorCode(5_0081, "生产报工明细不存在"); + ErrorCode MACHINE_COMPONENT_PARENT_ERROR = new ErrorCode(5_0081, "生产报工明细不存在"); + ErrorCode MACHINE_COMPONENT_PARENT_NOT_EXITS = new ErrorCode(5_008, "生产报工单不存在"); + ErrorCode MACHINE_COMPONENT_PARENT_IS_CHILD = new ErrorCode(5_0081, "生产报工明细不存在"); + ErrorCode MACHINE_COMPONENT_NAME_DUPLICATE = new ErrorCode(5_0081, "生产报工明细不存在"); } diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/machine/MachineComponentController.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/machine/MachineComponentController.java new file mode 100644 index 000000000..e0b469fad --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/machine/MachineComponentController.java @@ -0,0 +1,93 @@ +package cn.iocoder.yudao.module.mes.controller.admin.machine; + +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 javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +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.machine.vo.*; +import cn.iocoder.yudao.module.mes.dal.dataobject.machine.MachineComponentDO; +import cn.iocoder.yudao.module.mes.service.machine.MachineComponentService; + +@Tag(name = "管理后台 - 机台") +@RestController +@RequestMapping("/mes/machine-component") +@Validated +public class MachineComponentController { + + @Resource + private MachineComponentService machineComponentService; + + @PostMapping("/create") + @Operation(summary = "创建机台") + @PreAuthorize("@ss.hasPermission('mes:machine-component:create')") + public CommonResult createMachineComponent(@Valid @RequestBody MachineComponentSaveReqVO createReqVO) { + return success(machineComponentService.createMachineComponent(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新机台") + @PreAuthorize("@ss.hasPermission('mes:machine-component:update')") + public CommonResult updateMachineComponent(@Valid @RequestBody MachineComponentSaveReqVO updateReqVO) { + machineComponentService.updateMachineComponent(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除机台") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('mes:machine-component:delete')") + public CommonResult deleteMachineComponent(@RequestParam("id") Long id) { + machineComponentService.deleteMachineComponent(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得机台") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('mes:machine-component:query')") + public CommonResult getMachineComponent(@RequestParam("id") Long id) { + MachineComponentDO machineComponent = machineComponentService.getMachineComponent(id); + return success(BeanUtils.toBean(machineComponent, MachineComponentRespVO.class)); + } + + @GetMapping("/list") + @Operation(summary = "获得机台列表") + @PreAuthorize("@ss.hasPermission('mes:machine-component:query')") + public CommonResult> getMachineComponentList(@Valid MachineComponentListReqVO listReqVO) { + List list = machineComponentService.getMachineComponentList(listReqVO); + return success(BeanUtils.toBean(list, MachineComponentRespVO.class)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出机台 Excel") + @PreAuthorize("@ss.hasPermission('mes:machine-component:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportMachineComponentExcel(@Valid MachineComponentListReqVO listReqVO, + HttpServletResponse response) throws IOException { + List list = machineComponentService.getMachineComponentList(listReqVO); + // 导出 Excel + ExcelUtils.write(response, "机台.xls", "数据", MachineComponentRespVO.class, + BeanUtils.toBean(list, MachineComponentRespVO.class)); + } + +} \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/machine/vo/MachineComponentListReqVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/machine/vo/MachineComponentListReqVO.java new file mode 100644 index 000000000..3cd86b701 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/machine/vo/MachineComponentListReqVO.java @@ -0,0 +1,60 @@ +package cn.iocoder.yudao.module.mes.controller.admin.machine.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import java.time.LocalDateTime; +import org.springframework.format.annotation.DateTimeFormat; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 机台列表 Request VO") +@Data +public class MachineComponentListReqVO { + + @Schema(description = "装备名称", example = "芋艿") + private String name; + + @Schema(description = "父id", example = "24628") + private Long parentId; + + @Schema(description = "显示顺序") + private Integer sort; + + @Schema(description = "组织机台ID", example = "13753") + private Long orgId; + + @Schema(description = "装备SN号") + private String serialCode; + + @Schema(description = "出厂日期") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] outgoingTime; + + @Schema(description = "出厂报告") + private String outgoingReport; + + @Schema(description = "位置") + private String position; + + @Schema(description = "规格") + private String standard; + + @Schema(description = "备注", example = "你猜") + private String remark; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + + @Schema(description = "状态", example = "1") + private Integer status; + + @Schema(description = "组织类型", example = "1") + private Integer componentType; + + @Schema(description = "机台类型", example = "1") + private String machineType; + +} \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/machine/vo/MachineComponentRespVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/machine/vo/MachineComponentRespVO.java new file mode 100644 index 000000000..6d24db824 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/machine/vo/MachineComponentRespVO.java @@ -0,0 +1,81 @@ +package cn.iocoder.yudao.module.mes.controller.admin.machine.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.util.*; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; +import com.alibaba.excel.annotation.*; +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; + +@Schema(description = "管理后台 - 机台 Response VO") +@Data +@ExcelIgnoreUnannotated +public class MachineComponentRespVO { + + @Schema(description = "装备id", requiredMode = Schema.RequiredMode.REQUIRED, example = "12527") + @ExcelProperty("装备id") + private Long id; + + @Schema(description = "装备名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") + @ExcelProperty("装备名称") + private String name; + + @Schema(description = "父id", requiredMode = Schema.RequiredMode.REQUIRED, example = "24628") + @ExcelProperty("父id") + private Long parentId; + + @Schema(description = "显示顺序", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("显示顺序") + private Integer sort; + + @Schema(description = "组织机台ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "13753") + @ExcelProperty("组织机台ID") + private Long orgId; + + @Schema(description = "装备SN号") + @ExcelProperty("装备SN号") + private String serialCode; + + @Schema(description = "出厂日期") + @ExcelProperty("出厂日期") + private LocalDateTime outgoingTime; + + @Schema(description = "出厂报告") + @ExcelProperty("出厂报告") + private String outgoingReport; + + @Schema(description = "位置") + @ExcelProperty("位置") + private String position; + + @Schema(description = "规格") + @ExcelProperty("规格") + private String standard; + + @Schema(description = "备注", example = "你猜") + @ExcelProperty("备注") + private String remark; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @ExcelProperty(value = "状态", converter = DictConvert.class) + @DictFormat("mes_machine_status") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 + private Integer status; + + @Schema(description = "组织类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @ExcelProperty(value = "组织类型", converter = DictConvert.class) + @DictFormat("mes_machine_type") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 + private Integer componentType; + + @Schema(description = "机台类型", example = "1") + @ExcelProperty(value = "机台类型", converter = DictConvert.class) + @DictFormat("mes_org_type") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 + private String machineType; + +} \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/machine/vo/MachineComponentSaveReqVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/machine/vo/MachineComponentSaveReqVO.java new file mode 100644 index 000000000..9b4f85468 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/machine/vo/MachineComponentSaveReqVO.java @@ -0,0 +1,62 @@ +package cn.iocoder.yudao.module.mes.controller.admin.machine.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 机台新增/修改 Request VO") +@Data +public class MachineComponentSaveReqVO { + + @Schema(description = "装备id", requiredMode = Schema.RequiredMode.REQUIRED, example = "12527") + private Long id; + + @Schema(description = "装备名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") + @NotEmpty(message = "装备名称不能为空") + private String name; + + @Schema(description = "父id", requiredMode = Schema.RequiredMode.REQUIRED, example = "24628") + @NotNull(message = "父id不能为空") + private Long parentId; + + @Schema(description = "显示顺序", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "显示顺序不能为空") + private Integer sort; + + @Schema(description = "组织机台ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "13753") + @NotNull(message = "组织机台ID不能为空") + private Long orgId; + + @Schema(description = "装备SN号") + private String serialCode; + + @Schema(description = "出厂日期") + private LocalDateTime outgoingTime; + + @Schema(description = "出厂报告") + private String outgoingReport; + + @Schema(description = "位置") + private String position; + + @Schema(description = "规格") + private String standard; + + @Schema(description = "备注", example = "你猜") + private String remark; + + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "状态不能为空") + private Integer status; + + @Schema(description = "组织类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "组织类型不能为空") + private Integer componentType; + + @Schema(description = "机台类型", example = "1") + private String machineType; + +} \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/machine/MachineComponentDO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/machine/MachineComponentDO.java new file mode 100644 index 000000000..b2db2e724 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/machine/MachineComponentDO.java @@ -0,0 +1,92 @@ +package cn.iocoder.yudao.module.mes.dal.dataobject.machine; + +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +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_machine_component") +@KeySequence("mes_machine_component_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MachineComponentDO extends BaseDO { + + public static final Long PARENT_ID_ROOT = 0L; + + /** + * 装备id + */ + @TableId + private Long id; + /** + * 装备名称 + */ + private String name; + /** + * 父id + */ + private Long parentId; + /** + * 显示顺序 + */ + private Integer sort; + /** + * 组织机台ID + */ + private Long orgId; + /** + * 装备SN号 + */ + private String serialCode; + /** + * 出厂日期 + */ + private LocalDateTime outgoingTime; + /** + * 出厂报告 + */ + private String outgoingReport; + /** + * 位置 + */ + private String position; + /** + * 规格 + */ + private String standard; + /** + * 备注 + */ + private String remark; + /** + * 状态 + * + * 枚举 {@link TODO mes_machine_status 对应的类} + */ + private Integer status; + /** + * 组织类型 + * + * 枚举 {@link TODO mes_machine_type 对应的类} + */ + private Integer componentType; + /** + * 机台类型 + * + * 枚举 {@link TODO mes_org_type 对应的类} + */ + private String machineType; + +} \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/machine/MachineComponentMapper.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/machine/MachineComponentMapper.java new file mode 100644 index 000000000..b87d3c24f --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/machine/MachineComponentMapper.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.module.mes.dal.mysql.machine; + +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.machine.MachineComponentDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.mes.controller.admin.machine.vo.*; + +/** + * 机台 Mapper + * + * @author 内蒙必硕 + */ +@Mapper +public interface MachineComponentMapper extends BaseMapperX { + + default List selectList(MachineComponentListReqVO reqVO) { + return selectList(new LambdaQueryWrapperX() + .likeIfPresent(MachineComponentDO::getName, reqVO.getName()) + .eqIfPresent(MachineComponentDO::getParentId, reqVO.getParentId()) + .eqIfPresent(MachineComponentDO::getSort, reqVO.getSort()) + .eqIfPresent(MachineComponentDO::getOrgId, reqVO.getOrgId()) + .eqIfPresent(MachineComponentDO::getSerialCode, reqVO.getSerialCode()) + .betweenIfPresent(MachineComponentDO::getOutgoingTime, reqVO.getOutgoingTime()) + .eqIfPresent(MachineComponentDO::getOutgoingReport, reqVO.getOutgoingReport()) + .eqIfPresent(MachineComponentDO::getPosition, reqVO.getPosition()) + .eqIfPresent(MachineComponentDO::getStandard, reqVO.getStandard()) + .eqIfPresent(MachineComponentDO::getRemark, reqVO.getRemark()) + .betweenIfPresent(MachineComponentDO::getCreateTime, reqVO.getCreateTime()) + .eqIfPresent(MachineComponentDO::getStatus, reqVO.getStatus()) + .eqIfPresent(MachineComponentDO::getComponentType, reqVO.getComponentType()) + .eqIfPresent(MachineComponentDO::getMachineType, reqVO.getMachineType()) + .orderByDesc(MachineComponentDO::getId)); + } + + default MachineComponentDO selectByParentIdAndName(Long parentId, String name) { + return selectOne(MachineComponentDO::getParentId, parentId, MachineComponentDO::getName, name); + } + + default Long selectCountByParentId(Long parentId) { + return selectCount(MachineComponentDO::getParentId, parentId); + } + +} \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/machine/MachineComponentService.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/machine/MachineComponentService.java new file mode 100644 index 000000000..162e26345 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/machine/MachineComponentService.java @@ -0,0 +1,56 @@ +package cn.iocoder.yudao.module.mes.service.machine; + +import java.util.*; +import cn.iocoder.yudao.module.mes.controller.admin.machine.vo.*; +import cn.iocoder.yudao.module.mes.dal.dataobject.machine.MachineComponentDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; + +import javax.validation.Valid; + +/** + * 机台 Service 接口 + * + * @author 内蒙必硕 + */ +public interface MachineComponentService { + + /** + * 创建机台 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createMachineComponent(@Valid MachineComponentSaveReqVO createReqVO); + + /** + * 更新机台 + * + * @param updateReqVO 更新信息 + */ + void updateMachineComponent(@Valid MachineComponentSaveReqVO updateReqVO); + + /** + * 删除机台 + * + * @param id 编号 + */ + void deleteMachineComponent(Long id); + + /** + * 获得机台 + * + * @param id 编号 + * @return 机台 + */ + MachineComponentDO getMachineComponent(Long id); + + /** + * 获得机台列表 + * + * @param listReqVO 查询条件 + * @return 机台列表 + */ + List getMachineComponentList(MachineComponentListReqVO listReqVO); + +} \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/machine/MachineComponentServiceImpl.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/machine/MachineComponentServiceImpl.java new file mode 100644 index 000000000..214cdf690 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/machine/MachineComponentServiceImpl.java @@ -0,0 +1,138 @@ +package cn.iocoder.yudao.module.mes.service.machine; + +import org.springframework.stereotype.Service; + +import org.springframework.validation.annotation.Validated; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import cn.iocoder.yudao.module.mes.controller.admin.machine.vo.*; +import cn.iocoder.yudao.module.mes.dal.dataobject.machine.MachineComponentDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; + +import cn.iocoder.yudao.module.mes.dal.mysql.machine.MachineComponentMapper; + +import javax.annotation.Resource; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; + +/** + * 机台 Service 实现类 + * + * @author 内蒙必硕 + */ +@Service +@Validated +public class MachineComponentServiceImpl implements MachineComponentService { + + @Resource + private MachineComponentMapper machineComponentMapper; + + @Override + public Long createMachineComponent(MachineComponentSaveReqVO createReqVO) { + // 校验父id的有效性 + validateParentMachineComponent(null, createReqVO.getParentId()); + // 校验装备名称的唯一性 + validateMachineComponentNameUnique(null, createReqVO.getParentId(), createReqVO.getName()); + + // 插入 + MachineComponentDO machineComponent = BeanUtils.toBean(createReqVO, MachineComponentDO.class); + machineComponentMapper.insert(machineComponent); + // 返回 + return machineComponent.getId(); + } + + @Override + public void updateMachineComponent(MachineComponentSaveReqVO updateReqVO) { + // 校验存在 + validateMachineComponentExists(updateReqVO.getId()); + // 校验父id的有效性 + validateParentMachineComponent(updateReqVO.getId(), updateReqVO.getParentId()); + // 校验装备名称的唯一性 + validateMachineComponentNameUnique(updateReqVO.getId(), updateReqVO.getParentId(), updateReqVO.getName()); + + // 更新 + MachineComponentDO updateObj = BeanUtils.toBean(updateReqVO, MachineComponentDO.class); + machineComponentMapper.updateById(updateObj); + } + + @Override + public void deleteMachineComponent(Long id) { + // 校验存在 + validateMachineComponentExists(id); + // 校验是否有子机台 + if (machineComponentMapper.selectCountByParentId(id) > 0) { + throw exception(MACHINE_COMPONENT_EXITS_CHILDREN); + } + // 删除 + machineComponentMapper.deleteById(id); + } + + private void validateMachineComponentExists(Long id) { + if (machineComponentMapper.selectById(id) == null) { + throw exception(MACHINE_COMPONENT_NOT_EXISTS); + } + } + + private void validateParentMachineComponent(Long id, Long parentId) { + if (parentId == null || MachineComponentDO.PARENT_ID_ROOT.equals(parentId)) { + return; + } + // 1. 不能设置自己为父机台 + if (Objects.equals(id, parentId)) { + throw exception(MACHINE_COMPONENT_PARENT_ERROR); + } + // 2. 父机台不存在 + MachineComponentDO parentMachineComponent = machineComponentMapper.selectById(parentId); + if (parentMachineComponent == null) { + throw exception(MACHINE_COMPONENT_PARENT_NOT_EXITS); + } + // 3. 递归校验父机台,如果父机台是自己的子机台,则报错,避免形成环路 + if (id == null) { // id 为空,说明新增,不需要考虑环路 + return; + } + for (int i = 0; i < Short.MAX_VALUE; i++) { + // 3.1 校验环路 + parentId = parentMachineComponent.getParentId(); + if (Objects.equals(id, parentId)) { + throw exception(MACHINE_COMPONENT_PARENT_IS_CHILD); + } + // 3.2 继续递归下一级父机台 + if (parentId == null || MachineComponentDO.PARENT_ID_ROOT.equals(parentId)) { + break; + } + parentMachineComponent = machineComponentMapper.selectById(parentId); + if (parentMachineComponent == null) { + break; + } + } + } + + private void validateMachineComponentNameUnique(Long id, Long parentId, String name) { + MachineComponentDO machineComponent = machineComponentMapper.selectByParentIdAndName(parentId, name); + if (machineComponent == null) { + return; + } + // 如果 id 为空,说明不用比较是否为相同 id 的机台 + if (id == null) { + throw exception(MACHINE_COMPONENT_NAME_DUPLICATE); + } + if (!Objects.equals(machineComponent.getId(), id)) { + throw exception(MACHINE_COMPONENT_NAME_DUPLICATE); + } + } + + @Override + public MachineComponentDO getMachineComponent(Long id) { + return machineComponentMapper.selectById(id); + } + + @Override + public List getMachineComponentList(MachineComponentListReqVO listReqVO) { + return machineComponentMapper.selectList(listReqVO); + } + +} \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/resources/mapper/machine/MachineComponentMapper.xml b/yudao-module-mes/yudao-module-mes-biz/src/main/resources/mapper/machine/MachineComponentMapper.xml new file mode 100644 index 000000000..7fa8dc26a --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/resources/mapper/machine/MachineComponentMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/test/java/cn/iocoder/yudao/module/mes/service/machine/MachineComponentServiceImplTest.java b/yudao-module-mes/yudao-module-mes-biz/src/test/java/cn/iocoder/yudao/module/mes/service/machine/MachineComponentServiceImplTest.java new file mode 100644 index 000000000..73ebacbfd --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/test/java/cn/iocoder/yudao/module/mes/service/machine/MachineComponentServiceImplTest.java @@ -0,0 +1,181 @@ +package cn.iocoder.yudao.module.mes.service.machine; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; + + + +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; + +import cn.iocoder.yudao.module.mes.controller.admin.machine.vo.*; +import cn.iocoder.yudao.module.mes.dal.dataobject.machine.MachineComponentDO; +import cn.iocoder.yudao.module.mes.dal.mysql.machine.MachineComponentMapper; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import javax.annotation.Resource; +import org.springframework.context.annotation.Import; +import java.util.*; +import java.time.LocalDateTime; + +import static cn.hutool.core.util.RandomUtil.*; +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +/** + * {@link MachineComponentServiceImpl} 的单元测试类 + * + * @author 内蒙必硕 + */ +@Import(MachineComponentServiceImpl.class) +public class MachineComponentServiceImplTest extends BaseDbUnitTest { + + @Resource + private MachineComponentServiceImpl machineComponentService; + + @Resource + private MachineComponentMapper machineComponentMapper; + + @Test + public void testCreateMachineComponent_success() { + // 准备参数 + MachineComponentSaveReqVO createReqVO = randomPojo(MachineComponentSaveReqVO.class).setId(null); + + // 调用 + Long machineComponentId = machineComponentService.createMachineComponent(createReqVO); + // 断言 + assertNotNull(machineComponentId); + // 校验记录的属性是否正确 + MachineComponentDO machineComponent = machineComponentMapper.selectById(machineComponentId); + assertPojoEquals(createReqVO, machineComponent, "id"); + } + + @Test + public void testUpdateMachineComponent_success() { + // mock 数据 + MachineComponentDO dbMachineComponent = randomPojo(MachineComponentDO.class); + machineComponentMapper.insert(dbMachineComponent);// @Sql: 先插入出一条存在的数据 + // 准备参数 + MachineComponentSaveReqVO updateReqVO = randomPojo(MachineComponentSaveReqVO.class, o -> { + o.setId(dbMachineComponent.getId()); // 设置更新的 ID + }); + + // 调用 + machineComponentService.updateMachineComponent(updateReqVO); + // 校验是否更新正确 + MachineComponentDO machineComponent = machineComponentMapper.selectById(updateReqVO.getId()); // 获取最新的 + assertPojoEquals(updateReqVO, machineComponent); + } + + @Test + public void testUpdateMachineComponent_notExists() { + // 准备参数 + MachineComponentSaveReqVO updateReqVO = randomPojo(MachineComponentSaveReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> machineComponentService.updateMachineComponent(updateReqVO), MACHINE_COMPONENT_NOT_EXISTS); + } + + @Test + public void testDeleteMachineComponent_success() { + // mock 数据 + MachineComponentDO dbMachineComponent = randomPojo(MachineComponentDO.class); + machineComponentMapper.insert(dbMachineComponent);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbMachineComponent.getId(); + + // 调用 + machineComponentService.deleteMachineComponent(id); + // 校验数据不存在了 + assertNull(machineComponentMapper.selectById(id)); + } + + @Test + public void testDeleteMachineComponent_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> machineComponentService.deleteMachineComponent(id), MACHINE_COMPONENT_NOT_EXISTS); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetMachineComponentList() { + // mock 数据 + MachineComponentDO dbMachineComponent = randomPojo(MachineComponentDO.class, o -> { // 等会查询到 + o.setName(null); + o.setParentId(null); + o.setSort(null); + o.setOrgId(null); + o.setSerialCode(null); + o.setOutgoingTime(null); + o.setOutgoingReport(null); + o.setPosition(null); + o.setStandard(null); + o.setRemark(null); + o.setCreateTime(null); + o.setStatus(null); + o.setComponentType(null); + o.setMachineType(null); + }); + machineComponentMapper.insert(dbMachineComponent); + // 测试 name 不匹配 + machineComponentMapper.insert(cloneIgnoreId(dbMachineComponent, o -> o.setName(null))); + // 测试 parentId 不匹配 + machineComponentMapper.insert(cloneIgnoreId(dbMachineComponent, o -> o.setParentId(null))); + // 测试 sort 不匹配 + machineComponentMapper.insert(cloneIgnoreId(dbMachineComponent, o -> o.setSort(null))); + // 测试 orgId 不匹配 + machineComponentMapper.insert(cloneIgnoreId(dbMachineComponent, o -> o.setOrgId(null))); + // 测试 serialCode 不匹配 + machineComponentMapper.insert(cloneIgnoreId(dbMachineComponent, o -> o.setSerialCode(null))); + // 测试 outgoingTime 不匹配 + machineComponentMapper.insert(cloneIgnoreId(dbMachineComponent, o -> o.setOutgoingTime(null))); + // 测试 outgoingReport 不匹配 + machineComponentMapper.insert(cloneIgnoreId(dbMachineComponent, o -> o.setOutgoingReport(null))); + // 测试 position 不匹配 + machineComponentMapper.insert(cloneIgnoreId(dbMachineComponent, o -> o.setPosition(null))); + // 测试 standard 不匹配 + machineComponentMapper.insert(cloneIgnoreId(dbMachineComponent, o -> o.setStandard(null))); + // 测试 remark 不匹配 + machineComponentMapper.insert(cloneIgnoreId(dbMachineComponent, o -> o.setRemark(null))); + // 测试 createTime 不匹配 + machineComponentMapper.insert(cloneIgnoreId(dbMachineComponent, o -> o.setCreateTime(null))); + // 测试 status 不匹配 + machineComponentMapper.insert(cloneIgnoreId(dbMachineComponent, o -> o.setStatus(null))); + // 测试 componentType 不匹配 + machineComponentMapper.insert(cloneIgnoreId(dbMachineComponent, o -> o.setComponentType(null))); + // 测试 machineType 不匹配 + machineComponentMapper.insert(cloneIgnoreId(dbMachineComponent, o -> o.setMachineType(null))); + // 准备参数 + MachineComponentListReqVO reqVO = new MachineComponentListReqVO(); + reqVO.setName(null); + reqVO.setParentId(null); + reqVO.setSort(null); + reqVO.setOrgId(null); + reqVO.setSerialCode(null); + reqVO.setOutgoingTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); + reqVO.setOutgoingReport(null); + reqVO.setPosition(null); + reqVO.setStandard(null); + reqVO.setRemark(null); + reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); + reqVO.setStatus(null); + reqVO.setComponentType(null); + reqVO.setMachineType(null); + + // 调用 + List list = machineComponentService.getMachineComponentList(reqVO); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(dbMachineComponent, list.get(0)); + } + +} \ No newline at end of file diff --git a/yudao-server/pom.xml b/yudao-server/pom.xml index 8884e86b6..b6e9cf6d3 100644 --- a/yudao-server/pom.xml +++ b/yudao-server/pom.xml @@ -119,6 +119,12 @@ yudao-module-mes-biz ${revision} + + + cn.iocoder.boot + yudao-module-iot-biz + ${revision} + diff --git a/yudao-server/src/main/java/cn/iocoder/yudao/server/controller/DefaultController.java b/yudao-server/src/main/java/cn/iocoder/yudao/server/controller/DefaultController.java index a9e690853..46ed3c7fd 100644 --- a/yudao-server/src/main/java/cn/iocoder/yudao/server/controller/DefaultController.java +++ b/yudao-server/src/main/java/cn/iocoder/yudao/server/controller/DefaultController.java @@ -58,5 +58,14 @@ public class DefaultController { return CommonResult.error(NOT_IMPLEMENTED.getCode(), "[支付模块 yudao-module-pay - 已禁用][参考 https://doc.iocoder.cn/pay/build/ 开启]"); } - + @RequestMapping(value = {"/admin-api/iot/**"}) + public CommonResult iot404() { + return CommonResult.error(NOT_IMPLEMENTED.getCode(), + "[iot模块 yudao-module-pay - 已禁用][参考 https://doc.iocoder.cn/pay/build/ 开启]"); + } + @RequestMapping(value = {"/admin-api/mes/**"}) + public CommonResult mes404() { + return CommonResult.error(NOT_IMPLEMENTED.getCode(), + "[mes模块 yudao-module-pay - 已禁用][参考 https://doc.iocoder.cn/pay/build/ 开启]"); + } }