diff --git a/zc-business/src/main/java/com/zc/business/controller/DcEmergencyPlansController.java b/zc-business/src/main/java/com/zc/business/controller/DcEmergencyPlansController.java index f260969a..9f5b213f 100644 --- a/zc-business/src/main/java/com/zc/business/controller/DcEmergencyPlansController.java +++ b/zc-business/src/main/java/com/zc/business/controller/DcEmergencyPlansController.java @@ -63,13 +63,14 @@ public class DcEmergencyPlansController extends BaseController { public AjaxResult listByEventType(@RequestBody DcEvent dcEvent) { List dcEmergencyPlansList = dcEmergencyPlansService.selectDcEmergencyPlansByEventType(dcEvent); + dcEmergencyPlansService.dispositionDeviceContent(dcEmergencyPlansList,dcEvent); return AjaxResult.success(dcEmergencyPlansList); } /** * 感知事件-根据事件数据查询事件预案列表 */ - @ApiOperation("感知事件-根据事件数据查询事件预案列表") +// @ApiOperation("感知事件-根据事件数据查询事件预案列表") @PreAuthorize("@ss.hasPermi('business:plans:list')") @PostMapping("/list/warning/type") public AjaxResult listByEventType(@RequestBody DcWarning dcWarning) { @@ -91,7 +92,7 @@ public class DcEmergencyPlansController extends BaseController { /** * 感知事件-情报板确认回显原始模板 */ - @ApiOperation("感知事件-情报板确认回显原始模板") +// @ApiOperation("感知事件-情报板确认回显原始模板") @PreAuthorize("@ss.hasPermi('business:plans:list')") @PostMapping("/warning/board/confirm") public AjaxResult warningBoardConfirm(@RequestBody DcEventAnDcEmergencyPlans dcEventAnDcEmergencyPlans) { @@ -101,7 +102,7 @@ public class DcEmergencyPlansController extends BaseController { /** * 感知事件-情报板自动生成文字 */ - @ApiOperation("感知事件-情报板自动生成文字") +// @ApiOperation("感知事件-情报板自动生成文字") @PostMapping("/warning/automatic") public AjaxResult warningAutomaticGeneration(@RequestBody DcEventAnDcEmergencyPlans dcEventAnDcEmergencyPlans) { return AjaxResult.success(dcEmergencyPlansService.warningAutomaticGeneration(dcEventAnDcEmergencyPlans)); @@ -110,7 +111,7 @@ public class DcEmergencyPlansController extends BaseController { /** * 交通事件-情报板自动生成文字 */ - @ApiOperation("交通事件-情报板自动生成文字") +// @ApiOperation("交通事件-情报板自动生成文字") @PostMapping("/event/automatic") public AjaxResult eventAutomaticGeneration(@RequestBody DcEventAnDcEmergencyPlans dcEventAnDcEmergencyPlans) { return AjaxResult.success(dcEmergencyPlansService.eventAutomaticGeneration(dcEventAnDcEmergencyPlans)); @@ -138,7 +139,7 @@ public class DcEmergencyPlansController extends BaseController { /** * 感知事件确定 */ - @ApiOperation("感知事件确认") +// @ApiOperation("感知事件确认") @PreAuthorize("@ss.hasPermi('business:plans:edit')") @PostMapping("/warning/confirm") public AjaxResult warningConfirm(@RequestBody DcEventAnDcEmergencyPlans dcEventAnDcEmergencyPlans) { @@ -149,7 +150,7 @@ public class DcEmergencyPlansController extends BaseController { * 新增事件预案 */ @ApiOperation("新增预案") -// @PreAuthorize("@ss.hasPermi('business:plans:add')") + @PreAuthorize("@ss.hasPermi('business:plans:add')") @PostMapping public AjaxResult add(@RequestBody DcEmergencyPlans dcEmergencyPlans) { return toAjax(dcEmergencyPlansService.insertDcEmergencyPlans(dcEmergencyPlans)); @@ -159,7 +160,7 @@ public class DcEmergencyPlansController extends BaseController { * 修改事件预案 */ @ApiOperation("修改预案") -// @PreAuthorize("@ss.hasPermi('business:plans:edit')") + @PreAuthorize("@ss.hasPermi('business:plans:edit')") @PutMapping public AjaxResult update(@RequestBody DcEmergencyPlans dcEmergencyPlans) { return toAjax(dcEmergencyPlansService.updateDcEmergencyPlans(dcEmergencyPlans)); diff --git a/zc-business/src/main/java/com/zc/business/controller/DcEventController.java b/zc-business/src/main/java/com/zc/business/controller/DcEventController.java index 6d5d060b..7a2899a7 100644 --- a/zc-business/src/main/java/com/zc/business/controller/DcEventController.java +++ b/zc-business/src/main/java/com/zc/business/controller/DcEventController.java @@ -6,6 +6,7 @@ import javax.servlet.http.HttpServletResponse; import com.zc.business.domain.DcEvent; import com.zc.business.service.IDcEventService; +import com.zc.common.core.websocket.WebSocketService; import io.swagger.annotations.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; @@ -94,6 +95,7 @@ public class DcEventController extends BaseController @GetMapping(value = "/{id}") public AjaxResult getInfo(@PathVariable("id") String id) { + DcEvent dcEvent = dcEventService.selectDcEventById(id); return AjaxResult.success(dcEvent); } @@ -122,10 +124,8 @@ public class DcEventController extends BaseController //@PreAuthorize("@ss.hasPermi('system:event:add')") @Log(title = "事件信息", businessType = BusinessType.INSERT) @PostMapping - public AjaxResult add(@RequestBody DcEvent dcEvent) { - return toAjax(dcEventService.insertDcEvent(dcEvent)); } @@ -161,5 +161,57 @@ public class DcEventController extends BaseController return map; } + @ApiOperation("根据事件id修改事件状态") + // @PreAuthorize("@ss.hasPermi('system:event:edit')") + @Log(title = "事件信息", businessType = BusinessType.UPDATE) + @PutMapping("/dcEventState/{id}/{state}") + public AjaxResult dcEventState(@PathVariable("id") String id,@PathVariable("state") int state) + { + + return toAjax(dcEventService.updateDcEventState(id,state)); + } + + + /** + * @Description 查询事件流程状态 + * + * @author liuwenge + * @date 2024/4/11 11:19 + * @param eventId 事件id + * @return com.ruoyi.common.core.domain.AjaxResult + */ + @ApiOperation("查询事件流程状态") + @GetMapping( "/getProcessNode/{eventId}") + public AjaxResult getProcessNode(@ApiParam(name = "eventId", value = "事件id", required = true) @PathVariable("eventId") String eventId){ + return dcEventService.getProcessNode(eventId); + } + + /** + * @Description 解除事件 + * + * @author liuwenge + * @date 2024/4/11 14:12 + * @param eventId + * @return com.ruoyi.common.core.domain.AjaxResult + */ + @ApiOperation("解除事件") + @PostMapping("/completeEvent") + public AjaxResult completeEvent(String eventId){ + return dcEventService.completeEvent(eventId); + } + + /** + * @Description 解除事件 + * + * @author liuwenge + * @date 2024/4/11 14:12 + * @param eventId + * @return com.ruoyi.common.core.domain.AjaxResult + */ + @ApiOperation("无需清障") + @PostMapping("/skipClear") + public AjaxResult skipClear(String eventId){ + return dcEventService.skipClear(eventId); + } } diff --git a/zc-business/src/main/java/com/zc/business/controller/DcEventImportantController.java b/zc-business/src/main/java/com/zc/business/controller/DcEventImportantController.java new file mode 100644 index 00000000..f1fb84bc --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/controller/DcEventImportantController.java @@ -0,0 +1,98 @@ +package com.zc.business.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.enums.BusinessType; +import com.zc.business.domain.DcEventImportant; +import com.zc.business.service.IDcEventImportantService; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.common.core.page.TableDataInfo; + +/** + * 事件侧重要素Controller + * + * @author ruoyi + * @date 2024-04-11 + */ +@RestController +@RequestMapping("/business/eventImportant") +public class DcEventImportantController extends BaseController +{ + @Autowired + private IDcEventImportantService dcEventImportantService; + + /** + * 查询事件侧重要素列表 + */ + @GetMapping("/list") + public TableDataInfo list(DcEventImportant dcEventImportant) + { + startPage(); + List list = dcEventImportantService.selectDcEventImportantList(dcEventImportant); + return getDataTable(list); + } + + /** + * 导出事件侧重要素列表 + */ + @Log(title = "事件侧重要素", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, DcEventImportant dcEventImportant) + { + List list = dcEventImportantService.selectDcEventImportantList(dcEventImportant); + ExcelUtil util = new ExcelUtil<>(DcEventImportant.class); + util.exportExcel(response, list, "事件侧重要素数据"); + } + + /** + * 获取事件侧重要素详细信息 + */ + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") String id) + { + return AjaxResult.success(dcEventImportantService.selectDcEventImportantByEventId(id)); + } + + /** + * 新增事件侧重要素 + */ + @Log(title = "事件侧重要素", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody DcEventImportant dcEventImportant) + { + return toAjax(dcEventImportantService.insertDcEventImportant(dcEventImportant)); + } + + /** + * 修改事件侧重要素 + */ + @Log(title = "事件侧重要素", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody DcEventImportant dcEventImportant) + { + return toAjax(dcEventImportantService.updateDcEventImportant(dcEventImportant)); + } + + /** + * 删除事件侧重要素 + */ + @Log(title = "事件侧重要素", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable String[] ids) + { + return toAjax(dcEventImportantService.deleteDcEventImportantByEventIds(ids)); + } +} diff --git a/zc-business/src/main/java/com/zc/business/controller/DcEventImportantFileController.java b/zc-business/src/main/java/com/zc/business/controller/DcEventImportantFileController.java new file mode 100644 index 00000000..e72348a5 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/controller/DcEventImportantFileController.java @@ -0,0 +1,165 @@ +package com.zc.business.controller; + +import java.io.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.servlet.http.HttpServletResponse; + +import com.zc.business.utils.PoiUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.enums.BusinessType; +import com.zc.business.domain.DcEventImportantFile; +import com.zc.business.service.IDcEventImportantFileService; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.common.core.page.TableDataInfo; + +/** + * 重要事件文件内容Controller + * + * @author ruoyi + * @date 2024-04-12 + */ +@Api(tags = "重要事件文件内容") +@RestController +@RequestMapping("/business/eventImportantFile") +public class DcEventImportantFileController extends BaseController +{ + @Autowired + private IDcEventImportantFileService dcEventImportantFileService; + + /** + * 分页查询重要事件文件内容 + */ + @ApiOperation("分页查询重要事件文件内容") + @GetMapping("/page") + public TableDataInfo page(DcEventImportantFile dcEventImportantFile) + { + startPage(); + List list = dcEventImportantFileService.selectDcEventImportantFileList(dcEventImportantFile); + return getDataTable(list); + } + + /** + * 无分页查询重要事件文件内容列表 + */ + @ApiOperation("无分页查询重要事件文件内容列表") + @GetMapping("/list") + public List list(DcEventImportantFile dcEventImportantFile) + { + return dcEventImportantFileService.selectDcEventImportantFileList(dcEventImportantFile); + } + + /** + * 导出重要事件文件内容列表 + */ + @Log(title = "重要事件文件内容", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, DcEventImportantFile dcEventImportantFile) + { + List list = dcEventImportantFileService.selectDcEventImportantFileList(dcEventImportantFile); + ExcelUtil util = new ExcelUtil<>(DcEventImportantFile.class); + util.exportExcel(response, list, "重要事件文件内容数据"); + } + + /** + * 下载重要事件文件 + */ + @ApiOperation("下载重要事件文件") + @Log(title = "下载重要事件文件", businessType = BusinessType.EXPORT) + @PostMapping("/download") + public void download(HttpServletResponse response, DcEventImportantFile dcEventImportantFile) + { + InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("wordTemplate/importantTemplate.docx"); + + XWPFDocument document = null; + try { + + + //获取docx解析对象 + document = new XWPFDocument(inputStream); + Map textMap = new HashMap<>(); + textMap.put("${fromDept}",dcEventImportantFile.getFromDept()); + textMap.put("${createTime}",dcEventImportantFile.getCreateTime()); + textMap.put("${title}",dcEventImportantFile.getTitle()); + textMap.put("${toDept}",dcEventImportantFile.getToDept()); + textMap.put("${content}",dcEventImportantFile.getContent()); + textMap.put("${createName}",dcEventImportantFile.getCreateName()); + textMap.put("${phoneNumber}",dcEventImportantFile.getPhoneNumber()); + textMap.put("${issued}",dcEventImportantFile.getIssued()); + + //解析替换文本段落对象 + PoiUtil.changeText(document, textMap); + + document.write(response.getOutputStream()); + } catch (IOException e) { + e.printStackTrace(); + }finally { + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + } + + /** + * 获取重要事件文件内容详细信息 + */ + @ApiOperation("获取重要事件文件内容详细信息") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") String id) + { + return AjaxResult.success(dcEventImportantFileService.selectDcEventImportantFileByEventId(id)); + } + + /** + * 新增重要事件文件内容 + */ + @ApiOperation("新增重要事件文件内容") + @Log(title = "重要事件文件内容", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody DcEventImportantFile dcEventImportantFile) + { + return toAjax(dcEventImportantFileService.insertDcEventImportantFile(dcEventImportantFile)); + } + + /** + * 修改重要事件文件内容 + */ + @ApiOperation("修改重要事件文件内容") + @Log(title = "重要事件文件内容", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody DcEventImportantFile dcEventImportantFile) + { + return toAjax(dcEventImportantFileService.updateDcEventImportantFile(dcEventImportantFile)); + } + + /** + * 删除重要事件文件内容 + */ + @ApiOperation("删除重要事件文件内容") + @Log(title = "重要事件文件内容", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable String[] ids) + { + return toAjax(dcEventImportantFileService.deleteDcEventImportantFileByEventIds(ids)); + } +} diff --git a/zc-business/src/main/java/com/zc/business/controller/DcEventProcessController.java b/zc-business/src/main/java/com/zc/business/controller/DcEventProcessController.java index 275ee8ce..79e0fcf7 100644 --- a/zc-business/src/main/java/com/zc/business/controller/DcEventProcessController.java +++ b/zc-business/src/main/java/com/zc/business/controller/DcEventProcessController.java @@ -47,9 +47,18 @@ public class DcEventProcessController extends BaseController * 查询事件处理流程列表 */ @ApiOperation("查询事件处理流程列表") - // @PreAuthorize("@ss.hasPermi('system:process:list')") @GetMapping("/list") - public TableDataInfo list(DcEventProcess dcEventProcess) + public List list(DcEventProcess dcEventProcess) + { + return dcEventProcessService.selectDcEventProcessList(dcEventProcess); + } + + /** + * 分页查询事件处理流程列表 + */ + @ApiOperation("分页查询事件处理流程列表") + @GetMapping("/page") + public TableDataInfo page(DcEventProcess dcEventProcess) { startPage(); List list = dcEventProcessService.selectDcEventProcessList(dcEventProcess); @@ -90,12 +99,7 @@ public class DcEventProcessController extends BaseController // @PreAuthorize("@ss.hasPermi('system:process:add')") @Log(title = "事件处理流程", businessType = BusinessType.INSERT) @PostMapping - public AjaxResult add(@RequestBody DcEventProcess dcEventProcess) throws IOException, InvalidExtensionException { - //如果有文件传入 - if(!dcEventProcess.getFile().isEmpty()){ - String address =FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), dcEventProcess.getFile(), MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); - dcEventProcess.setContext(address); - } + public AjaxResult add(@RequestBody DcEventProcess dcEventProcess){ return toAjax(dcEventProcessService.insertDcEventProcess(dcEventProcess)); } diff --git a/zc-business/src/main/java/com/zc/business/domain/DcEvent.java b/zc-business/src/main/java/com/zc/business/domain/DcEvent.java index 172107f8..aa171517 100644 --- a/zc-business/src/main/java/com/zc/business/domain/DcEvent.java +++ b/zc-business/src/main/java/com/zc/business/domain/DcEvent.java @@ -229,6 +229,10 @@ public class DcEvent { private List processConfigList; @ApiModelProperty("事件标题") private String eventTitle; +@ApiModelProperty("维度") + private String dimension; +@ApiModelProperty("经度") + private String longitude; /** * 2014/2/21新增 */ @@ -298,6 +302,6 @@ public class DcEvent { private String remark; private String subclass; - - +@ApiModelProperty("关联管制事件id") +private String linkId; } diff --git a/zc-business/src/main/java/com/zc/business/domain/DcEventImportant.java b/zc-business/src/main/java/com/zc/business/domain/DcEventImportant.java new file mode 100644 index 00000000..39a73626 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/domain/DcEventImportant.java @@ -0,0 +1,183 @@ +package com.zc.business.domain; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.List; +import java.util.Map; + +/** + * @Description 事件侧重要素 + * + * @author liuwenge + * @date 2024/4/11 18:28 + */ +@ApiModel("事件侧重要素") +public class DcEventImportant +{ + + @ApiModelProperty(value = "事件id") + private String id; + + @ApiModelProperty(value = "事件id") + private String eventId; + + @ApiModelProperty(value = "车型及车牌号") + private String plateNumber; + + @ApiModelProperty(value = "分流点名称及桩号") + private String diversionPoint; + + @ApiModelProperty(value = "目前进度") + private String currentProgress; + + @ApiModelProperty(value = "已采取措施") + private String takeSteps; + + @ApiModelProperty(value = "是否启动预案") + private Integer planStatus; + + @ApiModelProperty(value = "交警是否到达") + private Integer trafficPoliceStatus; + + @ApiModelProperty(value = "医疗是否到达") + private Integer medicalStatus; + + @ApiModelProperty(value = "消防是否到达") + private Integer fireStatus; + + @ApiModelProperty(value = "是否做好情报板提示工作") + private Integer boardStatus; + + @ApiModelProperty(value = "是否有危化品泄漏") + private Integer chemicalsStatus; + + @ApiModelProperty(value = "预案等级") + private String planLevel; + + @ApiModelProperty(value = "危化品名称") + private String chemicalsName; + + @ApiModelProperty(value = "危化品泄露程度") + private String leakageLevel; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getEventId() { + return eventId; + } + + public void setEventId(String eventId) { + this.eventId = eventId; + } + + public String getPlateNumber() { + return plateNumber; + } + + public void setPlateNumber(String plateNumber) { + this.plateNumber = plateNumber; + } + + public String getDiversionPoint() { + return diversionPoint; + } + + public void setDiversionPoint(String diversionPoint) { + this.diversionPoint = diversionPoint; + } + + public String getCurrentProgress() { + return currentProgress; + } + + public void setCurrentProgress(String currentProgress) { + this.currentProgress = currentProgress; + } + + public String getTakeSteps() { + return takeSteps; + } + + public void setTakeSteps(String takeSteps) { + this.takeSteps = takeSteps; + } + + public Integer getPlanStatus() { + return planStatus; + } + + public void setPlanStatus(Integer planStatus) { + this.planStatus = planStatus; + } + + public Integer getTrafficPoliceStatus() { + return trafficPoliceStatus; + } + + public void setTrafficPoliceStatus(Integer trafficPoliceStatus) { + this.trafficPoliceStatus = trafficPoliceStatus; + } + + public Integer getMedicalStatus() { + return medicalStatus; + } + + public void setMedicalStatus(Integer medicalStatus) { + this.medicalStatus = medicalStatus; + } + + public Integer getFireStatus() { + return fireStatus; + } + + public void setFireStatus(Integer fireStatus) { + this.fireStatus = fireStatus; + } + + public Integer getBoardStatus() { + return boardStatus; + } + + public void setBoardStatus(Integer boardStatus) { + this.boardStatus = boardStatus; + } + + public Integer getChemicalsStatus() { + return chemicalsStatus; + } + + public void setChemicalsStatus(Integer chemicalsStatus) { + this.chemicalsStatus = chemicalsStatus; + } + + public String getPlanLevel() { + return planLevel; + } + + public void setPlanLevel(String planLevel) { + this.planLevel = planLevel; + } + + public String getChemicalsName() { + return chemicalsName; + } + + public void setChemicalsName(String chemicalsName) { + this.chemicalsName = chemicalsName; + } + + public String getLeakageLevel() { + return leakageLevel; + } + + public void setLeakageLevel(String leakageLevel) { + this.leakageLevel = leakageLevel; + } +} diff --git a/zc-business/src/main/java/com/zc/business/domain/DcEventImportantFile.java b/zc-business/src/main/java/com/zc/business/domain/DcEventImportantFile.java new file mode 100644 index 00000000..400dbb98 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/domain/DcEventImportantFile.java @@ -0,0 +1,173 @@ +package com.zc.business.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.core.domain.BaseEntity; + +/** + * 重要事件文件内容对象 dc_event_important_file + * + * @author ruoyi + * @date 2024-04-12 + */ +public class DcEventImportantFile +{ + private static final long serialVersionUID = 1L; + + private Long id; + + /** 事件id */ + private String eventId; + + /** 报送单位 */ + @Excel(name = "报送单位") + private String fromDept; + + /** 报送时间 */ + @Excel(name = "报送时间") + private String createTime; + + /** 标题 */ + @Excel(name = "标题") + private String title; + + /** 发至单位 */ + @Excel(name = "发至单位") + private String toDept; + + /** 内容 */ + @Excel(name = "内容") + private String content; + + /** 填报人 */ + @Excel(name = "填报人") + private String createName; + + /** 联系电话 */ + @Excel(name = "联系电话") + private String phoneNumber; + + /** 签发人 */ + @Excel(name = "签发人") + private String issued; + + /** 类型 1:初报,2续报,3终报 */ + @Excel(name = "类型 1:初报,2续报,3终报") + private String type; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public void setEventId(String eventId) + { + this.eventId = eventId; + } + + public String getEventId() + { + return eventId; + } + public void setFromDept(String fromDept) + { + this.fromDept = fromDept; + } + + public String getFromDept() + { + return fromDept; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public void setTitle(String title) + { + this.title = title; + } + + public String getTitle() + { + return title; + } + public void setToDept(String toDept) + { + this.toDept = toDept; + } + + public String getToDept() + { + return toDept; + } + public void setContent(String content) + { + this.content = content; + } + + public String getContent() + { + return content; + } + public void setCreateName(String createName) + { + this.createName = createName; + } + + public String getCreateName() + { + return createName; + } + public void setPhoneNumber(String phoneNumber) + { + this.phoneNumber = phoneNumber; + } + + public String getPhoneNumber() + { + return phoneNumber; + } + public void setIssued(String issued) + { + this.issued = issued; + } + + public String getIssued() + { + return issued; + } + public void setType(String type) + { + this.type = type; + } + + public String getType() + { + return type; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("eventId", getEventId()) + .append("fromDept", getFromDept()) + .append("createTime", getCreateTime()) + .append("title", getTitle()) + .append("toDept", getToDept()) + .append("content", getContent()) + .append("createName", getCreateName()) + .append("phoneNumber", getPhoneNumber()) + .append("issued", getIssued()) + .append("type", getType()) + .toString(); + } +} diff --git a/zc-business/src/main/java/com/zc/business/domain/DcEventProcess.java b/zc-business/src/main/java/com/zc/business/domain/DcEventProcess.java index 4295717d..be0ab666 100644 --- a/zc-business/src/main/java/com/zc/business/domain/DcEventProcess.java +++ b/zc-business/src/main/java/com/zc/business/domain/DcEventProcess.java @@ -47,17 +47,14 @@ public class DcEventProcess private Integer source; /** 1-节点 - 2-信息发布 + 2-信息发布 + 3-设备管控 + 4-文件生成 */ - @ApiModelProperty(value="流程类型") - @Excel(name = "1-节点 2-信息发布 ") + @ApiModelProperty(value="流程类型 1-节点,2-信息发布,3-设备管控,4-文件生成") + @Excel(name = "流程类型") private Integer processType; - /** $column.columnComment */ - @ApiModelProperty("内容") - @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") - private String context; - /** $column.columnComment */ @ApiModelProperty("流程ID") @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") @@ -68,6 +65,20 @@ public class DcEventProcess @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") private String processName; + /** $column.columnComment */ + @ApiModelProperty("内容") + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String context; + + /** $column.type */ + @ApiModelProperty("内容类型") + @Excel(name = "${type}", readConverterExp = "$column.readConverterExp()") + private String type; + + @ApiModelProperty("上传文件") + private MultipartFile file; + + public MultipartFile getFile() { return file; } @@ -76,9 +87,6 @@ public class DcEventProcess this.file = file; } - @ApiModelProperty("上传文件") - private MultipartFile file; - public void setId(Long id) { this.id = id; @@ -161,6 +169,14 @@ public class DcEventProcess return processName; } + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) @@ -173,6 +189,7 @@ public class DcEventProcess .append("context", getContext()) .append("processId", getProcessId()) .append("processName", getProcessName()) + .append("type", getType()) .toString(); } } diff --git a/zc-business/src/main/java/com/zc/business/domain/DcEventTrafficControl.java b/zc-business/src/main/java/com/zc/business/domain/DcEventTrafficControl.java index 2b0cffc5..32c2b6fa 100644 --- a/zc-business/src/main/java/com/zc/business/domain/DcEventTrafficControl.java +++ b/zc-business/src/main/java/com/zc/business/domain/DcEventTrafficControl.java @@ -97,4 +97,6 @@ public class DcEventTrafficControl extends BaseEntity @TableField(exist = false) private DcFacility dcFacility; + @TableField(exist = false) + private Long[] facilityIds; // 数组存储多个设备ID } diff --git a/zc-business/src/main/java/com/zc/business/domain/EventPlanAssoc.java b/zc-business/src/main/java/com/zc/business/domain/EventPlanAssoc.java index 162d32e4..d41b8c5d 100644 --- a/zc-business/src/main/java/com/zc/business/domain/EventPlanAssoc.java +++ b/zc-business/src/main/java/com/zc/business/domain/EventPlanAssoc.java @@ -36,16 +36,17 @@ public class EventPlanAssoc { private Integer emergencyPlansId; /** - * 执行控制设备 (设备id用逗号隔开) + * 控制类型 1执行此操作 2恢复操作 */ - @ApiModelProperty("执行控制设备") - private String executingControlDevice; + @ApiModelProperty("控制类型") + private Integer operationType; /** - * 恢复控制设备 (设备id用逗号隔开) + * 控制设备 (设备id用逗号隔开) */ - @ApiModelProperty("恢复控制设备") - private String recoveredControlDevice; + @ApiModelProperty("控制设备") + private String controlDevice; + @ApiModelProperty("创建时间") private Date createTime; @@ -56,11 +57,5 @@ public class EventPlanAssoc { * 执行操作结果 */ @ApiModelProperty("执行操作结果") - private String executingControlResult; - - /** - * 恢复操作结果 - */ - @ApiModelProperty("恢复操作结果") - private String recoveredControlResult; + private String controlResult; } diff --git a/zc-business/src/main/java/com/zc/business/enums/EventSubclassEnum.java b/zc-business/src/main/java/com/zc/business/enums/EventSubclassEnum.java index 061e773d..68e8059b 100644 --- a/zc-business/src/main/java/com/zc/business/enums/EventSubclassEnum.java +++ b/zc-business/src/main/java/com/zc/business/enums/EventSubclassEnum.java @@ -5,28 +5,34 @@ package com.zc.business.enums; * @author wangjiabao */ public enum EventSubclassEnum { - REAR_END_COLLISION("1-1", "追尾","前方发生追尾 注意避让"), - ROLLOVER("1-2", "侧翻","前方发生侧翻 注意避让"), - COLLISION_WITH_GUARDRAIL("1-3", "撞护栏","前方车撞击护栏注意避让"), - NATURAL("1-4", "自然","前方发生自然现象请注意"), - OTHER_ACCIDENTS("1-5", "其他事故","前方发生事故谨慎驾驶"), - VEHICLE_MALFUNCTION("2-1", "车辆故障","前方发生故障注意避让"), - ROAD_CONGESTION("4-1", "道路拥堵","前方道路拥堵"), - OVERPASS_CONGESTION("4-2", "立交拥堵","前方立交拥堵"), - TOLL_STATION_CONGESTION("4-3", "收费站拥堵","前方收费站拥堵"), - SERVICE_AREA_CONGESTION("4-4", "服务区拥堵","前方服务区拥堵"), - PEDESTRIAN("5-1", "行人","有行人穿行请注意"), - NON_MOTOR_VEHICLES("5-2", "非机动车","有非机动车上路请注意"), - MOTORCYCLE("5-3", "摩托车","有摩托车上路请注意"), - OTHER("5-4", "其他","有非法上路车辆"), - SMOKE("6-1", "烟雾","烟雾道路请注意驾驶"), - FALLEN_TREES("6-2", "倒伏树木","有倒伏树木请注意"), - SCATTERED_MATERIALS("6-3", "洒落物","有洒落物请注意"), - ANIMAL("6-4", "动物","有动物请注意"), - OTHER_OBSTACLES("6-5", "其他障碍","有不明障碍请注意"), - CLOSED_OR_SUSPENDED_OPERATIONS("8-1", "封闭、暂停营业","服务区封闭、暂停营业"), - SHUTDOWN_OF_IMPORTANT_FACILITIES("8-2", "重要设施停用","服务区重要设施停用"), - OTHER_ABNORMALITIES_IN_THE_SERVICE_AREA("8-3", "服务区其他异常","服务区设备停用"), + REAR_END_COLLISION("1-1", "追尾","前方*发生追尾 注意避让"), + ROLLOVER("1-2", "侧翻","前方*发生侧翻 注意避让"), + COLLISION_WITH_GUARDRAIL("1-3", "撞护栏","前方*车撞击护栏注意避让"), + NATURAL("1-4", "自然","前方*发生自然现象请注意"), + OTHER_ACCIDENTS("1-5", "其他事故","前方*发生事故谨慎驾驶"), + VEHICLE_MALFUNCTION("2-1", "车辆故障","前方*发生故障注意避让"), + THE_MAIN_LINE_IS_CLOSED_AND_RESTRICTED("3-1", "主线封闭和限行","前方*主线封闭和限行"), + TOLL_BOOTHS_ARE_CLOSED_AND_RESTRICTED("3-2", "收费站封闭和限行","前方*收费站封闭和限行"), + THE_INTERCHANGE_IS_CLOSED_AND_RESTRICTED("3-3", "立交封闭和限行","前方*立交封闭和限行"), + THE_SERVICE_AREA_IS_CLOSED_AND_RESTRICTED("3-4", "服务区封闭和限行","前方*服务区封闭和限行"), + + + ROAD_CONGESTION("4-1", "道路拥堵","前方*道路拥堵"), + OVERPASS_CONGESTION("4-2", "立交拥堵","前方*立交拥堵"), + TOLL_STATION_CONGESTION("4-3", "收费站拥堵","前方*收费站拥堵"), + SERVICE_AREA_CONGESTION("4-4", "服务区拥堵","前方*服务区拥堵"), + PEDESTRIAN("5-1", "行人","前方*有行人穿行请注意"), + NON_MOTOR_VEHICLES("5-2", "非机动车","前方*有非机动车上路请注意"), + MOTORCYCLE("5-3", "摩托车","前方*有摩托车上路请注意"), + OTHER("5-4", "其他","前方*有非法上路车辆"), + SMOKE("6-1", "烟雾","前方*烟雾道路请注意驾驶"), + FALLEN_TREES("6-2", "倒伏树木","前方*有倒伏树木请注意"), + SCATTERED_MATERIALS("6-3", "洒落物","前方*有洒落物请注意"), + ANIMAL("6-4", "动物","前方*有动物请注意"), + OTHER_OBSTACLES("6-5", "其他障碍","前方*有不明障碍请注意"), + CLOSED_OR_SUSPENDED_OPERATIONS("8-1", "封闭、暂停营业","前方*服务区封闭、暂停营业"), + SHUTDOWN_OF_IMPORTANT_FACILITIES("8-2", "重要设施停用","前方*服务区重要设施停用"), + OTHER_ABNORMALITIES_IN_THE_SERVICE_AREA("8-3", "服务区其他异常","前方*服务区设备停用"), RAIN("10-1", "雨","雨天请谨慎驾驶"), SNOW("10-2", "雪","雪天路滑请谨慎驾驶"), HEAVY_FOG("10-3", "大雾","大雾天气请谨慎驾驶"), diff --git a/zc-business/src/main/java/com/zc/business/enums/ValueConverter.java b/zc-business/src/main/java/com/zc/business/enums/ValueConverter.java index 8409dd4e..5af2c2d5 100644 --- a/zc-business/src/main/java/com/zc/business/enums/ValueConverter.java +++ b/zc-business/src/main/java/com/zc/business/enums/ValueConverter.java @@ -22,6 +22,13 @@ public class ValueConverter { private static final Map valueMappingSon = new HashMap<>(); // 静态映射,用于存储转换关系 事件源转换 private static final Map valueMappingSource = new HashMap<>(); + // 事件来源名称 + private static final Map eventSourceName = new HashMap<>(); + // 事件类型名称 + private static final Map eventTypeName = new HashMap<>(); + // 事件字段 + private static final Map eventLabel = new HashMap<>(); + static { valueMappingSource.put(1,5); valueMappingSource.put(4,7); @@ -87,6 +94,135 @@ public class ValueConverter { valueMappingSon.put("11-2", "2-1"); valueMappingSon.put("11-3", "2-1"); valueMappingSon.put("99-1", "11-1"); + + eventSourceName.put("1","96659"); + eventSourceName.put("2","交警转接"); + eventSourceName.put("3","道路巡查"); + eventSourceName.put("4","视频巡查"); + eventSourceName.put("5","视频AI"); + eventSourceName.put("6","一键救援"); + eventSourceName.put("7","其他"); + + eventTypeName.put("1","交通事故"); + eventTypeName.put("2","车辆故障"); + eventTypeName.put("3","交通管制"); + eventTypeName.put("4","交通拥堵"); + eventTypeName.put("5","非法上路"); + eventTypeName.put("6","路障清除"); + eventTypeName.put("7","施工建设"); + eventTypeName.put("8","服务区异常"); + eventTypeName.put("9","设施设备隐患"); + eventTypeName.put("10","异常天气"); + eventTypeName.put("11","其他事件"); + + eventLabel.put("id","事件编号"); + eventLabel.put("deptId","所属部门"); + eventLabel.put("stakeMark","桩号"); + eventLabel.put("direction","方向"); + eventLabel.put("userId","处理人员"); + eventLabel.put("startTime","开始时间"); + eventLabel.put("endTime","结束时间"); + eventLabel.put("estimatedEndTime","预计解除时间"); + eventLabel.put("eventLevel","事件等级"); +// eventLabel.put("eventType","事件类型"); + eventLabel.put("eventCause","事件原因"); + eventLabel.put("description","描述"); + eventLabel.put("eventState","状态"); + eventLabel.put("eventSource","来源"); +// eventLabel.put("eventNature","事件性质"); + eventLabel.put("eventSourceTips","来源补充说明"); + eventLabel.put("occurrenceTime","发生时间"); +// eventLabel.put("isPerceived","是否感知事件"); + eventLabel.put("lang","影响车道"); + eventLabel.put("roadName","高速名称"); + eventLabel.put("eventTitle","时间标题"); + eventLabel.put("remark","备注"); + eventLabel.put("dcEventAbnormalWeather.weatherSituation","天气情况"); + eventLabel.put("dcEventAbnormalWeather.emergencyLevel","紧急级别"); + eventLabel.put("dcEventAbnormalWeather.endStakeMark","终止桩号"); + eventLabel.put("dcEventAbnormalWeather.numericalValue","异常天气数值"); + eventLabel.put("dcEventAccident.reporterName","报警人姓名"); + eventLabel.put("dcEventAccident.reporterPhoneNumber","报警人电话"); + eventLabel.put("dcEventAccident.locationType","地点"); + eventLabel.put("dcEventAccident.trafficJam","压车(公里)"); + eventLabel.put("dcEventAccident.weatherCondition","天气情况"); + eventLabel.put("dcEventAccident.impactLevel","影响"); + eventLabel.put("dcEventAccident.isReverseCargo","是否倒货"); + eventLabel.put("dcEventAccident.isMaintenance","是否养护事故"); + eventLabel.put("dcEventAccident.policeContact","交警电话"); + eventLabel.put("dcEventAccident.towingServiceContact","清障电话"); + eventLabel.put("dcEventAccident.congestionAhead","前方是否拥堵"); + eventLabel.put("dcEventAccident.atIntersection","是否分岔口"); + eventLabel.put("dcEventAccident.onCurve","是否处在弯道"); + eventLabel.put("dcEventAccident.spillageItem","洒落物名称"); + eventLabel.put("dcEventAccident.vehicleOwnerPhone","车主电话"); + eventLabel.put("dcEventAccident.smallCar","小型车(辆)"); + eventLabel.put("dcEventAccident.trucks","货车(辆)"); + eventLabel.put("dcEventAccident.buses","客车(辆)"); + eventLabel.put("dcEventAccident.tankers","罐车(辆)"); + eventLabel.put("dcEventAccident.minorInjuries","轻伤(人)"); + eventLabel.put("dcEventAccident.seriousInjuries","重伤(人)"); + eventLabel.put("dcEventAccident.fatalities","死亡(人)"); + eventLabel.put("dcEventAccident.isPrivate","私密事件"); + eventLabel.put("dcEventAccident.facilityId","设施关联"); + eventLabel.put("dcEventAccident.rampId","匝道id"); + eventLabel.put("dcEventAccident.location","地点"); + eventLabel.put("dcEventConstruction.controlMode","管制方式"); + eventLabel.put("dcEventConstruction.locationType","地点类型"); + eventLabel.put("dcEventConstruction.specialPlaceDescription","特殊地点描述"); + eventLabel.put("dcEventConstruction.specialConstruction","专项施工"); + eventLabel.put("dcEventConstruction.otherConstructionName","其他施工名称"); + eventLabel.put("dcEventConstruction.constructionMeasurement","施工措施"); + eventLabel.put("dcEventConstruction.facilityId","设施id"); + eventLabel.put("dcEventConstruction.exitsInlets","出入口"); + eventLabel.put("dcEventConstruction.laneOccupancy","占用车道"); + eventLabel.put("dcEventConstruction.trafficCondition","通行情况"); + eventLabel.put("dcEventConstruction.constructionMethod","施工方式"); + eventLabel.put("dcEventConstruction.localRoadName","地方道路名称"); + eventLabel.put("dcEventConstruction.endStakeMark","结束桩号"); + eventLabel.put("dcEventConstruction.location","地点"); + eventLabel.put("dcEventServiceArea.exitsInlets","出入口"); + eventLabel.put("dcEventServiceArea.facilityId","服务区"); + eventLabel.put("dcEventServiceArea.disableFacility","停用设施"); + eventLabel.put("dcEventTrafficCongestion.congestionMileage","拥堵里程(公里)"); + eventLabel.put("dcEventTrafficCongestion.maxCongestionMileage","最大拥堵里程(公里)"); + eventLabel.put("dcEventTrafficCongestion.congestionCause","拥堵原因"); + eventLabel.put("dcEventTrafficCongestion.facilityId","设施id"); + eventLabel.put("dcEventTrafficCongestion.rampId","匝道"); + eventLabel.put("dcEventTrafficCongestion.location","地点"); + eventLabel.put("dcEventTrafficCongestion.detailedReasons","详细原因"); + eventLabel.put("dcEventTrafficCongestion.locationType","地点类型"); + eventLabel.put("dcEventTrafficCongestion.locationDescription","地点描述"); + eventLabel.put("dcEventTrafficCongestion.endStakeMark","终止桩号"); + eventLabel.put("dcEventVehicleAccident.reporterName","报警人姓名"); + eventLabel.put("dcEventVehicleAccident.reporterPhoneNumber","报警人电话"); + eventLabel.put("dcEventVehicleAccident.locationType","地点方式"); + eventLabel.put("dcEventVehicleAccident.trafficJam","压车(公里)"); + eventLabel.put("dcEventVehicleAccident.weatherCondition","天气情况"); + eventLabel.put("dcEventVehicleAccident.congestionAhead","前方是否拥堵"); + eventLabel.put("dcEventVehicleAccident.atIntersection","是否分岔口"); + eventLabel.put("dcEventVehicleAccident.onCurve","是否处在弯道"); + eventLabel.put("dcEventVehicleAccident.smallCar","小型车(辆)"); + eventLabel.put("dcEventVehicleAccident.trucks","货车(辆)"); + eventLabel.put("dcEventVehicleAccident.buses","客车(辆)"); + eventLabel.put("dcEventVehicleAccident.tankers","罐车(辆)"); + eventLabel.put("dcEventVehicleAccident.minorInjuries","轻伤(人)"); + eventLabel.put("dcEventVehicleAccident.seriousInjuries","重伤(人)"); + eventLabel.put("dcEventVehicleAccident.fatalities","死亡(人)"); + eventLabel.put("dcEventVehicleAccident.isPrivate","私密事件"); + eventLabel.put("dcEventVehicleAccident.facilityId","设施id"); + eventLabel.put("dcEventVehicleAccident.rampId","匝道"); + eventLabel.put("dcEventVehicleAccident.location","地点"); + eventLabel.put("dcEventTrafficControl.controlType","管制分类"); + eventLabel.put("dcEventTrafficControl.controlCause","管制原因"); + eventLabel.put("dcEventTrafficControl.exitsInlets","出入口"); + eventLabel.put("dcEventTrafficControl.facilityId","设施id"); + eventLabel.put("dcEventTrafficControl.rampId","匝道"); + eventLabel.put("dcEventTrafficControl.causeType","原因类型"); + eventLabel.put("dcEventTrafficControl.measure","措施"); + eventLabel.put("dcEventTrafficControl.classify","分类"); + eventLabel.put("dcEventTrafficControl.limitedType","限制类型"); +// eventLabel.put("dcEventTrafficControl.vehicleType","车辆类型"); } } @@ -100,6 +236,18 @@ public class ValueConverter { public static Map getValueMappingSource() { return ValueMappingHolder.valueMappingSource; } + + public static Map getEventSourceName() { + return ValueMappingHolder.eventSourceName; + } + + public static Map getEventTypeName() { + return ValueMappingHolder.eventTypeName; + } + + public static Map getEventLabel() { + return ValueMappingHolder.eventLabel; + } /** * 根据输入值返回转换后的值 * 如果输入值不在映射中,则返回输入值本身 @@ -118,6 +266,22 @@ public class ValueConverter { Map mapping = getValueMappingSource(); return mapping.getOrDefault(inputValue, inputValue); } + + + public static String eventSourceName(String inputValue) { + Map mapping = getEventSourceName(); + return mapping.getOrDefault(inputValue, inputValue); + } + + public static String eventTypeName(String inputValue) { + Map mapping = getEventTypeName(); + return mapping.getOrDefault(inputValue, inputValue); + } + public static String eventLabel(String inputValue) { + Map mapping = getEventLabel(); + return mapping.getOrDefault(inputValue, inputValue); + } + //测试 // @Test // public void text(){ diff --git a/zc-business/src/main/java/com/zc/business/enums/WarningSubclassEnum.java b/zc-business/src/main/java/com/zc/business/enums/WarningSubclassEnum.java index 6a3e4c19..02bbb6ec 100644 --- a/zc-business/src/main/java/com/zc/business/enums/WarningSubclassEnum.java +++ b/zc-business/src/main/java/com/zc/business/enums/WarningSubclassEnum.java @@ -27,7 +27,7 @@ public enum WarningSubclassEnum { EMERGENCY_LANE_BLOCKED("4-7", "应急车道被占用", "发生"), VEHICLE_EXIT_EMERGENCY_LANE("4-8", "车离开应急车道", "发生"), OTHER_CONDITION("4-9", "其他", "发生停车"), - OTHER_UNKNOWN("4-10", "未知车俩", "发生停车"), + OTHER_UNKNOWN("4-10", "未知车辆", "发生停车"), REVERSING_OR_GOING_BACKWARDS("5-1", "倒车/逆行", "发生"), LINEBALL("5-2", "压线", "发生压线"), TURNROUND("5-3", "掉头", "发生掉头"), diff --git a/zc-business/src/main/java/com/zc/business/mapper/DcEventImportantFileMapper.java b/zc-business/src/main/java/com/zc/business/mapper/DcEventImportantFileMapper.java new file mode 100644 index 00000000..af094b3b --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/mapper/DcEventImportantFileMapper.java @@ -0,0 +1,61 @@ +package com.zc.business.mapper; + +import java.util.List; +import com.zc.business.domain.DcEventImportantFile; + +/** + * 重要事件文件内容Mapper接口 + * + * @author ruoyi + * @date 2024-04-12 + */ +public interface DcEventImportantFileMapper +{ + /** + * 查询重要事件文件内容 + * + * @param id 重要事件文件内容主键 + * @return 重要事件文件内容 + */ + public DcEventImportantFile selectDcEventImportantFileByEventId(String id); + + /** + * 查询重要事件文件内容列表 + * + * @param dcEventImportantFile 重要事件文件内容 + * @return 重要事件文件内容集合 + */ + List selectDcEventImportantFileList(DcEventImportantFile dcEventImportantFile); + + /** + * 新增重要事件文件内容 + * + * @param dcEventImportantFile 重要事件文件内容 + * @return 结果 + */ + int insertDcEventImportantFile(DcEventImportantFile dcEventImportantFile); + + /** + * 修改重要事件文件内容 + * + * @param dcEventImportantFile 重要事件文件内容 + * @return 结果 + */ + int updateDcEventImportantFile(DcEventImportantFile dcEventImportantFile); + + /** + * 删除重要事件文件内容 + * + * @param id 重要事件文件内容主键 + * @return 结果 + */ + int deleteDcEventImportantFileByEventId(String id); + + /** + * 批量删除重要事件文件内容 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteDcEventImportantFileByEventIds(String[] ids); +} diff --git a/zc-business/src/main/java/com/zc/business/mapper/DcEventImportantMapper.java b/zc-business/src/main/java/com/zc/business/mapper/DcEventImportantMapper.java new file mode 100644 index 00000000..1aa5d2bf --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/mapper/DcEventImportantMapper.java @@ -0,0 +1,61 @@ +package com.zc.business.mapper; + +import java.util.List; +import com.zc.business.domain.DcEventImportant; + +/** + * 事件侧重要素Mapper接口 + * + * @author ruoyi + * @date 2024-04-11 + */ +public interface DcEventImportantMapper +{ + /** + * 查询事件侧重要素 + * + * @param id 事件侧重要素主键 + * @return 事件侧重要素 + */ + public DcEventImportant selectDcEventImportantByEventId(String id); + + /** + * 查询事件侧重要素列表 + * + * @param dcEventImportant 事件侧重要素 + * @return 事件侧重要素集合 + */ + List selectDcEventImportantList(DcEventImportant dcEventImportant); + + /** + * 新增事件侧重要素 + * + * @param dcEventImportant 事件侧重要素 + * @return 结果 + */ + int insertDcEventImportant(DcEventImportant dcEventImportant); + + /** + * 修改事件侧重要素 + * + * @param dcEventImportant 事件侧重要素 + * @return 结果 + */ + int updateDcEventImportant(DcEventImportant dcEventImportant); + + /** + * 删除事件侧重要素 + * + * @param id 事件侧重要素主键 + * @return 结果 + */ + int deleteDcEventImportantByEventId(String id); + + /** + * 批量删除事件侧重要素 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteDcEventImportantByEventIds(String[] ids); +} diff --git a/zc-business/src/main/java/com/zc/business/mapper/DcEventMapper.java b/zc-business/src/main/java/com/zc/business/mapper/DcEventMapper.java index c82f85ef..40d81d8c 100644 --- a/zc-business/src/main/java/com/zc/business/mapper/DcEventMapper.java +++ b/zc-business/src/main/java/com/zc/business/mapper/DcEventMapper.java @@ -4,7 +4,9 @@ package com.zc.business.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.zc.business.domain.DcEvent; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import java.util.Date; import java.util.List; import java.util.Map; @@ -50,6 +52,15 @@ public interface DcEventMapper extends BaseMapper */ int updateDcEvent(DcEvent dcEvent); + + /** + * 修改事件性质 关联管制事件id + * + * @param dcEvent 事件信息 + * @return 结果 + */ + int updateDcEventLinkId(DcEvent dcEvent); + /** * 删除事件信息 * @@ -83,6 +94,27 @@ public interface DcEventMapper extends BaseMapper */ boolean batchInsertDcEvent(List eventList); + int updateDcEventState(@Param("id") String id,@Param("state") int state); + + /** + * @Description 查询事件流程状态 + * + * @author liuwenge + * @date 2024/4/11 11:19 + * @param eventId 事件id + * @return com.ruoyi.common.core.domain.AjaxResult + */ + List> getProcessNode(@Param("eventId") String eventId); + + /** + * @Description 解除事件 + * + * @author liuwenge + * @date 2024/4/11 14:15 + * @param eventId + * @return boolean + */ + boolean completeEvent(@Param("eventId") String eventId); } diff --git a/zc-business/src/main/java/com/zc/business/mapper/DcEventProcessMapper.java b/zc-business/src/main/java/com/zc/business/mapper/DcEventProcessMapper.java index 0e7668a1..d512e150 100644 --- a/zc-business/src/main/java/com/zc/business/mapper/DcEventProcessMapper.java +++ b/zc-business/src/main/java/com/zc/business/mapper/DcEventProcessMapper.java @@ -35,6 +35,14 @@ public interface DcEventProcessMapper */ int insertDcEventProcess(DcEventProcess dcEventProcess); + /** + * 批量新增事件处理流程 + * + * @param dcEventProcessList 事件处理流程 + * @return 结果 + */ + boolean batchInsertDcEventProcess(List dcEventProcessList); + /** * 修改事件处理流程 * @@ -65,4 +73,6 @@ public interface DcEventProcessMapper * @return */ List selectDcDispatchByEventId(String id); + + int selectFinalNode(String eventId); } diff --git a/zc-business/src/main/java/com/zc/business/service/DcEmergencyPlansService.java b/zc-business/src/main/java/com/zc/business/service/DcEmergencyPlansService.java index de8faf8e..02d4d32a 100644 --- a/zc-business/src/main/java/com/zc/business/service/DcEmergencyPlansService.java +++ b/zc-business/src/main/java/com/zc/business/service/DcEmergencyPlansService.java @@ -1,6 +1,6 @@ package com.zc.business.service; -import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; import com.zc.business.domain.*; import java.util.List; @@ -39,6 +39,11 @@ public interface DcEmergencyPlansService { */ List selectDcEmergencyPlansByEventType(DcEvent event); + /** + * 处置设备智能发布的内容 + */ + void dispositionDeviceContent(List list, DcEvent dcEvent); + /** * 感知事件-根据事件类型查询事件预案 * @@ -63,7 +68,7 @@ public interface DcEmergencyPlansService { * @param dcEventAnDcEmergencyPlans 事件数据 和 事件预案数据 * @return 结果 */ - JSONArray executionEventConfirmation(DcEventAnDcEmergencyPlans dcEventAnDcEmergencyPlans); + JSONObject executionEventConfirmation(DcEventAnDcEmergencyPlans dcEventAnDcEmergencyPlans); /** * 根据事件id-查询预案事件关联表 @@ -79,7 +84,7 @@ public interface DcEmergencyPlansService { * @param dcEventAnDcEmergencyPlans 事件数据 和 事件预案数据 * @return 结果 */ - JSONArray executionWarningConfirmation(DcEventAnDcEmergencyPlans dcEventAnDcEmergencyPlans); + JSONObject executionWarningConfirmation(DcEventAnDcEmergencyPlans dcEventAnDcEmergencyPlans); /** * 感知事件-情报板自动生成 @@ -111,14 +116,6 @@ public interface DcEmergencyPlansService { */ int updateDcEmergencyPlans(DcEmergencyPlans dcEmergencyPlans); - /** - * 批量修改事件预案 - * - * @param dcEmergencyPlansList 事件预案 - * @return 结果 - */ - int updateBatchDcEmergencyPlans(List dcEmergencyPlansList); - /** * 批量删除事件预案 * diff --git a/zc-business/src/main/java/com/zc/business/service/IDcEventImportantFileService.java b/zc-business/src/main/java/com/zc/business/service/IDcEventImportantFileService.java new file mode 100644 index 00000000..f67f2899 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/service/IDcEventImportantFileService.java @@ -0,0 +1,61 @@ +package com.zc.business.service; + +import java.util.List; +import com.zc.business.domain.DcEventImportantFile; + +/** + * 重要事件文件内容Service接口 + * + * @author ruoyi + * @date 2024-04-12 + */ +public interface IDcEventImportantFileService +{ + /** + * 查询重要事件文件内容 + * + * @param id 重要事件文件内容主键 + * @return 重要事件文件内容 + */ + public DcEventImportantFile selectDcEventImportantFileByEventId(String id); + + /** + * 查询重要事件文件内容列表 + * + * @param dcEventImportantFile 重要事件文件内容 + * @return 重要事件文件内容集合 + */ + List selectDcEventImportantFileList(DcEventImportantFile dcEventImportantFile); + + /** + * 新增重要事件文件内容 + * + * @param dcEventImportantFile 重要事件文件内容 + * @return 结果 + */ + int insertDcEventImportantFile(DcEventImportantFile dcEventImportantFile); + + /** + * 修改重要事件文件内容 + * + * @param dcEventImportantFile 重要事件文件内容 + * @return 结果 + */ + int updateDcEventImportantFile(DcEventImportantFile dcEventImportantFile); + + /** + * 批量删除重要事件文件内容 + * + * @param ids 需要删除的重要事件文件内容主键集合 + * @return 结果 + */ + int deleteDcEventImportantFileByEventIds(String[] ids); + + /** + * 删除重要事件文件内容信息 + * + * @param id 重要事件文件内容主键 + * @return 结果 + */ + int deleteDcEventImportantFileByEventId(String id); +} diff --git a/zc-business/src/main/java/com/zc/business/service/IDcEventImportantService.java b/zc-business/src/main/java/com/zc/business/service/IDcEventImportantService.java new file mode 100644 index 00000000..b212e772 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/service/IDcEventImportantService.java @@ -0,0 +1,61 @@ +package com.zc.business.service; + +import java.util.List; +import com.zc.business.domain.DcEventImportant; + +/** + * 事件侧重要素Service接口 + * + * @author ruoyi + * @date 2024-04-11 + */ +public interface IDcEventImportantService +{ + /** + * 查询事件侧重要素 + * + * @param id 事件侧重要素主键 + * @return 事件侧重要素 + */ + public DcEventImportant selectDcEventImportantByEventId(String id); + + /** + * 查询事件侧重要素列表 + * + * @param dcEventImportant 事件侧重要素 + * @return 事件侧重要素集合 + */ + List selectDcEventImportantList(DcEventImportant dcEventImportant); + + /** + * 新增事件侧重要素 + * + * @param dcEventImportant 事件侧重要素 + * @return 结果 + */ + int insertDcEventImportant(DcEventImportant dcEventImportant); + + /** + * 修改事件侧重要素 + * + * @param dcEventImportant 事件侧重要素 + * @return 结果 + */ + int updateDcEventImportant(DcEventImportant dcEventImportant); + + /** + * 批量删除事件侧重要素 + * + * @param ids 需要删除的事件侧重要素主键集合 + * @return 结果 + */ + int deleteDcEventImportantByEventIds(String[] ids); + + /** + * 删除事件侧重要素信息 + * + * @param id 事件侧重要素主键 + * @return 结果 + */ + int deleteDcEventImportantByEventId(String id); +} diff --git a/zc-business/src/main/java/com/zc/business/service/IDcEventProcessService.java b/zc-business/src/main/java/com/zc/business/service/IDcEventProcessService.java index bbe9c157..f0023517 100644 --- a/zc-business/src/main/java/com/zc/business/service/IDcEventProcessService.java +++ b/zc-business/src/main/java/com/zc/business/service/IDcEventProcessService.java @@ -1,6 +1,9 @@ package com.zc.business.service; +import java.io.IOException; import java.util.List; + +import com.ruoyi.common.exception.file.InvalidExtensionException; import com.zc.business.domain.DcEventProcess; /** @@ -35,6 +38,14 @@ public interface IDcEventProcessService */ int insertDcEventProcess(DcEventProcess dcEventProcess); + /** + * 批量新增事件处理流程 + * + * @param dcEventProcessList 事件处理流程 + * @return 结果 + */ + boolean batchInsertDcEventProcess(List dcEventProcessList); + /** * 修改事件处理流程 * diff --git a/zc-business/src/main/java/com/zc/business/service/IDcEventService.java b/zc-business/src/main/java/com/zc/business/service/IDcEventService.java index ed7ce542..c05eac4e 100644 --- a/zc-business/src/main/java/com/zc/business/service/IDcEventService.java +++ b/zc-business/src/main/java/com/zc/business/service/IDcEventService.java @@ -1,6 +1,7 @@ package com.zc.business.service; +import com.ruoyi.common.core.domain.AjaxResult; import com.zc.business.domain.DcEvent; import java.util.List; @@ -57,6 +58,11 @@ public interface IDcEventService */ public int updateDcEvent(DcEvent dcEvent); + /** + * @param dcEvent + * @return int + */ + /** * 批量删除事件信息 * @@ -89,4 +95,36 @@ public interface IDcEventService Map selectCount(); List eventPileNumberQueryEvent(Map parameter); + + int updateDcEventState(String id, int state); + + /** + * @Description 查询事件流程状态 + * + * @author liuwenge + * @date 2024/4/11 11:19 + * @param eventId 事件id + * @return com.ruoyi.common.core.domain.AjaxResult + */ + AjaxResult getProcessNode(String eventId); + + /** + * @Description 解除事件 + * + * @author liuwenge + * @date 2024/4/11 14:13 + * @param eventId + * @return com.ruoyi.common.core.domain.AjaxResult + */ + AjaxResult completeEvent(String eventId); + + /** + * @Description 无需清障 + * + * @author liuwenge + * @date 2024/4/11 14:13 + * @param eventId + * @return com.ruoyi.common.core.domain.AjaxResult + */ + AjaxResult skipClear(String eventId); } diff --git a/zc-business/src/main/java/com/zc/business/service/impl/DcEmergencyPlansServiceImpl.java b/zc-business/src/main/java/com/zc/business/service/impl/DcEmergencyPlansServiceImpl.java index bf54a4b8..f38ee2c4 100644 --- a/zc-business/src/main/java/com/zc/business/service/impl/DcEmergencyPlansServiceImpl.java +++ b/zc-business/src/main/java/com/zc/business/service/impl/DcEmergencyPlansServiceImpl.java @@ -9,6 +9,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.uuid.IdUtils; import com.zc.business.constant.DeviceFunctionIdConstants; import com.zc.business.constant.DeviceTypeConstants; import com.zc.business.controller.BroadcastController; @@ -20,6 +21,7 @@ import com.zc.business.mapper.EventPlanAssocMapper; import com.zc.business.service.DcEmergencyPlansService; import com.zc.business.service.DcExecuteActionService; import com.zc.business.service.IDcDeviceService; +import com.zc.business.service.IDcFacilityService; import com.zc.common.core.httpclient.exception.HttpException; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @@ -50,6 +52,9 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { @Resource private EventPlanAssocMapper eventPlanAssocMapper; + @Resource + private IDcFacilityService dcFacilityService; + @Resource private ThreadPoolTaskExecutor threadPoolTaskExecutor; @@ -110,8 +115,6 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { return dcEmergencyPlansList.stream() .filter(dcEmergencyPlans -> { String triggerMechanism = dcEmergencyPlans.getTriggerMechanism(); -// JSONObject triggerJson = JSONObject.parseObject(triggerMechanism); -// String eventSubclass = triggerJson.get("eventSubclass").toString(); return triggerMechanism.equals(event.getSubclass()); }) .collect(Collectors.toList()); @@ -120,8 +123,6 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { return dcEmergencyPlansList.stream() .filter(dcEmergencyPlans -> { String triggerMechanism = dcEmergencyPlans.getTriggerMechanism(); -// JSONObject triggerJson = JSONObject.parseObject(triggerMechanism); -// String locationType = triggerJson.get("locationType").toString(); DcEventVehicleAccident dcEventVehicleAccident = event.getDcEventVehicleAccident(); String eventLocationType = dcEventVehicleAccident.getLocationType().toString(); return triggerMechanism.equals(eventLocationType); @@ -132,9 +133,6 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { return dcEmergencyPlansList.stream() .filter(dcEmergencyPlans -> { String triggerMechanism = dcEmergencyPlans.getTriggerMechanism(); -// JSONObject triggerJson = JSONObject.parseObject(triggerMechanism); - // 分类 -// Integer classify = Integer.parseInt(triggerJson.get("classify").toString()); // 事件--交通管制数据 DcEventTrafficControl dcEventTrafficControl = event.getDcEventTrafficControl(); Integer eventClassify = Integer.parseInt(dcEventTrafficControl.getClassify().toString()); @@ -148,6 +146,110 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { } + /** + * 处置设备智能发布的内容 + */ + @Override + public void dispositionDeviceContent(List list, DcEvent dcEvent) { + // 事件桩号 + dcEvent.setStakeMark(dcEvent.getStakeMark().replace("K", "")); + String[] markArray = dcEvent.getStakeMark().split("\\+"); + if (markArray[1].length() < 3) { + // 不足三位 补零 + markArray[1] = String.format("%0" + 3 + "d", markArray[1]); + } + + // 情报板 语音广播 + list.forEach(dcEmergencyPlans -> { + List dcExecuteActions = dcEmergencyPlans.getDcExecuteAction(); + dcExecuteActions.forEach(dcExecuteAction -> { + JSONObject executeConfig = JSON.parseObject(dcExecuteAction.getExecuteConfig()); + if (dcExecuteAction.getDeviceType() == DeviceTypeEnum.ROAD_SECTION_VOICE_BROADCASTING.getCode() + && executeConfig.get("operationType").equals("2")) { + // 执行操作中智能发布语音广播 + String content = intelligentPublishingOfInformation(dcEvent); + updateIntelligentPublishingContent(dcExecuteAction,markArray,dcEvent,content,dcEvent.getDirection()); + } else if (dcExecuteAction.getDeviceType() == DeviceTypeEnum.VARIABLE_INFORMATION_FLAG.getCode() + && executeConfig.get("operationType").equals("2")) { + // 执行操作中智能发布情报板 + String content = intelligentPublishingOfInformation(dcEvent); + updateIntelligentPublishingContent(dcExecuteAction,markArray,dcEvent,content,dcEvent.getDirection()); + } + }); + }); + } + + /** + * 更改智能发布中的发布内容-计算公里数 + */ + public void updateIntelligentPublishingContent(DcExecuteAction dcExecuteAction, + String[] markArray, + DcEvent dcEvent, + String content, + String direction) { + List deviceList = ruleFiltering(dcExecuteAction, markArray, dcEvent.getDirection()); + JSONObject executeConfig = JSON.parseObject(dcExecuteAction.getExecuteConfig()); + List> contentList = new ArrayList<>(); + deviceList.forEach(dcDevice -> { + Map map = new HashMap<>(); + map.put("dcDeviceId",dcDevice.getId()); + map.put("deviceName",dcDevice.getDeviceName()); + // 公里数 + int kilometers = 0; + // 米数 + int meters = 0; + dcDevice.setStakeMark(dcDevice.getStakeMark().replace("K", "")); + String[] deviceMarkArray = dcDevice.getStakeMark().split("\\+"); + if (deviceMarkArray[1].length() < 3) { + // 不足三位 补零 + deviceMarkArray[1] = String.format("%0" + 3 + "d", deviceMarkArray[1]); + } + if (direction.equals("菏泽方向") || direction.equals("1")) { + kilometers = Math.abs(Integer.parseInt(markArray[0]) - Integer.parseInt(deviceMarkArray[0])); + meters = Integer.parseInt(markArray[1]) - Integer.parseInt(deviceMarkArray[1]); + }else { + kilometers = Math.abs(Integer.parseInt(deviceMarkArray[0]) - Integer.parseInt(markArray[0])); + meters = Integer.parseInt(deviceMarkArray[1]) - Integer.parseInt(markArray[1]); + } + + double roundedDistance = Math.round((kilometers + meters / 1000.0) * 10.0) / 10.0; + if (roundedDistance < 1) { + map.put("content",content.replace("*",(int) (roundedDistance * 1000)+"米")); + }else { + if (roundedDistance % 1 == 0) { + // 去除掉1.0公里的情况 + map.put("content",content.replace("*",(int)roundedDistance+"公里")); + }else { + map.put("content",content.replace("*",roundedDistance+"公里")); + } + + } + + if (dcExecuteAction.getDeviceType() == DeviceTypeEnum.VARIABLE_INFORMATION_FLAG.getCode()) { + // 情报板 + // stopTime + map.put("stopTime", "50"); + // inScreenMode + map.put("inScreenMode", "1"); + // fontSpacing + map.put("fontSpacing", "0"); + // fontColor + map.put("fontColor", "ffff00"); + // fontType + map.put("fontType", "1"); + // fontSize + map.put("fontSize", "36"); + // screenSize 768*64 宽度和高度 + map.put("screenSize", "768*64"); + // formatStyle + map.put("formatStyle", "2"); + } + contentList.add(map); + }); + executeConfig.put("contentList",contentList); + dcExecuteAction.setExecuteConfig(executeConfig.toJSONString()); + } + /** * 感知事件 - 根据事件类型查询事件预案 * @@ -196,8 +298,7 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { markArray[1] = String.format("%0" + 3 + "d", markArray[1]); } DcExecuteAction executeAction = dcEventAnDcEmergencyPlans.getDcEmergencyPlans().getExecuteAction(); - Integer operationType = dcEventAnDcEmergencyPlans.getOperationType(); - List dcDevices = ruleFiltering(executeAction, markArray, direction, operationType); + List dcDevices = ruleFiltering(executeAction, markArray, direction); return getBoardTemplate(dcDevices); } @@ -218,8 +319,7 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { markArray[1] = String.format("%0" + 3 + "d", markArray[1]); } DcExecuteAction executeAction = dcEventAnDcEmergencyPlans.getDcEmergencyPlans().getExecuteAction(); - Integer operationType = dcEventAnDcEmergencyPlans.getOperationType(); - List dcDevices = ruleFiltering(executeAction, markArray, direction, operationType); + List dcDevices = ruleFiltering(executeAction, markArray, direction); return getBoardTemplate(dcDevices); } @@ -289,12 +389,9 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { * @param direction * @return */ - public List ruleFiltering(DcExecuteAction dcExecuteAction, String[] markArray, String direction, Integer operationType) { + public List ruleFiltering(DcExecuteAction dcExecuteAction, String[] markArray, String direction) { Integer searchRule = dcExecuteAction.getSearchRule(); - // 区分执行操作还是恢复操作 - JSONObject otherConfig = operationType.equals(1)? - JSON.parseObject(dcExecuteAction.getExecuteConfig()): JSON.parseObject(dcExecuteAction.getRecoverConfig()); List start = new ArrayList<>(); List end = new ArrayList<>(); // 设备列表 @@ -306,13 +403,13 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { // 指定设备资源 // 根据设备id,获取设备集合 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - List deviceList = (List) otherConfig.get("deviceList"); + String[] deviceList = dcExecuteAction.getDeviceList().split(","); queryWrapper.in(DcDevice::getIotDeviceId, deviceList); dcDevices = dcDeviceService.list(queryWrapper); } else if (searchRule.equals(2)) { // 事件上游最近 - if (direction.equals("菏泽方向")) { + if (direction.equals("菏泽方向") || direction.equals("1")) { // 上行 取最大的几个 start.add("55"); start.add("379"); @@ -351,8 +448,8 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { } } else if (searchRule.equals(3)) { - // 事件下游最近 - if (direction.equals("菏泽方向")) { + // 事件下游最近 没有这个类型 + if (direction.equals("菏泽方向") || direction.equals("1")) { // 上行 取最大的几个 start.add(markArray[0]); start.add(markArray[1]); @@ -406,8 +503,29 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { // 根据桩号范围,查询附近设备 dcDevices = dcDeviceService.devicePileNumberQueryDevice(parameter); } - - return dcDevices; + //将0公里和负数的设备去掉 + return dcDevices.stream() + .filter(device -> { + device.setStakeMark(device.getStakeMark().replace("K", "")); + String[] deviceMarkArray = device.getStakeMark().split("\\+"); + if (deviceMarkArray[1].length() < 3) { + deviceMarkArray[1] = String.format("%0" + 3 + "d", deviceMarkArray[1]); + } + int kilometers = 0; + int meters = 0; + if (direction.equals("菏泽方向") || direction.equals("1")) { + // 菏泽方向 桩号增大 设备桩号要小于事件桩号 + kilometers = Integer.parseInt(markArray[0]) - Integer.parseInt(deviceMarkArray[0]); + meters = Integer.parseInt(markArray[1]) - Integer.parseInt(deviceMarkArray[1]); + }else { + // 济南方向 桩号减小 设备桩号要大于事件桩号 + kilometers = Integer.parseInt(deviceMarkArray[0]) - Integer.parseInt(markArray[0]); + meters = Integer.parseInt(deviceMarkArray[1]) - Integer.parseInt(markArray[1]); + } + double roundedDistance = Math.round((kilometers + meters / 1000.0) * 10.0) / 10.0; + return kilometers >= 0 && roundedDistance > 0; + }) + .collect(Collectors.toList()); } @@ -418,7 +536,7 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { * @return 结果 */ @Override - public JSONArray executionEventConfirmation(DcEventAnDcEmergencyPlans dcEventAnDcEmergencyPlans) { + public JSONObject executionEventConfirmation(DcEventAnDcEmergencyPlans dcEventAnDcEmergencyPlans) { // 获取事件数据 DcEvent dcEvent = dcEventAnDcEmergencyPlans.getDcEvent(); // 方向 @@ -478,8 +596,17 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { @Override public DcInfoBoardTemplate eventAutomaticGeneration(DcEventAnDcEmergencyPlans dcEventAnDcEmergencyPlans) { // 根据交通事件的事件类型,生成相应的情报板内容 - DcEvent dcEvent = dcEventAnDcEmergencyPlans.getDcEvent(); DcInfoBoardTemplate dcInfoBoardTemplate = dcEventAnDcEmergencyPlans.getDcInfoBoardTemplate(); + DcEvent dcEvent = dcEventAnDcEmergencyPlans.getDcEvent(); + dcInfoBoardTemplate.setContent(intelligentPublishingOfInformation(dcEvent)); + return dcInfoBoardTemplate; + } + + /** + * 智能发布信息匹配 + */ + public String intelligentPublishingOfInformation(DcEvent dcEvent) { + String content = "请注意前方危险"; int eventType = Integer.parseInt(dcEvent.getEventType().toString()); if (eventType == EventTypeEnum.ABNORMAL_WEATHER.getCode() || eventType == EventTypeEnum.TRAFFIC_ACCIDENT.getCode() || @@ -488,42 +615,41 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { eventType == EventTypeEnum.SERVICE_AREA_ABNORMALITY.getCode() || eventType == EventTypeEnum.ROADBLOCK_CLEARANCE.getCode()) { - String content = Arrays.stream(EventSubclassEnum.values()) + content = Arrays.stream(EventSubclassEnum.values()) .filter(eventSubclassEnum -> eventSubclassEnum.getCode().equals(dcEvent.getSubclass())) .findFirst() .map(EventSubclassEnum::getText) .orElse("请注意前方危险"); - dcInfoBoardTemplate.setContent(content); } else if (eventType == EventTypeEnum.VEHICLE_MALFUNCTION.getCode()) { // 车辆故障 DcEventVehicleAccident dcEventVehicleAccident = dcEvent.getDcEventVehicleAccident(); int locationType = Integer.parseInt(dcEventVehicleAccident.getLocationType().toString()); + // 路广设施id + Integer facilityId = dcEventVehicleAccident.getFacilityId(); + DcFacility facility = dcFacilityService.getFacility(facilityId.toString()); + String facilityName = facility.getFacilityName(); if (locationType == 1) { - dcInfoBoardTemplate.setContent("高速主线发生车辆故障"); - } else if (locationType == 2) { - dcInfoBoardTemplate.setContent("服务区发生车辆故障"); - } else if (locationType == 3) { - dcInfoBoardTemplate.setContent("立交桥发生车辆故障"); - } else if (locationType == 4) { - dcInfoBoardTemplate.setContent("收费站发生车辆故障"); + content = "前方*高速主线发生车辆故障"; + } else if (locationType == 2 || locationType == 3 || locationType == 4) { + // 服务区、立交、收费站 + content = "前方*"+facilityName+"发生车辆故障"; } } else if (eventType == EventTypeEnum.TRAFFIC_CONTROL.getCode()) { // 交通管制 DcEventTrafficControl dcEventTrafficControl = dcEvent.getDcEventTrafficControl(); int classify = Integer.parseInt(dcEventTrafficControl.getClassify().toString()); - String content = Arrays.stream(ClassifyEnum.values()) + content = Arrays.stream(ClassifyEnum.values()) .filter(eventSubclassEnum -> eventSubclassEnum.getCode() == classify) .findFirst() .map(ClassifyEnum::getText) - .orElse("前方存在限行或关闭"); - dcInfoBoardTemplate.setContent(content); + .orElse("前方*存在限行或关闭"); } else { // 施工建设 - dcInfoBoardTemplate.setContent("前方施工请注意驾驶"); + content = "前方*施工请注意驾驶"; } - return dcInfoBoardTemplate; + return content; } /** @@ -533,7 +659,7 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { * @return */ @Override - public JSONArray executionWarningConfirmation(DcEventAnDcEmergencyPlans dcEventAnDcEmergencyPlans) { + public JSONObject executionWarningConfirmation(DcEventAnDcEmergencyPlans dcEventAnDcEmergencyPlans) { // 获取事件数据 DcWarning dcWarning = dcEventAnDcEmergencyPlans.getDcWarning(); @@ -550,7 +676,7 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { * @param dcEventAnDcEmergencyPlans 事件数据 和 事件预案数据 * @return */ - public JSONArray executionConfirmation(DcEventAnDcEmergencyPlans dcEventAnDcEmergencyPlans, + public JSONObject executionConfirmation(DcEventAnDcEmergencyPlans dcEventAnDcEmergencyPlans, String stakeMark, String direction, String id) { @@ -574,7 +700,7 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { //获取事件预案中的操作配置 dcEmergencyPlans.getDcExecuteAction() .forEach(dcExecuteAction -> { - List dcDevices = ruleFiltering(dcExecuteAction, markArray, direction, operationType); + List dcDevices = ruleFiltering(dcExecuteAction, markArray, direction); JSONObject otherConfig = operationType.equals(1)? JSON.parseObject(dcExecuteAction.getExecuteConfig()): JSON.parseObject(dcExecuteAction.getRecoverConfig()); try { @@ -600,32 +726,32 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { }); // 创建一个 预案事件关联对象 EventPlanAssoc eventPlanAssoc = new EventPlanAssoc(); + JSONObject resultObject = new JSONObject(); // 事件编号 eventPlanAssoc.setEventId(id); + eventPlanAssoc.setOperationType(dcEventAnDcEmergencyPlans.getOperationType()); EventPlanAssoc selectEventPlanAssoc = eventPlanAssocMapper.selectByEventId(eventPlanAssoc); - // 区分是执行操作 还是 恢复操作 - if (dcEventAnDcEmergencyPlans.getOperationType().equals(1) && StringUtils.isEmpty(selectEventPlanAssoc.getId())) { - // 首次执行操作 + + if (selectEventPlanAssoc == null) { + // 执行新增 eventPlanAssoc.setEmergencyPlansId(dcEmergencyPlans.getId()); - eventPlanAssoc.setExecutingControlDevice(deviceIds.toString().replaceFirst(";", "")); - eventPlanAssoc.setExecutingControlResult(resultArray.toJSONString()); + eventPlanAssoc.setControlDevice(deviceIds.toString().replaceFirst(";", "")); + eventPlanAssoc.setControlResult(resultArray.toJSONString()); eventPlanAssoc.setCreateTime(DateUtils.getNowDate()); + // IdUtils.fastSimpleUUID() + eventPlanAssoc.setId(IdUtils.fastSimpleUUID()); eventPlanAssocMapper.insertEventPlanAssoc(eventPlanAssoc); - } - else if (StringUtils.isNotEmpty(selectEventPlanAssoc.getId()) && dcEventAnDcEmergencyPlans.getOperationType().equals(1)) { - // 多次执行操作 - selectEventPlanAssoc.setExecutingControlResult(resultArray.toJSONString()); + resultObject.put("eventPlanAssocId",eventPlanAssoc.getId()); + }else { + // 执行修改操作 selectEventPlanAssoc.setUpdateTime(DateUtils.getNowDate()); + selectEventPlanAssoc.setControlDevice(deviceIds.toString().replaceFirst(";", "")); + selectEventPlanAssoc.setControlResult(resultArray.toJSONString()); eventPlanAssocMapper.updateEventPlanAssoc(selectEventPlanAssoc); + resultObject.put("eventPlanAssocId",selectEventPlanAssoc.getId()); } - else { - // 恢复操作 未执行的事件不能进行恢复操作 - selectEventPlanAssoc.setUpdateTime(DateUtils.getNowDate()); - selectEventPlanAssoc.setRecoveredControlDevice(deviceIds.toString().replaceFirst(";", "")); - selectEventPlanAssoc.setRecoveredControlResult(resultArray.toJSONString()); - eventPlanAssocMapper.updateEventPlanAssoc(selectEventPlanAssoc); - } - return resultArray; + resultObject.put("deviceOperationResult",resultArray); + return resultObject; } /** @@ -635,7 +761,7 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { List dcDevices, JSONObject otherConfig, JSONArray resultArray) { - + CountDownLatch latch = new CountDownLatch(dcDevices.size()); for (DcDevice device : dcDevices) { @@ -653,18 +779,24 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { props.put("onWorkStatus", otherConfig.get("state").toString()); props.put("inWorkStatus", otherConfig.get("state").toString()); props.put("mode", controlModel); + JSONObject result = new JSONObject(); if (controlModel.equals("01")) { String startTime = otherConfig.get("startTime").toString(); String endTime = otherConfig.get("endTime").toString(); props.put("mode", "01"); props.put("startDisplayTime", startTime); props.put("endDisplayTime", endTime); - } + result.put("content","时间自动"); + } else if (controlModel.equals("00")) { + result.put("content","手动"); + }else { + result.put("content","万年历"); + } AjaxResult ajaxResult = dcDeviceController.invokedFunction(iotDeviceId, functionId, props); // 将调用结果存入到 resultArray(操作结果) 中 - JSONObject result = new JSONObject(); result.put("device", device.getId()); + result.put("deviceName",device.getDeviceName()); result.put("result", ajaxResult); resultArray.add(result); @@ -673,19 +805,40 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { else if (device.getDeviceType().equals(DeviceTypeConstants.VARIABLE_INFORMATION_FLAG.toString())) { if (operationType == 1) { // 情报板发布全流程 - boardReleaseProcess(props, iotDeviceId, otherConfig, device, resultArray); + if (otherConfig.get("operationType").equals("2")) { + JSONArray contentList = JSON.parseArray(otherConfig.get("contentList").toString()); + JSONObject foundContent = contentList.stream() + .map(content -> JSON.parseObject(content.toString())) + .filter(jsonObject -> + Integer.parseInt(jsonObject.get("dcDeviceId").toString()) == device.getId()) + .findFirst() + .orElse(null); + if (foundContent == null) { + // 说明没有匹配到设备 + JSONObject errorResult = new JSONObject(); + errorResult.put("device",device.getId()); + errorResult.put("errorMessage","未匹配到对应的模板内容"); + resultArray.add(errorResult); + } + JSONObject jsonObject = new JSONObject(); + jsonObject.put("dcInfoBoardTemplate",foundContent); + boardReleaseProcess(props, iotDeviceId, jsonObject, device, resultArray); + }else { + boardReleaseProcess(props, iotDeviceId, otherConfig, device, resultArray); + } + } else { // 恢复操作 if (otherConfig.get("operationType").equals("2")) { // 还原上次 props.put("fileId", "10"); functionId = DeviceFunctionIdConstants.VARIABLE_INFORMATION_FLAG_1B; - AjaxResult ajaxResult1B; - - ajaxResult1B = dcDeviceController.invokedFunction(iotDeviceId, functionId, props); + AjaxResult ajaxResult1B = dcDeviceController.invokedFunction(iotDeviceId, functionId, props); JSONObject result = new JSONObject(); result.put("device", device.getId()); + result.put("deviceName",device.getDeviceName()); + result.put("content","还原上次"); result.put("result", ajaxResult1B); resultArray.add(result); }else { @@ -702,7 +855,27 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { params.put("name", "task-event"); params.put("outVVol", "8"); params.put("priority", "1"); - params.put("text", otherConfig.get("content")); + if (otherConfig.get("operationType").equals("2")) { + // 智能发布 + JSONArray contentList = JSON.parseArray(otherConfig.get("contentList").toString()); + JSONObject foundContent = contentList.stream() + .map(content -> JSON.parseObject(content.toString())) + .filter(jsonObject -> + Integer.parseInt(jsonObject.get("dcDeviceId").toString()) == device.getId()) + .findFirst() + .orElse(null); + if (foundContent == null) { + // 说明没有匹配到设备 + JSONObject errorResult = new JSONObject(); + errorResult.put("device",device.getId()); + errorResult.put("deviceName",device.getDeviceName()); + errorResult.put("errorMessage","未匹配到对应的广播内容"); + resultArray.add(errorResult); + } + params.put("text", foundContent.get("content")); + }else { + params.put("text", otherConfig.get("content")); + } params.put("repeatTimes", "3"); params.put("functionType", "startPaTts"); JSONArray termList = new JSONArray(); @@ -712,6 +885,8 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { JSONObject returnResult = broadcastController.nearCamListDistance(params); JSONObject result = new JSONObject(); result.put("device", device.getId()); + result.put("deviceName",device.getDeviceName()); + result.put("content",params.get("text")); result.put("result", returnResult); resultArray.add(result); @@ -724,6 +899,7 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { AjaxResult ajaxResultState = dcDeviceController.invokedFunction(iotDeviceId, functionId, new HashMap<>()); JSONObject result = new JSONObject(); result.put("device", device.getId()); + result.put("deviceName",device.getDeviceName()); result.put("result", ajaxResultState); resultArray.add(result); @@ -736,6 +912,8 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { AjaxResult ajaxResult = dcDeviceController.invokedFunction(iotDeviceId, functionId, propsTime); JSONObject resultTime = new JSONObject(); resultTime.put("device", device.getId()); + resultTime.put("deviceName",device.getDeviceName()); + resultTime.put("content","操作时长"+otherConfig.get("operationDuration")); resultTime.put("result", ajaxResult); resultArray.add(resultTime); @@ -743,10 +921,18 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { } catch (HttpException | IOException e) { log.error(e.toString()); throw new RuntimeException(e); + } finally { + latch.countDown(); // 确保在异常情况下也能减少CountDownLatch计数 } }); } + try { + latch.await(); // 等待所有线程执行完毕 + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } /** @@ -765,8 +951,7 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { functionId = DeviceFunctionIdConstants.VARIABLE_INFORMATION_FLAG_11; props.put("fileName", "play011.lst"); props.put("size", "65535"); - AjaxResult ajaxResult11; - ajaxResult11 = dcDeviceController.invokedFunction(iotDeviceId, functionId, props); + AjaxResult ajaxResult11 = dcDeviceController.invokedFunction(iotDeviceId, functionId, props); if (ajaxResult11.get("code").equals(200)) { // 2:执行13功能码 HashMap props11 = new HashMap<>(); @@ -797,8 +982,7 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { parameters.put("formatStyle", dcInfoBoardTemplate.getFormatStyle()); list.add(parameters); props11.put("parameters", list); - AjaxResult ajaxResult13 = null; - ajaxResult13 = dcDeviceController.invokedFunction(iotDeviceId, functionId, props11); + AjaxResult ajaxResult13 = dcDeviceController.invokedFunction(iotDeviceId, functionId, props11); JSONObject result = new JSONObject(); if (ajaxResult13.get("code").equals(200)) { HashMap props1B = new HashMap<>(); @@ -807,11 +991,15 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { props1B.put("fileId", "11"); AjaxResult ajaxResult1B = dcDeviceController.invokedFunction(iotDeviceId, functionId, props1B); result.put("device", device.getId()); + result.put("deviceName",device.getDeviceName()); + result.put("content",dcInfoBoardTemplate.getContent()); result.put("result", ajaxResult1B); resultArray.add(result); } else { result.put("device", device.getId()); + result.put("deviceName",device.getDeviceName()); + result.put("content","发布失败"); result.put("result", ajaxResult13); resultArray.add(result); } @@ -889,11 +1077,6 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { return dcExecuteActionService.updateDcExecuteActionBatch(dcExecuteActionList); } - @Override - public int updateBatchDcEmergencyPlans(List dcEmergencyPlansList) { - return 0; - } - /** * 批量删除事件预案 * diff --git a/zc-business/src/main/java/com/zc/business/service/impl/DcEventImportantFileServiceImpl.java b/zc-business/src/main/java/com/zc/business/service/impl/DcEventImportantFileServiceImpl.java new file mode 100644 index 00000000..586619f6 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/service/impl/DcEventImportantFileServiceImpl.java @@ -0,0 +1,120 @@ +package com.zc.business.service.impl; + +import java.util.Date; +import java.util.List; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.zc.business.domain.DcEventProcess; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.zc.business.mapper.DcEventImportantFileMapper; +import com.zc.business.domain.DcEventImportantFile; +import com.zc.business.service.IDcEventImportantFileService; + +/** + * 重要事件文件内容Service业务层处理 + * + * @author ruoyi + * @date 2024-04-12 + */ +@Service +public class DcEventImportantFileServiceImpl implements IDcEventImportantFileService +{ + @Autowired + private DcEventImportantFileMapper dcEventImportantFileMapper; + @Autowired + private DcEventProcessServiceImpl dcEventProcessService; + + /** + * 查询重要事件文件内容 + * + * @param id 重要事件文件内容主键 + * @return 重要事件文件内容 + */ + @Override + public DcEventImportantFile selectDcEventImportantFileByEventId(String id) + { + return dcEventImportantFileMapper.selectDcEventImportantFileByEventId(id); + } + + /** + * 查询重要事件文件内容列表 + * + * @param dcEventImportantFile 重要事件文件内容 + * @return 重要事件文件内容 + */ + @Override + public List selectDcEventImportantFileList(DcEventImportantFile dcEventImportantFile) + { + return dcEventImportantFileMapper.selectDcEventImportantFileList(dcEventImportantFile); + } + + /** + * 新增重要事件文件内容 + * + * @param dcEventImportantFile 重要事件文件内容 + * @return 结果 + */ + @Override + public int insertDcEventImportantFile(DcEventImportantFile dcEventImportantFile) + { + int i = dcEventImportantFileMapper.insertDcEventImportantFile(dcEventImportantFile); + if (i > 0){ + DcEventProcess dcEventProcess = new DcEventProcess(); + dcEventProcess.setEventId(dcEventImportantFile.getEventId()); + dcEventProcess.setOperationTime(new Date()); + dcEventProcess.setOperator(SecurityUtils.getUserId().toString()); + dcEventProcess.setSource(1); + dcEventProcess.setProcessType(4); + dcEventProcess.setProcessId(dcEventImportantFile.getId()); + String context = "重要事件"; + if ("1".equals(dcEventImportantFile.getType())){ + context = "重要事件初报"; + } else if ("2".equals(dcEventImportantFile.getType())){ + context = "重要事件续报"; + } else if ("3".equals(dcEventImportantFile.getType())){ + context = "重要事件终报"; + } + dcEventProcess.setContext(context); + dcEventProcessService.insertDcEventProcess(dcEventProcess); + + } + return i; + } + + /** + * 修改重要事件文件内容 + * + * @param dcEventImportantFile 重要事件文件内容 + * @return 结果 + */ + @Override + public int updateDcEventImportantFile(DcEventImportantFile dcEventImportantFile) + { + return dcEventImportantFileMapper.updateDcEventImportantFile(dcEventImportantFile); + } + + /** + * 批量删除重要事件文件内容 + * + * @param ids 需要删除的重要事件文件内容主键 + * @return 结果 + */ + @Override + public int deleteDcEventImportantFileByEventIds(String[] ids) + { + return dcEventImportantFileMapper.deleteDcEventImportantFileByEventIds(ids); + } + + /** + * 删除重要事件文件内容信息 + * + * @param eventId 重要事件文件内容主键 + * @return 结果 + */ + @Override + public int deleteDcEventImportantFileByEventId(String id) + { + return dcEventImportantFileMapper.deleteDcEventImportantFileByEventId(id); + } +} diff --git a/zc-business/src/main/java/com/zc/business/service/impl/DcEventImportantServiceImpl.java b/zc-business/src/main/java/com/zc/business/service/impl/DcEventImportantServiceImpl.java new file mode 100644 index 00000000..f828a8c2 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/service/impl/DcEventImportantServiceImpl.java @@ -0,0 +1,93 @@ +package com.zc.business.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.zc.business.mapper.DcEventImportantMapper; +import com.zc.business.domain.DcEventImportant; +import com.zc.business.service.IDcEventImportantService; + +/** + * 事件侧重要素Service业务层处理 + * + * @author ruoyi + * @date 2024-04-11 + */ +@Service +public class DcEventImportantServiceImpl implements IDcEventImportantService +{ + @Autowired + private DcEventImportantMapper dcEventImportantMapper; + + /** + * 查询事件侧重要素 + * + * @param id 事件侧重要素主键 + * @return 事件侧重要素 + */ + @Override + public DcEventImportant selectDcEventImportantByEventId(String id) + { + return dcEventImportantMapper.selectDcEventImportantByEventId(id); + } + + /** + * 查询事件侧重要素列表 + * + * @param dcEventImportant 事件侧重要素 + * @return 事件侧重要素 + */ + @Override + public List selectDcEventImportantList(DcEventImportant dcEventImportant) + { + return dcEventImportantMapper.selectDcEventImportantList(dcEventImportant); + } + + /** + * 新增事件侧重要素 + * + * @param dcEventImportant 事件侧重要素 + * @return 结果 + */ + @Override + public int insertDcEventImportant(DcEventImportant dcEventImportant) + { + return dcEventImportantMapper.insertDcEventImportant(dcEventImportant); + } + + /** + * 修改事件侧重要素 + * + * @param dcEventImportant 事件侧重要素 + * @return 结果 + */ + @Override + public int updateDcEventImportant(DcEventImportant dcEventImportant) + { + return dcEventImportantMapper.updateDcEventImportant(dcEventImportant); + } + + /** + * 批量删除事件侧重要素 + * + * @param ids 需要删除的事件侧重要素主键 + * @return 结果 + */ + @Override + public int deleteDcEventImportantByEventIds(String[] ids) + { + return dcEventImportantMapper.deleteDcEventImportantByEventIds(ids); + } + + /** + * 删除事件侧重要素信息 + * + * @param id 事件侧重要素主键 + * @return 结果 + */ + @Override + public int deleteDcEventImportantByEventId(String id) + { + return dcEventImportantMapper.deleteDcEventImportantByEventId(id); + } +} diff --git a/zc-business/src/main/java/com/zc/business/service/impl/DcEventProcessServiceImpl.java b/zc-business/src/main/java/com/zc/business/service/impl/DcEventProcessServiceImpl.java index e5a2096c..4c91278c 100644 --- a/zc-business/src/main/java/com/zc/business/service/impl/DcEventProcessServiceImpl.java +++ b/zc-business/src/main/java/com/zc/business/service/impl/DcEventProcessServiceImpl.java @@ -1,6 +1,13 @@ package com.zc.business.service.impl; +import java.io.IOException; import java.util.List; + +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.exception.file.InvalidExtensionException; +import com.ruoyi.common.utils.file.FileUploadUtils; +import com.ruoyi.common.utils.file.MimeTypeUtils; +import com.zc.business.domain.DcEvent; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.zc.business.mapper.DcEventProcessMapper; @@ -18,6 +25,8 @@ public class DcEventProcessServiceImpl implements IDcEventProcessService { @Autowired private DcEventProcessMapper dcEventProcessMapper; + @Autowired + private DcEventServiceImpl dcEventService; /** * 查询事件处理流程 @@ -52,9 +61,53 @@ public class DcEventProcessServiceImpl implements IDcEventProcessService @Override public int insertDcEventProcess(DcEventProcess dcEventProcess) { + //如果有文件传入 + if(!dcEventProcess.getFile().isEmpty()){ + try { + String address = FileUploadUtils.upload(RuoYiConfig.getUploadPath(), dcEventProcess.getFile(), MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); + dcEventProcess.setContext(address); + String type = address.split("\\.")[1]; + dcEventProcess.setType(type); + } catch (IOException | InvalidExtensionException e){ + e.printStackTrace(); + } + } + //判断是否最后一个节点 + if (dcEventProcess.getProcessType() != null && dcEventProcess.getProcessType() == 1){ + int finalNode = dcEventProcessMapper.selectFinalNode(dcEventProcess.getEventId()); + if (finalNode == dcEventProcess.getProcessId()){ + dcEventService.updateDcEventState(dcEventProcess.getEventId(),2); + } + } return dcEventProcessMapper.insertDcEventProcess(dcEventProcess); } + /** + * 新增事件处理流程 + * + * @param dcEventProcessList 事件处理流程 + * @return 结果 + */ + @Override + public boolean batchInsertDcEventProcess(List dcEventProcessList) + { + dcEventProcessList.forEach(dcEventProcess -> { + //如果有文件传入 + if(!dcEventProcess.getFile().isEmpty()){ + try { + String address = FileUploadUtils.upload(RuoYiConfig.getUploadPath(), dcEventProcess.getFile(), MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); + dcEventProcess.setContext(address); + String type = address.split("\\.")[1]; + dcEventProcess.setType(type); + } catch (IOException | InvalidExtensionException e){ + e.printStackTrace(); + } + } + }); + + return dcEventProcessMapper.batchInsertDcEventProcess(dcEventProcessList); + } + /** * 修改事件处理流程 * diff --git a/zc-business/src/main/java/com/zc/business/service/impl/DcEventServiceImpl.java b/zc-business/src/main/java/com/zc/business/service/impl/DcEventServiceImpl.java index 53846d7b..d1411627 100644 --- a/zc-business/src/main/java/com/zc/business/service/impl/DcEventServiceImpl.java +++ b/zc-business/src/main/java/com/zc/business/service/impl/DcEventServiceImpl.java @@ -1,23 +1,34 @@ package com.zc.business.service.impl; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.uuid.IdUtils; import com.ruoyi.system.service.ISysDeptService; +import com.sun.xml.bind.v2.TODO; import com.zc.business.domain.*; +import com.zc.business.enums.EventSubclassEnum; +import com.zc.business.enums.ValueConverter; import com.zc.business.mapper.*; +import com.zc.business.service.IDcEventProcessService; import com.zc.business.service.IDcEventService; import com.zc.business.service.IMiddleDatabaseService; +import com.zc.business.utils.diff.Diff; +import com.zc.business.utils.diff.model.Result; +import com.zc.common.core.websocket.WebSocketService; +import org.junit.Test; +import org.apache.poi.ss.formula.functions.T; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.text.SimpleDateFormat; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -67,8 +78,13 @@ public class DcEventServiceImpl extends ServiceImpl impl //查询路网信息 @Autowired private DcFacilityServiceImpl dcFacilityService; + //事件处置记录 + @Autowired + private IDcEventProcessService dcEventProcessService; - + private final String HAPPEN = "发生"; + private final String EVENT = "事件"; + private final String SUBEVENT = "0"; /** * 查询事件信息 * @@ -121,6 +137,11 @@ public class DcEventServiceImpl extends ServiceImpl impl */ @Override public int insertDcEvent(DcEvent dcEvent) { + + String dcEventId =dcEvent.getId(); + + + //获取事件类型 int eventType = Math.toIntExact(dcEvent.getEventType()); @@ -131,7 +152,7 @@ public class DcEventServiceImpl extends ServiceImpl impl //获取部门信息 dcEvent.setDeptId(SecurityUtils.getDeptId()); //用户 - dcEvent.setUserId(SecurityUtils.getUserId()); + dcEvent.setUserId(SecurityUtils.getUserId()); dcEvent.setCreateTime(DateUtils.getNowDate()); @@ -170,11 +191,16 @@ public class DcEventServiceImpl extends ServiceImpl impl int i7 = dcEventMapper.insertDcEvent(dcEvent); + if (i7>0 && eventType != 3){ + extracted(dcEvent);//事件推送到 首页 + } if (i7 > 0) { - //中间库 - MdEvent mdEvent = new MdEvent(dcEvent); - middleDatabaseService.insertMiddleDatabaseEvent(mdEvent); +if (dcEvent.getDcEventTrafficControl().getFacilityIds().length<1 &&dcEventId == null){//非 事件处置 和收费站等多条数据添加 + //中间库 + MdEvent mdEvent = new MdEvent(dcEvent); + middleDatabaseService.insertMiddleDatabaseEvent(mdEvent); +} switch (eventType) { //交通事故 case 1: @@ -196,8 +222,149 @@ public class DcEventServiceImpl extends ServiceImpl impl //交通管制 case 3: if (dcEvent.getDcEventTrafficControl() != null) { - dcEvent.getDcEventTrafficControl().setId(uuid); - int i6 = dcEventTrafficControlMapper.insertDcEventTrafficControl(dcEvent.getDcEventTrafficControl()); + //TODO 插入多个收费站 + if (dcEvent.getDcEventTrafficControl().getFacilityIds().length==1){//facilityIds==1 说明只选择了一个收费站 + + if (dcEventId !=null){//不等于空 事件处置页面 修改 + dcEventMapper.deleteDcEventById(uuid);//删除添加的事件主类 + DcEvent dcEvent1 = new DcEvent(); + dcEvent1.setId(dcEventId);//事件id + dcEvent1.setEventNature(1l);//首发事件 + dcEvent1.setLinkId(uuid);//关联管制事件id + dcEventMapper.updateDcEventLinkId(dcEvent1);//修改事件性质 + dcEvent.getDcEventTrafficControl().setId(uuid); + dcEvent.getDcEventTrafficControl().setFacilityId(dcEvent.getDcEventTrafficControl().getFacilityIds()[0]);//取出数组字段赋值 设施id + int i6 = dcEventTrafficControlMapper.insertDcEventTrafficControl(dcEvent.getDcEventTrafficControl());// + }else { + //中间库 + MdEvent mdEvent = new MdEvent(dcEvent); + middleDatabaseService.insertMiddleDatabaseEvent(mdEvent); + extracted(dcEvent);//事件推送到 首页 + + dcEvent.getDcEventTrafficControl().setId(uuid); + dcEvent.getDcEventTrafficControl().setFacilityId(dcEvent.getDcEventTrafficControl().getFacilityIds()[0]);//取出数组字段赋值 设施id + int i6 = dcEventTrafficControlMapper.insertDcEventTrafficControl(dcEvent.getDcEventTrafficControl()); + } + + }else if (dcEvent.getDcEventTrafficControl().getFacilityIds().length>1){//facilityIds1=1 说明只选择了多个收费站 + + if (dcEventId !=null){//不等于空 事件处置页面 修改 + dcEventMapper.deleteDcEventById(uuid);//删除添加的事件主类 + DcEvent dcEvent1 = new DcEvent(); + dcEvent1.setId(dcEventId);//事件id + dcEvent1.setEventNature(1l);//首发事件 + Map map = new HashMap<>(); + for (int i = 0; i < dcEvent.getDcEventTrafficControl().getFacilityIds().length; i++) { //设置事件Id UUID无下划线格式32 + String facilityUUID = IdUtils.fastSimpleUUID(); + map.put("facilityId"+i,facilityUUID);//每循环一次生成一个uuid + } + StringBuilder sb2 = new StringBuilder(); + // 遍历map, + int a = 0; + for (Map.Entry entry : map.entrySet()) { + sb2.append(entry.getValue()); + if (dcEvent.getDcEventTrafficControl().getFacilityIds().length-a !=1){ + sb2.append(","); + } + a++; + } + String linkId2 = sb2.toString(); + dcEvent1.setLinkId(linkId2);//关联管制事件id + dcEventMapper.updateDcEventLinkId(dcEvent1);//修改事件性质 + for (int i = 0; i < dcEvent.getDcEventTrafficControl().getFacilityIds().length; i++) { + dcEvent.getDcEventTrafficControl().setId(map.get("facilityId"+i));//交通管制事件id + dcEvent.getDcEventTrafficControl().setFacilityId(dcEvent.getDcEventTrafficControl().getFacilityIds()[i]);//取出数组字段赋值 设施id + // 使用StringBuilder来构建逗号分隔的字符串 + + //新增第一条数据 + dcEvent.setId(map.get("facilityId" + i)); + dcEvent.setEventState(0L); + dcEvent.setDeptId(SecurityUtils.getDeptId()); + dcEvent.setUserId(SecurityUtils.getUserId()); + dcEvent.setCreateTime(DateUtils.getNowDate()); + dcEvent.setEventNature(2L);//关联管制 + + StringBuilder sb = new StringBuilder(); + // 遍历map,排除与当前索引i对应的键 + for (Map.Entry entry : map.entrySet()) { + if (!entry.getKey().equals("facilityId" + i)) { + if (sb.length() > 0) { + sb.append(","); + } + sb.append(entry.getValue()); + } + } + String linkId = sb.toString(); + dcEvent.setLinkId(linkId); + + //交通管制 + if (eventType == 3 && dcEvent.getDcEventTrafficControl().getFacilityIds()[i] != null) { + String facilityId = String.valueOf(dcEvent.getDcEventTrafficControl().getFacilityIds()[i]); + dcEvent.setStakeMark(extracted(facilityId)); + } + dcEventMapper.insertDcEvent(dcEvent); + extracted(dcEvent); + //中间库 + MdEvent mdEvent = new MdEvent(dcEvent); + middleDatabaseService.insertMiddleDatabaseEvent(mdEvent); + + int i6 = dcEventTrafficControlMapper.insertDcEventTrafficControl(dcEvent.getDcEventTrafficControl()); + + } + }else { + + dcEventMapper.deleteDcEventById(uuid);//删除添加的事件主类 + Map map = new HashMap<>(); + for (int i = 0; i < dcEvent.getDcEventTrafficControl().getFacilityIds().length; i++) { //设置事件Id UUID无下划线格式32 + String facilityUUID = IdUtils.fastSimpleUUID(); + map.put("facilityId"+i,facilityUUID);//每循环一次生成一个uuid + } + for (int i = 0; i < dcEvent.getDcEventTrafficControl().getFacilityIds().length; i++) { + + dcEvent.getDcEventTrafficControl().setId(map.get("facilityId" + i));//交通管制事件id + dcEvent.getDcEventTrafficControl().setFacilityId(dcEvent.getDcEventTrafficControl().getFacilityIds()[i]);//取出数组字段赋值 设施id + + //新增第一条数据 + dcEvent.setId(map.get("facilityId" + i)); + dcEvent.setEventState(0L); + dcEvent.setDeptId(SecurityUtils.getDeptId()); + dcEvent.setUserId(SecurityUtils.getUserId()); + dcEvent.setCreateTime(DateUtils.getNowDate()); + dcEvent.setEventNature(2L);//关联管制 + + // 使用StringBuilder来构建逗号分隔的字符串 + StringBuilder sb = new StringBuilder(); + + // 遍历map,排除与当前索引i对应的键 + for (Map.Entry entry : map.entrySet()) { + if (!entry.getKey().equals("facilityId" + i)) { + if (sb.length() > 0) { + sb.append(","); + } + sb.append(entry.getValue()); + } + } + + String linkId = sb.toString(); + dcEvent.setLinkId(linkId); + System.out.println(linkId); + + //交通管制 + if (eventType == 3 && dcEvent.getDcEventTrafficControl().getFacilityIds()[i] != null) { + String facilityId = String.valueOf(dcEvent.getDcEventTrafficControl().getFacilityIds()[i]); + dcEvent.setStakeMark(extracted(facilityId)); + } + //中间库 + MdEvent mdEvent = new MdEvent(dcEvent); + middleDatabaseService.insertMiddleDatabaseEvent(mdEvent); + + dcEventMapper.insertDcEvent(dcEvent); + extracted(dcEvent); + int i6 = dcEventTrafficControlMapper.insertDcEventTrafficControl(dcEvent.getDcEventTrafficControl()); + } + } + } + } break; //交通拥堵 @@ -253,6 +420,28 @@ public class DcEventServiceImpl extends ServiceImpl impl } } + /** + * 推送 事件信息 + * @param dcEvent + */ + private void extracted(DcEvent dcEvent) { + String direction = "";// 方向 + String EventSubclass = "";// 事件类型 + if (dcEvent.getDirection().equals("1")) { + direction="菏泽方向"; + }else { + direction="济南方向"; + } + for (EventSubclassEnum eventSubclass : EventSubclassEnum.values()) { + if (eventSubclass.getCode().equals(dcEvent.getEventSubclass())) { + EventSubclass=eventSubclass.getInfo(); + break; + } + } + String content= direction+" " + dcEvent.getStakeMark()+" "+HAPPEN+EventSubclass+EVENT ; + WebSocketService.broadcast(SUBEVENT, content); //推送事件消息 0不是感知事件 + } + //根据路网设施查询桩号 private String extracted(String facilityId) { DcFacility facility = dcFacilityService.getFacility(facilityId); @@ -342,6 +531,25 @@ public class DcEventServiceImpl extends ServiceImpl impl break; } + + //事件处置流程记录 + DcEventProcess dcEventProcess = new DcEventProcess(); + dcEventProcess.setEventId(dcEvent.getId()); + dcEventProcess.setOperationTime(new Date()); + dcEventProcess.setOperator(SecurityUtils.getUserId().toString()); + dcEventProcess.setSource(1); + List processConfigList = dcProcessConfigMapper.selectDcProcessConfigByEventType(dcEvent.getEventType().intValue()); + if (processConfigList != null && processConfigList.size() > 0){ + DcProcessConfig dcProcessConfig = processConfigList.get(0); + dcEventProcess.setProcessType(1); + dcEventProcess.setProcessId(Long.valueOf(dcProcessConfig.getNodeNode())); + dcEventProcess.setProcessName(dcProcessConfig.getProcessNode()); + } + String sourceName = ValueConverter.eventSourceName(dcEvent.getEventSource().toString()); + String typeName = ValueConverter.eventTypeName(dcEvent.getEventType().toString()); + dcEventProcess.setContext("由" + sourceName + "上报了一起" + typeName + "事件"); + dcEventProcessService.insertDcEventProcess(dcEventProcess); + return i7; } else { return -1; @@ -364,6 +572,8 @@ public class DcEventServiceImpl extends ServiceImpl impl if (flag) { //中间库 List mdEventList = new ArrayList<>(); + List dcEventProcessList = new ArrayList<>(); + for (DcEvent dcEvent : dcEventList) { MdEvent mdEvent = new MdEvent(dcEvent); mdEventList.add(mdEvent); @@ -433,8 +643,29 @@ public class DcEventServiceImpl extends ServiceImpl impl break; } + + //事件处置流程记录 + DcEventProcess dcEventProcess = new DcEventProcess(); + dcEventProcess.setEventId(dcEvent.getId()); + dcEventProcess.setOperationTime(new Date()); + dcEventProcess.setOperator(SecurityUtils.getUserId().toString()); + dcEventProcess.setSource(1); + List processConfigList = dcProcessConfigMapper.selectDcProcessConfigByEventType(dcEvent.getEventType().intValue()); + if (processConfigList != null && processConfigList.size() > 0){ + DcProcessConfig dcProcessConfig = processConfigList.get(0); + dcEventProcess.setProcessType(1); + dcEventProcess.setProcessId(Long.valueOf(dcProcessConfig.getNodeNode())); + dcEventProcess.setProcessName(dcProcessConfig.getProcessNode()); + } + String sourceName = ValueConverter.eventSourceName(dcEvent.getEventSource().toString()); + String typeName = ValueConverter.eventTypeName(dcEvent.getEventType().toString()); + dcEventProcess.setContext("由" + sourceName + "上报了一起" + typeName + "事件"); + dcEventProcessList.add(dcEventProcess); } middleDatabaseService.batchInsertMiddleDatabaseEvent(mdEventList); + + //批量插入事件流程记录表 + dcEventProcessService.batchInsertDcEventProcess(dcEventProcessList); } return flag; @@ -448,10 +679,24 @@ public class DcEventServiceImpl extends ServiceImpl impl */ @Override public int updateDcEvent(DcEvent dcEvent) { + DcEvent oldEvent = selectEventSubclassById(dcEvent.getEventType().intValue(),dcEvent.getId()); + dcEvent.setUpdateTime(DateUtils.getNowDate()); int i7 = dcEventMapper.updateDcEvent(dcEvent); if (i7 > 0) { + String context = comparisonInfo(oldEvent,dcEvent); + + //事件处置流程记录 + DcEventProcess dcEventProcess = new DcEventProcess(); + dcEventProcess.setEventId(dcEvent.getId()); + dcEventProcess.setOperationTime(new Date()); + dcEventProcess.setOperator(SecurityUtils.getUserId().toString()); + dcEventProcess.setSource(1); + dcEventProcess.setContext(context); + dcEventProcessService.insertDcEventProcess(dcEventProcess); + + //中间库 MdEvent mdEvent = new MdEvent(dcEvent); middleDatabaseService.updateMiddleDatabaseEvent(mdEvent); @@ -511,6 +756,8 @@ public class DcEventServiceImpl extends ServiceImpl impl } + + /** * 批量删除事件信息 * @@ -723,6 +970,33 @@ public class DcEventServiceImpl extends ServiceImpl impl return dcEvents; } + @Override + public int updateDcEventState(String id, int state) { + int i = dcEventMapper.updateDcEventState(id,state); + if (i > 0){ + DcEvent dcEvent = dcEventMapper.selectDcEventById(id); + + //事件处置流程记录 + DcEventProcess dcEventProcess = new DcEventProcess(); + dcEventProcess.setEventId(dcEvent.getId()); + dcEventProcess.setOperationTime(new Date()); + dcEventProcess.setOperator(SecurityUtils.getUserId().toString()); + dcEventProcess.setSource(1); + List processConfigList = dcProcessConfigMapper.selectDcProcessConfigByEventType(dcEvent.getEventType().intValue()); + if (processConfigList != null && processConfigList.size() > 0){ + DcProcessConfig dcProcessConfig = processConfigList.get(0); + dcEventProcess.setProcessType(1); + dcEventProcess.setProcessId(Long.valueOf(dcProcessConfig.getNodeNode())); + dcEventProcess.setProcessName(dcProcessConfig.getProcessNode()); + } + String sourceName = ValueConverter.eventSourceName(dcEvent.getEventSource().toString()); + String typeName = ValueConverter.eventTypeName(dcEvent.getEventType().toString()); + dcEventProcess.setContext("由" + sourceName + "上报了一起" + typeName + "事件"); + dcEventProcessService.insertDcEventProcess(dcEventProcess); + } + return i; + } + public static List castList(Object obj, Class clazz) { List result = new ArrayList(); if (obj instanceof List) { @@ -733,4 +1007,462 @@ public class DcEventServiceImpl extends ServiceImpl impl } return null; } + + /** + * @Description 事件信息比对 + * + * @author liuwenge + * @date 2024/4/10 16:24 + * @param oldEvent 旧数据 + * @param newEvent 新数据 + * @return java.lang.String + */ + public String comparisonInfo(DcEvent oldEvent,DcEvent newEvent){ + String context = ""; + if (oldEvent == null || newEvent == null){ + return context; + } + Diff diff = new Diff(); + List diffList = diff.diff(JSON.toJSON(oldEvent).toString(),JSON.toJSON(newEvent).toString()); + for (Result result : diffList) { + if ("ADD".equals(result.getDiffType()) || "MODIFY".equals(result.getDiffType())){ + if ("startTime".equals(result.getRightPath()) + || "endTime".equals(result.getRightPath()) + || "estimatedEndTime".equals(result.getRightPath()) + || "occurrenceTime".equals(result.getRightPath())){ + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + try { + Date date = new Date(); + date.setTime(Long.parseLong(result.getRight().toString())); + result.setRight(df.format(date));; + } catch (Exception e){ + e.printStackTrace(); + } + } else if ("direction".equals(result.getRightPath())){ + if ("1".equals(result.getRight())){ + result.setRight("上行"); + } else if ("2".equals(result.getRight())){ + result.setRight("中"); + } else if ("3".equals(result.getRight())){ + result.setRight("下行"); + } + } else if ("eventState".equals(result.getRightPath())){ + if ("0".equals(result.getRight())){ + result.setRight("待确认"); + } else if ("1".equals(result.getRight())){ + result.setRight("处理中"); + } else if ("2".equals(result.getRight())){ + result.setRight("已完成"); + } + } else if ("eventSource".equals(result.getRightPath())){ + result.setRight(ValueConverter.eventSourceName(result.getRight().toString())); + } else if ("lang".equals(result.getRightPath())){ + String langStr = ""; + String langArr[] = result.getRight().toString().split(","); + for (String lang : langArr) { + if ("1".equals(lang)){ + langStr = langStr + "行1,"; + } else if ("2".equals(lang)){ + langStr = langStr + "行2,"; + } else if ("3".equals(lang)){ + langStr = langStr + "行3,"; + } else if ("4".equals(lang)){ + langStr = langStr + "行4,"; + } else if ("0".equals(lang)){ + langStr = langStr + "应急车道,"; + } + } + if (langStr.length() > 0){ + langStr = langStr.substring(0,langStr.length() -1); + } + result.setRight(langStr); + } else if ("dcEventAbnormalWeather.weatherSituation".equals(result.getRightPath())){ + if ("1-1".equals(result.getRight())){ + result.setRight("雨雾"); + } else if ("1-2".equals(result.getRight())){ + result.setRight("雨雪"); + } else if ("1-3".equals(result.getRight())){ + result.setRight("中雨"); + } else if ("1-4".equals(result.getRight())){ + result.setRight("小雨"); + } else if ("1-5".equals(result.getRight())){ + result.setRight("大雨"); + } else if ("1-6".equals(result.getRight())){ + result.setRight("暴雨"); + } else if ("2-1".equals(result.getRight())){ + result.setRight("小雪"); + } else if ("2-2".equals(result.getRight())){ + result.setRight("中雪"); + } else if ("2-3".equals(result.getRight())){ + result.setRight("大雪"); + } else if ("2-4".equals(result.getRight())){ + result.setRight("暴雪"); + } else if ("2-5".equals(result.getRight())){ + result.setRight("大暴雪"); + } else if ("2-6".equals(result.getRight())){ + result.setRight("特大暴雪"); + } else if ("3-1".equals(result.getRight())){ + result.setRight("轻雾"); + } else if ("3-2".equals(result.getRight())){ + result.setRight("大雾"); + } else if ("3-3".equals(result.getRight())){ + result.setRight("浓雾"); + } else if ("3-4".equals(result.getRight())){ + result.setRight("强浓雾"); + } else if ("3-5".equals(result.getRight())){ + result.setRight("团雾"); + } + } else if ("dcEventAbnormalWeather.emergencyLevel".equals(result.getRightPath())){ + if ("1".equals(result.getRight())){ + result.setRight("一般"); + } else if ("2".equals(result.getRight())){ + result.setRight("紧急"); + } + } else if ("dcEventAccident.locationType".equals(result.getRightPath())){ + if ("1".equals(result.getRight())){ + result.setRight("高速主线"); + } else if ("2".equals(result.getRight())){ + result.setRight("服务区"); + } else if ("3".equals(result.getRight())){ + result.setRight("立交桥"); + } else if ("4".equals(result.getRight())){ + result.setRight("收费站"); + } + } else if ("dcEventAccident.weatherCondition".equals(result.getRightPath())){ + if ("1".equals(result.getRight())){ + result.setRight("晴"); + } else if ("2".equals(result.getRight())){ + result.setRight("雨"); + } else if ("3".equals(result.getRight())){ + result.setRight("雪"); + } else if ("4".equals(result.getRight())){ + result.setRight("雾"); + } else if ("5".equals(result.getRight())){ + result.setRight("其他"); + } + } else if ("dcEventAccident.impactLevel".equals(result.getRightPath())){ + if ("1".equals(result.getRight())){ + result.setRight("无"); + } else if ("2".equals(result.getRight())){ + result.setRight("危化品泄漏"); + } else if ("3".equals(result.getRight())){ + result.setRight("整车自燃"); + } else if ("4".equals(result.getRight())){ + result.setRight("车辆复燃"); + } else if ("5".equals(result.getRight())){ + result.setRight("散装人工倒货"); + } + } else if ("dcEventAccident.isReverseCargo".equals(result.getRightPath()) + || "dcEventAccident.isMaintenance".equals(result.getRightPath()) + || "dcEventAccident.congestionAhead".equals(result.getRightPath()) + || "dcEventAccident.atIntersection".equals(result.getRightPath()) + || "dcEventAccident.onCurve".equals(result.getRightPath()) + || "dcEventAccident.isPrivate".equals(result.getRightPath()) + || "dcEventVehicleAccident.congestionAhead".equals(result.getRightPath()) + || "dcEventVehicleAccident.atIntersection".equals(result.getRightPath()) + || "dcEventVehicleAccident.onCurve".equals(result.getRightPath()) + || "dcEventVehicleAccident.isPrivate".equals(result.getRightPath())){ + if ("0".equals(result.getRight())){ + result.setRight("否"); + } else if ("1".equals(result.getRight())){ + result.setRight("是"); + } + } else if ("dcEventConstruction.controlMode".equals(result.getRightPath())){ + if ("1".equals(result.getRight())){ + result.setRight("封闭"); + } else if ("2".equals(result.getRight())){ + result.setRight("不封闭"); + } + } else if ("dcEventConstruction.locationType".equals(result.getRightPath())){ + if ("1".equals(result.getRight())){ + result.setRight("单点"); + } else if ("2".equals(result.getRight())){ + result.setRight("多点"); + } + } else if ("dcEventConstruction.specialConstruction".equals(result.getRightPath())){ + if ("1".equals(result.getRight())){ + result.setRight("专项工程施工"); + } else if ("2".equals(result.getRight())){ + result.setRight("改扩建专项工程施工"); + } else if ("3".equals(result.getRight())){ + result.setRight("桥梁专项工程施工"); + } else if ("4".equals(result.getRight())){ + result.setRight("其他专项工程施工"); + } + } else if ("dcEventConstruction.constructionMeasurement".equals(result.getRightPath())){ + if ("0".equals(result.getRight())){ + result.setRight("无"); + } else if ("1".equals(result.getRight())){ + result.setRight("并道行驶"); + } else if ("2".equals(result.getRight())){ + result.setRight("临时保通"); + } else if ("3".equals(result.getRight())){ + result.setRight("借路侧服务区通行"); + } + } else if ("dcEventConstruction.exitsInlets".equals(result.getRightPath()) + || "dcEventServiceArea.exitsInlets".equals(result.getRightPath()) + || "dcEventTrafficControl.exitsInlets".equals(result.getRightPath())){ + if ("1".equals(result.getRight())){ + result.setRight("出口"); + } else if ("2".equals(result.getRight())){ + result.setRight("入口"); + } + } else if ("dcEventConstruction.trafficCondition".equals(result.getRightPath())){ + if ("1".equals(result.getRight())){ + result.setRight("通行正常"); + } else if ("2".equals(result.getRight())){ + result.setRight("通行受阻"); + } + } else if ("dcEventServiceArea.disableFacility".equals(result.getRightPath())){ + if ("1".equals(result.getRight())){ + result.setRight("卫生间"); + } else if ("2".equals(result.getRight())){ + result.setRight("餐厅"); + } else if ("3".equals(result.getRight())){ + result.setRight("停车场"); + } else if ("4".equals(result.getRight())){ + result.setRight("加油站"); + } else if ("5".equals(result.getRight())){ + result.setRight("充电桩"); + } + } else if ("dcEventTrafficCongestion.congestionCause".equals(result.getRightPath())){ + if ("1".equals(result.getRight())){ + result.setRight("车流量大"); + } else if ("2".equals(result.getRight())){ + result.setRight("交通事故"); + } else if ("3".equals(result.getRight())){ + result.setRight("恶劣天气"); + } else if ("4".equals(result.getRight())){ + result.setRight("施工"); + } else if ("5".equals(result.getRight())){ + result.setRight("其他"); + } + } else if ("dcEventTrafficCongestion.location".equals(result.getRightPath())){ + if ("1".equals(result.getRight())){ + result.setRight("入口"); + } else if ("2".equals(result.getRight())){ + result.setRight("出口"); + } else if ("3".equals(result.getRight())){ + result.setRight("入口内广场"); + } else if ("4".equals(result.getRight())){ + result.setRight("出口内广场"); + } else if ("5".equals(result.getRight())){ + result.setRight("外广场"); + } else if ("6".equals(result.getRight())){ + result.setRight("入口车道"); + } else if ("7".equals(result.getRight())){ + result.setRight("出口车道"); + } else if ("8".equals(result.getRight())){ + result.setRight("入口匝道"); + } else if ("9".equals(result.getRight())){ + result.setRight("出口匝道"); + } + } else if ("dcEventTrafficCongestion.locationType".equals(result.getRightPath()) + || "dcEventVehicleAccident.locationType".equals(result.getRightPath())){ + if ("1".equals(result.getRight())){ + result.setRight("高速主线"); + } else if ("2".equals(result.getRight())){ + result.setRight("服务区"); + } else if ("3".equals(result.getRight())){ + result.setRight("立交桥"); + } else if ("4".equals(result.getRight())){ + result.setRight("收费站"); + } + } else if ("dcEventTrafficCongestion.weatherCondition".equals(result.getRightPath())){ + if ("1".equals(result.getRight())){ + result.setRight("晴"); + } else if ("2".equals(result.getRight())){ + result.setRight("雨"); + } else if ("3".equals(result.getRight())){ + result.setRight("雪"); + } else if ("4".equals(result.getRight())){ + result.setRight("雾"); + } else if ("5".equals(result.getRight())){ + result.setRight("其他"); + } + } else if ("dcEventTrafficControl.controlType".equals(result.getRightPath())){ + if ("1".equals(result.getRight())){ + result.setRight("封闭"); + } else if ("2".equals(result.getRight())){ + result.setRight("限行"); + } + } else if ("dcEventTrafficControl.controlCause".equals(result.getRightPath())){ + if ("1".equals(result.getRight())){ + result.setRight("车流量大"); + } else if ("2".equals(result.getRight())){ + result.setRight("交通事故"); + } else if ("3".equals(result.getRight())){ + result.setRight("恶劣天气"); + } else if ("4".equals(result.getRight())){ + result.setRight("施工"); + } else if ("5".equals(result.getRight())){ + result.setRight("警备任务"); + } else if ("6".equals(result.getRight())){ + result.setRight("其他"); + } + } else if ("dcEventTrafficControl.causeType".equals(result.getRightPath())){ + if ("3-1".equals(result.getRight())){ + result.setRight("雨"); + } else if ("3-2".equals(result.getRight())){ + result.setRight("雪"); + } else if ("3-3".equals(result.getRight())){ + result.setRight("雾"); + } else if ("3-4".equals(result.getRight())){ + result.setRight("道路积水"); + } else if ("3-5".equals(result.getRight())){ + result.setRight("道路湿滑"); + } else if ("3-6".equals(result.getRight())){ + result.setRight("道路结冰"); + } else if ("3-7".equals(result.getRight())){ + result.setRight("沙尘暴"); + } else if ("4-1".equals(result.getRight())){ + result.setRight("专项工程施工"); + } else if ("4-2".equals(result.getRight())){ + result.setRight("改扩建工程施工"); + } else if ("4-3".equals(result.getRight())){ + result.setRight("其他施工"); + } + } else if ("dcEventTrafficControl.measure".equals(result.getRightPath())){ + if ("1".equals(result.getRight())){ + result.setRight("临时关闭"); + } else if ("2".equals(result.getRight())){ + result.setRight("限行车辆"); + } else if ("3".equals(result.getRight())){ + result.setRight("限行车道"); + } else if ("4".equals(result.getRight())){ + result.setRight("限行车道且限行车辆"); + } else if ("5".equals(result.getRight())){ + result.setRight("间隔放行"); + } else if ("6".equals(result.getRight())){ + result.setRight("并道行驶"); + } else if ("7".equals(result.getRight())){ + result.setRight("限速"); + } + } else if ("dcEventTrafficControl.classify".equals(result.getRightPath())){ + if ("1".equals(result.getRight())){ + result.setRight("主线关闭"); + } else if ("2".equals(result.getRight())){ + result.setRight("主线限行"); + } else if ("3".equals(result.getRight())){ + result.setRight("主线间隔放行"); + } else if ("4".equals(result.getRight())){ + result.setRight("主线并道"); + } else if ("5".equals(result.getRight())){ + result.setRight("主线限速"); + } + } else if ("dcEventTrafficControl.limitedType".equals(result.getRightPath())){ + if ("1".equals(result.getRight())){ + result.setRight("只允许"); + } else if ("2".equals(result.getRight())){ + result.setRight("禁止"); + } + } + String label = ValueConverter.eventLabel(result.getRightPath()); + context = context + label + "修改为:" + result.getRight() + ","; + } + } + + if (context.length() > 0){ + context = context.substring(0,context.length() -1); + } + + + return context; + } + + + /** + * @Description 查询事件流程状态 + * + * @author liuwenge + * @date 2024/4/11 11:19 + * @param eventId 事件id + * @return com.ruoyi.common.core.domain.AjaxResult + */ + @Override + public AjaxResult getProcessNode(String eventId){ + List> processNode = dcEventMapper.getProcessNode(eventId); + return AjaxResult.success(processNode); + } + + /** + * @Description 解除事件 + * + * @author liuwenge + * @date 2024/4/11 14:13 + * @param eventId + * @return com.ruoyi.common.core.domain.AjaxResult + */ + @Override + public AjaxResult completeEvent(String eventId){ + boolean flag = dcEventMapper.completeEvent(eventId); + if (flag){ + DcEvent dcEvent = dcEventMapper.selectDcEventById(eventId); + + String datePoor = getDatePoor(dcEvent.getEndTime(),dcEvent.getStartTime()); + + //事件处置流程记录 + DcEventProcess dcEventProcess = new DcEventProcess(); + dcEventProcess.setEventId(eventId); + dcEventProcess.setOperationTime(new Date()); + dcEventProcess.setOperator(SecurityUtils.getUserId().toString()); + dcEventProcess.setSource(1); + + dcEventProcess.setContext("事件解除,处置完毕,处置时长:" + datePoor); + dcEventProcessService.insertDcEventProcess(dcEventProcess); + return AjaxResult.success("解除事件成功"); + } + return AjaxResult.error("解除事件失败"); + } + + /** + * @Description 无需清障 + * + * @author liuwenge + * @date 2024/4/11 14:13 + * @param eventId + * @return com.ruoyi.common.core.domain.AjaxResult + */ + @Override + public AjaxResult skipClear(String eventId){ + + //事件处置流程记录 + DcEventProcess dcEventProcess = new DcEventProcess(); + dcEventProcess.setEventId(eventId); + dcEventProcess.setOperationTime(new Date()); + dcEventProcess.setOperator(SecurityUtils.getUserId().toString()); + dcEventProcess.setSource(1); + dcEventProcess.setProcessType(1); + dcEventProcess.setProcessId(6L); + dcEventProcess.setProcessName("清障结束"); + + dcEventProcess.setContext("选择不需要清障"); + dcEventProcessService.insertDcEventProcess(dcEventProcess); + return AjaxResult.success("无需清障成功"); + } + + //时间比对 + public static String getDatePoor(Date endDate, Date nowDate) { + + long nd = 1000 * 24 * 60 * 60; + long nh = 1000 * 60 * 60; + long nm = 1000 * 60; + long ns = 1000; + + // 获得两个时间的毫秒时间差异 + long diff = endDate.getTime() - nowDate.getTime(); + + // 计算差多少天 + long day = diff / nd; + // 计算差多少小时 + long hour = diff % nd / nh; + // 计算差多少分钟 + long min = diff % nd % nh / nm; + // 计算差多少秒//输出结果 + long sec = diff % nd % nh % nm / ns; + + return day + "天" + hour + "小时" + min + "分钟" + sec + "秒"; + + } + } diff --git a/zc-business/src/main/java/com/zc/business/service/impl/DcWarningServiceImpl.java b/zc-business/src/main/java/com/zc/business/service/impl/DcWarningServiceImpl.java index db0e0729..f50f740a 100644 --- a/zc-business/src/main/java/com/zc/business/service/impl/DcWarningServiceImpl.java +++ b/zc-business/src/main/java/com/zc/business/service/impl/DcWarningServiceImpl.java @@ -1,6 +1,7 @@ package com.zc.business.service.impl; + import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.utils.DateUtils; @@ -11,11 +12,13 @@ import com.zc.business.domain.DcWaringStrategy; import com.zc.business.domain.DcWarning; import com.zc.business.domain.DcWarningBatchConvert; import com.zc.business.enums.ValueConverter; +import com.zc.business.enums.WarningSubclassEnum; import com.zc.business.mapper.DcEventMapper; import com.zc.business.mapper.DcWarningMapper; import com.zc.business.service.IDcEventService; import com.zc.business.service.IDcWarningService; import com.zc.business.utils.StakeMarkUtils; +import com.zc.common.core.websocket.WebSocketService; import org.apache.commons.lang3.StringUtils; import org.json.JSONArray; import org.json.JSONObject; @@ -49,7 +52,9 @@ public class DcWarningServiceImpl implements IDcWarningService private IDcEventService dcEventService; @Resource private RedisCache redisCache; - + private final String HAPPEN = "发生"; + private final String EVENT = "事件"; + private final String SUBEVENT = "1"; private static final String WARNINGSTRATEGY = "warningStrategy";//redis策略缓存的key private static final String WARNINGDATA = "warningData:";//redis事件缓存的key private static String JUDGE = "1"; //自定义判断参数,1为满足0为不满足 @@ -125,6 +130,10 @@ public class DcWarningServiceImpl implements IDcWarningService dcWarning.setEndTime(DateUtils.getObtainDateAfter(Integer.parseInt(strategyTime)));//注入过期时间 if (dataId==null){//如果不存在直接加入数据库,加入缓存,配置对应的缓存过期时间以及数据库过期时间 int insertDcWarning = dcWarningMapper.insertDcWarning(dcWarning);//加入数据库 + //事件推送至 Websocket + extracted(dcWarning); + + if (insertDcWarning==0){ return 0; } @@ -138,6 +147,8 @@ public class DcWarningServiceImpl implements IDcWarningService redisCache.deleteObject(WARNINGDATA+key); String id = dcWarning.getId(); redisCache.setCacheObject(WARNINGDATA+key,id,Integer.parseInt(strategyTime),TimeUnit.MINUTES); + //事件推送至 Websocket + extracted(dcWarning); return dcWarningMapper.insertDcWarning(dcWarning); } String otherConfig=""; @@ -166,9 +177,33 @@ public class DcWarningServiceImpl implements IDcWarningService redisCache.setCacheObject(WARNINGDATA+key,dataId,Integer.parseInt(strategyTime),TimeUnit.MINUTES);//重新设置延迟时间 return dcWarningMapper.updateOtherConfig(dataId, jsonObject.toString(),dcWarning.getEndTime());//修改数据库配置 } + //事件推送至 Websocket + extracted(dcWarning); return dcWarningMapper.insertDcWarning(dcWarning);//如果没有配置策略直接加入数据库; } + /** + * 事件推送至 Websocket + * @param dcWarning + */ + private void extracted(DcWarning dcWarning) { + String direction = "";// 方向 + String EventSubclass = "";// 事件类型 + if (dcWarning.getDirection().equals("1")) { + direction="菏泽方向"; + }else { + direction="济南方向"; + } + for (WarningSubclassEnum eventSubclass : WarningSubclassEnum.values()) { + if (eventSubclass.getCode().equals(dcWarning.getWarningSubclass())) { + EventSubclass=eventSubclass.getInfo(); + break; + } + } + String content= direction+" " + dcWarning.getStakeMark()+" "+HAPPEN+EventSubclass+EVENT ; + WebSocketService.broadcast(SUBEVENT, content); //推送事件消息 0不是感知事件 + } + //优先级策略(还差优先级策略需要配置) // public int priority(DcWarning dcWarning){ // dcWarning.setCreateTime(DateUtils.getNowDate()); diff --git a/zc-business/src/main/java/com/zc/business/utils/PoiUtil.java b/zc-business/src/main/java/com/zc/business/utils/PoiUtil.java index e799f2ef..5727021c 100644 --- a/zc-business/src/main/java/com/zc/business/utils/PoiUtil.java +++ b/zc-business/src/main/java/com/zc/business/utils/PoiUtil.java @@ -5,6 +5,7 @@ import com.google.common.base.Strings; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellReference; +import org.apache.poi.util.Units; import org.apache.poi.xddf.usermodel.chart.XDDFChartData; import org.apache.poi.xddf.usermodel.chart.XDDFDataSource; import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory; @@ -18,10 +19,8 @@ import org.springframework.util.StringUtils; import java.io.*; import java.math.BigInteger; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.Map.Entry; /** * @author : LCheng @@ -30,8 +29,6 @@ import java.util.Map; */ public class PoiUtil { - public static int headingCount1 = 1; - public static int headingCount2 = 1; /** * 根据word模板导出 针对图表(柱状图,折线图,饼图等)的处理 @@ -365,5 +362,212 @@ public class PoiUtil { tocField.setInstr(tocFieldCode); tocField.setDirty(STOnOff.TRUE); } + + + /** + * 替换段落文本 + * @param document docx解析对象 + * @param textMap 需要替换的信息集合 + */ + public static void changeText(XWPFDocument document, Map textMap){ + //获取段落集合 + + + // 获取段落集合 + Iterator iterator = document.getParagraphsIterator(); + XWPFParagraph paragraph = null; + while (iterator.hasNext()) { + paragraph = iterator.next(); + // 判断此段落是否需要替换 + if (checkText(paragraph.getText())) { + replaceValue(paragraph, textMap); + } + } + } + + /*** + * @Description :检查文本中是否包含指定的字符(此处为“$”) + * @param text + * @return boolean + * @Date 2022/11/17 17:22 + */ + public static boolean checkText(String text) { + boolean check = false; + if (text.contains("$")) { + check = true; + } + return check; + } + + /** + * 替换图片 + * + * @param document + * @param picData + * @throws Exception + */ + + public static void changePic(XWPFDocument document, Map picData) throws Exception { + // 获取段落集合 + Iterator iterator = document.getParagraphsIterator(); + XWPFParagraph paragraph; + while (iterator.hasNext()) { + paragraph = iterator.next(); + // 判断此段落是否需要替换 + String text = paragraph.getText(); + if (checkText(text)) { + replacePicValue(paragraph, picData); + } + } + } + + /*** + * @Description :替换表格内的文字 + * @param document + * @param data + * @return void + * @Date 2022/11/18 11:29 + */ + public static void changeTableText(XWPFDocument document, Map data) { + // 获取文件的表格 + Iterator tableList = document.getTablesIterator(); + XWPFTable table; + List rows; + List cells; + // 循环所有需要进行替换的文本,进行替换 + while (tableList.hasNext()) { + table = tableList.next(); + if (checkText(table.getText())) { + rows = table.getRows(); + // 遍历表格,并替换模板 + for (XWPFTableRow row : rows) { + cells = row.getTableCells(); + for (XWPFTableCell cell : cells) { + // 判断单元格是否需要替换 + if (checkText(cell.getText())) { + List paragraphs = cell.getParagraphs(); + for (XWPFParagraph paragraph : paragraphs) { + replaceValue(paragraph, data); + } + } + } + } + } + } + } + + /*** + * @Description :替换表格内图片 + * @param document + * @param picData + * @return void + * @Date 2022/11/18 11:29 + */ + public static void changeTablePic(XWPFDocument document, Map picData) throws Exception { + // 获取文件的表格 + Iterator tableList = document.getTablesIterator(); + XWPFTable table; + List rows; + List cells; + // 循环所有需要进行替换的文本,进行替换 + while (tableList.hasNext()) { + table = tableList.next(); + if (checkText(table.getText())) { + rows = table.getRows(); + // 遍历表格,并替换模板 + for (XWPFTableRow row : rows) { + cells = row.getTableCells(); + for (XWPFTableCell cell : cells) { + // 判断单元格是否需要替换 + if (checkText(cell.getText())) { + List paragraphs = cell.getParagraphs(); + for (XWPFParagraph paragraph : paragraphs) { + replacePicValue(paragraph, picData); + } + } + } + } + } + } + } + + /*** + * @Description :替换内容 + * @param paragraph + * @param textMap + * @return void + * @Date 2022/11/18 11:33 + */ + public static void replaceValue(XWPFParagraph paragraph, Map textMap) { + XWPFRun run, nextRun; + String runsText; + List runs = paragraph.getRuns(); + for (int i = 0; i < runs.size(); i++) { + run = runs.get(i); + runsText = run.getText(0); + if (runsText.contains("${") || (runsText.contains("$") && runs.get(i + 1).getText(0).substring(0, 1).equals("{"))) { + while (!runsText.contains("}")) { + nextRun = runs.get(i + 1); + runsText = runsText + nextRun.getText(0); + //删除该节点下的数据 + paragraph.removeRun(i + 1); + } + Object value = changeValue(runsText, textMap); + //判断key在Map中是否存在 + if (textMap.containsKey(runsText)) { + if (value != null) { + run.setText(value.toString(), 0); + } else { + run.setText("", 0); + } + } else { + //如果匹配不到,则不修改 + run.setText(runsText, 0); + } + } + } + } + + /*** + * @Description :替换图片内容 + * @param paragraph + * @param picData + * @return void + * @Date 2022/11/18 11:33 + */ + public static void replacePicValue(XWPFParagraph paragraph, Map picData) throws Exception { + List runs = paragraph.getRuns(); + for (XWPFRun run : runs) { + Object value = changeValue(run.toString(), picData); + if (picData.containsKey(run.toString())) { + //清空内容 + run.setText("", 0); + FileInputStream is = new FileInputStream((String) value); + //图片宽度、高度 + int width = Units.toEMU(100), height = Units.toEMU(100); + //添加图片信息,段落高度需要在模板中自行调整 + run.addPicture(is, XWPFDocument.PICTURE_TYPE_PNG, (String) value, width, height); + } + } + } + + /*** + * @Description :匹配参数 + * @param value + * @param textMap + * @return java.lang.Object + * @Date 2022/11/18 11:33 + */ + public static Object changeValue(String value, Map textMap) { + Object valu = ""; + for (Map.Entry textSet : textMap.entrySet()) { + // 匹配模板与替换值 格式${key} + String key = textSet.getKey(); + if (value.contains(key)) { + valu = textSet.getValue(); + } + } + return valu; + } } diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/AlgorithmEnum.java b/zc-business/src/main/java/com/zc/business/utils/diff/AlgorithmEnum.java new file mode 100644 index 00000000..f9391273 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/AlgorithmEnum.java @@ -0,0 +1,82 @@ +package com.zc.business.utils.diff; + +import com.zc.business.utils.diff.algorithm.AlgorithmModule; +import com.zc.business.utils.diff.algorithm.array.SimilarArrayComparator; +import com.zc.business.utils.diff.algorithm.array.SimpleArrayComparator; +import com.zc.business.utils.diff.algorithm.nulls.DefaultNullComparator; +import com.zc.business.utils.diff.algorithm.object.LeftJoinObjectComparator; +import com.zc.business.utils.diff.algorithm.object.SimpleObjectComparator; +import com.zc.business.utils.diff.algorithm.other.DefaultOtherComparator; +import com.zc.business.utils.diff.algorithm.primitive.DefaultPrimitiveComparator; + +/** + * 算法模型枚举类:提供一些默认实现的算法模型 + * @Author JingWei + * @create 2022/3/2 + */ +public enum AlgorithmEnum { + + /** + * 默认的比较算法模型 + */ + DEFAULT(defaultAlgorithmModule()), + + /** + * 数组比较采用Simple,对象比较采用Simple + */ + SIMPLE_ARRAY_AND_SIMPLE_OBJECT(simpleAndSimpleAlgorithmModule()), + + /** + * 数组比较采用Simple,对象比较采用LeftJoin + */ + SIMPLE_ARRAY_AND_LEFTJOIN_OBJECT(simpleAndLeftJoinAlgorithmModule()), + + /** + * 数组比较采用Similar,对象比较采用LeftJoin + */ + SIMLAR_ARRAY_AND_LEFTJOIN_OBJECT(similarAndLeftJoinAlgorithmModule()), + + /** + * 数组比较采用Similar,对象比较采用Simple + */ + MOST_COMMONLY_USED(similarAndSimpleAlgorithmModule()); + + final private AlgorithmModule algorithmModule; + + AlgorithmEnum(AlgorithmModule algorithmModule) { + this.algorithmModule = algorithmModule; + } + + + public AlgorithmModule getAlgorithmModule() { + return algorithmModule; + } + + private static AlgorithmModule defaultAlgorithmModule() { + return new AlgorithmModule(new SimpleObjectComparator(), new SimilarArrayComparator(), + new DefaultPrimitiveComparator(), new DefaultNullComparator(), new DefaultOtherComparator()); + + } + + private static AlgorithmModule simpleAndSimpleAlgorithmModule() { + return new AlgorithmModule(new SimpleObjectComparator(), new SimpleArrayComparator(), + new DefaultPrimitiveComparator(), new DefaultNullComparator(), new DefaultOtherComparator()); + } + + + private static AlgorithmModule simpleAndLeftJoinAlgorithmModule() { + return new AlgorithmModule(new LeftJoinObjectComparator(), new SimpleArrayComparator(), + new DefaultPrimitiveComparator(), new DefaultNullComparator(), new DefaultOtherComparator()); + } + + private static AlgorithmModule similarAndLeftJoinAlgorithmModule() { + return new AlgorithmModule(new LeftJoinObjectComparator(), new SimilarArrayComparator(), + new DefaultPrimitiveComparator(), new DefaultNullComparator(), new DefaultOtherComparator()); + } + + private static AlgorithmModule similarAndSimpleAlgorithmModule() { + return new AlgorithmModule(new SimpleObjectComparator(), new SimilarArrayComparator(), + new DefaultPrimitiveComparator(), new DefaultNullComparator(), new DefaultOtherComparator()); + } + +} \ No newline at end of file diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/Diff.java b/zc-business/src/main/java/com/zc/business/utils/diff/Diff.java new file mode 100644 index 00000000..638b8ee9 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/Diff.java @@ -0,0 +1,208 @@ +package com.zc.business.utils.diff; + +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.zc.business.utils.diff.algorithm.AlgorithmModule; +import com.zc.business.utils.diff.algorithm.array.ArrayComparator; +import com.zc.business.utils.diff.algorithm.array.SimilarArrayComparator; +import com.zc.business.utils.diff.algorithm.nulls.DefaultNullComparator; +import com.zc.business.utils.diff.algorithm.nulls.NullComparator; +import com.zc.business.utils.diff.algorithm.object.ObjectComparator; +import com.zc.business.utils.diff.algorithm.object.SimpleObjectComparator; +import com.zc.business.utils.diff.algorithm.other.DefaultOtherComparator; +import com.zc.business.utils.diff.algorithm.other.OtherComparator; +import com.zc.business.utils.diff.algorithm.primitive.DefaultPrimitiveComparator; +import com.zc.business.utils.diff.algorithm.primitive.PrimitiveComparator; +import com.zc.business.utils.diff.model.DiffContext; +import com.zc.business.utils.diff.model.PathModule; +import com.zc.business.utils.diff.model.Result; +import com.zc.business.utils.diff.model.ResultConvertUtil; + +import java.util.List; + +/** + * DIFF入口,用于比较两个Json字符串 + * @Author JingWei + * @create 2022/2/25 + */ +public class Diff { + /** + * 算法模型。根据传入的算法模型使用该算法模型进行diff比较。 + */ + private AlgorithmEnum algorithmEnum; + /** + * 特殊路径集合。当前路径符合特殊路径且特殊路径下比较结果相同,会在返回结果中做额外标识标识。 + */ + private List specialPath; + /** + * 噪音字段集合。如果当前路径符合噪音字段路径,则不会比较。 + */ + private List noisePahList; + /** + * 以下为5种可以自定义的比较器,条件是algorithmEnum为空(如果algorithmEnum有值,直接使用algorithmEnum对应算法模型,比较器不生效) + */ + private ObjectComparator objectComparator; + private ArrayComparator arrayComparator; + private PrimitiveComparator primitiveComparator; + private NullComparator nullComparator; + private OtherComparator otherComparator; + + + /** + * @param a 要比较的第一个JsonElement + * @param b 要比较的第二个JsonElement + * @return 用来展示的diff结果 + */ + public List diffElement(JsonElement a, JsonElement b) { + DiffContext diffContext; + //用噪音路径和自定义路径构造路径模型 + PathModule pathModule = new PathModule(noisePahList, specialPath); + //如果有算法模型直接使用算法模型 + if(algorithmEnum != null){ + diffContext = algorithmEnum.getAlgorithmModule().diffElement(a, b, pathModule); + }//如果也没有比较器,直接用默认算法模型 + else if(objectComparator == null && arrayComparator == null && primitiveComparator == null && nullComparator == null && otherComparator == null){ + diffContext = AlgorithmEnum.DEFAULT.getAlgorithmModule().diffElement(a, b, pathModule); + }//如果有比较器,为空的比较器用默认替换,然后构造算法模型, + else { + constrcutDefaultComparator(); + diffContext = new AlgorithmModule(objectComparator, arrayComparator, primitiveComparator, nullComparator, otherComparator).diffElement(a, b, pathModule); + } + return ResultConvertUtil.constructResult(diffContext); + } + + /** + * @param strA 要比较的第一个字符串 + * @param strB 要比较的第二个字符串 + * @return 用来展示的diff结果 + */ + public List diff(String strA, String strB) { + return diffElement(new JsonParser().parse(strA), new JsonParser().parse(strB)); + } + + public Diff() { + } + + /** + * 没有初始的比较器替换成默认的 + */ + private void constrcutDefaultComparator() { + //如果没有初始化算法,则采用默认的算法。 + if(objectComparator == null){ + objectComparator = defaultObjectComparator(); + } + if(arrayComparator == null){ + arrayComparator = defaultArrayComparator(); + } + if(primitiveComparator == null){ + primitiveComparator = defaultPrimitiveComparator(); + } + if(nullComparator == null){ + nullComparator = defaultNullComparator(); + } + if(otherComparator == null){ + otherComparator = defaultOtherComparator(); + } + } + + private ObjectComparator defaultObjectComparator() { + return new SimpleObjectComparator(); + } + + private ArrayComparator defaultArrayComparator() { + return new SimilarArrayComparator(); + } + + private PrimitiveComparator defaultPrimitiveComparator() { + return new DefaultPrimitiveComparator(); + } + + private NullComparator defaultNullComparator() { + return new DefaultNullComparator(); + } + + private OtherComparator defaultOtherComparator() { + return new DefaultOtherComparator(); + } + + /** + * 选择算法模型 + * @param algorithmEnum 算法模型枚举类 + * @return 对象本身 + */ + public Diff withAlgorithmEnum(AlgorithmEnum algorithmEnum){ + this.algorithmEnum = algorithmEnum; + return this; + } + + /** + * 设置自定义路径 + * @param specialPath 自定义路径列表 + * @return 对象本身 + */ + public Diff withSpecialPath(List specialPath){ + this.specialPath = specialPath; + return this; + } + + /** + * 设置噪音路径 + * @param noisePahList 噪音路径列表 + * @return 对象本身 + */ + public Diff withNoisePahList(List noisePahList){ + this.noisePahList = noisePahList; + return this; + } + + /** + * 自定义对象比较器 + * @param objectComparator 对象比较器 + * @return 对象本身 + */ + public Diff withObjectComparator(ObjectComparator objectComparator) { + this.objectComparator = objectComparator; + return this; + } + + /** + * 自定义数组比较器 + * @param arrayComparator 数组比较器 + * @return 对象本身 + */ + public Diff withArrayComparator(ArrayComparator arrayComparator) { + this.arrayComparator = arrayComparator; + return this; + } + + + /** + * 自定义基本类型比较器 + * @param primitiveComparator 基本类型比较器 + * @return 对象本身 + */ + public Diff withPrimitiveAlgorithm(PrimitiveComparator primitiveComparator) { + this.primitiveComparator = primitiveComparator; + return this; + } + + /** + * 自定义空类型比较器 + * @param nullComparator 空类型比较器 + * @return 对象本身 + */ + public Diff withNullComparator(NullComparator nullComparator) { + this.nullComparator = nullComparator; + return this; + } + + /** + * 自定义其他类型比较器 + * @param otherComparator 其他类型比较器 + * @return 对象本身 + */ + public Diff withOtheComparator(OtherComparator otherComparator) { + this.otherComparator = otherComparator; + return this; + } +} diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/AbstractObjectAndArray.java b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/AbstractObjectAndArray.java new file mode 100644 index 00000000..64670d1c --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/AbstractObjectAndArray.java @@ -0,0 +1,49 @@ +package com.zc.business.utils.diff.algorithm; + +import com.google.gson.JsonElement; +import com.zc.business.utils.diff.model.Constants; +import com.zc.business.utils.diff.model.DiffContext; +import com.zc.business.utils.diff.model.PathModule; +import com.zc.business.utils.diff.model.SingleNodeDifference; + +/** + * 数组和对象比较的公有方法抽象类 + * @Author JingWei + * @create 2022/3/1 + */ +public abstract class AbstractObjectAndArray { + protected AlgorithmModule algorithmModule; + + /** + * diff算法比较核心方法,比较2个JsonElement的入口。 + * @param a 比较的第一个JsonElement + * @param b 比较的第二个JsonElement + * @param pathModule 路径模型 + * @return 不同的比较结果 + */ + public DiffContext diffElement(JsonElement a, JsonElement b, PathModule pathModule) { + return algorithmModule.diffElement(a, b, pathModule); + } + + /** + * 构造算法模型,比如使用对象和数组类型算法比较时,内部会用到其他类型的算法。 + * @param algorithmModule 算法模型 + */ + public void constructAlgorithmModule(AlgorithmModule algorithmModule) { + this.algorithmModule = algorithmModule; + } + + /** + * 如果下层diff结果不同,会把下层diff结果加入到上层diff结果中去。 + * @param parentResult 上层结果 + * @param childResult 下层结果 + */ + public void parentContextAddChildContext(DiffContext parentResult, DiffContext childResult) { + if(childResult.isSame() == Constants.DIFFERENT) { + for (SingleNodeDifference singleNodeDifference : childResult.getDiffResultModels()) { + parentResult.getDiffResultModels().add(singleNodeDifference); + } + parentResult.setSame(false); + } + } +} \ No newline at end of file diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/AbstractPrimitiveAndOther.java b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/AbstractPrimitiveAndOther.java new file mode 100644 index 00000000..62a564be --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/AbstractPrimitiveAndOther.java @@ -0,0 +1,34 @@ +package com.zc.business.utils.diff.algorithm; + +import com.google.gson.JsonElement; + +/** + * 基本类型和其它类型比较的公有方法抽象类 + * @Author JingWei + * @create 2022/1/11 + */ +public abstract class AbstractPrimitiveAndOther { + /** + * 将比较的元素转换成String类型方便结果展示 + * @param element 元素 + * @return 元素转换成的字符串 + */ + protected static String jsonElement2Str(JsonElement element){ + //该对象不存在的情况 + if(element == null){ + return null; + } else if (element.isJsonObject()) { + return "{省略内部字段}"; + } else if (element.isJsonArray()) { + return "[省略内部元素]"; + } else if (element.isJsonPrimitive()) { + return element.getAsJsonPrimitive().getAsString(); + } else if (element.isJsonNull()) { + return "null"; + }else{ + throw new RuntimeException("异常"); + } + } + + +} diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/AlgorithmModule.java b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/AlgorithmModule.java new file mode 100644 index 00000000..440313fe --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/AlgorithmModule.java @@ -0,0 +1,66 @@ +package com.zc.business.utils.diff.algorithm; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonNull; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import com.zc.business.utils.diff.algorithm.array.ArrayComparator; +import com.zc.business.utils.diff.algorithm.nulls.NullComparator; +import com.zc.business.utils.diff.algorithm.object.ObjectComparator; +import com.zc.business.utils.diff.algorithm.other.OtherComparator; +import com.zc.business.utils.diff.algorithm.primitive.PrimitiveComparator; +import com.zc.business.utils.diff.model.DiffContext; +import com.zc.business.utils.diff.model.PathModule; + +/** + * 算法模型 + * 算法模型包含5种比较器,对象、数组、基本类型、空类型、其他类型比较器。 + * 当2个JsonElement的子类同时为对象、数组、基本类型、空类型,使用前4种比较器。当2个JsonElement的子类类型不相同时,使用其它类型比较器。 + * @Author JingWei + * @create 2022/1/13 + */ +public class AlgorithmModule{ + protected ObjectComparator objectAlgorithm; + protected ArrayComparator arrayAlgorithm; + protected PrimitiveComparator primitiveComparator; + protected NullComparator nullComparator; + protected OtherComparator otherComparator; + + public AlgorithmModule(ObjectComparator objectAlgorithm, ArrayComparator arrayAlgorithm, + PrimitiveComparator primitiveComparator, NullComparator nullComparator, OtherComparator otherComparator) { + this.arrayAlgorithm = arrayAlgorithm; + this.objectAlgorithm = objectAlgorithm; + this.primitiveComparator = primitiveComparator; + this.nullComparator = nullComparator; + this.otherComparator = otherComparator; + objectAlgorithm.constructAlgorithmModule(this); + arrayAlgorithm.constructAlgorithmModule(this); + } + + /** + * 判断要比较的两个JsonElement的类型,并根据类型调用对应的算法进行比较 + * @param a 要比较的第一个元素 + * @param b 要比较的第二个元素 + * @param pathModule 路径模型 + * @return 返回比较结果 + */ + public DiffContext diffElement(JsonElement a, JsonElement b, PathModule pathModule) { + if (a instanceof JsonObject && b instanceof JsonObject) { + return objectAlgorithm.diff( (JsonObject) a, (JsonObject) b, pathModule); + } else if (a instanceof JsonArray && b instanceof JsonArray) { + return arrayAlgorithm.diffArray((JsonArray) a, (JsonArray) b, pathModule); + } else if (a instanceof JsonPrimitive && b instanceof JsonPrimitive) { + return primitiveComparator.diff((JsonPrimitive) a, (JsonPrimitive) b, pathModule); + } else if (a instanceof JsonNull && b instanceof JsonNull) { + return nullComparator.diff((JsonNull) a, (JsonNull) b, pathModule); + } else { + return otherComparator.diff(a, b, pathModule); + } + } + + public ArrayComparator getArrayAlgorithm() { + return arrayAlgorithm; + } + +} diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/Comparator.java b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/Comparator.java new file mode 100644 index 00000000..530ea2e4 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/Comparator.java @@ -0,0 +1,9 @@ +package com.zc.business.utils.diff.algorithm; + +/** + * 比较器最顶层的接口,逻辑意义 + * @Author JingWei + * @create 2022/3/2 + */ +public interface Comparator { +} diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/array/AbstractArray.java b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/array/AbstractArray.java new file mode 100644 index 00000000..2aa87a37 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/array/AbstractArray.java @@ -0,0 +1,22 @@ +package com.zc.business.utils.diff.algorithm.array; + +import com.zc.business.utils.diff.algorithm.AbstractObjectAndArray; + +/** + * 数组比较的公有方法抽象类 + * @Author JingWei + * @create 2022/3/1 + */ +public abstract class AbstractArray extends AbstractObjectAndArray implements ArrayComparator { + /** + * 数组索引号加一个中括号表示数组路径 + * @param i 数组元素的索引号 + * @return 索引号增加中括号 + */ + protected String constructArrayPath(Integer i){ + if(i == null || i < 0 ){ + throw new RuntimeException("数组索引号入参为空或者为负。 入参:" + i); + } + return "[" + i + "]"; + } +} diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/array/ArrayComparator.java b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/array/ArrayComparator.java new file mode 100644 index 00000000..160dccb2 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/array/ArrayComparator.java @@ -0,0 +1,43 @@ +package com.zc.business.utils.diff.algorithm.array; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.zc.business.utils.diff.algorithm.AlgorithmModule; +import com.zc.business.utils.diff.algorithm.Comparator; +import com.zc.business.utils.diff.model.DiffContext; +import com.zc.business.utils.diff.model.PathModule; + + +/** + * 数组类型比较器接口,用于2个JsonElement均为数组时对2个元素进行比较。 + * @Author JingWei + * @create 2022/2/23 + */ +public interface ArrayComparator extends Comparator { + /** + * 对两个JsonArray进行比较的方法 + * @param a 要比较的第一个JsonArray + * @param b 要比较的第二个JsonArray + * @param pathModule 路径模型 + * @return 返回不相等的结果 + */ + DiffContext diffArray(JsonArray a, JsonArray b, PathModule pathModule) ; + + /** + * 对象内部包含其他非数组类型,对这些类型比较需要使用JsonElement比较方法 + * @param a 要比较的第一个JsonElement + * @param b 要比较的第一个JsonElement + * @param pathModule 路径模型 + * @return 返回不相等的结果 + */ + DiffContext diffElement(JsonElement a, JsonElement b, PathModule pathModule); + + /** + * 构造算法模型,数组中元素比较需要使用到其他非数组算法 + * @param algorithmModule 算法模型:包含对象、数组、基本类型、空类型、其他类型算法 + */ + void constructAlgorithmModule(AlgorithmModule algorithmModule); + + + +} diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/array/SimilarArrayComparator.java b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/array/SimilarArrayComparator.java new file mode 100644 index 00000000..1406790b --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/array/SimilarArrayComparator.java @@ -0,0 +1,252 @@ +package com.zc.business.utils.diff.algorithm.array; + +import com.google.gson.JsonArray; +import com.zc.business.utils.diff.model.DiffContext; +import com.zc.business.utils.diff.model.PathModule; +import com.zc.business.utils.diff.model.SingleNodeDifference; + +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; + +/** + * 相似度数组算法比较器:当数组进行比较找不到相等元素时,通过算法优先找最接近的元素进行匹配 + * + * 举例: + *"[{\"a\":7,\"b\":5,\"c\":6},{\"a\":6,\"b\":2,\"c\":3}]"和 + *"[{\"a\":1,\"b\":2,\"c\":3},{\"a\":4,\"b\":5,\"c\":6},{\"a\":7,\"b\":8,\"c\":9}]"比较 + * 数组一中第一个元素依次和数组二中元素比较,分别有3组不同,1组不同,2组不同 + * 数组一中第二个元素依次和数组二中元素比较,分别有1组不同,3组不同,3组不同 + * 一、得到相似矩阵如下 + * 3 1 2 + * 1 3 3 + * 二、遍历矩阵所有元素,找到值最小的元素,并且行和列的其他元素不能再被使用。行和列即为要比较的2个元素在各自数组中的索引号 + * 第一次找到1,第二次找到另外一个1. + * 三、遍历矩阵中未使用所有列,列索引号为多余的元素在数组中的位置。 + * 只有第三列可以使用 ,第二组中第3个元素为新增元素。 + * + * @Author JingWei + * @create 2022/2/24 + */ +public class SimilarArrayComparator extends AbstractArray { + /** + * USEABLE表示当前位置可以使用 + */ + private final boolean USEABLE = false; + + /** + * USED表示当前位置已经被使用过 + */ + private final boolean USED = true; + + + /** + * @param a 要比较的第一个数组 + * @param b 要比较的第二个数组 + * @param pathModule 路径模型 + * @return 返回不相等的结果 + */ + @Override + public DiffContext diffArray(JsonArray a, JsonArray b, PathModule pathModule) { + DiffContext diffContext; + //a数组长度小于等于b,直接使用diff数组比较算法 + if(a.size() <= b.size()){ + diffContext = diff(a, b, pathModule); + } + //当a数组长度大于b时,需要交换pathModule中a和b路径, 并交换数组a和b,再使用diff数组比较算法 + else { + exchangeLeftAndRightPath(pathModule); + diffContext = diff(b, a, pathModule); + exchangeLeftAndRightPath(pathModule); + exchangeResult(diffContext); + } + return diffContext; + } + + /** + * 交换返回结果中每一个路径和结果 + * @param diffContext 返回结果 + */ + private void exchangeResult(DiffContext diffContext) { + List singleNodeDifferences = diffContext.getDiffResultModels(); + for(SingleNodeDifference singleNodeDifference : singleNodeDifferences){ + exchangePathAndResult(singleNodeDifference); + } + } + + /** + * 交换返回结果中的路径和结果 + * @param singleNodeDifference 返回结果 + */ + private void exchangePathAndResult(SingleNodeDifference singleNodeDifference) { + String tempStringA = singleNodeDifference.getLeftPath(); + Object tempLeft = singleNodeDifference.getLeft(); + singleNodeDifference.setLeftPath(singleNodeDifference.getRightPath()); + singleNodeDifference.setRightPath(tempStringA); + singleNodeDifference.setLeft(singleNodeDifference.getRight()); + singleNodeDifference.setRight(tempLeft); + } + + + /** + * 将路径模型中a和b的路径交换 + * @param pathModule 路径模型 + */ + private void exchangeLeftAndRightPath(PathModule pathModule) { + LinkedList tempA = pathModule.getLeftPath(); + pathModule.setLeftPath(pathModule.getRightPath()); + pathModule.setRightPath(tempA); + } + + + /** + * 数组比较核心算法,支持数组a长度小于b长度时使用 + */ + DiffContext diff(JsonArray a, JsonArray b, PathModule pathModule ) { + int rowlength = a.size(); + int linelength = b.size(); + //a数组中m个元素,与b数组中n个元素比较,共比较m*n次,所有比较结果会得组成一个矩阵,矩阵中的数字用来存储比较结果。 + int [][] similarMatrix = new int[rowlength][linelength]; + //创建一个行和列数组 用来判断当前行和列是否被使用过 + boolean []row = new boolean[rowlength]; + boolean []line = new boolean[linelength]; + for (int i = 0; i < rowlength; i++) { + pathModule.addLeftPath(constructArrayPath(i)); + //a数组中m个元素,与b数组中n个元素比较,比较结果生成一个m*n的矩阵 + constructSimilarMatrix(a, b, i, pathModule, similarMatrix, row, line); + pathModule.removeLastLeftPath(); + } + return obtainDiffResult(a, b, pathModule, row, line, similarMatrix); + } + + + /** + * 通过相似度矩阵,获取比较结果。 第一步在矩阵找到最小的数字,即找到最接近的几对结果。 第二步找剩余未使用的列数,即多余的元素 + */ + private DiffContext obtainDiffResult(JsonArray a, JsonArray b, PathModule pathModule, boolean[] row, boolean[] line, int[][] similarMatrix) { + DiffContext arrayDiffContext = new DiffContext(); + //找到a和b都有的结果,并且是最接近的几对结果 + obtainModifyDiffResult(a,b,pathModule,row,line,similarMatrix, arrayDiffContext); + //a没有b有的结果,即新增的结果 + obtainAddDiffResult(b,pathModule,line, arrayDiffContext); + + return arrayDiffContext; + } + + + /** + * 得到新增的结果。由于b数组长度大于a,会有几个元素多余。在选出a和b最接近的几对元素后,剩下的几个元素被认为是新增的。 + */ + private void obtainAddDiffResult(JsonArray b, PathModule pathModule, boolean[] line, DiffContext arrayDiffContext) { + for (int j = 0; j < line.length; j++) { + if (line[j] == USED) { + continue; + } + DiffContext addOrDeleteDiffContext = constructAddContext(b, j, pathModule); + parentContextAddChildContext(arrayDiffContext, addOrDeleteDiffContext); + } + } + + /** + * 从m*n的矩阵中选出最接近的几组结果,矩阵中的数字越小,说明2个元素比较时结果相差越少 + */ + private void obtainModifyDiffResult(JsonArray a, JsonArray b, PathModule pathModule, boolean[] row, boolean[] line, int[][] similarMatrix, DiffContext arrayDiffContext) { + int counts = 0; + //找到还未使用行的数量(行数小于列数) + for (boolean value : row) { + if (Objects.equals(USEABLE, value)) { + counts++; + } + } + //不同结果对数等于未使用的行数 + for (int n = 0; n < counts; n++) { + int bestLineIndex = 0; + int bestRowIndex = 0; + int minDiffPair = Integer.MAX_VALUE; + //遍历矩阵中所有元素,找最小的数字,矩阵中的数字越小,说明2个元素比较时结果相差越少 + for (int i = 0; i < row.length; i++) { + for (int j = 0; j < line.length; j++) { + //如果行或列被使用,跳过该行 + if (row[i] == USED || line[j] == USED) { + continue; + } + //如果当前元素数字更小,那么把当前行和列保存下来,数字更新为当前最优结果 + if (similarMatrix[i][j] < minDiffPair) { + bestRowIndex = i; + bestLineIndex = j; + minDiffPair = similarMatrix[i][j]; + } + } + } + //将找到的最优结果添加到返回结果中 + DiffContext modifyDiffContext = constructModifyContext(a, b, bestRowIndex, bestLineIndex, pathModule); + row[bestRowIndex] = USED; + line[bestLineIndex] = USED; + parentContextAddChildContext(arrayDiffContext, modifyDiffContext); + } + } + + /** + * 此时a数组没有该元素,b数组有元素,结果为新增 + * @param b 数组 + * @param index 索引号 + * @param pathModule 路径模型 + * @return 生成的不同结果 + */ + private DiffContext constructAddContext(JsonArray b, int index, PathModule pathModule) { + pathModule.addAllpath(constructArrayPath(index)); + DiffContext diffContext = diffElement(null, b.get(index), pathModule); + pathModule.removeAllLastPath(); + return diffContext; + } + + /** + * 返回两个数组对应索引号元素比较结果 + * @param a 数组a + * @param b 数组b + * @param i 数组a中元素的索引号 + * @param bestLineIndex 数组b中元素的索引号,即找到的和a中元素接接近的元素索引号。 + * @param pathModule 路径模型 + * @return 返回不同的结果 + */ + private DiffContext constructModifyContext(JsonArray a, JsonArray b, int i, int bestLineIndex, PathModule pathModule) { + pathModule.addLeftPath(constructArrayPath(i)); + pathModule.addRightPath(constructArrayPath(bestLineIndex)); + DiffContext diffContext = diffElement(a.get(i), b.get(bestLineIndex), pathModule); + pathModule.removeAllLastPath(); + return diffContext; + } + + /** + * 用数组a的一个元素与数组b中所有元素分别比较,会得到n次比较结果,结果为不相等的结果对数,在矩阵中更新n次结果。 + */ + private void constructSimilarMatrix(JsonArray arrayA, JsonArray arrayB, int rowIndex, PathModule pathModule, int [][]similarArray, boolean[] row, boolean[] line) { + if(rowIndex < 0 || rowIndex >= arrayB.size()){ + throw new RuntimeException("索引号入参超出数组长度。 索引号:" + rowIndex +" 数组B:" + arrayB); + } + + for (int j = 0; j < arrayB.size(); j++) { + if (line[j] == USEABLE) { + pathModule.addRightPath(constructArrayPath(j)); + DiffContext diffContext = diffElement(arrayA.get(rowIndex), arrayB.get(j), pathModule); + pathModule.removeLastRightPath(); + if (diffContext.isSame()) { + row[rowIndex] = USED; + line[j] = USED; + return; + } else if(existSpecialPath(diffContext.getSpecialPathResult())){ + similarArray[rowIndex][j] = 0 ; + } else { + similarArray[rowIndex][j] = diffContext.getDiffResultModels().size(); + } + } + } + } + + /** + * 判断比较结果是否有特殊路径 + */ + private boolean existSpecialPath(LinkedList specialPathResult) { + return specialPathResult != null && !specialPathResult.isEmpty(); + } +} diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/array/SimpleArrayComparator.java b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/array/SimpleArrayComparator.java new file mode 100644 index 00000000..36a3d791 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/array/SimpleArrayComparator.java @@ -0,0 +1,62 @@ +package com.zc.business.utils.diff.algorithm.array; + +import com.google.gson.JsonArray; +import com.zc.business.utils.diff.model.DiffContext; +import com.zc.business.utils.diff.model.PathModule; + +/** + * 简单数组比较器:数组对比时按照索引号顺序依次进行比较 + * 例:[A,B,C] 与 [C,B,A]比较时,依次找索引号为0、为1、为2进行比较,相同结果对为 ,不同结果 会加入到返回结果中。 + * @Author JingWei + * @create 2022/1/14 + */ +public class SimpleArrayComparator extends AbstractArray { + /** + * 对两个JsonArray进行比较的方法。 + * @param a 要比较的第一个数组 + * @param b 要比较的第二个数组 + * @param pathModule 路径模型 + * @return 返回不相等的比较结果 + */ + @Override + public DiffContext diffArray(JsonArray a, JsonArray b, PathModule pathModule) { + DiffContext arrayDiffContext = new DiffContext(); + int maxLength = Math.max(a.size(), b.size()); + //根据数组a和b长度的大的值进行遍历 + for (int i = 0; i < maxLength; i++) { + pathModule.addAllpath(constructArrayPath(i)); + DiffContext diffContext = generateDiffResult(a,b,i,pathModule); + parentContextAddChildContext(arrayDiffContext, diffContext); + } + return arrayDiffContext; + } + + /** + * 生成比较结果,分以下3种情况考虑 + * i < a.size() && i < b.size() + * a.size() <= i + * b.size() <= i + * @param a 数组a + * @param b 数组b + * @param i 数组a和b中正在比较的元素索引号 + * @param pathModule 路径模型 + * @return 返回不相等的比较结果 + */ + private DiffContext generateDiffResult(JsonArray a, JsonArray b, int i, PathModule pathModule) { + if(i >= a.size() && i >= b.size()){ + throw new RuntimeException("数组索引号入参超过数组长度。 索引号:" + i + " 数组a:" + a + "数组b:" + b); + } + DiffContext diffContext; + if(i < a.size() && i < b.size()){ + diffContext = diffElement(a.get(i), b.get(i), pathModule); + }else if (i >= a.size()){ + diffContext = diffElement(null, b.get(i), pathModule); + }else{ + diffContext = diffElement(a.get(i), null, pathModule); + } + return diffContext; + } + + +} + diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/nulls/DefaultNullComparator.java b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/nulls/DefaultNullComparator.java new file mode 100644 index 00000000..06bab025 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/nulls/DefaultNullComparator.java @@ -0,0 +1,27 @@ +package com.zc.business.utils.diff.algorithm.nulls; + +import com.google.gson.JsonNull; +import com.zc.business.utils.diff.model.DiffContext; +import com.zc.business.utils.diff.model.PathModule; + +/** + * 当要比较的两个JsonElement都为空类型时,默认实现的算法比较器 + * @Author JingWei + * @create 2022/1/10 + */ +public class DefaultNullComparator implements NullComparator { + + /** + * 当要比较的两个JsonElement是空类型时,默认比较方法 + * @param a 第一个空类型 + * @param b 第二个空类型 + * @param pathModule 路径模型 + * @return 返回结果 + */ + @Override + public DiffContext diff(JsonNull a, JsonNull b, PathModule pathModule){ + return new DiffContext(); + } + + +} \ No newline at end of file diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/nulls/NullComparator.java b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/nulls/NullComparator.java new file mode 100644 index 00000000..4d90e34d --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/nulls/NullComparator.java @@ -0,0 +1,25 @@ +package com.zc.business.utils.diff.algorithm.nulls; + +import com.google.gson.JsonNull; +import com.zc.business.utils.diff.algorithm.Comparator; +import com.zc.business.utils.diff.model.DiffContext; +import com.zc.business.utils.diff.model.PathModule; + +/** + * 空类型比较器接口,用于2个JsonElement均为JsonNull时对2个元素进行比较。 + * @Author JingWei + * @create 2022/2/23 + */ +public interface NullComparator extends Comparator { + + /** + * 对两个JsonNull进行比较时,需要实现此方法。 + * @param a 要比较的第一个JsonNull + * @param b 要比较的第二个JsonNull + * @param pathModule 路径模型 + * @return 返回不同的比较结果 + */ + DiffContext diff(JsonNull a, JsonNull b, PathModule pathModule); + + +} \ No newline at end of file diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/object/AbstractObject.java b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/object/AbstractObject.java new file mode 100644 index 00000000..b8305829 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/object/AbstractObject.java @@ -0,0 +1,128 @@ +package com.zc.business.utils.diff.algorithm.object; + +import com.google.common.base.Joiner; +import com.google.gson.JsonObject; +import com.zc.business.utils.diff.algorithm.AbstractObjectAndArray; +import com.zc.business.utils.diff.model.Constants; +import com.zc.business.utils.diff.model.DiffContext; +import com.zc.business.utils.diff.model.PathModule; + +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 对象比较的一些公有方法抽象类 + * @Author JingWei + * @create 2022/2/24 + */ +public abstract class AbstractObject extends AbstractObjectAndArray implements ObjectComparator { + + /** + * 对两个对象进行比较:遍历keySet中的所有key, 在a和b对象中找对应的value值进行比较 + * @param a 要比较的第一个对象 + * @param b 要比较的第二个对象 + * @param keySet key的集合 + * @param pathModule 路径模型 + * @return 不同的比较结果 + */ + protected DiffContext diffValueByKey(JsonObject a, JsonObject b, Set keySet, PathModule pathModule) { + DiffContext objectDiffContext = new DiffContext(); + LinkedList specialPathResult = new LinkedList<>(); + for (String key : keySet) { + //更新a和b当前路径 + pathModule.addAllpath(key); + //如果对象当前路径在噪音路径集合中,直接跳过比较 + if (!needDiff(pathModule.getNoisePahList(), pathModule.getLeftPath())) { + pathModule.removeAllLastPath(); + continue; + } + //生成比较结果 + DiffContext diffContext = diffElement(a.get(key), b.get(key), pathModule); + parentContextAddChildContext(objectDiffContext, diffContext); + //特殊路径处理 + specialPathHandle(diffContext.isSame(), specialPathResult, pathModule); + pathModule.removeAllLastPath(); + + } + objectDiffContext.setSpecialPathResult(specialPathResult); + return objectDiffContext; + } + + /** + * 如果比较的路径为特殊路径并且比较相等,特殊路径会被标识,添加到返回结果中。 + * @param isSame 比较结果是否相等 + * @param specialPathResult 返回的特殊路径结果 + * @param pathModule 路径模型 + */ + private void specialPathHandle(boolean isSame,LinkedList specialPathResult, PathModule pathModule) { + //如果比较结果不等,直接返回。 + if (!isSame){ + return; + } + //如果存在特殊路径,将特殊路径加入到集合中 + String specialPath = getSpecialPath(pathModule); + if( existPath(specialPath)){ + specialPathResult.add(specialPath); + } + } + + /** + * 校验路径是否存在,即路径是否为空 + * @param specialPath 特殊路径 + * @return 特殊路径是否为空 + */ + private boolean existPath(String specialPath) { + return specialPath != null; + } + + /** + * 判断当前路径是否在特殊路径集合中,如果在,则返回特殊路径。 + * @param pathModule 路径模型 + * @return 返回的特殊路径字符串 + */ + protected String getSpecialPath(PathModule pathModule) { + if(pathModule == null || pathModule.getSpecialPath() == null || pathModule.getSpecialPath().isEmpty()){ + return null; + } + String currentPath = listJoin(pathModule.getLeftPath()); + if(pathModule.getSpecialPath().contains(currentPath)){ + return currentPath; + } + return null; + } + + /** + * 判断当前字段是否需要diff,如果在噪音字段集合中,则不需要diff,返回false。 + * @param noisePahList 噪音路径列表 + * @param pathList 当前路径 + * @return 当前路径是否在噪音路径中 + */ + protected boolean needDiff(List noisePahList, LinkedList pathList) { + if(noisePahList == null || pathList == null || noisePahList.isEmpty() || pathList.isEmpty()){ + return true; + } + String path = listJoin(pathList); + if(noisePahList.contains(path)){ + return false; + } + return true; + } + + /** + * 将path路径列表改为字符串 + * @param path 当前路径 + * @return 当前路径字符串 + */ + protected String listJoin(LinkedList path) { + if(path == null){ + throw new RuntimeException("当前路径不能为空"); + } + List collect = path.stream().filter(e -> e.charAt(0) != '[').collect(Collectors.toList()); + return Joiner.on(Constants.MERGE_PATH).join(collect); + } + + + +} \ No newline at end of file diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/object/LeftJoinObjectComparator.java b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/object/LeftJoinObjectComparator.java new file mode 100644 index 00000000..e87b3e07 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/object/LeftJoinObjectComparator.java @@ -0,0 +1,30 @@ +package com.zc.business.utils.diff.algorithm.object; + +import com.google.gson.JsonObject; +import com.zc.business.utils.diff.model.DiffContext; +import com.zc.business.utils.diff.model.PathModule; + +/** + * 左匹配对象比较器:当对两个JsonObject进行比较时,只对第一个对象中keySet中存在keyValue值进行比较。 + * + * 举例: + * {"a":1,"b":2,"c":3}和{"a":1,"b":4,"c":3,"d":4}进行比较 + * 只会比较第一个对象中有的字段,即比较第一个对象中有的"a","b","c"3个字段,第二个对象中的"d"字段没有被比较 + * + * @Author JingWei + * @create 2022/2/18 + */ +public class LeftJoinObjectComparator extends AbstractObject { + /** + * @param a 要比较的第一个JsonObject + * @param b 要比较的第二个JsonObject + * @param pathModule 路径模型 + * @return 不同的比较结果 + */ + @Override + public DiffContext diff(JsonObject a, JsonObject b, PathModule pathModule){ + //用a的keySet作为遍历集合。 + return diffValueByKey(a, b, a.keySet(), pathModule); + } + +} \ No newline at end of file diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/object/ObjectComparator.java b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/object/ObjectComparator.java new file mode 100644 index 00000000..86571d1e --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/object/ObjectComparator.java @@ -0,0 +1,40 @@ +package com.zc.business.utils.diff.algorithm.object; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.zc.business.utils.diff.algorithm.AlgorithmModule; +import com.zc.business.utils.diff.algorithm.Comparator; +import com.zc.business.utils.diff.model.DiffContext; +import com.zc.business.utils.diff.model.PathModule; + +/** + * 对象类型比较器接口,用于2个JsonElement均为JsonObject时对2个元素进行比较。 + * @Author JingWei + * @create 2022/2/23 + */ +public interface ObjectComparator extends Comparator { + + /** + * 对两个JsonObject进行比较时,需要实现此方法。 + * @param a 要比较的第一个JsonObject + * @param b 要比较的第二个JsonObject + * @param pathModule 路径模型 + * @return 返回不同的比较结果 + */ + DiffContext diff(JsonObject a, JsonObject b, PathModule pathModule); + + /** + * 对象内部包含其他非JsonObject类型,对这些类型比较需要使用JsonElement比较方法 + * @param a 元素a + * @param b 元素b + * @param pathModule 路径模型 + * @return 返回不同的比较结果 + */ + DiffContext diffElement(JsonElement a, JsonElement b, PathModule pathModule); + + /** + * 构造算法模型,对象比较时,内部元素比较需要使用到其他非数组算法 + * @param algorithmModule 算法模型:包含对象、数组、基本类型、空类型、其他类型算法 + */ + void constructAlgorithmModule(AlgorithmModule algorithmModule); +} \ No newline at end of file diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/object/SimpleObjectComparator.java b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/object/SimpleObjectComparator.java new file mode 100644 index 00000000..c61551f3 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/object/SimpleObjectComparator.java @@ -0,0 +1,33 @@ +package com.zc.business.utils.diff.algorithm.object; + +import com.google.common.collect.Sets; +import com.google.gson.JsonObject; +import com.zc.business.utils.diff.model.DiffContext; +import com.zc.business.utils.diff.model.PathModule; + +import java.util.Set; + +/** + * 简单对象比较器:当对两个JsonObject进行比较时,两个对象所有keySet中key对应的Value都会被比较。 + * 举例: + * {"b":2,"c":3}和{"a":1,"d":4}进行比较 + * 会比较两个对象中所有的字段,即比较两个对象中并集"a","b","c","d"4个字段 + * @Author JingWei + * @create 2022/2/16 + */ +public class SimpleObjectComparator extends AbstractObject { + /** + * @param a 要比较的第一个JsonObject + * @param b 要比较的第二个JsonObject + * @param pathModule 路径模型 + * @return 不同的比较结果 + */ + @Override + public DiffContext diff(JsonObject a, JsonObject b, PathModule pathModule) { + Set unionSet = Sets.union(a.keySet(), b.keySet()); + //用a和b的keySet的并集作为遍历集合。 + return diffValueByKey(a, b, unionSet, pathModule); + } + + +} diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/other/DefaultOtherComparator.java b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/other/DefaultOtherComparator.java new file mode 100644 index 00000000..dc43f4d3 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/other/DefaultOtherComparator.java @@ -0,0 +1,38 @@ +package com.zc.business.utils.diff.algorithm.other; + +import com.google.common.base.Joiner; +import com.google.gson.JsonElement; +import com.zc.business.utils.diff.algorithm.AbstractPrimitiveAndOther; +import com.zc.business.utils.diff.model.Constants; +import com.zc.business.utils.diff.model.DiffContext; +import com.zc.business.utils.diff.model.PathModule; +import com.zc.business.utils.diff.model.SingleNodeDifference; + +import java.util.ArrayList; +import java.util.List; + +/** + * 当要比较的两个JsonElement的不同时为对象、组数、空、基本类型时,默认实现的比较器。 + * @Author JingWei + * @create 2022/1/10 + */ +public class DefaultOtherComparator extends AbstractPrimitiveAndOther implements OtherComparator { + + /** + * @param a 要比较的第一个JsonElement + * @param b 要比较的第二个JsonElement + * @param pathModule 路径模型 + * @return 不同的比较结果 + */ + @Override + public DiffContext diff(JsonElement a, JsonElement b, PathModule pathModule){ + //比较结果一定会不同,因为要比较的a和b类型不同才会调用该方法。 + DiffContext otherDiffContext = new DiffContext(Constants.DIFFERENT); + List singleNodeDifferences = new ArrayList<>(); + singleNodeDifferences.add(new SingleNodeDifference(Joiner.on(Constants.MERGE_PATH).join(pathModule.getLeftPath()), Joiner.on(Constants.MERGE_PATH).join(pathModule.getRightPath()), jsonElement2Str(a), jsonElement2Str(b))); + otherDiffContext.setDiffResultModels(singleNodeDifferences); + return otherDiffContext; + } + + +} diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/other/OtherComparator.java b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/other/OtherComparator.java new file mode 100644 index 00000000..ffe7e628 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/other/OtherComparator.java @@ -0,0 +1,24 @@ +package com.zc.business.utils.diff.algorithm.other; + +import com.google.gson.JsonElement; +import com.zc.business.utils.diff.algorithm.Comparator; +import com.zc.business.utils.diff.model.DiffContext; +import com.zc.business.utils.diff.model.PathModule; + +/** + * 其他类型比较器接口,用于2个JsonElement不同时为对象、数组、空、基本类型时对2个元素进行比较。 + * + * 举例:第一个要比较类型为对象类型,第二个要比较类型为数组类型。 + * @Author JingWei + * @create 2022/2/23 + */ +public interface OtherComparator extends Comparator { + /** + * 对两个JsonElement进行比较并且两个JsonElement的类型不相等时,需要实现此方法。 + * @param a 要比较的第一个JsonElement + * @param b 要比较的第二个JsonElement + * @return 不同的比较结果 + */ + DiffContext diff(JsonElement a, JsonElement b, PathModule pathModule); + +} diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/primitive/DefaultPrimitiveComparator.java b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/primitive/DefaultPrimitiveComparator.java new file mode 100644 index 00000000..b6c2e8ee --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/primitive/DefaultPrimitiveComparator.java @@ -0,0 +1,39 @@ +package com.zc.business.utils.diff.algorithm.primitive; + +import com.google.common.base.Joiner; +import com.google.gson.JsonPrimitive; +import com.zc.business.utils.diff.algorithm.AbstractPrimitiveAndOther; +import com.zc.business.utils.diff.model.Constants; +import com.zc.business.utils.diff.model.DiffContext; +import com.zc.business.utils.diff.model.PathModule; +import com.zc.business.utils.diff.model.SingleNodeDifference; + +import java.util.ArrayList; +import java.util.List; + +/** + * 当要比较的两个JsonElement是基本类型时,默认实现的比较器。 + * @Author JingWei + * @create 2022/1/10 + */ +public class DefaultPrimitiveComparator extends AbstractPrimitiveAndOther implements PrimitiveComparator { + /** + * @param a 要比较的第一个JsonPrimitive + * @param b 要比较的第二个JsonPrimitive + * @param pathModule 路径模型 + * @return 不同的比较结果 + */ + @Override + public DiffContext diff(JsonPrimitive a, JsonPrimitive b, PathModule pathModule){ + DiffContext primitiveDiffContext = new DiffContext(); + //如果a和b不相等,返回a和b的比较结果。 + if(Constants.DIFFERENT == a.equals(b)) { + List singleNodeDifferences = new ArrayList<>(); + singleNodeDifferences.add(new SingleNodeDifference(Joiner.on(Constants.MERGE_PATH).join(pathModule.getLeftPath()), Joiner.on(Constants.MERGE_PATH).join(pathModule.getRightPath()), jsonElement2Str(a), jsonElement2Str(b))); + primitiveDiffContext.setDiffResultModels(singleNodeDifferences); + primitiveDiffContext.setSame(Constants.DIFFERENT); + } + return primitiveDiffContext; + } + +} diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/primitive/PrimitiveComparator.java b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/primitive/PrimitiveComparator.java new file mode 100644 index 00000000..cfcdc0be --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/algorithm/primitive/PrimitiveComparator.java @@ -0,0 +1,23 @@ +package com.zc.business.utils.diff.algorithm.primitive; + +import com.google.gson.JsonPrimitive; +import com.zc.business.utils.diff.algorithm.Comparator; +import com.zc.business.utils.diff.model.DiffContext; +import com.zc.business.utils.diff.model.PathModule; + +/** + * 基本类型比较器接口,用于2个JsonElement均为基本类型的时对2个元素进行比较。 + * @Author JingWei + * @create 2022/2/23 + */ +public interface PrimitiveComparator extends Comparator { + /** + * 对两个基本类型进行比较时,需要实现此方法。 + * @param a 要比较的第一个JsonPrimitive + * @param b 要比较的第二个JsonPrimitive + * @param pathModule 路径模型 + * @return 不同的比较结果 + */ + DiffContext diff(JsonPrimitive a, JsonPrimitive b, PathModule pathModule); + +} diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/model/Constants.java b/zc-business/src/main/java/com/zc/business/utils/diff/model/Constants.java new file mode 100644 index 00000000..c5380e3b --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/model/Constants.java @@ -0,0 +1,20 @@ +package com.zc.business.utils.diff.model; + + +/** + * 常量 + * @Author JingWei + * @create 2022/3/2 + */ +public class Constants { + /** + * 描述比较结果不同 + */ + public static final boolean DIFFERENT = false; + /** + * 描述比较结果相同 + */ + public static final boolean SAME = true; + public static final String SPLIT_PATH = "\\."; + public static final String MERGE_PATH = "."; +} diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/model/DiffContext.java b/zc-business/src/main/java/com/zc/business/utils/diff/model/DiffContext.java new file mode 100644 index 00000000..9a0977ed --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/model/DiffContext.java @@ -0,0 +1,61 @@ +package com.zc.business.utils.diff.model; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * diff比较上下文 + * @Author JingWei + * @create 2022/3/2 + */ +public class DiffContext { + /** + * 比较结果是否相同 + */ + private boolean isSame; + + /** + * 比较结果不同时,存储所有不同的结果对 + */ + private List singleNodeDifferences; + + /** + * 比较结果中,出现了特殊路径下值相等的情况,会存储该特殊路径。 + */ + private LinkedList specialPathResult; + + public DiffContext(boolean isSame) { + this.isSame = isSame; + this.singleNodeDifferences = new ArrayList<>(); + } + + public boolean isSame() { + return isSame; + } + + public void setSame(boolean same) { + isSame = same; + } + + public List getDiffResultModels() { + return singleNodeDifferences; + } + + public void setDiffResultModels(List singleNodeDifferences) { + this.singleNodeDifferences = singleNodeDifferences; + } + + public DiffContext() { + this.isSame = true; + this.singleNodeDifferences = new ArrayList<>(); + } + + public LinkedList getSpecialPathResult() { + return specialPathResult; + } + + public void setSpecialPathResult(LinkedList specialPathResult) { + this.specialPathResult = specialPathResult; + } +} diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/model/PathModule.java b/zc-business/src/main/java/com/zc/business/utils/diff/model/PathModule.java new file mode 100644 index 00000000..1a95e509 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/model/PathModule.java @@ -0,0 +1,122 @@ +package com.zc.business.utils.diff.model; + +import java.util.LinkedList; +import java.util.List; + +/** + * 路径模型 + * A和B比较时,实时更新当前正在进行比较的元素路径。 + * + * @Author JingWei + * @create 2022/2/15 + */ +public class PathModule { + /** + * 对象A当前遍历到的路径 + */ + private LinkedList leftPath; + /** + * 对象B当前遍历到的路径 + */ + private LinkedList rightPath; + /** + * 特殊路径集合。当前路径符合特殊路径且特殊路径下比较结果相同,会在返回结果中做额外标识标识。 + */ + private List specialPath; + /** + * 噪音字段集合。如果当前路径符合噪音字段路径,则不会比较。 + */ + private List noisePahList; + + public PathModule() { + this.leftPath = new LinkedList<>(); + this.rightPath = new LinkedList<>(); + } + + public PathModule(List noisePahList) { + this.leftPath = new LinkedList<>(); + this.rightPath = new LinkedList<>(); + this.noisePahList = noisePahList; + } + + public PathModule(List noisePahList, List specialPath) { + this.leftPath = new LinkedList<>(); + this.rightPath = new LinkedList<>(); + this.noisePahList = noisePahList; + this.specialPath = specialPath; + } + + public List getNoisePahList() { + return noisePahList; + } + + public void setNoisePahList(List noisePahList) { + this.noisePahList = noisePahList; + } + + public List getSpecialPath() { + return specialPath; + } + + public void setSpecialPath(LinkedList specialPath) { + this.specialPath = specialPath; + } + + public LinkedList getLeftPath() { + return leftPath; + } + + public void setLeftPath(LinkedList leftPath) { + this.leftPath = leftPath; + } + + public LinkedList getRightPath() { + return rightPath; + } + + public void setRightPath(LinkedList rightPath) { + this.rightPath = rightPath; + } + + /** + * 同时在A和B路径列表最后加上一个Path路径 + */ + public void addAllpath(String lastPath) { + leftPath.add(lastPath); + rightPath.add(lastPath); + } + + public void addLeftPath(String lastPath) { + leftPath.add(lastPath); + } + + public void addRightPath(String lastPath) { + rightPath.add(lastPath); + } + + + /** + * 同时移除A和B路径列表中最后的一个路径 + */ + public void removeAllLastPath() { + leftPath.removeLast(); + rightPath.removeLast(); + } + + /** + * 移除A路径列表中最后的一个路径 + */ + public void removeLastLeftPath() { + leftPath.removeLast(); + } + + /** + * 移除B路径列表中最后的一个路径 + */ + public void removeLastRightPath() { + rightPath.removeLast(); + } + + +} + diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/model/Result.java b/zc-business/src/main/java/com/zc/business/utils/diff/model/Result.java new file mode 100644 index 00000000..0e55470a --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/model/Result.java @@ -0,0 +1,71 @@ +package com.zc.business.utils.diff.model; + +import java.io.Serializable; + +/** + * diff比较最终结果 + * @Author JingWei + * @create 2022/3/2 + */ +public class Result implements Serializable { + /** + * 第一个对象路径 + */ + private String leftPath; + /** + * 第二个对象路径 + */ + private String rightPath; + /** + * 第一个对象值 + */ + private Object left; + /** + * 第二个对象值 + */ + private Object right; + /** + * 比较结果 + */ + private String diffType; + + public String getLeftPath() { + return leftPath; + } + + public String getRightPath() { + return rightPath; + } + + public void setLeftPath(String leftPath) { + this.leftPath = leftPath; + } + + public void setRightPath(String rightPath) { + this.rightPath = rightPath; + } + + public Object getLeft() { + return left; + } + + public void setLeft(Object left) { + this.left = left; + } + + public Object getRight() { + return right; + } + + public void setRight(Object right) { + this.right = right; + } + + public String getDiffType() { + return diffType; + } + + public void setDiffType(String diffType) { + this.diffType = diffType; + } +} diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/model/ResultConvertUtil.java b/zc-business/src/main/java/com/zc/business/utils/diff/model/ResultConvertUtil.java new file mode 100644 index 00000000..ecc86d5b --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/model/ResultConvertUtil.java @@ -0,0 +1,66 @@ +package com.zc.business.utils.diff.model; + +import java.util.ArrayList; +import java.util.Objects; + +/** + * 结果转换工具:将diff上下文转换成diff最终结果 + * @Author JingWei + * @create 2022/2/25 + */ +public class ResultConvertUtil { + public static final String OBJECT_NULL = null; + //diff结果类型分为修改、新增、删除 + public static final String TYPE_MODIFY = "MODIFY"; + public static final String TYPE_ADD = "ADD"; + public static final String TYPE_DELETE = "DELETE"; + + /** + * 将diff上下文转换成diff最终结果 + * @param diffContext diff比较的直接结果 + * @return diff展示的结果 + */ + public static ArrayList constructResult(DiffContext diffContext) { + ArrayList list = new ArrayList<>(); + for (SingleNodeDifference resultModel : diffContext.getDiffResultModels()) { + Result printModel = convert(resultModel); + boolean leftAndRightBothNull = (Objects.equals(OBJECT_NULL,resultModel.getLeft())) + && Objects.equals(OBJECT_NULL,resultModel.getRight()) ; + //判断两个对象是否同时为空 + if (leftAndRightBothNull) { + printModel.setDiffType(TYPE_MODIFY); + } + //这种情况为对象A中keySet没这个key,或者A数组长度小于B 数组中没这个元素。 + else if (Objects.equals(OBJECT_NULL,resultModel.getLeft()) ) { + printModel.setDiffType(TYPE_ADD); + printModel.setLeftPath(null); + } + //这种情况为对象B中keySet没这个key,或者B数组长度小于A 数组中没这个元素。 + else if (Objects.equals(OBJECT_NULL,resultModel.getRight()) ) { + printModel.setDiffType(TYPE_DELETE); + printModel.setRightPath(null); + } + //其他情况 + else { + printModel.setDiffType(TYPE_MODIFY); + } + list.add(printModel); + } + return list; + } + + + /** + * 数据模型转换,增加类型字段。 + * @param resultModel 比较结果 + * @return 展示模型 + */ + private static Result convert(SingleNodeDifference resultModel) { + Result printModel = new Result(); + printModel.setLeft(resultModel.getLeft()); + printModel.setRight(resultModel.getRight()); + printModel.setLeftPath(resultModel.getLeftPath()); + printModel.setRightPath(resultModel.getRightPath()); + return printModel; + } +} diff --git a/zc-business/src/main/java/com/zc/business/utils/diff/model/SingleNodeDifference.java b/zc-business/src/main/java/com/zc/business/utils/diff/model/SingleNodeDifference.java new file mode 100644 index 00000000..da9e9b40 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/utils/diff/model/SingleNodeDifference.java @@ -0,0 +1,69 @@ +package com.zc.business.utils.diff.model; + +import java.io.Serializable; + +/** + * 单对元素比较结果 + * @Author JingWei + * @create 2022/3/2 + */ +public class SingleNodeDifference implements Serializable { + /** + * 第一个对象路径 + */ + private String leftPath; + /** + * 第二个对象路径 + */ + private String rightPath; + /** + * 第一个对象值 + */ + private Object left; + /** + * 第二个对象值 + */ + private Object right; + /** + * 比较结果 + */ + + public SingleNodeDifference(String leftPath, String rightPath, Object left, Object right) { + this.leftPath = leftPath; + this.rightPath = rightPath; + this.left = left; + this.right = right; + } + + public String getLeftPath() { + return leftPath; + } + + public void setLeftPath(String leftPath) { + this.leftPath = leftPath; + } + + public String getRightPath() { + return rightPath; + } + + public void setRightPath(String rightPath) { + this.rightPath = rightPath; + } + + public Object getLeft() { + return left; + } + + public void setLeft(Object left) { + this.left = left; + } + + public Object getRight() { + return right; + } + + public void setRight(Object right) { + this.right = right; + } +} \ No newline at end of file diff --git a/zc-business/src/main/resources/mapper/business/DcEventImportantFileMapper.xml b/zc-business/src/main/resources/mapper/business/DcEventImportantFileMapper.xml new file mode 100644 index 00000000..5d16abf7 --- /dev/null +++ b/zc-business/src/main/resources/mapper/business/DcEventImportantFileMapper.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + select id,event_id, from_dept, create_time, title, to_dept, content, create_name, phone_number, issued, type from dc_event_important_file + + + + + + + + insert into dc_event_important_file + + event_id, + from_dept, + create_time, + title, + to_dept, + content, + create_name, + phone_number, + issued, + type, + + + #{eventId}, + #{fromDept}, + #{createTime}, + #{title}, + #{toDept}, + #{content}, + #{createName}, + #{phoneNumber}, + #{issued}, + #{type}, + + + + + update dc_event_important_file + + event_id = #{eventId}, + from_dept = #{fromDept}, + from_dept = #{fromDept}, + create_time = #{createTime}, + title = #{title}, + to_dept = #{toDept}, + content = #{content}, + create_name = #{createName}, + phone_number = #{phoneNumber}, + issued = #{issued}, + type = #{type}, + + where id = #{id} + + + + delete from dc_event_important_file where id = #{id} + + + + delete from dc_event_important_file where id in + + #{id} + + + \ No newline at end of file diff --git a/zc-business/src/main/resources/mapper/business/DcEventImportantMapper.xml b/zc-business/src/main/resources/mapper/business/DcEventImportantMapper.xml new file mode 100644 index 00000000..2e61910a --- /dev/null +++ b/zc-business/src/main/resources/mapper/business/DcEventImportantMapper.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + select id, event_id, plate_number, diversion_point, current_progress, take_steps, plan_status, traffic_police_status, medical_status, fire_status, board_status, chemicals_status, plan_level, chemicals_name, leakage_level from dc_event_important + + + + + + + + insert into dc_event_important + + event_id, + plate_number, + diversion_point, + current_progress, + take_steps, + plan_status, + traffic_police_status, + medical_status, + fire_status, + board_status, + chemicals_status, + plan_level, + chemicals_name, + leakage_level, + + + #{eventId}, + #{plateNumber}, + #{diversionPoint}, + #{currentProgress}, + #{takeSteps}, + #{planStatus}, + #{trafficPoliceStatus}, + #{medicalStatus}, + #{fireStatus}, + #{boardStatus}, + #{chemicalsStatus}, + #{planLevel}, + #{chemicalsName}, + #{leakageLevel}, + + + + + update dc_event_important + + event_id = #{eventId}, + plate_number = #{plateNumber}, + diversion_point = #{diversionPoint}, + current_progress = #{currentProgress}, + take_steps = #{takeSteps}, + plan_status = #{planStatus}, + traffic_police_status = #{trafficPoliceStatus}, + medical_status = #{medicalStatus}, + fire_status = #{fireStatus}, + board_status = #{boardStatus}, + chemicals_status = #{chemicalsStatus}, + plan_level = #{planLevel}, + chemicals_name = #{chemicalsName}, + leakage_level = #{leakageLevel}, + + where id = #{id} + + + + delete from dc_event_important where id = #{id} + + + + delete from dc_event_important where id in + + #{id} + + + \ No newline at end of file diff --git a/zc-business/src/main/resources/mapper/business/DcEventMapper.xml b/zc-business/src/main/resources/mapper/business/DcEventMapper.xml index 590b58bf..97fb7fe1 100644 --- a/zc-business/src/main/resources/mapper/business/DcEventMapper.xml +++ b/zc-business/src/main/resources/mapper/business/DcEventMapper.xml @@ -4,43 +4,91 @@ "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + --> - + - SELECT - id, - dc_event.dept_id as dept_id, - sys_dept.dept_name, - stake_mark, - CASE direction - WHEN '1' THEN '菏泽方向' - WHEN '3' THEN '济南方向' - END AS direction, - dc_event.user_id as user_id, - sys_user.nick_name as nickName, - start_time, - end_time, - estimated_end_time, - event_level, - event_type, - event_title, - is_perceived, - CASE event_type - WHEN '1' THEN '交通事故' - WHEN '2' THEN '车辆故障' - WHEN '3' THEN '交通管制' - WHEN '4' THEN '交通拥堵' - WHEN '5' THEN '非法上路' - WHEN '6' THEN '路障清除' - WHEN '7' THEN '施工建设' - WHEN '8' THEN '服务区异常' - WHEN '9' THEN '设施设备隐患' - WHEN '10' THEN '异常天气' - WHEN '11' THEN '其他事件' - ELSE '其他' - END AS stringEventType, - CASE event_subclass - WHEN '1-1'THEN '追尾' - WHEN '1-2'THEN '侧翻' - WHEN '1-3'THEN '撞护栏' - WHEN '1-4'THEN '自然' - WHEN '1-5'THEN '其他事故' - WHEN '2-1'THEN '车辆故障' - WHEN '3-1'THEN '主线封闭和限行' - WHEN '3-2'THEN '收费站封闭和限行' - WHEN '3-3'THEN '立交封闭和限行' - WHEN '3-4'THEN '服务区封闭和限行' - WHEN '4-1'THEN '道路拥堵' - WHEN '4-2'THEN '立交拥堵' - WHEN '4-3'THEN '收费站拥堵' - WHEN '4-4'THEN '服务区拥堵' - WHEN '5-1'THEN '行人' - WHEN '5-2'THEN '非机动车' - WHEN '5-3'THEN '摩托车' - WHEN '5-4'THEN '其他' - WHEN '6-1'THEN '烟雾' - WHEN '6-2'THEN '倒伏树木' - WHEN '6-3'THEN '撒落物' - WHEN '6-4'THEN '动物' - WHEN '6-5'THEN '其他' - WHEN '7-1'THEN '道路养护施工' - WHEN '7-2'THEN '收费站养护施工' - WHEN '7-3'THEN '服务区养护施工' - WHEN '7-4'THEN '枢纽立交匝道养护施工' - WHEN '7-5'THEN '地方道路养护施工' - WHEN '7-6'THEN '道路工程建设施工' - WHEN '7-7'THEN '收费站工程建设施工' - WHEN '7-8'THEN '服务区工程建设施工' - WHEN '7-9' THEN '枢纽立交匝道工程建设施工' - WHEN '7-10' THEN'地方道路工程建设施工' - WHEN '8-1'THEN'封闭、暂停营业' - WHEN '8-2'THEN'重要设施停用' - WHEN '8-3'THEN'服务区其他异常' - WHEN '9-1'THEN'摄像机' - WHEN '9-2'THEN'护栏' - WHEN '9-3'THEN'隔离栅' - WHEN '9-4'THEN'情报板' - WHEN '9-5'THEN'防炫板' - WHEN '9-6'THEN'其他' - WHEN '10-1' THEN'雨' - WHEN '10-2' THEN'雪' - WHEN '10-3' THEN'雾' - WHEN '10-4' THEN'大风' - WHEN '10-5' THEN'低温寒潮' - WHEN '10-6' THEN'路面积雪' - WHEN '10-7' THEN'路面结冰' - WHEN '10-8' THEN'路面积水' - WHEN '10-9' THEN'其他' - WHEN '11-1' THEN'其他事件' - END AS event_subclass, - event_cause, - description, - dc_event.event_state, - CASE dc_event.event_state - WHEN '0' THEN '待确认' - WHEN '1' THEN '处理中' - WHEN '2' THEN '已完成' - WHEN '3' THEN '已撤销' - END AS stringEventState, - event_source, - CASE event_source - WHEN '1' THEN '96659' - WHEN '2' THEN '交警转接' - WHEN '3' THEN '道路巡查' - WHEN '4' THEN '视频巡查' - WHEN '5' THEN '视频AI' - WHEN '6' THEN '一键救援' - ELSE '其他' - END AS stringEventSource, - event_nature, - dc_event.remark as remark, - dc_event.create_time as create_time, - dc_event.update_time as update_time, - event_source_tips, - occurrence_time, - in_tunnel, - road_id, - lang - FROM - dc_event - LEFT JOIN sys_user on dc_event.user_id = sys_user.user_id - LEFT JOIN sys_dept on dc_event.dept_id = sys_dept.dept_id - - - select dc_event.id AS id, - dc_event.stake_mark, - dc_event.direction, - dc_event.is_perceived, - dc_event.user_id, - dc_event.start_time, - dc_event.end_time, - dc_event.occurrence_time, - dc_event.estimated_end_time, - dc_event.event_level, - dc_event.event_type AS event_type, + SELECT id, + dc_event.dept_id as dept_id, + sys_dept.dept_name, + stake_mark, + CASE direction + WHEN '1' THEN '菏泽方向' + WHEN '3' THEN '济南方向' + END AS direction, + dc_event.user_id as user_id, + sys_user.nick_name as nickName, + start_time, + end_time, + estimated_end_time, + event_level, + event_type, + longitude, + dimension, + event_title, + link_id, + is_perceived, + CASE event_type + WHEN '1' THEN '交通事故' + WHEN '2' THEN '车辆故障' + WHEN '3' THEN '交通管制' + WHEN '4' THEN '交通拥堵' + WHEN '5' THEN '非法上路' + WHEN '6' THEN '路障清除' + WHEN '7' THEN '施工建设' + WHEN '8' THEN '服务区异常' + WHEN '9' THEN '设施设备隐患' + WHEN '10' THEN '异常天气' + WHEN '11' THEN '其他事件' + ELSE '其他' + END AS stringEventType, + CASE event_subclass + WHEN '1-1' THEN '追尾' + WHEN '1-2' THEN '侧翻' + WHEN '1-3' THEN '撞护栏' + WHEN '1-4' THEN '自然' + WHEN '1-5' THEN '其他事故' + WHEN '2-1' THEN '车辆故障' + WHEN '3-1' THEN '主线封闭和限行' + WHEN '3-2' THEN '收费站封闭和限行' + WHEN '3-3' THEN '立交封闭和限行' + WHEN '3-4' THEN '服务区封闭和限行' + WHEN '4-1' THEN '道路拥堵' + WHEN '4-2' THEN '立交拥堵' + WHEN '4-3' THEN '收费站拥堵' + WHEN '4-4' THEN '服务区拥堵' + WHEN '5-1' THEN '行人' + WHEN '5-2' THEN '非机动车' + WHEN '5-3' THEN '摩托车' + WHEN '5-4' THEN '其他' + WHEN '6-1' THEN '烟雾' + WHEN '6-2' THEN '倒伏树木' + WHEN '6-3' THEN '撒落物' + WHEN '6-4' THEN '动物' + WHEN '6-5' THEN '其他' + WHEN '7-1' THEN '道路养护施工' + WHEN '7-2' THEN '收费站养护施工' + WHEN '7-3' THEN '服务区养护施工' + WHEN '7-4' THEN '枢纽立交匝道养护施工' + WHEN '7-5' THEN '地方道路养护施工' + WHEN '7-6' THEN '道路工程建设施工' + WHEN '7-7' THEN '收费站工程建设施工' + WHEN '7-8' THEN '服务区工程建设施工' + WHEN '7-9' THEN '枢纽立交匝道工程建设施工' + WHEN '7-10' THEN '地方道路工程建设施工' + WHEN '8-1' THEN '封闭、暂停营业' + WHEN '8-2' THEN '重要设施停用' + WHEN '8-3' THEN '服务区其他异常' + WHEN '9-1' THEN '摄像机' + WHEN '9-2' THEN '护栏' + WHEN '9-3' THEN '隔离栅' + WHEN '9-4' THEN '情报板' + WHEN '9-5' THEN '防炫板' + WHEN '9-6' THEN '其他' + WHEN '10-1' THEN '雨' + WHEN '10-2' THEN '雪' + WHEN '10-3' THEN '雾' + WHEN '10-4' THEN '大风' + WHEN '10-5' THEN '低温寒潮' + WHEN '10-6' THEN '路面积雪' + WHEN '10-7' THEN '路面结冰' + WHEN '10-8' THEN '路面积水' + WHEN '10-9' THEN '其他' + WHEN '11-1' THEN '其他事件' + END AS event_subclass, + event_cause, + description, + dc_event.event_state, + CASE dc_event.event_state + WHEN '0' THEN '待确认' + WHEN '1' THEN '处理中' + WHEN '2' THEN '已完成' + WHEN '3' THEN '已撤销' + END AS stringEventState, + event_source, + CASE event_source + WHEN '1' THEN '96659' + WHEN '2' THEN '交警转接' + WHEN '3' THEN '道路巡查' + WHEN '4' THEN '视频巡查' + WHEN '5' THEN '视频AI' + WHEN '6' THEN '一键救援' + ELSE '其他' + END AS stringEventSource, + event_nature, + dc_event.remark as remark, + dc_event.create_time as create_time, + dc_event.update_time as update_time, + event_source_tips, + occurrence_time, + in_tunnel, + road_id, + lang + FROM dc_event + LEFT JOIN sys_user on dc_event.user_id = sys_user.user_id + LEFT JOIN sys_dept on dc_event.dept_id = sys_dept.dept_id + - dc_event.event_subclass, - dc_event.event_cause, - dc_event.description, - dc_event.event_state, - dc_event.event_source, - dc_event.event_nature, - dc_event.remark, - dc_event.create_time, - dc_event.update_time, - dc_event.event_source_tips, - dc_event.in_tunnel, - dc_event.road_id, - dc_event.event_title, + select dc_event.id AS id, + dc_event.stake_mark, + dc_event.link_id, + dc_event.dimension, + dc_event.longitude, + dc_event.direction, + dc_event.is_perceived, + dc_event.user_id, + dc_event.start_time, + dc_event.end_time, + dc_event.occurrence_time, + dc_event.estimated_end_time, + dc_event.event_level, + dc_event.event_type AS event_type, - dc_event_type.event_name AS event_name, - dc_process_config.node_node AS node_node, - dc_process_config.process_node AS process_node, - dc_process_config.common_phrases AS common_phrases, - dc_dispatch.id AS dc_dispatch_id, - dc_dispatch.organization_id, - dc_dispatch.dispatch_name, - dc_dispatch.dispatch_status, - dc_dispatch.remark AS dc_dispatch_remark, - dc_dispatch.end_time AS dc_dispatch_end_time, - dc_dispatch.start_time AS dc_dispatch_start_time, - dc_dispatch.event_id, - dc_organization.id AS dc_organization_id, - dc_organization.parent_id, - dc_organization.organization_type, - dc_organization.organization_name, - dc_organization.organization_address, - dc_organization.stake_mark AS dc_organization_stake_mark, - dc_organization.rescue_unit, - dc_organization.description AS dc_organization_description, - dc_vehicles.vehicle_plate, - dc_vehicles.vehicle_type, - dc_vehicles.vehicle_status, - dc_vehicles.remark AS dc_vehicles_remark, - dc_employees.post_id, - dc_employees.NAME, - dc_employees.contact_number FROM dc_event + dc_event.event_subclass, + dc_event.event_cause, + dc_event.description, + dc_event.event_state, + dc_event.event_source, + dc_event.event_nature, + dc_event.remark, + dc_event.create_time, + dc_event.update_time, + dc_event.event_source_tips, + dc_event.in_tunnel, + dc_event.road_id, + dc_event.event_title, - + dc_event_type.event_name AS event_name, + dc_process_config.node_node AS node_node, + dc_process_config.process_node AS process_node, + dc_process_config.common_phrases AS common_phrases, + dc_dispatch.id AS dc_dispatch_id, + dc_dispatch.organization_id, + dc_dispatch.dispatch_name, + dc_dispatch.dispatch_status, + dc_dispatch.remark AS dc_dispatch_remark, + dc_dispatch.end_time AS dc_dispatch_end_time, + dc_dispatch.start_time AS dc_dispatch_start_time, + dc_dispatch.event_id, + dc_organization.id AS dc_organization_id, + dc_organization.parent_id, + dc_organization.organization_type, + dc_organization.organization_name, + dc_organization.organization_address, + dc_organization.stake_mark AS dc_organization_stake_mark, + dc_organization.rescue_unit, + dc_organization.description AS dc_organization_description, + dc_vehicles.vehicle_plate, + dc_vehicles.vehicle_type, + dc_vehicles.vehicle_status, + dc_vehicles.remark AS dc_vehicles_remark, + dc_employees.post_id, + dc_employees.NAME, + dc_employees.contact_number + FROM dc_event - - - + + + + - - insert into dc_event - - id, - dept_id, - stake_mark, - direction, - user_id, - start_time, - end_time, - estimated_end_time, - event_level, - event_type, - event_subclass, - event_cause, - description, - event_state, - event_source, - event_nature, - remark, - create_time, - update_time, - event_source_tips, - in_tunnel, - road_id, - lang, - event_title, - occurrence_time, - is_perceived, - - - #{id}, - #{deptId}, - #{stakeMark}, - #{direction}, - #{userId}, - #{startTime}, - #{endTime}, - #{estimatedEndTime}, - #{eventLevel}, - #{eventType}, - #{eventSubclass}, - #{eventCause}, - #{description}, - #{eventState}, - #{eventSource}, - #{eventNature}, - #{remark}, - #{createTime}, - #{updateTime}, - #{eventSourceTips}, - #{inTunnel}, - #{roadId}, - #{lang}, - #{eventTitle}, - #{occurrenceTime}, - #{isPerceived}, - - - - + + insert into dc_event + + id, + dept_id, + stake_mark, + direction, + user_id, + start_time, + end_time, + estimated_end_time, + event_level, + event_type, + event_subclass, + event_cause, + description, + event_state, + event_source, + event_nature, + remark, + create_time, + update_time, + event_source_tips, + in_tunnel, + road_id, + lang, + event_title, + occurrence_time, + is_perceived, + dimension, + longitude, + link_id, + + + #{id}, + #{deptId}, + #{stakeMark}, + #{direction}, + #{userId}, + #{startTime}, + #{endTime}, + #{estimatedEndTime}, + #{eventLevel}, + #{eventType}, + #{eventSubclass}, + #{eventCause}, + #{description}, + #{eventState}, + #{eventSource}, + #{eventNature}, + #{remark}, + #{createTime}, + #{updateTime}, + #{eventSourceTips}, + #{inTunnel}, + #{roadId}, + #{lang}, + #{eventTitle}, + #{occurrenceTime}, + #{isPerceived}, + #{dimension}, + #{longitude}, + #{linkId}, + + + + insert into dc_event id, @@ -575,6 +597,8 @@ event_title, occurrence_time, is_perceived, + dimension, + longitude, #{dcEvent.id}, @@ -603,70 +627,111 @@ #{dcEvent.eventTitle}, #{dcEvent.occurrenceTime}, #{dcEvent.isPerceived}, + #{dcEvent.dimension}, + #{dcEvent.longitude}, - update dc_event - - dept_id = #{deptId}, - stake_mark = #{stakeMark}, - direction = #{direction}, - user_id = #{userId}, - start_time = #{startTime}, - end_time = #{endTime}, - estimated_end_time = #{estimatedEndTime}, - event_level = #{eventLevel}, - event_type = #{eventType}, - event_subclass = #{eventSubclass}, - event_cause = #{eventCause}, - description = #{description}, - event_state = #{eventState}, - event_source = #{eventSource}, - event_nature = #{eventNature}, - remark = #{remark}, - create_time = #{createTime}, - update_time = #{updateTime}, - event_source_tips = #{eventSourceTips}, - in_tunnel = #{inTunnel}, - road_id = #{roadId}, - road_id = #{lang}, - event_title = #{eventTitle}, - occurrence_time = #{occurrenceTime}, - is_perceived = #{isPerceived}, - - where id = #{id} - + update dc_event + + dept_id = #{deptId}, + stake_mark = #{stakeMark}, + direction = #{direction}, + user_id = #{userId}, + start_time = #{startTime}, + end_time = #{endTime}, + estimated_end_time = #{estimatedEndTime}, + event_level = #{eventLevel}, + event_type = #{eventType}, + event_subclass = #{eventSubclass}, + event_cause = #{eventCause}, + description = #{description}, + event_state = #{eventState}, + event_source = #{eventSource}, + event_nature = #{eventNature}, + remark = #{remark}, + create_time = #{createTime}, + update_time = #{updateTime}, + event_source_tips = #{eventSourceTips}, + in_tunnel = #{inTunnel}, + road_id = #{roadId}, + road_id = #{lang}, + event_title = #{eventTitle}, + occurrence_time = #{occurrenceTime}, + is_perceived = #{isPerceived}, + dimension = #{dimension}, + longitude = #{longitude}, + link_id = #{linkId}, + + where id = #{id} + + + update dc_event + + dept_id = #{deptId}, + stake_mark = #{stakeMark}, + direction = #{direction}, + user_id = #{userId}, + start_time = #{startTime}, + end_time = #{endTime}, + estimated_end_time = #{estimatedEndTime}, + event_level = #{eventLevel}, + event_type = #{eventType}, + event_subclass = #{eventSubclass}, + event_cause = #{eventCause}, + description = #{description}, + event_state = #{eventState}, + event_source = #{eventSource}, + remark = #{remark}, + create_time = #{createTime}, + update_time = #{updateTime}, + event_source_tips = #{eventSourceTips}, + in_tunnel = #{inTunnel}, + road_id = #{roadId}, + road_id = #{lang}, + event_title = #{eventTitle}, + occurrence_time = #{occurrenceTime}, + is_perceived = #{isPerceived}, + dimension = #{dimension}, + + event_nature = #{eventNature}, + link_id = #{linkId}, + + where id = #{id} + + - - delete from dc_event where id = #{id} - + + delete + from dc_event + where id = #{id} + - - delete from dc_event where id in - - #{id} - - + + delete from dc_event where id in + + #{id} + + - + - + - + SELECT s.status, + COALESCE(t.count, 0) AS count FROM ( SELECT 0 AS event_state, 'state0Count' AS status UNION ALL SELECT 1 AS event_state, 'state1Count' AS status UNION ALL @@ -674,9 +739,33 @@ SELECT 3 AS event_state, 'state3Count' AS status ) s LEFT JOIN ( - SELECT event_state, COUNT(*) AS count + SELECT event_state, COUNT (*) AS count FROM dc_event GROUP BY event_state - ) t ON s.event_state = t.event_state; + ) t + ON s.event_state = t.event_state; + + + + + + + update dc_event + + event_state = #{state}, + + where id = #{id} + + + + update dc_event set end_time = now(),event_state = '2' + where id = #{eventId} + \ No newline at end of file diff --git a/zc-business/src/main/resources/mapper/business/DcEventProcessMapper.xml b/zc-business/src/main/resources/mapper/business/DcEventProcessMapper.xml index d0a8053f..28e045e5 100644 --- a/zc-business/src/main/resources/mapper/business/DcEventProcessMapper.xml +++ b/zc-business/src/main/resources/mapper/business/DcEventProcessMapper.xml @@ -14,10 +14,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + - select id, event_id, operation_time, operator, source, process_type, context, process_id, process_name from dc_event_process + select id, event_id, operation_time, operator, source, process_type, context, process_id, process_name, `type` from dc_event_process + \ No newline at end of file diff --git a/zc-business/src/main/resources/mapper/business/EventPlanAssocMapper.xml b/zc-business/src/main/resources/mapper/business/EventPlanAssocMapper.xml index 82941ea3..58efcd2c 100644 --- a/zc-business/src/main/resources/mapper/business/EventPlanAssocMapper.xml +++ b/zc-business/src/main/resources/mapper/business/EventPlanAssocMapper.xml @@ -7,36 +7,36 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" insert into event_plan_assoc + id, event_id, emergency_plans_id, - executing_control_device, - recovered_control_device, + control_device, + operation_type, create_time, update_time, - executing_control_result, - recovered_control_result, + control_result, + #{id}, #{eventId}, #{emergencyPlansId}, - #{executingControlDevice}, - #{recoveredControlDevice}, + #{controlDevice}, + #{operationType}, #{createTime}, #{updateTime}, - #{executingControlResult}, - #{recoveredControlResult} + #{controlResult}, - select id,event_id,emergency_plans_id,executing_control_device,recovered_control_device,create_time,update_time, - executing_control_result,recovered_control_result + select id,event_id,emergency_plans_id,control_device,create_time,update_time, + control_result,operation_type from event_plan_assoc @@ -44,18 +44,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" event_id = #{eventId}, emergency_plans_id = #{emergencyPlansId}, - - executing_control_device = #{executingControlDevice}, + + control_device = #{controlDevice}, - - recovered_control_device = #{recoveredControlDevice}, + + operation_type = #{operationType}, update_time = #{updateTime}, - - executing_control_result = #{executingControlResult}, - - - recovered_control_result = #{recoveredControlResult}, + + control_result = #{controlResult}, where id = #{id} diff --git a/zc-business/src/main/resources/wordTemplate/importantTemplate.docx b/zc-business/src/main/resources/wordTemplate/importantTemplate.docx new file mode 100644 index 00000000..c389ddbd Binary files /dev/null and b/zc-business/src/main/resources/wordTemplate/importantTemplate.docx differ