feat(config): 添加新环境配置并扩展设备台账功能
- 添加 application-dlsmls-pro.yml 新环境配置文件
- 修改 application-dev.yml 中数据库连接URL
- 在 DeviceLedger 实体类中增加 areaId、isIotDevice 和 externalCode 字段
- 在 DeviceLedgerDto 中添加物联网设备标识和外部编码属性
- 更新 DeviceLedgerMapper.xml 查询逻辑,关联设备区域表并添加过滤条件
- 在 DeviceMaintenance 相关实体类中增加区域ID字段支持
- 修改 DeviceMaintenanceMapper.xml 查询语句,关联设备区域信息
- 扩展 DeviceMaintenanceServiceImpl 中的保存和更新方法
- 在 InspectionTask 实体类中添加巡检状态和区域ID字段
- 增加 InspectionTask 的分页查询和记录查询功能
- 添加 JclyController 控制器类用于HTTP服务接口
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.device.controller; |
| | | |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.ruoyi.device.pojo.DeviceArea; |
| | | import com.ruoyi.device.service.IDeviceAreaService; |
| | | import com.ruoyi.framework.aspectj.lang.annotation.Log; |
| | | import com.ruoyi.framework.aspectj.lang.enums.BusinessType; |
| | | import com.ruoyi.framework.web.domain.AjaxResult; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Api(tags = "设å¤åºå管ç") |
| | | @RestController |
| | | @RequestMapping("/device/area") |
| | | public class DeviceAreaController { |
| | | |
| | | @Autowired |
| | | private IDeviceAreaService deviceAreaService; |
| | | |
| | | @GetMapping("/tree") |
| | | @ApiOperation("设å¤åºåæ ") |
| | | public AjaxResult tree() { |
| | | return AjaxResult.success(deviceAreaService.listTree()); |
| | | } |
| | | |
| | | @GetMapping("/treeWithDevices") |
| | | @ApiOperation("设å¤åºåæ -å
å«è®¾å¤å表") |
| | | public AjaxResult treeWithDevices() { |
| | | return AjaxResult.success(deviceAreaService.listTreeWithDevices()); |
| | | } |
| | | |
| | | @GetMapping("/page") |
| | | @ApiOperation("设å¤åºåå页") |
| | | public AjaxResult page(Page page, DeviceArea deviceArea) { |
| | | return AjaxResult.success(deviceAreaService.queryPage(page, deviceArea)); |
| | | } |
| | | |
| | | @GetMapping("/{id}") |
| | | @ApiOperation("设å¤åºå详æ
") |
| | | public AjaxResult detail(@PathVariable Long id) { |
| | | return AjaxResult.success(deviceAreaService.getById(id)); |
| | | } |
| | | |
| | | @PostMapping |
| | | @ApiOperation("æ°å¢è®¾å¤åºå") |
| | | @Log(title = "设å¤åºå", businessType = BusinessType.INSERT) |
| | | public AjaxResult add(@RequestBody DeviceArea deviceArea) { |
| | | return deviceAreaService.saveDeviceArea(deviceArea); |
| | | } |
| | | |
| | | @PutMapping |
| | | @ApiOperation("ä¿®æ¹è®¾å¤åºå") |
| | | @Log(title = "设å¤åºå", businessType = BusinessType.UPDATE) |
| | | public AjaxResult update(@RequestBody DeviceArea deviceArea) { |
| | | return deviceAreaService.updateDeviceArea(deviceArea); |
| | | } |
| | | |
| | | @DeleteMapping |
| | | @ApiOperation("å é¤è®¾å¤åºå") |
| | | @Log(title = "设å¤åºå", businessType = BusinessType.DELETE) |
| | | public AjaxResult delete(@RequestBody List<Long> ids) { |
| | | return deviceAreaService.removeDeviceAreas(ids); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.device.dto; |
| | | |
| | | import com.ruoyi.device.pojo.DeviceLedger; |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Data |
| | | public class DeviceAreaTreeDto { |
| | | |
| | | private Long id; |
| | | |
| | | private Long parentId; |
| | | |
| | | private String areaName; |
| | | |
| | | private String label; |
| | | |
| | | private Long sort; |
| | | |
| | | private String remark; |
| | | |
| | | private List<DeviceLedger> deviceList; |
| | | |
| | | private List<DeviceAreaTreeDto> children; |
| | | } |
| | |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import com.ruoyi.dto.DateQueryDto; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | |
| | | |
| | | @Schema(description = "设å¤ç±»å") |
| | | private String type; |
| | | |
| | | @ApiModelProperty("æ¯å¦ä¸ºç©èè®¾å¤ 0-å¦ 1-æ¯") |
| | | private Integer isIotDevice; |
| | | |
| | | @ApiModelProperty("å¤é¨ç¼ç ") |
| | | private String externalCode; |
| | | |
| | | @Schema(description = "设å¤åºåID") |
| | | private Long areaId; |
| | | |
| | | @Schema(description = "设å¤åºååç§°") |
| | | @TableField(exist = false) |
| | | private String areaName; |
| | | } |
| | |
| | | @Data |
| | | public class DeviceMaintenanceDto extends DeviceMaintenance { |
| | | |
| | | @Schema(description = "设å¤åºååç§°") |
| | | private String areaName; |
| | | |
| | | |
| | | @Schema(description = "设å¤ä¿å
»id") |
| | | private Long id; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.device.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.ruoyi.device.pojo.DeviceArea; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | | @Mapper |
| | | public interface DeviceAreaMapper extends BaseMapper<DeviceArea> { |
| | | |
| | | IPage<DeviceArea> queryPage(Page page, @Param("deviceArea") DeviceArea deviceArea); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.device.pojo; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.*; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | @Data |
| | | @TableName("device_area") |
| | | @ApiModel("设å¤åºå") |
| | | public class DeviceArea { |
| | | |
| | | @TableId(value = "id", type = IdType.AUTO) |
| | | private Long id; |
| | | |
| | | @ApiModelProperty("åºååç§°") |
| | | private String areaName; |
| | | |
| | | @ApiModelProperty("ç¶çº§ID") |
| | | private Long parentId; |
| | | |
| | | @ApiModelProperty("æåº") |
| | | private Long sort; |
| | | |
| | | @ApiModelProperty("夿³¨") |
| | | private String remark; |
| | | |
| | | @ApiModelProperty("å建æ¶é´") |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private LocalDateTime createTime; |
| | | |
| | | @ApiModelProperty("æ´æ°æ¶é´") |
| | | @TableField(fill = FieldFill.INSERT_UPDATE) |
| | | private LocalDateTime updateTime; |
| | | |
| | | @ApiModelProperty("åå»ºç¨æ·") |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Integer createUser; |
| | | |
| | | @ApiModelProperty("æ´æ°ç¨æ·") |
| | | @TableField(fill = FieldFill.INSERT_UPDATE) |
| | | private Integer updateUser; |
| | | |
| | | @ApiModelProperty("ç§æ·ID") |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Long tenantId; |
| | | |
| | | @ApiModelProperty("é¨é¨ID") |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Long deptId; |
| | | |
| | | @TableField(exist = false) |
| | | @ApiModelProperty("ç¶çº§åç§°") |
| | | private String parentName; |
| | | } |
| | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | |
| | | * ä¾åºååç§° |
| | | */ |
| | | private String supplierName; |
| | | |
| | | private Long areaId; |
| | | |
| | | /** |
| | | * åä½ |
| | |
| | | |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Long deptId; |
| | | |
| | | @ApiModelProperty("æ¯å¦ä¸ºç©èè®¾å¤ 0-å¦ 1-æ¯") |
| | | private Integer isIotDevice; |
| | | |
| | | @ApiModelProperty("å¤é¨ç¼ç ") |
| | | private String externalCode; |
| | | } |
| | |
| | | @Schema(description = "设å¤å°è´¦id") |
| | | private Long deviceLedgerId; |
| | | |
| | | @Schema(description = "设å¤åºåID") |
| | | private Long areaId; |
| | | |
| | | @Schema(description = "ä¿å
»ä»»å¡id") |
| | | private Long maintenanceTaskId; |
| | | |
| | |
| | | @Schema(description = "设å¤å°è´¦id") |
| | | private Long deviceLedgerId; |
| | | |
| | | @Schema(description = "设å¤åºåID") |
| | | private Long areaId; |
| | | |
| | | private String deviceName; |
| | | |
| | | private String deviceModel; |
| | |
| | | @TableId(type = IdType.AUTO) |
| | | private Long id; |
| | | |
| | | @Schema(description = "设å¤åºåID") |
| | | private Long areaId; |
| | | |
| | | @Schema(description = "设å¤åç§°") |
| | | @Excel(name = "ä¿å
»ä»»å¡åç§°") |
| | | private String taskName; |
| | |
| | | |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Long deptId; |
| | | |
| | | @TableField(exist = false) |
| | | private String areaName; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.device.service; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.ruoyi.device.dto.DeviceAreaTreeDto; |
| | | import com.ruoyi.device.pojo.DeviceArea; |
| | | import com.ruoyi.framework.web.domain.AjaxResult; |
| | | |
| | | import java.util.List; |
| | | |
| | | public interface IDeviceAreaService extends IService<DeviceArea> { |
| | | |
| | | IPage<DeviceArea> queryPage(Page page, DeviceArea deviceArea); |
| | | |
| | | List<DeviceAreaTreeDto> listTree(); |
| | | |
| | | List<DeviceAreaTreeDto> listTreeWithDevices(); |
| | | |
| | | AjaxResult saveDeviceArea(DeviceArea deviceArea); |
| | | |
| | | AjaxResult updateDeviceArea(DeviceArea deviceArea); |
| | | |
| | | AjaxResult removeDeviceAreas(List<Long> ids); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.device.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.common.utils.bean.BeanUtils; |
| | | import com.ruoyi.device.dto.DeviceAreaTreeDto; |
| | | import com.ruoyi.device.mapper.DeviceAreaMapper; |
| | | import com.ruoyi.device.mapper.DeviceLedgerMapper; |
| | | import com.ruoyi.device.pojo.DeviceArea; |
| | | import com.ruoyi.device.pojo.DeviceLedger; |
| | | import com.ruoyi.device.service.IDeviceAreaService; |
| | | import com.ruoyi.framework.web.domain.AjaxResult; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.util.CollectionUtils; |
| | | |
| | | import java.util.*; |
| | | |
| | | @Service |
| | | public class DeviceAreaServiceImpl extends ServiceImpl<DeviceAreaMapper, DeviceArea> implements IDeviceAreaService { |
| | | |
| | | @Autowired |
| | | private DeviceAreaMapper deviceAreaMapper; |
| | | |
| | | @Autowired |
| | | private DeviceLedgerMapper deviceLedgerMapper; |
| | | |
| | | @Override |
| | | public IPage<DeviceArea> queryPage(Page page, DeviceArea deviceArea) { |
| | | return deviceAreaMapper.queryPage(page, deviceArea); |
| | | } |
| | | |
| | | @Override |
| | | public List<DeviceAreaTreeDto> listTree() { |
| | | return buildTree(Collections.emptyMap()); |
| | | } |
| | | |
| | | @Override |
| | | public List<DeviceAreaTreeDto> listTreeWithDevices() { |
| | | LambdaQueryWrapper<DeviceLedger> queryWrapper = new LambdaQueryWrapper<>(); |
| | | queryWrapper.isNotNull(DeviceLedger::getAreaId); |
| | | queryWrapper.orderByAsc(DeviceLedger::getId); |
| | | List<DeviceLedger> deviceLedgers = deviceLedgerMapper.selectList(queryWrapper); |
| | | |
| | | Map<Long, List<DeviceLedger>> deviceMap = new HashMap<>(); |
| | | for (DeviceLedger deviceLedger : deviceLedgers) { |
| | | deviceMap.computeIfAbsent(deviceLedger.getAreaId(), key -> new ArrayList<>()).add(deviceLedger); |
| | | } |
| | | return buildTree(deviceMap); |
| | | } |
| | | |
| | | @Override |
| | | public AjaxResult saveDeviceArea(DeviceArea deviceArea) { |
| | | if (deviceArea == null || !StringUtils.hasText(deviceArea.getAreaName())) { |
| | | return AjaxResult.error("åºååç§°ä¸è½ä¸ºç©º"); |
| | | } |
| | | normalizeDeviceArea(deviceArea); |
| | | if (existsSameName(deviceArea.getParentId(), deviceArea.getAreaName(), null)) { |
| | | return AjaxResult.error("å级åºååç§°å·²åå¨"); |
| | | } |
| | | if (deviceArea.getParentId() != null && deviceAreaMapper.selectById(deviceArea.getParentId()) == null) { |
| | | return AjaxResult.error("ç¶çº§åºåä¸åå¨"); |
| | | } |
| | | return this.save(deviceArea) ? AjaxResult.success() : AjaxResult.error(); |
| | | } |
| | | |
| | | @Override |
| | | public AjaxResult updateDeviceArea(DeviceArea deviceArea) { |
| | | if (deviceArea == null || deviceArea.getId() == null) { |
| | | return AjaxResult.error("åºåIDä¸è½ä¸ºç©º"); |
| | | } |
| | | if (!StringUtils.hasText(deviceArea.getAreaName())) { |
| | | return AjaxResult.error("åºååç§°ä¸è½ä¸ºç©º"); |
| | | } |
| | | normalizeDeviceArea(deviceArea); |
| | | DeviceArea current = deviceAreaMapper.selectById(deviceArea.getId()); |
| | | if (current == null) { |
| | | return AjaxResult.error("åºåä¸åå¨"); |
| | | } |
| | | if (deviceArea.getParentId() != null && deviceArea.getId().equals(deviceArea.getParentId())) { |
| | | return AjaxResult.error("ç¶çº§åºåä¸è½éæ©èªèº«"); |
| | | } |
| | | if (isDescendant(deviceArea.getId(), deviceArea.getParentId())) { |
| | | return AjaxResult.error("ç¶çº§åºåä¸è½éæ©åèç¹"); |
| | | } |
| | | if (deviceArea.getParentId() != null && deviceAreaMapper.selectById(deviceArea.getParentId()) == null) { |
| | | return AjaxResult.error("ç¶çº§åºåä¸åå¨"); |
| | | } |
| | | if (existsSameName(deviceArea.getParentId(), deviceArea.getAreaName(), deviceArea.getId())) { |
| | | return AjaxResult.error("å级åºååç§°å·²åå¨"); |
| | | } |
| | | return this.updateById(deviceArea) ? AjaxResult.success() : AjaxResult.error(); |
| | | } |
| | | |
| | | @Override |
| | | public AjaxResult removeDeviceAreas(List<Long> ids) { |
| | | if (CollectionUtils.isEmpty(ids)) { |
| | | return AjaxResult.error("è¯·éæ©è¦å é¤çåºå"); |
| | | } |
| | | LambdaQueryWrapper<DeviceArea> childWrapper = new LambdaQueryWrapper<>(); |
| | | childWrapper.in(DeviceArea::getParentId, ids); |
| | | if (deviceAreaMapper.selectCount(childWrapper) > 0) { |
| | | return AjaxResult.error("åå¨ååºåï¼ä¸è½ç´æ¥å é¤"); |
| | | } |
| | | return this.removeBatchByIds(ids) ? AjaxResult.success() : AjaxResult.error(); |
| | | } |
| | | |
| | | private List<DeviceAreaTreeDto> buildTree(Map<Long, List<DeviceLedger>> deviceMap) { |
| | | LambdaQueryWrapper<DeviceArea> queryWrapper = new LambdaQueryWrapper<>(); |
| | | queryWrapper.and(wrapper -> wrapper.isNull(DeviceArea::getParentId).or().eq(DeviceArea::getParentId, 0L)); |
| | | queryWrapper.orderByAsc(DeviceArea::getSort).orderByAsc(DeviceArea::getId); |
| | | List<DeviceArea> rootList = deviceAreaMapper.selectList(queryWrapper); |
| | | |
| | | List<DeviceAreaTreeDto> tree = new ArrayList<>(); |
| | | for (DeviceArea deviceArea : rootList) { |
| | | DeviceAreaTreeDto node = toTreeDto(deviceArea, deviceMap); |
| | | node.setChildren(buildChildren(deviceArea.getId(), deviceMap)); |
| | | tree.add(node); |
| | | } |
| | | return tree; |
| | | } |
| | | |
| | | private void normalizeDeviceArea(DeviceArea deviceArea) { |
| | | if (deviceArea.getParentId() != null && deviceArea.getParentId() == 0L) { |
| | | deviceArea.setParentId(null); |
| | | } |
| | | if (deviceArea.getSort() == null) { |
| | | deviceArea.setSort(0L); |
| | | } |
| | | } |
| | | |
| | | private boolean existsSameName(Long parentId, String areaName, Long excludeId) { |
| | | LambdaQueryWrapper<DeviceArea> queryWrapper = new LambdaQueryWrapper<>(); |
| | | queryWrapper.eq(DeviceArea::getAreaName, areaName); |
| | | if (parentId == null) { |
| | | queryWrapper.and(wrapper -> wrapper.isNull(DeviceArea::getParentId).or().eq(DeviceArea::getParentId, 0L)); |
| | | } else { |
| | | queryWrapper.eq(DeviceArea::getParentId, parentId); |
| | | } |
| | | if (excludeId != null) { |
| | | queryWrapper.ne(DeviceArea::getId, excludeId); |
| | | } |
| | | return deviceAreaMapper.selectCount(queryWrapper) > 0; |
| | | } |
| | | |
| | | private boolean isDescendant(Long currentId, Long parentId) { |
| | | if (currentId == null || parentId == null) { |
| | | return false; |
| | | } |
| | | Long cursor = parentId; |
| | | while (cursor != null && cursor != 0L) { |
| | | if (currentId.equals(cursor)) { |
| | | return true; |
| | | } |
| | | DeviceArea parent = deviceAreaMapper.selectById(cursor); |
| | | if (parent == null) { |
| | | return false; |
| | | } |
| | | cursor = parent.getParentId(); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | private List<DeviceAreaTreeDto> buildChildren(Long parentId, Map<Long, List<DeviceLedger>> deviceMap) { |
| | | LambdaQueryWrapper<DeviceArea> queryWrapper = new LambdaQueryWrapper<>(); |
| | | queryWrapper.eq(DeviceArea::getParentId, parentId); |
| | | queryWrapper.orderByAsc(DeviceArea::getSort).orderByAsc(DeviceArea::getId); |
| | | List<DeviceArea> children = deviceAreaMapper.selectList(queryWrapper); |
| | | |
| | | List<DeviceAreaTreeDto> result = new ArrayList<>(); |
| | | for (DeviceArea child : children) { |
| | | DeviceAreaTreeDto node = toTreeDto(child, deviceMap); |
| | | node.setChildren(buildChildren(child.getId(), deviceMap)); |
| | | result.add(node); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | private DeviceAreaTreeDto toTreeDto(DeviceArea deviceArea, Map<Long, List<DeviceLedger>> deviceMap) { |
| | | DeviceAreaTreeDto dto = new DeviceAreaTreeDto(); |
| | | BeanUtils.copyProperties(deviceArea, dto); |
| | | dto.setLabel(deviceArea.getAreaName()); |
| | | dto.setDeviceList(new ArrayList<>(deviceMap.getOrDefault(deviceArea.getId(), Collections.emptyList()))); |
| | | dto.setChildren(new ArrayList<>()); |
| | | return dto; |
| | | } |
| | | } |
| | |
| | | import com.ruoyi.device.dto.DeviceMaintenanceDto; |
| | | import com.ruoyi.device.execl.DeviceMaintenanceExeclDto; |
| | | import com.ruoyi.device.mapper.DeviceMaintenanceMapper; |
| | | import com.ruoyi.device.pojo.DeviceLedger; |
| | | import com.ruoyi.device.pojo.DeviceMaintenance; |
| | | import com.ruoyi.device.service.IDeviceLedgerService; |
| | | import com.ruoyi.device.service.IDeviceMaintenanceService; |
| | | import com.ruoyi.device.vo.DeviceMaintenanceVo; |
| | | import com.ruoyi.device.vo.DeviceRepairVo; |
| | |
| | | public class DeviceMaintenanceServiceImpl extends ServiceImpl<DeviceMaintenanceMapper, DeviceMaintenance> implements IDeviceMaintenanceService { |
| | | |
| | | private final DeviceMaintenanceMapper deviceMaintenanceMapper; |
| | | private final IDeviceLedgerService deviceLedgerService; |
| | | private final SparePartsMapper sparePartsMapper; |
| | | private final SparePartsRequisitionRecordService sparePartsRequisitionRecordService; |
| | | private final FileUtil fileUtil; |
| | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public AjaxResult saveDeviceRepair(DeviceMaintenanceDto deviceMaintenance) { |
| | | DeviceLedger byId = deviceLedgerService.getById(deviceMaintenance.getDeviceLedgerId()); |
| | | if (byId != null) { |
| | | deviceMaintenance.setDeviceName(byId.getDeviceName()); |
| | | deviceMaintenance.setDeviceModel(byId.getDeviceModel()); |
| | | deviceMaintenance.setAreaId(byId.getAreaId()); |
| | | } |
| | | boolean save = this.save(deviceMaintenance); |
| | | if (save){ |
| | | // å¤çå¾çä¸ä¼ |
| | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public AjaxResult updateDeviceDeviceMaintenance(DeviceMaintenanceDto deviceMaintenance) { |
| | | DeviceMaintenance oldDeviceMaintenance = this.getById(deviceMaintenance.getId()); |
| | | Long effectiveDeviceLedgerId = deviceMaintenance.getDeviceLedgerId() != null |
| | | ? deviceMaintenance.getDeviceLedgerId() |
| | | : oldDeviceMaintenance.getDeviceLedgerId(); |
| | | DeviceLedger byId = deviceLedgerService.getById(effectiveDeviceLedgerId); |
| | | if (byId != null) { |
| | | deviceMaintenance.setDeviceName(byId.getDeviceName()); |
| | | deviceMaintenance.setDeviceModel(byId.getDeviceModel()); |
| | | deviceMaintenance.setAreaId(byId.getAreaId()); |
| | | } |
| | | // å¤çå¤ä»¶ä½¿ç¨æ
åµ |
| | | if (com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(deviceMaintenance.getSparePartsUseList())) { |
| | | List<Long> sparePartIds = new ArrayList<>(); |
| | |
| | | DeviceLedger byId = deviceLedgerService.getById(deviceRepairDto.getDeviceLedgerId()); |
| | | deviceRepairDto.setDeviceName(byId.getDeviceName()); |
| | | deviceRepairDto.setDeviceModel(byId.getDeviceModel()); |
| | | deviceRepairDto.setAreaId(byId.getAreaId()); |
| | | if (deviceRepairDto.getStatus() == null) { |
| | | deviceRepairDto.setStatus(STATUS_PENDING_REPAIR); |
| | | } |
| | |
| | | if (oldDeviceRepair == null) { |
| | | return AjaxResult.error("æ¥ä¿®è®°å½ä¸åå¨"); |
| | | } |
| | | Long effectiveDeviceLedgerId = deviceRepairDto.getDeviceLedgerId() != null |
| | | ? deviceRepairDto.getDeviceLedgerId() |
| | | : oldDeviceRepair.getDeviceLedgerId(); |
| | | DeviceLedger byId = deviceLedgerService.getById(effectiveDeviceLedgerId); |
| | | if (byId != null) { |
| | | deviceRepairDto.setDeviceName(byId.getDeviceName()); |
| | | deviceRepairDto.setDeviceModel(byId.getDeviceModel()); |
| | | deviceRepairDto.setAreaId(byId.getAreaId()); |
| | | } |
| | | if (deviceRepairDto.getStatus() != null |
| | | && deviceRepairDto.getStatus() == STATUS_COMPLETED |
| | | && (oldDeviceRepair.getStatus() == null |
| | |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.common.utils.bean.BeanUtils; |
| | | import com.ruoyi.device.mapper.DeviceAreaMapper; |
| | | import com.ruoyi.device.mapper.DeviceLedgerMapper; |
| | | import com.ruoyi.device.mapper.MaintenanceTaskMapper; |
| | | import com.ruoyi.device.pojo.DeviceArea; |
| | | import com.ruoyi.device.pojo.DeviceLedger; |
| | | import com.ruoyi.device.pojo.MaintenanceTask; |
| | | import com.ruoyi.device.service.MaintenanceTaskService; |
| | | import com.ruoyi.framework.web.domain.AjaxResult; |
| | |
| | | private final SysUserMapper sysUserMapper; |
| | | private final TimingTaskServiceImpl timingTaskService; |
| | | private final MaintenanceTaskScheduler maintenanceTaskScheduler; |
| | | private final DeviceLedgerMapper deviceLedgerMapper; |
| | | private final DeviceAreaMapper deviceAreaMapper; |
| | | |
| | | @Override |
| | | public AjaxResult listPage(Page page, MaintenanceTask maintenanceTask) { |
| | | Page<MaintenanceTask> taskPage = maintenanceTaskMapper.selectPage(page, new QueryWrapper<MaintenanceTask>().orderByDesc("create_time")); |
| | | QueryWrapper<MaintenanceTask> queryWrapper = new QueryWrapper<MaintenanceTask>().orderByDesc("create_time"); |
| | | if (maintenanceTask.getAreaId() != null) { |
| | | queryWrapper.eq("area_id", maintenanceTask.getAreaId()); |
| | | } |
| | | Page<MaintenanceTask> taskPage = maintenanceTaskMapper.selectPage(page, queryWrapper); |
| | | // 2. å¦ææ²¡ææ°æ®ï¼ç´æ¥è¿å空å页 |
| | | if (taskPage.getRecords().isEmpty()) { |
| | | return AjaxResult.success(taskPage); |
| | |
| | | List<SysUser> users = sysUserMapper.selectUserByIds((new ArrayList<>(userIds))); |
| | | users.forEach(user -> userNickNameMap.put(user.getUserId(), user.getNickName())); |
| | | } |
| | | Map<Long, DeviceLedger> ledgerMap = new HashMap<>(); |
| | | Set<Long> areaIds = new HashSet<>(); |
| | | taskPage.getRecords().forEach(task -> { |
| | | // 设置ç»è®°äººæµç§° |
| | | if (task.getTaskId() != null) { |
| | | DeviceLedger deviceLedger = deviceLedgerMapper.selectById(task.getTaskId()); |
| | | if (deviceLedger != null) { |
| | | ledgerMap.put(task.getTaskId(), deviceLedger); |
| | | if (deviceLedger.getAreaId() != null) { |
| | | areaIds.add(deviceLedger.getAreaId()); |
| | | } |
| | | } |
| | | } |
| | | }); |
| | | Map<Long, String> areaNameMap = new HashMap<>(); |
| | | if (!areaIds.isEmpty()) { |
| | | List<DeviceArea> areas = deviceAreaMapper.selectBatchIds(new ArrayList<>(areaIds)); |
| | | areas.forEach(area -> areaNameMap.put(area.getId(), area.getAreaName())); |
| | | } |
| | | taskPage.getRecords().forEach(task -> { |
| | | // çå§çé§æîæµçæ¨ç»? |
| | | if (task.getRegistrantId() != null) { |
| | | task.setRegistrant(userNickNameMap.getOrDefault(task.getRegistrantId(), "æªç¥ç¨æ·")); |
| | | task.setRegistrant(userNickNameMap.getOrDefault(task.getRegistrantId(), "éîç
¡é¢ã¦å")); |
| | | } |
| | | DeviceLedger deviceLedger = ledgerMap.get(task.getTaskId()); |
| | | if (deviceLedger != null) { |
| | | task.setAreaId(deviceLedger.getAreaId()); |
| | | task.setAreaName(areaNameMap.getOrDefault(deviceLedger.getAreaId(), "")); |
| | | } |
| | | }); |
| | | return AjaxResult.success(taskPage); |
| | |
| | | |
| | | @Override |
| | | public AjaxResult add(MaintenanceTask maintenanceTask) { |
| | | DeviceLedger deviceLedger = deviceLedgerMapper.selectById(maintenanceTask.getTaskId()); |
| | | if (deviceLedger != null) { |
| | | maintenanceTask.setAreaId(deviceLedger.getAreaId()); |
| | | } |
| | | maintenanceTask.setActive(true); |
| | | // 计ç®é¦æ¬¡æ§è¡æ¶é´ |
| | | TimingTask task = new TimingTask(); |
| | |
| | | @Override |
| | | public AjaxResult updateByMaintenanceTaskId(MaintenanceTask maintenanceTask) { |
| | | MaintenanceTask maintenanceTask1 = maintenanceTaskMapper.selectById(maintenanceTask.getId()); |
| | | DeviceLedger deviceLedger = deviceLedgerMapper.selectById(maintenanceTask.getTaskId()); |
| | | if (deviceLedger != null) { |
| | | maintenanceTask.setAreaId(deviceLedger.getAreaId()); |
| | | } |
| | | if (maintenanceTask1 == null) { |
| | | return AjaxResult.warn("æ²¡ææ¤æ°æ®"); |
| | | } |
| | |
| | | |
| | | @Data |
| | | public class DeviceMaintenanceVo extends DeviceMaintenance { |
| | | @Schema(description = "设å¤åºååç§°") |
| | | private String areaName; |
| | | @Schema(description = "设å¤ä¿å
»id") |
| | | private Long id; |
| | | |
| | |
| | | @Data |
| | | public class DeviceRepairVo extends DeviceRepair { |
| | | |
| | | @Schema(description = "设å¤åºååç§°") |
| | | private String areaName; |
| | | |
| | | @Schema(description = "æ¥ä¿®æ¶é´å符串") |
| | | private String repairTimeStr; |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.http.service.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.device.pojo.DeviceLedger; |
| | | import com.ruoyi.device.service.IDeviceLedgerService; |
| | | import com.ruoyi.framework.web.controller.BaseController; |
| | | import com.ruoyi.framework.web.domain.AjaxResult; |
| | | import com.ruoyi.http.service.impl.RealTimeEnergyConsumptionServiceImpl; |
| | | import io.swagger.annotations.Api; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @RestController |
| | | @RequestMapping("/iot") |
| | | @Api(tags = "æ°éæ¥å£") |
| | | public class JclyController extends BaseController { |
| | | |
| | | @Autowired |
| | | private RealTimeEnergyConsumptionServiceImpl realTimeEnergyConsumptionService; |
| | | |
| | | @Autowired |
| | | private IDeviceLedgerService deviceLedgerService; |
| | | |
| | | /** |
| | | * 宿¶è·å温湿度ï¼äºæ°§åç¢³æ°æ® |
| | | */ |
| | | @GetMapping("/getRealData") |
| | | public AjaxResult getRealData() { |
| | | List<DeviceLedger> iotDevices = deviceLedgerService.list(new LambdaQueryWrapper<DeviceLedger>() |
| | | .eq(DeviceLedger::getIsIotDevice, 1) |
| | | .isNotNull(DeviceLedger::getExternalCode) |
| | | .ne(DeviceLedger::getExternalCode, "")); |
| | | |
| | | Map<String, String> guidDeviceNameMap = iotDevices.stream() |
| | | .filter(item -> StringUtils.isNotEmpty(item.getExternalCode())) |
| | | .collect(Collectors.toMap( |
| | | item -> item.getExternalCode().trim(), |
| | | item -> StringUtils.isNotEmpty(item.getDeviceName()) ? item.getDeviceName().trim() : "", |
| | | (oldValue, newValue) -> StringUtils.isNotEmpty(oldValue) ? oldValue : newValue, |
| | | LinkedHashMap::new |
| | | )); |
| | | List<String> guidList = new ArrayList<>(guidDeviceNameMap.keySet()); |
| | | |
| | | List<Map<String, String>> maps = realTimeEnergyConsumptionService |
| | | .getRealData(guidList); |
| | | for (Map<String, String> item : maps) { |
| | | String guid = item.get("guid"); |
| | | if (StringUtils.isNotEmpty(guid)) { |
| | | String deviceName = guidDeviceNameMap.get(guid.trim()); |
| | | if (StringUtils.isNotEmpty(deviceName)) { |
| | | item.put("deviceName", deviceName); |
| | | } |
| | | } |
| | | } |
| | | return AjaxResult.success(maps); |
| | | } |
| | | |
| | | /** |
| | | * è·åå岿°æ® |
| | | */ |
| | | @GetMapping("/getHistoryData") |
| | | public AjaxResult getHistoryData(@RequestParam(value = "guid") String guid, |
| | | @RequestParam(value = "startTime") long startTime, |
| | | @RequestParam(value = "endTime") long endTime) { |
| | | List<Map<String, String>> maps = realTimeEnergyConsumptionService.getHistoryData(guid, startTime, endTime); |
| | | return AjaxResult.success(maps); |
| | | } |
| | | |
| | | } |
| | |
| | | import com.alibaba.fastjson2.JSON; |
| | | import com.alibaba.fastjson2.JSONArray; |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.common.utils.http.HttpUtils; |
| | | import com.ruoyi.http.service.RealTimeEnergyConsumptionService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.Collections; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.*; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | | * @author :yys |
| | |
| | | @Slf4j |
| | | public class RealTimeEnergyConsumptionServiceImpl implements RealTimeEnergyConsumptionService { |
| | | |
| | | private static final long REMOTE_CACHE_TTL_SECONDS_30 = 30L; |
| | | |
| | | private static final String URL = "https://new.e-elitech.cn/api/data-api"; |
| | | |
| | | private static final String TOKEN_URL = "/elitechAccess/getToken"; |
| | | |
| | | private static final String REAL_TIME_URL = "/elitechAccess/v2/getRealTimeData"; //è·å设å¤å®æ¶æ°æ® |
| | | private static final String REAL_TIME_URL = "/elitechAccess/v2/getRealTimeData"; |
| | | |
| | | private static final String REAL_HISTORY_URL = URL + "/elitechAccess/v2/getHistoryData"; |
| | | |
| | | private static final String KET_ID = "75804708"; |
| | | |
| | | private static final String KEY_SECRET = "xTUGToozKpYgUPqTsZzB"; |
| | | |
| | | private static final String USER_NAME = "ç¨æ·30773662"; |
| | | private static final String USER_NAME = "\u7528\u623730773662"; |
| | | |
| | | private static final String PASS_WORD = "y17775163675"; |
| | | |
| | | private static final String DEVICE_GUID = "90444196515214284663"; |
| | | private static final String REAL_TIME_CACHE_PREFIX = "JCLY:REAL_TIME:"; |
| | | |
| | | private static final String HISTORY_CACHE_PREFIX = "JCLY:HISTORY:"; |
| | | |
| | | /** |
| | | * æ ¹æ®paramCodeæåæ¢å¤´åæ° |
| | | * @param paramList 设å¤åæ°æ°ç» |
| | | * @param targetCode ç®æ æ¢å¤´ç¼ç |
| | | * @return æ¢å¤´åæ°å¯¹è±¡ï¼å
å«name/value/unitï¼ |
| | | */ |
| | | private static final String TOKEN_CACHE_KEY = "JCLY_TOKEN:"; |
| | | |
| | | private static final String STATUS_KEY = "status"; |
| | | |
| | | private static final String STATUS_MESSAGE_KEY = "statusMessage"; |
| | | |
| | | private static final String STATUS_ONLINE = "å¨çº¿"; |
| | | |
| | | private static final String STATUS_OFFLINE = "offline"; |
| | | |
| | | private static final String STATUS_ERROR = "error"; |
| | | |
| | | @Autowired |
| | | private RedisTemplate<String, String> redisTemplate; |
| | | |
| | | private static JSONObject getProbeParam(JSONArray paramList, String targetCode) { |
| | | if (paramList == null) { |
| | | return new JSONObject(); |
| | | } |
| | | for (int i = 0; i < paramList.size(); i++) { |
| | | JSONObject paramObj = paramList.getJSONObject(i); |
| | | if (targetCode.equals(paramObj.getString("paramCode"))) { |
| | | return paramObj; |
| | | } |
| | | } |
| | | return new JSONObject(); // æªå¹é
å°è¿å空对象ï¼é¿å
空æé |
| | | return new JSONObject(); |
| | | } |
| | | |
| | | /** |
| | | * 宿¶è·å温湿度ï¼äºæ°§åç¢³æ°æ® |
| | | */ |
| | | public static void main(String[] args) { |
| | | String realTimeData = getRealTimeData(getToken()); |
| | | Map<String, Object> map = JSON.parseObject(realTimeData, Map.class); |
| | | if(map.get("code").equals(0)){ |
| | | // 1. è§£æå¤å±data为JSONæ°ç»ï¼æ¥å£è¿åç设å¤åè¡¨ï¼ |
| | | JSONArray deviceList = JSON.parseArray(map.get("data").toString()); |
| | | // 2. éå设å¤åè¡¨ï¼æ¤å¤ä»
å第ä¸ä¸ªè®¾å¤ï¼è¥æå¤ä¸ªè®¾å¤å¯å¾ªç¯å¤çï¼ |
| | | if (!deviceList.isEmpty()) { |
| | | JSONObject deviceObj = deviceList.getJSONObject(0); |
| | | // 3. è§£æè®¾å¤å
çåæ°æ°ç»ï¼ææparamCode对åºçåæ°ï¼ |
| | | JSONArray paramList = deviceObj.getJSONArray("data"); |
| | | public List<Map<String, String>> getHistoryData(String guid, long startTime, long endTime) { |
| | | List<Map<String, String>> resultList = new ArrayList<>(); |
| | | String token = getToken(); |
| | | try { |
| | | String historyData = requestHistoryData(token, guid, startTime, endTime); |
| | | JSONObject resultObj = JSON.parseObject(historyData); |
| | | if (resultObj == null) { |
| | | resultList.add(buildStatusItem(guid, STATUS_ERROR, "history response is empty")); |
| | | return resultList; |
| | | } |
| | | |
| | | // 4. å®ä¹ç®æ æ¢å¤´çparamCodeï¼æéæ©å± |
| | | String[] targetCodes = {"0100", "0110", "0120", "0130"}; |
| | | for (String code : targetCodes) { |
| | | // 5. éååæ°æ°ç»ï¼å¹é
ç®æ paramCode |
| | | for (int i = 0; i < paramList.size(); i++) { |
| | | JSONObject paramObj = paramList.getJSONObject(i); |
| | | String currentCode = paramObj.getString("paramCode"); |
| | | if (code.equals(currentCode)) { |
| | | // 6. æåæ ¸å¿å段ï¼å¼ãåä½ãæ¢å¤´åç§°ï¼ |
| | | String paramName = paramObj.getString("paramName"); // æ¢å¤´1/æ¢å¤´2... |
| | | String value = paramObj.getString("value"); // æ°å¼ï¼345.80/24.90...ï¼ |
| | | String unitCode = paramObj.getString("unitCode"); // åä½ï¼Lux/â/%RH/ppmï¼ |
| | | Integer code = resultObj.getInteger("code"); |
| | | if (!Integer.valueOf(0).equals(code)) { |
| | | resultList.add(buildStatusItem(guid, resolveStatusByCodeOrMessage(code, resultObj.getString("msg")), resultObj.getString("msg"))); |
| | | return resultList; |
| | | } |
| | | |
| | | // 7. ä¸å¡å¤çï¼æå°/èµå¼/åå¨çï¼æéä¿®æ¹ï¼ |
| | | System.out.println(paramName + "ï¼" + value + " " + unitCode); |
| | | // å¹é
å°åç´æ¥è·³åºå
å±å¾ªç¯ï¼æåæç |
| | | break; |
| | | JSONArray historyList = resultObj.getJSONArray("data"); |
| | | if (historyList == null || historyList.isEmpty()) { |
| | | resultList.add(buildStatusItem(guid, STATUS_OFFLINE, "no history data")); |
| | | return resultList; |
| | | } |
| | | |
| | | for (int i = 0; i < historyList.size(); i++) { |
| | | JSONObject historyObj = historyList.getJSONObject(i); |
| | | Map<String, String> historyItem = new HashMap<>(); |
| | | historyItem.put("guid", firstNonBlank( |
| | | historyObj.getString("deviceGuid"), |
| | | historyObj.getString("guid"), |
| | | guid |
| | | )); |
| | | historyItem.put("subUId", stringValue(historyObj.get("subUid"))); |
| | | historyItem.put("monitorTimeStamp", stringValue(historyObj.get("monitorTimeStamp"))); |
| | | historyItem.put("monitorTimeStr", historyObj.getString("monitorTimeStr")); |
| | | historyItem.put("position", historyObj.getString("position")); |
| | | historyItem.put("address", historyObj.getString("address")); |
| | | historyItem.put(STATUS_KEY, resolveStatusByAlarmState(historyObj.get("alarmState"), STATUS_ONLINE)); |
| | | |
| | | JSONArray paramList = historyObj.getJSONArray("data"); |
| | | if (paramList != null && !paramList.isEmpty()) { |
| | | for (int j = 0; j < paramList.size(); j++) { |
| | | JSONObject paramObj = paramList.getJSONObject(j); |
| | | String paramCode = paramObj.getString("paramCode"); |
| | | String value = paramObj.getString("value"); |
| | | String unitCode = paramObj.getString("unitCode"); |
| | | String fullValue = concatValueWithUnit(value, unitCode); |
| | | if ("0100".equals(paramCode)) { |
| | | historyItem.put("light", fullValue); |
| | | } else if ("0110".equals(paramCode)) { |
| | | historyItem.put("temperature", fullValue); |
| | | } else if ("0120".equals(paramCode)) { |
| | | historyItem.put("humidity", fullValue); |
| | | } else if ("0130".equals(paramCode)) { |
| | | historyItem.put("co2", fullValue); |
| | | } else if ("0042".equals(paramCode)) { |
| | | historyItem.put("battery", fullValue); |
| | | } else if (paramCode != null) { |
| | | historyItem.put(paramCode, fullValue); |
| | | } |
| | | } |
| | | } |
| | | resultList.add(historyItem); |
| | | } |
| | | return resultList; |
| | | } catch (Exception ex) { |
| | | log.error("history data parse/request failed, guid={}", guid, ex); |
| | | resultList.add(buildStatusItem(guid, STATUS_ERROR, ex.getMessage())); |
| | | return resultList; |
| | | } |
| | | } |
| | | |
| | | public List<Map<String, String>> getRealData(List<String> guidList) { |
| | | log.info("start get real data"); |
| | | List<Map<String, String>> listMaps = new ArrayList<>(); |
| | | if (guidList == null || guidList.isEmpty()) { |
| | | return listMaps; |
| | | } |
| | | |
| | | String token = getToken(); |
| | | try { |
| | | String realTimeData = getRealTimeData(token, guidList); |
| | | JSONObject batchResp = JSON.parseObject(realTimeData); |
| | | Integer code = batchResp == null ? null : batchResp.getInteger("code"); |
| | | if (Integer.valueOf(0).equals(code)) { |
| | | parseRealDataResponse(batchResp, guidList, listMaps); |
| | | return listMaps; |
| | | } |
| | | log.warn("batch getRealData failed, fallback one by one. code={}, msg={}", code, batchResp == null ? null : batchResp.getString("msg")); |
| | | } catch (Exception ex) { |
| | | log.error("batch getRealData exception, fallback one by one", ex); |
| | | } |
| | | |
| | | for (String guid : guidList) { |
| | | listMaps.add(fetchSingleDeviceRealData(token, guid)); |
| | | } |
| | | return listMaps; |
| | | } |
| | | |
| | | public static void main(String[] args) { |
| | | System.out.println(); |
| | | } |
| | | |
| | | public static String getToken(){ |
| | | public String getToken() { |
| | | String cachedToken = sanitizeToken(redisTemplate.opsForValue().get(TOKEN_CACHE_KEY)); |
| | | if (cachedToken != null) { |
| | | return cachedToken; |
| | | } |
| | | Map<String, String> param = new HashMap<>(); |
| | | param.put("keyId", KET_ID); |
| | | param.put("keySecret", KEY_SECRET); |
| | | param.put("userName", USER_NAME); |
| | | param.put("password", PASS_WORD); |
| | | log.info("请æ±åæ°ï¼{}", JSON.toJSONString( param)); |
| | | log.info("request token payload: {}", JSON.toJSONString(param)); |
| | | String result = HttpUtils.sendPostJson(URL + TOKEN_URL, JSON.toJSONString(param)); |
| | | log.info("è¿åç»æï¼{}", result); |
| | | log.info("request token response: {}", result); |
| | | Map<String, Object> map = JSON.parseObject(result, Map.class); |
| | | if (map.get("code").equals(0)) { |
| | | if (Integer.valueOf(0).equals(map.get("code"))) { |
| | | Object token = map.get("data"); |
| | | log.info("token:{}", token); |
| | | redisTemplate.opsForValue().set(TOKEN_CACHE_KEY, token.toString(), 60 * 60 * 12); |
| | | return token.toString(); |
| | | } |
| | | log.error("get token failed, response={}", result); |
| | | return null; |
| | | } |
| | | |
| | | private String sanitizeToken(String token) { |
| | | if (token == null) { |
| | | return null; |
| | | } |
| | | String cleanedToken = token.replace("\0", "").trim(); |
| | | return cleanedToken.isEmpty() ? null : cleanedToken; |
| | | } |
| | | |
| | | private String firstNonBlank(String... values) { |
| | | for (String value : values) { |
| | | if (value != null && !value.trim().isEmpty()) { |
| | | return value; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | private String stringValue(Object value) { |
| | | return value == null ? null : String.valueOf(value); |
| | | } |
| | | |
| | | private String refreshToken() { |
| | | redisTemplate.delete(TOKEN_CACHE_KEY); |
| | | return getToken(); |
| | | } |
| | | |
| | | private boolean isUnauthorizedException(Exception ex) { |
| | | if (ex == null || ex.getMessage() == null) { |
| | | return false; |
| | | } |
| | | String msg = ex.getMessage().toLowerCase(); |
| | | return msg.contains("401") || msg.contains("unauthorized"); |
| | | } |
| | | |
| | | private boolean isUnauthorizedResponse(String result) { |
| | | if (result == null || result.trim().isEmpty()) { |
| | | return false; |
| | | } |
| | | try { |
| | | JSONObject obj = JSON.parseObject(result); |
| | | if (obj == null) { |
| | | return false; |
| | | } |
| | | Integer code = obj.getInteger("code"); |
| | | if (code != null && (code == 401 || code == 403)) { |
| | | return true; |
| | | } |
| | | String msg = obj.getString("msg"); |
| | | return msg != null && msg.toLowerCase().contains("unauthorized"); |
| | | } catch (Exception ignore) { |
| | | return result.contains("401"); |
| | | } |
| | | } |
| | | |
| | | private String requestWithTokenRetry(String url, String payload, String token, String scene) { |
| | | String usedToken = sanitizeToken(token); |
| | | if (usedToken == null) { |
| | | usedToken = refreshToken(); |
| | | } |
| | | try { |
| | | String result = HttpUtils.sendPostJson(url, payload, usedToken); |
| | | if (!isUnauthorizedResponse(result) && StringUtils.isNotEmpty(result)) { |
| | | return result; |
| | | } |
| | | log.warn("{} got unauthorized response, refresh token and retry once", scene); |
| | | } catch (Exception ex) { |
| | | if (!isUnauthorizedException(ex)) { |
| | | throw ex; |
| | | } |
| | | log.warn("{} got 401 exception, refresh token and retry once", scene); |
| | | } |
| | | |
| | | String newToken = refreshToken(); |
| | | if (newToken == null) { |
| | | throw new RuntimeException("refresh token failed"); |
| | | } |
| | | return HttpUtils.sendPostJson(url, payload, newToken); |
| | | } |
| | | |
| | | private String concatValueWithUnit(String value, String unitCode) { |
| | | if (value == null) { |
| | | return null; |
| | | } |
| | | return value + (unitCode == null ? "" : unitCode); |
| | | } |
| | | |
| | | private Map<String, String> buildStatusItem(String guid, String status, String statusMessage) { |
| | | Map<String, String> result = new HashMap<>(); |
| | | result.put("guid", guid); |
| | | result.put(STATUS_KEY, status); |
| | | if (statusMessage != null && !statusMessage.trim().isEmpty()) { |
| | | result.put(STATUS_MESSAGE_KEY, statusMessage); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | public static String getRealTimeData(String token){ |
| | | private String resolveStatusByCodeOrMessage(Integer code, String message) { |
| | | if (code != null && (code == 5 || code == 1003 || code == 1004)) { |
| | | return STATUS_OFFLINE; |
| | | } |
| | | if (message == null) { |
| | | return STATUS_ERROR; |
| | | } |
| | | String lowered = message.toLowerCase(); |
| | | if (lowered.contains("offline") || message.contains("离线")) { |
| | | return STATUS_OFFLINE; |
| | | } |
| | | return STATUS_ERROR; |
| | | } |
| | | |
| | | private void parseRealDataResponse(JSONObject responseObj, List<String> requestedGuids, List<Map<String, String>> output) { |
| | | JSONArray deviceList = responseObj.getJSONArray("data"); |
| | | Set<String> returnedGuids = new HashSet<>(); |
| | | if (deviceList != null) { |
| | | for (int deviceIndex = 0; deviceIndex < deviceList.size(); deviceIndex++) { |
| | | JSONObject deviceObj = deviceList.getJSONObject(deviceIndex); |
| | | Map<String, String> deviceData = parseSingleDevice(deviceObj, null); |
| | | String guid = deviceData.get("guid"); |
| | | if (guid != null) { |
| | | returnedGuids.add(guid); |
| | | } |
| | | output.add(deviceData); |
| | | } |
| | | } |
| | | |
| | | for (String requestGuid : requestedGuids) { |
| | | if (!returnedGuids.contains(requestGuid)) { |
| | | output.add(buildStatusItem(requestGuid, STATUS_OFFLINE, "device not returned by remote API")); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private Map<String, String> fetchSingleDeviceRealData(String token, String guid) { |
| | | try { |
| | | String singleResult = getRealTimeData(token, Collections.singletonList(guid)); |
| | | JSONObject singleObj = JSON.parseObject(singleResult); |
| | | if (singleObj == null) { |
| | | return buildStatusItem(guid, STATUS_ERROR, "single device response is empty"); |
| | | } |
| | | Integer code = singleObj.getInteger("code"); |
| | | if (!Integer.valueOf(0).equals(code)) { |
| | | return buildStatusItem(guid, resolveStatusByCodeOrMessage(code, singleObj.getString("msg")), singleObj.getString("msg")); |
| | | } |
| | | |
| | | JSONArray dataList = singleObj.getJSONArray("data"); |
| | | if (dataList == null || dataList.isEmpty()) { |
| | | return buildStatusItem(guid, STATUS_OFFLINE, "single device response has no data"); |
| | | } |
| | | return parseSingleDevice(dataList.getJSONObject(0), guid); |
| | | } catch (Exception ex) { |
| | | log.error("single getRealData failed, guid={}", guid, ex); |
| | | return buildStatusItem(guid, STATUS_ERROR, ex.getMessage()); |
| | | } |
| | | } |
| | | |
| | | private Map<String, String> parseSingleDevice(JSONObject deviceObj, String fallbackGuid) { |
| | | Map<String, String> deviceData = new HashMap<>(); |
| | | String deviceGuid = firstNonBlank( |
| | | deviceObj.getString("deviceGuid"), |
| | | deviceObj.getString("guid"), |
| | | deviceObj.getString("devGuid"), |
| | | deviceObj.getString("sn"), |
| | | fallbackGuid |
| | | ); |
| | | if (deviceGuid != null) { |
| | | deviceData.put("guid", deviceGuid); |
| | | } |
| | | |
| | | JSONArray paramList = deviceObj.getJSONArray("data"); |
| | | if (paramList == null || paramList.isEmpty()) { |
| | | deviceData.put(STATUS_KEY, STATUS_OFFLINE); |
| | | deviceData.put(STATUS_MESSAGE_KEY, "device data is empty"); |
| | | return deviceData; |
| | | } |
| | | |
| | | deviceData.put(STATUS_KEY, resolveStatusByAlarmState(deviceObj.get("alarmState"), STATUS_ONLINE)); |
| | | for (int i = 0; i < paramList.size(); i++) { |
| | | JSONObject paramObj = paramList.getJSONObject(i); |
| | | String code = paramObj.getString("paramCode"); |
| | | String value = paramObj.getString("value"); |
| | | String unitCode = paramObj.getString("unitCode"); |
| | | String fullValue = concatValueWithUnit(value, unitCode); |
| | | if ("0100".equals(code)) { |
| | | deviceData.put("light", fullValue); |
| | | } else if ("0110".equals(code)) { |
| | | deviceData.put("temperature", fullValue); |
| | | } else if ("0120".equals(code)) { |
| | | deviceData.put("humidity", fullValue); |
| | | } else if ("0130".equals(code)) { |
| | | deviceData.put("co2", fullValue); |
| | | } else if ("0042".equals(code)) { |
| | | deviceData.put("battery", fullValue); |
| | | } |
| | | } |
| | | return deviceData; |
| | | } |
| | | |
| | | private String resolveStatusByAlarmState(Object alarmState, String defaultStatus) { |
| | | if (alarmState == null) { |
| | | return defaultStatus; |
| | | } |
| | | if (alarmState instanceof Boolean) { |
| | | return (Boolean) alarmState ? STATUS_OFFLINE : STATUS_ONLINE; |
| | | } |
| | | String normalized = String.valueOf(alarmState).trim().toLowerCase(); |
| | | if ("true".equals(normalized) || "1".equals(normalized)) { |
| | | return STATUS_OFFLINE; |
| | | } |
| | | if ("false".equals(normalized) || "0".equals(normalized)) { |
| | | return STATUS_ONLINE; |
| | | } |
| | | return defaultStatus; |
| | | } |
| | | |
| | | public String getRealTimeData(String token, List<String> guidList) { |
| | | Map<String, Object> param = new HashMap<>(); |
| | | param.put("keyId", KET_ID); |
| | | param.put("keySecret", KEY_SECRET); |
| | | param.put("deviceGuids", Collections.singletonList(DEVICE_GUID)); |
| | | log.info("请æ±åæ°ï¼{}", JSON.toJSONString( param)); |
| | | String result = HttpUtils.sendPostJson(URL + REAL_TIME_URL, JSON.toJSONString(param),token); |
| | | log.info("è¿åç»æï¼{}", result); |
| | | param.put("deviceGuids", guidList); |
| | | log.info("request realtime payload: {}", JSON.toJSONString(param)); |
| | | String cacheKey = REAL_TIME_CACHE_PREFIX + JSON.toJSONString(param); |
| | | String cachedResult = sanitizeToken(redisTemplate.opsForValue().get(cacheKey)); |
| | | if (cachedResult != null) { |
| | | log.info("hit realtime cache: {}", cacheKey); |
| | | return cachedResult; |
| | | } |
| | | String result = requestWithTokenRetry(URL + REAL_TIME_URL, JSON.toJSONString(param), token, "getRealTimeData"); |
| | | log.info("request realtime response: {}", result); |
| | | cacheRemoteResponse(cacheKey, result); |
| | | return result; |
| | | } |
| | | |
| | | public String requestHistoryData(String token, String guid, long startTime, long endTime) { |
| | | Map<String, Object> param = new HashMap<>(); |
| | | param.put("keyId", KET_ID); |
| | | param.put("keySecret", KEY_SECRET); |
| | | param.put("deviceGuid", guid); |
| | | param.put("startTime", startTime); |
| | | param.put("endTime", endTime); |
| | | log.info("request history payload: {}", JSON.toJSONString(param)); |
| | | String cacheKey = HISTORY_CACHE_PREFIX + JSON.toJSONString(param); |
| | | String cachedResult = sanitizeToken(redisTemplate.opsForValue().get(cacheKey)); |
| | | if (cachedResult != null) { |
| | | log.info("hit history cache: {}", cacheKey); |
| | | return cachedResult; |
| | | } |
| | | String result = requestWithTokenRetry(REAL_HISTORY_URL, JSON.toJSONString(param), token, "getHistoryData"); |
| | | log.info("request history response: {}", result); |
| | | cacheRemoteResponse(cacheKey, result); |
| | | return result; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | private void cacheRemoteResponse(String cacheKey, String result) { |
| | | if (result == null || result.trim().isEmpty()) { |
| | | return; |
| | | } |
| | | redisTemplate.opsForValue().set(cacheKey, result, REMOTE_CACHE_TTL_SECONDS_30, TimeUnit.SECONDS); |
| | | } |
| | | } |
| | |
| | | import com.ruoyi.framework.aspectj.lang.enums.BusinessType; |
| | | import com.ruoyi.framework.web.controller.BaseController; |
| | | import com.ruoyi.framework.web.domain.R; |
| | | import com.ruoyi.inspectiontask.dto.InspectionTaskDto; |
| | | import com.ruoyi.inspectiontask.dto.TimingTaskDto; |
| | | import com.ruoyi.inspectiontask.pojo.InspectionTask; |
| | | import com.ruoyi.inspectiontask.pojo.TimingTask; |
| | | import com.ruoyi.inspectiontask.service.InspectionTaskService; |
| | | import com.ruoyi.inspectiontask.service.TimingTaskService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | |
| | | public class TimingTaskController extends BaseController { |
| | | |
| | | private TimingTaskService timingTaskService; |
| | | private InspectionTaskService inspectionTaskService; |
| | | |
| | | /** |
| | | * 宿¶å·¡æ£ä»»å¡è¡¨æ¥è¯¢ |
| | |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹å¯ç¨ç¶æ |
| | | */ |
| | | @PostMapping("/changeEnable") |
| | | @Operation(summary = "å¯ç¨æç¦ç¨å®æ¶ä»»å¡") |
| | | @Log(title = "宿¶ä»»å¡", businessType = BusinessType.UPDATE) |
| | | public R changeEnable(@RequestBody TimingTask timingTask) throws SchedulerException { |
| | | return R.ok(timingTaskService.changeEnable(timingTask.getId(), timingTask.getIsEnabled())); |
| | | } |
| | | |
| | | /** |
| | | * 彿¥å·¡æ£è®°å½ |
| | | */ |
| | | @GetMapping("/recordList/{timingId}") |
| | | @Operation(summary = "æå®æ¶ä»»å¡æ¥è¯¢å·¡æ£è®°å½") |
| | | public R<IPage<InspectionTaskDto>> recordList(Page<InspectionTask> page, @PathVariable Long timingId) { |
| | | IPage<InspectionTaskDto> list = inspectionTaskService.selectInspectionTaskRecordList(page, timingId); |
| | | return R.ok(list); |
| | | } |
| | | |
| | | /** |
| | | * 宿¶å·¡æ£ä»»å¡è¡¨å é¤ |
| | | */ |
| | | @DeleteMapping("/delTimingTask") |
| | |
| | | package com.ruoyi.inspectiontask.dto; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import com.ruoyi.basic.dto.StorageBlobDTO; |
| | | import com.ruoyi.basic.dto.StorageBlobVO; |
| | | import com.ruoyi.inspectiontask.pojo.InspectionTask; |
| | | import lombok.Data; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | @Data |
| | |
| | | private List<StorageBlobVO> commonFileListAfterVO; //ç产å |
| | | private List<StorageBlobVO> commonFileListBeforeVO; //ç产å |
| | | |
| | | |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private LocalDateTime createTimeStart; |
| | | |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private LocalDateTime createTimeEnd; |
| | | |
| | | private String areaName; |
| | | } |
| | |
| | | public class TimingTaskDto extends TimingTask { |
| | | |
| | | private List<String> inspector; |
| | | |
| | | private String areaName; |
| | | } |
| | |
| | | package com.ruoyi.inspectiontask.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.ruoyi.inspectiontask.dto.InspectionTaskDto; |
| | | import com.ruoyi.inspectiontask.pojo.InspectionTask; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | | /** |
| | | * @author :yys |
| | | * @date : 2025/9/19 10:46 |
| | | */ |
| | | public interface InspectionTaskMapper extends BaseMapper<InspectionTask> { |
| | | |
| | | IPage<InspectionTask> selectInspectionTaskAggregatePage(Page<InspectionTask> page, @Param("dto") InspectionTaskDto dto); |
| | | } |
| | |
| | | import com.baomidou.mybatisplus.annotation.*; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import com.ruoyi.framework.aspectj.lang.annotation.Excel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | |
| | | |
| | | @Schema(description = "设å¤id") |
| | | private Integer taskId; |
| | | |
| | | @ApiModelProperty(value = "å·¡æ£ç¶æï¼1=å¾
å·¡æ£ï¼2=已巡æ£") |
| | | @Excel(name = "å·¡æ£ç¶æ", readConverterExp = "1=å¾
å·¡æ£,2=已巡æ£") |
| | | private Integer inspectionStatus; |
| | | |
| | | @Schema(description = "å·¡æ£äººID") |
| | | private String inspectorId; |
| | |
| | | |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Long deptId; |
| | | |
| | | private Long areaId; |
| | | |
| | | @Schema(description = "æ¥æºå®æ¶ä»»å¡ID") |
| | | private Long timingId; |
| | | } |
| | |
| | | |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Long deptId; |
| | | |
| | | private Long areaId; |
| | | |
| | | @Schema(description = "设å¤IDéå") |
| | | private String taskIdsStr; |
| | | } |
| | |
| | | |
| | | IPage<InspectionTaskDto> selectInspectionTaskList(Page<InspectionTask> page, InspectionTaskDto inspectionTaskDto); |
| | | |
| | | IPage<InspectionTaskDto> selectInspectionTaskRecordList(Page<InspectionTask> page, Long timingId); |
| | | |
| | | int addOrEditInspectionTask(InspectionTaskDto inspectionTaskDto); |
| | | |
| | | int delByIds(Long[] ids); |
| | |
| | | |
| | | int addOrEditTimingTask(TimingTaskDto timingTaskDto) throws SchedulerException; |
| | | |
| | | int changeEnable(Long id, Integer isEnabled) throws SchedulerException; |
| | | |
| | | int delByIds(Long[] ids); |
| | | |
| | | void updateTaskExecutionTime(Long taskId); |
| | |
| | | import com.ruoyi.common.utils.SecurityUtils; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.common.utils.bean.BeanUtils; |
| | | import com.ruoyi.device.mapper.DeviceAreaMapper; |
| | | import com.ruoyi.device.mapper.DeviceLedgerMapper; |
| | | import com.ruoyi.device.pojo.DeviceArea; |
| | | import com.ruoyi.device.mapper.DeviceRepairMapper; |
| | | import com.ruoyi.device.pojo.DeviceLedger; |
| | | import com.ruoyi.device.pojo.DeviceRepair; |
| | |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.util.Date; |
| | | import java.util.*; |
| | | import java.util.function.Function; |
| | |
| | | |
| | | private final DeviceLedgerMapper deviceLedgerMapper; |
| | | |
| | | private final DeviceAreaMapper deviceAreaMapper; |
| | | |
| | | private static final String INSPECTION_RESULT_ABNORMAL = "0"; |
| | | private static final String INSPECTION_RESULT_NORMAL = "1"; |
| | | private static final int REPAIR_STATUS_PENDING = 0; |
| | | |
| | | @Override |
| | | public IPage<InspectionTaskDto> selectInspectionTaskList(Page<InspectionTask> page, InspectionTaskDto inspectionTaskDto) { |
| | | LambdaQueryWrapper<InspectionTask> queryWrapper = new LambdaQueryWrapper<>(); |
| | | queryWrapper.orderByDesc(InspectionTask::getCreateTime); |
| | | if (StringUtils.isNotBlank(inspectionTaskDto.getTaskName())) { |
| | | queryWrapper.like(InspectionTask::getTaskName, inspectionTaskDto.getTaskName()); |
| | | } |
| | | if (StringUtils.isNotBlank(inspectionTaskDto.getInspectionProject())) { |
| | | queryWrapper.like(InspectionTask::getInspectionProject, inspectionTaskDto.getInspectionProject()); |
| | | } |
| | | queryWrapper.orderByDesc(InspectionTask::getCreateTime); |
| | | IPage<InspectionTask> entityPage = inspectionTaskMapper.selectPage(page, queryWrapper); |
| | | IPage<InspectionTask> entityPage = inspectionTaskMapper.selectInspectionTaskAggregatePage(page, inspectionTaskDto); |
| | | |
| | | // æ æ°æ®æåè¿å |
| | | if (CollectionUtils.isEmpty(entityPage.getRecords())) { |
| | | return new Page<>(entityPage.getCurrent(), entityPage.getSize(), entityPage.getTotal()); |
| | | } |
| | | //ç»è®°äººids |
| | | |
| | | List<Long> registrantIds = entityPage.getRecords().stream().map(InspectionTask::getRegistrantId).collect(Collectors.toList()); |
| | | // æ¹éæ¥è¯¢ç»è®°äºº |
| | | Map<Long, SysUser> sysUserMap; |
| | | if (!registrantIds.isEmpty()) { |
| | | List<SysUser> sysUsers = sysUserMapper.selectUsersByIds(registrantIds); |
| | |
| | | } else { |
| | | sysUserMap = new HashMap<>(); |
| | | } |
| | | //è·åææä¸éå¤çç¨æ·ID |
| | | |
| | | Set<Long> allUserIds = entityPage.getRecords().stream() |
| | | .map(InspectionTask::getInspectorId) // è·å"2,3"è¿æ ·çå符串 |
| | | .map(InspectionTask::getInspectorId) |
| | | .filter(StringUtils::isNotBlank) |
| | | .flatMap(idsStr -> Arrays.stream(idsStr.split(","))) |
| | | .map(idStr -> { |
| | |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toSet()); |
| | | |
| | | // 使ç¨SQLæ¹éæ¥è¯¢ç¨æ·ä¿¡æ¯ |
| | | Map<Long, String> userIdToNameMap = allUserIds.isEmpty() |
| | | ? Collections.emptyMap() |
| | | : sysUserMapper.selectUsersByIds(new ArrayList<>(allUserIds)) |
| | |
| | | SysUser::getUserId, |
| | | SysUser::getNickName, |
| | | (existing, replacement) -> existing)); |
| | | List<InspectionTaskDto> dtoList = entityPage.getRecords().stream().map(inspectionTask -> { |
| | | InspectionTaskDto dto = new InspectionTaskDto(); |
| | | BeanUtils.copyProperties(inspectionTask, dto); // å¤å¶ä¸»å¯¹è±¡å±æ§ |
| | | |
| | | // 设置ç»è®°äºº |
| | | SysUser sysUser = sysUserMap.get(inspectionTask.getRegistrantId()); |
| | | if (sysUser != null) { |
| | | dto.setRegistrant(sysUser.getNickName()); |
| | | } |
| | | // å¤çå·¡æ£äººåç§° |
| | | if (StringUtils.isNotBlank(inspectionTask.getInspectorId())) { |
| | | String inspectorNames = Arrays.stream(inspectionTask.getInspectorId().split(",")) |
| | | .map(String::trim) |
| | | .map(idStr -> { |
| | | try { |
| | | Long userId = Long.parseLong(idStr); |
| | | return userIdToNameMap.getOrDefault(userId, "æªç¥ç¨æ·(" + idStr + ")"); |
| | | } catch (NumberFormatException e) { |
| | | return "æ æID(" + idStr + ")"; |
| | | } |
| | | }) |
| | | .collect(Collectors.joining(",")); |
| | | dto.setInspector(inspectorNames); |
| | | } |
| | | Set<Long> areaIds = entityPage.getRecords().stream() |
| | | .map(InspectionTask::getAreaId) |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toSet()); |
| | | Map<Long, String> areaNameMap = new HashMap<>(); |
| | | if (!areaIds.isEmpty()) { |
| | | List<DeviceArea> areas = deviceAreaMapper.selectBatchIds(new ArrayList<>(areaIds)); |
| | | areas.forEach(area -> areaNameMap.put(area.getId(), area.getAreaName())); |
| | | } |
| | | |
| | | dto.setDateStr(inspectionTask.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); |
| | | // åå§åä¸ä¸ªéä»¶å表 |
| | | dto.setCommonFileListVO(fileUtil.getStorageBlobVOsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum.FILE, RecordTypeEnum.INSPECTION_TASK, inspectionTask.getId())); |
| | | dto.setCommonFileListAfterVO(fileUtil.getStorageBlobVOsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum.AFTER_FILE, RecordTypeEnum.INSPECTION_TASK, inspectionTask.getId())); |
| | | dto.setCommonFileListBeforeVO(fileUtil.getStorageBlobVOsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum.BEFORE_FILE, RecordTypeEnum.INSPECTION_TASK, inspectionTask.getId())); |
| | | List<InspectionTaskDto> dtoList = buildInspectionTaskDtoList( |
| | | entityPage.getRecords(), |
| | | sysUserMap, |
| | | userIdToNameMap, |
| | | areaNameMap |
| | | ); |
| | | |
| | | IPage<InspectionTaskDto> resultPage = new Page<>(); |
| | | BeanUtils.copyProperties(entityPage, resultPage); |
| | | resultPage.setRecords(dtoList); |
| | | return resultPage; |
| | | } |
| | | |
| | | return dto; |
| | | }).collect(Collectors.toList()); |
| | | private List<InspectionTaskDto> buildInspectionTaskDtoList(List<InspectionTask> records, |
| | | Map<Long, SysUser> sysUserMap, |
| | | Map<Long, String> userIdToNameMap, |
| | | Map<Long, String> areaNameMap) { |
| | | if (CollectionUtils.isEmpty(records)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | return records.stream() |
| | | .map(record -> buildInspectionTaskDto(record, sysUserMap, userIdToNameMap, areaNameMap)) |
| | | .collect(Collectors.toList()); |
| | | } |
| | | |
| | | // 7. æå»ºè¿åå页对象 |
| | | private InspectionTaskDto buildInspectionTaskDto(InspectionTask baseTask, |
| | | Map<Long, SysUser> sysUserMap, |
| | | Map<Long, String> userIdToNameMap, |
| | | Map<Long, String> areaNameMap) { |
| | | InspectionTaskDto dto = new InspectionTaskDto(); |
| | | BeanUtils.copyProperties(baseTask, dto); |
| | | |
| | | SysUser sysUser = sysUserMap.get(baseTask.getRegistrantId()); |
| | | if (sysUser != null) { |
| | | dto.setRegistrant(sysUser.getNickName()); |
| | | } |
| | | if (StringUtils.isNotBlank(baseTask.getInspectorId())) { |
| | | String inspectorNames = Arrays.stream(baseTask.getInspectorId().split(",")) |
| | | .map(String::trim) |
| | | .map(idStr -> { |
| | | try { |
| | | Long userId = Long.parseLong(idStr); |
| | | return userIdToNameMap.getOrDefault(userId, "æªç¥ç¨æ·(" + idStr + ")"); |
| | | } catch (NumberFormatException e) { |
| | | return "æ æID(" + idStr + ")"; |
| | | } |
| | | }) |
| | | .collect(Collectors.joining(",")); |
| | | dto.setInspector(inspectorNames); |
| | | } |
| | | |
| | | if (baseTask.getCreateTime() != null) { |
| | | dto.setDateStr(baseTask.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); |
| | | } |
| | | if (baseTask.getAreaId() != null) { |
| | | dto.setAreaName(areaNameMap.getOrDefault(baseTask.getAreaId(), "")); |
| | | } |
| | | dto.setCommonFileListVO(fileUtil.getStorageBlobVOsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum.FILE, RecordTypeEnum.INSPECTION_TASK, baseTask.getId())); |
| | | dto.setCommonFileListAfterVO(fileUtil.getStorageBlobVOsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum.AFTER_FILE, RecordTypeEnum.INSPECTION_TASK, baseTask.getId())); |
| | | dto.setCommonFileListBeforeVO(fileUtil.getStorageBlobVOsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum.BEFORE_FILE, RecordTypeEnum.INSPECTION_TASK, baseTask.getId())); |
| | | return dto; |
| | | } |
| | | |
| | | @Override |
| | | public IPage<InspectionTaskDto> selectInspectionTaskRecordList(Page<InspectionTask> page, Long timingId) { |
| | | InspectionTaskDto queryDto = new InspectionTaskDto(); |
| | | queryDto.setTimingId(timingId); |
| | | queryDto.setCreateTimeStart(LocalDate.now().atStartOfDay()); |
| | | queryDto.setCreateTimeEnd(queryDto.getCreateTimeStart().plusDays(1)); |
| | | |
| | | IPage<InspectionTask> entityPage = inspectionTaskMapper.selectInspectionTaskAggregatePage(page, queryDto); |
| | | if (CollectionUtils.isEmpty(entityPage.getRecords())) { |
| | | return new Page<>(entityPage.getCurrent(), entityPage.getSize(), entityPage.getTotal()); |
| | | } |
| | | |
| | | List<Long> registrantIds = entityPage.getRecords().stream().map(InspectionTask::getRegistrantId).collect(Collectors.toList()); |
| | | Map<Long, SysUser> sysUserMap; |
| | | if (!registrantIds.isEmpty()) { |
| | | List<SysUser> sysUsers = sysUserMapper.selectUsersByIds(registrantIds); |
| | | sysUserMap = sysUsers.stream().collect(Collectors.toMap(SysUser::getUserId, Function.identity())); |
| | | } else { |
| | | sysUserMap = new HashMap<>(); |
| | | } |
| | | |
| | | Set<Long> allUserIds = entityPage.getRecords().stream() |
| | | .map(InspectionTask::getInspectorId) |
| | | .filter(StringUtils::isNotBlank) |
| | | .flatMap(idsStr -> Arrays.stream(idsStr.split(","))) |
| | | .map(idStr -> { |
| | | try { |
| | | return Long.parseLong(idStr.trim()); |
| | | } catch (NumberFormatException e) { |
| | | return null; |
| | | } |
| | | }) |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toSet()); |
| | | |
| | | Map<Long, String> userIdToNameMap = allUserIds.isEmpty() |
| | | ? Collections.emptyMap() |
| | | : sysUserMapper.selectUsersByIds(new ArrayList<>(allUserIds)) |
| | | .stream() |
| | | .collect(Collectors.toMap( |
| | | SysUser::getUserId, |
| | | SysUser::getNickName, |
| | | (existing, replacement) -> existing)); |
| | | |
| | | Set<Long> areaIds = entityPage.getRecords().stream() |
| | | .map(InspectionTask::getAreaId) |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toSet()); |
| | | Map<Long, String> areaNameMap = new HashMap<>(); |
| | | if (!areaIds.isEmpty()) { |
| | | List<DeviceArea> areas = deviceAreaMapper.selectBatchIds(new ArrayList<>(areaIds)); |
| | | areas.forEach(area -> areaNameMap.put(area.getId(), area.getAreaName())); |
| | | } |
| | | |
| | | List<InspectionTaskDto> dtoList = entityPage.getRecords().stream() |
| | | .map(task -> buildInspectionTaskDto(task, sysUserMap, userIdToNameMap, areaNameMap)) |
| | | .collect(Collectors.toList()); |
| | | |
| | | IPage<InspectionTaskDto> resultPage = new Page<>(); |
| | | BeanUtils.copyProperties(entityPage, resultPage); |
| | | resultPage.setRecords(dtoList); |
| | |
| | | BeanUtils.copyProperties(inspectionTaskDto, inspectionTask); |
| | | inspectionTask.setRegistrantId(SecurityUtils.getLoginUser().getUserId()); |
| | | inspectionTask.setRegistrant(SecurityUtils.getLoginUser().getUsername()); |
| | | inspectionTask.setInspectionStatus(2); |
| | | fillAcceptanceInfo(inspectionTask, oldInspectionTask); |
| | | int i; |
| | | if (Objects.isNull(inspectionTaskDto.getId())) { |
| | |
| | | import java.time.LocalDateTime; |
| | | import java.time.LocalTime; |
| | | import java.time.YearMonth; |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @Component |
| | | @DisallowConcurrentExecution // ç¦æ¢å¹¶åæ§è¡åä¸ä¸ªJob |
| | |
| | | // throw new JobExecutionException("宿¶ä»»å¡å·²ç¦ç¨: " + taskId); |
| | | // } |
| | | |
| | | // 2. å建并ä¿åå·¡æ£ä»»å¡è®°å½ - è¿å°±æ¯æ¨æä¾ç代ç åºè¯¥æ¾çä½ç½® |
| | | InspectionTask inspectionTask = createInspectionTask(timingTask); |
| | | inspectionTaskMapper.insert(inspectionTask); |
| | | // 2. è§£æè®¾å¤IDå表ï¼ä¸ºæ¯ä¸ªè®¾å¤å建巡æ£ä»»å¡è®°å½ |
| | | List<Integer> deviceIds = resolveDeviceIds(timingTask); |
| | | for (Integer deviceId : deviceIds) { |
| | | InspectionTask inspectionTask = createInspectionTask(timingTask, deviceId); |
| | | inspectionTaskMapper.insert(inspectionTask); |
| | | } |
| | | |
| | | // 3. æ´æ°å®æ¶ä»»å¡çæ§è¡æ¶é´ |
| | | if (!tasks.isEmpty()) { |
| | |
| | | } |
| | | } |
| | | |
| | | // è¿å°±æ¯æ¨æä¾ç代ç å°è£
æçæ¹æ³ |
| | | private InspectionTask createInspectionTask(TimingTask timingTask) { |
| | | private List<Integer> resolveDeviceIds(TimingTask timingTask) throws JobExecutionException { |
| | | if (StringUtils.isNotBlank(timingTask.getTaskIdsStr())) { |
| | | return Arrays.stream(timingTask.getTaskIdsStr().split(",")) |
| | | .map(String::trim) |
| | | .filter(StringUtils::isNotBlank) |
| | | .map(Integer::parseInt) |
| | | .collect(Collectors.toList()); |
| | | } |
| | | if (timingTask.getTaskId() != null) { |
| | | List<Integer> list = new ArrayList<>(); |
| | | list.add(timingTask.getTaskId()); |
| | | return list; |
| | | } |
| | | throw new JobExecutionException("宿¶ä»»å¡ " + timingTask.getId() + " æªé
置设å¤ID"); |
| | | } |
| | | |
| | | private InspectionTask createInspectionTask(TimingTask timingTask, Integer deviceId) { |
| | | InspectionTask inspectionTask = new InspectionTask(); |
| | | |
| | | // å¤å¶åºæ¬å±æ§ |
| | | inspectionTask.setTaskName(timingTask.getTaskName()); |
| | | inspectionTask.setInspectionProject(timingTask.getInspectionProject()); |
| | | inspectionTask.setTaskId(timingTask.getTaskId()); |
| | | inspectionTask.setTaskId(deviceId); |
| | | inspectionTask.setInspectorId(timingTask.getInspectorIds()); |
| | | inspectionTask.setInspectionLocation(timingTask.getInspectionLocation()); |
| | | inspectionTask.setAreaId(timingTask.getAreaId()); |
| | | inspectionTask.setTimingId(timingTask.getId()); |
| | | String remarks = "èªå¨çæèªå®æ¶ä»»å¡ID: " + timingTask.getId(); |
| | | if (StringUtils.isNotBlank(timingTask.getRemarks())) { |
| | | remarks = remarks + "ï¼" + timingTask.getRemarks(); |
| | |
| | | inspectionTask.setFrequencyType(timingTask.getFrequencyType()); |
| | | inspectionTask.setFrequencyDetail(timingTask.getFrequencyDetail()); |
| | | inspectionTask.setTenantId(timingTask.getTenantId()); |
| | | inspectionTask.setInspectionStatus(1); |
| | | |
| | | return inspectionTask; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.inspectiontask.service.impl; |
| | | |
| | | import java.time.DayOfWeek; |
| | | import java.time.LocalDateTime; |
| | | import java.time.LocalTime; |
| | | import java.time.YearMonth; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.time.format.DateTimeParseException; |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | |
| | | final class TimingTaskScheduleUtils { |
| | | |
| | | private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm"); |
| | | |
| | | private TimingTaskScheduleUtils() { |
| | | } |
| | | |
| | | static LocalDateTime calculateFirstExecutionTime(String frequencyType, String frequencyDetail) { |
| | | return calculateNextExecutionTime(frequencyType, frequencyDetail, LocalDateTime.now().minusSeconds(1)); |
| | | } |
| | | |
| | | static LocalDateTime calculateNextExecutionTime(String frequencyType, String frequencyDetail, LocalDateTime currentTime) { |
| | | if (frequencyType == null || frequencyDetail == null) { |
| | | throw new IllegalArgumentException("ä»»å¡åæ°ä¸è½ä¸ºç©º"); |
| | | } |
| | | switch (frequencyType.toUpperCase()) { |
| | | case "DAILY": |
| | | return calculateDailyNextTime(frequencyDetail, currentTime); |
| | | case "WEEKLY": |
| | | return calculateWeeklyNextTime(frequencyDetail, currentTime); |
| | | case "MONTHLY": |
| | | return calculateMonthlyNextTime(frequencyDetail, currentTime); |
| | | case "QUARTERLY": |
| | | return calculateQuarterlyNextTime(frequencyDetail, currentTime); |
| | | default: |
| | | throw new IllegalArgumentException("䏿¯æçé¢çç±»å: " + frequencyType); |
| | | } |
| | | } |
| | | |
| | | private static LocalDateTime calculateDailyNextTime(String timeStr, LocalDateTime current) { |
| | | LocalTime executionTime = parseTime(timeStr); |
| | | LocalDateTime nextTime = LocalDateTime.of(current.toLocalDate(), executionTime); |
| | | return current.isBefore(nextTime) ? nextTime : nextTime.plusDays(1); |
| | | } |
| | | |
| | | private static LocalDateTime calculateWeeklyNextTime(String detail, LocalDateTime current) { |
| | | String[] parts = validateAndSplit(detail, ",", 2); |
| | | Set<DayOfWeek> targetDays = parseDayOfWeeks(parts[0]); |
| | | LocalTime time = parseTime(parts[1]); |
| | | |
| | | LocalDateTime nextTime = current; |
| | | for (int i = 0; i < 366; i++) { |
| | | nextTime = nextTime.plusDays(1); |
| | | if (targetDays.contains(nextTime.getDayOfWeek())) { |
| | | return LocalDateTime.of(nextTime.toLocalDate(), time); |
| | | } |
| | | } |
| | | throw new IllegalArgumentException("æ æ³æ¾å°ä¸ä¸æ¬¡æ§è¡æ¶é´"); |
| | | } |
| | | |
| | | private static LocalDateTime calculateMonthlyNextTime(String detail, LocalDateTime current) { |
| | | String[] parts = validateAndSplit(detail, ",", 2); |
| | | int dayOfMonth = validateDayOfMonth(parts[0]); |
| | | LocalTime time = parseTime(parts[1]); |
| | | |
| | | for (int i = 0; i < 24; i++) { |
| | | YearMonth targetYearMonth = YearMonth.from(current).plusMonths(i); |
| | | int adjustedDay = Math.min(dayOfMonth, targetYearMonth.lengthOfMonth()); |
| | | LocalDateTime target = LocalDateTime.of( |
| | | targetYearMonth.getYear(), |
| | | targetYearMonth.getMonthValue(), |
| | | adjustedDay, |
| | | time.getHour(), |
| | | time.getMinute() |
| | | ); |
| | | if (target.isAfter(current)) { |
| | | return target; |
| | | } |
| | | } |
| | | throw new IllegalArgumentException("æ æ³æ¾å°ä¸ä¸æ¬¡æ§è¡æ¶é´"); |
| | | } |
| | | |
| | | private static LocalDateTime calculateQuarterlyNextTime(String detail, LocalDateTime current) { |
| | | String[] parts = validateAndSplit(detail, ",", 3); |
| | | int startMonth = validateMonth(parts[0]); |
| | | int dayOfMonth = validateDayOfMonth(parts[1]); |
| | | LocalTime time = parseTime(parts[2]); |
| | | |
| | | YearMonth anchor = YearMonth.of(current.getYear(), startMonth); |
| | | for (int i = 0; i < 12; i++) { |
| | | YearMonth targetYearMonth = anchor.plusMonths(3L * i); |
| | | int adjustedDay = Math.min(dayOfMonth, targetYearMonth.lengthOfMonth()); |
| | | LocalDateTime target = LocalDateTime.of( |
| | | targetYearMonth.getYear(), |
| | | targetYearMonth.getMonthValue(), |
| | | adjustedDay, |
| | | time.getHour(), |
| | | time.getMinute() |
| | | ); |
| | | if (target.isAfter(current)) { |
| | | return target; |
| | | } |
| | | } |
| | | throw new IllegalArgumentException("æ æ³æ¾å°ä¸ä¸æ¬¡æ§è¡æ¶é´"); |
| | | } |
| | | |
| | | private static LocalTime parseTime(String timeStr) { |
| | | try { |
| | | return LocalTime.parse(timeStr, TIME_FORMATTER); |
| | | } catch (DateTimeParseException e) { |
| | | throw new IllegalArgumentException("æ¶é´æ ¼å¼å¿
须为HH:mm", e); |
| | | } |
| | | } |
| | | |
| | | private static String[] validateAndSplit(String input, String delimiter, int expectedParts) { |
| | | String[] parts = input.split(delimiter); |
| | | if (parts.length != expectedParts) { |
| | | throw new IllegalArgumentException("åæ°æ ¼å¼é误"); |
| | | } |
| | | return parts; |
| | | } |
| | | |
| | | private static int validateDayOfMonth(String dayStr) { |
| | | int day = Integer.parseInt(dayStr.trim()); |
| | | if (day < 1 || day > 31) { |
| | | throw new IllegalArgumentException("æ¥æå¿
é¡»å¨1-31ä¹é´"); |
| | | } |
| | | return day; |
| | | } |
| | | |
| | | private static int validateMonth(String monthStr) { |
| | | int month = Integer.parseInt(monthStr.trim()); |
| | | if (month < 1 || month > 12) { |
| | | throw new IllegalArgumentException("æä»½å¿
é¡»å¨1-12ä¹é´"); |
| | | } |
| | | return month; |
| | | } |
| | | |
| | | private static Set<DayOfWeek> parseDayOfWeeks(String dayOfWeekStr) { |
| | | Set<DayOfWeek> days = new HashSet<>(); |
| | | for (String dayStr : dayOfWeekStr.split("\\|")) { |
| | | switch (dayStr.trim().toUpperCase()) { |
| | | case "MON": |
| | | days.add(DayOfWeek.MONDAY); |
| | | break; |
| | | case "TUE": |
| | | days.add(DayOfWeek.TUESDAY); |
| | | break; |
| | | case "WED": |
| | | days.add(DayOfWeek.WEDNESDAY); |
| | | break; |
| | | case "THU": |
| | | days.add(DayOfWeek.THURSDAY); |
| | | break; |
| | | case "FRI": |
| | | days.add(DayOfWeek.FRIDAY); |
| | | break; |
| | | case "SAT": |
| | | days.add(DayOfWeek.SATURDAY); |
| | | break; |
| | | case "SUN": |
| | | days.add(DayOfWeek.SUNDAY); |
| | | break; |
| | | default: |
| | | throw new IllegalArgumentException("æ æçææå : " + dayStr); |
| | | } |
| | | } |
| | | return days; |
| | | } |
| | | } |
| | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.common.utils.bean.BeanUtils; |
| | | import com.ruoyi.device.mapper.DeviceAreaMapper; |
| | | import com.ruoyi.device.pojo.DeviceArea; |
| | | import com.ruoyi.inspectiontask.dto.TimingTaskDto; |
| | | import com.ruoyi.inspectiontask.mapper.TimingTaskMapper; |
| | | import com.ruoyi.inspectiontask.pojo.TimingTask; |
| | |
| | | private final TimingTaskMapper timingTaskMapper; |
| | | private final TimingTaskScheduler timingTaskScheduler; |
| | | private final SysUserMapper sysUserMapper; |
| | | private final DeviceAreaMapper deviceAreaMapper; |
| | | private static final int ENABLED = 1; |
| | | private static final int DISABLED = 0; |
| | | |
| | |
| | | } |
| | | if (timingTask.getIsEnabled() != null) { |
| | | queryWrapper.eq(TimingTask::getIsEnabled, timingTask.getIsEnabled()); |
| | | } |
| | | if (timingTask.getAreaId() != null) { |
| | | queryWrapper.eq(TimingTask::getAreaId, timingTask.getAreaId()); |
| | | } |
| | | if (StringUtils.isNotBlank(timingTask.getTaskIdsStr())) { |
| | | queryWrapper.like(TimingTask::getTaskIdsStr, timingTask.getTaskIdsStr()); |
| | | } |
| | | queryWrapper.orderByDesc(TimingTask::getCreateTime); |
| | | IPage<TimingTask> taskPage = timingTaskMapper.selectPage(page, queryWrapper); |
| | |
| | | users.forEach(user -> userNickNameMap.put(user.getUserId(), user.getNickName())); |
| | | } |
| | | |
| | | // 4.1 æ¹éæ¥è¯¢åºååç§° |
| | | Set<Long> areaIds = taskPage.getRecords().stream() |
| | | .map(TimingTask::getAreaId) |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toSet()); |
| | | Map<Long, String> areaNameMap = new HashMap<>(); |
| | | if (!areaIds.isEmpty()) { |
| | | List<DeviceArea> areas = deviceAreaMapper.selectBatchIds(new ArrayList<>(areaIds)); |
| | | areas.forEach(area -> areaNameMap.put(area.getId(), area.getAreaName())); |
| | | } |
| | | |
| | | // 5. 转æ¢ä¸ºDTO |
| | | List<TimingTaskDto> dtoList = taskPage.getRecords().stream().map(task -> { |
| | | TimingTaskDto dto = new TimingTaskDto(); |
| | |
| | | dto.setInspector(inspectorNickNames); |
| | | } |
| | | |
| | | // 设置åºååç§° |
| | | if (task.getAreaId() != null) { |
| | | dto.setAreaName(areaNameMap.getOrDefault(task.getAreaId(), "")); |
| | | } |
| | | |
| | | return dto; |
| | | }).collect(Collectors.toList()); |
| | | |
| | |
| | | } |
| | | |
| | | @Override |
| | | @Transactional |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int addOrEditTimingTask(TimingTaskDto timingTaskDto) throws SchedulerException { |
| | | TimingTask oldTimingTask = null; |
| | | if (Objects.nonNull(timingTaskDto.getId())) { |
| | |
| | | } |
| | | return result; |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int changeEnable(Long id, Integer isEnabled) throws SchedulerException { |
| | | TimingTask oldTimingTask = timingTaskMapper.selectById(id); |
| | | if (oldTimingTask == null) { |
| | | throw new IllegalArgumentException("宿¶ä»»å¡ä¸åå¨"); |
| | | } |
| | | TimingTask update = new TimingTask(); |
| | | update.setId(id); |
| | | update.setIsEnabled(resolveEnabledValue(isEnabled, oldTimingTask)); |
| | | update.setActive(ENABLED == update.getIsEnabled()); |
| | | |
| | | int result = timingTaskMapper.updateById(update); |
| | | if (result <= 0) { |
| | | return result; |
| | | } |
| | | |
| | | boolean enabled = isEnabled(update.getIsEnabled(), update.isActive()); |
| | | if (!enabled) { |
| | | timingTaskScheduler.unscheduleTimingTask(id); |
| | | } else if (oldTimingTask.getIsEnabled() != null && oldTimingTask.getIsEnabled() == DISABLED) { |
| | | timingTaskScheduler.scheduleTimingTask(oldTimingTask); |
| | | } else { |
| | | timingTaskScheduler.resumeTimingTask(id); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | public LocalDateTime calculateFirstExecutionTime(TimingTask task) { |
| | |
| | | } |
| | | |
| | | private LocalDateTime calculateCustomFirstExecution(String frequencyDetail) { |
| | | return null; |
| | | return TimingTaskScheduleUtils.calculateFirstExecutionTime("QUARTERLY", frequencyDetail); |
| | | } |
| | | |
| | | @Override |
| | |
| | | /** |
| | | * è®¡ç®æ¯å£åº¦ä»»å¡ç䏿¬¡æ§è¡æ¶é´ |
| | | */ |
| | | private LocalDateTime calculateQuarterlyNextTime(String detail, LocalDateTime current) { |
| | | private LocalDateTime calculateQuarterlyNextTimeLegacy(String detail, LocalDateTime current) { |
| | | String[] parts = detail.split(","); |
| | | int quarterMonth = Integer.parseInt(parts[0]); // 1=第1个æï¼2=第2个æï¼3=第3个æ |
| | | int dayOfMonth = Integer.parseInt(parts[1]); |
| | |
| | | /** |
| | | * è§£æææå å符串 |
| | | */ |
| | | private LocalDateTime calculateQuarterlyNextTime(String detail, LocalDateTime current) { |
| | | return TimingTaskScheduleUtils.calculateNextExecutionTime("QUARTERLY", detail, current); |
| | | } |
| | | private Set<DayOfWeek> parseDayOfWeeks(String dayOfWeekStr) { |
| | | Set<DayOfWeek> days = new HashSet<>(); |
| | | String[] dayStrs = dayOfWeekStr.split("\\|"); |
| | |
| | | druid: |
| | | # ä¸»åºæ°æ®æº |
| | | master: |
| | | url: jdbc:mysql://localhost:3306/product-inventory-management-new-pro?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 |
| | | url: jdbc:mysql://localhost:3306/product-inventory-management-dlsmls-pro?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 |
| | | username: root |
| | | password: 123456 |
| | | # ä»åºæ°æ®æº |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 项ç®ç¸å
³é
ç½® |
| | | ruoyi: |
| | | # åç§° |
| | | name: RuoYi |
| | | # çæ¬ |
| | | version: 3.8.9 |
| | | # çæå¹´ä»½ |
| | | copyrightYear: 2025 |
| | | # æä»¶è·¯å¾ 示ä¾ï¼ Windowsé
ç½®D:/ruoyi/uploadPathï¼Linuxé
ç½® /home/ruoyi/uploadPathï¼ |
| | | profile: /javaWork/product-inventory-management/file |
| | | |
| | | # è·åipå°åå¼å
³ |
| | | addressEnabled: false |
| | | # éªè¯ç ç±»å math æ°åè®¡ç® char å符éªè¯ |
| | | captchaType: math |
| | | # åå审æ¹ç¼å·åç¼(é
ç½®æä»¶åç¼å½å) |
| | | approvalNumberPrefix: NEW |
| | | |
| | | # ä¸ªæ¨ Unipush é
ç½® |
| | | getui: |
| | | appId: PfjyAAE0FK64FaO1w2CMb1 |
| | | appKey: zTMb831OEL6J4GK1uE3Ob4 |
| | | masterSecret: K1GFtsv42v61tXGnF7SGE5 |
| | | domain: https://restapi.getui.cn/v2/ |
| | | # 离线æ¨é使ç¨çå
å/ç»ä»¶å |
| | | intentComponent: uni.app.UNI099A590/io.dcloud.PandoraEntry |
| | | |
| | | # å¼åç¯å¢é
ç½® |
| | | server: |
| | | # æå¡å¨çHTTP端å£ï¼é»è®¤ä¸º8080 |
| | | port: 9003 |
| | | servlet: |
| | | # åºç¨ç访é®è·¯å¾ |
| | | context-path: / |
| | | tomcat: |
| | | # tomcatçURIç¼ç |
| | | uri-encoding: UTF-8 |
| | | # è¿æ¥æ°æ»¡åçæéæ°ï¼é»è®¤ä¸º100 |
| | | accept-count: 1000 |
| | | threads: |
| | | # tomcatæå¤§çº¿ç¨æ°ï¼é»è®¤ä¸º200 |
| | | max: 800 |
| | | # Tomcatå¯å¨åå§åççº¿ç¨æ°ï¼é»è®¤å¼10 |
| | | min-spare: 100 |
| | | |
| | | # æ¥å¿é
ç½® |
| | | logging: |
| | | level: |
| | | com.ruoyi: warn |
| | | org.springframework: warn |
| | | |
| | | minio: |
| | | endpoint: http://114.132.189.42/ |
| | | port: 7019 |
| | | secure: false |
| | | accessKey: admin |
| | | secretKey: 12345678 |
| | | preview-expiry: 24 # é¢è§å°åé»è®¤24å°æ¶ |
| | | default-bucket: jxc |
| | | # ç¨æ·é
ç½® |
| | | user: |
| | | password: |
| | | # å¯ç æå¤§éè¯¯æ¬¡æ° |
| | | maxRetryCount: 5 |
| | | # å¯ç é宿¶é´ï¼é»è®¤10åéï¼ |
| | | lockTime: 10 |
| | | |
| | | # Springé
ç½® |
| | | spring: |
| | | datasource: |
| | | type: com.alibaba.druid.pool.DruidDataSource |
| | | driverClassName: com.mysql.cj.jdbc.Driver |
| | | druid: |
| | | # ä¸»åºæ°æ®æº |
| | | master: |
| | | url: jdbc:mysql://172.17.0.1:3306/product-inventory-management-dlsmls-pro?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 |
| | | username: root |
| | | password: xd@123456.. |
| | | # ä»åºæ°æ®æº |
| | | slave: |
| | | # 仿°æ®æºå¼å
³/é»è®¤å
³é |
| | | enabled: false |
| | | url: |
| | | username: |
| | | password: |
| | | # åå§è¿æ¥æ° |
| | | initialSize: 5 |
| | | # æå°è¿æ¥æ± æ°é |
| | | minIdle: 10 |
| | | # æå¤§è¿æ¥æ± æ°é |
| | | maxActive: 20 |
| | | # é
ç½®è·åè¿æ¥çå¾
è¶
æ¶çæ¶é´ |
| | | maxWait: 60000 |
| | | # é
ç½®è¿æ¥è¶
æ¶æ¶é´ |
| | | connectTimeout: 30000 |
| | | # é
ç½®ç½ç»è¶
æ¶æ¶é´ |
| | | socketTimeout: 60000 |
| | | # é
ç½®é´éå¤ä¹
æè¿è¡ä¸æ¬¡æ£æµï¼æ£æµéè¦å
³éç空é²è¿æ¥ï¼å使¯æ¯«ç§ |
| | | timeBetweenEvictionRunsMillis: 60000 |
| | | # é
ç½®ä¸ä¸ªè¿æ¥å¨æ± 䏿å°çåçæ¶é´ï¼å使¯æ¯«ç§ |
| | | minEvictableIdleTimeMillis: 300000 |
| | | # é
ç½®ä¸ä¸ªè¿æ¥å¨æ± 䏿大çåçæ¶é´ï¼å使¯æ¯«ç§ |
| | | maxEvictableIdleTimeMillis: 900000 |
| | | # é
ç½®æ£æµè¿æ¥æ¯å¦ææ |
| | | validationQuery: SELECT 1 FROM DUAL |
| | | testWhileIdle: true |
| | | testOnBorrow: false |
| | | testOnReturn: false |
| | | webStatFilter: |
| | | enabled: true |
| | | statViewServlet: |
| | | enabled: true |
| | | # 设置ç½ååï¼ä¸å¡«åå
许ææè®¿é® |
| | | allow: |
| | | url-pattern: /druid/* |
| | | # æ§å¶å°ç®¡çç¨æ·ååå¯ç |
| | | login-username: ruoyi |
| | | login-password: 123456 |
| | | filter: |
| | | stat: |
| | | enabled: true |
| | | # æ
¢SQLè®°å½ |
| | | log-slow-sql: true |
| | | slow-sql-millis: 1000 |
| | | merge-sql: true |
| | | wall: |
| | | config: |
| | | multi-statement-allow: true |
| | | # èµæºä¿¡æ¯ |
| | | messages: |
| | | # å½é
åèµæºæä»¶è·¯å¾ |
| | | basename: i18n/messages |
| | | # æä»¶ä¸ä¼ |
| | | servlet: |
| | | multipart: |
| | | # å个æä»¶å¤§å° |
| | | max-file-size: 1GB |
| | | # 设置æ»ä¸ä¼ çæä»¶å¤§å° |
| | | max-request-size: 2GB |
| | | # æå¡æ¨¡å |
| | | devtools: |
| | | restart: |
| | | # çé¨ç½²å¼å
³ |
| | | enabled: false |
| | | # redis é
ç½® |
| | | data: |
| | | mongodb: |
| | | uri: mongodb://114.132.189.42:9028/chat_memory_db_dlsmls-pro |
| | | # redis é
ç½® |
| | | redis: |
| | | # å°å |
| | | # host: 127.0.0.1 |
| | | host: 172.17.0.1 |
| | | # 端å£ï¼é»è®¤ä¸º6379 |
| | | port: 6379 |
| | | # æ°æ®åºç´¢å¼ |
| | | database: 4 |
| | | # å¯ç |
| | | # password: root2022! |
| | | password: |
| | | |
| | | # è¿æ¥è¶
æ¶æ¶é´ |
| | | timeout: 10s |
| | | lettuce: |
| | | pool: |
| | | # è¿æ¥æ± ä¸çæå°ç©ºé²è¿æ¥ |
| | | min-idle: 0 |
| | | # è¿æ¥æ± ä¸çæå¤§ç©ºé²è¿æ¥ |
| | | max-idle: 8 |
| | | # è¿æ¥æ± çæå¤§æ°æ®åºè¿æ¥æ° |
| | | max-active: 8 |
| | | # #è¿æ¥æ± æå¤§é»å¡çå¾
æ¶é´ï¼ä½¿ç¨è´å¼è¡¨ç¤ºæ²¡æéå¶ï¼ |
| | | max-wait: -1ms |
| | | |
| | | # Quartz宿¶ä»»å¡é
ç½®ï¼æ°å¢é¨åï¼ |
| | | quartz: |
| | | job-store-type: jdbc # ä½¿ç¨æ°æ®åºåå¨ |
| | | jdbc: |
| | | initialize-schema: never # 馿¬¡è¿è¡æ¶èªå¨åå»ºè¡¨ç»æï¼æååæ¹ä¸ºnever |
| | | schema: classpath:org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql # MySQLè¡¨ç»æèæ¬ |
| | | properties: |
| | | org: |
| | | quartz: |
| | | scheduler: |
| | | instanceName: RuoYiScheduler |
| | | instanceId: AUTO |
| | | jobStore: |
| | | class: org.quartz.impl.jdbcjobstore.JobStoreTX |
| | | driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate # MySQLéé
|
| | | tablePrefix: qrtz_ # 表ååç¼ï¼ä¸èæ¬ä¸è´ |
| | | isClustered: false # åèç¹æ¨¡å¼ï¼éç¾¤éæ¹ä¸ºtrueï¼ |
| | | clusterCheckinInterval: 10000 |
| | | txIsolationLevelSerializable: true |
| | | threadPool: |
| | | class: org.quartz.simpl.SimpleThreadPool |
| | | threadCount: 10 # çº¿ç¨æ± å¤§å° |
| | | threadPriority: 5 |
| | | makeThreadsDaemons: true |
| | | updateCheck: false # å
³éçæ¬æ£æ¥ |
| | | # tokené
ç½® |
| | | token: |
| | | # 令çèªå®ä¹æ è¯ |
| | | header: Authorization |
| | | # 令çå¯é¥ |
| | | secret: xpAVjhCjQDaDB7mjPAzMDSbQWXNu2zYkTdDNUsPMS5Xx8QMmQVYN7n74eZrYJxDJ |
| | | # ä»¤çæææï¼é»è®¤30åéï¼ |
| | | expireTime: 450 |
| | | |
| | | # MyBatis Plusé
ç½® |
| | | mybatis-plus: |
| | | # æç´¢æå®å
å«å æ ¹æ®èªå·±çé¡¹ç®æ¥ |
| | | typeAliasesPackage: com.ruoyi.**.pojo |
| | | # é
ç½®mapperçæ«æï¼æ¾å°ææçmapper.xmlæ å°æä»¶ |
| | | mapperLocations: classpath*:mapper/**/*Mapper.xml |
| | | # å è½½å
¨å±çé
ç½®æä»¶ |
| | | configLocation: classpath:mybatis/mybatis-config.xml |
| | | global-config: |
| | | enable-sql-runner: true |
| | | db-config: |
| | | id-type: auto |
| | | |
| | | # PageHelperå页æä»¶ |
| | | pagehelper: |
| | | helperDialect: mysql |
| | | supportMethodsArguments: true |
| | | params: count=countSql |
| | | |
| | | # Swaggeré
ç½® |
| | | swagger: |
| | | # æ¯å¦å¼å¯swagger |
| | | enabled: true |
| | | # 请æ±åç¼ |
| | | pathMapping: /dev-api |
| | | |
| | | # 鲿¢XSSæ»å» |
| | | xss: |
| | | # è¿æ»¤å¼å
³ |
| | | enabled: true |
| | | # æé¤é¾æ¥ï¼å¤ä¸ªç¨éå·åéï¼ |
| | | excludes: /system/notice |
| | | # å¹é
龿¥ |
| | | urlPatterns: /system/*,/monitor/*,/tool/* |
| | | |
| | | # 代ç çæ |
| | | gen: |
| | | # ä½è
|
| | | author: ruoyi |
| | | # é»è®¤çæå
è·¯å¾ system éæ¹æèªå·±ç模ååç§° å¦ system monitor tool |
| | | packageName: com.ruoyi.project.system |
| | | # èªå¨å»é¤è¡¨åç¼ï¼é»è®¤æ¯true |
| | | autoRemovePre: false |
| | | # 表åç¼ï¼çæç±»åä¸ä¼å
å«è¡¨åç¼ï¼å¤ä¸ªç¨éå·åéï¼ |
| | | tablePrefix: sys_ |
| | | # æ¯å¦å
è®¸çææä»¶è¦çå°æ¬å°ï¼èªå®ä¹è·¯å¾ï¼ï¼é»è®¤ä¸å
许 |
| | | allowOverwrite: false |
| | | |
| | | # æä»¶ä¸ä¼ é
ç½® |
| | | file: |
| | | temp-dir: /javaWork/product-inventory-management/file/temp/uploads # 临æ¶ç®å½ |
| | | upload-dir: /javaWork/product-inventory-management/file/prod/uploads # æ£å¼ç®å½ |
| | | path: /javaWork/product-inventory-management/file # ä¸ä¼ ç®å½ |
| | | urlPrefix: /prod-api/common # 龿¥åç¼ |
| | | domain: http://1.15.17.182:9074 # åååç¼ |
| | | expired: 120 # è¿ææ¶é´(åä½:åé) |
| | | useLimit: 10 # ä½¿ç¨æ¬¡æ° |
| | | compress: true # æ¯å¦å缩 |
| | | needCompressSize: 10MB # å缩éå¼ |
| | | compressQuality: 0.5 # å缩质é(0.0-1.0) |
| | |
| | | dl.tenant_id, |
| | | dl.is_depr, |
| | | dl.annual_depreciation_amount, |
| | | dl.type |
| | | dl.type, |
| | | dl.area_id, |
| | | dl.is_iot_device, |
| | | dl.external_code, |
| | | da.area_name AS areaName |
| | | FROM device_ledger dl |
| | | left join sys_user su on dl.create_user = su.user_id |
| | | left join device_area da on dl.area_id = da.id |
| | | <where> |
| | | <!-- 设å¤åç§° --> |
| | | <if test="deviceLedger.deviceName != null and deviceLedger.deviceName != ''"> |
| | |
| | | <if test="deviceLedger.tenantId != null"> |
| | | AND tenant_id = #{deviceLedger.tenantId} |
| | | </if> |
| | | |
| | | <!-- 设å¤åºå --> |
| | | <if test="deviceLedger.areaId != null"> |
| | | AND dl.area_id = #{deviceLedger.areaId} |
| | | </if> |
| | | |
| | | <!-- æ¯å¦ç©èè®¾å¤ --> |
| | | <if test="deviceLedger.isIotDevice != null"> |
| | | AND dl.is_iot_device = #{deviceLedger.isIotDevice} |
| | | </if> |
| | | |
| | | <!-- å¤é¨ç¼ç --> |
| | | <if test="deviceLedger.externalCode != null and deviceLedger.externalCode != ''"> |
| | | AND dl.external_code LIKE CONCAT('%', #{deviceLedger.externalCode}, '%') |
| | | </if> |
| | | </where> |
| | | ORDER BY create_time DESC |
| | | </select> |
| | |
| | | <select id="queryPage" resultType="com.ruoyi.device.dto.DeviceMaintenanceDto"> |
| | | select dm.id, |
| | | dm.device_ledger_id, |
| | | dm.area_id, |
| | | dm.maintenance_plan_time, |
| | | dm.maintenance_actually_time, |
| | | dm.maintenance_result, |
| | |
| | | dl.device_name, |
| | | dm.machinery_category, |
| | | dl.device_model, |
| | | da.area_name, |
| | | su.nick_name as create_user_name |
| | | from device_maintenance dm |
| | | left join device_ledger dl on dm.device_ledger_id = dl.id |
| | | left join device_area da on dl.area_id = da.id |
| | | left join sys_user su on dm.create_user = su.user_id |
| | | <where> |
| | | <if test="deviceMaintenanceDto.deviceName != null"> |
| | |
| | | and dm.maintenance_actually_time >= str_to_date(#{deviceMaintenanceDto.maintenanceActuallyTime}, '%Y-%m-%d') |
| | | and dm.maintenance_actually_time < date_add(str_to_date(#{deviceMaintenanceDto.maintenanceActuallyTime}, '%Y-%m-%d'), interval 1 day) |
| | | </if> |
| | | <if test="deviceMaintenanceDto.areaId != null"> |
| | | and dm.area_id = #{deviceMaintenanceDto.areaId} |
| | | </if> |
| | | </where> |
| | | order by dm.create_time desc |
| | | </select> |
| | | <select id="detailById" resultType="com.ruoyi.device.vo.DeviceMaintenanceVo"> |
| | | select dm.id, |
| | | dm.device_ledger_id, |
| | | dm.area_id, |
| | | dm.maintenance_plan_time, |
| | | dm.maintenance_actually_time, |
| | | dm.maintenance_result, |
| | |
| | | dm.maintenance_actually_name, |
| | | dl.device_name, |
| | | dl.device_model, |
| | | da.area_name, |
| | | su.user_name as create_user_name |
| | | from device_maintenance dm |
| | | left join device_ledger dl on dm.device_ledger_id = dl.id |
| | | left join device_area da on dl.area_id = da.id |
| | | left join sys_user su on dm.create_user = su.user_id |
| | | where dm.id = #{id} |
| | | </select> |
| | |
| | | <select id="queryPage" resultType="com.ruoyi.device.vo.DeviceRepairVo"> |
| | | select dr.id, |
| | | dr.device_ledger_id, |
| | | dr.area_id, |
| | | dr.repair_time, |
| | | dr.repair_name, |
| | | dr.remark, |
| | |
| | | dr.update_time, |
| | | dr.create_user, |
| | | dr.update_user, |
| | | dr.tenant_id, |
| | | dl.device_name, |
| | | dl.device_model, |
| | | dr.machinery_category |
| | | dr.tenant_id, |
| | | dl.device_name, |
| | | dl.device_model, |
| | | dr.machinery_category, |
| | | da.area_name |
| | | from device_repair dr |
| | | left join device_ledger dl on dr.device_ledger_id = dl.id |
| | | left join device_area da on dl.area_id = da.id |
| | | <where> |
| | | <if test="deviceRepairDto.deviceName != null"> |
| | | and dl.device_name like concat('%',#{deviceRepairDto.deviceName},'%') |
| | |
| | | <if test="deviceRepairDto.maintenanceTimeStr != null and deviceRepairDto.maintenanceTimeStr != '' "> |
| | | and dr.maintenance_time like concat('%',#{deviceRepairDto.maintenanceTimeStr},'%') |
| | | </if> |
| | | <if test="deviceRepairDto.areaId != null"> |
| | | and dr.area_id = #{deviceRepairDto.areaId} |
| | | </if> |
| | | </where> |
| | | order by dr.create_time desc |
| | | </select> |
| | | <select id="detailById" resultType="com.ruoyi.device.vo.DeviceRepairVo"> |
| | | select dr.id, |
| | | dr.device_ledger_id, |
| | | dr.area_id, |
| | | dr.repair_time, |
| | | dr.repair_name, |
| | | dr.remark, |
| | |
| | | dr.tenant_id, |
| | | dl.device_name, |
| | | dr.machinery_category, |
| | | dl.device_model |
| | | dl.device_model, |
| | | da.area_name |
| | | from device_repair dr |
| | | left join device_ledger dl on dr.device_ledger_id = dl.id |
| | | left join device_area da on dl.area_id = da.id |
| | | where dr.id = #{id} |
| | | </select> |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
| | | "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.ruoyi.inspectiontask.mapper.InspectionTaskMapper"> |
| | | |
| | | <select id="selectInspectionTaskAggregatePage" resultType="com.ruoyi.inspectiontask.pojo.InspectionTask"> |
| | | SELECT |
| | | MIN(id) AS id, |
| | | GROUP_CONCAT(DISTINCT task_name ORDER BY create_time SEPARATOR ',') AS task_name, |
| | | MAX(inspection_project) AS inspection_project, |
| | | MAX(task_id) AS task_id, |
| | | CASE |
| | | WHEN SUM(CASE WHEN inspection_status = 1 THEN 1 ELSE 0 END) > 0 THEN 1 |
| | | WHEN SUM(CASE WHEN inspection_status = 2 THEN 1 ELSE 0 END) > 0 THEN 2 |
| | | ELSE MAX(inspection_status) |
| | | END AS inspection_status, |
| | | MAX(inspector_id) AS inspector_id, |
| | | MAX(inspector) AS inspector, |
| | | MAX(remarks) AS remarks, |
| | | MAX(inspection_result) AS inspection_result, |
| | | MAX(abnormal_description) AS abnormal_description, |
| | | MAX(device_repair_id) AS device_repair_id, |
| | | MAX(acceptance_user_id) AS acceptance_user_id, |
| | | MAX(acceptance_name) AS acceptance_name, |
| | | MAX(registrant_id) AS registrant_id, |
| | | MAX(registrant) AS registrant, |
| | | MAX(frequency_type) AS frequency_type, |
| | | MAX(frequency_detail) AS frequency_detail, |
| | | MAX(inspection_location) AS inspection_location, |
| | | MAX(deleted) AS deleted, |
| | | MAX(create_user) AS create_user, |
| | | MAX(create_time) AS create_time, |
| | | MAX(update_user) AS update_user, |
| | | MAX(update_time) AS update_time, |
| | | MAX(tenant_id) AS tenant_id, |
| | | MAX(dept_id) AS dept_id, |
| | | MAX(area_id) AS area_id, |
| | | MAX(timing_id) AS timing_id |
| | | FROM inspection_task |
| | | <where> |
| | | deleted = 0 |
| | | <if test="dto != null and dto.taskName != null and dto.taskName != ''"> |
| | | AND task_name LIKE CONCAT('%', #{dto.taskName}, '%') |
| | | </if> |
| | | <if test="dto != null and dto.inspectionProject != null and dto.inspectionProject != ''"> |
| | | AND inspection_project LIKE CONCAT('%', #{dto.inspectionProject}, '%') |
| | | </if> |
| | | <if test="dto != null and dto.areaId != null"> |
| | | AND area_id = #{dto.areaId} |
| | | </if> |
| | | <if test="dto != null and dto.timingId != null"> |
| | | AND timing_id = #{dto.timingId} |
| | | </if> |
| | | <if test="dto != null and dto.createTimeStart != null"> |
| | | AND create_time <![CDATA[>=]]> #{dto.createTimeStart} |
| | | </if> |
| | | <if test="dto != null and dto.createTimeEnd != null"> |
| | | AND create_time <![CDATA[<]]> #{dto.createTimeEnd} |
| | | </if> |
| | | </where> |
| | | GROUP BY IFNULL(timing_id, id) |
| | | ORDER BY create_time DESC |
| | | </select> |
| | | </mapper> |