diff --git a/dk-api/api-business/src/main/java/org/dromara/business/api/domain/RemoteBusinessAlertRequest.java b/dk-api/api-business/src/main/java/org/dromara/business/api/domain/RemoteBusinessAlertRequest.java new file mode 100644 index 0000000..81b8ae1 --- /dev/null +++ b/dk-api/api-business/src/main/java/org/dromara/business/api/domain/RemoteBusinessAlertRequest.java @@ -0,0 +1,20 @@ +package org.dromara.business.api.domain; + +import lombok.Data; +import org.dromara.business.api.domain.vo.RemoteBusinessAlertVo; + +import java.util.List; + +/** + * 预警任务对象 business_alert + * + * @author LionLi + * @date 2025-02-27 + */ +@Data +public class RemoteBusinessAlertRequest { + + private List alertVoList; + private String activeProfile; + +} diff --git a/dk-api/api-system/src/main/java/org/dromara/system/api/RemoteConfigService.java b/dk-api/api-system/src/main/java/org/dromara/system/api/RemoteConfigService.java index dbf88c8..42e1dc6 100644 --- a/dk-api/api-system/src/main/java/org/dromara/system/api/RemoteConfigService.java +++ b/dk-api/api-system/src/main/java/org/dromara/system/api/RemoteConfigService.java @@ -23,6 +23,8 @@ public interface RemoteConfigService { */ String selectStreamIp(); + boolean selectXingluoAutoSubmit(); + // List selectStreamType(String deviceSn); } diff --git a/dk-api/api-system/src/main/java/org/dromara/system/api/RemoteDeptService.java b/dk-api/api-system/src/main/java/org/dromara/system/api/RemoteDeptService.java index d40fc45..13cc9c3 100644 --- a/dk-api/api-system/src/main/java/org/dromara/system/api/RemoteDeptService.java +++ b/dk-api/api-system/src/main/java/org/dromara/system/api/RemoteDeptService.java @@ -24,9 +24,11 @@ public interface RemoteDeptService { RemoteDeptVo selectDeptById(Long deptId); - List> getNamePathList(); + List> getNamePathList(Long deptId); List selectListByParentId(String deptId); RemoteDeptVo getByParentId(String deptId); + + List listTreeDeptByChild(Long deptId); } diff --git a/dk-api/api-system/src/main/java/org/dromara/system/api/RemoteSubmailConfigService.java b/dk-api/api-system/src/main/java/org/dromara/system/api/RemoteSubmailConfigService.java index 4bc2563..ee3af3a 100644 --- a/dk-api/api-system/src/main/java/org/dromara/system/api/RemoteSubmailConfigService.java +++ b/dk-api/api-system/src/main/java/org/dromara/system/api/RemoteSubmailConfigService.java @@ -3,6 +3,10 @@ package org.dromara.system.api; import org.dromara.common.core.domain.R; import org.dromara.system.api.domain.vo.RemoteClientVo; +import java.util.List; +import java.util.Map; +import java.util.Set; + /** * 客户端服务 * @@ -17,4 +21,11 @@ public interface RemoteSubmailConfigService { */ R remoteCmdSend(String code, String multiParam ); + /** + * @param code 编码 + * @param alertList 预警信息 + * @return 客户端对象 + */ + void remoteSend(String code,List> alertList); + } diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/ErrorCodeEnum.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/ErrorCodeEnum.java new file mode 100644 index 0000000..b1aebbc --- /dev/null +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/debug/ErrorCodeEnum.java @@ -0,0 +1,615 @@ +package org.dromara.common.sdk.cloudapi.debug; + +import org.dromara.common.sdk.common.IErrorInfo; +import org.dromara.common.sdk.mqtt.events.IEventsErrorCode; +import org.dromara.common.sdk.mqtt.services.IServicesErrorCode; + +import java.util.Arrays; + +/** + * @author sean.zhou + * @version 0.1 + * @date 2021/11/25 + */ +public enum ErrorCodeEnum implements IServicesErrorCode, IEventsErrorCode, IErrorInfo { + E219004(219004, "飞行任务已过期,无法执行(上云重新选择任务执行时间:任务过期) 机场日志"), + E219014(219014, "机场不属于该项目,无法执行当前操作或执行飞行任务,请将机场迁回该项目或到机场所在项目重试(机场不属于该项目,权限隔离:检查机场工作项目是否匹配) 机场日志"), + E219016(219016, "飞行任务已被挂起,无法执行(任务挂起:检查任务是否挂起) 机场日志"), + E219018(219018, "机场执行飞行任务过程中超时未响应,1小时未上报任何状态(设备离线或设备mqtt连接中断,无法上报信息:1.检查机场是否开机 2.检查机场网络是否正常 3.如仍未解决拉取机场日志反馈售后分析。) 机场日志"), + E219101(219101, "服务器异常,请稍后重试(dtcp服务异常:拉取机场日志联系售后分析。) 机场日志"), + E219102(219102, "机场已离线,无法执行飞行任务,请检查机场是否已断电,机场网络连接是否正常(设备离线或设备mqtt连接中断,无法上报信息:1.检查机场是否开机 2.检查机场网络是否正常 3.如仍未解决问题拉取机场日志联系售后分析) 机场日志"), + E219103(219103, "项目中不存在此机场,无法执行飞行任务(机场不属于该项目,权限隔离:1.检查机场工作项目是否匹配) 机场日志"), + E219104(219104, "服务器内部错误,无法执行飞行任务(服务配置错误,无法识别该命令:拉取机场日志反馈售后分析) 机场日志"), + E219105(219105, "云端与机场通信异常,无法执行飞行任务(机场没有在10s内回复任务命令reply:拉取机场日志反馈售后分析) 机场日志"), + E219304(219304, "机场数据雨量过大(天气阻飞:检查是否开启项目在线天气阻飞,如没有则为气象站阻飞) 机场日志"), + E219305(219305, "机场数据风速过大(天气阻飞:检查是否开启项目在线天气阻飞,如没有则为气象站阻飞) 机场日志"), + E312001(312001, "一致性升级失败(触发一致性升级,但设备没有请求一致性升级,会返回该错误码:尝试在固件升级时开启无人机,并关闭无人机的4G增强)"), + E312003(312003, "固件升级失败(校验文件MD5失败:检查下发文件的MD5)"), + E312010(312010, "固件升级错误(下发的升级请求命令与协议不符合:1、检查下发mqtt命令格式是否有误。注意文件大小是整数类型,不是字符串 2、回复ota_progress方法可以停止错误推送)"), + E312013(312013, "固件升级失败(需要关闭4G,并在无人机开机状态下更新固件:请检查固件升级包是否匹配对应机型)"), + E312014(312014, "设备升级中,请勿重复操作"), + E312015(312015, "机场:{dock_org_name} 业务繁忙无法进行设备升级,请等待机场处于空闲中后再试"), + E312016(312016, "升级失败,机场和飞行器图传链路异常,请重启机场和飞行器后重试"), + E312022(312022, "飞行器开机失败或未连接,请检查飞行器是否在舱内,是否安装电池,机场和飞行器是否已对频"), + E312023(312023, "推杆闭合失败无法升级飞行器,请检查急停按钮是否被按下,推杆是否有异物卡住"), + E312026(312026, "离线升级包解压失败 检查一下下载的离线固件包是否损坏,或者重新下发一下"), + E312027(312027, "升级失败,机场未检测到飞行器"), + E312028(312028, "升级失败,设备升级过程中设备被重启"), + E312029(312029, "设备重启中无法进行设备升级,请等待设备重启完成后重试"), + E312030(312030, "升级失败,飞行器增强图传开启后无法升级,请关闭飞行器增强图传后重试"), + E312031(312031, "重试升级出错 可能是传输断开 重启飞机和飞行器后重试,确保机场网络可以访问到指令的文件下载地址"), + E312306(312306, "升级失败,固件文件包下载失败,网络异常,请检查网络状态 网络环境导致固件下载失败"), + E312307(312307, "升级失败,固件文件包下载失败,网络异常,请检查网络状态 网络异常、网络差、有防火墙等"), + E312502(312502, "升级失败 无"), + E312527(312527, "文件错误或者被删除 检查传入的file地址是否能访问到,并且点击连接可以下载文件。"), + E312534(312534, "飞机升级失败,飞机在机场重启失败。 1、检查无人机开机。 2、关闭无人机和机场的4G增强,拔掉4G模块。 3、固件有防回滚,不可降级"), + E312704(312704, "飞行器电量过低,请充电至20%以上后重试"), + E314000(314000, "设备当前无法支持该操作,建议检查设备当前工作状态"), + E314001(314001, "飞行任务下发失败,请稍后重试 机场日志 司空2服务异常 拉取机场日志反馈售后分析。"), + E314002(314002, "飞行任务下发失败,请稍后重试 任务没下发fingerprint"), + E314003(314003, "航线文件格式不兼容,请检查航线文件是否正确"), + E314004(314004, "飞行任务下发失败,请稍后重试或重启机场后重试(文件地址获取不到) 机场日志 1. 机场网络不稳定存在数据波动 2. 网络DNS服务器解析失败 1、检查机场和飞机的固件版本是否配套,具体配套版本可以查看机场的发布记录或者上云API 版本的发布记录。 2、检查下发任务中的URL是否正确,在浏览器中输入该URL,需要能够自动触发下载。 3、检查机场网络是否能够访问该下发任务中的URL。 4、检查云端服务是否正常回复了机场请求的任务资源获取接口。(云端一定要回复该接口,机场才能正常获取航线文件) 5、如果同一个航线文件有时可以正常执行,有时却报错,需要排查机场的网络带宽是否稳定。"), + E314005(314005, "飞行任务下发失败,请稍后重试或重启机场后重试"), + E314006(314006, "飞行器初始化失败,请重启机场后重试"), + E314007(314007, "机场传输航线至飞行器失败,请重启机场后重试 机场日志、飞机日志 1、图传信号质量不佳 2、设备存在异常 1、重启机场和飞行器重试 2、交叉验证飞行器或机场的图传功能是否正常 3、拉取机场和飞行器日志提单给售后分析 4、检查机场拖链处馈线是否发生断裂,主控模块处SMA接口是否拧紧 5、飞机与机场的图传信息指令不佳导致,检查图传信号 6、检查航线文件是否有问题。可以用Pilot上传航线文件到飞机,看看能不能识别。 7、第一个航点不能设置isRisky为true"), + E314008(314008, "飞行器起飞前准备超时,请重启机场后重试"), + E314009(314009, "飞行器初始化失败,请重启机场后重试"), + E314010(314010, "航线执行失败,请重启机场后重试 机场日志、飞机日志 1、航线距离机场过远 2、航线未知原因退出 1、重新下发任务 2、重启机场再次尝试 3、多次尝试仍未解决拉取机场和飞机日志联系售后分析"), + E314011(314011, "机场系统异常,无法获取飞行任务执行结果 重启机场再次尝试"), + E314012(314012, "飞行器起飞前准备失败,无法执行飞行任务,请重启机场后重试 机场日志、飞机日志 1、固件版本过低 2、设备逻辑异常 1、请升级最新固件 2、如果升级后还有问题,请检查是否有阻飞的HMS上报,按对应提示排查解决 3、如果仍无法解决请拉取机场和飞行器日志联系售后分析 4、检查飞机固件与机场固件是否匹配"), + E314013(314013, "飞行任务下发失败,机场无法获取到本次飞行任务的航线,无法执行飞行任务,请稍后重试 机场日志、飞机日志 机场异常重启(上一次任务未执行完成,本地缓存了该任务执行信息,下次启动会将上次任务结果上报) 1、重新下发任务 2、多次尝试仍未解决拉取机场和飞机日志联系售后分析 https://sdk-forum.dji.net/hc/zh-cn/articles/16745838728985"), + E314014(314014, "机场系统异常,飞行任务执行失败,请稍后重试 机场日志 机场异常重启(上一次任务未执行完成,本地缓存了该任务执行信息,下次启动会将上次任务结果上报) 1、重新下发任务 2、如果重新下发任务无法恢复,需要关掉“设备运维界面”里面的“用户改善计划”"), + E314015(314015, "机场传输精准复拍航线至飞行器失败,无法执行飞行任务,请稍后重试或重启机场后重试"), + E314016(314016, "航线文件解析失败,无法执行飞行任务,请检查航线文件 机场不支持执行除了精准复拍外的其他航线类型,KMZ超过1MB 删除KMZ中的res目录(地形信息)"), + E314017(314017, "机场系统异常,飞行任务执行失败,请稍后重试 精准复拍类型KMZ文件错误"), + E314018(314018, "飞行器RTK定位异常,无法执行飞行任务,请稍后重试或重启机场后重试"), + E314019(314019, "飞行器RTK收敛失败,无法执行飞行任务,请稍后重试或重启机场后重试"), + E314020(314020, "飞行器不在停机坪正中间或飞行器朝向不正确,无法执行飞行任务,请检查飞行器位置和朝向 机场日志、飞机日志 1、飞行器不在机场停机坪正中间或飞行器摆放方向不正确 2、电离层闪烁 3、飞行器内部定位异常 1、确认飞机在机场上的摆放位置和方向是否正确 2、确认没有电离层闪烁现象 3、查看HMS报错信息,根据提示进行排查 4、重启飞行器,多次重启后仍存在问题请拉取机场和飞行器日志联系售后分析"), + E314021(314021, "飞行器RTK定位异常,无法执行飞行任务,请稍后重试或重启机场后重试 机场日志、飞机日志 1、电离层闪烁 2、飞行器内部定位异常 1、确认没有电离层闪烁现象 2、查看HMS报错信息 3、重启飞行器,多次重启后仍存在问题请拉取机场和飞行器日志联系售后分析"), + E314024(314024, "进离场航线下发失败,请稍后重试或重启机场后重试"), + E314025(314025, "RTK收敛超时,用户手动取消任务"), + E314200(314200, "任务失败,由于机场网络断开,飞行器已自动返航,请确保机场已连接网络后再试 检查机场网络情况,然后重试 机场与MQTT之间的连接断开。检查网络情况"), + E315000(315000, "机场通信异常,请重启机场后重试"), + E315001(315001, "A起B降-起飞机场设置SDR拓扑信息失败 1、机场通信异常,请远程开启飞机并等待1分钟后,再次下发任务重试 2、sdr_id信息有误"), + E315002(315002, "A起B降-降落机场设置编号失败 云端回复机场时不要超过30秒,不要过慢,信息保证准确。失败就需要从头重试"), + E315003(315003, "机场通信异常,请重启机场后重试"), + E315004(315004, "任务失败,请等待两个机场都空闲后,再次下发任务重试"), + E315005(315005, "机场通信异常,请重启机场后重试"), + E315006(315006, "机场通信异常,请重启机场后重试"), + E315007(315007, "机场通信异常,请将机场升级到最新版本或重启机场后重试 RTK异常,RTK配置信息失败 1、确保起飞时RTK收敛 2、二代机库即使是模拟飞行也要保证RTK收敛才可以模拟"), + E315008(315008, "降落机场和起飞机场标定信息不一致,请确认两个机场均链路通畅且使用了相同的网络信息标定"), + E315009(315009, "机场通信异常,请重启机场后重试 固件潜在问题,等待固件更新"), + E315010(315010, "无法停止飞行任务,请稍后重试,如果仍报错请联系大疆售后"), + E315011(315011, "无法停止飞行任务,请稍后重试,如果仍报错请联系大疆售后"), + E315012(315012, "无法停止飞行任务,请稍后重试,如果仍报错请联系大疆售后"), + E315013(315013, "飞行任务下发失败,请稍后重试,如果仍报错请联系大疆售后"), + E315014(315014, "当前任务类型不支持设置返航点"), + E315015(315015, "返航点设置失败,请稍后重试,如果仍报错请联系大疆售后"), + E315016(315016, "飞行任务下发失败,请稍后重试,如果仍报错请联系大疆售后 蛙跳任务中回复的机场current_step有误,与机场的实际状态不匹配"), + E315017(315017, "飞行任务下发失败,请稍后重试,如果仍报错请联系大疆售后"), + E315018(315018, "任务失败,请等待两个机场都空闲后,再次下发任务重试"), + E315019(315019, "设备部署位置不佳,无法执行蛙跳任务,请选择其他机场再试"), + E315050(315050, "机场系统异常,请重启机场后重试"), + E315051(315051, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后"), + E315052(315052, "机场位置未收敛,请等待一段时间后重试"), + E315053(315053, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后"), + E315054(315054, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后"), + E315055(315055, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后"), + E315056(315056, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后"), + E315057(315057, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后"), + E315058(315058, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后"), + E315059(315059, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后"), + E315060(315060, "A起B降-SDR信息中,A控数量分配过多 蛙跳任务飞机的控制源设置错误,可能两个机场的control_source_index都是1"), + E315061(315061, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后"), + E315062(315062, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后 检查蛙跳任务是否缺少参数"), + E315063(315063, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后"), + E315064(315064, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后"), + E315065(315065, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后"), + E316001(316001, "备降点设置失败"), + E316002(316002, "备降安全转移高度设置失败"), + E316003(316003, "飞行器参数配置失败,请重启机场后重试 机场日志、飞机日志 设置起飞高度失败(图传链路不稳导致) 1、重新下发任务 2、重试多次后依然存在请拉取机场和飞行器日志"), + E316004(316004, "失控行为设置失败"), + E316005(316005, "飞行器RTK收敛失败,无法执行飞行任务,请稍后重试或重启机场后重试 机场日志、飞机日志 1、安装环境存在遮挡 2、电离层闪烁 3、机场RTK未标定 4、图传断链 5、设备工作异常 1、确认APP踏勘选址结果是否大于80分 2、确认没有电离层闪烁现象 3、确认机场RTK完成标定 4、重新下发任务 5、重试多次依然失败后拉取机场和飞机的日志"), + E316006(316006, "任务超时,飞行器已丢失或降落时机场未开启舱盖或展开推杆,飞行器无法降落回机场,请尽快至机场部署现场检查飞行器状况"), + E316007(316007, "飞行器初始化失败,请重启机场后重试"), + E316008(316008, "机场获取飞行器控制权失败,无法执行飞行任务,请确认遥控器未锁定控制权 机场日志、飞机日志 1、飞行控制权获取失败 2、遥控器B控接管后锁定控制权 3、机场与飞行器图传链路逻辑错误 1、确认飞机和机场已经对频 2、如有B控连接,请关闭遥控器后重试 3、重启机场和飞行器重试"), + E316009(316009, "飞行器电量低,无法执行飞行任务,请充电后(建议≥50%)重试 机场日志、飞机日志 飞行器电量不足 等待充电至30%以上"), + E316010(316010, "机场未检测到飞行器,无法执行飞行任务,请检查舱内是否有飞行器,机场与飞行器是否已对频,或重启机场后重试 机场日志、飞机日志 1、图传未推送飞控OSD 2、飞行器与机场图传链路不稳定 1、重启飞行器和机场,重新下发任务 2、多次下发依然不行,请拉取机场和飞机日志进一步分析"), + E316011(316011, "飞行器降落位置偏移过大,请检查飞行器是否需要现场摆正"), + E316012(316012, "飞行器起飞前准备失败,无法执行飞行任务,请重启机场后重试 1、图传质量差导致 2、检查flight id是否有下划线或其它特殊字符"), + E316013(316013, "电池电量查询失败"), + E316014(316014, "飞行器起飞前准备失败,无法执行飞行任务,请重启机场后重试"), + E316015(316015, "飞行器RTK收敛位置距离机场过远,无法执行飞行任务,请重启机场后重试 机场日志、飞机日志 1、安装环境存在遮挡 2、电离层闪烁 3、设备工作异常 1、确认APP踏勘选址结果是否大于80分 2、确认没有电离层闪烁现象 3、确认机场RTK完成标定 4、重新下发任务 5、重试多次依然失败后拉取机场和飞机的日志"), + E316016(316016, "飞行器降落至机场超时,可能是机场与飞行器断连导致,请通过直播查看飞行器是否降落至舱内"), + E316017(316017, "获取飞行器媒体数量超时,可能是机场与飞行器断连导致,请通过直播查看飞行器是否降落至舱内"), + E316018(316018, "飞行任务执行超时,可能是机场与飞行器断连导致,请通过直播查看飞行器是否降落至舱内"), + E316019(316019, "机场系统错误,无法执行飞行任务,请稍后重试"), + E316020(316020, "飞行器使用的RTK信号源错误,请稍后重试 机场日志、飞机日志 1、飞行器RTK源使用错误 2、飞行器在与机场对频使用前连接过D-RTK2基站/网络RTK/自定义网络RTK等 1、重新下发任务 2、多次下发依然异常,请拉取机场和飞机日志联系售后分析"), + E316021(316021, "飞行器RTK信号源检查超时,请稍后重试 机场日志、飞机日志 图传断链不稳定 1、重启飞行器和机场,重新下发任务 2、多次下发依然不行,请拉取机场和飞机日志进一步分析"), + E316022(316022, "飞行器无法执行返航指令,请检查飞行器是否已开机,机场与飞行器是否已断连,请确认无以上问题后重试"), + E316023(316023, "飞行器无法执行返航指令,飞行器已被B控接管,请在B控操控飞行器,或关闭B控后重试"), + E316024(316024, "飞行器执行返航指令失败,请检查飞行器是否已起飞,确认飞行器已起飞后请重试"), + E316025(316025, "飞行器参数配置失败,请稍后重试或重启机场后重试 设置返航高度失败 返航高度的格式不是整数类型"), + E316026(316026, "机场急停按钮被按下,无法执行飞行任务,请释放急停按钮后重试 机场日志、飞机日志 急停按钮被按下 向外拔出急停按钮"), + E316027(316027, "飞行器参数配置超时,请稍后重试或重启机场后重试"), + E316029(316029, "机场急停按钮被按下,飞行器将飞往备降点降落,请立即检查飞行器是否已安全降落并将飞行器放回至机场"), + E316030(316030, "返航点刷新失败,请稍后重试 机场日志、飞机日志 链路不稳定 1、重启飞行器和机场,重新下发任务 2、多次下发依然不行,请拉取机场和飞机日志进一步分析"), + E316031(316031, "机场系统运行异常,请重新下发任务 机场日志、飞机日志 设置返航模式失败;二代机库下发任务需指定返航模式"), + E316032(316032, "获取电池数据超时,请稍后重试或重启飞行器后重试 机场日志、飞机日志 图传丢包 1、重新下发任务 2、多次下发依然异常,请拉取机场和飞机日志联系售后分析"), + E316033(316033, "飞行器电池循环次数过高,为保证飞行安全,已自动终止任务,建议更换该电池 机场日志、飞机日志 电池循环次数超过500次 1、检查电池循环次数是否过高 2、确认没有超过500次需要拉取机场和飞机日志联系售后分析"), + E316034(316034, "无法起飞,飞行器固件版本与机场固件版本不匹配,为保证飞行安全请升级固件后再试 升级机场和飞机固件到最新版本"), + E316035(316035, "进离场航线下发失败,请确保设备固件为最新版本后重新下发任务,如果持续报错,请联系大疆售后。"), + E316050(316050, "飞行器因电量过低在舱外降落,请立即检查飞行器是否已安全降落并将飞行器放回至机场"), + E316051(316051, "飞行任务异常,飞行器在舱外降落,请立即检查飞行器是否已安全降落并将飞行器放回至机场"), + E316052(316052, "飞行任务异常,飞行器将飞往备降点降落,请立即检查飞行器是否已安全降落并将飞行器放回至机场"), + E316053(316053, "用户已操控飞行器降落,请立即检查飞行器是否已安全降落并将飞行器放回至机场"), + E316054(316054, "无法启动模拟器,启动模拟器需要RTK收敛"), + E316100(316100, "获取相机概要信息失败,请重试"), + E316101(316101, "设置相机为单拍模式失败,请重试"), + E316102(316102, "关闭相机水印失败,请重试"), + E316103(316103, "设置测光模式为平均测光失败,请重试"), + E316104(316104, "切换镜头到广角镜头失败,请重试"), + E316105(316105, "设置相机存储照片失败,请重试"), + E316106(316106, "红外变焦倍数设置失败,请重试"), + E316107(316107, "照片尺寸设置为4K失败,请重试"), + E316108(316108, "设置照片存储格式为JPEG失败,请重试"), + E316109(316109, "关闭相机畸变矫正失败,请重试"), + E316110(316110, "打开相机机械快门失败,请重试"), + E316111(316111, "设置对焦模式失败,请重试"), + E317001(317001, "获取飞行器媒体文件数量失败,请重启机场后重试"), + E317002(317002, "飞行器存储格式化失败,飞行器未开机、未连接或未检测到相机,请确认无以上问题后重试,或重启飞行器后重试"), + E317003(317003, "飞行器存储格式化失败,请重启飞行器后重试"), + E317004(317004, "机场媒体文件格式化失败,请稍后重试或重启机场后重试"), + E317005(317005, "飞行器结束录像失败,本次飞行任务的媒体文件可能无法上传 调用结束录像的方法时飞行器已经退出指令飞行模式,需在指令飞行模式下结束录像。"), + E317006(317006, "无法格式化,请等待当前飞行器媒体文件下载完成后再试"), + E317007(317007, "获取媒体文件数量失败,请稍后重试,如本架次任务有媒体文件且持续报错可联系大疆售后"), + E318101(318101, "飞行因HMS告警,无法执行飞行任务 检查HMS相关告警"), + E319001(319001, "机场作业中或设备异常反馈上传日志中,无法执行飞行任务,请等待当前飞行任务或操作执行完成后重试"), + E319002(319002, "机场系统运行异常,请重启机场后重试 机场日志、飞机日志 机场内部通讯异常 1、重启飞行器和机场,重新下发任务 2、多次下发依然不行,请拉取机场和飞机日志进一步分析"), + E319003(319003, "机场系统运行异常,请重新下发任务 机场日志、飞机日志 1、云端下发了不存在的flight_id任务 2、机场内部缓存任务异常 1、重启飞行器和机场,重新下发任务 2、多次下发依然不行,请拉取机场和飞机日志进一步分析 3、是否任务下发过于频繁 4、任务执行时间是否超出execute_time前后30秒。"), + E319004(319004, "飞行任务执行超时,已自动终止本次飞行任务 机场日志、飞机日志 机场与云端时间不同步 1、检查机场与云端时间是否一致 2、任务下发与执行指令间隔不得超过30秒 3、断点续飞时mission_id需与之前的航线mission_id不同"), + E319005(319005, "云端与机场通信异常,无法执行飞行任务 机场日志、飞机日志 机场与云端时间不同步 1、重启飞行器和机场,重新下发任务 2、多次下发依然不行,请拉取机场和飞机日志进一步分析"), + E319006(319006, "取消飞行任务失败,飞行任务已经在执行中"), + E319007(319007, "修改飞行任务失败,飞行任务已经在执行中"), + E319008(319008, "机场时间与云端时间不同步,机场无法执行飞行任务 机场日志 机场与云端时间不同步 1、重启飞行器和机场,重新下发任务 2、多次下发依然不行,请拉取机场和飞机日志进一步分析 3、若内网服务器与设备时间存在误差,需要在服务器上搭建NTP服务器,通过配置接口同步设备时间。"), + E319009(319009, "飞行任务下发失败,请稍后重试或重启机场后重试"), + E319010(319010, "机场固件版本过低,无法执行飞行任务,请升级机场固件为最新版本后重试"), + E319015(319015, "机场正在初始化中,无法执行飞行任务,请等待机场初始化完成后重试"), + E319016(319016, "机场正在执行其他飞行任务,无法执行本次飞行任务 机场日志、飞机日志 机场正在执行上一个任务 等待上个任务执行完成,再下发任务"), + E319017(319017, "机场正在处理上次飞行任务媒体文件,无法执行本次飞行任务,请稍后重试 机场日志、飞机日志 1、机场正在获取飞行器媒体列表 2、上个任务未收到云端ACK消息 等待列表获取完成"), + E319018(319018, "机场正在自动导出日志(设备异常反馈),无法执行飞行任务,请稍后重试"), + E319019(319019, "机场正在拉取日志(设备异常反馈),无法执行飞行任务,请稍后重试 检查是否调用了拉取日志功能"), + E319020(319020, "航线中断失败,请稍后重试"), + E319021(319021, "退出远程控制失败,请稍后重试"), + E319022(319022, "指点飞行失败,请稍后重试"), + E319023(319023, "指点飞行停止失败,请稍后重试"), + E319024(319024, "一键起飞失败,请稍后重试"), + E319025(319025, "机场未准备完成,无法执行云端下发的飞行任务,请稍后重试"), + E319026(319026, "飞行器电池电量低于用户设置的任务开始执行电量,请等待充电完成后再执行飞行任务"), + E319027(319027, "机场或飞行器剩余存储容量过低,无法执行飞行任务,请等待媒体文件上传释放存储后再执行飞行任务"), + E319028(319028, "正在更新自定义飞行区"), + E319029(319029, "正在更新离线地图"), + E319030(319030, "操作失败,无飞行器控制权 DRC控制需要在1分钟内至少下发一次心跳。"), + E319031(319031, "控制权异常,请刷新重试 使用Method: drone_control进行飞行控制时,需要保证seq从0开始连续递增,不论是单次发送还是连续发送。"), + E319032(319032, "指点飞行失败,请稍后重试"), + E319033(319033, "虚拟摇杆操作失败,请稍后重试 检查发送的指令seq是否递增。"), + E319034(319034, "虚拟摇杆操作失败,请稍后重试"), + E319035(319035, "急停失败,请稍后重试"), + E319036(319036, "设备远程调试中,请稍后重试"), + E319037(319037, "设备远程调试中,请稍后重试 设备本地调试中,请稍后重试 机场连接了USB进行调试,请断开USB连接。"), + E319038(319038, "设备正在升级,请稍后重试"), + E319042(319042, "航线恢复失败,请稍后重试"), + E319043(319043, "取消返航失败,请稍后重试"), + E319044(319044, "航线任务已结束,无法恢复"), + E319045(319045, "急停成功,请重新按键操作;WASD失败 1、检查DRC命令的seq是否从0开始递增 2、检查是否暂停了航线再执行DRC控制 飞行器报错319045后,下一个飞行控制指令需要seq从0开始递增。注意:飞行控制drone_control与DRC心跳heart_beat的seq是独立的。"), + E319046(319046, "无法暂停航线,飞行器尚未进入航线或已退出航线 不处于航线任务中。调用流程问题,比如在指令飞行过程中暂停航线。"), + E319999(319999, "机场系统运行异常,请重启机场后重试 未知错误,需要根据下发的指令来判断哪个业务导致问题 1、切镜头不能切换到normal镜头 2、检查参数是否有误 3、红外相关参数设置,需要将直播画面切换到直播镜头"), + E321000(321000, "航线执行异常,请稍后重试或重启机场后重试 机场日志、飞机日志 航线未知原因退出 拉取机场和飞机日志联系售后分析"), + E321001(321001, "mission id不存在"), + E321002(321002, "wayline info错误"), + E321003(321003, "要执行的航线文件版本不匹配"), + E321004(321004, "航线文件解析失败,无法执行飞行任务,请检查航线文件"), + E321005(321005, "航线缺少断点信息,机场无法执行飞行任务"), + E321006(321006, "无效的命令"), + E321016(321016, "模拟器打开失败"), + E321257(321257, "飞行任务已在执行中,请勿重复执行"), + E321258(321258, "飞行任务无法终止,请检查飞行器状态"), + E321259(321259, "飞行任务未开始执行,无法终止飞行任务"), + E321260(321260, "飞行任务未开始执行,无法中断飞行任务"), + E321261(321261, "飞行任务冲突,无法获取飞机控制权"), + E321262(321262, "该状态下无法恢复航线"), + E321513(321513, "航线规划高度已超过飞行器限高,机场无法执行飞行任务 机场日志、飞机日志 1、存在限飞区 2、用户设置了限高 1、检查是否存在限飞区 2、检查用户设置的限高 3、检查航线文件 4、检查飞机位置"), + E321514(321514, "任务失败,起点或终点位于限远区域的缓冲区内或超过限远距离,机场无法执行飞行任务 机场日志、飞机日志 1、存在限飞区 2、用户设置了限远 1、检查是否存在限飞区 2、检查用户设置的限远 3、检查航线文件 4、检查飞机位置"), + E321515(321515, "航线穿过限飞区,机场无法执行飞行任务"), + E321516(321516, "飞行器飞行高度过低,飞行任务执行被终止"), + E321517(321517, "飞行器触发避障,飞行任务执行被终止。为保证飞行安全,请勿用当前航线执行断点续飞任务 飞机日志 1、存在障碍物 2、存在降雨或有雾天气 3、概率偶现误检测 1、检查航线与障碍物距离是否小于5米 2、检查是否存在降雨或有雾天气 3、手动触发返航并对飞行器视觉进行标定 4、多次重试标定依然存在问题,请拉取飞机日志反馈售后分析。"), + E321518(321518, "RTK信号弱,为保证飞行安全,已自动终止本次飞行任务"), + E321519(321519, "飞行器接近限飞区或限远距离自动返航,无法完成航线飞行 飞机日志 存在限飞区 检查是否存在限飞区与飞机位置高度"), + E321520(321520, "打pitch/roll杆中断航线(农机航线专用)"), + E321521(321521, "超过机场限飞区限高"), + E321522(321522, "请求自动起飞失败"), + E321523(321523, "飞行器起桨失败,请稍后重试,如果仍报错请联系大疆售后 机场日志、飞机日志 1、桨叶存在破损 2、桨叶垫片过紧 3、飞机摆放位置变化导致误检测 1、检查桨叶状态 2、检查桨叶垫片是否过紧 3、将飞行器在停机坪上摆放正确"), + E321524(321524, "飞行器起飞前准备失败,可能是飞行器无GPS或档位错误导致,请检查飞行器状态 飞机日志 1、有可能是因为没有GPS或档位不对等原因导致,具体原因需分析日志 2、拉取飞行器日志联系售后分析"), + E321525(321525, "农机航线:仿地绕行失败,暂停航线"), + E321527(321527, "飞行器RTK收敛失败,无法执行飞行任务,请稍后重试或重启机场后重试 请检查飞行器RTK是否收敛成功"), + E321528(321528, "触碰自定义飞行区边界,航线任务已暂停 机场日志、飞机日志 规划的航线任务与规划的自定义飞行区有冲突 重新规划并下发航线任务或重新规划并上传自定义飞行区"), + E321530(321530, "飞行航线过程中轨迹规划失败,航线任务已暂停"), + E321531(321531, "进离场航线执行失败,请联系大疆售后。"), + E321532(321532, "进离场航线执行失败,请联系大疆售后。"), + E321533(321533, "进离场航线执行失败,请联系大疆售后。"), + E321769(321769, "飞行器卫星定位信号差,无法执行飞行任务,请重启机场后重试 机场日志、飞机日志 飞行器GPS信号弱 1、检查飞行器是否飞过信号差区域 2、检查飞行器是否受到HMS干扰 3、多次出现请拉取飞行器日志联系售后分析"), + E321770(321770, "飞行器档位错误,无法执行飞行任务,请重启机场后重试 机场日志、飞机日志 B控接管,且B控不是N档或接管后未切换档位 检查B控状态"), + E321771(321771, "飞行器返航点未设置,无法执行飞行任务,请重启机场后重试"), + E321772(321772, "飞行器电量低于30%,无法执行飞行任务,请充电后重试(建议电量≥50%)"), + E321773(321773, "低电量返航 机场日志、飞机日志 飞机电量过低 1、确认航线是否过长 2、确认飞行时电量是否充足 3、确认是否存在大风HMS告警 4、确认是否有电池相关错误码 5、确认电池健康状态 6、多次出现请拉取飞机日志"), + E321774(321774, "ADSB(触发ADS-B主动避让功能才会有)"), + E321775(321775, "飞行器航线飞行过程中失联,无法完成航线飞行 机场日志、飞机日志 飞行器与机场图传断连 1、确认失去RC信号时飞行器位置是否过远 2、确认失去RC信号时飞行器与机场是否存在遮挡 3、多次出现请拉取机场和飞行器日志联系售后分析"), + E321776(321776, "飞行器RTK收敛失败,无法执行飞行任务,请重启机场后重试"), + E321777(321777, "飞行器未悬停,无法开始执行飞行任务"), + E321778(321778, "用户使用B控操控飞行器起桨,机场无法执行飞行任务"), + E321779(321779, "实时仿地过程中,相机状态有问题(过亮、过暗、两侧亮度不一致)"), + E321780(321780, "实时仿地用户设置的仿地高度不合法(大于200m或小于30m)"), + E321781(321781, "实时仿地过程中全局地图计算出错"), + E321782(321782, "home点未匹配RTK开关状态"), + E321784(321784, "任务过程中遇到大风紧急返航"), + E322023(322023, "飞机严重故障,无法执行(hms level为3的故障)"), + E322025(322025, "找不到对应的负载(多负载情况下才有用)"), + E322026(322026, "航点动作执行失败"), + E322027(322027, "农机大田果树航线:喷洒药箱无药、播撒料箱无料"), + E322028(322028, "农机航线:避障开启,但雷达断链"), + E322281(322281, "用户退出航线,任务失败,机场执行飞行任务过程被手动打断或异常终止(例如按停止航线按钮)"), + E322282(322282, "机场执行飞行任务过程中被中断,飞行器被云端设备或B控接管 机场日志、飞机日志 B控接管后按暂停键中断航线 确认用户是否有操作"), + E322283(322283, "机场执行飞行任务过程中被用户触发返航,无法完成航线飞行 机场日志、飞机日志 用户通过司空2或遥控器主动触发返航 确认用户是否有操作"), + E322284(322284, "农机航线:用户在航线飞行过程中,主动打开/关闭仿地绕行开关"), + E322285(322285, "用户切换RC-Mode档位"), + E322332(322332, "航点坐标超出了合理范围 1、检查航线是否过远 2、检查航线是否过高或过低"), + E322536(322536, "航线任务WP平台初始化失败"), + E322537(322537, "Job退出但Mission异常运行"), + E322538(322538, "飞机已经起桨,不允许直接起飞,需要停桨才能开始航线"), + E322539(322539, "航线的断点信息错误,机场无法执行飞行任务"), + E322540(322540, "使用不支持的坐标系"), + E322541(322541, "使用不支持的高度模式"), + E322542(322542, "使用不支持的过渡航线模式"), + E322543(322543, "使用不支持的yaw模式"), + E322544(322544, "使用不支持的转yaw方向模式"), + E322545(322545, "使用不支持的航点类型"), + E322546(322546, "航线文件格式错误,首尾航点不能使用协调转弯类型"), + E322547(322547, "航线文件格式错误,航线全局速度超过合理范围"), + E322548(322548, "航线文件格式错误,航点数量异常"), + E322549(322549, "航线文件格式错误,经纬度数据异常"), + E322550(322550, "航线文件格式错误,转弯截距异常"), + E322551(322551, "航段最大速度超过合理范围"), + E322552(322552, "航段目标速度超过合理范围"), + E322553(322553, "航点yaw角度超过合理范围"), + E322554(322554, "垂直航段yaw模式异常"), + E322555(322555, "断点续飞的mission_id输入错误"), + E322556(322556, "断点续飞的progress信息输入错误"), + E322557(322557, "断点续飞的任务状态异常"), + E322558(322558, "断点续飞的航点index信息输入错误"), + E322559(322559, "断点续飞的经纬度信息输入错误"), + E322560(322560, "断点续飞的航点yaw输入错误"), + E322561(322561, "断点续飞的标志位设置错误"), + E322562(322562, "读取轨迹信息失败"), + E322563(322563, "航线轨迹生成失败,请检查飞机视觉镜头是否存在脏污或重启飞机后再试,如果仍报错请联系大疆售后。"), + E322564(322564, "轨迹库运行失败"), + E322565(322565, "航线避障紧急刹车"), + E322588(322588, "找不到对应动作"), + E322591(322591, "动作INDEX不能重复"), + E322592(322592, "动作数量异常(过多或过少)"), + E322593(322593, "动作树不能为空"), + E322594(322594, "航线文件格式错误,航点动作有误 动作树层级不能为空"), + E322595(322595, "航线文件格式错误,动作ID不能重复 动作ID不能重复;航线文件中的wpml:actionId不得重复"), + E322596(322596, "动作节点子节点数量不能小于2"), + E322597(322597, "动作INDEX超过合理范围"), + E322598(322598, "动作ID值不能为65535"), + E322599(322599, "动作树生成错误(子节点数量不等于下层节点数量)"), + E322600(322600, "动作树层级过多"), + E322601(322601, "动作树层级过少"), + E322602(322602, "动作组数量超过合理范围"), + E322603(322603, "航线文件格式错误,动作树生效范围错误"), + E322604(322604, "动作树根节点状态错误"), + E322605(322605, "动作树普通节点状态错误"), + E322606(322606, "断点续飞中动作index超过合理范围"), + E322607(322607, "动作树数量错误"), + E322608(322608, "断点信息中触发器运行结果异常"), + E322609(322609, "断点续飞中动作组ID信息不能重复"), + E322610(322610, "断点续飞中动作组位置不能重复"), + E322611(322611, "断点续飞中动作组位置超过合理范围"), + E322612(322612, "续飞中动作id不在断点信息中"), + E322613(322613, "续飞中不能修改动作状态为中断"), + E322614(322614, "断点信息错误导致续飞失败"), + E322634(322634, "未找到对应的动作执行器"), + E322649(322649, "未找到触发器"), + E322650(322650, "到点触发参数设置错误"), + E324012(324012, "日志压缩过程超时,所选日志过多,请减少选择的日志后重试"), + E324013(324013, "设备日志列表获取失败,请稍后重试"), + E324014(324014, "设备日志列表为空,请刷新页面或重启机场后重试"), + E324015(324015, "飞行器已关机或未连接,无法获取日志列表,请确认飞行器在舱内,通过远程调试将飞行器开机后重试"), + E324016(324016, "机场存储空间不足,日志压缩失败,请清理机场存储空间或稍后重试"), + E324017(324017, "日志压缩失败,无法获取所选飞行器日志,请刷新页面或重启机场后重试"), + E324018(324018, "日志文件拉取失败,导致本次设备异常反馈上传失败,请稍后重试或重启机场后重试"), + E324019(324019, "因机场网络异常,日志上传失败,请稍后重试。如果连续多次出现该问题,请联系代理商或大疆售后进行网络排障"), + E324021(324021, "因机场断电或重启导致日志导出中断,日志导出失败,请稍后重试"), + E324030(324030, "因机场网络异常、飞行器图传链路异常等原因,媒体文件暂时无法上传或文件已上传但云端读取失败 1、该任务已经不存在于上传队列中 检查是否存在网络波动"), + E324042(324042, "飞机未连接,无法查询/更新/开关证书 需要飞机开机后再操作解禁证书。"), + E325000(325000, "机场没有收到4G发送的dongle信息 1、在打开4G或者关闭4G时会报这个错 2、命令超时 与SDR和LTE链路切换有关,dongle或链路信息获取超时。请检查飞机是否开机,4G dongle是否正常工作。"), + E325001(325001, "云端下发给机场的命令不符合格式要求,机场无法执行 JSON解析错误 1、数据格式与文档不匹配 2、数据超出了允许范围"), + E325003(325003, "设备端命令响应错误,请重试 命令未知错误 1、检查下发指令参数是否与文档一致 2、需起飞后才可使用DRC命令控云台 3、相机模式错误,如录像模式下拍照 4、非直播红外镜头情况下设置红外参数 5、双光相机设置保存的照片类型。"), + E325004(325004, "设备端命令请求已超时,请重试 请求超时。需确认调用方法及流程正确。"), + E325005(325005, "当前机场无法响应任务,请稍后重试"), + E325006(325006, "当前机场启动检查中,请稍后重试"), + E325007(325007, "当前机场执行作业任务中,请稍后重试"), + E325008(325008, "当前机场处理作业任务结果中,请稍后重试"), + E325009(325009, "当前机场执行远程日志导出中,请稍后重试"), + E325010(325010, "当前机场更新自定义飞行区中,请稍后重试"), + E325011(325011, "当前机场更新离线地图中,请稍后重试"), + E325012(325012, "当前飞机未连接,请稍后重试"), + E325013(325013, "设备正忙,请稍后重试"), + E325014(325014, "未知错误 检查切换镜头指令的video_type大小写是否有误"), + E326002(326002, "飞行器未安装DJI Cellular模块"), + E326003(326003, "飞行器DJI Cellular模块中未安装SIM卡"), + E326004(326004, "飞行器DJI Cellular模块需要强制升级,否则无法使用"), + E326005(326005, "操作失败,增强图传无法建立连接,请检查4G信号强度,或咨询运营商查询套餐流量和APN设置 检查4G模块是否亮绿灯"), + E326006(326006, "增强图传开关切换失败,请稍后重试"), + E326007(326007, "切换链路的JSON请求无效 JSON数据异常 发送的MQTT命令格式有误,需要注意link_workmode参数为整数类型。"), + E326008(326008, "机场未安装DJI Cellular模块"), + E326009(326009, "机场DJI Cellular模块中未安装SIM卡"), + E326010(326010, "机场DJI Cellular模块需要强制升级,否则无法使用"), + E326011(326011, "检查飞机是否开机,需要飞机开机进行设置。"), + E326015(326015, "设备繁忙,稍后重试"), + E326103(326103, "当前eSIM正在激活中,请稍后再试"), + E326104(326104, "当前eSIM正在切换运营商中,请稍后再试"), + E326105(326105, "DJI增强图传模块正在切换模式中,请稍后再试"), + E326106(326106, "DJI增强图传模块异常,请重启设备后再试,如果仍报错请联系大疆售后"), + E326107(326107, "请在设备管理 > 机场 > 设备运维中激活DJI增强图传模块的eSIM或插入SIM卡后再试"), + E327000(327000, "参数设置失败,请稍后重试"), + E327001(327001, "参数设置失败,请稍后重试 需检查DRC连接状态是否为已连接 1、可通过监控Topic:thing/product/{gateway_sn}/events,method为drc_status_notify上报的状态是否为2(已连接) 2、若未上报可监控机场OSD状态上报的drc_state:2(已连接)"), + E327002(327002, "获取控制权失败,请稍后重试"), + E327003(327003, "获取控制权失败,请稍后重试 被抢夺设备不在线 需根据飞机上报的OSD payload_index传入正确payload_index"), + E327004(327004, "画面拖动失败,请重试"), + E327005(327005, "双击画面归中失败 https://sdk-forum.dji.net/hc/zh-cn/articles/20319918034073"), + E327006(327006, "拍照失败 1、开启录像需将相机切换到录像模式 2、开启录像前需获取负载控制权"), + E327007(327007, "开始录像失败 检查相机模式和负载控制权"), + E327008(327008, "停止录像失败"), + E327009(327009, "切换相机模式失败 可能原因: 1、未插SD卡 2、SD卡有问题,不兼容 3、升级到最新固件重试 4、未抢夺负载控制权 5、下发指令频率过高,相机回调状态未响应"), + E327010(327010, "ZOOM相机变焦失败 1、在机场上报的OSD中查看zoom_factor是否变化 2、使用遥控器连接飞机,查看变焦倍数是否变化 3、设置变焦倍数为其它值,查看云端是否能获知 4、命令超时未收到回包 5、相机模块内部错误(当前状态不支持)"), + E327011(327011, "IR相机变焦失败"), + E327012(327012, "获取控制权失败,请稍后重试"), + E327013(327013, "参数设置失败,请稍后重试"), + E327014(327014, "云台已达限位"), + E327015(327015, "直播启动失败,建议刷新直播或重新打开设备小窗 无效的相机镜头类型"), + E327016(327016, "失联动作设置失败,请重试"), + E327017(327017, "指点飞行高度设置失败,请重试"), + E327018(327018, "指点飞行模式切换失败,请重试"), + E327019(327019, "当前状态无法看向标注点 当前状态不支持“look at”"), + E327020(327020, "全景拍照停止命令超时"), + E327050(327050, "当前设备状态不支持播放音频"), + E327051(327051, "下载音频文件失败"), + E327052(327052, "喊话器处理模式切换失败"), + E327053(327053, "上传音频文件失败 1、检查storage_config_get请求与回复是否正常 2、确认OSS配置正确 3、确认喊话器支持PSDK3.6及以上版本 4、无人机和机场固件升级至最新 5、检查文件MD5是否正确"), + E327054(327054, "播放音频失败 音频可通过命令检查:ffplay -nodisp -autoexit -ar 16000 -ac 1 -f s16le -i xxx.pcm"), + E327055(327055, "设置工作模式失败"), + E327056(327056, "上传文本失败"), + E327057(327057, "停止播放失败"), + E327058(327058, "设置播放模式失败"), + E327059(327059, "设置音量失败 基于司空2交叉验证喊话器功能是否正常"), + E327060(327060, "设置控件值失败"), + E327061(327061, "发送文本值失败"), + E327062(327062, "切换系统语言失败"), + E327063(327063, "获取设备功能列表失败 检查自定义飞行区参数是否缺失"), + E327064(327064, "获取设备配置文件失败"), + E327065(327065, "获取设备图片文件失败"), + E327066(327066, "设备文件压缩失败"), + E327067(327067, "设备文件上传失败"), + E327068(327068, "上传音频文件失败,MD5校验失败"), + E327069(327069, "上传音频文件失败"), + E327070(327070, "上传音频文件失败,异常终止"), + E327071(327071, "上传TTS文本失败,MD5校验失败"), + E327072(327072, "上传TTS文本失败"), + E327073(327073, "上传TTS文本失败,异常终止"), + E327074(327074, "喊话器重播失败"), + E327075(327075, "喊话器编码失败"), + E327201(327201, "全景拍照失败"), + E327202(327202, "全景拍摄终止"), + E327203(327203, "当前设备不支持全景拍照"), + E327204(327204, "系统繁忙,无法全景拍照"), + E327205(327205, "请求失败,无法全景拍照"), + E327206(327206, "飞机未起飞,无法开始全景拍摄"), + E327207(327207, "控制权获取失败,全景拍摄终止"), + E327208(327208, "未知相机错误,无法开始全景拍摄"), + E327209(327209, "相机超时,全景拍摄终止"), + E327210(327210, "无法全景拍照"), + E327211(327211, "存储空间不足,全景拍摄终止"), + E327212(327212, "飞机运动中,无法开始全景拍摄"), + E327213(327213, "云台运动中,无法开始全景拍摄"), + E327214(327214, "用户操作摇杆,全景拍摄终止"), + E327215(327215, "碰到限飞区,全景拍摄终止"), + E327216(327216, "触发距离限制,全景拍摄终止"), + E327217(327217, "云台受阻,全景拍摄终止"), + E327218(327218, "拍照失败,全景拍摄终止"), + E327219(327219, "全景图片拼接失败"), + E327220(327220, "加载标定参数失败,全景拍摄终止"), + E327221(327221, "调整相机参数失败,全景拍摄终止"), + E327500(327500, "飞行器镜头除雾失败,请稍后重试"), + E327504(327504, "播放音频失败 1、检查音频文件格式"), + E328023(328023, "因飞机告警导致无法起飞"), + E328051(328051, "飞机未完成实名登记,请连接遥控器,按照指引完成实名登记后飞行"), + E328052(328052, "飞机实名登记状态已注销,请连接遥控器,按照指引完成实名登记后飞行"), + E328079(328079, "电池认证失败,请更换DJI官方电池(0x1610004F) 1、请检查使用的电池是否为DJI官方电池,设备固件是否最新(如不是最新请升级至最新且匹配版本),非官方电池将阻飞; 2、请更换电池排查;如果更换多个电池故障依旧,建议使用75%浓度以上的酒精擦拭电池或者机身上的金属触点;"), + E332514(332514, "HMS告警导致的无法起飞"), + E336000(336000, "指点飞行命令发送失败,请重试"), + E336001(336001, "飞行器数据异常,无法响应指令"), + E336002(336002, "飞行器GPS信号差"), + E336003(336003, "飞行器定位失效,无法响应指令"), + E336004(336004, "指点飞行自主规划失败"), + E336005(336005, "飞行器返航点未更新"), + E336006(336006, "飞行器已失联,已退出指点飞行"), + E336017(336017, "飞行器电量不足以完成当前任务"), + E336018(336018, "已切换飞行器规划模式"), + E336019(336019, "指点飞行因限高自动调整飞行高度"), + E336513(336513, "目标点在禁飞区内"), + E336514(336514, "目标点超出飞行器限远"), + E336515(336515, "目标点在禁飞区内"), + E336516(336516, "目标点超出飞行器限高"), + E336517(336517, "目标点超出飞行器限低"), + E337025(337025, "飞行器无法起飞"), + E337026(337026, "目标点异常,请重试 设置的目标点经纬度超出了有效范围"), + E337027(337027, "飞行器速度设置异常,请重试"), + E337028(337028, "飞行器版本异常,请检查飞行器版本"), + E337029(337029, "飞行器无法响应当前任务,请稍后重试"), + E337030(337030, "指令飞行安全离场高过低 起飞高度输入过低"), + E337537(337537, "已触碰禁飞区"), + E337538(337538, "已触碰飞行器限远"), + E337539(337539, "已触碰禁飞区"), + E337540(337540, "已触碰飞行器限高或限高区"), + E337541(337541, "已触碰飞行器限低"), + E337542(337542, "飞行器起飞失败,请重试"), + E337543(337543, "目标点可能在障碍物内,请检查周边环境"), + E337544(337544, "检测到障碍物,请检查周边环境"), + E337545(337545, "飞行器规划异常,请重试 规划因为某种原因删除了路径 10.1.8版本会修复。起飞时RTK不收敛会导致该报错。"), + E337546(337546, "已触碰自定义飞行区边界"), + E338001(338001, "飞行器通信异常,无法执行飞行任务,请重启飞行器与机场后重试"), + E338002(338002, "飞行器通信异常,无法执行飞行任务,请重启飞行器与机场后重试"), + E338003(338003, "飞行器通信异常,无法执行飞行任务,请重启飞行器与机场后重试"), + E338004(338004, "飞行器通信异常,无法执行飞行任务,请重启飞行器与机场后重试"), + E338005(338005, "起飞机场与降落机场部署距离超出限制,无法执行飞行任务,请选择两个部署距离不超过15km的机场执行任务"), + E338006(338006, "无法执行飞行任务,请检查降落机场是否已申请解禁证书、是否位于自定义禁飞区或是否位于自定义飞行区外"), + E338007(338007, "目标降落机场部署突破限高区限高,无法执行任务,请申请解禁证书后再试"), + E338008(338008, "目标降落机场部署突破飞行器设置的限高,无法执行任务,请调整限高后重试"), + E338009(338009, "飞行器GPS定位信号差,无法执行任务,请重启飞行器后重试"), + E338010(338010, "飞行器定位失效,无法执行任务,请重启飞行器后重试"), + E338011(338011, "任务失败,目标机场处于地理鸟笼作业区域外,请重新规划任务后再试"), + E338017(338017, "飞行器数据更新失败,无法执行任务,请重启飞行器后重试"), + E338018(338018, "飞行器数据更新失败,无法执行任务,请重启飞行器后重试"), + E338019(338019, "飞行器到目标机场的返航路线正在规划中,无法执行任务,请重启飞行器后重试"), + E338020(338020, "飞行器无法根据规划的路径到达目标降落机场,无法执行任务,请重新选择降落机场后再试"), + E338021(338021, "飞行器当前电量不足以到达目标降落机场,无法执行任务,请给飞行器充电后重试"), + E338049(338049, "响应遥控器杆量,已退出指点飞行"), + E338050(338050, "响应终止指令,已退出指点飞行"), + E338051(338051, "飞行器低电量返航,已退出指点飞行"), + E338052(338052, "飞行器低电量降落,已退出指点飞行"), + E338053(338053, "附近有载人机,已退出指点飞行"), + E338054(338054, "响应其他高优先级任务,已退出指点飞行"), + E338255(338255, "飞行器通信异常,无法执行飞行任务,请重启飞行器与机场后重试"), + E386534(386534, "航线错误。上云API不支持通过KML设置模板航线。必须基于WPML来生成航线"), + E386535(386535, "航线执行异常,请稍后重试或重启机场后重试"), + E513001(513001, "直播失败,飞行器不存在或飞行器类型错误 机场日志、飞机日志 云端直播命令内容有误,例如本地机场或飞机的SN是4SEDL13001002C,但实际收到的云端命令中SN与本地SN不匹配。需要查看云端日志定位。 请检查云端发送到机场的命令格式是否正确(机场上报的直播能力中携带了机场及飞机设备的SN号,需要检查云端下发的直播命令中的SN号是否与其匹配)"), + E513002(513002, "直播失败,相机不存在或相机类型错误 机场日志、飞机日志 直播错误,相机不存在,飞机没有挂Z30,却要求Z30的图传,就需要报此错误 请检查云端发送到机场的命令格式是否正确(机场上报的直播能力中携带了相机的video_id,需要检查云端下发的直播命令中的video_id是否与其匹配)"), + E513003(513003, "相机已经在直播中,请勿重复开启直播 机场日志、飞机日志 重复点播,相机已经在直播中(云端已特殊处理) 通过state查看直播状态,确定是否有镜头正在直播"), + E513005(513005, "直播失败,直播参数(清晰度)设置错误 机场日志、飞机日志 直播错误,策略不支持,比如APP只支持标清、高清、超清、自适应四种直播策略,不支持其他类型的策略 请检查云端发送到机场的直播命令格式是否正确(直播命令中携带的清晰度枚举值是否在合理范围内)"), + E513006(513006, "操作失败,相机未开启直播,无法响应直播设置 机场日志、飞机日志 \"直播视频没有图传订阅(liveview订阅中没有该码流) 直播错误,当前APP不在liveview界面,无法响应某些直播设置\" 非正常流程,请上传机场及飞机日志反馈售后进行故障分析"), + E513008(513008, "操作失败,相机未开启直播,无法响应直播设置 机场日志、飞机日志 liveview订阅的图传通道数据异常(图传码流为0) \"1、检查飞机与机场之间的图传质量(由于图传受干扰,导致机场接收到的飞机图传码流异常;如果确认图传质量良好但仍出现513008错误码,请上传机场及飞机日志用于定位) 2、飞机不能直播也有可能是机场的固件问题,要把机场固件升级到最新。\""), + E513009(513009, "无"), + E513010(513010, "直播失败,设备无法联网 机场日志、飞机日志 无法连接流媒体服务 \"直播声网连接失败 设备无法连接到直播服务器,可能原因有。 1、网络不佳,未能连接上流媒体服务器 2、流媒体服务器配置有误 3、流媒体服务器不支持的推流格式,例如:非WHIP信令的WebRTC服务。 4、如果使用WebRTC协议,请注意:机场2 WebRTC直播在国内仅支持HTTP,在海外支持HTTPS的Dolby服务器。这种情况下,可以用HTTP做个反向代理。\""), + E513011(513011, "操作失败,设备未开启直播 机场日志、飞机日志 停止或设置清晰度请求失败,因为没有正在直播 机场向直播服务器发起Register注册时超时。可能是服务器没有收到这条注册消息或者服务器流程异常。"), + E513012(513012, "操作失败,设备已在直播中,不支持切换镜头"), + E513013(513013, "直播失败,直播使用的视频传输协议不支持"), + E513014(513014, "直播失败,直播参数错误或者不完整 机场日志、飞机日志 URL参数错误 请检查云端发送到机场的直播命令格式是否正确"), + E513015(513015, "直播异常,网络卡顿 机场日志、飞机日志 网络拥塞 请检查机场网络状态(机场上行带宽至少10Mbps)"), + E513016(513016, "直播异常,视频解码失败 机场日志、飞机日志 视频关键帧错误(长时间收不到关键帧) \"1、非正常流程,请上传机场及飞机日志用于定位编码问题 2、检查是否网络原因导致关键帧丢失\""), + E513017(513017, "直播已暂停,请等待当前飞行器媒体文件下载完成后再试 机场日志、飞机日志 由于相机进入回放导致无法直播 检查飞机是否处于执行完毕航线任务后上传媒体过程中,此时无法开启飞机直播。其他情况如出现513017请上传机场及飞行器日志反馈售后分析"), + E513099(513099, "直播失败,请稍后重试 内部错误 \"1、重启机场和飞行器后重试 2、检查直播参数特别是参数的数据类型是否有误。\""), + E514100(514100, "机场运行异常,请重启机场后重试"), + E514101(514101, "推杆闭合失败,请检查停机坪上是否存在异物,飞行器方向是否放反,或重启机场后重试 机场日志、飞机日志 1、停机坪电源线断裂 2、推杆舵机损坏 3、推杆被异物卡住 1、根据HMS报错信息进行故障排查 2、重启机场后进行重试 3、检查推杆状态 4、可能存在硬件损坏:停机坪电源线断裂/推杆舵机损坏/推杆被异物卡住"), + E514102(514102, "推杆展开失败,请检查停机坪上是否存在异物,或重启机场后重试"), + E514103(514103, "飞行器电量低,无法执行飞行任务,请充电后(建议≥50%)重试 机场日志、飞机日志 飞行器电量低 等待充电至30%以上,重新下发任务"), + E514104(514104, "飞行器电池开始充电失败,请重启机场后重试 充电时请保持飞机舱关闭。另外,请检查HMS中是否有任何过热警报。过热也会导致充电异常。"), + E514105(514105, "飞行器电池停止充电失败,请重启机场后重试 机场日志、飞机日志 1、内部逻辑异常 2、充电链路通讯异常 1、升级最新固件 2、重启机场和飞行器 3、拉取机场和飞行器日志联系售后分析"), + E514106(514106, "飞行器电源控制异常,请重启机场后重试"), + E514107(514107, "舱盖开启失败,请检查舱盖周围是否存在异物,或重启机场后重试 机场日志、飞机日志 1、舱盖卡住或重物覆盖导致堵转 2、电机刹车异常,无法正常解锁 3、主控模块异常 4、电机减速机损坏卡死 5、驱动器损坏 6、电机线圈短路 7、位置反馈磁环位置发生移动 1、机场上电,手动按下解锁按钮,检查是否有“咔哒”的解锁声音,手动开启舱盖,检查是否可以正常开启或关闭舱盖以及是否有异响。 2、若无,则可能为刹车损坏或刹车连接器接触不良,需卸下摆臂把舱盖取下并掀开停机坪,排查主控模块刹车接口供电,更换主控模块或电机进行交叉测试。 3、若有解锁声音但无法开启舱盖,则可能电机卡死损坏,需更换电机。 4、若手动可正常开启但APP控制不动作,则可能是驱动器或电机损坏。 5、使用APP重新标定舱盖位置。"), + E514108(514108, "舱盖关闭失败,请检查舱盖周围是否存在异物,或重启机场后重试 机场日志、飞机日志 1、舱盖卡住或重物覆盖导致堵转 2、磁环位置发生移动 3、主控模块损坏 4、电机减速机损坏卡死 5、驱动器损坏 6、霍尔传感器异常 1、机场上电,手动按下解锁按钮,检查是否有“咔哒”的解锁声音,手动开启舱盖,检查是否可以正常开启或关闭舱盖以及是否有异响。 2、若无,则可能为刹车损坏或刹车连接器接触不良,需卸下摆臂把舱盖取下并掀开停机坪,排查主控模块刹车接口供电,再测量刹车线圈电阻,根据测量结果更换主控模块或电机。 3、若有解锁声音但无法开启舱盖,则可能电机卡死损坏,需更换电机。 4、若手动可正常开启但APP控制不动作,则可能是驱动器或电机损坏,或主控损坏。 5、使用APP重新标定舱盖位置。"), + E514109(514109, "飞行器开机失败,请检查飞行器电池是否安装到位且电量是否正常,或重启机场后重试 机场日志、飞机日志 1、飞行器电池电量低 2、电池固件不兼容 3、充电连接器通讯异常 1、检查飞机电池电量是否大于30% 2、升级至最新机场和飞机固件 3、修复以上问题后重启机场重试"), + E514110(514110, "飞行器关机失败,请重启机场后重试 机场日志、飞机日志 1、固件版本过低 2、充电连接器通讯异常 1、升级飞行器和机场固件至最新版本 2、重启后重试 3、检查充电连接器金属片是否插入飞行器"), + E514111(514111, "飞行器慢转收桨控制异常,请重启机场后重试"), + E514112(514112, "飞行器慢转收桨控制异常,请重启机场后重试"), + E514113(514113, "机场与飞行器无法建立有线连接,请检查飞行器是否在舱内,推杆闭合时是否被卡住,充电连接器是否脏污或损坏 机场日志、飞机日志 1、停机坪下充电连接线断裂 2、飞机不在机场停机坪上 3、推杆片簧金属片没有插入飞机 1、检查飞行器是否在停机坪上 2、检查左右充电线连接是否正常且无断裂 3、远程调试是否可控制飞行器开关机或充电 4、检查充电连接器金属片是否插入飞行器"), + E514114(514114, "获取飞行器电源状态失败,请重启机场后重试"), + E514116(514116, "无法执行当前操作,机场正在执行其他控制指令,请稍后重试 机场日志、飞机日志 指令冲突 等待上一步操作执行完毕后再进行操作"), + E514117(514117, "舱盖开启或关闭未到位,请重启机场后重试"), + E514118(514118, "推杆展开或闭合未到位,请重启机场后重试"), + E514120(514120, "机场与飞行器断连,请重启机场后重试或重新对频 机场和无人机之间的图传链路断开了,可以尝试重启机场"), + E514121(514121, "机场急停按钮被按下,请释放急停按钮 机场日志、飞机日志 急停按钮被按下 向外拔出急停按钮"), + E514122(514122, "获取飞行器充电状态失败,请重启机场后重试"), + E514123(514123, "飞行器电池电量过低无法开机"), + E514124(514124, "获取飞行器电池信息失败,无法执行飞行任务,请重启机场后重试 机场日志 1、电池未插到位 2、电池电量低,进入休眠状态 1、检查双电池是否插入到位 2、确认电池电量是否为0 3、打开远程调试,给飞机充电至40%以上后重试下发任务"), + E514125(514125, "飞行器电池电量已接近满电状态,无法开始充电,请使用至95%以下再进行充电"), + E514126(514126, "获取bid失败,请检查发送的MQTT命令是否缺少bid字段"), + E514134(514134, "雨量过大,机场无法执行飞行任务,请稍后重试 机场日志 大雨无法飞行 等待雨量减小后再下发任务"), + E514135(514135, "风速过大(≥12m/s),机场无法执行飞行任务,请稍后重试 机场日志 大风无法飞行 等待风速降低后再下发任务"), + E514136(514136, "机场供电断开,机场无法执行飞行任务,请恢复机场供电后重试 机场日志 1、无市电输入 2、ACDC损坏 3、ACDC与主控模块连接线缆断开 1、检查市电供电是否正常 2、检查ACDC输出是否正常 3、检查ACDC与主控模块连接线缆 4、更换ACDC或主控模块"), + E514137(514137, "环境温度过低于-20℃(-4°F),机场无法执行飞行任务,请稍后重试"), + E514138(514138, "飞行器电池正在保养中,机场无法执行飞行任务,请等待保养结束后重试"), + E514139(514139, "飞行器电池无法执行保养指令,飞行器电池无需保养"), + E514140(514140, "飞行器电池无法执行保养指令,飞行器电池无需保养"), + E514141(514141, "机场系统运行异常,请重启机场后重试 机场日志、飞机日志 设备逻辑异常 远程重启机场和飞行器后重新下发任务,若仍存在问题,请拉取机场和飞行器日志联系售后分析"), + E514142(514142, "飞行器起飞前,机场与飞行器无法建立有线连接,请检查飞行器是否在舱内,推杆闭合时是否被卡住,充电连接器是否脏污或损坏 机场日志、飞机日志 1、起飞前检查充电连接器通讯异常 2、飞机不在机场停机坪上 3、推杆片簧金属片没有插入飞机 4、检查并修复以上异常后,重启机场 1、远程调试是否可控制飞行器开关机或充电 2、检查飞行器是否在停机坪上 3、检查充电连接器金属片是否已插入飞行器 4、检查停机坪下方充电连接线是否连接正常"), + E514143(514143, "推杆未闭合或闭合不到位,请稍后重试或重启机场后重试 机场日志 1、停机坪与主控模块电源线连接不良 2、推杆舵机损坏 3、推杆被异物卡住 4、检查并修复以上异常后,重启机场 1、远程调试控制推杆运动,查看是否正常运行 2、通过机场监控摄像头查看推杆是否有异物卡住 3、机场断电后手动推动推杆,检查是否卡住 4、可能硬件损坏:停机坪与主控模块电源线连接不良/推杆舵机损坏"), + E514144(514144, "舱盖未关闭或关闭不到位,请稍后重试或重启机场后重试"), + E514145(514145, "机场处于现场调试中,无法执行当前操作或飞行任务,请断开遥控器与机场数据线后重试 机场日志 处于现场调试无法作业"), + E514146(514146, "机场处于远程调试中,无法执行飞行任务,请退出远程调试后重试 机场日志 处于远程调试无法作业"), + E514147(514147, "设备升级中,无法进行远程调试或执行飞行任务,请等待升级完成后重试 机场日志 处于升级状态无法作业"), + E514148(514148, "机场已经在作业中,无法进行远程调试或再次执行飞行任务,请等待当前任务执行完成后重试"), + E514149(514149, "机场系统运行异常,无法执行飞行任务,请重启机场后重试"), + E514150(514150, "设备重启中,无法执行飞行任务,请等待重启完成后重试 机场日志 机场重启中 等待重启完成"), + E514151(514151, "设备升级中,无法执行设备重启指令,请等待升级完成后重试"), + E514153(514153, "机场已退出远程调试模式,无法执行当前操作"), + E514154(514154, "获取内循环出风口温度失败,请稍后再试"), + E514156(514156, "飞机不在舱内,请立即检查飞行器是否已安全降落并将飞行器放回至机场"), + E514157(514157, "执行开机失败,无线充电线圈业务繁忙,请重启机场后再试 1、检查市电是否断开"), + E514158(514158, "无法起飞,机场RTK业务异常,请重启机场后再试 机器RTK异常。模拟飞行需要RTK正常收敛。"), + E514159(514159, "任务失败,降落机场检测到飞行器,请确保降落机场没有飞行器后再试"), + E514162(514162, "飞机和机场连接失败,请关闭机场舱盖或重启机场后再试"), + E514163(514163, "电池功能异常,请确保飞行器电池插入到位或重启飞行器后再试"), + E514164(514164, "设备重启失败,请稍后重试,如果仍报错请联系大疆售后。"), + E514165(514165, "设备重启失败,请稍后重试,如果仍报错请联系大疆售后。"), + E514170(514170, "机场系统初始化中,无法执行当前操作或指令,请等待机场系统初始化完成后重试"), + E514171(514171, "云端下发给机场的命令不符合格式要求,机场无法执行"), + E514172(514172, "飞行器无法关机,蓝牙连接状态为未连接,请尝试重启飞行器和机场,或去现场重新对频飞行器与机场后再试"), + E514173(514173, "由于天气原因(环境温度低于5℃并且降雨大于等于中雨),可能导致桨叶结冰影响作业安全,暂无法执行任务"), + E514174(514174, "飞行器充电失败,机场舱盖开启或关闭未到位,请关闭舱盖后再试"), + E514180(514180, "停止空调制冷或停止空调制热失败,请稍后重试"), + E514181(514181, "开启空调制冷失败,请稍后重试"), + E514182(514182, "开启空调制热失败,请稍后重试"), + E514183(514183, "开启空调除湿失败,请稍后重试"), + E514184(514184, "当前温度低于 0 ℃(32°F),无法开启空调制冷"), + E514185(514185, "当前温度高于 45 ℃(115°F),无法开启空调制热"), + E514300(514300, "网关异常"), + E514301(514301, "请求超时,连接断开 1、为了保证DRC链路不断开,每分钟需要至少发送一次心跳命令给机场。"), + E514302(514302, "网络证书异常,连接失败"), + E514303(514303, "机场网络波动导致DRC连接丢失 需检查DRC连接状态是否为已连接 1、可通过监控Topic:thing/product/{gateway_sn}/events,method为drc_status_notify上报的状态是否为2(已连接) 2、若未上报可监控机场OSD状态上报的drc_state:2(已连接)做补偿。"), + E328145(328145, "禁飞等问题"), + E328074(328074, "无人机定位问题"), + + UNKNOWN(-1, "UNKNOWN"), + + ; + + + private final String msg; + + private final int code; + + ErrorCodeEnum(int code, String msg) { + this.code = code; + this.msg = msg; + } + + @Override + public String getMessage() { + return this.msg; + } + + @Override + public Integer getCode() { + return this.code; + } + + /** + * @param code error code + * @return enumeration object + */ + public static ErrorCodeEnum find(int code) { + return Arrays.stream(values()).filter(codeEnum -> codeEnum.code == code).findAny().orElse(UNKNOWN); + } + +} diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/api/AbstractOfflineMapService.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/api/AbstractOfflineMapService.java index 19e3f97..9426236 100644 --- a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/api/AbstractOfflineMapService.java +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/map/api/AbstractOfflineMapService.java @@ -10,12 +10,12 @@ import org.dromara.common.sdk.config.version.CloudSDKVersionEnum; import org.dromara.common.sdk.config.version.GatewayManager; import org.dromara.common.sdk.config.version.GatewayTypeEnum; import org.dromara.common.sdk.mqtt.ChannelName; +import org.dromara.common.sdk.mqtt.MqttGatewayPublish; import org.dromara.common.sdk.mqtt.MqttReply; +import org.dromara.common.sdk.mqtt.TopicConst; import org.dromara.common.sdk.mqtt.requests.TopicRequestsRequest; import org.dromara.common.sdk.mqtt.requests.TopicRequestsResponse; -import org.dromara.common.sdk.mqtt.services.ServicesPublish; -import org.dromara.common.sdk.mqtt.services.ServicesReplyData; -import org.dromara.common.sdk.mqtt.services.TopicServicesResponse; +import org.dromara.common.sdk.mqtt.services.*; import org.dromara.common.sdk.mqtt.state.TopicStateRequest; import org.dromara.common.sdk.mqtt.state.TopicStateResponse; import jakarta.annotation.Resource; @@ -23,6 +23,11 @@ import org.springframework.integration.annotation.ServiceActivator; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHeaders; +import java.util.Objects; +import java.util.UUID; + +import static org.springframework.integration.context.IntegrationContextUtils.DEFAULT_TIMEOUT; + /** * @author sean @@ -34,6 +39,10 @@ public abstract class AbstractOfflineMapService { @Resource private ServicesPublish servicesPublish; + @Resource + private MqttGatewayPublish gatewayPublish; + + /** * When the offline map is closed, offline map synchronization will no longer automatically synchronize. * @param request data @@ -78,10 +87,20 @@ public abstract class AbstractOfflineMapService { * @param request data * @param headers The headers for a {@link Message}. * @return events_reply + * TopicRequestsResponse> */ @ServiceActivator(inputChannel = ChannelName.INBOUND_REQUESTS_OFFLINE_MAP_GET, outputChannel = ChannelName.OUTBOUND_REQUESTS) @CloudSDKVersion(since = CloudSDKVersionEnum.V1_0_1, include = GatewayTypeEnum.DOCK2) - public TopicRequestsResponse> offlineMapGet(TopicRequestsRequest request, MessageHeaders headers) { - throw new UnsupportedOperationException("offlineMapGet not implemented"); + public void offlineMapGet(TopicRequestsRequest request, MessageHeaders headers) { + MqttReply success = MqttReply.success(); + String topic = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + Objects.requireNonNull(request.getGateway()) + TopicConst.SERVICES_SUF; + gatewayPublish.publish( + topic,0, new TopicServicesRequest<>() + .setTid(UUID.randomUUID().toString()) + .setBid(null) + .setTimestamp(System.currentTimeMillis()) + .setMethod("offline_map_get") + .setData(success)); + //throw new UnsupportedOperationException("offlineMapGet not implemented"); } } diff --git a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/psdk/PsdkWidgetValue.java b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/psdk/PsdkWidgetValue.java index 1de1384..c7f30a7 100644 --- a/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/psdk/PsdkWidgetValue.java +++ b/dk-common/common-cloudsdk/src/main/java/org/dromara/common/sdk/cloudapi/psdk/PsdkWidgetValue.java @@ -35,7 +35,7 @@ public class PsdkWidgetValue { private PsdkSpeaker psdkSpeaker; @JsonProperty("values") - private List values; + private List values; public PsdkWidgetValue() { } @@ -99,11 +99,11 @@ public class PsdkWidgetValue { return this; } - public List getValues() { + public List getValues() { return values; } - public PsdkWidgetValue setValues(List values) { + public PsdkWidgetValue setValues(List values) { this.values = values; return this; } diff --git a/dk-common/common-mybatis/src/main/resources/common-mybatis.yml b/dk-common/common-mybatis/src/main/resources/common-mybatis.yml index f5dc637..f43eea0 100644 --- a/dk-common/common-mybatis/src/main/resources/common-mybatis.yml +++ b/dk-common/common-mybatis/src/main/resources/common-mybatis.yml @@ -23,7 +23,7 @@ mybatis-plus: dbConfig: # 主键类型 # AUTO 自增 NONE 空 INPUT 用户输入 ASSIGN_ID 雪花 ASSIGN_UUID 唯一 UUID - idType: ASSIGN_ID + idType: AUTO # 逻辑已删除值(框架表均使用此值 禁止随意修改) logicDeleteValue: 2 # 逻辑未删除值 diff --git a/dk-common/common-oss/src/main/java/org/dromara/common/oss/core/OssClient.java b/dk-common/common-oss/src/main/java/org/dromara/common/oss/core/OssClient.java index 4d76be2..311ac1f 100644 --- a/dk-common/common-oss/src/main/java/org/dromara/common/oss/core/OssClient.java +++ b/dk-common/common-oss/src/main/java/org/dromara/common/oss/core/OssClient.java @@ -363,6 +363,11 @@ public class OssClient { return url; } + //自定义上传prefix路径 + public UploadResult uploadPrefix(byte[] data, String prefix, String suffix,String fileName, String contentType) { + return upload(new ByteArrayInputStream(data), getPath(prefix, suffix,fileName), Long.valueOf(data.length), contentType); + } + /** * 上传 byte[] 数据到 Amazon S3,使用指定的后缀构造对象键。 * @@ -649,4 +654,5 @@ public class OssClient { return policy.replaceAll("bucketName", bucketName); } + } diff --git a/dk-modules/business/pom.xml b/dk-modules/business/pom.xml index 1b3151d..f917221 100644 --- a/dk-modules/business/pom.xml +++ b/dk-modules/business/pom.xml @@ -121,6 +121,34 @@ common-rocketmq + + e-iceblue + spire.doc.free + 5.2.0 + + + + org.springframework.boot + spring-boot-starter-freemarker + + + + + com.itextpdf + itextpdf + 5.5.11 + + + com.itextpdf.tool + xmlworker + 5.5.11 + + + com.itextpdf + itext-asian + 5.2.0 + + ${project.artifactId} diff --git a/dk-modules/business/src/main/java/org/dromara/business/controller/BusinessAlertConstructInfoOssController.java b/dk-modules/business/src/main/java/org/dromara/business/controller/BusinessAlertConstructInfoOssController.java new file mode 100644 index 0000000..4b28248 --- /dev/null +++ b/dk-modules/business/src/main/java/org/dromara/business/controller/BusinessAlertConstructInfoOssController.java @@ -0,0 +1,160 @@ +package org.dromara.business.controller; + +import java.io.IOException; +import java.net.URL; +import java.util.List; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.dromara.business.domain.BusinessAlertConstructInfoOss; +import org.dromara.business.utils.MinioUntil; +import org.dromara.business.utils.constants.MinIOConstants; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.core.utils.file.MimeTypeUtils; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.oss.core.OssClient; +import org.dromara.common.oss.entity.UploadResult; +import org.dromara.common.oss.factory.OssFactory; +import org.dromara.business.domain.bo.BusinessAlertConstructInfoOssBo; +import org.dromara.business.service.IBusinessAlertConstructInfoOssService; +import org.dromara.business.domain.vo.BusinessAlertConstructInfoOssVo; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.web.core.BaseController; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.core.domain.R; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.excel.utils.ExcelUtil; +import org.springframework.web.multipart.MultipartFile; + +/** + * 预警任务-施工信息-oss + * 前端访问路由地址为:/business/businessAlertConstructInfoOss + * + * @author szs + * @date 2025-06-04 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/alertConstructInfoOss") +public class BusinessAlertConstructInfoOssController extends BaseController { + + private final IBusinessAlertConstructInfoOssService businessAlertConstructInfoOssService; + + /** + * 查询预警任务-施工信息-oss列表 + */ +// @SaCheckPermission("business:businessAlertConstructInfoOss:list") + @GetMapping("/list") + public TableDataInfo list(BusinessAlertConstructInfoOssBo bo, PageQuery pageQuery) { + TableDataInfo businessAlertConstructInfoOssVoTableDataInfo = businessAlertConstructInfoOssService.queryPageList(bo, pageQuery); + return businessAlertConstructInfoOssVoTableDataInfo; + } + + + /** + * 预警任务-施工信息-oss - 上传 + */ +// @SaCheckPermission("business:businessAlertConstructInfoOss:upload") +// @Log(title = "预警任务-施工信息-oss", businessType = BusinessType.EXPORT) + @PostMapping("/upload") + public R upload(@RequestPart("file") MultipartFile file, BusinessAlertConstructInfoOssBo bo, HttpServletResponse response) { + if (ObjectUtil.isNull(file)) { + return R.fail("上传文件不能为空"); + } + if(ObjectUtil.isNull(bo.getAlertConstructInfoId())){ + return R.fail("施工信息ID不能为空!"); + } + + //文件上传 +// OssClient storage = OssFactory.instance(MinIOConstants.BUCKET_DKCY); + OssClient storage = OssFactory.instance(MinIOConstants.BUCKET_NANTONG); + String originalfileName = file.getOriginalFilename(); + String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length()); + UploadResult uploadResult; + try { + uploadResult = storage.uploadPrefix(file.getBytes(),"construct", suffix, originalfileName, file.getContentType()); + } catch (IOException e) { + throw new ServiceException(e.getMessage()); + } + //保存记录 + BusinessAlertConstructInfoOssBo businessAlertConstructInfoOssBo = new BusinessAlertConstructInfoOssBo(); + businessAlertConstructInfoOssBo.setAlertConstructInfoId(bo.getAlertConstructInfoId()); + businessAlertConstructInfoOssBo.setFileName(file.getName()); + businessAlertConstructInfoOssBo.setOriginalName(originalfileName); + businessAlertConstructInfoOssBo.setFileSuffix(suffix); + businessAlertConstructInfoOssBo.setUrl(uploadResult.getFilename()); //格式:construct/2025/06/05/46e26e2df3a94a2dabb0d445ad3438f2DJI_20250602104843_0001_V.jpeg + businessAlertConstructInfoOssBo.setService(storage.getConfigKey()); + businessAlertConstructInfoOssService.insertByBo(businessAlertConstructInfoOssBo); + return R.ok(businessAlertConstructInfoOssBo); + } + + /** + * 导出预警任务-施工信息-oss列表 + */ +// @SaCheckPermission("business:businessAlertConstructInfoOss:export") +// @Log(title = "预警任务-施工信息-oss", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(BusinessAlertConstructInfoOssBo bo, HttpServletResponse response) { + List list = businessAlertConstructInfoOssService.queryList(bo); + ExcelUtil.exportExcel(list, "预警任务-施工信息-oss", BusinessAlertConstructInfoOssVo.class, response); + } + + /** + * 获取预警任务-施工信息-oss详细信息 + * + * @param id 主键 + */ +// @SaCheckPermission("business:businessAlertConstructInfoOss:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(businessAlertConstructInfoOssService.queryById(id)); + } + + /** + * 新增预警任务-施工信息-oss + */ +// @SaCheckPermission("business:businessAlertConstructInfoOss:add") +// @Log(title = "预警任务-施工信息-oss", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody BusinessAlertConstructInfoOssBo bo) { + return toAjax(businessAlertConstructInfoOssService.insertByBo(bo)); + } + + /** + * 修改预警任务-施工信息-oss + */ +// @SaCheckPermission("business:businessAlertConstructInfoOss:edit") +// @Log(title = "预警任务-施工信息-oss", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody BusinessAlertConstructInfoOssBo bo) { + return toAjax(businessAlertConstructInfoOssService.updateByBo(bo)); + } + + /** + * 删除预警任务-施工信息-oss + * + * @param ids 主键串 + */ +// @SaCheckPermission("business:businessAlertConstructInfoOss:remove") +// @Log(title = "预警任务-施工信息-oss", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + Boolean result = businessAlertConstructInfoOssService.deleteWithValidByIds(List.of(ids), true); + return toAjax(result); + } +} diff --git a/dk-modules/business/src/main/java/org/dromara/business/controller/BusinessAlertController.java b/dk-modules/business/src/main/java/org/dromara/business/controller/BusinessAlertController.java index aa6233a..34f84ad 100644 --- a/dk-modules/business/src/main/java/org/dromara/business/controller/BusinessAlertController.java +++ b/dk-modules/business/src/main/java/org/dromara/business/controller/BusinessAlertController.java @@ -1,38 +1,31 @@ package org.dromara.business.controller; import cn.dev33.satoken.annotation.SaCheckPermission; -import cn.hutool.core.convert.Convert; -import cn.hutool.core.util.ObjectUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.nacos.client.utils.TenantUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import org.apache.dubbo.config.annotation.DubboReference; +import org.dromara.business.api.domain.RemoteBusinessAlertRequest; import org.dromara.business.domain.BusinessAlert; import org.dromara.business.domain.bo.BusinessAlertBo; import org.dromara.business.domain.vo.BusinessAlertVo; import org.dromara.business.service.IBusinessAlertService; -import org.dromara.business.utils.MinioUntil; -import org.dromara.business.utils.constants.MinIOConstants; import org.dromara.common.core.domain.R; -import org.dromara.common.core.utils.DateUtils; import org.dromara.common.log.annotation.Log; import org.dromara.common.log.enums.BusinessType; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; -import org.dromara.common.satoken.utils.LoginHelper; -import org.dromara.common.tenant.helper.TenantHelper; import org.dromara.common.web.core.BaseController; import org.dromara.system.api.RemoteNoticeService; import org.dromara.system.api.RemoteSubmailConfigService; -import org.dromara.system.api.domain.bo.RemoteNoticeBo; import org.dromara.workflow.api.RemoteWorkflowService; -import org.dromara.workflow.api.domain.RemoteStartProcess; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -import java.util.Date; +import java.io.IOException; import java.util.List; /** @@ -121,41 +114,16 @@ public class BusinessAlertController extends BaseController { @Operation(summary ="预警推送-实时预警模块专用",description = "预警推送-实时预警模块专用") @GetMapping("/pushAlert") public R pushAlert(Long alertId,@RequestParam(required = false) String deptId,@RequestParam(required = false)String deptName) { - BusinessAlert businessAlert= businessAlertService.getBusinessAlert(alertId); - if(!ObjectUtil.hasEmpty(deptId,deptName)){ - businessAlert.setDeptName(deptName); - businessAlert.setDeptId(deptId); - } - businessAlert.setCreateTime(new Date()); - //businessAlert.setJobName(deptName + businessAlert.getLabelCn() + DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",businessAlert.getCreateTime())); - businessAlertService.updateBusinessAlert(businessAlert); - RemoteStartProcess startProcess = new RemoteStartProcess(); - startProcess.setBusinessId(String.valueOf(businessAlert.getId())); - startProcess.setFlowCode("alertChz"); - remoteWorkflowService.startWorkFlowBatch(List.of(startProcess)); - RemoteNoticeBo remoteNoticeBo = new RemoteNoticeBo(); - remoteNoticeBo.setNoticeTitle(businessAlert.getDeptName()+"产生预警,预警类型["+businessAlert.getLabelCn()+"],请立即查看"); - remoteNoticeBo.setNoticeType("3"); - remoteNoticeBo.setNoticeContent(businessAlert.getDeptName()+"产生预警,预警类型["+businessAlert.getLabelCn()+"],请立即查看"); - remoteNoticeBo.setStatus("0"); - remoteNoticeBo.setIsRead(0); - remoteNoticeBo.setCreateBy(1L); - remoteNoticeBo.setCreateDept(1L); - remoteNoticeBo.setCreateTime(businessAlert.getCreateTime()); - if (businessAlert.getBusinessType() == 2){ - businessAlert.setImages(MinioUntil.getObjectUrlOne(MinIOConstants.BUCKET_DKCY, businessAlert.getImages(), 3600).toString()); - } - remoteNoticeBo.setDeviceSn(businessAlert.getDeviceSn()); - businessAlert.setDeviceSn(businessAlert.getDeviceSn()); - remoteNoticeBo.setParam(JSON.toJSONString(businessAlert)); - remoteNoticeService.saveNotice(remoteNoticeBo); - remoteSubmailConfigService.remoteCmdSend("smsMultixsend", JSON.toJSONString(businessAlert)); + + businessAlertService.pushAlert(alertId,deptId,deptName); + + return R.ok(); } /** - * 查询全部预警/待办/已完成/忽略 + * 前端视频画框 */ @Operation(summary ="ai实时流预警保存",description = "ai实时流预警保存") @PostMapping("/saveAlertList") @@ -186,34 +154,53 @@ public class BusinessAlertController extends BaseController { } + /** + * 导出预警数据 + * @param bo + */ + @Operation(summary ="导出预警数据",description = "导出预警数据") + @GetMapping("/alert/export") + public void exportBusinessAlert(BusinessAlertBo bo, HttpServletResponse response) throws IOException { + businessAlertService.exportAlert(bo,response); + } - - @Operation(summary ="ai实时流预警保存-用于演示",description = "ai实时流预警保存-用于演示") - @PostMapping("/saveAlert") - public R selectAlert(@RequestBody BusinessAlertVo vo) { - vo.setBusinessType(2); - BusinessAlert businessAlert = businessAlertService.addBusinessAlert(vo); - RemoteStartProcess startProcess = new RemoteStartProcess(); - startProcess.setBusinessId(String.valueOf(businessAlert.getId())); - startProcess.setFlowCode("alertChz"); - remoteWorkflowService.startWorkFlowBatch(List.of(startProcess)); - RemoteNoticeBo remoteNoticeBo = new RemoteNoticeBo(); - remoteNoticeBo.setNoticeTitle(vo.getDeptName()+"产生预警,预警类型["+vo.getLabelCn()+"],请立即查看"); - remoteNoticeBo.setNoticeType("3"); - remoteNoticeBo.setNoticeContent(vo.getDeptName()+"产生预警,预警类型["+vo.getLabelCn()+"],请立即查看"); - remoteNoticeBo.setStatus("0"); - remoteNoticeBo.setIsRead(0); - remoteNoticeBo.setCreateBy(1L); - remoteNoticeBo.setCreateDept(1L); - remoteNoticeBo.setCreateTime(businessAlert.getCreateTime()); - if (businessAlert.getBusinessType() == 2){ - businessAlert.setImages(MinioUntil.getObjectUrlOne(MinIOConstants.BUCKET_DKCY, vo.getImages(), 3600).toString()); - } - remoteNoticeBo.setDeviceSn(vo.getDeviceSn()); - businessAlert.setDeviceSn(vo.getDeviceSn()); - remoteNoticeBo.setParam(JSON.toJSONString(businessAlert)); - remoteNoticeService.saveNotice(remoteNoticeBo); - remoteSubmailConfigService.remoteCmdSend("smsMultixsend", JSON.toJSONString(vo)); - return R.ok(); + @PostMapping("/saveBusinessAlert") +// public Boolean saveBusinessAlert(List alertVoList, String activeProfile) { +// public Boolean saveBusinessAlert(@RequestBody RemoteBusinessAlertRequest requestObj) { + public Boolean saveBusinessAlert(@RequestBody JSONObject requestJSON) { +// return businessAlertService.batchAddBusinessAlert(alertVoList, activeProfile); + RemoteBusinessAlertRequest requestObj = JSONUtil.toBean(requestJSON, RemoteBusinessAlertRequest.class); + return businessAlertService.batchAddBusinessAlert(requestObj.getAlertVoList(), requestObj.getActiveProfile()); } + + + +// @Operation(summary ="ai实时流预警保存-用于演示",description = "ai实时流预警保存-用于演示") +// @PostMapping("/saveAlert") +// public R selectAlert(@RequestBody BusinessAlertVo vo) { +// vo.setBusinessType(2); +// BusinessAlert businessAlert = businessAlertService.addBusinessAlert(vo); +// RemoteStartProcess startProcess = new RemoteStartProcess(); +// startProcess.setBusinessId(String.valueOf(businessAlert.getId())); +// startProcess.setFlowCode("alertChz"); +// remoteWorkflowService.startWorkFlowBatch(List.of(startProcess)); +// RemoteNoticeBo remoteNoticeBo = new RemoteNoticeBo(); +// remoteNoticeBo.setNoticeTitle(vo.getDeptName()+"产生预警,预警类型["+vo.getLabelCn()+"],请立即查看"); +// remoteNoticeBo.setNoticeType("3"); +// remoteNoticeBo.setNoticeContent(vo.getDeptName()+"产生预警,预警类型["+vo.getLabelCn()+"],请立即查看"); +// remoteNoticeBo.setStatus("0"); +// remoteNoticeBo.setIsRead(0); +// remoteNoticeBo.setCreateBy(1L); +// remoteNoticeBo.setCreateDept(1L); +// remoteNoticeBo.setCreateTime(businessAlert.getCreateTime()); +// if (businessAlert.getBusinessType() == 2){ +// businessAlert.setImages(MinioUntil.getObjectUrlOne(MinIOConstants.BUCKET_DKCY, vo.getImages(), 3600).toString()); +// } +// remoteNoticeBo.setDeviceSn(vo.getDeviceSn()); +// businessAlert.setDeviceSn(vo.getDeviceSn()); +// remoteNoticeBo.setParam(JSON.toJSONString(businessAlert)); +// remoteNoticeService.saveNotice(remoteNoticeBo); +// remoteSubmailConfigService.remoteCmdSend("smsMultixsend", JSON.toJSONString(vo)); +// return R.ok(); +// } } diff --git a/dk-modules/business/src/main/java/org/dromara/business/controller/BusinessLayerController.java b/dk-modules/business/src/main/java/org/dromara/business/controller/BusinessLayerController.java new file mode 100644 index 0000000..112b46c --- /dev/null +++ b/dk-modules/business/src/main/java/org/dromara/business/controller/BusinessLayerController.java @@ -0,0 +1,89 @@ +package org.dromara.business.controller; + + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.constraints.NotEmpty; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.dromara.business.domain.bo.BusinessLayerBo; +import org.dromara.business.domain.vo.BusinessLayerVo; + +import org.dromara.business.service.IBusinessLayerService; +import org.dromara.common.core.domain.R; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.web.core.BaseController; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@Slf4j +@Validated +@RequiredArgsConstructor +@RestController +@Tag(name = "图层模块") +@RequestMapping("/layer") +public class BusinessLayerController extends BaseController { + + private final IBusinessLayerService businessLayerService; + /** + * 图层模块列表 + */ + @Operation(summary ="图层模块列表",description = "图层模块列表") +// @SaCheckPermission("business:layer:list") + @GetMapping("/list") + public R> list(BusinessLayerBo bo, PageQuery pageQuery) { + return R.ok(businessLayerService.queryPageList(bo, pageQuery)); + } + + @Operation(summary ="图层下拉列表",description = "图层下拉列表") + @GetMapping("/optionSelect") + public R> optionSelect() { + return R.ok(businessLayerService.optionSelect()); + } + + /** + * 图层新增 + */ + @Operation(summary ="图层新增",description = "图层新增") +// @SaCheckPermission("business:layer:add") + @Log(title = "图层新增", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody BusinessLayerBo bo) { + return toAjax(businessLayerService.insert(bo)); + } + + /** + * 图层修改 + */ +// @SaCheckPermission("business:layer:edit") + @Operation(summary ="图层修改",description = "图层修改") + @Log(title = "图层修改", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody BusinessLayerBo bo) { + return toAjax(businessLayerService.update(bo)); + } + + /** + * 删除 + * + * @param id 主键 + */ +// @SaCheckPermission("business:task:remove") + @Operation(summary ="图层删除",description = "图层删除") + @Log(title = "图层删除", businessType = BusinessType.DELETE) + @GetMapping("/delete") + public R remove(@RequestParam("id") Long id) { + return toAjax(businessLayerService.delete(id)); + } +} diff --git a/dk-modules/business/src/main/java/org/dromara/business/domain/BusinessAlert.java b/dk-modules/business/src/main/java/org/dromara/business/domain/BusinessAlert.java index e98774b..3906abe 100644 --- a/dk-modules/business/src/main/java/org/dromara/business/domain/BusinessAlert.java +++ b/dk-modules/business/src/main/java/org/dromara/business/domain/BusinessAlert.java @@ -257,4 +257,36 @@ public class BusinessAlert { //预警扩展施工信息 @TableField(exist = false) private BusinessAlertConstructInfoVo alertConstructInfoVo; + + /** + * 指南针 + */ + @TableField(exist = false) + private String icon; + + + @TableField(exist = false) + private String postCategory; //类别编码,用来过滤预警查询返回值(南通的查询南通类,丰县查询丰县) + + + /** + * 无人机方向 + */ + private String direction; + + /** + * 无人机云台偏航角 + */ + private String gimbalYaw; + + /** + * 无人机高 + */ + private String height; + + /** + * 无人机俯视角 + */ + private String gimbalPitch; + } diff --git a/dk-modules/business/src/main/java/org/dromara/business/domain/BusinessAlertConstructInfo.java b/dk-modules/business/src/main/java/org/dromara/business/domain/BusinessAlertConstructInfo.java index 4c349fc..881d1c6 100644 --- a/dk-modules/business/src/main/java/org/dromara/business/domain/BusinessAlertConstructInfo.java +++ b/dk-modules/business/src/main/java/org/dromara/business/domain/BusinessAlertConstructInfo.java @@ -4,8 +4,10 @@ import org.dromara.common.tenant.core.TenantEntity; import com.baomidou.mybatisplus.annotation.*; import lombok.Data; import lombok.EqualsAndHashCode; +import org.dromara.business.domain.BusinessAlertConstructInfoOss; import java.io.Serial; +import java.util.List; /** * 预警任务-施工信息对象 business_alert_construct_info @@ -22,7 +24,7 @@ public class BusinessAlertConstructInfo extends TenantEntity { private static final long serialVersionUID = 1L; /** - * + * */ @TableId(value = "id") private Long id; @@ -83,4 +85,8 @@ public class BusinessAlertConstructInfo extends TenantEntity { private String remark; + @TableField(exist = false) + private List alertConstructInfoOssList; + + } diff --git a/dk-modules/business/src/main/java/org/dromara/business/domain/BusinessAlertConstructInfoOss.java b/dk-modules/business/src/main/java/org/dromara/business/domain/BusinessAlertConstructInfoOss.java new file mode 100644 index 0000000..07e4d61 --- /dev/null +++ b/dk-modules/business/src/main/java/org/dromara/business/domain/BusinessAlertConstructInfoOss.java @@ -0,0 +1,74 @@ +package org.dromara.business.domain; + +import org.dromara.common.tenant.core.TenantEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; + +/** + * 预警任务-施工信息-oss对象 business_alert_construct_info_oss + * + * @author szs + * @date 2025-06-04 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("business_alert_construct_info_oss") +public class BusinessAlertConstructInfoOss extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId(value = "id") + private Long id; + + /** + * 施工信息ID + */ + private Long alertConstructInfoId; + + /** + * 施工信息 + */ + private Long alertConstructInfoName; + + /** + * 文件名 + */ + private String fileName; + + /** + * 原名 + */ + private String originalName; + + /** + * 文件后缀名 + */ + private String fileSuffix; + + /** + * URL地址 + */ + private String url; + + @TableField(exist = false) + private String previewUrl; + + /** + * 备注 + */ + private String remark; + + /** + * 服务商 + */ + private String service; + + +} diff --git a/dk-modules/business/src/main/java/org/dromara/business/domain/BusinessLayer.java b/dk-modules/business/src/main/java/org/dromara/business/domain/BusinessLayer.java new file mode 100644 index 0000000..06ffc43 --- /dev/null +++ b/dk-modules/business/src/main/java/org/dromara/business/domain/BusinessLayer.java @@ -0,0 +1,70 @@ +package org.dromara.business.domain; + + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.common.translation.annotation.Translation; +import org.dromara.common.translation.constant.TransConstant; + +import java.io.Serial; +import java.util.Date; + +@Data +@TableName(value = "business_layer", autoResultMap = true) +public class BusinessLayer extends BaseEntity { + + /** + * id + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + + private String layerName; + + + /*0:禁用 1:启用*/ + private Boolean enable; + + /** + * 0菜单 1三维 2矢量 3影像 + */ + private Integer layerType; + + @TableField(exist = false) + @Translation(type = TransConstant.DICT_TYPE_TO_LABEL, mapper = "layerType", other = "layer_type") + private String layerTypeName; + + /** + * 图层url + */ + private String layerUrl; + + /** + * 部门id + */ + private Long deptId; + + /** + * 部门名称 + */ + private String deptName; + + /** + * 备注 + */ + private String remark; + + /** + * 排序 + */ + private Integer sort; + + /** + * 父类id + */ + private Long parentId; + +} diff --git a/dk-modules/business/src/main/java/org/dromara/business/domain/bo/BusinessAlertBo.java b/dk-modules/business/src/main/java/org/dromara/business/domain/bo/BusinessAlertBo.java index 5db6e46..319602d 100644 --- a/dk-modules/business/src/main/java/org/dromara/business/domain/bo/BusinessAlertBo.java +++ b/dk-modules/business/src/main/java/org/dromara/business/domain/bo/BusinessAlertBo.java @@ -247,4 +247,31 @@ public class BusinessAlertBo { */ private String caseNumber; + /** + * 不传的话默认world + */ + private String exportType = "world"; + + /** + * 无人机方向 + */ + private String direction; + + /** + * 无人机云台偏航角 + */ + private String gimbalYaw; + + /** + * 无人机高 + */ + private String height; + + /** + * 无人机俯视角 + */ + private String gimbalPitch; + + private String postCategory; //类别编码,用来过滤预警查询返回值(南通的查询南通类,丰县查询丰县) + } diff --git a/dk-modules/business/src/main/java/org/dromara/business/domain/bo/BusinessAlertConstructInfoOssBo.java b/dk-modules/business/src/main/java/org/dromara/business/domain/bo/BusinessAlertConstructInfoOssBo.java new file mode 100644 index 0000000..d340f85 --- /dev/null +++ b/dk-modules/business/src/main/java/org/dromara/business/domain/bo/BusinessAlertConstructInfoOssBo.java @@ -0,0 +1,73 @@ +package org.dromara.business.domain.bo; + +import org.dromara.business.domain.BusinessAlertConstructInfoOss; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; + +/** + * 预警任务-施工信息-oss业务对象 business_alert_construct_info_oss + * + * @author szs + * @date 2025-06-04 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = BusinessAlertConstructInfoOss.class, reverseConvertGenerate = false) +public class BusinessAlertConstructInfoOssBo extends BaseEntity { + + /** + * 主键 + */ + @NotNull(message = "主键不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 施工信息ID + */ + @NotNull(message = "施工信息ID不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long alertConstructInfoId; + + /** + * 施工信息 + */ + private Long alertConstructInfoName; + + /** + * 文件名 + */ + @NotBlank(message = "文件名不能为空", groups = { AddGroup.class, EditGroup.class }) + private String fileName; + + /** + * 原名 + */ + private String originalName; + + /** + * 文件后缀名 + */ + private String fileSuffix; + + /** + * URL地址 + */ + private String url; + + /** + * 备注 + */ + private String remark; + + /** + * 服务商 + */ + @NotBlank(message = "服务商不能为空", groups = { AddGroup.class, EditGroup.class }) + private String service; + + +} diff --git a/dk-modules/business/src/main/java/org/dromara/business/domain/bo/BusinessLayerBo.java b/dk-modules/business/src/main/java/org/dromara/business/domain/bo/BusinessLayerBo.java new file mode 100644 index 0000000..ca9c350 --- /dev/null +++ b/dk-modules/business/src/main/java/org/dromara/business/domain/bo/BusinessLayerBo.java @@ -0,0 +1,68 @@ +package org.dromara.business.domain.bo; + + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import io.github.linpeilie.annotations.AutoMapper; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import org.dromara.business.domain.BusinessLayer; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.translation.annotation.Translation; +import org.dromara.common.translation.constant.TransConstant; + +import java.io.Serial; +import java.util.Date; + +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = BusinessLayer.class,reverseConvertGenerate = false) +public class BusinessLayerBo { + @Serial + private static final long serialVersionUID = 1L; + + /** + * id + */ + private Long id; + + + @NotNull(message = "图层名称不能为空", groups = { AddGroup.class}) + private String layerName; + + /*0:禁用 1:启用*/ + private Boolean enable; + /** + * 时间 + * */ + private Date createTime; + + /** + * 0目录 1地址 + */ + @NotNull(message = "图层类型不能为空", groups = { AddGroup.class}) + private Integer layerType; + + /** + * 图层url + */ + private String layerUrl; + + private String tenantId; + @NotNull(message = "部门id不能为空", groups = { AddGroup.class}) + private Long deptId; + + @NotNull(message = "部门名称不能为空", groups = { AddGroup.class}) + private String deptName; + + private String remark; + + //排序 + private Integer sort; + //父部门id + private Long parentId; + + private String startTime; + private String endTime; + +} diff --git a/dk-modules/business/src/main/java/org/dromara/business/domain/model/enums/LayerTypeEnum.java b/dk-modules/business/src/main/java/org/dromara/business/domain/model/enums/LayerTypeEnum.java new file mode 100644 index 0000000..54ef2bb --- /dev/null +++ b/dk-modules/business/src/main/java/org/dromara/business/domain/model/enums/LayerTypeEnum.java @@ -0,0 +1,23 @@ +package org.dromara.business.domain.model.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum LayerTypeEnum { + + menu(0,"目录"), + + threeDimensional(1,"三维"), + + vector(2,"矢量"), + + image(3,"影像"); + + + private Integer type; + + private String desc; + +} diff --git a/dk-modules/business/src/main/java/org/dromara/business/domain/vo/BusinessAlertConstructInfoOssVo.java b/dk-modules/business/src/main/java/org/dromara/business/domain/vo/BusinessAlertConstructInfoOssVo.java new file mode 100644 index 0000000..a6270a5 --- /dev/null +++ b/dk-modules/business/src/main/java/org/dromara/business/domain/vo/BusinessAlertConstructInfoOssVo.java @@ -0,0 +1,88 @@ +package org.dromara.business.domain.vo; + +import org.dromara.business.domain.BusinessAlertConstructInfoOss; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + + +/** + * 预警任务-施工信息-oss视图对象 business_alert_construct_info_oss + * + * @author szs + * @date 2025-06-04 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = BusinessAlertConstructInfoOss.class) +public class BusinessAlertConstructInfoOssVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @ExcelProperty(value = "主键") + private Long id; + + /** + * 施工信息ID + */ + @ExcelProperty(value = "施工信息ID") + private Long alertConstructInfoId; + + /** + * 施工信息 + */ + @ExcelProperty(value = "施工信息") + private Long alertConstructInfoName; + + /** + * 文件名 + */ + @ExcelProperty(value = "文件名") + private String fileName; + + /** + * 原名 + */ + @ExcelProperty(value = "原名") + private String originalName; + + /** + * 文件后缀名 + */ + @ExcelProperty(value = "文件后缀名") + private String fileSuffix; + + /** + * URL地址 + */ + @ExcelProperty(value = "URL地址") + private String url; + + private String previewUrl; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + /** + * 服务商 + */ + @ExcelProperty(value = "服务商") + private String service; + + +} diff --git a/dk-modules/business/src/main/java/org/dromara/business/domain/vo/BusinessAlertConstructInfoVo.java b/dk-modules/business/src/main/java/org/dromara/business/domain/vo/BusinessAlertConstructInfoVo.java index b4d48af..f1abc2b 100644 --- a/dk-modules/business/src/main/java/org/dromara/business/domain/vo/BusinessAlertConstructInfoVo.java +++ b/dk-modules/business/src/main/java/org/dromara/business/domain/vo/BusinessAlertConstructInfoVo.java @@ -7,11 +7,12 @@ import org.dromara.common.excel.annotation.ExcelDictFormat; import org.dromara.common.excel.convert.ExcelDictConvert; import io.github.linpeilie.annotations.AutoMapper; import lombok.Data; +import org.dromara.business.domain.BusinessAlertConstructInfoOss; import java.io.Serial; import java.io.Serializable; import java.util.Date; - +import java.util.List; /** @@ -29,7 +30,7 @@ public class BusinessAlertConstructInfoVo implements Serializable { private static final long serialVersionUID = 1L; /** - * + * */ @ExcelProperty(value = "") private Long id; @@ -100,5 +101,7 @@ public class BusinessAlertConstructInfoVo implements Serializable { @ExcelProperty(value = "备注") private String remark; + private List alertConstructInfoOssList;//文件列表 + } diff --git a/dk-modules/business/src/main/java/org/dromara/business/domain/vo/BusinessAlertVo.java b/dk-modules/business/src/main/java/org/dromara/business/domain/vo/BusinessAlertVo.java index cfc7d8e..83d5d10 100644 --- a/dk-modules/business/src/main/java/org/dromara/business/domain/vo/BusinessAlertVo.java +++ b/dk-modules/business/src/main/java/org/dromara/business/domain/vo/BusinessAlertVo.java @@ -211,4 +211,37 @@ public class BusinessAlertVo implements Serializable { * 案件号 */ private String caseNumber; + + + /** + * 无人机方向 + */ + private String direction; + + /** + * 无人机云台偏航角 + */ + private String gimbalYaw; + + /** + * 无人机高 + */ + private String height; + + /** + * 无人机俯视角 + */ + private String gimbalPitch; + + /** + * 画框的四个角度参数 + */ + private Integer lx; + + private Integer ly; + + private Integer rx; + + private Integer ry; + } diff --git a/dk-modules/business/src/main/java/org/dromara/business/domain/vo/BusinessLayerVo.java b/dk-modules/business/src/main/java/org/dromara/business/domain/vo/BusinessLayerVo.java new file mode 100644 index 0000000..52460ff --- /dev/null +++ b/dk-modules/business/src/main/java/org/dromara/business/domain/vo/BusinessLayerVo.java @@ -0,0 +1,76 @@ +package org.dromara.business.domain.vo; + + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.github.linpeilie.annotations.AutoMapper; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.business.domain.BusinessLayer; +import org.dromara.business.domain.BusinessTask; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.translation.annotation.Translation; +import org.dromara.common.translation.constant.TransConstant; + +import java.io.Serial; +import java.util.Date; +import java.util.List; + +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = BusinessLayer.class) +public class BusinessLayerVo { + @Serial + private static final long serialVersionUID = 1L; + + /** + * id + */ + private Long id; + + /** + * 用于前端渲染 + */ + private Long key; + + private String layerName; + + /*0:禁用 1:启用*/ + private Boolean enable; + + /** + * 0菜单 1三维 2矢量 3影像 + */ + private Integer layerType; + + @Translation(type = TransConstant.DICT_TYPE_TO_LABEL, mapper = "layerType", other = "layer_type") + private String layerTypeName; + + private String tenantId; + + private Long deptId; + + /** + * 图层url + */ + private String layerUrl; + + private String deptName; + + private String remark; + + //排序 + private Integer sort; + + //父id + private Long parentId; + + private List children; + + //用于前端回显 + private List deptIdList; + +} diff --git a/dk-modules/business/src/main/java/org/dromara/business/dubbo/RemoteBusinessAlertServiceImpl.java b/dk-modules/business/src/main/java/org/dromara/business/dubbo/RemoteBusinessAlertServiceImpl.java index e139e1e..9a1726d 100644 --- a/dk-modules/business/src/main/java/org/dromara/business/dubbo/RemoteBusinessAlertServiceImpl.java +++ b/dk-modules/business/src/main/java/org/dromara/business/dubbo/RemoteBusinessAlertServiceImpl.java @@ -1,6 +1,7 @@ package org.dromara.business.dubbo; import lombok.RequiredArgsConstructor; +import org.apache.dubbo.config.annotation.DubboReference; import org.apache.dubbo.config.annotation.DubboService; import org.dromara.business.api.RemoteBusinessAlertService; import org.dromara.business.api.domain.bo.RemoteBusinessAlertBo; @@ -9,6 +10,8 @@ import org.dromara.business.domain.vo.BusinessAlertVo; import org.dromara.business.service.IBusinessAlertService; import org.dromara.business.utils.MinioUntil; import org.dromara.business.utils.constants.MinIOConstants; +import org.dromara.system.api.RemoteSubmailConfigService; +import org.dromara.system.api.RemoteUserService; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; @@ -26,7 +29,8 @@ import java.util.stream.Collectors; public class RemoteBusinessAlertServiceImpl implements RemoteBusinessAlertService { private final IBusinessAlertService businessAlertService; - + @DubboReference(timeout = 30000) + private RemoteSubmailConfigService remoteSubmailConfigService; @Override public Boolean saveBusinessAlert(List alertVoList, String activeProfile) { @@ -84,5 +88,7 @@ public class RemoteBusinessAlertServiceImpl implements RemoteBusinessAlertServic }).toList(); businessAlertService.batchUpdateDept(alertVoList); + //短信推送 + remoteSubmailConfigService.remoteSend("smsMultixsend", alertList); } } diff --git a/dk-modules/business/src/main/java/org/dromara/business/feign/FeignDeviceGroup.java b/dk-modules/business/src/main/java/org/dromara/business/feign/FeignDeviceGroup.java index 21924a8..648aabe 100644 --- a/dk-modules/business/src/main/java/org/dromara/business/feign/FeignDeviceGroup.java +++ b/dk-modules/business/src/main/java/org/dromara/business/feign/FeignDeviceGroup.java @@ -22,4 +22,8 @@ public interface FeignDeviceGroup { @GetMapping("/device/flight/count") public Map getDevices(); + + @GetMapping("/media/api/v1/files/degree") + public Double getGimbalYawDegree(@RequestParam("fileId") String fileId); + } diff --git a/dk-modules/business/src/main/java/org/dromara/business/mapper/BusinessAlertConstructInfoOssMapper.java b/dk-modules/business/src/main/java/org/dromara/business/mapper/BusinessAlertConstructInfoOssMapper.java new file mode 100644 index 0000000..ccccccc --- /dev/null +++ b/dk-modules/business/src/main/java/org/dromara/business/mapper/BusinessAlertConstructInfoOssMapper.java @@ -0,0 +1,20 @@ +package org.dromara.business.mapper; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Param; +import org.dromara.business.domain.BusinessAlertConstructInfoOss; +import org.dromara.business.domain.vo.BusinessAlertConstructInfoOssVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 预警任务-施工信息-ossMapper接口 + * + * @author szs + * @date 2025-06-04 + */ +public interface BusinessAlertConstructInfoOssMapper extends BaseMapperPlus { + + Page selectVoPageData(@Param("page") Page page,@Param("ew") QueryWrapper qw); +} diff --git a/dk-modules/business/src/main/java/org/dromara/business/mapper/BusinessAlertMapper.java b/dk-modules/business/src/main/java/org/dromara/business/mapper/BusinessAlertMapper.java index e2823c1..a6b500a 100644 --- a/dk-modules/business/src/main/java/org/dromara/business/mapper/BusinessAlertMapper.java +++ b/dk-modules/business/src/main/java/org/dromara/business/mapper/BusinessAlertMapper.java @@ -121,4 +121,9 @@ public interface BusinessAlertMapper extends BaseMapperPlus alertVoList); + + @DataPermission( + @DataColumn(key = "deptName", value = "t.dept_id") + ) + List exportAlert(@Param("ew") QueryWrapper ew, @Param("tbPrefix") ProjectTablePrefixConfig tbPrefix); } diff --git a/dk-modules/business/src/main/java/org/dromara/business/mapper/BusinessLayerMapper.java b/dk-modules/business/src/main/java/org/dromara/business/mapper/BusinessLayerMapper.java new file mode 100644 index 0000000..622861f --- /dev/null +++ b/dk-modules/business/src/main/java/org/dromara/business/mapper/BusinessLayerMapper.java @@ -0,0 +1,20 @@ +package org.dromara.business.mapper; + + + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Param; +import org.dromara.business.domain.BusinessLayer; +import org.dromara.business.domain.bo.BusinessLayerBo; +import org.dromara.business.domain.bo.BusinessTaskBo; +import org.dromara.business.domain.vo.BusinessLayerVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +import java.util.List; + +public interface BusinessLayerMapper extends BaseMapperPlus { + + Page queryPageList(@Param("page") Page page, @Param("bo") BusinessLayerBo bo); + + List selectInfoByParent(@Param("parentId") Long parentId); +} diff --git a/dk-modules/business/src/main/java/org/dromara/business/service/IBusinessAlertConstructInfoOssService.java b/dk-modules/business/src/main/java/org/dromara/business/service/IBusinessAlertConstructInfoOssService.java new file mode 100644 index 0000000..4ab5544 --- /dev/null +++ b/dk-modules/business/src/main/java/org/dromara/business/service/IBusinessAlertConstructInfoOssService.java @@ -0,0 +1,69 @@ +package org.dromara.business.service; + +import org.dromara.business.domain.BusinessAlertConstructInfoOss; +import org.dromara.business.domain.vo.BusinessAlertConstructInfoOssVo; +import org.dromara.business.domain.bo.BusinessAlertConstructInfoOssBo; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 预警任务-施工信息-ossService接口 + * + * @author szs + * @date 2025-06-04 + */ +public interface IBusinessAlertConstructInfoOssService { + + /** + * 查询预警任务-施工信息-oss + * + * @param id 主键 + * @return 预警任务-施工信息-oss + */ + BusinessAlertConstructInfoOssVo queryById(Long id); + + /** + * 分页查询预警任务-施工信息-oss列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 预警任务-施工信息-oss分页列表 + */ + TableDataInfo queryPageList(BusinessAlertConstructInfoOssBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的预警任务-施工信息-oss列表 + * + * @param bo 查询条件 + * @return 预警任务-施工信息-oss列表 + */ + List queryList(BusinessAlertConstructInfoOssBo bo); + + /** + * 新增预警任务-施工信息-oss + * + * @param bo 预警任务-施工信息-oss + * @return 是否新增成功 + */ + Boolean insertByBo(BusinessAlertConstructInfoOssBo bo); + + /** + * 修改预警任务-施工信息-oss + * + * @param bo 预警任务-施工信息-oss + * @return 是否修改成功 + */ + Boolean updateByBo(BusinessAlertConstructInfoOssBo bo); + + /** + * 校验并批量删除预警任务-施工信息-oss信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/dk-modules/business/src/main/java/org/dromara/business/service/IBusinessAlertService.java b/dk-modules/business/src/main/java/org/dromara/business/service/IBusinessAlertService.java index 7b0fc80..1ef5e4a 100644 --- a/dk-modules/business/src/main/java/org/dromara/business/service/IBusinessAlertService.java +++ b/dk-modules/business/src/main/java/org/dromara/business/service/IBusinessAlertService.java @@ -1,5 +1,6 @@ package org.dromara.business.service; +import jakarta.servlet.http.HttpServletResponse; import org.dromara.business.api.domain.bo.RemoteBusinessAlertBo; import org.dromara.business.api.domain.vo.RemoteBusinessAlertVo; import org.dromara.business.domain.BusinessAlert; @@ -8,6 +9,7 @@ import org.dromara.business.domain.vo.BusinessAlertVo; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.PageQuery; +import java.io.IOException; import java.util.List; import java.util.Map; @@ -102,4 +104,9 @@ public interface IBusinessAlertService { Boolean updateBusinessAlert(BusinessAlert businessAlert); TableDataInfo listAiVerifyAlert(BusinessAlertVo vo,PageQuery pageQuery); + + void exportAlert(BusinessAlertBo bo, HttpServletResponse response) throws IOException; + + void pushAlert(Long alertId, String deptId, String deptName); + } diff --git a/dk-modules/business/src/main/java/org/dromara/business/service/IBusinessLayerService.java b/dk-modules/business/src/main/java/org/dromara/business/service/IBusinessLayerService.java new file mode 100644 index 0000000..7d47bd7 --- /dev/null +++ b/dk-modules/business/src/main/java/org/dromara/business/service/IBusinessLayerService.java @@ -0,0 +1,27 @@ +package org.dromara.business.service; + +import org.dromara.business.domain.bo.BusinessLayerBo; +import org.dromara.business.domain.vo.BusinessLayerVo; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; + +import java.util.List; + +public interface IBusinessLayerService { + + /** + * 分页查询工单预约列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 工单预约分页列表 + */ + TableDataInfo queryPageList(BusinessLayerBo bo, PageQuery pageQuery); + + Boolean insert(BusinessLayerBo bo); + Boolean update(BusinessLayerBo bo); + Boolean delete(Long id); + + List optionSelect(); + +} diff --git a/dk-modules/business/src/main/java/org/dromara/business/service/impl/BusinessAlertConstructInfoOssServiceImpl.java b/dk-modules/business/src/main/java/org/dromara/business/service/impl/BusinessAlertConstructInfoOssServiceImpl.java new file mode 100644 index 0000000..79c362d --- /dev/null +++ b/dk-modules/business/src/main/java/org/dromara/business/service/impl/BusinessAlertConstructInfoOssServiceImpl.java @@ -0,0 +1,193 @@ +package org.dromara.business.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import org.dromara.business.domain.BusinessAlert; +import org.dromara.business.service.IBusinessAlertConstructInfoOssService; +import org.dromara.business.utils.MinioUntil; +import org.dromara.business.utils.constants.MinIOConstants; +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import org.dromara.business.domain.BusinessAlertConstructInfoOss; +import org.dromara.business.domain.bo.BusinessAlertConstructInfoOssBo; +import org.dromara.business.domain.vo.BusinessAlertConstructInfoOssVo; +import org.dromara.business.mapper.BusinessAlertConstructInfoOssMapper; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 预警任务-施工信息-ossService业务层处理 + * + * @author szs + * @date 2025-06-04 + */ +@RequiredArgsConstructor +@Service +public class BusinessAlertConstructInfoOssServiceImpl implements IBusinessAlertConstructInfoOssService { + + private final BusinessAlertConstructInfoOssMapper baseMapper; + + /** + * 查询预警任务-施工信息-oss + * + * @param id 主键 + * @return 预警任务-施工信息-oss + */ + @Override + public BusinessAlertConstructInfoOssVo queryById(Long id){ + return baseMapper.selectVoById(id); + } + + /** + * 分页查询预警任务-施工信息-oss列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 预警任务-施工信息-oss分页列表 + */ + @Override + public TableDataInfo queryPageList(BusinessAlertConstructInfoOssBo bo, PageQuery pageQuery) { + QueryWrapper wrapper = buildQueryWrapperQuery(bo); + Page result = baseMapper.selectVoPageData(pageQuery.build(), wrapper); + result.getRecords().forEach(item -> { + item.setPreviewUrl(MinioUntil.getObjectUrlOne(MinIOConstants.BUCKET_NANTONG, item.getUrl(), 3600).toString()); + }); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的预警任务-施工信息-oss列表 + * + * @param bo 查询条件 + * @return 预警任务-施工信息-oss列表 + */ + @Override + public List queryList(BusinessAlertConstructInfoOssBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(BusinessAlertConstructInfoOssBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(bo.getAlertConstructInfoId() != null, BusinessAlertConstructInfoOss::getAlertConstructInfoId, bo.getAlertConstructInfoId()); + lqw.like(bo.getAlertConstructInfoName() != null, BusinessAlertConstructInfoOss::getAlertConstructInfoName, bo.getAlertConstructInfoName()); + lqw.like(StringUtils.isNotBlank(bo.getFileName()), BusinessAlertConstructInfoOss::getFileName, bo.getFileName()); + lqw.like(StringUtils.isNotBlank(bo.getOriginalName()), BusinessAlertConstructInfoOss::getOriginalName, bo.getOriginalName()); + lqw.eq(StringUtils.isNotBlank(bo.getFileSuffix()), BusinessAlertConstructInfoOss::getFileSuffix, bo.getFileSuffix()); + lqw.eq(StringUtils.isNotBlank(bo.getUrl()), BusinessAlertConstructInfoOss::getUrl, bo.getUrl()); + lqw.eq(StringUtils.isNotBlank(bo.getService()), BusinessAlertConstructInfoOss::getService, bo.getService()); + return lqw; + } + + private QueryWrapper buildQueryWrapperQuery(BusinessAlertConstructInfoOssBo bo) { + QueryWrapper wrapper = new QueryWrapper<>(); + if(ObjectUtil.isNotEmpty(bo.getId())){ + wrapper.eq("t.id", bo.getId()); + } + if(ObjectUtil.isNotEmpty(bo.getAlertConstructInfoId())){ + wrapper.eq("t.alert_construct_info_id", bo.getAlertConstructInfoId()); + } + if(ObjectUtil.isNotEmpty(bo.getAlertConstructInfoName())){ + wrapper.eq("t.alert_construct_info_name", bo.getAlertConstructInfoName()); + } + if(ObjectUtil.isNotEmpty(bo.getFileName())){ + wrapper.eq("t.file_name", bo.getFileName()); + } + + if(ObjectUtil.isNotEmpty(bo.getOriginalName())){ + wrapper.eq("t.original_name", bo.getOriginalName()); + } + if(ObjectUtil.isNotEmpty(bo.getFileSuffix())){ + wrapper.eq("t.file_suffix", bo.getFileSuffix()); + } + if(ObjectUtil.isNotEmpty(bo.getUrl())){ + wrapper.eq("t.url", bo.getUrl()); + } + if(ObjectUtil.isNotEmpty(bo.getCreateDept())){ + wrapper.eq("t.create_dept", bo.getCreateDept()); + } + if(ObjectUtil.isNotEmpty(bo.getCreateTime())){ + wrapper.eq("t.create_time", bo.getCreateTime()); + } + if(ObjectUtil.isNotEmpty(bo.getCreateBy())){ + wrapper.eq("t.create_by", bo.getCreateBy()); + } + + if(ObjectUtil.isNotEmpty(bo.getUpdateTime())){ + wrapper.eq("t.update_time", bo.getUpdateTime()); + } + + if(ObjectUtil.isNotEmpty(bo.getUpdateBy())){ + wrapper.eq("t.update_by", bo.getUpdateBy()); + } + if(ObjectUtil.isNotEmpty(bo.getRemark())){ + wrapper.eq("t.remark", bo.getRemark()); + } + if(ObjectUtil.isNotEmpty(bo.getService())){ + wrapper.eq("t.service", bo.getService()); + } + return wrapper; + } + + /** + * 新增预警任务-施工信息-oss + * + * @param bo 预警任务-施工信息-oss + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(BusinessAlertConstructInfoOssBo bo) { + BusinessAlertConstructInfoOss add = MapstructUtils.convert(bo, BusinessAlertConstructInfoOss.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改预警任务-施工信息-oss + * + * @param bo 预警任务-施工信息-oss + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(BusinessAlertConstructInfoOssBo bo) { + BusinessAlertConstructInfoOss update = MapstructUtils.convert(bo, BusinessAlertConstructInfoOss.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(BusinessAlertConstructInfoOss entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除预警任务-施工信息-oss信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } +} diff --git a/dk-modules/business/src/main/java/org/dromara/business/service/impl/BusinessAlertServiceImpl.java b/dk-modules/business/src/main/java/org/dromara/business/service/impl/BusinessAlertServiceImpl.java index f451e41..c796b5a 100644 --- a/dk-modules/business/src/main/java/org/dromara/business/service/impl/BusinessAlertServiceImpl.java +++ b/dk-modules/business/src/main/java/org/dromara/business/service/impl/BusinessAlertServiceImpl.java @@ -1,30 +1,40 @@ package org.dromara.business.service.impl; +import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.itextpdf.text.DocumentException; +import freemarker.template.TemplateException; +import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.config.annotation.DubboReference; +import org.apache.dubbo.config.annotation.DubboService; import org.dromara.business.api.domain.bo.RemoteBusinessAlertBo; import org.dromara.business.api.domain.vo.RemoteBusinessAlertConstructInfo; import org.dromara.business.api.domain.vo.RemoteBusinessAlertVo; import org.dromara.business.config.ProjectTablePrefixConfig; import org.dromara.business.domain.BusinessAlert; +import org.dromara.business.domain.BusinessAlertConstructInfo; import org.dromara.business.domain.bo.BusinessAlertBo; import org.dromara.business.domain.vo.BusinessAlertConstructInfoVo; import org.dromara.business.domain.vo.BusinessAlertVo; +import org.dromara.business.feign.FeignDeviceGroup; import org.dromara.business.mapper.BusinessAlertConstructInfoMapper; import org.dromara.business.mapper.BusinessAlertMapper; import org.dromara.business.service.IBusinessAlertService; -import org.dromara.business.utils.BatchProcessorUtil; -import org.dromara.business.utils.MinioUntil; +import org.dromara.business.utils.*; import org.dromara.business.utils.constants.MinIOConstants; import org.dromara.common.core.enums.BusinessStatusEnum; import org.dromara.common.core.enums.FormatsType; @@ -34,18 +44,25 @@ import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StreamUtils; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; -import org.dromara.business.utils.MinioUtil; import org.dromara.common.satoken.utils.LoginHelper; -import org.dromara.system.api.RemoteLabelPostService; +import org.dromara.resource.api.RemoteMessageService; +import org.dromara.system.api.*; +import org.dromara.system.api.domain.bo.RemoteNoticeBo; import org.dromara.system.api.domain.vo.RemoteAiLabelPostVo; import org.dromara.system.api.domain.vo.RemoteUserVo; +import org.dromara.business.domain.BusinessAlertConstructInfoOss; +import org.dromara.business.mapper.BusinessAlertConstructInfoOssMapper; import org.dromara.workflow.api.RemoteWorkflowService; import org.dromara.workflow.api.domain.RemoteStartProcess; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; import java.lang.reflect.Method; +import java.net.HttpURLConnection; import java.net.URL; import java.time.LocalDate; import java.time.format.DateTimeFormatter; @@ -54,9 +71,16 @@ import java.util.Date; import java.util.List; import java.util.Map; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.image.BufferedImage; +import javax.imageio.ImageIO; +import java.util.Base64; + /** * 预警任务Service业务层处理 * @@ -66,13 +90,19 @@ import java.util.stream.Collectors; @RequiredArgsConstructor @Service @Slf4j +@DubboService public class BusinessAlertServiceImpl implements IBusinessAlertService { private final BusinessAlertMapper baseMapper; + @DubboReference(timeout = 30000) + private RemoteSubmailConfigService remoteSubmailConfigService; @Autowired private BusinessAlertConstructInfoMapper businessAlertConstructInfoMapper; + @Autowired + private BusinessAlertConstructInfoOssMapper businessAlertConstructInfoOssMapper; + @DubboReference(timeout = 30000) RemoteWorkflowService remoteWorkflowService; @@ -82,6 +112,22 @@ public class BusinessAlertServiceImpl implements IBusinessAlertService { @Autowired private ProjectTablePrefixConfig ptPrefix; + @DubboReference + private RemoteUserService remoteUserService; + + @Autowired + FeignDeviceGroup feignDeviceGroup; + + @DubboReference + private final RemoteMessageService remoteMessageService; + + @DubboReference + private RemoteConfigService remoteConfigService; + + @DubboReference(timeout = 30000) + private RemoteNoticeService remoteNoticeService; + + /** * 新增预警任务 * @@ -92,7 +138,7 @@ public class BusinessAlertServiceImpl implements IBusinessAlertService { public BusinessAlert addBusinessAlert(BusinessAlertVo param) { BusinessAlert alert = MapstructUtils.convert(param, BusinessAlert.class); alert.setCreateTime(new Date()); - alert.setJobName(alert.getLabelCn()+ DateUtils.getTime()); +// alert.setJobName(alert.getLabelCn()+ DateUtils.getTime()); //创建案件号 try { incrementalAlertCount(alert); @@ -129,28 +175,90 @@ public class BusinessAlertServiceImpl implements IBusinessAlertService { @Override public void addBusinessAlertList(List alertVoList) { - if(!alertVoList.isEmpty()) { - incrementalCount(alertVoList); - List remoteStartProcessList = new ArrayList<>(); - for (BusinessAlertVo alertVo : alertVoList) { - alertVo.setBusinessType(2); - alertVo.setHandleType(BusinessStatusEnum.WAITING.getStatus()); - BusinessAlert alert = addBusinessAlert(alertVo); - RemoteStartProcess startProcess = new RemoteStartProcess(); - startProcess.setBusinessId(String.valueOf(alert.getId())); - startProcess.setFlowCode("alertChz"); - remoteStartProcessList.add(startProcess); - } + if (ObjectUtil.isEmpty(alertVoList)){ + throw new ServiceException("参数为空!"); + } - int startIndex = 0; // 从第 0 条开始 - int batchSize = 5; // 每批处理 5 条 - boolean flag = BatchProcessorUtil.processBatches(remoteStartProcessList, batchSize, startIndex, batch -> { - //批量新增部门区域数据 - remoteWorkflowService.startWorkFlowBatch(batch); - }); + try { + incrementalCount(alertVoList); + } catch (Exception e) { + log.error(e.getMessage(),e); + } + + //用于短信推送 + List> noticeList=new ArrayList<>(); + List remoteStartProcessList = new ArrayList<>(); + for (BusinessAlertVo alertVo : alertVoList) { + Mapmap=new HashMap<>(); + alertVo.setBusinessType(2); + + //构建pixel + JSONObject pixelJson = new JSONObject(); + pixelJson.put("lef_x",alertVo.getLx()); + pixelJson.put("lef_y",alertVo.getLy()); + pixelJson.put("right_x",alertVo.getRx()); + pixelJson.put("right_y",alertVo.getRy()); + alertVo.setPixelCoordinate(pixelJson.toJSONString()); + + BusinessAlert alert = addBusinessAlert(alertVo); + RemoteStartProcess startProcess = new RemoteStartProcess(); + startProcess.setBusinessId(String.valueOf(alert.getId())); + + String flowCode = remoteWorkflowService.getFlowCode(alertVo.getLabelEn()); + log.info("flowCode:{}",flowCode); + + startProcess.setFlowCode(flowCode); + map.put("deptId",alert.getDeptId()); + map.put("deptName",alert.getDeptName()); + map.put("labelCn",alert.getLabelCn()); + map.put("labelEn",alert.getLabelEn()); + map.put("jobName",alert.getJobName()); + noticeList.add(map); + remoteStartProcessList.add(startProcess); + + //推送消息-基于部门-找用户 发送json格式 + ArrayList deptIds = new ArrayList<>(); + deptIds.add(Long.parseLong(alert.getDeptId())); + List remoteUserVos = remoteUserService.selectUsersByDeptIds(deptIds); + List userIds = remoteUserVos.stream().map(RemoteUserVo::getUserId).collect(Collectors.toList()); + + String imagePreviewUrl = MinioUntil.getObjectUrlOne(MinIOConstants.BUCKET_DKCY, alertVo.getImages(), 3600).toString(); + JSONObject jsonObject = setupBusinessAlertSSEObj( alert, imagePreviewUrl); + remoteMessageService.publishMessage(userIds, jsonObject.toString() ); + System.out.println("已发送:"+ "预警内容:"+ jsonObject.toString()); } + int startIndex = 0; // 从第 0 条开始 + int batchSize = 5; // 每批处理 5 条 + boolean flag = BatchProcessorUtil.processBatches(remoteStartProcessList, batchSize, startIndex, batch -> { + //批量新增部门区域数据 + remoteWorkflowService.startWorkFlowBatch(batch); + }); + remoteSubmailConfigService.remoteSend("smsMultixsend",noticeList); + + //推送消息-基于部门-找用户-批量 +// List deptStrIds = alertVoList.stream().map(BusinessAlertVo::getDeptId).distinct().collect(Collectors.toList()); +// List deptIds = deptStrIds.stream().map(Long::parseLong).collect(Collectors.toList()); +// List remoteUserVos = remoteUserService.selectUsersByDeptIds(deptIds); +// List userIds = remoteUserVos.stream().map(RemoteUserVo::getUserId).collect(Collectors.toList()); +// +// remoteMessageService.publishMessage(userIds, "预警"); + + } + + /** 预警信息转jsonObj给前台提示预警 **/ + private static JSONObject setupBusinessAlertSSEObj( BusinessAlert alert, String imagePreviewUrl) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("deptId", alert.getDeptId()); + jsonObject.put("deptName", alert.getDeptName()); + jsonObject.put("images", imagePreviewUrl); + jsonObject.put("labelCn", alert.getLabelCn()); + jsonObject.put("lat", alert.getLat()); + jsonObject.put("lng", alert.getLng()); + jsonObject.put("createTime", ObjectUtil.isNotEmpty(alert.getCreateTime()) ? alert.getCreateTime() : new Date()); + jsonObject.put("jobName", alert.getJobName()); + return jsonObject; } /** @@ -165,9 +273,11 @@ public class BusinessAlertServiceImpl implements IBusinessAlertService { alert.setCreateTime(new Date()); alert.setHandleType(BusinessStatusEnum.VERIFY.getStatus()); RemoteBusinessAlertConstructInfo remoteAlertConstructInfo = alert.getRemoteAlertConstructInfo(); - BusinessAlertConstructInfoVo alertConstructInfoVo = new BusinessAlertConstructInfoVo(); - BeanUtils.copyProperties(alert.getRemoteAlertConstructInfo(), alertConstructInfoVo); - businessAlert.setAlertConstructInfoVo(alertConstructInfoVo); + if(BeanUtil.isNotEmpty(remoteAlertConstructInfo)){ + BusinessAlertConstructInfoVo alertConstructInfoVo = new BusinessAlertConstructInfoVo(); + BeanUtils.copyProperties(remoteAlertConstructInfo, alertConstructInfoVo); + businessAlert.setAlertConstructInfoVo(alertConstructInfoVo); + } BeanUtils.copyProperties(alert, businessAlert); if(!StrUtil.equals("default", activeProfile)){ businessAlert.setBusinessType(2); @@ -181,6 +291,22 @@ public class BusinessAlertServiceImpl implements IBusinessAlertService { }).toList(); boolean b = this.baseMapper.insertBatch(businessAlerts); + + //推送消息-基于部门-找用户 发送json格式 --此时没有deptId,无效预警 + for (BusinessAlert alert : businessAlerts) { + if(ObjectUtil.isEmpty(alert.getDeptId())){ + continue; + } + ArrayList deptIds = new ArrayList<>(); + deptIds.add(Long.parseLong(alert.getDeptId())); + List remoteUserVos = remoteUserService.selectUsersByDeptIds(deptIds); + List userIds = remoteUserVos.stream().map(RemoteUserVo::getUserId).collect(Collectors.toList()); + + String imagePreviewUrl = MinioUntil.getObjectUrlOne(MinIOConstants.BUCKET_DKCY, alert.getImages(), 3600).toString(); + JSONObject jsonObject = setupBusinessAlertSSEObj(alert, imagePreviewUrl); + remoteMessageService.publishMessage(userIds, jsonObject.toString() ); + } + /*List alertConstructInfoList = businessAlerts.stream().map(alert -> { BusinessAlertConstructInfoVo alertConstructInfoVo = alert.getAlertConstructInfoVo(); BusinessAlertConstructInfo businessAlertConstructInfo = new BusinessAlertConstructInfo(); @@ -190,6 +316,19 @@ public class BusinessAlertServiceImpl implements IBusinessAlertService { }).collect(Collectors.toList()); businessAlertConstructInfoMapper.insertBatch(alertConstructInfoList);*/ + //基于系统参数判断是否要自动提交 + boolean submitFlag = remoteConfigService.selectXingluoAutoSubmit(); + if(submitFlag){ + System.out.println("记录内容提交"); + String collect = alertVoList.stream().map(RemoteBusinessAlertVo::getLabelCn).collect(Collectors.joining(",")); + System.out.println(collect); + for (BusinessAlert businessAlert : businessAlerts) { +// this.pushAlert(businessAlert.getAlertId(),); + + } + + } + return b; } @@ -271,10 +410,12 @@ public class BusinessAlertServiceImpl implements IBusinessAlertService { QueryWrapper wrapper = buildQueryWrapper(bo); if (ObjectUtil.isEmpty(wrapper)){ - return new TableDataInfo<>(); + return TableDataInfo.build(); } Page page = this.baseMapper.pageBusinessAlert(pageQuery.build(), wrapper, ptPrefix); + //拼接-预警扩展施工信息 + setupConstructInfo(page.getRecords(), page); try {//预警管理查询图片 page.getRecords().forEach(businessAlertVo->{ @@ -306,13 +447,15 @@ public class BusinessAlertServiceImpl implements IBusinessAlertService { QueryWrapper wrapper = buildQueryWrapper(bo); if (ObjectUtil.isEmpty(wrapper)){ - return new TableDataInfo<>(); + return TableDataInfo.build(); } wrapper.in("t.flowStatus", BusinessStatusEnum.CANCEL.getStatus()); Page page = this.baseMapper.pageBusinessAlertCancel(pageQuery.build(), wrapper, ptPrefix); + //拼接-预警扩展施工信息 + setupConstructInfo(page.getRecords(), page); try { page.getRecords().forEach(businessAlertVo->{ if (businessAlertVo.getBusinessType() == 2){ @@ -343,7 +486,7 @@ public class BusinessAlertServiceImpl implements IBusinessAlertService { QueryWrapper wrapper = buildQueryWrapper(bo); if (ObjectUtil.isEmpty(wrapper)){ - return new TableDataInfo<>(); + return TableDataInfo.build(); } wrapper.eq("t.handle_type",BusinessStatusEnum.FINISH.getStatus()); @@ -351,6 +494,9 @@ public class BusinessAlertServiceImpl implements IBusinessAlertService { Page page = this.baseMapper.pageBusinessAlertFinish(pageQuery.build(), wrapper, ptPrefix); + //拼接-预警扩展施工信息 + setupConstructInfo(page.getRecords(), page); + try { page.getRecords().forEach(businessAlertVo->{ if (businessAlertVo.getBusinessType() == 2){ @@ -380,7 +526,7 @@ public class BusinessAlertServiceImpl implements IBusinessAlertService { QueryWrapper wrapper = buildQueryWrapper(bo); if (ObjectUtil.isEmpty(wrapper)){ - return new TableDataInfo<>(); + return TableDataInfo.build(); } wrapper.eq("t.node_type", 1); @@ -402,6 +548,9 @@ public class BusinessAlertServiceImpl implements IBusinessAlertService { }); } + //拼接-预警扩展施工信息 + setupConstructInfo(records, page); + try { page.getRecords().forEach(businessAlertVo->{ if (businessAlertVo.getBusinessType() == 2){ @@ -425,7 +574,7 @@ public class BusinessAlertServiceImpl implements IBusinessAlertService { QueryWrapper wrapper = buildQueryWrapper(bo); if (ObjectUtil.isEmpty(wrapper)){ - return new TableDataInfo<>(); + return TableDataInfo.build(); } String tableWorkflow = ptPrefix.getTableWorkflow(); // eg: "dk_workflow" @@ -436,6 +585,9 @@ public class BusinessAlertServiceImpl implements IBusinessAlertService { Page page = this.baseMapper.pageBusinessAlertHandle(pageQuery.build(), wrapper, ptPrefix); + //拼接-预警扩展施工信息 + setupConstructInfo(page.getRecords(), page); + try { page.getRecords().forEach(businessAlertVo->{ businessAlertVo.setHandleType(null); @@ -455,6 +607,35 @@ public class BusinessAlertServiceImpl implements IBusinessAlertService { return TableDataInfo.build(page); } + private void setupConstructInfo(List records, Page page) { + List alertIds = records.stream().map(BusinessAlert::getId).collect(Collectors.toList()); + if(alertIds.isEmpty()){ + return; + } + LambdaQueryWrapper qw = new LambdaQueryWrapper(); + qw.in(BusinessAlertConstructInfo::getBusinessAlertId, alertIds); + List constructInfoVoList = businessAlertConstructInfoMapper.selectVoList(qw,BusinessAlertConstructInfoVo.class); + List constructInfoIds = constructInfoVoList.stream().map(BusinessAlertConstructInfoVo::getId).collect(Collectors.toList()); + + List alertConstructInfoOssList = new ArrayList<>(); + if(!constructInfoIds.isEmpty()){ + LambdaQueryWrapper alertConstructOssQw = new LambdaQueryWrapper<>(); + alertConstructOssQw.in(BusinessAlertConstructInfoOss::getAlertConstructInfoId,constructInfoIds); + alertConstructInfoOssList = businessAlertConstructInfoOssMapper.selectVoList(alertConstructOssQw, BusinessAlertConstructInfoOss.class); + } + + for (BusinessAlert record : page.getRecords()) { + BusinessAlertConstructInfoVo businessAlertConstructInfoVo = constructInfoVoList.stream().filter(item -> item.getBusinessAlertId().equals(record.getId())).findFirst().orElse(null); + if(ObjectUtil.isNotNull(businessAlertConstructInfoVo)){ + List constructInfoOssList = alertConstructInfoOssList.stream().filter(item -> item.getAlertConstructInfoId().equals(businessAlertConstructInfoVo.getId())).collect(Collectors.toList()); + businessAlertConstructInfoVo.setAlertConstructInfoOssList(constructInfoOssList); + } + record.setAlertConstructInfoVo(businessAlertConstructInfoVo); + + } + } + + /** * 构建wrapper @@ -532,7 +713,7 @@ public class BusinessAlertServiceImpl implements IBusinessAlertService { } catch (Exception e) { e.printStackTrace(); } - return null; + return TableDataInfo.build(); } @@ -759,6 +940,180 @@ public class BusinessAlertServiceImpl implements IBusinessAlertService { return TableDataInfo.build(businessAlertVos); } + @Override + public void exportAlert(BusinessAlertBo bo, HttpServletResponse response) throws IOException { + + Map resultMap = new HashMap<>(); + + if (ObjectUtil.hasEmpty(bo.getStartTime(),bo.getEndTime())) { + bo.setStartTime(DateUtils.getDate()); + bo.setEndTime(DateUtils.getDate()); + } + + //获取所有的用户信息 + List remoteUserVos = remoteUserService.selectUserByUserIds(List.of()); + + Map> userIdMap = remoteUserVos.stream().collect(Collectors.groupingBy(RemoteUserVo::getUserId)); + + QueryWrapper wrapper = buildQueryWrapper(bo); + + if (ObjectUtil.isEmpty(wrapper)){ + throw new RuntimeException("没有可查看的预警数据!"); + } + + wrapper.eq("t.business_type",1); + + //根据前端查询条件查询 + List alertList = this.baseMapper.exportAlert(wrapper,ptPrefix); + alertList = alertList.stream().filter(p-> !p.getHandleType().equalsIgnoreCase("cancel")).toList(); + + long todoCount = alertList.stream().filter(p -> p.getHandleType().equalsIgnoreCase("waiting")).count(); + long finishCount = alertList.stream().filter(p -> p.getHandleType().equalsIgnoreCase("finish")).count(); + + //构建预警数量 + resultMap.put("total",alertList.size()); + resultMap.put("todo",todoCount); + resultMap.put("finish",finishCount); + + //构建预警时间 + resultMap.put("startTime",bo.getStartTime()); + resultMap.put("endTime",bo.getEndTime()); + + long startMillis = System.currentTimeMillis(); + + alertList.parallelStream().forEach(businessAlert->{ + try { + + if (ObjectUtil.isNotEmpty(businessAlert.getAssignUserId()) && ObjectUtil.isNotEmpty(userIdMap.get(Long.valueOf(businessAlert.getAssignUserId())))){ + businessAlert.setAssignUserName(userIdMap.get(Long.valueOf(businessAlert.getAssignUserId())).get(0).getNickName()); + } + + businessAlert.setHandleType(businessAlert.getHandleType().equalsIgnoreCase("waiting")?"未处理":businessAlert.getHandleType().equalsIgnoreCase("finish")?"已完结":businessAlert.getHandleType().equalsIgnoreCase("cancel")?"已忽略":"待验证"); + + if (businessAlert.getBusinessType() == 1){ + businessAlert.setImages(MinioUntil.getObjectUrlOne(MinIOConstants.BUCKET_ALERT, businessAlert.getImages(), 3600).toString()); + businessAlert.setMaxImages(MinioUntil.getObjectUrlOne(MinIOConstants.BUCKET_ALERT, businessAlert.getMaxImages(), 3600).toString()); + businessAlert.setMaxMateSourceImgUrl(MinioUntil.getObjectUrlOne(MinIOConstants.BUCKET_ALERT, businessAlert.getMaxMateSourceImgUrl(), 3600).toString()); + businessAlert.setMateSourceImgUrl(MinioUntil.getObjectUrlOne(MinIOConstants.BUCKET_ALERT, businessAlert.getMateSourceImgUrl(), 3600).toString()); + }else { + businessAlert.setImages(MinioUntil.getObjectUrlOne(MinIOConstants.BUCKET_ALERT, businessAlert.getImages(), 3600).toString()); + } + + //获取指南针 +// Double gimbalYawDegree = feignDeviceGroup.getGimbalYawDegree(businessAlert.getTaskImageId()); +// if (ObjectUtil.isNotEmpty(gimbalYawDegree) && gimbalYawDegree != -1.0){ +// if (gimbalYawDegree < 0){ +// gimbalYawDegree = gimbalYawDegree - 180; +// }else { +// gimbalYawDegree = 180 - gimbalYawDegree; +// } +// +// log.info("旋转角度${}",gimbalYawDegree); +// +// String rotatedAndOverlayImage = ImageRotator.rotateAndOverlayImage(null, null, gimbalYawDegree); +// businessAlert.setIcon(rotatedAndOverlayImage); +// } + + } catch (Exception e) { + log.error(e.getMessage(),e); + } + }); + + long endMillis = System.currentTimeMillis(); + + + System.out.println("消耗时长:" + (endMillis-startMillis)); + resultMap.put("alertList",alertList); + + + if (bo.getExportType().equalsIgnoreCase("world")){ + //生成word + FreemarkerUtil.renderTplFileToWord("预警导出.docx","alert.ftl",resultMap,response); + } else if (bo.getExportType().equalsIgnoreCase("pdf")) { + try { + HtmlConvertPdfHelper.renderTplFileToPDF("预警导出.pdf","pdfAlert.ftl",resultMap,response); + } catch (Exception e) { + log.error(e.getMessage(),e); + } + } + } + + @Override + public void pushAlert(Long alertId, String deptId, String deptName) { + BusinessAlert businessAlert= this.getBusinessAlert(alertId); + if(!ObjectUtil.hasEmpty(deptId,deptName)){ + businessAlert.setDeptName(deptName); + businessAlert.setDeptId(deptId); + } + businessAlert.setCreateTime(new Date()); + //businessAlert.setJobName(deptName + businessAlert.getLabelCn() + DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",businessAlert.getCreateTime())); + this.updateBusinessAlert(businessAlert); + RemoteStartProcess startProcess = new RemoteStartProcess(); + startProcess.setBusinessId(String.valueOf(businessAlert.getId())); + startProcess.setFlowCode("alertChz"); + remoteWorkflowService.startWorkFlowBatch(List.of(startProcess)); + RemoteNoticeBo remoteNoticeBo = new RemoteNoticeBo(); + remoteNoticeBo.setNoticeTitle(businessAlert.getDeptName()+"产生预警,预警类型["+businessAlert.getLabelCn()+"],请立即查看"); + remoteNoticeBo.setNoticeType("3"); + remoteNoticeBo.setNoticeContent(businessAlert.getDeptName()+"产生预警,预警类型["+businessAlert.getLabelCn()+"],请立即查看"); + remoteNoticeBo.setStatus("0"); + remoteNoticeBo.setIsRead(0); + remoteNoticeBo.setCreateBy(1L); + remoteNoticeBo.setCreateDept(1L); + remoteNoticeBo.setCreateTime(businessAlert.getCreateTime()); + if (businessAlert.getBusinessType() == 2){ + businessAlert.setImages(MinioUntil.getObjectUrlOne(MinIOConstants.BUCKET_DKCY, businessAlert.getImages(), 3600).toString()); + } + remoteNoticeBo.setDeviceSn(businessAlert.getDeviceSn()); + businessAlert.setDeviceSn(businessAlert.getDeviceSn()); + remoteNoticeBo.setParam(JSON.toJSONString(businessAlert)); + remoteNoticeService.saveNotice(remoteNoticeBo); + remoteSubmailConfigService.remoteCmdSend("smsMultixsend", JSON.toJSONString(businessAlert)); + } + + + // 压缩图片方法 + private static BufferedImage compressImage(BufferedImage originalImage, int targetWidth, int targetHeight) { + Image resizedImage = originalImage.getScaledInstance(targetWidth, targetHeight, Image.SCALE_SMOOTH); + BufferedImage bufferedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB); + Graphics2D g = bufferedImage.createGraphics(); + g.drawImage(resizedImage, 0, 0, null); + g.dispose(); + return bufferedImage; + } + + // 下载图片并转换为Base64 + public static String imageToBase64(String imageUrl) throws Exception { + int targetWidth = 800; // 你可以调整这个值来控制图片压缩的程度 + int targetHeight = 600; + + // 创建URL对象 + URL url = new URL(imageUrl); + // 打开连接 + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + + // 获取输入流 + InputStream inputStream = connection.getInputStream(); + + // 读取图片 + BufferedImage originalImage = ImageIO.read(inputStream); + + // 压缩图片 + BufferedImage compressedImage = compressImage(originalImage, targetWidth, targetHeight); + + // 将压缩后的图片转换为字节数组 + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ImageIO.write(compressedImage, "jpg", byteArrayOutputStream); // 将图片写为JPEG格式 + byte[] imageBytes = byteArrayOutputStream.toByteArray(); + + // 将字节数组编码为Base64 + String base64Encoded = Base64.getEncoder().encodeToString(imageBytes); + + return base64Encoded; + } + + @Override public Boolean deleteAlert(List alertIdList) { if (ObjectUtil.isEmpty(alertIdList)) { @@ -768,8 +1123,21 @@ public class BusinessAlertServiceImpl implements IBusinessAlertService { LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>(); wrapper.eq(BusinessAlert::getHandleType,BusinessStatusEnum.VERIFY.getStatus()); wrapper.in(BusinessAlert::getId, alertIdList); + List businessAlerts = this.baseMapper.selectList(wrapper); +// 删除文件 - 仅处理ai识别文件删除 + for (BusinessAlert businessAlert : businessAlerts) { + if(businessAlert.getBusinessType().equals(2)){ + try { + MinioUtil.deleteFile(businessAlert.getImages(), MinIOConstants.BUCKET_DKCY); + } catch (Exception e) { + log.error(e.getMessage(),e); +// throw new RuntimeException(e); + } + } + } - return this.baseMapper.delete(wrapper) > 0; + boolean b = this.baseMapper.delete(wrapper) > 0; + return b; } @Override @@ -782,6 +1150,7 @@ public class BusinessAlertServiceImpl implements IBusinessAlertService { //更新number this.baseMapper.batchUpdateCaseNumber(alertVoList); + } catch (Exception e) { log.error(e.getMessage(),e); } @@ -873,6 +1242,13 @@ public class BusinessAlertServiceImpl implements IBusinessAlertService { List businessAlerts = this.baseMapper.listTodoAlert(wrapper, ptPrefix); BusinessAlert businessAlert = businessAlerts.stream().filter(p -> p.getId().equals(alertId)).findFirst().get(); + //拼接-预警扩展施工信息 + QueryWrapper qw = new QueryWrapper(); + qw.eq("business_alert_id", businessAlert.getId()); + List constructInfoVoList = businessAlertConstructInfoMapper.selectVoList(qw); + if(!constructInfoVoList.isEmpty()){ + businessAlert.setAlertConstructInfoVo(constructInfoVoList.getFirst()); + } try { if (businessAlert.getBusinessType() == 2){ @@ -902,7 +1278,8 @@ public class BusinessAlertServiceImpl implements IBusinessAlertService { MinioUtil.deleteFile(businessAlert.getImages(), MinIOConstants.BUCKET_DKCY); MinioUtil.deleteFile(businessAlert.getImages(), MinIOConstants.BUCKET_ALERT); } catch (Exception e) { - throw new RuntimeException(e); + log.error(e.getMessage(),e); +// throw new RuntimeException(e); } return this.baseMapper.update(wrapper) > 0; @@ -963,6 +1340,5 @@ public class BusinessAlertServiceImpl implements IBusinessAlertService { public static void main(String[] args) { - System.out.println(getLastSixDays()); } } diff --git a/dk-modules/business/src/main/java/org/dromara/business/service/impl/BusinessAlertStatisticsServiceImpl.java b/dk-modules/business/src/main/java/org/dromara/business/service/impl/BusinessAlertStatisticsServiceImpl.java index 5e4be56..381d878 100644 --- a/dk-modules/business/src/main/java/org/dromara/business/service/impl/BusinessAlertStatisticsServiceImpl.java +++ b/dk-modules/business/src/main/java/org/dromara/business/service/impl/BusinessAlertStatisticsServiceImpl.java @@ -428,6 +428,10 @@ public class BusinessAlertStatisticsServiceImpl implements IBusinessAlertStatist //查询所有的职能岗位 List postVoList = remotePostService.listPost(); postVoList = postVoList.stream().filter(item -> StrUtil.equals("0",item.getStatus())).toList();//剔除禁用规则 + //基于类别编码postCategory过滤返回值:区分南通 / 丰县等部门数据 【postCategory不能为空再过滤数据】 + if(StrUtil.isNotEmpty(businessAlertBo.getPostCategory()) ){ + postVoList = postVoList.stream().filter(item -> StrUtil.equals(businessAlertBo.getPostCategory(), item.getPostCategory())).toList(); + } if (ObjectUtil.isEmpty(postVoList)) { return ListUtil.empty(); @@ -457,6 +461,10 @@ public class BusinessAlertStatisticsServiceImpl implements IBusinessAlertStatist //查询所有的职能岗位 List postVoList = remotePostService.listPost(); postVoList = postVoList.stream().filter(item -> StrUtil.equals("0",item.getStatus())).toList();//剔除禁用规则 + //基于类别编码postCategory过滤返回值:区分南通 / 丰县等部门数据 【postCategory不能为空再过滤数据】 + if(StrUtil.isNotEmpty(businessAlertBo.getPostCategory()) ){ + postVoList = postVoList.stream().filter(item -> StrUtil.equals(businessAlertBo.getPostCategory(), item.getPostCategory())).toList(); + } List result = new ArrayList<>(); @@ -507,6 +515,10 @@ public class BusinessAlertStatisticsServiceImpl implements IBusinessAlertStatist //查询所有的职能岗位 List postVoList = remotePostService.listPost(); postVoList = postVoList.stream().filter(item -> StrUtil.equals("0",item.getStatus())).toList();//剔除禁用规则 + //基于类别编码postCategory过滤返回值:区分南通 / 丰县等部门数据 【postCategory不能为空再过滤数据】 + if(StrUtil.isNotEmpty(businessAlertBo.getPostCategory()) ){ + postVoList = postVoList.stream().filter(item -> StrUtil.equals(businessAlertBo.getPostCategory(), item.getPostCategory())).toList(); + } List result = new ArrayList<>(); if (ObjectUtil.isEmpty(postVoList)) { @@ -547,6 +559,10 @@ public class BusinessAlertStatisticsServiceImpl implements IBusinessAlertStatist //查询所有的职能岗位 List postVoList = remotePostService.listPost(); postVoList = postVoList.stream().filter(item -> StrUtil.equals("0",item.getStatus())).toList();//剔除禁用规则 + //基于类别编码postCategory过滤返回值:区分南通 / 丰县等部门数据 【postCategory不能为空再过滤数据】 + if(StrUtil.isNotEmpty(businessAlertBo.getPostCategory()) ){ + postVoList = postVoList.stream().filter(item -> StrUtil.equals(businessAlertBo.getPostCategory(), item.getPostCategory())).toList(); + } List monthList = getLastSixMonths(); diff --git a/dk-modules/business/src/main/java/org/dromara/business/service/impl/BusinessLayerServiceImpl.java b/dk-modules/business/src/main/java/org/dromara/business/service/impl/BusinessLayerServiceImpl.java new file mode 100644 index 0000000..3f91bb8 --- /dev/null +++ b/dk-modules/business/src/main/java/org/dromara/business/service/impl/BusinessLayerServiceImpl.java @@ -0,0 +1,143 @@ +package org.dromara.business.service.impl; + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.convert.impl.MapConverter; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.dubbo.config.annotation.DubboReference; +import org.dromara.business.domain.BusinessLayer; +import org.dromara.business.domain.bo.BusinessLayerBo; +import org.dromara.business.domain.model.enums.LayerTypeEnum; +import org.dromara.business.domain.vo.BusinessLayerVo; +import org.dromara.business.mapper.BusinessLayerMapper; +import org.dromara.business.service.IBusinessLayerService; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.system.api.RemoteDeptService; +import org.dromara.system.api.domain.vo.RemoteDeptVo; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +import java.util.*; + + +@Slf4j +@RequiredArgsConstructor +@Service +public class BusinessLayerServiceImpl implements IBusinessLayerService { + + private final BusinessLayerMapper baseMapper; + + @DubboReference(timeout = 30000) + RemoteDeptService remoteDeptService; + + @Override + public TableDataInfo queryPageList(BusinessLayerBo bo, PageQuery pageQuery) { + Page result = baseMapper.queryPageList(pageQuery.build(), bo); + + result.getRecords().forEach(businessLayerVo -> { + List deptList = remoteDeptService.listTreeDeptByChild(businessLayerVo.getDeptId()); + LinkedList deptIdList = new LinkedList<>(); + deptList.forEach(deptVo -> { + deptIdList.add(deptVo.getDeptId()); + }); + + List layerVoList = baseMapper.selectInfoByParent(businessLayerVo.getId()); + + businessLayerVo.setChildren(buildTree(layerVoList,businessLayerVo.getId())); + businessLayerVo.setDeptIdList(deptIdList); + }); + + return TableDataInfo.build(result); + } + + + @Override + public Boolean insert(BusinessLayerBo bo) { + BusinessLayer layerVo = Convert.convert( BusinessLayer.class,bo); + + RemoteDeptVo remoteDeptVo = remoteDeptService.selectDeptById(layerVo.getDeptId()); + + layerVo.setDeptName(remoteDeptVo.getDeptName()); + + return baseMapper.insert(layerVo)>0; + } + + @Override + public Boolean update(BusinessLayerBo bo) { + + BusinessLayer businessLayer = baseMapper.selectById(bo.getId()); + + //判断是否修改部门 + if (!businessLayer.getDeptId().equals(bo.getDeptId())) { + RemoteDeptVo remoteDeptVo = remoteDeptService.selectDeptById(bo.getDeptId()); + + bo.setDeptName(remoteDeptVo.getDeptName()); + } + + BeanUtils.copyProperties(bo,businessLayer); + + return baseMapper.updateById(businessLayer)>0; + } + + @Override + public Boolean delete(Long id) { + return baseMapper.deleteById(id)>0; + } + + @Override + public List optionSelect() { + List layerVoList = baseMapper.selectInfoByParent(0L); + + if (ObjectUtil.isEmpty(layerVoList)){ + return List.of(); + } + + return layerVoList.stream().filter(p-> p.getLayerType().equals(LayerTypeEnum.menu.getType())).toList(); + } + + + /** + * 构建树 + * @param allNodes + * @return + */ + public List buildTree(List allNodes, Long parentId) { + // 创建一个Map来存储所有节点,键为ID,值为节点 + Map nodeMap = new HashMap<>(); + for (BusinessLayerVo node : allNodes) { + nodeMap.put(node.getId(), node); + } + + // 用来存储根节点(即 parentId 为传入值的节点) + List rootNodes = new ArrayList<>(); + + // 遍历所有节点,将子节点添加到父节点的 children 列表中 + for (BusinessLayerVo node : allNodes) { + List deptList = remoteDeptService.listTreeDeptByChild(node.getDeptId()); + LinkedList deptIdList = new LinkedList<>(); + deptList.forEach(deptVo -> { + deptIdList.add(deptVo.getDeptId()); + }); + + node.setDeptIdList(deptIdList); + + if (node.getParentId().equals(parentId)) { + rootNodes.add(node); // 当前节点的 parentId 与传入的 parentId 匹配,作为根节点 + } else { + BusinessLayerVo parentNode = nodeMap.get(node.getParentId()); + if (parentNode != null) { + // 确保父节点的 children 列表已初始化 + if (parentNode.getChildren() == null) { + parentNode.setChildren(new ArrayList<>()); + } + parentNode.getChildren().add(node); // 将当前节点添加到父节点的 children 列表中 + } + } + } + + return rootNodes; + } +} diff --git a/dk-modules/business/src/main/java/org/dromara/business/utils/FreemarkerUtil.java b/dk-modules/business/src/main/java/org/dromara/business/utils/FreemarkerUtil.java new file mode 100644 index 0000000..cee4804 --- /dev/null +++ b/dk-modules/business/src/main/java/org/dromara/business/utils/FreemarkerUtil.java @@ -0,0 +1,264 @@ +package org.dromara.business.utils; + + +import cn.hutool.extra.spring.SpringUtil; +import com.spire.doc.Document; +import com.spire.doc.FileFormat; +import freemarker.template.Template; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.core.io.InputStreamSource; +import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; + +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.Map; + +public class FreemarkerUtil { + + + /** + * Freemarker的配置类,模板目录默认 在 resources下的 templates + */ + private static FreeMarkerConfigurer freeMarkerConfigurer = SpringUtil.getBean(FreeMarkerConfigurer.class); + + + /** + * 将模板文件填充数据后转为String + * + * @param templateName ftl模板文件名 + * @param datas 数据集合 + * @return + */ + public static String renderTplFileToStr(String templateName, Map datas) { + + try { + Template template = freeMarkerConfigurer.getConfiguration().getTemplate(templateName, "UTF-8"); + + + StringWriter out = new StringWriter(); + + template.process(datas, out); + + out.flush(); + out.close(); + return out.getBuffer().toString(); + + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + + /** + * 将模板文件填充数据后导出为文件(导出html,word文件都使用此方法) + * + * @param templateName ftl模板文件名 + * @param datas 数据集合 + * @param outFile 导出的文件路径名称 + */ + public static void renderTplFileToLocalFile(String templateName, Map datas, ByteArrayOutputStream fos) { + + Writer out = null; + + OutputStreamWriter oWriter = null; + try { + Template template = freeMarkerConfigurer.getConfiguration().getTemplate(templateName, "UTF-8"); + oWriter = new OutputStreamWriter(fos, "UTF-8"); + // 这个地方对流的编码不可或缺,使用main()单独调用时,应该可以,但是如果是web请求导出时导出后word文档就会打不开,并且包XML文件错误。主要是编码格式不正确,无法解析。 + out = new BufferedWriter(new OutputStreamWriter(fos)); + out = new BufferedWriter(oWriter); + template.process(datas, out); + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + if (oWriter != null) { + oWriter.close(); + } + if (fos != null) { + fos.close(); + } + if (out != null) { + out.close(); + } + } catch (IOException ioException) { + ioException.printStackTrace(); + } + + } + } + + + + /** + * 根据word模板获取输入流 + * + * @param templateName + * @param datas + * @return + * @throws IOException + */ + public static InputStream renderTplFileToWordInputStream(String templateName, Map datas) throws IOException { + Document doc = null; + DataInputStream in = null; + try { + in = renderTplFileToIOFile(templateName, datas); + doc = new Document(); + doc.loadFromStream(in, FileFormat.Auto); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + doc.saveToStream(baos, FileFormat.Docx); + + ByteArrayOutputStream byteArrayOutputStream = ZipStreamUtil.copyStream(baos); + //输出流转为输入流 + InputStreamSource inputStreamSource = new ByteArrayResource(byteArrayOutputStream.toByteArray()); + return inputStreamSource.getInputStream(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (in != null) { + in.close(); + } + if (doc != null) { + doc.close(); + } + } + return null; + + } + + + + + /** + * 将模板文件填充数据后返回文件流 + * + * @param templateName ftl模板文件名 + * @param datas 数据集合 + */ + public static DataInputStream renderTplFileToIOFile(String templateName, Map datas) throws Exception { + ByteArrayInputStream in = null; + Writer out = null; + try { + Template template = freeMarkerConfigurer.getConfiguration().getTemplate(templateName, "UTF-8"); + out = new StringWriter(); + template.process(datas, out); + String out1 = out.toString().replace("&", "&");//替换非法字符 + in = new ByteArrayInputStream(out1.getBytes("UTF-8")); + return new DataInputStream(in); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (out != null) { + out.close(); + } + if (in != null) { + in.close(); + } + } + return null; + } + + + /** + * 根据word模板获取输入流 + * + * @param templateName + * @param datas + * @return + * @throws IOException + */ + public static void renderTplFileToWord(String documentName , String templateName, Map datas, HttpServletResponse response) throws IOException { + response.setContentType("application/x-msdownload;"); + response.setHeader("Content-disposition", "attachment; filename=" + documentName); + Document doc = null; + DataInputStream in = null; + try { + in = renderTplFileToIOFile(templateName, datas); + doc = new Document(); + doc.loadFromStream(in, FileFormat.Auto); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + doc.saveToStream(baos, FileFormat.Docx); + + ByteArrayOutputStream byteArrayOutputStream = ZipStreamUtil.copyStream(baos); + // 将生成的文档写入到响应的输出流中 + response.reset(); // 重置响应 + response.getOutputStream().write(byteArrayOutputStream.toByteArray()); + response.getOutputStream().flush(); + + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (in != null) { + in.close(); + } + if (doc != null) { + doc.close(); + } + } + + + } + + + /** + * 根据word模板获取输入流 + * + * @param templateName + * @param datas + * @return + * @throws IOException + */ + public static void renderTplFileToPDF(String fileName ,String templateName, Map datas,HttpServletResponse response) throws IOException { + response.setCharacterEncoding(StandardCharsets.UTF_8.name()); // 字符集编码 + response.setContentType("application/pdf;"); + response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8")); + response.addHeader("Access-Control-Allow-Origin", "*"); // 实现跨域 + Document doc = null; + DataInputStream in = null; + try { + in = renderTplFileToIOFile(templateName, datas); + doc = new Document(); + doc.loadFromStream(in, FileFormat.Auto); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + doc.saveToStream(baos, FileFormat.PDF); + + // 将生成的文档写入到响应的输出流中 + response.reset(); // 重置响应 + response.getOutputStream().write(baos.toByteArray()); + response.getOutputStream().flush(); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + + public static String encodeImageToBase64(String imageUrl) throws Exception { + URL url = new URL(imageUrl); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + + try (InputStream in = connection.getInputStream(); + ByteArrayOutputStream baos = new ByteArrayOutputStream()) { + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = in.read(buffer)) != -1) { + baos.write(buffer, 0, bytesRead); + } + byte[] imageBytes = baos.toByteArray(); + return Base64.getEncoder().encodeToString(imageBytes); + } + } + + +} diff --git a/dk-modules/business/src/main/java/org/dromara/business/utils/HtmlConvertPdfHelper.java b/dk-modules/business/src/main/java/org/dromara/business/utils/HtmlConvertPdfHelper.java new file mode 100644 index 0000000..9f45e05 --- /dev/null +++ b/dk-modules/business/src/main/java/org/dromara/business/utils/HtmlConvertPdfHelper.java @@ -0,0 +1,101 @@ +package org.dromara.business.utils; + +import cn.hutool.extra.spring.SpringUtil; +import com.itextpdf.text.Document; +import com.itextpdf.text.DocumentException; +import com.itextpdf.text.Font; +import com.itextpdf.text.pdf.BaseFont; +import com.itextpdf.text.pdf.PdfWriter; +import com.itextpdf.tool.xml.XMLWorkerFontProvider; +import com.itextpdf.tool.xml.XMLWorkerHelper; +import freemarker.template.TemplateException; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.ui.freemarker.FreeMarkerTemplateUtils; +import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.net.URLEncoder; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.Map; + +/** + * Html转换Pdf + * + * @author :Mall + * @date :Created in 2022-04-25 + */ +public class HtmlConvertPdfHelper { + + /** + * Freemarker的配置类,模板目录默认 在 resources下的 templates + */ + private static FreeMarkerConfigurer freeMarkerConfigurer = SpringUtil.getBean(FreeMarkerConfigurer.class); + + public static void renderTplFileToPDF(String fileName , String templateName, Map datas, HttpServletResponse response) { + try { + response.setCharacterEncoding(StandardCharsets.UTF_8.name()); // 字符集编码 + response.setContentType("application/pdf;"); + response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8")); + response.addHeader("Access-Control-Allow-Origin", "*"); // 实现跨域 + byte[] bytes = htmlConvertPDF(datas, templateName); + // 将生成的文档写入到响应的输出流中 + response.reset(); // 重置响应 + response.getOutputStream().write(bytes); + response.getOutputStream().flush(); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * freemarker转PDF + * + * @param templateName ftl文件名称,需要在resources/templates目录下 + * @return + * @throws IOException + */ + public static byte[] htmlConvertPDF(Object map,String templateName) throws IOException, TemplateException, DocumentException { + String htmlText = FreeMarkerTemplateUtils.processTemplateIntoString(freeMarkerConfigurer.getConfiguration().getTemplate(templateName), map); + return htmlConvertPDF(htmlText); + } + + /** + * 根据HTML内容转Image + * + * @param htmText HTML文本字符串 + */ + public static byte[] htmlConvertPDF(String htmText) throws DocumentException, IOException { + //最终返回的byte流 + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + //第一步,创建一个 iTextSharp.text.Document对象的实例: + Document document = new Document(); + //第二步,为该Document创建一个Writer实例: + PdfWriter writer = PdfWriter.getInstance(document, byteArrayOutputStream); + //第三步,打开当前Document + document.open(); + XMLWorkerHelper.getInstance().parseXHtml(writer, document, new ByteArrayInputStream(htmText.getBytes()), null, Charset.defaultCharset(), new AsianFontProvider()); + document.close(); + return byteArrayOutputStream.toByteArray(); + } +} + + +/** + * 用于中文显示的Provider + */ +class AsianFontProvider extends XMLWorkerFontProvider { + @Override + public Font getFont(final String fontname, String encoding, float size, int style) { + try { + BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); + return new Font(bfChinese, size, style); + } catch (Exception e) { + } + return super.getFont(fontname, encoding, size, style); + } +} + diff --git a/dk-modules/business/src/main/java/org/dromara/business/utils/ImageRotator.java b/dk-modules/business/src/main/java/org/dromara/business/utils/ImageRotator.java new file mode 100644 index 0000000..c9fb2f2 --- /dev/null +++ b/dk-modules/business/src/main/java/org/dromara/business/utils/ImageRotator.java @@ -0,0 +1,127 @@ + +package org.dromara.business.utils; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.Base64; + + +public class ImageRotator { + + /** + * 旋转图片并叠加到另一个图片上 + * @param sourceImagePath 源图片路径 + * @param targetImagePath 目标图片路径 + * @param angle 旋转角度(顺时针) + * @return 处理后的图片的Base64字符串 + */ + public static String rotateAndOverlayImage(String sourceImagePath, String targetImagePath, double angle) { + try { + + URL resourceUrl = ImageRotator.class.getClassLoader().getResource("templates/1.png"); + URL targetUrl = ImageRotator.class.getClassLoader().getResource("templates/2.png"); + + // 读取源图片和目标图片 + BufferedImage sourceImage = ImageIO.read(new File(resourceUrl.getPath())); + BufferedImage targetImage = ImageIO.read(new File(targetUrl.getPath())); + + // 创建旋转后的图片 + BufferedImage rotatedImage = rotateImage(sourceImage, angle); + + // 创建新的画布,使用目标图片的尺寸 + BufferedImage resultImage = new BufferedImage( + targetImage.getWidth(), + targetImage.getHeight(), + BufferedImage.TYPE_INT_ARGB + ); + + // 创建图形上下文 + Graphics2D g2d = resultImage.createGraphics(); + + // 绘制目标图片 + g2d.drawImage(targetImage, 0, 0, null); + + // 计算旋转图片的位置(居中) + int x = (targetImage.getWidth() - rotatedImage.getWidth()) / 2; + int y = (targetImage.getHeight() - rotatedImage.getHeight()) / 2; + + // 绘制旋转后的图片 + g2d.drawImage(rotatedImage, x, y, null); + + // 释放图形上下文 + g2d.dispose(); + + // 转换为Base64 + return convertToBase64(resultImage); + + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 旋转图片 + * @param image 要旋转的图片 + * @param angle 旋转角度(顺时针) + * @return 旋转后的图片 + */ + private static BufferedImage rotateImage(BufferedImage image, double angle) { + double rads = Math.toRadians(angle); + double sin = Math.abs(Math.sin(rads)); + double cos = Math.abs(Math.cos(rads)); + + int w = image.getWidth(); + int h = image.getHeight(); + + int newWidth = (int) Math.floor(w * cos + h * sin); + int newHeight = (int) Math.floor(h * cos + w * sin); + + BufferedImage rotated = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB); + Graphics2D g2d = rotated.createGraphics(); + + g2d.translate((newWidth - w) / 2, (newHeight - h) / 2); + g2d.rotate(rads, w / 2, h / 2); + g2d.drawImage(image, 0, 0, null); + g2d.dispose(); + + return rotated; + } + + /** + * 将图片转换为Base64字符串 + * @param image 要转换的图片 + * @return Base64字符串 + */ + private static String convertToBase64(BufferedImage image) { + try { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ImageIO.write(image, "PNG", outputStream); + byte[] imageBytes = outputStream.toByteArray(); + return Base64.getEncoder().encodeToString(imageBytes); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + // 使用示例 + public static void main(String[] args) { + String sourceImagePath = "C:\\Users\\Administrator\\Desktop\\1.png"; // 源图片路径 + String targetImagePath = "C:\\Users\\Administrator\\Desktop\\2.png"; // 目标图片路径 + double angle = 45.0; // 旋转角度 + + String base64Result = rotateAndOverlayImage(sourceImagePath, targetImagePath, angle); + if (base64Result != null) { + System.out.println("处理成功,Base64结果:" + base64Result); + } else { + System.out.println("处理失败"); + } + } +} + diff --git a/dk-modules/business/src/main/java/org/dromara/business/utils/ZipStreamUtil.java b/dk-modules/business/src/main/java/org/dromara/business/utils/ZipStreamUtil.java new file mode 100644 index 0000000..65b86b5 --- /dev/null +++ b/dk-modules/business/src/main/java/org/dromara/business/utils/ZipStreamUtil.java @@ -0,0 +1,283 @@ +package org.dromara.business.utils; + +import java.io.*; +import java.net.MalformedURLException; +import java.net.URL; +import java.nio.file.Files; +import java.util.function.BiFunction; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import java.util.zip.ZipOutputStream; + +import static java.util.zip.ZipEntry.STORED; +import static java.util.zip.ZipOutputStream.DEFLATED; + +public class ZipStreamUtil { + + public static void main(String[] args) { +/* String srcPath = "E:\\360极速浏览器下载\\Linksla生产 (1).docx"; + String outPath = "E:\\360极速浏览器下载\\Linksla生产2.docx"; + try (FileInputStream is = new FileInputStream(srcPath)) { + try (FileOutputStream os = new FileOutputStream(outPath)) { + ZipStreamUtil.zipEntryCopyStream(os, is, new BiFunction() { + @Override + public byte[] apply(ZipEntry se, ZipInputStream zis) { + byte[] rt = null; + String name = se.getName(); + if (null == name) return rt; + String line = String.format("ZipEntry(%s, isDirectory=%d, size=%d, compressedSize=%d, time=%d, crc=%d, method=%d, comment=%s)", + se.getName(), (se.isDirectory()) ? 1 : 0, se.getSize(), se.getCompressedSize(), se.getTime(), se.getCrc(), se.getMethod(), se.getComment()); + System.out.println(line); + if (name.endsWith("word/document.xml")) { + try { + byte[] oldBytes = ZipStreamUtil.toByteArray(zis); + String str = (new String(oldBytes)); + String appendString = str.replace("Evaluation Warning: The document was created with Spire.Doc for JAVA.", ""); + //rt = str.getBytes(); + // 为了避免多余的编码转换, 改成下面的代码更好. + try (ByteArrayOutputStream buf = new ByteArrayOutputStream()) { + //ZipStreamUtil.copyStream(buf, zis); + buf.write(appendString.getBytes()); + rt = buf.toByteArray(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + return rt; + } + }); + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("ZipTxtAppendTest done." + outPath);*/ + } + + + /** + * 过滤word 水印 + * + * @param baos + * @return + * @throws IOException + */ + public static ByteArrayOutputStream copyStream(ByteArrayOutputStream baos) throws IOException { + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + + ByteArrayOutputStream baoss = new ByteArrayOutputStream(); + try { + + ZipStreamUtil.zipEntryCopyStream(baoss, bais, new BiFunction() { + @Override + public byte[] apply(ZipEntry se, ZipInputStream zis) { + byte[] rt = null; + String name = se.getName(); + if (null == name) return rt; + String line = String.format("ZipEntry(%s, isDirectory=%d, size=%d, compressedSize=%d, time=%d, crc=%d, method=%d, comment=%s)", + se.getName(), (se.isDirectory()) ? 1 : 0, se.getSize(), se.getCompressedSize(), se.getTime(), se.getCrc(), se.getMethod(), se.getComment()); + System.out.println(line); + if (name.endsWith("word/document.xml")) { + try { + byte[] oldBytes = ZipStreamUtil.toByteArray(zis); + String str = (new String(oldBytes)); + String appendString = str.replace("Evaluation Warning: The document was created with Spire.Doc for JAVA.", ""); + try (ByteArrayOutputStream buf = new ByteArrayOutputStream()) { + buf.write(appendString.getBytes()); + rt = buf.toByteArray(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + return rt; + } + }); + } finally { + bais.close(); + baoss.close(); + } + + return baoss; + } + + + public static byte[] toByteArray(InputStream in) throws IOException { + try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { + copyStream(out, in); + return out.toByteArray(); + } + } + + public static void copyStream(OutputStream os, InputStream is) throws IOException { + copyStream(os, is, 0); + } + public static void copyStream(OutputStream os, InputStream is, int bufsize) throws IOException { + if (bufsize <= 0) bufsize = 4096; + int len; + byte[] bytes = new byte[bufsize]; + while ((len = is.read(bytes)) != -1) { + os.write(bytes, 0, len); + } + } + + + /** + * 基于ZIP项目的复制Zip流. + * + * @param dst The output stream of the destination zip. + * @param src Source zip. + * @param transform 转换处理. 可以为null, 不转换. 该回调函数的原型为`byte[] transform(ZipEntry zipEntry, ZipInputStream zis)`, 当返回值为 null时保留原值, 为非null时用返回值替换当前ZipEntry对应的流数据. + * @return 返回转换次数. + * @throws IOException + */ + public static int zipEntryCopyStreamZip(ZipOutputStream zos, ZipInputStream zis, BiFunction transform) throws IOException { + int rt = 0; + ZipEntry se; + while ((se = zis.getNextEntry()) != null) { + if (null == se) continue; + //String line = String.format("ZipEntry(%s, isDirectory=%d, size=%d, compressedSize=%d, time=%d, crc=%d, method=%d, comment=%s)", + // se.getName(), (se.isDirectory())?1:0, se.getSize(), se.getCompressedSize(), se.getTime(), se.getCrc(), se.getMethod(), se.getComment()); + //System.out.println(line); + byte[] dstBytes = null; + if (null != transform) { + dstBytes = transform.apply(se, zis); + } + // choose by dstBytes. + if (null == dstBytes) { + ZipEntry de = new ZipEntry(se); + de.setCompressedSize(-1); // 重新压缩后, csize 可能不一致, 故需要恢复为默认值. + zos.putNextEntry(de); + copyStream(zos, zis); + zos.closeEntry(); + } else { + ++rt; + //ZipEntry de = new ZipEntry(se); + //de.setCompressedSize(-1); + //de.setCrc(-1); + // == fix IllegalArgumentException. + ZipEntry de = new ZipEntry(se.getName()); + //System.out.println(se.getTime()); + //final long timeNone = 312739200000L; + //if (timeNone!=se.getTime() && null!=se.getLastModifiedTime()) { // 发现会被自动改为当前时间. + if (null != se.getLastModifiedTime()) { + de.setLastModifiedTime(se.getLastModifiedTime()); + } + if (null != se.getLastAccessTime()) { + de.setLastAccessTime(se.getLastAccessTime()); + } + if (null != se.getCreationTime()) { + de.setCreationTime(se.getCreationTime()); + } + de.setSize(dstBytes.length); + //de.setCompressedSize(se.getCompressedSize()); // changed. + //de.setCrc(se.getCrc()); // changed. + int method = se.getMethod(); + if (method != STORED && method != DEFLATED) { + // No setMethod . + } else { + de.setMethod(method); + } + de.setExtra(se.getExtra()); + de.setComment(se.getComment()); + zos.putNextEntry(de); + zos.write(dstBytes); + zos.closeEntry(); + } + } + return rt; + } + + /** + * 基于ZIP项目的复制流. + * + * @param dst The output stream of the destination zip. + * @param src Source zip. + * @param transform 转换处理. 可以为null, 不转换. 该回调函数的原型为`byte[] transform(ZipEntry zipEntry, ZipInputStream zis)`, 当返回值为 null时保留原值, 为非null时用返回值替换当前ZipEntry对应的流数据. + * @return 返回转换次数. + * @throws IOException + */ + public static int zipEntryCopyStream(OutputStream os, InputStream is, BiFunction transform) throws IOException { + try (ZipInputStream zis = new ZipInputStream(is)) { + try (ZipOutputStream zos = new ZipOutputStream(os)) { + return zipEntryCopyStreamZip(zos, zis, transform); + } + } + } + + public static void saveImageToFile(String imageUrl, File destination) throws IOException { + try (InputStream in = new URL(imageUrl).openStream()) { + Files.copy(in, destination.toPath()); + } + } + + public static void addFolderToZip(File sourceFolder, String baseFolderName, ZipOutputStream zos) throws IOException { + for (File file : sourceFolder.listFiles()) { + if (file.isDirectory()) { + addFolderToZip(file, baseFolderName + "/" + file.getName(), zos); + } else { + try (InputStream in = Files.newInputStream(file.toPath())) { + ZipEntry zipEntry = new ZipEntry(baseFolderName + "/" + file.getName()); + zos.putNextEntry(zipEntry); + byte[] buffer = new byte[1024]; + int length; + while ((length = in.read(buffer)) >= 0) { + zos.write(buffer, 0, length); + } + zos.closeEntry(); + } + } + } + } + + public static void deleteDirectory(File directory) { + for (File file : directory.listFiles()) { + if (file.isDirectory()) { + deleteDirectory(file); + } + file.delete(); + } + directory.delete(); + } + + + + // Helper method to add image to zip stream + public static void addImageToZip(String imageUrl, File targetFile, String folderName, ZipOutputStream zos) throws IOException { + if (imageUrl == null || imageUrl.isEmpty()) { + throw new IllegalArgumentException("The image URL cannot be null or empty."); + } + + URL url; + try { + url = new URL(imageUrl); + } catch (MalformedURLException e) { + throw new IOException("Invalid URL format: " + imageUrl, e); + } + + try (InputStream imageStream = url.openStream()) { + // Create zip entry for image + String zipEntryName = folderName + "/" + targetFile.getName(); + ZipEntry zipEntry = new ZipEntry(zipEntryName); + zos.putNextEntry(zipEntry); + + // Write image content to zip stream + byte[] buffer = new byte[8192]; // 8KB buffer for optimal performance + int bytesRead; + while ((bytesRead = imageStream.read(buffer)) != -1) { + zos.write(buffer, 0, bytesRead); + } + + zos.closeEntry(); + } catch (IOException e) { + // Log the error and rethrow the exception for higher-level handling + System.err.println("Error processing image from URL: " + imageUrl); + e.printStackTrace(); + throw e; + } + } + + +} diff --git a/dk-modules/business/src/main/java/org/dromara/business/utils/constants/MinIOConstants.java b/dk-modules/business/src/main/java/org/dromara/business/utils/constants/MinIOConstants.java index 367c04a..53b9c76 100644 --- a/dk-modules/business/src/main/java/org/dromara/business/utils/constants/MinIOConstants.java +++ b/dk-modules/business/src/main/java/org/dromara/business/utils/constants/MinIOConstants.java @@ -17,4 +17,7 @@ public interface MinIOConstants { String BUCKET_ALERT = "alert"; //桶名称 图斑 String BUCKET_PATTERN = "pattern"; + + //南通-丰县Buskcet + String BUCKET_NANTONG = "nantongsitebucket"; } diff --git a/dk-modules/business/src/main/resources/mapper/business/BusinessAlertConstructInfoOssMapper.xml b/dk-modules/business/src/main/resources/mapper/business/BusinessAlertConstructInfoOssMapper.xml new file mode 100644 index 0000000..f05efa0 --- /dev/null +++ b/dk-modules/business/src/main/resources/mapper/business/BusinessAlertConstructInfoOssMapper.xml @@ -0,0 +1,12 @@ + + + + + + + diff --git a/dk-modules/business/src/main/resources/mapper/business/BusinessAlertMapper.xml b/dk-modules/business/src/main/resources/mapper/business/BusinessAlertMapper.xml index dc1ab60..b3be2bf 100644 --- a/dk-modules/business/src/main/resources/mapper/business/BusinessAlertMapper.xml +++ b/dk-modules/business/src/main/resources/mapper/business/BusinessAlertMapper.xml @@ -967,4 +967,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + diff --git a/dk-modules/business/src/main/resources/mapper/business/BusinessLayerMapper.xml b/dk-modules/business/src/main/resources/mapper/business/BusinessLayerMapper.xml new file mode 100644 index 0000000..24ebede --- /dev/null +++ b/dk-modules/business/src/main/resources/mapper/business/BusinessLayerMapper.xml @@ -0,0 +1,76 @@ + + + + + + + + + diff --git a/dk-modules/business/src/main/resources/templates/1.png b/dk-modules/business/src/main/resources/templates/1.png new file mode 100644 index 0000000000000000000000000000000000000000..b6a9e2397eaf1707b3cf3b511b3681058a9f14bf GIT binary patch literal 12919 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 literal 0 HcmV?d00001 diff --git a/dk-modules/business/src/main/resources/templates/2.png b/dk-modules/business/src/main/resources/templates/2.png new file mode 100644 index 0000000000000000000000000000000000000000..c86474c8d2d3f166ac0f6b45ba943968b341dc17 GIT binary patch literal 12424 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 literal 0 HcmV?d00001 diff --git a/dk-modules/business/src/main/resources/templates/alert.ftl b/dk-modules/business/src/main/resources/templates/alert.ftl new file mode 100644 index 0000000..7937b57 --- /dev/null +++ b/dk-modules/business/src/main/resources/templates/alert.ftl @@ -0,0 +1,1943 @@ + + + + + Administrator + yq + 2025-05-26T09:01:00Z + 2025-05-27T03:08:26Z + 5760 + 3 + 116 + 537 + 0 + 0 + 551 + 14 + + + 2052-12.1.0.20784 + eyJoZGlkIjoiM2MxY2NjZmNmMGMxZDJkYTNjN2QyNjc2NjA3ZjE1M2MiLCJ1c2VySWQiOiIxNjgxNjEwNDAzIn0= + C76A426093194B63871CC6838E0A1530_13 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 报表日期 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${startTime?if_exists}~${endTime?if_exists} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 数据情况 + + + + + + + + + + + + + + + + + + + + 预警信息总计: ${total?if_exists}条;未处理:${todo?if_exists}条;已完结:${finish?if_exists}条。 + + + + + + + + + + + + + + + + + + + + 详情如下 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 序号 + + + + + + + + + + + + + + + + + + + + + + + + + + + 预警名称 + + + + + + + + + + + + + + + + + + + + + + + + + + + 所属部门 + + + + + + + + + + + + + + + + + + + + + + + + + + + 预警状态 + + + + + + + + + + + + + + + + + + + + + + + + + + + 经纬度 + + + + + + + + + + + + + + + + + + + + + + + + + + + 预警时间 + + + + + <#if (alertList?size gt 0) && alertList??> + <#list alertList as item> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${item_index + 1} + + + + + + + + + + + + + + + + + + + + + + + + + + + ${item.jobName?if_exists} + + + + + + + + + + + + + + + + + + + + + + + + + + + ${item.deptName?if_exists} + + + + + + + + + + + + + + + + + + + + + + + + + + + ${item.handleType?if_exists} + + + + + + + + + + + + + + + + + + + + + + + + + + + ${item.lng?if_exists} + + + + + + + + + + + + + + + + + + + + + ${item.lat?if_exists} + + + + + + + + + + + + + + + + + + + + + + + + + + + ${item.createTime?datetime?string('yyyy-MM-dd HH:mm:ss')} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <#if alertList?? && (alertList?size gt 0) > + <#list alertList as item> + + + + + + + + + + + + + + + + + + + (${item_index+1}) 预警信息: ${item.jobName?if_exists} + + + <#if item.businessType?if_exists==2> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 影像 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${item.images?if_exists} + + + + + + + + + + + + + + + + + <#elseif item.businessType?if_exists==1> + <#-- + + + + + + + + + + + + + + icon + + + + + + + + + + + + + --> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 前期影像 + + + + + + + + + + + + + + + + + + + + + + + + 后期影像 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <#if item.mateSourceImgUrl??> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <#if item.images??> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <#if item.maxMateSourceImgUrl??> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <#if item.maxImages??> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 处置内容 + + + + + + + + + + + + + + + + + + + + + 识别类型: ${item.labelCn?if_exists} + + + + + + + + + + + + + + + + + + + + + 预警时间: ${item.createTime?datetime?string('yyyy-MM-dd HH:mm:ss')} + + + + + + + + + + + + + + + + + + + + + 指派人员: ${item.assignUserName?if_exists} + + + + + + + + + + + + + + + + + + + + + <#if item.assignDate??> + 指派时间: ${item.assignDate?datetime?string("yyyy-MM-dd HH:mm:ss")} + <#else > + 指派时间: - + + + + + + + + + + + + + <#if item.reason??> + + + + + + + + + + + + + + + + + + + 任务内容 + + + + + + + + + + + + + + + + + + + + + ${item.reason?if_exists} + + + + <#if item.reason??> + + + + + + + + + + + + + + + + + + + +<#-- 现场情况--> + + + + + <#-- + + + + + + + + + + + + + + + +<#– ${item.maxMateSourceImgUrl?if_exists}–> + + + + + + + + + + + +<#– + + + + + + + + + + + + + + + + + –> + --> + <#--换页符--> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PAGE \* MERGEFORMAT + + + + + + 1 + + + + + + 页 共 + + + + + + NUMPAGES \* MERGEFORMAT + + + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dk-modules/business/src/main/resources/templates/pdfAlert.ftl b/dk-modules/business/src/main/resources/templates/pdfAlert.ftl new file mode 100644 index 0000000..34a8e52 --- /dev/null +++ b/dk-modules/business/src/main/resources/templates/pdfAlert.ftl @@ -0,0 +1,125 @@ + + + + Early Warning Record + + + + +

一、报表日期

+

${startTime?if_exists}~${endTime?if_exists}

+

二、数据情况

+

预警信息总计:${total?if_exists}条;未处理:${todo?if_exists}条; 已完结:${finish?if_exists}条。

+

详情如下

+ + + + + + + + + + + + + + + + + + + + + <#if (alertList?size gt 0) && alertList??> + <#list alertList as item> + + + + + + + + + + + +
序号预警名称所属部门预警状态经纬度预警时间
${item_index + 1}${item.jobName?if_exists}${item.deptName?if_exists}${item.handleType?if_exists}${item.lng?if_exists} ${item.lat?if_exists}${item.createTime?datetime?string('yyyy-MM-dd HH:mm:ss')}
+ + +<#if (alertList?size gt 0) && alertList??> + <#list alertList as item> +
+

(${item_index + 1})预警信息:${item.jobName?if_exists}

+ + + + + + + + + + + + + + + + + + + +
前期影像后期影像
前期影像1前期影像2
后期影像1后期影像2
+ + <#if item.assignUserId??> +

处置内容

+ + + + + + + + + + + + + + + +
识别类型:${item.labelCn?if_exists}指派人员: ${item.assignUserName?if_exists}
预警时间: ${item.createTime?datetime?string('yyyy-MM-dd HH:mm:ss')}指派时间: + <#if item.assignDate??> + ${item.assignDate?datetime?string('yyyy-MM-dd HH:mm:ss')} + +
任务内容: ${item.reason?if_exists}
+ + + + + diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/feign/RemoteBusinessAlertFeign.java b/dk-modules/sample/src/main/java/org/dromara/sample/feign/RemoteBusinessAlertFeign.java new file mode 100644 index 0000000..863090d --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/feign/RemoteBusinessAlertFeign.java @@ -0,0 +1,16 @@ +package org.dromara.sample.feign; + +import cn.hutool.json.JSONObject; +import org.dromara.business.api.domain.RemoteBusinessAlertRequest; +import org.dromara.common.core.domain.R; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +@FeignClient(name = "gateway",path = "business") +public interface RemoteBusinessAlertFeign { + + @PostMapping("/saveBusinessAlert") +// public R saveBusinessAlert(@RequestBody RemoteBusinessAlertRequest requestObj); + public R saveBusinessAlert(@RequestBody JSONObject requestObj); +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/feign/RemoteConfigFeign.java b/dk-modules/sample/src/main/java/org/dromara/sample/feign/RemoteConfigFeign.java new file mode 100644 index 0000000..c23cc2a --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/feign/RemoteConfigFeign.java @@ -0,0 +1,18 @@ +package org.dromara.sample.feign; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; + +import java.util.List; + +@FeignClient(name = "gateway",path = "system") +public interface RemoteConfigFeign { + + + @GetMapping("/config/configKeyFeign/{configKey}") + String getConfigKey(@PathVariable String configKey); + + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/feign/RemoteSystemFeign.java b/dk-modules/sample/src/main/java/org/dromara/sample/feign/RemoteSystemFeign.java index 2192f4a..83f5f4e 100644 --- a/dk-modules/sample/src/main/java/org/dromara/sample/feign/RemoteSystemFeign.java +++ b/dk-modules/sample/src/main/java/org/dromara/sample/feign/RemoteSystemFeign.java @@ -3,6 +3,7 @@ package org.dromara.sample.feign; import org.dromara.common.core.domain.R; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -13,4 +14,7 @@ public interface RemoteSystemFeign { @GetMapping("/config/selectStreamType") public List selectStreamType(@RequestParam String deviceSn); + + @GetMapping(value = "/config/configKeyFeign/{configKey}") + public String getConfigKeyFeign(@PathVariable String configKey); } diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/config/XingluoApiConfig.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/config/XingluoApiConfig.java new file mode 100644 index 0000000..76bda87 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/config/XingluoApiConfig.java @@ -0,0 +1,32 @@ +package org.dromara.sample.manage.config; + +import cn.hutool.core.io.IoUtil; +import cn.hutool.core.util.StrUtil; +import io.minio.*; +import io.minio.http.Method; +import lombok.Data; +import lombok.Getter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Component; + +import java.io.InputStream; +import java.util.HashMap; + +@Data +@Component +@ConfigurationProperties(prefix="xingluoapi") +public class XingluoApiConfig { + + @Value("${xingluoapi.engineLogin:http://60.204.247.65:8100/Third/Login}") + private String engineLogin; + @Value("${xingluoapi.engineCallbackUrl:http://121.237.178.63:11100/sample/manage/api/v1/saEngineRecord/some}") + private String engineCallbackUrl; + @Value("${xingluoapi.engineStart:http://60.204.247.65:8100/Third/Engine/Start}") + private String engineStart; + @Value("${xingluoapi.engineStop:http://60.204.247.65:8100/Third/Engine/Stop}") + private String engineStop; + + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/config/XingluoApiEnum.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/config/XingluoApiEnum.java new file mode 100644 index 0000000..b6e37cc --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/config/XingluoApiEnum.java @@ -0,0 +1,82 @@ +package org.dromara.sample.manage.config; + +public enum XingluoApiEnum { +//2022 秸秆焚烧(烟、火、焚后痕迹) fire ---------- + FIRE(2022, "可见光","秸秆焚烧","秸秆燃烧预警","2010_12",2022, 1899717400907046931l,"fire","秸秆燃烧"), +//2023 烟火识别 ------ + FIREWORKS(2022, "可见光","烟火识别","烟火识别预警","2010_13",2023, 1899717400907046931l,"fire","烟火识别"), +//2003 佩戴安全带 ------ A null object appeared + SAFETY_HARNESS(2003, "可见光","是否佩戴安全带","安全带预警","2003_ext",2003, 1899717400907046940l,"SafetyHarness","安全带"), +//2024 安全帽 ------- A null object appeared + SAFETY_HELMET(2004, "可见光","是否佩戴安全帽","安全帽预警","2004_ext",2004, 1899717400907046939l,"SafetyHelmet","安全帽"), +//2034 路面车辆计数 + CARCOUNT(2034, "可见光","路面车辆计数","路面车辆计数","2010_24",2034, 1899717400907046953l,"carCount","路面车辆计数"), +//2015 多类型车辆计数 + CARCOUNTMULTITYPE(2015, "可见光","多类型车辆计数","多类型车辆计数","2010_5",2015, 1899717400907046953l,"carCountMultiType","多类型车辆计数"), +//2016 多类型车辆拥堵聚集 + CARMULTITYPEJAM(2016, "可见光","多类型车辆拥堵聚集","多类型车辆拥堵聚集","2010_6",2016, 1899717400907046955l,"carMultiTypeJam","多类型车辆拥堵聚集"), +//2039 无人机安全帽检测 --------- + SAFETY_HELMET_NEW(2039, "可见光","无人机安全帽检测","安全帽预警","2010_29",2039, 1899717400907046939l,"SafetyHelmet","安全帽"); + + + private final Integer id; + private final String sence; + private final String type; + private final String typeStr; //类型描述 + private final String extraType; + private final Integer senceId; + + private final Long aiLabelId; //ailabel对照数据 + private final String aiType; + private final String aiName; + + XingluoApiEnum(Integer id, String sence, String type, String typeStr, String extraType, Integer senceId, Long aiLabelId,String aiType, String aiName) { + this.id = id; + this.sence = sence; + this.type = type; + this.typeStr = typeStr; + this.extraType = extraType; + this.senceId = senceId; + + this.aiLabelId = aiLabelId; + this.aiType = aiType; + this.aiName = aiName; + } + + + public Integer getId() { + return id; + } + + public String getSence() { + return sence; + } + + public String getType() { + return type; + } + + public String getTypeStr() { + return typeStr; + } + + public String getExtraType() { + return extraType; + } + + public Integer getSenceId() { + return senceId; + } + + public Long getAiLabelId() { + return aiLabelId; + } + + public String getAiType() { + return aiType; + } + + public String getAiName() { + return aiName; + } +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/config/xingluoApiType.json b/dk-modules/sample/src/main/java/org/dromara/sample/manage/config/xingluoApiType.json new file mode 100644 index 0000000..149fc3e --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/config/xingluoApiType.json @@ -0,0 +1,110 @@ +{ + "code": 200, + "message": "操作成功", + "data": [ + { + "id": 2022, + "sence": "可见光", + "type": "秸秆焚烧(烟、火、焚后痕迹)", + "extra_type": "2010_12", + "model": "01", + "user": "xuzhou_ai", + "difficult": 0, + "if_open": 1, + "sence_id": 2022, + "conf": 0.7, + "aiConfig": 0 + }, + { + "id": 2023, + "sence": "可见光", + "type": "烟火识别", + "extra_type": "2010_13", + "model": "01", + "user": "xuzhou_ai", + "difficult": 0, + "if_open": 1, + "sence_id": 2023, + "conf": 0.7, + "aiConfig": 0 + }, + { + "id": 2003, + "sence": "可见光", + "type": "是否佩戴安全绳", + "extra_type": "2003_ext", + "model": "01", + "user": "xuzhou_ai", + "difficult": 0, + "if_open": 1, + "sence_id": 2003, + "conf": 0.7, + "aiConfig": 0 + }, + { + "id": 2004, + "sence": "可见光", + "type": "是否佩戴安全帽", + "extra_type": "2004_ext", + "model": "01", + "user": "xuzhou_ai", + "difficult": 0, + "if_open": 1, + "sence_id": 2004, + "conf": 0.7, + "aiConfig": 1 + }, + { + "id": 2034, + "sence": "可见光", + "type": "路面车辆计数", + "extra_type": "2010_24", + "model": "01", + "user": "xuzhou_ai", + "difficult": 0, + "if_open": 1, + "sence_id": 2034, + "conf": 0.7, + "aiConfig": 0 + }, + { + "id": 2015, + "sence": "可见光", + "type": "多类型车辆计数", + "extra_type": "2010_5", + "model": "01", + "user": "xuzhou_ai", + "difficult": 0, + "if_open": 1, + "sence_id": 2015, + "conf": 0.7, + "aiConfig": 0 + }, + { + "id": 2016, + "sence": "可见光", + "type": "多类型车辆拥堵聚集", + "extra_type": "2010_6", + "model": "01", + "user": "xuzhou_ai", + "difficult": 0, + "if_open": 1, + "sence_id": 2016, + "conf": 0.7, + "aiConfig": 0 + }, + { + "id": 2039, + "sence": "可见光", + "type": "无人机安全帽检测", + "extra_type": "2010_29", + "model": "01", + "user": "xuzhou_ai", + "difficult": 0, + "if_open": 1, + "sence_id": 2039, + "conf": 0.7, + "aiConfig": 0 + } + ] +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/DeviceQrtzController.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/DeviceQrtzController.java index 23689df..1ab879c 100644 --- a/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/DeviceQrtzController.java +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/DeviceQrtzController.java @@ -47,7 +47,7 @@ public class DeviceQrtzController extends BaseController { * */ @SaCheckPermission("devict:qrtz:list") @GetMapping(value = "/page") - public TableDataInfo queryPageDept(@RequestParam(name="pageNum", defaultValue="1") Integer pageNum, + public TableDataInfo queryPageDept(@RequestParam(name="pageNo", defaultValue="1") Integer pageNum, @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, DeviceQrtzDTO deviceQrtzDTO) { Page page = new Page(pageNum,pageSize); return deviceQrtzService.listManageDeviceQrtz(page, deviceQrtzDTO); diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/SampleEngineRecordController.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/SampleEngineRecordController.java index 3bf7485..dc809ab 100644 --- a/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/SampleEngineRecordController.java +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/controller/SampleEngineRecordController.java @@ -1,30 +1,62 @@ package org.dromara.sample.manage.controller; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; import com.alibaba.nacos.common.utils.CollectionUtils; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.dubbo.config.annotation.DubboReference; +import org.dromara.business.api.RemoteBusinessAlertService; +import org.dromara.business.api.domain.vo.RemoteBusinessAlertVo; +import org.dromara.common.core.utils.file.MimeTypeUtils; +import org.dromara.common.oss.core.OssClient; +import org.dromara.common.oss.entity.UploadResult; +import org.dromara.common.oss.factory.OssFactory; import org.dromara.common.sdk.common.HttpResultResponse; +import org.dromara.sample.feign.RemoteSystemFeign; +import org.dromara.sample.manage.config.XingluoApiEnum; +import org.dromara.sample.manage.mapper.ITaskJobMapper; import org.dromara.sample.manage.model.dto.CallBackDTO; +import org.dromara.sample.manage.model.dto.DeviceDTO; import org.dromara.sample.manage.model.dto.EventsDTO; +import org.dromara.sample.manage.model.dto.ObjectsDTO; +import org.dromara.sample.manage.model.entity.TaskJobEntity; import org.dromara.sample.manage.model.entity.WarningRecordEntity; +import org.dromara.sample.manage.service.IDeviceService; import org.dromara.sample.manage.service.ISampleEngineRecordService; import org.dromara.sample.manage.service.ISampleWarningRecordService; +import org.dromara.sample.media.constant.MinIOConstants; +import org.dromara.sample.wayline.mapper.IWaylineJobMapper; +import org.dromara.sample.wayline.model.entity.WaylineJobEntity; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import javax.annotation.Resource; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; /** * @author sean.zhou * @version 0.1 * @date 2021/11/15 */ +//@RequiredArgsConstructor @RestController @Slf4j @RequestMapping("${url.manage.prefix}${url.manage.version}/saEngineRecord") @@ -35,7 +67,21 @@ public class SampleEngineRecordController { private ISampleEngineRecordService sampleEngineRecordService; @Autowired - private ISampleWarningRecordService sampleWarningRecordService; + private IDeviceService deviceService; + @Autowired + private RemoteSystemFeign remoteSystemFeign; + + + /** + * 获取场景算法 + * @param objectMap + * @return + */ + @PostMapping("/extractType") + @Operation(summary = "获取星逻引擎类型。", description = "获取星罗引擎算法") + public HttpResultResponse> extractType(@RequestBody Map objectMap) { + return HttpResultResponse.success(sampleEngineRecordService.extractType(objectMap)); + } /** * 启动星罗引擎。 @@ -55,23 +101,23 @@ public class SampleEngineRecordController { return HttpResultResponse.success(); } +// @Resource +// ITaskJobMapper taskJobMapper; + + /** + * 回调数据 + *{"events":[{"algoId":2022,"eventId":"NMwuELxmSA","extraType":"2010_12","frame":{"height":1080,"width":1920},"objects":[{"attrImage":"","attrName":"","attrText":"","classId":"3399529","trackId":"576g4","x":829,"y":638}],"picUrl":"https://dispatch-base-test.oss-cn-shanghai.aliyuncs.com/ai/report/29847/rsISeqAgsK/BzSdPemeNi/events/NMwuELxmSA.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20250607T102241Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Credential=LTAI5tLSJ1Jd91LeBLkeuQJx%2F20250607%2Fcn-shanghai%2Fs3%2Faws4_request&X-Amz-Signature=d7cf99add75296a285854bbf2bb8a112b80d76a46a7653a350c26ba154c82865"}],"taskId":"rsISeqAgsK"} + * + * @param resObject + */ @PostMapping("/some") @Operation(summary = "存储推流的预警(对外接口)。", description = "存储推流的预警(对外接口)。") - public void some(@RequestBody CallBackDTO callBackVo){ - WarningRecordEntity warningRecord = new WarningRecordEntity(); - List list = new ArrayList<>(); - if (CollectionUtils.isNotEmpty(callBackVo.getEvents())){ - for (EventsDTO eventsVo :callBackVo.getEvents()){ - warningRecord.setTaskId(callBackVo.getTaskId()); - warningRecord.setAlgoId(eventsVo.getAlgoId()); - warningRecord.setEventId(eventsVo.getEventId()); - warningRecord.setExtraType(eventsVo.getExtraType()); - warningRecord.setPicUrl(eventsVo.getPicUrl()); - warningRecord.setTimestamp(eventsVo.getTimestamp()); - list.add(warningRecord); - } - sampleWarningRecordService.saveBatch(list); - System.out.println(callBackVo); - } +// public void some(@RequestBody CallBackDTO callBackVo){ + public void some(@RequestBody JSONObject resObject){ + + Integer insertCount = sampleEngineRecordService.dealAlertData(resObject); } + + + } diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/EngineRecordEntity.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/EngineRecordEntity.java index ebffdb9..92494af 100644 --- a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/EngineRecordEntity.java +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/EngineRecordEntity.java @@ -30,12 +30,23 @@ public class EngineRecordEntity implements Serializable { @TableField(value = "device_sn") private String deviceSn; + /** + * 算法类型 + */ @TableField(value = "extra_type") private String extraType; + + //引擎任务id 格式:qMx86W2tE @TableField(value = "task_id") private String taskId; + //任务批次号 格式: WX20250526918312 + //(是调用其他接口中的关键字, 也就是飞行所关联的业务逻辑单据号) + @TableField(value = "mission_batch") + private String missionBatch; + + @TableField(fill = FieldFill.INSERT) private Date createTime; @@ -45,4 +56,10 @@ public class EngineRecordEntity implements Serializable { @TableField(value = "push_url") private String pushUrl; + @TableField(value = "stop_res_data") + private String stopResData; + + @TableField(value = "stop_res_data_str") + private String stopResDataStr; + } diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/TaskJobEntity.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/TaskJobEntity.java index 6c56af2..c08e7c4 100644 --- a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/TaskJobEntity.java +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/TaskJobEntity.java @@ -30,4 +30,9 @@ public class TaskJobEntity implements Serializable { private String jobId; + private String deviceSn; + + @TableField(fill = FieldFill.INSERT) + private Date createTime; + } diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/WarningRecordEntity.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/WarningRecordEntity.java index 5791d73..3d0577e 100644 --- a/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/WarningRecordEntity.java +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/model/entity/WarningRecordEntity.java @@ -1,14 +1,12 @@ package org.dromara.sample.manage.model.entity; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.*; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; import java.io.Serializable; +import java.util.Date; /** * 设备对象-》用于存储设备对象 iot_device @@ -21,7 +19,6 @@ import java.io.Serializable; @EqualsAndHashCode(callSuper = false) @Accessors(chain = true) public class WarningRecordEntity implements Serializable { - private static final long serialVersionUID = 1L; @TableId(type = IdType.AUTO) private String id; @@ -44,4 +41,14 @@ public class WarningRecordEntity implements Serializable { @TableField(value = "timestamp") private Integer timestamp;//事件时间戳,单位:毫秒") + @TableField(fill = FieldFill.INSERT) + private Date createTime; + + @TableField(value = "track_ids") + private String trackIds; + + + @TableField(value = "remark") + private String remark; + } diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDeviceService.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDeviceService.java index 0c77906..f990a81 100644 --- a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDeviceService.java +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/IDeviceService.java @@ -77,6 +77,8 @@ public interface IDeviceService { */ void spliceDeviceTopo(DeviceDTO device); + String getChildDeviceStreamUrlByDeviceSn(String childDeviceSn); + /** * Query the information of the device according to the sn of the device. * @param sn device sn diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/ISampleEngineRecordService.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/ISampleEngineRecordService.java index fba8e46..b65480d 100644 --- a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/ISampleEngineRecordService.java +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/ISampleEngineRecordService.java @@ -1,9 +1,15 @@ package org.dromara.sample.manage.service; +import cn.hutool.json.JSONObject; + import java.util.Map; public interface ISampleEngineRecordService { Map startEngine(Map objectMap); void closeEngine(Map objectMap); + + Map extractType(Map objectMap); + + Integer dealAlertData(JSONObject resObject); } diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceFlightRecordsServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceFlightRecordsServiceImpl.java index d441791..61caff5 100644 --- a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceFlightRecordsServiceImpl.java +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceFlightRecordsServiceImpl.java @@ -9,9 +9,7 @@ import org.dromara.sample.manage.service.IDeviceFlightRecordsService; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; @Service @@ -19,18 +17,30 @@ public class DeviceFlightRecordsServiceImpl extends ServiceImpl().eq(DeviceFlightRecordsEntity::getDeviceSn,deviceFlightRecords.getDeviceSn())); + DeviceFlightRecordsEntity deviceFlightRecordsEntities = this.baseMapper.selectOne(new LambdaQueryWrapper().eq(DeviceFlightRecordsEntity::getDeviceSn,currentFlightRecord.getDeviceSn())); + //不为空 if (ObjectUtil.isNotEmpty(deviceFlightRecordsEntities)) { - deviceFlightRecordsEntities.setFlyCount(deviceFlightRecordsEntities.getFlyCount() + deviceFlightRecords.getFlyCount()); - deviceFlightRecordsEntities.setFlyAccTime(deviceFlightRecordsEntities.getFlyAccTime() + deviceFlightRecords.getFlyAccTime()); + //飞行总架次大于等于表中数据替换 否则累加 + if (currentFlightRecord.getFlyCount() >= deviceFlightRecordsEntities.getFlyCount()){ + deviceFlightRecordsEntities.setFlyCount(currentFlightRecord.getFlyCount()); + }else { + deviceFlightRecordsEntities.setFlyCount(deviceFlightRecordsEntities.getFlyCount() + currentFlightRecord.getFlyCount()); + } + + //飞行总时长大于等于表中数据替换 否则累加 + if (currentFlightRecord.getFlyAccTime() >= deviceFlightRecordsEntities.getFlyAccTime()){ + deviceFlightRecordsEntities.setFlyAccTime(currentFlightRecord.getFlyAccTime()); + }else { + deviceFlightRecordsEntities.setFlyAccTime(deviceFlightRecordsEntities.getFlyAccTime() + currentFlightRecord.getFlyAccTime()); + } this.updateById(deviceFlightRecordsEntities); }else { - this.save(deviceFlightRecords); + this.save(currentFlightRecord); } } @@ -40,18 +50,28 @@ public class DeviceFlightRecordsServiceImpl extends ServiceImpl deviceFlightRecordsEntities = this.baseMapper.selectList(new LambdaQueryWrapper<>()); - int flyCount = deviceFlightRecordsEntities.stream() - .map(DeviceFlightRecordsEntity::getFlyCount) - .reduce(0, Integer::sum); + int flyCount = Optional.ofNullable(deviceFlightRecordsEntities) + .map(list -> list.stream() + .map(DeviceFlightRecordsEntity::getFlyCount) + .reduce(0, Integer::sum)) + .orElse(0); - int flyAccTime = deviceFlightRecordsEntities.stream() - .map(DeviceFlightRecordsEntity::getFlyAccTime) - .reduce(0, Integer::sum); +// int flyAccTime = deviceFlightRecordsEntities.stream() +// .map(DeviceFlightRecordsEntity::getFlyAccTime) +// .reduce(0, Integer::sum); + int flyAccTime = Optional.ofNullable(deviceFlightRecordsEntities) + .map(list -> list.stream() + .map(DeviceFlightRecordsEntity::getFlyAccTime) + .reduce(0, Integer::sum)) + .orElse(0); + + + int flyAccTimeHour = (int) Math.round(flyAccTime / 3600.0); resultMap.put("flyCount",flyCount); - resultMap.put("flyAccTime",flyAccTime); + resultMap.put("flyAccTime",flyAccTimeHour); return resultMap; } diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceServiceImpl.java index 78f0957..51eb246 100644 --- a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceServiceImpl.java +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/DeviceServiceImpl.java @@ -57,6 +57,7 @@ import org.springframework.util.StringUtils; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -247,6 +248,9 @@ public class DeviceServiceImpl implements IDeviceService { if(proIds == null){ proIds = deviceProService.listDeviceGroup(loginUser.getUserId()); } + if(ObjectUtil.isEmpty(proIds)){ + return new ArrayList(); + } List devicesList = this.getDevicesByParams( DeviceQueryParam.builder() .workspaceId(workspaceId) @@ -289,6 +293,15 @@ public class DeviceServiceImpl implements IDeviceService { subDevice.setPayloadsList(payloadService.getDevicePayloadEntitiesByDeviceSn(gateway.getChildDeviceSn())); } + @Override + public String getChildDeviceStreamUrlByDeviceSn(String childDeviceSn) { + DeviceDTO subDevice = getDevicesByParams(DeviceQueryParam.builder().deviceSn(childDeviceSn).build()).get(0); + String deviceVideoEnum = DeviceVideoEnum.find(subDevice.getDeviceName()).getDevice(); +// String string = new VideoId(subDevice.getDeviceSn() + SLASH + deviceVideoEnum + SLASH + VideoTypeEnum.NORMAL.getType() + DASH + DeviceTypeVideoEnum.ZERO.getVideoType()).toString(); + String childDeviceUrl = subDevice.getDeviceSn() + DASH + deviceVideoEnum; //1581F6Q8X254K00G085K-81-0-0 + return childDeviceUrl; + } + @Override public Optional getDeviceTopoForPilot(String sn) { if (!StringUtils.hasText(sn)) { diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/EngineRecordServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/EngineRecordServiceImpl.java index 50c040b..1f94261 100644 --- a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/EngineRecordServiceImpl.java +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/EngineRecordServiceImpl.java @@ -95,6 +95,7 @@ public class EngineRecordServiceImpl implements IEngineRecordService { JSONObject jsonObj = new JSONObject(); jsonObj.put("username", sanitize("xuzhou_ai")); // sanitize函数见下文 jsonObj.put("password", sanitize(md5)); + //{"code":200,"message":"操作成功","data":{"token":"eyJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE3NDc5NjY2NzksImV4cCI6MTc1MDU1ODY3OSwidWlkIjoiT2tUV0NyWWxZSSIsInRoaXJkIjoxfQ.lkOSgcWES1ViKmeVht6b1AKuw6MbxPxsmGVeuahy4QZfWkv8y8Ac80bkvZMVBQD_-DmcwK3HXOslrWI5_uHDuBRO2phB6BGXzqkb4GKvLsZMGI-Wrc4tHyZ-ojQ67uhWVUgnjFK4OnMsf5U9LxAxe0XJZQWwrm8KAh9Zb0iD4gY"}} String responseBody = PostRequest(jsonObj, "http://60.204.247.65:8100/Third/Login"); JSONObject jsonObject = new JSONObject(responseBody); // 逐层获取 data -> token @@ -107,14 +108,16 @@ public class EngineRecordServiceImpl implements IEngineRecordService { try { URI uri = new URIBuilder("http://60.204.247.65:8100/V2/AI/WX/User/Scene") .build(); + //{"code":200,"message":"操作成功","data":[{"scene":"可见光","id":2}]} sceneResponseBody = GetRequest(uri, token); } catch (URISyntaxException e) { - throw new RuntimeException(e); + log.error("星逻算法-场景查询异常",e); } JSONObject jsonObject1 = new JSONObject(sceneResponseBody); // 逐层获取 data -> token JSONObject data1 = jsonObject.getJSONObject("data"); String scene = data1.getString("scene"); +// String scene = jsonObject1.getJSONArray("data").getJSONObject(0).getString("scene"); //查询场景算法 List extra_type_list = new ArrayList<>(); @@ -125,6 +128,7 @@ public class EngineRecordServiceImpl implements IEngineRecordService { .build(); algorithmResponseBody = GetRequest(uri, token); ObjectMapper mapper = new ObjectMapper(); + //ExtraTypeResponse(code=200, message=操作成功, data=[ExtraType(id=2022, sence=可见光, type=秸秆焚烧(烟、火、焚后痕迹), extra_type=2010_12, model=01, user=xuzhou_ai, difficult=0, if_open=1, sence_id=2022, conf=0.7, aiConfig=0), ExtraType(id=2023, sence=可见光, type=烟火识别, extra_type=2010_13, model=01, user=xuzhou_ai, difficult=0, if_open=1, sence_id=2023, conf=0.7, aiConfig=0), ExtraType(id=2003, sence=可见光, type=是否佩戴安全绳, extra_type=2003_ext, model=01, user=xuzhou_ai, difficult=0, if_open=1, sence_id=2003, conf=0.7, aiConfig=0), ExtraType(id=2004, sence=可见光, type=是否佩戴安全帽, extra_type=2004_ext, model=01, user=xuzhou_ai, difficult=0, if_open=1, sence_id=2004, conf=0.7, aiConfig=1), ExtraType(id=2034, sence=可见光, type=路面车辆计数, extra_type=2010_24, model=01, user=xuzhou_ai, difficult=0, if_open=1, sence_id=2034, conf=0.7, aiConfig=0), ExtraType(id=2015, sence=可见光, type=多类型车辆计数, extra_type=2010_5, model=01, user=xuzhou_ai, difficult=0, if_open=1, sence_id=2015, conf=0.7, aiConfig=0), ExtraType(id=2016, sence=可见光, type=多类型车辆拥堵聚集, extra_type=2010_6, model=01, user=xuzhou_ai, difficult=0, if_open=1, sence_id=2016, conf=0.7, aiConfig=0)]) ExtraTypeResponse response = mapper.readValue(algorithmResponseBody,ExtraTypeResponse.class); List list = response.getData(); for (ExtraType extraType : list) { @@ -132,7 +136,7 @@ public class EngineRecordServiceImpl implements IEngineRecordService { break; } } catch (URISyntaxException | JsonProcessingException e) { - throw new RuntimeException(e); + log.error("星逻算法-算法列表查询失败",e); } JSONObject jsonObj2 = new JSONObject(); @@ -147,7 +151,7 @@ public class EngineRecordServiceImpl implements IEngineRecordService { try { response = mapper1.readValue(responseBody2, EngineResponse.class); } catch (JsonProcessingException e) { - throw new RuntimeException(e); + log.error("星逻算法-引擎启动失败",e); } objectMap.put("task_id",response.getData().getTask_id()); record.setPushUrl(objectMap.get("push_url").toString()); @@ -181,7 +185,7 @@ public class EngineRecordServiceImpl implements IEngineRecordService { if(dataObj != null && dataObj instanceof Integer) { int data = (Integer) dataObj; if (data ==1){ - mapper.delete(new LambdaQueryWrapper().eq(EngineRecordEntity::getDeviceSn, objectMap.get("device_sn"))); + mapper.delete(new LambdaQueryWrapper().eq(EngineRecordEntity::getDeviceSn, objectMap.get("deviceSn"))); }else { throw new RuntimeException("关闭引擎失败!"); } diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/LiveStreamServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/LiveStreamServiceImpl.java index 5bea65e..6cc2434 100644 --- a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/LiveStreamServiceImpl.java +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/LiveStreamServiceImpl.java @@ -1,29 +1,27 @@ package org.dromara.sample.manage.service.impl; -import cn.hutool.core.convert.Convert; +import cn.hutool.json.JSONArray; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; import jakarta.annotation.Resource; -import org.apache.commons.collections.CollectionUtils; -import org.dromara.common.rocketmq.producer.MessageProducerUtil; +import org.apache.dubbo.config.annotation.DubboReference; import org.dromara.common.sdk.cloudapi.device.DeviceDomainEnum; import org.dromara.common.sdk.cloudapi.device.VideoId; import org.dromara.common.sdk.cloudapi.livestream.*; import org.dromara.common.sdk.cloudapi.livestream.api.AbstractLivestreamService; -import org.dromara.common.sdk.cloudapi.wayline.FlighttaskProgress; import org.dromara.common.sdk.common.HttpResultResponse; import org.dromara.common.sdk.common.SDKManager; -import org.dromara.common.sdk.mqtt.CommonTopicRequest; import org.dromara.common.sdk.mqtt.MqttGatewayPublish; import org.dromara.common.sdk.mqtt.services.ServicesReplyData; import org.dromara.common.sdk.mqtt.services.TopicServicesResponse; -import org.dromara.sample.component.mqtt.model.EventsReceiver; import org.dromara.sample.feign.RemoteSystemFeign; import org.dromara.sample.manage.model.dto.*; -import org.dromara.sample.manage.model.entity.DeviceEntity; import org.dromara.sample.manage.model.param.DeviceQueryParam; import org.dromara.sample.manage.service.*; -import org.dromara.sample.wayline.model.dto.WaylineJobDTO; import org.dromara.sample.wayline.service.IWaylineJobService; import org.dromara.sample.wayline.service.IWaylineRedisService; +import org.dromara.system.api.RemoteDictService; +import org.dromara.system.api.domain.vo.RemoteDictDataVo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -70,6 +68,9 @@ public class LiveStreamServiceImpl implements ILiveStreamService { @Resource private RemoteSystemFeign remoteSystemFeign; + @DubboReference + private RemoteDictService remoteDictService; + @Override public List getLiveCapacity(String workspaceId) { @@ -290,6 +291,25 @@ public class LiveStreamServiceImpl implements ILiveStreamService { return agoraUrl.setSn(videoId.getDroneSn()); case RTMP: LivestreamRtmpUrl rtmpUrl = (LivestreamRtmpUrl) url.clone(); + //南通设备指定固定rtmpl路径 功能关闭 + /* List dictDataVoList = remoteDictService.selectDictDataByType("drone_stream_rtmp"); + for (RemoteDictDataVo remoteDictDataVo : dictDataVoList) { + if(JSONUtil.isTypeJSON(remoteDictDataVo.getRemark())){ + JSONArray jsonArr = JSONUtil.parseArray(remoteDictDataVo.getRemark()); + for (Object obj : jsonArr) { + JSONObject entries = new JSONObject(obj); + String droneSnStr = entries.getStr("droneSn"); + String rtmpUrlStr = entries.getStr("rtmpUrl"); + if(videoId.getDroneSn().equals(droneSnStr) ){ + rtmpUrl.setUrl(rtmpUrlStr); + } + } + } + }*/ + +// if(videoId.getDroneSn().equals("7CTXN2T00B07C5") || videoId.getDroneSn().equals("1581F6Q8X24CC00G02JB")){ +// rtmpUrl.setUrl("rtmp://106.13.57.190/live/livesteam/"); +// } return rtmpUrl.setUrl(rtmpUrl.getUrl() + videoId.getDroneSn() + "-" + videoId.getPayloadIndex().toString()); case GB28181: String random = String.valueOf(Math.abs(videoId.getDroneSn().hashCode()) % 1000); diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/SampleEngineRecordServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/SampleEngineRecordServiceImpl.java index 47b08fe..69d3850 100644 --- a/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/SampleEngineRecordServiceImpl.java +++ b/dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/SampleEngineRecordServiceImpl.java @@ -1,12 +1,19 @@ package org.dromara.sample.manage.service.impl; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.io.FileUtil; import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.alibaba.nacos.common.utils.CollectionUtils; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import io.seata.common.util.StringUtils; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.dubbo.config.annotation.DubboReference; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; @@ -15,48 +22,96 @@ import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; +import org.dromara.business.api.domain.RemoteBusinessAlertRequest; +import org.dromara.business.api.domain.vo.RemoteBusinessAlertVo; +import org.dromara.common.core.utils.file.MimeTypeUtils; +import org.dromara.common.oss.core.OssClient; +import org.dromara.common.oss.entity.UploadResult; +import org.dromara.common.oss.factory.OssFactory; import org.dromara.sample.common.util.Md5Utils; +import org.dromara.sample.feign.RemoteBusinessAlertFeign; +import org.dromara.sample.feign.RemoteConfigFeign; +import org.dromara.sample.feign.RemoteSystemFeign; +import org.dromara.sample.manage.config.XingluoApiConfig; +import org.dromara.sample.manage.config.XingluoApiEnum; import org.dromara.sample.manage.mapper.ISampleEngineRecordMapper; import org.dromara.sample.manage.mapper.ITaskJobMapper; +import org.dromara.sample.manage.mapper.SampleWarningRecordMapper; import org.dromara.sample.manage.model.dto.*; import org.dromara.sample.manage.model.entity.EngineRecordEntity; import org.dromara.sample.manage.model.entity.TaskJobEntity; +import org.dromara.sample.manage.model.entity.WarningRecordEntity; +import org.dromara.sample.manage.service.IDeviceService; import org.dromara.sample.manage.service.ISampleEngineRecordService; -import org.dromara.system.api.RemoteConfigService; +import org.dromara.sample.media.constant.MinIOConstants; +import org.dromara.sample.wayline.mapper.IWaylineJobMapper; +import org.dromara.sample.wayline.model.entity.WaylineJobEntity; import org.json.JSONArray; import org.json.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import javax.annotation.Resource; +import jakarta.annotation.Resource; +import java.io.IOException; +import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLConnection; import java.util.*; +import java.util.stream.Collectors; import static org.apache.commons.compress.utils.ArchiveUtils.sanitize; +@RequiredArgsConstructor @Service @Slf4j @Transactional public class SampleEngineRecordServiceImpl implements ISampleEngineRecordService { @Resource - ISampleEngineRecordMapper mapper; + ISampleEngineRecordMapper engineRecordMapper; @Resource ITaskJobMapper taskJobMapper; - @DubboReference - private RemoteConfigService remoteConfigService; + @Resource + SampleWarningRecordMapper sampleWarningRecordMapper; + + @Autowired + private XingluoApiConfig xingluoApiConfig; + + @Autowired + private IDeviceService deviceService; + +// @Autowired +// private ISampleWarningRecordService sampleWarningRecordService; + +// @Autowired + private final IWaylineJobMapper waylineJobMapper; + + @Resource + private RemoteConfigFeign remoteConfigFeign; + + @Resource + private RemoteSystemFeign remoteSystemFeign; + + + @Resource + private RemoteBusinessAlertFeign remoteBusinessAlertFeign; + + + @Override - public Map startEngine(Map objectMap){ + public Map extractType(Map objectMap) { EngineRecordEntity record = new EngineRecordEntity(); - String ip = remoteConfigService.selectStreamIp(); //获取token //设置请求Header和Body(如JSON) String md5 = Md5Utils.hash("xuzhou_ai"); JSONObject jsonObj = new JSONObject(); jsonObj.put("username", sanitize("xuzhou_ai")); // sanitize函数见下文 jsonObj.put("password", sanitize(md5)); + //{"code":200,"message":"操作成功","data":{"token":"eyJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE3NDc5NjY2NzksImV4cCI6MTc1MDU1ODY3OSwidWlkIjoiT2tUV0NyWWxZSSIsInRoaXJkIjoxfQ.lkOSgcWES1ViKmeVht6b1AKuw6MbxPxsmGVeuahy4QZfWkv8y8Ac80bkvZMVBQD_-DmcwK3HXOslrWI5_uHDuBRO2phB6BGXzqkb4GKvLsZMGI-Wrc4tHyZ-ojQ67uhWVUgnjFK4OnMsf5U9LxAxe0XJZQWwrm8KAh9Zb0iD4gY"}} String responseBody = PostRequest(jsonObj, "http://60.204.247.65:8100/Third/Login",""); JSONObject jsonObject = new JSONObject(responseBody); // 逐层获取 data -> token @@ -66,87 +121,151 @@ public class SampleEngineRecordServiceImpl implements ISampleEngineRecordService String algorithmResponseBody = null; //查询用户开通的场景 if (StringUtils.isNotEmpty(token)){ -// try { -// URI uri = new URIBuilder("http://60.204.247.65:8100/V2/AI/WX/User/Scene") -// .build(); -// sceneResponseBody = GetRequest(uri, token); -// } catch (URISyntaxException e) { -// throw new RuntimeException(e); -// } -// EngineTypeResponse engineTypeResponse = null; -// try { -// ObjectMapper mapper = new ObjectMapper(); -// engineTypeResponse = mapper.readValue(sceneResponseBody, EngineTypeResponse.class); -// } catch (JsonProcessingException e) { -// throw new RuntimeException(e); -// } -//// JSONObject jsonObject1 = new JSONObject(sceneResponseBody); -// // 逐层获取 data -> token -//// JSONObject data1 = jsonObject1.getJSONObject("data"); -// String scene = engineTypeResponse.getData().getScene(); -// -// //查询场景算法 -// List extra_type_list = new ArrayList<>(); -// try { -// URI uri = new URIBuilder("http://60.204.247.65:8100/V2/AI/WX/User/ExtraType/Get") -// .addParameter("scene",scene) -// .addParameter("if_open","1") -// .build(); -// algorithmResponseBody = GetRequest(uri, token); -// ObjectMapper mapper = new ObjectMapper(); -// ExtraTypeResponse response = mapper.readValue(algorithmResponseBody,ExtraTypeResponse.class); -// List list = response.getData(); -// for (ExtraType extraType : list) { -// extra_type_list.add(extraType.getExtra_type()); -// break; -// } -// } catch (URISyntaxException | JsonProcessingException e) { -// throw new RuntimeException(e); -// } + try { + URI uri = new URIBuilder("http://60.204.247.65:8100/V2/AI/WX/User/Scene") + .build(); + //{"code":200,"message":"操作成功","data":[{"scene":"可见光","id":2}]} + sceneResponseBody = GetRequest(uri, token); + } catch (URISyntaxException e) { + log.error("星逻算法-场景查询异常",e); + } + JSONObject jsonObject1 = new JSONObject(sceneResponseBody); + // 逐层获取 data -> token + JSONObject data1 = jsonObject.getJSONObject("data"); +// String scene = data1.getString("scene"); +// String scene = jsonObject1.getJSONArray("data").getJSONObject(0).getString("scene"); + + //查询场景算法 + List extra_type_list = new ArrayList<>(); + try { + URI uri = new URIBuilder("http://60.204.247.65:8100/V2/AI/WX/User/ExtraType/Get") + .addParameter("scene","可见光") + .addParameter("if_open","1") + .build(); + algorithmResponseBody = GetRequest(uri, token); + ObjectMapper mapper = new ObjectMapper(); + //ExtraTypeResponse(code=200, message=操作成功, data=[ExtraType(id=2022, sence=可见光, type=秸秆焚烧(烟、火、焚后痕迹), extra_type=2010_12, model=01, user=xuzhou_ai, difficult=0, if_open=1, sence_id=2022, conf=0.7, aiConfig=0), ExtraType(id=2023, sence=可见光, type=烟火识别, extra_type=2010_13, model=01, user=xuzhou_ai, difficult=0, if_open=1, sence_id=2023, conf=0.7, aiConfig=0), ExtraType(id=2003, sence=可见光, type=是否佩戴安全绳, extra_type=2003_ext, model=01, user=xuzhou_ai, difficult=0, if_open=1, sence_id=2003, conf=0.7, aiConfig=0), ExtraType(id=2004, sence=可见光, type=是否佩戴安全帽, extra_type=2004_ext, model=01, user=xuzhou_ai, difficult=0, if_open=1, sence_id=2004, conf=0.7, aiConfig=1), ExtraType(id=2034, sence=可见光, type=路面车辆计数, extra_type=2010_24, model=01, user=xuzhou_ai, difficult=0, if_open=1, sence_id=2034, conf=0.7, aiConfig=0), ExtraType(id=2015, sence=可见光, type=多类型车辆计数, extra_type=2010_5, model=01, user=xuzhou_ai, difficult=0, if_open=1, sence_id=2015, conf=0.7, aiConfig=0), ExtraType(id=2016, sence=可见光, type=多类型车辆拥堵聚集, extra_type=2010_6, model=01, user=xuzhou_ai, difficult=0, if_open=1, sence_id=2016, conf=0.7, aiConfig=0)]) + ExtraTypeResponse response = mapper.readValue(algorithmResponseBody,ExtraTypeResponse.class); + System.out.println(JSONUtil.toJsonStr(response)); + List list = response.getData(); + for (ExtraType extraType : list) { + extra_type_list.add(extraType.getExtra_type()); + break; + } + } catch (URISyntaxException | JsonProcessingException e) { + log.error("星逻算法-算法列表查询失败",e); + } + } + + return null; + } + + @Override + public Map startEngine(Map objectMap){ + System.out.println("objectMap" + objectMap); +// String configKey = remoteSystemFeign.getConfigKey("xingluo.auto.submit");//通 +// System.out.println("configKey"+configKey); + EngineRecordEntity record = new EngineRecordEntity(); +// String ip = remoteConfigService.selectStreamIp(); + String ip = remoteConfigFeign.getConfigKey("stream"); + System.out.println(ip); + ip = "121.237.182.235";//服务器使用ip + String md5 = Md5Utils.hash("xuzhou_ai"); //获取token + 设置请求Header和Body(如JSON) + JSONObject jsonObj = new JSONObject(); + jsonObj.put("username", sanitize("xuzhou_ai")); // sanitize函数见下文 + jsonObj.put("password", sanitize(md5)); + String responseBody = PostRequest(jsonObj, xingluoApiConfig.getEngineLogin(),""); //"http://60.204.247.65:8100/Third/Login" + JSONObject jsonObject = new JSONObject(responseBody); + + // 逐层获取 data -> token + JSONObject data = jsonObject.getJSONObject("data"); + String token = data.getString("token"); + String sceneResponseBody = null; + String algorithmResponseBody = null; + String taskId = ""; + String missionBatch = ""; + String deviceSn = MapUtil.getStr(objectMap, "deviceSn", ""); + //获取rtmpUrl + String rtmpUrl = ""; + DeviceDTO deviceDTO = deviceService.getDeviceBySn(deviceSn).orElse(null); + if (deviceDTO != null) { + String childDeviceRtmpUrl = deviceService.getChildDeviceStreamUrlByDeviceSn(deviceDTO.getChildDeviceSn()); + rtmpUrl = childDeviceRtmpUrl; + } + + //查询用户开通的场景 + Object rtmpUrlParam = objectMap.get("rtmpUrl"); + String pushUrl = "rtmp://" + ip + "/live/livesteam/" + rtmpUrl + "ai1"; + if (StringUtils.isNotEmpty(token)){ JSONObject jsonObj2 = new JSONObject(); String type = objectMap.get("type").toString(); - if (StringUtils.isNotEmpty(type)){ + if (StringUtils.isNotEmpty(type)){ //2004_ext 算法名称 List list = Arrays.asList(type.split(",")); jsonObj2.put("scene", "可见光"); // sanitize函数见下文 - jsonObj2.put("callback_url", "http://114.235.183.162:9888/ces/iot/deviceLog/some"); + jsonObj2.put("callback_url", xingluoApiConfig.getEngineCallbackUrl());//"http://121.237.178.63:11100/sample/manage/api/v1/saEngineRecord/some" jsonObj2.put("extra_type_list",new JSONArray(list)); - jsonObj2.put("input_url","http://"+ip+":19008/live/livesteam/"+objectMap.get("rtmpUrl")+".flv"); - jsonObj2.put("push_url", "rtmp://"+ip+"/live/livesteam/"+objectMap.get("rtmpUrl")+"ai1"); -// jsonObj2.put("play_url", objectMap.get("play_url")); - String responseBody2 = PostRequest(jsonObj2, "http://60.204.247.65:8100/Third/Engine/Start",token); +// jsonObj2.put("input_url","http://"+ip+":19008/live/livesteam/"+objectMap.get("rtmpUrl")+".flv"); + jsonObj2.put("input_url", "rtmp://"+ip+"/live/livesteam/"+ rtmpUrl);//预览接口必须要传rtmp,不能是flv + jsonObj2.put("push_url", pushUrl); //推流接口有时候不稳定,需要检查SRS服务 +// live.setUrl(url.toString().replace("rtmp", "webrtc")); +// jsonObj2.put("play_url", objectMap.get("play_url")); //play_url不必传, play和push是一对, play 其实是冗余的, 方便记录更详细的日志 + /** + * {"code":500,"message":"任务启动错误:can not open input stream http://114.235.183.163:19008/live/livesteam/7CTXN2T00B07C5-165-0-7.flv","data":null} + * {"code":500,"message":"AI开启失败","data":null} + * {"code":500,"message":"任务启动错误:can not open output rtmp://114.235.183.163/live/livesteam/7CTXN2T00B07C5-165-0-7ai1","data":null} + * {"code":200,"message":"操作成功","data":{"task_id":"NOZGoIIubQ","mission_batch":"WX1748254304635"}} + */ + + //测试环境,直接接收url,跳过无人机 +// Object rtmpUrlParam = objectMap.get("inputUrl"); +// jsonObj2.put("input_url", "rtmp://114.235.183.163/live/livesteam/1581F6Q8X24CE00G02S4-81-0-0");//预览接口必须要传rtmp,不能是flv +// jsonObj2.put("push_url", "rtmp://114.235.183.163/live/livesteam/1581F6Q8X24CE00G02S4-81-0-0ai1");//预览接口必须要传rtmp,不能是flv + + System.out.println(jsonObj2.toString()); + String responseBody2 = PostRequest(jsonObj2, xingluoApiConfig.getEngineStart(),token); //"http://60.204.247.65:8100/Third/Engine/Start" + System.out.println(responseBody2); ObjectMapper mapper1 = new ObjectMapper(); EngineResponse response = null; try { response = mapper1.readValue(responseBody2, EngineResponse.class); if (response.getCode() != 200){ - throw new RuntimeException("第三方接口调用失败!"); + log.error("第三方接口调用失败!"); } } catch (JsonProcessingException e) { - throw new RuntimeException(e); + log.error("星逻算法-引擎启动失败",e); } + taskId = response.getData().getTask_id(); + missionBatch = response.getData().getMission_batch(); + objectMap.put("task_id",response.getData().getTask_id()); - record.setPushUrl(objectMap.get("rtmpUrl").toString()); - record.setTaskId(MapUtil.getStr(objectMap,"task_id","")); - record.setDeviceSn(MapUtil.getStr(objectMap,"deviceSn","")); - record.setTaskId(response.getData().getTask_id()); + record.setDeviceSn(deviceSn); record.setExtraType(objectMap.get("type").toString()); + record.setPushUrl(rtmpUrl.toString()); + record.setTaskId(taskId); //MapUtil.getStr(objectMap,"task_id","") + record .setMissionBatch(missionBatch); + record.setPushUrl(pushUrl); System.out.print(objectMap); } } - Map map = new HashMap(); - - map.put("push_url", "http://"+ip+":1985/rtc/v1/whep/?app=live/livesteam&stream="+objectMap.get("rtmpUrl")+"ai1"); - - map.put("task_id", objectMap.get("task_id")); //添加启动引擎记录 - mapper.insert(record); + engineRecordMapper.insert(record); + + Map map = new HashMap(); +// map.put("push_url", "http://"+ip+":1985/rtc/v1/whep/?app=live/livesteam&stream="+ rtmpUrl +"ai1"); +// live.setUrl(url.toString().replace("rtmp", "webrtc")); + map.put("push_url", pushUrl.replaceFirst("rtmp", "webrtc")); + map.put("task_id", taskId);//objectMap.get("task_id") //添加任务id和jobid关联关系 TaskJobEntity taskJobEntity = new TaskJobEntity(); - taskJobEntity.setJobId(objectMap.get("jobId").toString()); + + String jobIdStr = MapUtil.getStr(objectMap, "jobId"); + jobIdStr = StrUtil.isEmpty(jobIdStr) ? "-1" : jobIdStr; //没有航线,默认-1 + taskJobEntity.setJobId(jobIdStr); taskJobEntity.setTaskId(objectMap.get("task_id").toString()); + taskJobEntity.setDeviceSn(deviceSn); taskJobMapper.insert(taskJobEntity); return map; } @@ -154,7 +273,14 @@ public class SampleEngineRecordServiceImpl implements ISampleEngineRecordService @Override public void closeEngine(Map objectMap) { JSONObject jsonObj2 = new JSONObject(); - EngineRecordEntity record = mapper.selectOne(new LambdaQueryWrapper().eq(EngineRecordEntity::getDeviceSn, objectMap.get("deviceSn"))); +// String taskId = (String)objectMap.get("taskId"); + String deviceSn = (String)objectMap.get("deviceSn"); + LambdaQueryWrapper engineRecordQW = new LambdaQueryWrapper(); +// engineRecordQW.eq(EngineRecordEntity::getTaskId, taskId); + engineRecordQW.eq(EngineRecordEntity::getDeviceSn,deviceSn); + engineRecordQW.orderByDesc(EngineRecordEntity::getCreateTime); + engineRecordQW.last("limit 1"); + EngineRecordEntity record = engineRecordMapper.selectOne(engineRecordQW); if (record == null){ // throw new RuntimeException("关闭引擎失败!"); }else { @@ -164,18 +290,40 @@ public class SampleEngineRecordServiceImpl implements ISampleEngineRecordService JSONObject jsonObj = new JSONObject(); jsonObj.put("username", sanitize("xuzhou_ai")); // sanitize函数见下文 jsonObj.put("password", sanitize(md5)); - String responseBody = PostRequest(jsonObj, "http://60.204.247.65:8100/Third/Login",""); + //{"code":200,"message":"操作成功","data":{"token":"eyJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE3NDgyNDM0MDgsImV4cCI6MTc1MDgzNTQwOCwidWlkIjoiT2tUV0NyWWxZSSIsInRoaXJkIjoxfQ.LZI1jEl7wyUquXJrApynEE7aUdpqiiqy8VD_3nm215I0dgkGTtDWa3PO26pDWFzw40kNPI5JwWuZBjEtroLAOEQtmhsI9BId5aw605D5jGQ69U6JTa7q095eJxIT2I7rMwAjMGqOtxDfRyw_U-GJPTA4nE4uy98yCXG56FBnrY8"}} + String responseBody = PostRequest(jsonObj, xingluoApiConfig.getEngineLogin(),"");//"http://60.204.247.65:8100/Third/Login" JSONObject jsonObject = new JSONObject(responseBody); // 逐层获取 data -> token JSONObject data = jsonObject.getJSONObject("data"); String token = data.getString("token"); - jsonObj2.put("task_id", record.getTaskId()); // sanitize函数见下文 - String responseBody2 = PostRequest(jsonObj2, "http://60.204.247.65:8100/Third/Engine/Stop",token); + //{"code":200,"message":"操作成功","data":0} + String responseBody2 = PostRequest(jsonObj2, xingluoApiConfig.getEngineStop(),token); //"http://60.204.247.65:8100/Third/Engine/Stop" JSONObject json = new JSONObject(responseBody2); + String resData = json.getString("data"); + String resDataStr = ""; +// String resDataStr = StrUtil.equals(resData,"1") ? "停止成功" : "停止失败"; + switch (resData){ + case "": + resDataStr = "停止成功(长时间未关闭)"; + break; + case "0": + resDataStr = "停止失败"; + break; + case "1": + resDataStr = "停止成功"; + break; + } + + EngineRecordEntity engineRecordUpdate = new EngineRecordEntity(); + engineRecordUpdate.setId(record.getId()); + engineRecordUpdate.setStopResData(resData); + engineRecordUpdate.setStopResDataStr(resDataStr); + engineRecordMapper.updateById(engineRecordUpdate); + // 方式2:安全获取(先判空再转换) - Object dataObj = json.get("data"); + /* Object dataObj = json.get("data"); if(dataObj != null && dataObj instanceof Integer) { int data1 = (Integer) dataObj; if (data1 ==1){ @@ -185,16 +333,201 @@ public class SampleEngineRecordServiceImpl implements ISampleEngineRecordService } } else { throw new RuntimeException("关闭引擎失败!"); + }*/ + } + + } + + @Override + public Integer dealAlertData(cn.hutool.json.JSONObject resObject) { + cn.hutool.json.JSONObject entries = new cn.hutool.json.JSONObject(resObject); + CallBackDTO callBackVo = JSONUtil.toBean(resObject, CallBackDTO.class); + String taskIdStr = entries.getStr("taskId"); + if(StrUtil.isBlank(taskIdStr)){return 0;} //无任务ID拦截 + if(callBackVo.getEvents().isEmpty()){ return 0;} + + //基于历史记录,找相同设备- trackId是否相同,不同才保存, (每次记录中eventId都不同,所以不做参考) + //同一图片上传可能包含多个物体,传值可能是 h1v93,或者fdi32,或者h1v93,fdi32, 只要trackIds不同,就保存记录 + List warningRecordList = new ArrayList<>(); +// String fileUrlStr = "mediafile/e5b8ce3a-3562-40e0-b244-91554d9c17ad/DJI_202505211323_001_e5b8ce3a-3562-40e0-b244-91554d9c17ad/DJI_20250521132610_0001_V.jpeg"; +// String fileUrl = fileService.getObjectUrlOne(MinIOConstants.BUCKET_DKCY, fileUrlStr, 360000).toString(); + if (CollectionUtils.isEmpty(callBackVo.getEvents())){return 0;} //空事件拦截 + + /** 传值转WarningRecord记录 **/ + for (EventsDTO eventsVo : callBackVo.getEvents()){ //一个事件一个图片 + String extraTypeStr = eventsVo.getExtraType(); + String trackIds = eventsVo.getObjects().stream().map(ObjectsDTO::getTrackId).collect(Collectors.joining(",")); +// Long count = sampleWarningRecordService.lambdaQuery() +// .eq(WarningRecordEntity::getTaskId, taskIdStr) +// .eq(WarningRecordEntity::getExtraType, extraTypeStr) +// .eq(WarningRecordEntity::getTrackIds, trackIds) +// .count(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(WarningRecordEntity::getTaskId, taskIdStr) + .eq(WarningRecordEntity::getExtraType, extraTypeStr) + .eq(WarningRecordEntity::getTrackIds, trackIds); + Long count = sampleWarningRecordMapper.selectCount(queryWrapper); + if(count > 0){continue;} + + WarningRecordEntity warningRecord = new WarningRecordEntity(); + warningRecord.setTaskId(callBackVo.getTaskId()); + warningRecord.setAlgoId(eventsVo.getAlgoId()); + warningRecord.setEventId(eventsVo.getEventId()); + warningRecord.setExtraType(eventsVo.getExtraType()); + warningRecord.setPicUrl(eventsVo.getPicUrl()); +// warningRecord.setPicUrl("http://114.235.183.147:9090/api/v1/download-shared-object/aHR0cDovLzEyNy4wLjAuMTo5MDAwL2RrY3kvbWVkaWFmaWxlL2U1YjhjZTNhLTM1NjItNDBlMC1iMjQ0LTkxNTU0ZDljMTdhZC9ESklfMjAyNTA1MjExMzIzXzAwMV9lNWI4Y2UzYS0zNTYyLTQwZTAtYjI0NC05MTU1NGQ5YzE3YWQvREpJXzIwMjUwNTIxMTMyNjEwXzAwMDFfVi5qcGVnP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QVI5MEk5QkxXWVZBWkRLOUowVjElMkYyMDI1MDUyMiUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTA1MjJUMTUxNzAxWiZYLUFtei1FeHBpcmVzPTQzMjAwJlgtQW16LVNlY3VyaXR5LVRva2VuPWV5SmhiR2NpT2lKSVV6VXhNaUlzSW5SNWNDSTZJa3BYVkNKOS5leUpoWTJObGMzTkxaWGtpT2lKQlVqa3dTVGxDVEZkWlZrRmFSRXM1U2pCV01TSXNJbVY0Y0NJNk1UYzBOemsyT0RneE9Dd2ljR0Z5Wlc1MElqb2lZV1J0YVc0aWZRLkh1N1VaVkhuS19EUWhfR1lnLVB0cVhBNFpJTHpPTk1vTkZ3by1YalI0N0R3U3VnZ2NyRC1EdXkxeEdfM3FmWXdRQmdPd29Ca2xGVTRYLWpvNncxY0lRJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZ2ZXJzaW9uSWQ9bnVsbCZYLUFtei1TaWduYXR1cmU9MjNmZjdhZWViNTJlZjk4ZWFmMTg5OTg4MjQzNDk5ZTRiYzgwNzI5ZWU1MzJkM2M2MTdlMDFmM2U3ODZlZDA1OQ"); + warningRecord.setTimestamp(eventsVo.getTimestamp()); + String objJsonStr = JSONUtil.toJsonStr(eventsVo.getObjects()); + warningRecord.setRemark(objJsonStr); + warningRecord.setTrackIds(trackIds); +// System.out.println(JSONUtil.toJsonStr(eventsVo.getObjects())); + warningRecordList.add(warningRecord); + } +// sampleWarningRecordService.saveBatch(warningRecordList); + sampleWarningRecordMapper.insert(warningRecordList); + + /** WarningRecord转 businessAlert记录 **/ + //保存数据到BusinessAlert + String activeProfile = "w_nantong"; + ArrayList alertVoList = new ArrayList<>(); + + for (WarningRecordEntity warningRecordEntity : warningRecordList) { + RemoteBusinessAlertVo remoteBusinessAlertVo = new RemoteBusinessAlertVo(); + if(ObjectUtil.isEmpty(warningRecordEntity.getTaskId())){ continue;} //空数据跳过 + + setupLabelInfo(warningRecordEntity, remoteBusinessAlertVo);//设置标签信息 + + //查找最新任务TaskJob + LambdaQueryWrapper taskJobquery = new LambdaQueryWrapper<>(TaskJobEntity.class) + .eq(TaskJobEntity::getTaskId, warningRecordEntity.getTaskId()) + .orderByDesc(TaskJobEntity::getCreateTime) + .last("limit 1"); + TaskJobEntity taskJobEntity = taskJobMapper.selectOne(taskJobquery); + + String deviceSn = ""; + if(BeanUtil.isNotEmpty(taskJobEntity)){ + String jobId = taskJobEntity.getJobId(); + deviceSn = taskJobEntity.getDeviceSn(); + if(StrUtil.equals("-1",jobId)){ //没有jobId,给个默认名称 + remoteBusinessAlertVo.setJobId("-1"); + remoteBusinessAlertVo.setJobName("手动飞行" + "-" +remoteBusinessAlertVo.getLabelCn()+ DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")); + } else if(StrUtil.isNotEmpty(jobId)){ + LambdaQueryWrapper waylineJobQuery = new LambdaQueryWrapper<>(); + waylineJobQuery.eq(WaylineJobEntity::getJobId,jobId); //jobId是unique唯一 + WaylineJobEntity waylineJobEntity = waylineJobMapper.selectOne(waylineJobQuery); + if(BeanUtil.isEmpty(waylineJobEntity)){continue;} //找不到航线-不处理预警 + remoteBusinessAlertVo.setJobId(waylineJobEntity.getJobId()); + remoteBusinessAlertVo.setJobName(waylineJobEntity.getName()); + } } + + remoteBusinessAlertVo.setLat(""); + remoteBusinessAlertVo.setLng(""); + if(StrUtil.isNotEmpty(deviceSn)){ + Optional deviceBySn = deviceService.getDeviceBySn(deviceSn); + DeviceDTO deviceDTO = deviceBySn.isPresent() ? deviceBySn.get() : null; + remoteBusinessAlertVo.setLat(deviceDTO.getLatitude()+ ""); //34.20912175973148 + remoteBusinessAlertVo.setLng(deviceDTO.getLongitude()+ "");//117.2260332850499 + } + + //预警基础信息扩展 +// remoteBusinessAlertVo.setAlertType("1"); //1:图片比对预警 2:AI实时预警 + remoteBusinessAlertVo.setAssign(false); + String minioUrl = saveAliyunPreviewToMinio(warningRecordEntity.getPicUrl(),deviceSn, MinIOConstants.BUCKET_DKCY); + remoteBusinessAlertVo.setImages(minioUrl); +// remoteBusinessAlertVo.setMaxImages("");//mateFileUrl +// remoteBusinessAlertVo.setMateSourceImgUrl("");//mateFileUrl + remoteBusinessAlertVo.setTaskContent(""); + remoteBusinessAlertVo.setHandleType("waiting"); +// remoteBusinessAlertVo.setDeptId(aiCompareEntity.getCreateDept()+"");//暂时没有 +// remoteBusinessAlertVo.setDeptName(aiCompareEntity.getDeptName()); + remoteBusinessAlertVo.setHandleNum(0); + //businessAlertConstructInfo数据 + alertVoList.add(remoteBusinessAlertVo); } +// businessAlertService.saveBusinessAlert(alertVoList,activeProfile); //远程触发预警消息 + RemoteBusinessAlertRequest remoteBusinessAlertRequest = new RemoteBusinessAlertRequest(); + remoteBusinessAlertRequest.setAlertVoList(alertVoList); + remoteBusinessAlertRequest.setActiveProfile(activeProfile); + cn.hutool.json.JSONObject requestObj = new cn.hutool.json.JSONObject(remoteBusinessAlertRequest); + remoteBusinessAlertFeign.saveBusinessAlert(requestObj); + + return callBackVo.getEvents().size(); + } + //基于算法名称赋值 + private static void setupLabelInfo(WarningRecordEntity warningRecordEntity, RemoteBusinessAlertVo remoteBusinessAlertVo) { + // String extraType = XingluoApiEnum.SAFETY_HARNESS.getExtraType(); + switch (warningRecordEntity.getExtraType()){ + case "2010_12": //秸秆焚烧 ------ + remoteBusinessAlertVo.setLabelCn(XingluoApiEnum.FIRE.getTypeStr()); + remoteBusinessAlertVo.setLabelEn(XingluoApiEnum.FIRE.getAiType()); + break; + case "2010_13": //烟火识别 + remoteBusinessAlertVo.setLabelCn(XingluoApiEnum.FIREWORKS.getTypeStr()); + remoteBusinessAlertVo.setLabelEn(XingluoApiEnum.FIREWORKS.getAiType()); + break; + case "2003_ext": //安全带预警 ------ + remoteBusinessAlertVo.setLabelCn(XingluoApiEnum.SAFETY_HARNESS.getTypeStr()); + remoteBusinessAlertVo.setLabelEn(XingluoApiEnum.SAFETY_HARNESS.getAiType()); + break; + case "2004_ext"://安全帽预警 ----- + remoteBusinessAlertVo.setLabelCn(XingluoApiEnum.SAFETY_HELMET.getTypeStr()); + remoteBusinessAlertVo.setLabelEn(XingluoApiEnum.SAFETY_HELMET.getAiType()); + break; + case "2010_24"://路面车辆计数 + remoteBusinessAlertVo.setLabelCn(XingluoApiEnum.CARCOUNT.getTypeStr()); + remoteBusinessAlertVo.setLabelEn(XingluoApiEnum.CARCOUNT.getAiType()); + break; + case "2010_5"://多类型车辆计数 + remoteBusinessAlertVo.setLabelCn(XingluoApiEnum.CARCOUNTMULTITYPE.getTypeStr()); + remoteBusinessAlertVo.setLabelEn(XingluoApiEnum.CARCOUNTMULTITYPE.getAiType()); + break; + case "2010_6"://多类型车辆拥堵聚集 + remoteBusinessAlertVo.setLabelCn(XingluoApiEnum.CARMULTITYPEJAM.getTypeStr()); + remoteBusinessAlertVo.setLabelEn(XingluoApiEnum.CARMULTITYPEJAM.getAiType()); + break; + case "2010_29": //无人机安全帽检测 ------ + remoteBusinessAlertVo.setLabelCn(XingluoApiEnum.SAFETY_HELMET_NEW.getTypeStr());//安全帽预警-新 + remoteBusinessAlertVo.setLabelEn(XingluoApiEnum.SAFETY_HELMET_NEW.getAiType()); //SafetyHelmet + break; + } + } + + + public String saveAliyunPreviewToMinio(String aliyunUrl,String deviceSn, String minioBucket) { + try { + URL url = new URL(aliyunUrl); + URLConnection conn = url.openConnection(); + conn.setConnectTimeout(3_500); + conn.setReadTimeout(3_500); + InputStream inputStream = conn.getInputStream(); + long fileSize = conn.getContentLengthLong(); + + String fileName = FileUtil.getName(url.getPath()); + String path = url.getPath().replace(fileName, deviceSn+ fileName); // eg: /ai/report/29847/{deviceSn+xxx.jpg} + String originalFileName = path.substring(path.lastIndexOf("/") + 1); // qwfbGaBixI.jpg + String suffix = originalFileName.contains(".") ? originalFileName.substring(originalFileName.lastIndexOf(".")) : ".jpg"; // fallback + +// String newFileName = IdUtils.fastUUID() + suffix; + OssClient minioClient = OssFactory.instance(minioBucket); + UploadResult result = minioClient.upload(inputStream, path, fileSize, MimeTypeUtils.IMAGE_JPG); +// MinioUtil.uploadFile(path,inputStream,); + + inputStream.close(); + return path; // 返回 MinIO 的访问地址 + } catch (IOException e) { + throw new RuntimeException("上传图片失败", e); + } } - public String PostRequest( JSONObject jsonObj, String url, String token - ) { + + + //通用提交 + public String PostRequest( JSONObject jsonObj, String url, String token) { try (CloseableHttpClient httpClient = HttpClients.createDefault()) { // 1. 创建POST请求对象 HttpPost post = new HttpPost(url); @@ -209,7 +542,7 @@ public class SampleEngineRecordServiceImpl implements ISampleEngineRecordService if (response.getStatusLine().getStatusCode() == 200) { return responseBody; } else { - throw new RuntimeException("第三方接口调用失败!"); + log.error("第三方接口调用失败!"); } } } catch (Exception e) { @@ -219,8 +552,7 @@ public class SampleEngineRecordServiceImpl implements ISampleEngineRecordService } - public String GetRequest(URI uri, String token - ) { + public String GetRequest(URI uri, String token) { try (CloseableHttpClient httpClient = HttpClients.createDefault()) { // URI uri = new URIBuilder("https://api.example.com/data") // .addParameter("param1", "value1") @@ -236,7 +568,8 @@ public class SampleEngineRecordServiceImpl implements ISampleEngineRecordService if (response.getStatusLine().getStatusCode() == 200){ return responseBody; }else { - throw new RuntimeException("第三方接口调用失败!"); + log.error("星逻算法-第三方接口调用失败"); +// throw new RuntimeException("第三方接口调用失败!"); } } } catch (Exception e) { diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/media/controller/FileController.java b/dk-modules/sample/src/main/java/org/dromara/sample/media/controller/FileController.java index 6a91180..905b9fb 100644 --- a/dk-modules/sample/src/main/java/org/dromara/sample/media/controller/FileController.java +++ b/dk-modules/sample/src/main/java/org/dromara/sample/media/controller/FileController.java @@ -85,4 +85,15 @@ public class FileController { } return HttpResultResponse.success(filesList); } + + /** + * 根据文件id查询图片的偏航角 + * @param fileId + * @return + */ + @GetMapping("/degree") + @Operation(summary = "根据文件id查询图片的偏航角", description = "根据文件id查询图片的偏航角") + public Double getGimbalYawDegree(@RequestParam("fileId") String fileId) { + return fileService.getGimbalYawDegree(fileId); + } } diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/media/service/IFileService.java b/dk-modules/sample/src/main/java/org/dromara/sample/media/service/IFileService.java index 6ece33f..86e0221 100644 --- a/dk-modules/sample/src/main/java/org/dromara/sample/media/service/IFileService.java +++ b/dk-modules/sample/src/main/java/org/dromara/sample/media/service/IFileService.java @@ -88,4 +88,7 @@ public interface IFileService { List getMediaFileDTO( String jobId,String fileType); String copyFile(String sourceBucket, String originFileUrl, String targetBucket); + String copyFileHttp(String fileUrl, String originFileUrl, String bucketDkcy); + + Double getGimbalYawDegree(String fileId); } diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/media/service/impl/FileServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/media/service/impl/FileServiceImpl.java index 437abc1..3d0a0b9 100644 --- a/dk-modules/sample/src/main/java/org/dromara/sample/media/service/impl/FileServiceImpl.java +++ b/dk-modules/sample/src/main/java/org/dromara/sample/media/service/impl/FileServiceImpl.java @@ -1,11 +1,14 @@ package org.dromara.sample.media.service.impl; +import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.dromara.common.core.utils.file.MimeTypeUtils; import org.dromara.common.oss.core.OssClient; +import org.dromara.common.oss.entity.UploadResult; import org.dromara.common.oss.factory.OssFactory; import org.dromara.common.redis.utils.RedisOpsUtils; import org.dromara.common.satoken.utils.LoginHelper; @@ -29,8 +32,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.io.IOException; +import java.io.InputStream; import java.net.URL; +import java.net.URLConnection; import java.util.*; import java.util.stream.Collectors; @@ -195,12 +201,52 @@ public class FileServiceImpl implements IFileService { MinioUtil.copyFile(originFileUrl,originFileUrl,sourceBucket,targetBucket);//列表图片 MinioUtil.copyFile(originFileUrl,originFileUrl,sourceBucket,MinIOConstants.BUCKET_ALERT);//预览图片 } catch (Exception e) { - throw new RuntimeException(e); + e.printStackTrace(); } return fileUrl; } + + @Override + public String copyFileHttp(String aliyunUrl, String originFileUrl, String minioBucket) { + try { + URL url = new URL(aliyunUrl); + URLConnection conn = url.openConnection(); + conn.setConnectTimeout(3_500); + conn.setReadTimeout(3_500); + InputStream inputStream = conn.getInputStream(); + long fileSize = conn.getContentLengthLong(); + + String fileName = FileUtil.getName(url.getPath()); +// String path = url.getPath().replace(fileName, deviceSn+ fileName); // eg: /ai/report/29847/{deviceSn+xxx.jpg} +// String originalFileName = path.substring(path.lastIndexOf("/") + 1); // qwfbGaBixI.jpg +// String suffix = originalFileName.contains(".") ? originalFileName.substring(originalFileName.lastIndexOf(".")) : ".jpg"; // fallback + +// String newFileName = IdUtils.fastUUID() + suffix; + OssClient minioClient = OssFactory.instance(minioBucket); + UploadResult result = minioClient.upload(inputStream, originFileUrl, fileSize, MimeTypeUtils.IMAGE_JPG); +// MinioUtil.uploadFile(path,inputStream,); + + inputStream.close(); + return result.getUrl(); // 返回 MinIO 的访问地址 + } catch (IOException e) { + throw new RuntimeException("上传图片失败", e); + } + } + + @Override + public Double getGimbalYawDegree(String fileId) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(MediaFileEntity::getFileId, fileId); + List mediaFileEntities = mapper.selectList(wrapper); + if (ObjectUtil.isNotEmpty(mediaFileEntities)){ + return mediaFileEntities.get(0).getGimbalYawDegree(); + } + + return -1.0; + } + /** * Convert the received file object into a database entity object. * @param file diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/controller/WaylineJobController.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/controller/WaylineJobController.java index 70c2321..7edd719 100644 --- a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/controller/WaylineJobController.java +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/controller/WaylineJobController.java @@ -154,4 +154,11 @@ public class WaylineJobController { } } + //根据设备sn查询jobname + @GetMapping("/{workspace_id}/getJobByDockSn") + @Operation(summary = "根据设备sn查询jobname。", description = "根据设备sn查询jobname。") + public HttpResultResponse getJobByDockSn( @RequestParam(name = "device_sn") String deviceSn) { + return HttpResultResponse.success(waylineJobService.getJobByDockSn(deviceSn)); + } + } diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineJobDTO.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineJobDTO.java index 62e97e5..a702779 100644 --- a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineJobDTO.java +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/dto/WaylineJobDTO.java @@ -58,6 +58,8 @@ public class WaylineJobDTO { private Integer code; + private String codeName; + private Integer rthAltitude; private OutOfControlActionEnum outOfControlAction; diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/IWaylineJobService.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/IWaylineJobService.java index 6b2532b..36e4064 100644 --- a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/IWaylineJobService.java +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/IWaylineJobService.java @@ -87,4 +87,6 @@ public interface IWaylineJobService { * @param fileType 图片类型 ("jpeg,mp4") * */ List getMediaFileDTO(String jobId, String fileType); + + WaylineJobDTO getJobByDockSn(String dockSn); } diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/AiCompareServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/AiCompareServiceImpl.java index 21ec388..b7aaa42 100644 --- a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/AiCompareServiceImpl.java +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/AiCompareServiceImpl.java @@ -214,7 +214,7 @@ public class AiCompareServiceImpl implements IAiCompareService { aiCompareEntity.setId(frameDTO.getCompareId()); aiCompareMapper.updateById(aiCompareEntity); frameDTO.setJobName(aiCompareEntity.getJobName()); - String originFileUrl = frameDTO.getFileUrl(); + String originFileUrl = frameDTO.getFileUrl();//waiwang/b0c5dc04-6232-4762-b748-16f8e6ea04ed/DJI_202506010857_001_b0c5dc04-6232-4762-b748-16f8e6ea04ed/DJI_20250601085925_0001_V.jpeg String fileUrl = fileService.getObjectUrlOne(MinIOConstants.BUCKET_MEDIAFILE, originFileUrl, 3600).toString(); frameDTO.setFileUrl(fileUrl); String originMateFileUrl = frameDTO.getMateFileUrl(); @@ -234,9 +234,20 @@ public class AiCompareServiceImpl implements IAiCompareService { //图片处理 // fileService.get(MinIOConstants.BUCKET_MEDIAFILE, originMateFileUrl, 3600); - //复制原图到指定bucket - String copyFileUrl = fileService.copyFile(MinIOConstants.BUCKET_MEDIAFILE, originMateFileUrl, MinIOConstants.BUCKET_DKCY); + //复制原图到指定bucket //mediafile + // originMateFileUrl:waiwang/b9e5ae94-e290-43af-9f66-12031580aba1/DJI_202506020949_001_b9e5ae94-e290-43af-9f66-12031580aba1/DJI_20250602095106_0001_V.jpeg + String linkType = ""; + if(StrUtil.startWith(fileUrl,"http")){ + linkType = "http"; + //http://yq-dajiang.oss-cn-hangzhou.aliyuncs.com/waiwang/56055519-3189-4af9-b4ea-56fe06df3082/DJI_202506010952_001_56055519-3189-4af9-b4ea-56fe06df3082/DJI_20250601100131_0001_V.jpeg + String fileUrlStr = fileService.copyFileHttp(fileUrl, originFileUrl, MinIOConstants.BUCKET_DKCY); + String fileMateUrlStr = fileService.copyFileHttp(mateFileUrl, originMateFileUrl, MinIOConstants.BUCKET_DKCY); + }else{ + String copyFileUrl = fileService.copyFile(MinIOConstants.BUCKET_MEDIAFILE, originMateFileUrl, MinIOConstants.BUCKET_DKCY); // String copyFileUrl = fileService.copyFile(MinIOConstants.BUCKET_MEDIAFILE, originFileUrl, MinIOConstants.BUCKET_ALERT); + } + + ArrayList alertVoList = new ArrayList<>(); //手动简化逻辑,上传图片 int frameCount =0; diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/WaylineJobServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/WaylineJobServiceImpl.java index e8cf671..82790e3 100644 --- a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/WaylineJobServiceImpl.java +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/WaylineJobServiceImpl.java @@ -7,6 +7,8 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.dromara.common.redis.config.RedisConst; import org.dromara.common.redis.utils.RedisOpsUtils; import org.dromara.common.satoken.utils.LoginHelper; +import org.dromara.common.sdk.cloudapi.debug.DebugErrorCodeEnum; +import org.dromara.common.sdk.cloudapi.debug.ErrorCodeEnum; import org.dromara.common.sdk.cloudapi.device.DockModeCodeEnum; import org.dromara.common.sdk.cloudapi.device.DroneModeCodeEnum; import org.dromara.common.sdk.cloudapi.device.OsdDock; @@ -265,6 +267,26 @@ public class WaylineJobServiceImpl implements IWaylineJobService { return fileService.getMediaFileDTO(jobId,fileType); } + @Override + public WaylineJobDTO getJobByDockSn(String dockSn) { + + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() + .eq(WaylineJobEntity::getStatus, 2) + .eq(WaylineJobEntity::getDockSn, dockSn); + + //降序查询 + queryWrapper.orderByDesc(WaylineJobEntity::getCreateTime); + + List waylineJobEntities = mapper.selectList(queryWrapper); + + if (ObjectUtil.isEmpty(waylineJobEntities)){ + return new WaylineJobDTO(); + } + + return entity2Dto(waylineJobEntities.getFirst()); + + } + private WaylineJobDTO entity2Dto(WaylineJobEntity entity) { if (entity == null) { return null; @@ -297,6 +319,7 @@ public class WaylineJobServiceImpl implements IWaylineJobService { .rthAltitude(entity.getRthAltitude()) .outOfControlAction(OutOfControlActionEnum.find(entity.getOutOfControlAction())) .mediaCount(entity.getMediaCount()) + .codeName(entity.getErrorCode()!=null?ErrorCodeEnum.find(entity.getErrorCode()).getMessage():null) .breakPoint(entity.getBreakPoint()); @@ -337,5 +360,4 @@ public class WaylineJobServiceImpl implements IWaylineJobService { .uploadedCount(uploadedSize).build()); return builder.build(); } - } diff --git a/dk-modules/system/pom.xml b/dk-modules/system/pom.xml index b0c2d65..62cef53 100644 --- a/dk-modules/system/pom.xml +++ b/dk-modules/system/pom.xml @@ -135,7 +135,6 @@ gt-shapefile 29.5 - diff --git a/dk-modules/system/src/main/java/org/dromara/system/DKSystemApplication.java b/dk-modules/system/src/main/java/org/dromara/system/DKSystemApplication.java index 63db867..c015fef 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/DKSystemApplication.java +++ b/dk-modules/system/src/main/java/org/dromara/system/DKSystemApplication.java @@ -4,6 +4,7 @@ import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup; +import org.springframework.scheduling.annotation.EnableAsync; /** * 系统模块 @@ -12,6 +13,7 @@ import org.springframework.boot.context.metrics.buffering.BufferingApplicationSt */ @EnableDubbo @SpringBootApplication +@EnableAsync public class DKSystemApplication { public static void main(String[] args) { SpringApplication application = new SpringApplication(DKSystemApplication.class); diff --git a/dk-modules/system/src/main/java/org/dromara/system/config/ProjectTablePrefixConfig.java b/dk-modules/system/src/main/java/org/dromara/system/config/ProjectTablePrefixConfig.java index 3e3e6c0..9ecea2c 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/config/ProjectTablePrefixConfig.java +++ b/dk-modules/system/src/main/java/org/dromara/system/config/ProjectTablePrefixConfig.java @@ -14,12 +14,12 @@ import org.springframework.context.annotation.Configuration; @ConfigurationProperties(prefix = "projecttableprefix") public class ProjectTablePrefixConfig { - @Value("${projectTablePrefix.tableBusiness:dk_business") + @Value("${projectTablePrefix.tableBusiness:dk_business}") private String tableBusiness; - @Value("${projectTablePrefix.tableCloud:dk_cloud") + @Value("${projectTablePrefix.tableCloud:dk_cloud}") private String tableCloud; - @Value("${projectTablePrefix.tableWorkflow:dk_workflow") + @Value("${projectTablePrefix.tableWorkflow:dk_workflow}") private String tableWorkflow; } diff --git a/dk-modules/system/src/main/java/org/dromara/system/controller/system/SysConfigController.java b/dk-modules/system/src/main/java/org/dromara/system/controller/system/SysConfigController.java index 58c66dd..abd524d 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/controller/system/SysConfigController.java +++ b/dk-modules/system/src/main/java/org/dromara/system/controller/system/SysConfigController.java @@ -73,6 +73,11 @@ public class SysConfigController extends BaseController { return R.ok("操作成功", configService.selectConfigByKey(configKey)); } + @GetMapping(value = "/configKeyFeign/{configKey}") + public String getConfigKeyFeign(@PathVariable String configKey) { + return configService.selectConfigByKey(configKey); + } + /** * 新增参数配置 */ diff --git a/dk-modules/system/src/main/java/org/dromara/system/controller/system/SysDepartBoundaryController.java b/dk-modules/system/src/main/java/org/dromara/system/controller/system/SysDepartBoundaryController.java index 3caef4e..a123090 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/controller/system/SysDepartBoundaryController.java +++ b/dk-modules/system/src/main/java/org/dromara/system/controller/system/SysDepartBoundaryController.java @@ -5,19 +5,18 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.dromara.common.satoken.utils.LoginHelper; -import org.dromara.system.domain.SysDepartBoundary ; import org.dromara.common.core.domain.R; +import org.dromara.common.idempotent.annotation.RepeatSubmit; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.web.core.BaseController; +import org.dromara.system.domain.SysDepartBoundary; import org.dromara.system.domain.bo.SysDepartBoundaryBo; import org.dromara.system.service.ISysDepartBoundaryService; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.util.List; -import java.util.Map; /** * 部门区域 @@ -40,7 +39,6 @@ public class SysDepartBoundaryController extends BaseController { @Operation(summary ="查询部门的地理位置",description = "查询部门的地理位置") @GetMapping(value = "/listJson") public R> listJson(SysDepartBoundary departBoundary) { -// departBoundary.setDeptId(String.valueOf(LoginHelper.getDeptId())); List listJson = departBoundaryService.listJson(departBoundary); return R.ok("查询成功!",listJson); } @@ -61,22 +59,27 @@ public class SysDepartBoundaryController extends BaseController { * 解析shp文件 * @return */ - @Operation(summary ="批量新增部门区域",description = "批量新增部门区域") - @RequestMapping(value = "/upload", method = RequestMethod.POST) - public R uploadShpFile(@RequestParam("file") MultipartFile file,@RequestParam("areaType") Integer areaType) { - return toAjax(departBoundaryService.uploadShpFile(file,areaType)); + @RepeatSubmit() + @Operation(summary ="新增部门区域",description = "新增部门区域(areaType: 0:市级 1:区级(县) 2:镇级(街道) 3:村级)") + @RequestMapping(value = "/{areaType}/{parentId}/upload", method = RequestMethod.POST) + public R uploadShpFile(@RequestParam("file") MultipartFile file, + @PathVariable Integer areaType, + @PathVariable Long parentId) { + return toAjax(departBoundaryService.uploadShpFile(file,areaType,parentId)); } + /** - * 编辑 - * - * @param + * 根据经纬度查询部门信息 + * @param lat、lng * @return */ - @Operation(summary ="编辑部门区域",description = "编辑部门区域") - @RequestMapping(value = "/update", method = RequestMethod.POST) - public R updateDepartBoundary(@RequestBody SysDepartBoundary departBoundary) { - return toAjax(departBoundaryService.updateDepartBoundary(departBoundary)); + @Operation(summary ="根据经纬度查询部门信息",description = "根据经纬度查询部门信息") + @GetMapping(value = "/location/list") + public R> listDepartBoundaryByLngAndLat(@RequestParam("lat") Double lat, + @RequestParam("lng") Double lng) { + List listJson = departBoundaryService.listDepartBoundaryByLngAndLat(lng,lat); + return R.ok(listJson); } @@ -91,8 +94,4 @@ public class SysDepartBoundaryController extends BaseController { public R deleteDepartBoundary(@RequestParam(name = "id") String id) { return toAjax(departBoundaryService.deleteDepartBoundary(id)); } - - - - } diff --git a/dk-modules/system/src/main/java/org/dromara/system/controller/system/SysDictDataController.java b/dk-modules/system/src/main/java/org/dromara/system/controller/system/SysDictDataController.java index 917d993..2bf1f4b 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/controller/system/SysDictDataController.java +++ b/dk-modules/system/src/main/java/org/dromara/system/controller/system/SysDictDataController.java @@ -14,12 +14,14 @@ import org.dromara.system.domain.bo.SysDictDataBo; import org.dromara.system.domain.vo.SysDictDataVo; import org.dromara.system.service.ISysDictDataService; import org.dromara.system.service.ISysDictTypeService; +import org.springframework.http.MediaType; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import jakarta.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; /** * 数据字典信息 @@ -80,6 +82,16 @@ public class SysDictDataController extends BaseController { return R.ok(data); } + @PostMapping(value = "/selectDataByType") + public R> selectDataByType(@RequestParam String dictType) { + List data = dictTypeService.selectDictDataByType(dictType); + List collect = data.stream().map(SysDictDataVo::getRemark).collect(Collectors.toList()); + if (ObjectUtil.isNull(data)) { + data = new ArrayList<>(); + } + return R.ok(collect); + } + /** * 新增字典类型 */ diff --git a/dk-modules/system/src/main/java/org/dromara/system/controller/system/SysRoleController.java b/dk-modules/system/src/main/java/org/dromara/system/controller/system/SysRoleController.java index dedb36f..3975f30 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/controller/system/SysRoleController.java +++ b/dk-modules/system/src/main/java/org/dromara/system/controller/system/SysRoleController.java @@ -26,6 +26,8 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import jakarta.servlet.http.HttpServletResponse; + +import java.util.ArrayList; import java.util.List; /** @@ -237,10 +239,18 @@ public class SysRoleController extends BaseController { @GetMapping(value = "/user/list") public R> listRoleUser() { String roleName = "dispose"; + String roleJiuLiName = "jiulihu_dipose"; + + List resultlist = new ArrayList<>(); + + List userList = roleService.getUserIno(roleName); + List userjiuliList = roleService.getUserIno(roleJiuLiName); + + resultlist.addAll(userjiuliList); - List userList = roleService.getUserIno(roleName); + resultlist.addAll(userList); - return R.ok(userList); + return R.ok(resultlist); } } diff --git a/dk-modules/system/src/main/java/org/dromara/system/controller/system/SysUserController.java b/dk-modules/system/src/main/java/org/dromara/system/controller/system/SysUserController.java index 107ee20..365b7dc 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/controller/system/SysUserController.java +++ b/dk-modules/system/src/main/java/org/dromara/system/controller/system/SysUserController.java @@ -274,6 +274,16 @@ public class SysUserController extends BaseController { return toAjax(userService.updateUserStatus(user.getUserId(), user.getStatus())); } + + /** + * 状态修改 + */ + @SaCheckPermission("system:user:edit") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping("/noticeType") + public R noticeType(@RequestBody SysUserBo user) { + return toAjax(userService.updateUserNoticeType(user.getUserId(), user.getNoticeType())); + } /** * 根据用户编号获取授权角色 * diff --git a/dk-modules/system/src/main/java/org/dromara/system/domain/SysDepartBoundary.java b/dk-modules/system/src/main/java/org/dromara/system/domain/SysDepartBoundary.java index 6310c68..e2b96d9 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/domain/SysDepartBoundary.java +++ b/dk-modules/system/src/main/java/org/dromara/system/domain/SysDepartBoundary.java @@ -1,6 +1,7 @@ package org.dromara.system.domain; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @@ -23,55 +24,34 @@ public class SysDepartBoundary extends BaseEntity { /**ID*/ @TableId(type = IdType.AUTO) - private String id; - - /** - * 租户Id - */ - private String tenantId; + private Long id; /**机构ID*/ - private String deptId; + private Long deptId; + /**机构/部门名称*/ private String deptName; - /**是否显示0显示,1不显示*/ - private Integer type; - - /**边界*/ - private String communityName; + /**部门全路径*/ + private String namePath; /**边界*/ private String boundary; /** - * 周长 - */ - private Double perimeter; - - /** - * 面积平方公里 - */ - private Double area; - - /** - * 面积亩 - */ - private Double areaMu; - - /** - * 编号 - */ - private String shpNo; - - /** - * 区域类别 + * 区域类别 areaType: 0:市级 1:区级(县) 2:镇级(街道) 3:村级 */ private Integer areaType; + /** + * 父类id + */ + private Long parentId; + /**删除状态(0,正常,1已删除)*/ private String delFlag; - private List deptIds; + @TableField(exist = false) + private List deptIds; } diff --git a/dk-modules/system/src/main/java/org/dromara/system/domain/SysUser.java b/dk-modules/system/src/main/java/org/dromara/system/domain/SysUser.java index 772b505..ed89ba4 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/domain/SysUser.java +++ b/dk-modules/system/src/main/java/org/dromara/system/domain/SysUser.java @@ -98,6 +98,7 @@ public class SysUser extends TenantEntity { */ private Date loginDate; + private Integer noticeType; /** * 备注 */ diff --git a/dk-modules/system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java b/dk-modules/system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java index 2b96210..871e7d1 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java +++ b/dk-modules/system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java @@ -108,6 +108,7 @@ public class SysUserBo extends BaseEntity { */ private String excludeUserIds; + private Integer noticeType; /** * 平台名称 */ diff --git a/dk-modules/system/src/main/java/org/dromara/system/domain/kmz/KmzResult.java b/dk-modules/system/src/main/java/org/dromara/system/domain/kmz/KmzResult.java new file mode 100644 index 0000000..483cc54 --- /dev/null +++ b/dk-modules/system/src/main/java/org/dromara/system/domain/kmz/KmzResult.java @@ -0,0 +1,25 @@ +package org.dromara.system.domain.kmz; + + +import lombok.Data; + +import java.util.Map; + +@Data +public class KmzResult { + + private String name; + + private Map attributes; + + private String wkt; + + public KmzResult(String name, Map attributes, String wkt) { + this.name = name; + this.attributes = attributes; + this.wkt = wkt; + } + + public KmzResult() { + } +} diff --git a/dk-modules/system/src/main/java/org/dromara/system/domain/kmz/Placemark.java b/dk-modules/system/src/main/java/org/dromara/system/domain/kmz/Placemark.java new file mode 100644 index 0000000..021bf2c --- /dev/null +++ b/dk-modules/system/src/main/java/org/dromara/system/domain/kmz/Placemark.java @@ -0,0 +1,15 @@ +package org.dromara.system.domain.kmz; + +import lombok.Data; + +import java.util.Map; + + +@Data +public class Placemark { + + private String name; + private String coordinates; + private Map attributes; + +} diff --git a/dk-modules/system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java b/dk-modules/system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java index 45397be..ef52276 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java +++ b/dk-modules/system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java @@ -47,6 +47,7 @@ public class SysUserVo implements Serializable { * 用户账号 */ private String userName; + private Integer noticeType; /** * 用户昵称 diff --git a/dk-modules/system/src/main/java/org/dromara/system/dubbo/RemoteConfigServiceImpl.java b/dk-modules/system/src/main/java/org/dromara/system/dubbo/RemoteConfigServiceImpl.java index e82b872..8ba79cc 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/dubbo/RemoteConfigServiceImpl.java +++ b/dk-modules/system/src/main/java/org/dromara/system/dubbo/RemoteConfigServiceImpl.java @@ -38,6 +38,11 @@ public class RemoteConfigServiceImpl implements RemoteConfigService { return ip; } + @Override + public boolean selectXingluoAutoSubmit() { + return sysConfigService.selectXingluoAutoSubmit(); + } + // @Override // public List selectStreamType(String deviceSn) { // List list =sysConfigService.selectStreamType(deviceSn); diff --git a/dk-modules/system/src/main/java/org/dromara/system/dubbo/RemoteDeptServiceImpl.java b/dk-modules/system/src/main/java/org/dromara/system/dubbo/RemoteDeptServiceImpl.java index 93de8ac..c9f453c 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/dubbo/RemoteDeptServiceImpl.java +++ b/dk-modules/system/src/main/java/org/dromara/system/dubbo/RemoteDeptServiceImpl.java @@ -50,8 +50,8 @@ public class RemoteDeptServiceImpl implements RemoteDeptService { } @Override - public List> getNamePathList() { - return sysDeptService.getNamePathList(); + public List> getNamePathList(Long deptId) { + return sysDeptService.getNamePathList(deptId); } @Override @@ -66,4 +66,11 @@ public class RemoteDeptServiceImpl implements RemoteDeptService { SysDeptVo sysDeptVo = sysDeptService.getByParentId(deptId); return BeanUtil.copyProperties(sysDeptVo, RemoteDeptVo.class); } + + @Override + public List listTreeDeptByChild(Long deptId) { + List deptVoList = sysDeptService.listTreeDeptByChild(deptId); + + return BeanUtil.copyToList(deptVoList, RemoteDeptVo.class); + } } diff --git a/dk-modules/system/src/main/java/org/dromara/system/dubbo/RemotePostServiceImpl.java b/dk-modules/system/src/main/java/org/dromara/system/dubbo/RemotePostServiceImpl.java index 410a68b..41c4851 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/dubbo/RemotePostServiceImpl.java +++ b/dk-modules/system/src/main/java/org/dromara/system/dubbo/RemotePostServiceImpl.java @@ -41,6 +41,7 @@ public class RemotePostServiceImpl implements RemotePostService { remotePostVo.setPostName(aiLabel.getPostName()); remotePostVo.setPostCode(aiLabel.getPostCode()); remotePostVo.setStatus(aiLabel.getStatus()); + remotePostVo.setPostCategory(aiLabel.getPostCategory()); return remotePostVo; }) .collect(Collectors.toList()); diff --git a/dk-modules/system/src/main/java/org/dromara/system/dubbo/RemoteSubmailConfigServiceImpl.java b/dk-modules/system/src/main/java/org/dromara/system/dubbo/RemoteSubmailConfigServiceImpl.java index e35f1c8..f0f6960 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/dubbo/RemoteSubmailConfigServiceImpl.java +++ b/dk-modules/system/src/main/java/org/dromara/system/dubbo/RemoteSubmailConfigServiceImpl.java @@ -1,17 +1,28 @@ package org.dromara.system.dubbo; -import cn.hutool.core.bean.BeanUtil; + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; import lombok.RequiredArgsConstructor; + import org.apache.dubbo.config.annotation.DubboService; import org.dromara.common.core.domain.R; -import org.dromara.system.api.RemoteClientService; + import org.dromara.system.api.RemoteSubmailConfigService; -import org.dromara.system.api.domain.vo.RemoteClientVo; -import org.dromara.system.domain.vo.SysClientVo; -import org.dromara.system.service.ISysClientService; + +import org.dromara.system.domain.vo.SysUserVo; import org.dromara.system.service.ISysSubmailConfigService; +import org.dromara.system.service.ISysUserService; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + /** * 客户端服务 * @@ -25,6 +36,7 @@ public class RemoteSubmailConfigServiceImpl implements RemoteSubmailConfigServic private final ISysSubmailConfigService sysSubmailConfigService; + private final ISysUserService userService; /** * @@ -36,4 +48,23 @@ public class RemoteSubmailConfigServiceImpl implements RemoteSubmailConfigServic public R remoteCmdSend(String code, String multiParam) { return sysSubmailConfigService.cmdSend(code, multiParam); } + + /** + * 根据部门获取部门下的短信推送人员,进行推送 + * */ + @Override + @Async + public void remoteSend(String code, List> alertList) { + if(!alertList.isEmpty()){ + for (Map map : alertList) { + map.put("createTime",new Date()); + Long deptId = Convert.toLong(map.get("deptId")); + List sysUserVos = userService.selectUserListByDept(Convert.toLong(deptId)); + Set phones = sysUserVos.stream().filter(u -> u.getNoticeType() == 1 && StrUtil.isNotEmpty(u.getPhonenumber())).map(SysUserVo::getPhonenumber).collect(Collectors.toSet()); + sysSubmailConfigService.sendPhone(code,phones, JSON.toJSONString(map)); + } + } + + + } } diff --git a/dk-modules/system/src/main/java/org/dromara/system/mapper/SysDepartBoundaryMapper.java b/dk-modules/system/src/main/java/org/dromara/system/mapper/SysDepartBoundaryMapper.java index 01ed7fd..e075336 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/mapper/SysDepartBoundaryMapper.java +++ b/dk-modules/system/src/main/java/org/dromara/system/mapper/SysDepartBoundaryMapper.java @@ -26,4 +26,5 @@ public interface SysDepartBoundaryMapper extends BaseMapper { String listJson(@Param("deptId") String deptId); + List listDepartBoundaryByLngAndLat(@Param("lng") Double lng,@Param("lat") Double lat); } diff --git a/dk-modules/system/src/main/java/org/dromara/system/mapper/SysDeptMapper.java b/dk-modules/system/src/main/java/org/dromara/system/mapper/SysDeptMapper.java index cd3caaf..a368ea3 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/mapper/SysDeptMapper.java +++ b/dk-modules/system/src/main/java/org/dromara/system/mapper/SysDeptMapper.java @@ -71,7 +71,9 @@ public interface SysDeptMapper extends BaseMapperPlus { }) Page selectPageDeptList(@Param("page") Page page, @Param(Constants.WRAPPER) Wrapper queryWrapper); - List> getNamePathList(); + List> getNamePathList(@Param("deptId") Long deptId); List listTreeDept(@Param("deptId") Long deptId, @Param("tbPrefix") ProjectTablePrefixConfig tbPrefix); + + List listTreeDeptByChild(@Param("deptId") Long deptId); } diff --git a/dk-modules/system/src/main/java/org/dromara/system/service/ISysConfigService.java b/dk-modules/system/src/main/java/org/dromara/system/service/ISysConfigService.java index 981170b..5c7cee9 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/service/ISysConfigService.java +++ b/dk-modules/system/src/main/java/org/dromara/system/service/ISysConfigService.java @@ -88,4 +88,6 @@ public interface ISysConfigService { List selectStreamType(String deviceSn); + boolean selectXingluoAutoSubmit(); + } diff --git a/dk-modules/system/src/main/java/org/dromara/system/service/ISysDepartBoundaryService.java b/dk-modules/system/src/main/java/org/dromara/system/service/ISysDepartBoundaryService.java index 9a4f39d..44861bb 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/service/ISysDepartBoundaryService.java +++ b/dk-modules/system/src/main/java/org/dromara/system/service/ISysDepartBoundaryService.java @@ -20,13 +20,15 @@ public interface ISysDepartBoundaryService extends IService{ List queryByDeptId(String deptId); - boolean uploadShpFile(MultipartFile file,Integer areaType); + boolean uploadShpFile(MultipartFile file,Integer areaType,Long parentId); - boolean deleteDepartBoundary(String id); + boolean deleteDepartBoundary(String deptId); boolean updateDepartBoundary(SysDepartBoundary departBoundary); boolean addDepartBoundary(SysDepartBoundary departBoundary); List listJson(SysDepartBoundary departBoundary); + + List listDepartBoundaryByLngAndLat(Double lng, Double lat); } diff --git a/dk-modules/system/src/main/java/org/dromara/system/service/ISysDeptService.java b/dk-modules/system/src/main/java/org/dromara/system/service/ISysDeptService.java index 8a1aa4f..b259af1 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/service/ISysDeptService.java +++ b/dk-modules/system/src/main/java/org/dromara/system/service/ISysDeptService.java @@ -1,6 +1,7 @@ package org.dromara.system.service; import cn.hutool.core.lang.tree.Tree; +import org.dromara.system.domain.SysDept; import org.dromara.system.domain.bo.SysDeptBo; import org.dromara.system.domain.vo.SysDeptVo; @@ -144,7 +145,7 @@ public interface ISysDeptService { * 查询每个部门的所属的部门全路径 * @return */ - List> getNamePathList(); + List> getNamePathList(Long deptId); /** * 根据父级找子级 @@ -157,4 +158,8 @@ public interface ISysDeptService { SysDeptVo getByParentId(String deptId); List listTreeDept(Long deptId); + + SysDept addBoundaryDept(SysDeptBo sysDeptBo); + + List listTreeDeptByChild(Long deptId); } diff --git a/dk-modules/system/src/main/java/org/dromara/system/service/ISysSubmailConfigService.java b/dk-modules/system/src/main/java/org/dromara/system/service/ISysSubmailConfigService.java index 7ae1f1c..01a7223 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/service/ISysSubmailConfigService.java +++ b/dk-modules/system/src/main/java/org/dromara/system/service/ISysSubmailConfigService.java @@ -10,6 +10,7 @@ import org.dromara.common.mybatis.core.page.PageQuery; import java.util.Collection; import java.util.List; +import java.util.Set; /** * 赛邮服务配置Service接口 @@ -71,5 +72,8 @@ public interface ISysSubmailConfigService { R cmdSend(String code, String multiParam); + R sendPhone(String code,Setphones, String multiParam); + String submailSendUtil(SysSubmailConfigBo bo, List configUserVoList); + String submailSendPhone(SysSubmailConfigBo bo, Set phones); } diff --git a/dk-modules/system/src/main/java/org/dromara/system/service/ISysUserService.java b/dk-modules/system/src/main/java/org/dromara/system/service/ISysUserService.java index 5b188c5..2d0e9e0 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/service/ISysUserService.java +++ b/dk-modules/system/src/main/java/org/dromara/system/service/ISysUserService.java @@ -169,6 +169,7 @@ public interface ISysUserService { * @return 结果 */ int updateUserStatus(Long userId, String status); + int updateUserNoticeType(Long userId, Integer noticeType); /** * 修改用户基本信息 diff --git a/dk-modules/system/src/main/java/org/dromara/system/service/impl/SysConfigServiceImpl.java b/dk-modules/system/src/main/java/org/dromara/system/service/impl/SysConfigServiceImpl.java index e99a3d1..c6f0b78 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/service/impl/SysConfigServiceImpl.java +++ b/dk-modules/system/src/main/java/org/dromara/system/service/impl/SysConfigServiceImpl.java @@ -2,6 +2,7 @@ package org.dromara.system.service.impl; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; import com.baomidou.dynamic.datasource.annotation.DS; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; @@ -219,4 +220,13 @@ public class SysConfigServiceImpl implements ISysConfigService { return collect; } + @Override + public boolean selectXingluoAutoSubmit() { + SysConfig sysConfig = baseMapper.selectOne(new LambdaQueryWrapper().eq(SysConfig::getConfigKey, "xingluo.auto.submit")); + if(ObjectUtil.isNotNull(sysConfig) && ObjectUtil.isNotEmpty(sysConfig.getConfigValue())) { + return StrUtil.equals(sysConfig.getConfigValue(),"true"); + } + return false; + } + } diff --git a/dk-modules/system/src/main/java/org/dromara/system/service/impl/SysDepartBoundaryServiceImpl.java b/dk-modules/system/src/main/java/org/dromara/system/service/impl/SysDepartBoundaryServiceImpl.java index d16ce1d..4256e16 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/service/impl/SysDepartBoundaryServiceImpl.java +++ b/dk-modules/system/src/main/java/org/dromara/system/service/impl/SysDepartBoundaryServiceImpl.java @@ -1,6 +1,7 @@ package org.dromara.system.service.impl; import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -8,13 +9,20 @@ import lombok.RequiredArgsConstructor; import org.apache.dubbo.config.annotation.DubboReference; import org.dromara.system.api.domain.vo.RemoteDeptVo; import org.dromara.system.domain.SysDepartBoundary; +import org.dromara.system.domain.SysDept; import org.dromara.system.domain.SysGeospatialVectors; import org.dromara.system.domain.SysVectorDict; import org.dromara.system.domain.bo.SysDepartBoundaryBo; +import org.dromara.system.domain.bo.SysDeptBo; +import org.dromara.system.domain.kmz.KmzResult; +import org.dromara.system.domain.vo.SysDeptVo; import org.dromara.system.mapper.SysDepartBoundaryMapper; import org.dromara.system.service.ISysDepartBoundaryService; +import org.dromara.system.service.ISysDeptService; import org.dromara.system.service.ISysVectorDictService; import org.dromara.system.utils.BatchProcessorUtil; +import org.dromara.system.utils.KmlParserUtil; +import org.dromara.system.utils.KmzParserUtil; import org.dromara.system.utils.ShpAnalysisUtil; import org.dromara.common.core.exception.ServiceException; import org.dromara.common.mybatis.core.page.PageQuery; @@ -26,10 +34,7 @@ import org.springframework.web.multipart.MultipartFile; import java.io.InputStream; import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; /** @@ -42,11 +47,17 @@ public class SysDepartBoundaryServiceImpl extends ServiceImpl listSysDepartBoundary(PageQuery pageQuery, SysDepartBoundary departBoundary) { + if (ObjectUtil.isNotEmpty(departBoundary.getDeptId())){ + List deptList = deptService.listTreeDept(departBoundary.getDeptId()); + + departBoundary.setDeptIds(deptList.stream().map(SysDeptVo::getDeptId).distinct().toList()); + } + + Page page = baseMapper.listSysDepartBoundary(pageQuery.build(),departBoundary); return TableDataInfo.build(page); @@ -65,12 +76,15 @@ public class SysDepartBoundaryServiceImpl extends ServiceImpl geospatialVectorsList = buildGeospatialVector(file); //6、生成新的对象集合存储数据表中 - List boundaryList = buildBusinessDepartBoundary(geospatialVectorsList,areaType); + List boundaryList = buildBusinessDepartBoundary(geospatialVectorsList,areaType,parentId); + + boundaryList = boundaryList.stream().filter(p-> ObjectUtil.isNotEmpty(p.getBoundary())).toList(); // 分批处理 int startIndex = 0; // 从第 0 条开始 @@ -94,10 +108,35 @@ public class SysDepartBoundaryServiceImpl extends ServiceImpl buildGeospatialVector(MultipartFile file){ List geospatialVectorsList = new ArrayList<>(); try { + + List> mapList = new ArrayList<>(); + //1、首先调用解析工具拿到解析的字段集合 - InputStream inputStream = file.getInputStream(); - List> mapList = ShpAnalysisUtil.analysisShpFile(inputStream); + if (file.getOriginalFilename().endsWith(".zip")) { + + mapList = ShpAnalysisUtil.analysisShpFile(file.getInputStream()); + + } else if (file.getOriginalFilename().endsWith(".kmz") || file.getOriginalFilename().endsWith(".ovkmz")) { + + List kmzResults = KmzParserUtil.parseKmz(file.getInputStream()); + List> kmzList = new ArrayList<>(); + kmzResults.forEach(kmzResult -> { + Map map = new HashMap<>(); + Map attributes = kmzResult.getAttributes(); + if (ObjectUtil.isNotEmpty(attributes)) { + map.putAll(attributes); + } + map.put("O_NAME", kmzResult.getName()); + map.put("the_geom", kmzResult.getWkt()); + kmzList.add(map); + }); + mapList = kmzList; + } else if (file.getOriginalFilename().endsWith(".kml") || file.getOriginalFilename().endsWith(".ovkml")) { + + mapList = KmlParserUtil.parseKml(file.getInputStream()); + + } // 3. 构建字典map List fieldsInfoList = vectorDictService.listVectorField(); @@ -176,33 +215,49 @@ public class SysDepartBoundaryServiceImpl extends ServiceImpl listJson(SysDepartBoundary departBoundary) { - if(StringUtils.isBlank(departBoundary.getDeptId())){ + if(ObjectUtil.isEmpty(departBoundary.getDeptId())){ throw new ServiceException("部门【id】不存在"); } SysDepartBoundaryBo child = new SysDepartBoundaryBo(); child.setDepartId(String.valueOf(departBoundary.getDeptId())); child.setAreaType(SysDepartBoundaryBo.AreaType.DistrictLevel); - child.setLandCategoriesJson(this.baseMapper.listJson(departBoundary.getDeptId())); + child.setLandCategoriesJson(this.baseMapper.listJson(String.valueOf(departBoundary.getDeptId()))); - RemoteDeptVo remoteDeptVo = remoteDeptService.getByParentId(departBoundary.getDeptId()); + SysDeptVo sysDeptVo = deptService.getByParentId(String.valueOf(departBoundary.getDeptId())); SysDepartBoundaryBo parent = new SysDepartBoundaryBo(); - parent.setDepartId(String.valueOf(remoteDeptVo.getDeptId())); + parent.setDepartId(String.valueOf(sysDeptVo.getDeptId())); parent.setAreaType(SysDepartBoundaryBo.AreaType.Municipal); - parent.setLandCategoriesJson(this.baseMapper.listJson(String.valueOf(remoteDeptVo.getDeptId()))); + parent.setLandCategoriesJson(this.baseMapper.listJson(String.valueOf(sysDeptVo.getDeptId()))); return List.of(child,parent); } + /** + * 根据经纬度查询部门信息 + * @param lng + * @param lat + * @return + */ + @Override + public List listDepartBoundaryByLngAndLat(Double lng, Double lat) { + + return this.baseMapper.listDepartBoundaryByLngAndLat(lng,lat); + } + @Override - public boolean deleteDepartBoundary(String id) { - SysDepartBoundary departBoundary = this.baseMapper.selectById(id); + public boolean deleteDepartBoundary(String deptId) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(SysDepartBoundary::getDeptId,deptId); + + List sysDepartBoundaries = this.baseMapper.selectList(wrapper); - if (ObjectUtil.isEmpty(departBoundary)) { + if (ObjectUtil.isEmpty(sysDepartBoundaries)) { throw new ServiceException("实体不存在!"); } - return this.baseMapper.deleteById(departBoundary.getId())>0; + + return this.baseMapper.deleteByIds(sysDepartBoundaries.stream().map(SysDepartBoundary::getId).distinct().toList())>0; } @@ -211,33 +266,88 @@ public class SysDepartBoundaryServiceImpl extends ServiceImpl buildBusinessDepartBoundary(List geospatialVectorsList, Integer areaType) { + private List buildBusinessDepartBoundary(List geospatialVectorsList, Integer areaType,Long parentId) { List resultList = new ArrayList<>(); - List> namePathList = remoteDeptService.getNamePathList(); + List> namePathList = deptService.getNamePathList(null); - Map>> namePathMap = namePathList.stream() + Map>> namePathMap = namePathList.stream().filter(p-> Long.valueOf(p.get("parentId").toString()).equals(parentId)) .collect(Collectors.groupingBy(item -> item.get("deptName").toString())); geospatialVectorsList.forEach(param->{ - SysDepartBoundary businessDepartBoundary = new SysDepartBoundary(); //获取区划名称 String divisionName = param.getAdminDivisionName(); - businessDepartBoundary.setBoundary(param.getLandCategories()); - if (ObjectUtil.isNotEmpty(namePathMap.get(divisionName))){ - Map objectMap = namePathMap.get(divisionName).get(0); - businessDepartBoundary.setShpNo(ObjectUtil.isEmpty(objectMap.get("shpNo"))?null:(String)objectMap.get("shpNo")); - businessDepartBoundary.setDeptName(objectMap.get("deptName") + ""); - businessDepartBoundary.setDeptId(objectMap.get("deptId") + ""); - businessDepartBoundary.setCommunityName(objectMap.get("namePath") + ""); - businessDepartBoundary.setAreaType(areaType); + //是集合 + if (isCollectionString(param.getLandCategories())){ + List geomList = convertStringToList(param.getLandCategories()); + + geomList.forEach(item->{ + SysDepartBoundary businessDepartBoundary = new SysDepartBoundary(); + + businessDepartBoundary.setBoundary(item); + + createBoundary(businessDepartBoundary,namePathMap,divisionName,areaType,parentId); + + resultList.add(businessDepartBoundary); + }); + + }else { + SysDepartBoundary businessDepartBoundary = new SysDepartBoundary(); + + businessDepartBoundary.setBoundary(param.getLandCategories()); + + createBoundary(businessDepartBoundary,namePathMap,divisionName,areaType,parentId); + resultList.add(businessDepartBoundary); } }); return resultList; } + private void createBoundary(SysDepartBoundary businessDepartBoundary, Map>> namePathMap, String divisionName, Integer areaType, Long parentId) { + businessDepartBoundary.setParentId(parentId); + //判断是否存在表中,在表中更新部门区域中的部门id信息 + if (ObjectUtil.isNotEmpty(namePathMap.get(divisionName))){ + Map objectMap = namePathMap.get(divisionName).get(0); + businessDepartBoundary.setDeptName(objectMap.get("deptName") + ""); + businessDepartBoundary.setDeptId(Long.valueOf(objectMap.get("deptId") + "")); + businessDepartBoundary.setNamePath(objectMap.get("namePath") + ""); + businessDepartBoundary.setAreaType(areaType); + }else { + //如果不存在在部门表中则添加 + SysDeptBo sysDeptBo = new SysDeptBo(); + sysDeptBo.setParentId(parentId); + sysDeptBo.setDeptName(divisionName); + + SysDept sysDept = deptService.addBoundaryDept(sysDeptBo); + + List> deptNamePath = deptService.getNamePathList(sysDept.getDeptId()); + + businessDepartBoundary.setDeptName(sysDept.getDeptName()); + businessDepartBoundary.setDeptId(sysDept.getDeptId()); + businessDepartBoundary.setNamePath(deptNamePath.getFirst().get("namePath").toString()); + businessDepartBoundary.setAreaType(areaType); + } + } + + + public static List convertStringToList(String str) { + // 去除首尾的 "[" 和 "]" + str = str.substring(1, str.length() - 1); + + // 使用逗号分割 + String[] items = str.split(", "); + + // 返回新的 List + return Arrays.asList(items); + } + + // 判断字符串是否是集合的字符串形式 + public static boolean isCollectionString(String str) { + return str != null && str.startsWith("[") && str.endsWith("]") && str.contains(","); + } + private static String capitalizeFirstLetter(String str) { if (str == null || str.isEmpty()) { diff --git a/dk-modules/system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java b/dk-modules/system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java index fc6b37e..78e5813 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java +++ b/dk-modules/system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java @@ -365,8 +365,8 @@ public class SysDeptServiceImpl implements ISysDeptService { @Override - public List> getNamePathList() { - return baseMapper.getNamePathList(); + public List> getNamePathList(Long deptId) { + return baseMapper.getNamePathList(deptId); } @Override @@ -392,4 +392,24 @@ public class SysDeptServiceImpl implements ISysDeptService { return baseMapper.listTreeDept(deptId, ptPrefix); //.getTableCloud() } + @Override + public SysDept addBoundaryDept(SysDeptBo bo) { + SysDept info = baseMapper.selectById(bo.getParentId()); + // 如果父节点不为正常状态,则不允许新增子节点 + if (!UserConstants.DEPT_NORMAL.equals(info.getStatus())) { + throw new ServiceException("部门停用,不允许新增"); + } + SysDept dept = MapstructUtils.convert(bo, SysDept.class); + dept.setAncestors(info.getAncestors() + StringUtils.SEPARATOR + dept.getParentId()); + + baseMapper.insert(dept); + + return dept; + } + + @Override + public List listTreeDeptByChild(Long deptId) { + return baseMapper.listTreeDeptByChild(deptId); //.getTableCloud() + } + } diff --git a/dk-modules/system/src/main/java/org/dromara/system/service/impl/SysSubmailConfigServiceImpl.java b/dk-modules/system/src/main/java/org/dromara/system/service/impl/SysSubmailConfigServiceImpl.java index c5d9894..5bed240 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/service/impl/SysSubmailConfigServiceImpl.java +++ b/dk-modules/system/src/main/java/org/dromara/system/service/impl/SysSubmailConfigServiceImpl.java @@ -32,10 +32,7 @@ import org.dromara.system.domain.SysSubmailConfig; import org.dromara.system.mapper.SysSubmailConfigMapper; import org.dromara.system.service.ISysSubmailConfigService; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Collection; +import java.util.*; import java.util.stream.Collectors; /** @@ -189,6 +186,75 @@ public class SysSubmailConfigServiceImpl implements ISysSubmailConfigService { return R.ok(result); } + @Override + public R sendPhone(String code, Set phones, String multiParam) { + //找到生效配置 + SysSubmailConfigBo bo = new SysSubmailConfigBo(); + bo.setCode(code); + List sysSubmailConfigVoTempList = this.queryList(bo); + if (sysSubmailConfigVoTempList.size() <= 0) { + return R.fail("暂无有效配置"); + } + SysSubmailConfigVo firstConfigVo = sysSubmailConfigVoTempList.get(0); + + BeanUtil.copyProperties(firstConfigVo,bo); + bo.setMultiParam(multiParam); + + String result = submailSendPhone(bo,phones); + return R.ok(result); + } + public String submailSendPhone(SysSubmailConfigBo bo, Set phones) { + if(!phones.isEmpty()){ + String subMailSaveFlag = SpringUtils.getBean(ISysConfigService.class).selectConfigByKey("submail.log.save"); + HashMap postParam = new HashMap<>(); + postParam.put("appid", bo.getAppid()); + postParam.put("signature", bo.getSignature()); + + String phonenumber =String.join(",", phones);; + String result = ""; + switch (bo.getCode()){ + case "smsSend": //短信发送 to/content + postParam.put("to", phonenumber); + postParam.put("content", bo.getContent()); + result = HttpUtil.post(bo.getUrl(), postParam); //JSONUtil.parseObj(result).getStr("status") + saveConfigLog(bo, subMailSaveFlag, phonenumber, result); + break; + case "smsXsend": //短信模板发送 to/project + postParam.put("to", phonenumber); + postParam.put("project", bo.getProject()); + postParam.put("vars", bo.getVars()); + result = HttpUtil.post(bo.getUrl(), postParam); + saveConfigLog(bo, subMailSaveFlag, phonenumber, result); + break; + case "smsMultisend": //短信一对多发送 multi +// postParam.put("to", phonenumber); +// postParam.put("project", bo.getProject()); +// postParam.put("vars", bo.getVars()); +// result = HttpUtil.post(bo.getUrl(), postParam); +// saveConfigLog(bo, subMailSaveFlag, phonenumber, result); + break; + case "smsMultixsend": //短信模板一对多发送 project/multi + postParam.put("to", phonenumber); + postParam.put("project", bo.getProject()); +// 拼接multi + JSONArray multiJson = new JSONArray(); + for (String phone : phones) { + JSONObject entries = new JSONObject(); + entries.set("to",phone); + entries.set("vars", JSONUtil.parseObj(bo.getMultiParam())); + multiJson.add(entries); + } + String multiJsonStr = multiJson.toString(); +// postParam.put("multi", multiJson.toString()); + postParam.put("multi", multiJsonStr); + result = HttpUtil.post(bo.getUrl(), postParam); + saveConfigLog(bo, subMailSaveFlag, phonenumber, result); + break; + } + return result; + } + return null; + } public String submailSendUtil(SysSubmailConfigBo bo, List configUserVoList) { String subMailSaveFlag = SpringUtils.getBean(ISysConfigService.class).selectConfigByKey("submail.log.save"); HashMap postParam = new HashMap<>(); diff --git a/dk-modules/system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java b/dk-modules/system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java index 8849a41..54b5d6a 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java +++ b/dk-modules/system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java @@ -376,6 +376,14 @@ public class SysUserServiceImpl implements ISysUserService { .eq(SysUser::getUserId, userId)); } + @Override + public int updateUserNoticeType(Long userId, Integer noticeType) { + return baseMapper.update(null, + new LambdaUpdateWrapper() + .set(SysUser::getNoticeType, noticeType) + .eq(SysUser::getUserId, userId)); + } + /** * 修改用户基本信息 * diff --git a/dk-modules/system/src/main/java/org/dromara/system/utils/KmlParserUtil.java b/dk-modules/system/src/main/java/org/dromara/system/utils/KmlParserUtil.java new file mode 100644 index 0000000..4cea698 --- /dev/null +++ b/dk-modules/system/src/main/java/org/dromara/system/utils/KmlParserUtil.java @@ -0,0 +1,140 @@ +package org.dromara.system.utils; + +import cn.hutool.core.util.ObjectUtil; + +import java.io.*; +import java.util.*; + +/** + * KML文件解析器 + * KML是Google Earth使用的标记语言格式 + */ +public class KmlParserUtil { + + /** + * 从KML内容中提取所有Placemark数据 + * + * @param kmlContent KML内容 + * @return 包含name和coordinates的Map列表 + */ + public static List> extractPlacemarks(String kmlContent) { + List> placemarkList = new ArrayList<>(); + int startIndex = 0; + + while (true) { + // 查找Placemark开始标签 + int startPlacemark = kmlContent.indexOf("", startIndex); + if (startPlacemark == -1) { + break; + } + + // 查找Placemark结束标签 + int endPlacemark = kmlContent.indexOf("", startPlacemark); + if (endPlacemark == -1) { + break; + } + + // 提取当前Placemark的内容 + String placemarkContent = kmlContent.substring(startPlacemark, endPlacemark + "".length()); + + // 提取name + String name = ""; + int nameStart = placemarkContent.indexOf(""); + int nameEnd = placemarkContent.indexOf(""); + if (nameStart != -1 && nameEnd != -1) { + name = placemarkContent.substring(nameStart + "".length(), nameEnd).trim(); + } + + // 提取coordinates + String coordinates = ""; + int coordStart = placemarkContent.indexOf(""); + int coordEnd = placemarkContent.indexOf(""); + if (coordStart != -1 && coordEnd != -1) { + coordinates = placemarkContent.substring(coordStart + "".length(), coordEnd).trim(); + } + + //提取 + if (ObjectUtil.isEmpty(name)){ + int dataStart = placemarkContent.indexOf("Data name =\"name\""); + if (dataStart != -1) { + int valueStart = placemarkContent.indexOf("", dataStart); + int valueEnd = placemarkContent.indexOf("", valueStart); + if (valueStart != -1 && valueEnd != -1) { + name = placemarkContent.substring(valueStart + "".length(), valueEnd).trim(); + } + } + } + + + // 创建Map并添加到列表 + Map placemarkMap = new HashMap<>(); + placemarkMap.put("O_NAME", name); + + String wkt = convertToWKT(coordinates); + + placemarkMap.put("the_geom", wkt); + + placemarkList.add(placemarkMap); + + // 更新搜索起始位置 + startIndex = endPlacemark + "".length(); + } + + return placemarkList; + } + + /** + * 将坐标字符串转换为WKT(Well-Known Text)格式 + * + * @param coordinates 坐标字符串 + * @return WKT格式的字符串 + */ + public static String convertToWKT(String coordinates) { + if (coordinates == null || coordinates.trim().isEmpty()) { + return ""; + } + + // 构建WKT格式的多边形 + StringBuilder wkt = new StringBuilder("POLYGON(("); + String[] coordPairs = coordinates.trim().split("\\s+"); + + // 处理每个坐标对 + for (int i = 0; i < coordPairs.length; i++) { + String[] coords = coordPairs[i].split(","); + if (coords.length >= 2) { + wkt.append(coords[0]).append(" ").append(coords[1]); + if (i < coordPairs.length - 1) { + wkt.append(", "); + } + } + } + + wkt.append("))"); + + StringBuffer polygonSb = new StringBuffer("GEOMETRYCOLLECTION("); + polygonSb.append(wkt); + polygonSb.append(")"); + + return polygonSb.toString(); + } + + /** + * 解析KML文件的主方法 + * + * @param inputStream KML文件的输入流 + * @return 包含name和coordinates的Map列表 + * @throws IOException 如果文件读取或处理过程中发生错误 + */ + public static List> parseKml(InputStream inputStream) throws IOException { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) { + StringBuilder kmlContent = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + kmlContent.append(line).append("\n"); + } + return extractPlacemarks(kmlContent.toString()); + } + } +} + + diff --git a/dk-modules/system/src/main/java/org/dromara/system/utils/KmzParserUtil.java b/dk-modules/system/src/main/java/org/dromara/system/utils/KmzParserUtil.java new file mode 100644 index 0000000..e7af342 --- /dev/null +++ b/dk-modules/system/src/main/java/org/dromara/system/utils/KmzParserUtil.java @@ -0,0 +1,262 @@ +package org.dromara.system.utils; + +import cn.hutool.core.util.ObjectUtil; +import org.dromara.system.domain.kmz.KmzResult; +import org.dromara.system.domain.kmz.Placemark; + +import java.io.*; +import java.nio.file.*; +import java.util.*; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +/** + * KMZ文件解析器 + * KMZ是Google Earth使用的压缩格式,包含KML文件和其他资源 + */ +public class KmzParserUtil { + + /** + * 解析KMZ文件的主方法 + * + * @param inputStream KMZ文件的路径 + * @return 解析结果列表 + * @throws IOException 如果文件读取或处理过程中发生错误 + */ + public static List parseKmz(InputStream inputStream) throws IOException { + // 存储解析出的地标信息 + List placemarks = new ArrayList<>(); + // 存储最终结果 + List results = new ArrayList<>(); + + // 创建临时目录用于解压KMZ文件 + Path tempDir = Files.createTempDirectory("kmz_parser_"); + try { + // 将KMZ文件解压到临时目录 + extractKmz(inputStream, tempDir.toString()); + + // 遍历临时目录,查找并解析所有KML文件 + Files.walk(tempDir) + .filter(path -> path.toString().endsWith(".kml")) + .forEach(path -> { + try { + String kmlContent = new String(Files.readAllBytes(path)); + parseKmlContent(kmlContent, placemarks); + } catch (IOException e) { + e.printStackTrace(); + } + }); + + // 将解析出的地标信息转换为最终结果格式 + for (Placemark placemark : placemarks) { + String wkt = convertToWKT(placemark.getCoordinates()); + results.add(new KmzResult(placemark.getName(), placemark.getAttributes(), wkt)); + } + + } finally { + // 清理临时目录 + deleteDirectory(tempDir); + } + + return results; + } + + /** + * 解压KMZ文件到指定目录 + * + * @param inputStream KMZ文件路径 + * @param outputDir 输出目录 + */ + private static void extractKmz(InputStream inputStream, String outputDir) throws IOException { + try (ZipInputStream zis = new ZipInputStream(inputStream)) { + ZipEntry entry; + while ((entry = zis.getNextEntry()) != null) { + Path outputPath = Paths.get(outputDir, entry.getName()); + + // 创建必要的父目录 + Files.createDirectories(outputPath.getParent()); + + // 跳过目录条目 + if (entry.isDirectory()) { + continue; + } + + // 解压文件内容 + try (OutputStream out = Files.newOutputStream(outputPath)) { + byte[] buffer = new byte[1024]; + int len; + while ((len = zis.read(buffer)) > 0) { + out.write(buffer, 0, len); + } + } + } + } + } + + /** + * 递归删除目录及其内容 + * + * @param directory 要删除的目录 + */ + private static void deleteDirectory(Path directory) throws IOException { + Files.walk(directory) + .sorted(Comparator.reverseOrder()) + .forEach(path -> { + try { + Files.delete(path); + } catch (IOException e) { + e.printStackTrace(); + } + }); + } + + /** + * 处理当前Placemark的所有坐标,为每个坐标创建新的Placemark对象 + * + * @param currentPlacemark 当前Placemark对象 + * @param currentCoordinates 当前Placemark的所有坐标 + * @param placemarks 存储所有Placemark的列表 + */ + private static void processCurrentPlacemarkCoordinates(Placemark currentPlacemark, List currentCoordinates, List placemarks) { + if (currentPlacemark != null && !currentCoordinates.isEmpty()) { + for (String coords : currentCoordinates) { + Placemark newPlacemark = new Placemark(); + newPlacemark.setName(currentPlacemark.getName()); + if (ObjectUtil.isNotEmpty(currentPlacemark.getAttributes())){ + newPlacemark.setAttributes(new HashMap<>(currentPlacemark.getAttributes())); + } + newPlacemark.setCoordinates(coords); + placemarks.add(newPlacemark); + } + } + } + + /** + * 解析KML文件内容 + * + * @param kmlContent KML文件内容 + * @param placemarks 存储解析出的地标信息 + */ + private static void parseKmlContent(String kmlContent, List placemarks) { + String[] lines = kmlContent.split("\n"); + Placemark currentPlacemark = null; + boolean inDescription = false; + StringBuilder descriptionContent = new StringBuilder(); + List currentCoordinates = new ArrayList<>(); + + // 添加调试日志 + System.out.println("开始解析KML内容,总行数: " + lines.length); + + for (String line : lines) { + line = line.trim(); + + if (line.startsWith("")) { + // 处理当前Placemark的所有坐标 + processCurrentPlacemarkCoordinates(currentPlacemark, currentCoordinates, placemarks); + currentPlacemark = new Placemark(); + currentCoordinates = new ArrayList<>(); + System.out.println("发现新的Placemark"); + } else if (line.startsWith("")) { + if (currentPlacemark != null) { + String name = line.replace("", "").replace("", "").trim(); + currentPlacemark.setName(name); + System.out.println("解析到名称: " + name); + } + } else if (line.startsWith("")) { + inDescription = true; + descriptionContent = new StringBuilder(); + System.out.println("开始解析描述"); + } else if (line.endsWith("")) { + inDescription = false; + if (currentPlacemark != null) { + String desc = descriptionContent.toString(); + System.out.println("描述内容: " + desc); + parseDescription(desc, currentPlacemark); + } + } else if (inDescription) { + descriptionContent.append(line).append("\n"); + } else if (line.startsWith("")) { + if (currentPlacemark != null) { + String coords = line.replace("", "").replace("", "").trim(); + currentCoordinates.add(coords); + System.out.println("解析到坐标: " + coords); + } + } + } + + // 处理最后一个Placemark + processCurrentPlacemarkCoordinates(currentPlacemark, currentCoordinates, placemarks); + + // 打印解析结果 + System.out.println("解析完成,共找到 " + placemarks.size() + " 个地标"); + for (Placemark p : placemarks) { + System.out.println("地标信息:"); + System.out.println(" 名称: " + p.getName()); + System.out.println(" 属性: " + p.getAttributes()); + System.out.println(" 坐标: " + p.getCoordinates()); + } + } + + /** + * 解析描述内容,提取属性信息 + * + * @param description 描述内容 + * @param placemark 地标对象 + */ + private static void parseDescription(String description, Placemark placemark) { + System.out.println("开始解析描述内容: " + description); + String[] lines = description.split("\n"); + Map attributes = new HashMap<>(); + for (String line : lines) { + line = line.trim(); + if (line.contains("\":")) { + String[] parts = line.split("\":"); + if (parts.length == 2) { + String key = parts[0].replace("\"", "").trim(); + String value = parts[1].replace("\"", "").trim(); + attributes.put(key, value); + System.out.println("解析到属性 - 键: " + key + ", 值: " + value); + } + } + } + + placemark.setAttributes(attributes); + } + + /** + * 将坐标字符串转换为WKT(Well-Known Text)格式 + * + * @param coordinates 坐标字符串 + * @return WKT格式的字符串 + */ + public static String convertToWKT(String coordinates) { + if (coordinates == null || coordinates.trim().isEmpty()) { + return ""; + } + + // 构建WKT格式的多边形 + StringBuilder wkt = new StringBuilder("POLYGON(("); + String[] coordPairs = coordinates.trim().split("\\s+"); + + // 处理每个坐标对 + for (int i = 0; i < coordPairs.length; i++) { + String[] coords = coordPairs[i].split(","); + if (coords.length >= 2) { + wkt.append(coords[0]).append(" ").append(coords[1]); + if (i < coordPairs.length - 1) { + wkt.append(", "); + } + } + } + + wkt.append("))"); + + StringBuffer polygonSb = new StringBuffer("GEOMETRYCOLLECTION("); + polygonSb.append(wkt); + polygonSb.append(")"); + + return polygonSb.toString(); + } +} + + diff --git a/dk-modules/system/src/main/java/org/dromara/system/utils/OssTianyiClientUtils.java b/dk-modules/system/src/main/java/org/dromara/system/utils/OssTianyiClientUtils.java index 9c557e8..6ea15ae 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/utils/OssTianyiClientUtils.java +++ b/dk-modules/system/src/main/java/org/dromara/system/utils/OssTianyiClientUtils.java @@ -121,7 +121,7 @@ public class OssTianyiClientUtils { .build() ); } catch (Exception e) { - throw new RuntimeException(e); + e.printStackTrace(); } // FileUtil.writeFromStream(inputStream, new File(downloadPath)); return inputStream; diff --git a/dk-modules/system/src/main/java/org/dromara/system/utils/ShpAnalysisUtil.java b/dk-modules/system/src/main/java/org/dromara/system/utils/ShpAnalysisUtil.java index e2a384e..cbef891 100644 --- a/dk-modules/system/src/main/java/org/dromara/system/utils/ShpAnalysisUtil.java +++ b/dk-modules/system/src/main/java/org/dromara/system/utils/ShpAnalysisUtil.java @@ -45,6 +45,7 @@ public class ShpAnalysisUtil { /** * 读取shp文件,返回要素集合 + * * @param shpPath shp文件路径 * @return 要素集合,包含地理位置和属性信息 */ @@ -52,7 +53,7 @@ public class ShpAnalysisUtil { List> resultList = new ArrayList<>(); try { - resultList=analysisShpFile(shpPath, "GBK"); + resultList = analysisShpFile(shpPath, "GBK"); } catch (Exception e) { log.error("无法使用支持的字符编码读取shp文件: {}", e.getMessage()); } @@ -62,6 +63,7 @@ public class ShpAnalysisUtil { /** * 读取shp文件,返回要素集合 + * * @param shpInputStream shp文件输入流 * @return 要素集合,包含地理位置和属性信息 */ @@ -81,7 +83,7 @@ public class ShpAnalysisUtil { * 读取shp文件的主要方法(仅支持ZIP输入流) * * @param shpInputStream shp文件ZIP输入流 - * @param charset 字符编码 + * @param charset 字符编码 * @return 要素集合,包含地理位置和属性信息 * @throws IllegalArgumentException 如果输入流不是ZIP格式 */ @@ -102,7 +104,7 @@ public class ShpAnalysisUtil { boolean shpFound = false; while ((entry = zipInputStream.getNextEntry()) != null) { // 处理文件名编码问题 - log.info("文件名字:{}",entry.getName()); + log.info("文件名字:{}", entry.getName()); File outputFile = new File(tempDir, entry.getName()); // 创建父目录 @@ -296,22 +298,25 @@ public class ShpAnalysisUtil { } - private static String analysisGeometry(Geometry geometry, MathTransform transform) throws TransformException { - String resultStr = ""; + private static Object analysisGeometry(Geometry geometry, MathTransform transform) throws TransformException { // 对每个 Polygon 进行坐标转换 Geometry transformedGeometry = JTS.transform(geometry, transform); MultiPolygon multiPolygon = (MultiPolygon) transformedGeometry; Geometry unionGeometry = UnaryUnionOp.union(multiPolygon); if (unionGeometry instanceof Polygon) { Polygon polygon = (Polygon) unionGeometry; - resultStr = convertPolygonToWKT(polygon); + return convertPolygonToWKT(polygon); + + } else if (unionGeometry instanceof MultiPolygon) { + MultiPolygon muPolygon = (MultiPolygon) unionGeometry; + + return convertMultiPolygonToWKT(muPolygon); } - return resultStr; + return ""; } - private static String convertPolygonToWKT(Polygon polygon) { StringBuffer polygonSb = new StringBuffer("GEOMETRYCOLLECTION(POLYGON(("); @@ -321,16 +326,45 @@ public class ShpAnalysisUtil { if (i > 0) polygonSb.append(","); polygonSb.append(coord.y + " " + coord.x); } - if(coordinates[0].x !=coordinates[coordinates.length-1].x){ - polygonSb.append(","+coordinates[0].y + " " + coordinates[0].x); + if (coordinates[0].x != coordinates[coordinates.length - 1].x) { + polygonSb.append("," + coordinates[0].y + " " + coordinates[0].x); } polygonSb.append(")))"); return polygonSb.toString(); } + private static List convertMultiPolygonToWKT(MultiPolygon multiPolygon) { + + List resultList = new ArrayList<>(); + + // 获取 MultiPolygon 中的每个 Polygon + for (int j = 0; j < multiPolygon.getNumGeometries(); j++) { + Polygon polygon = (Polygon) multiPolygon.getGeometryN(j); + + StringBuffer polygonSb = new StringBuffer("GEOMETRYCOLLECTION(POLYGON(("); + + Coordinate[] coordinates = polygon.getCoordinates(); + for (int i = 0; i < coordinates.length; i++) { + Coordinate coord = coordinates[i]; + if (i > 0) polygonSb.append(","); + polygonSb.append(coord.y + " " + coord.x); + } + if (coordinates[0].x != coordinates[coordinates.length - 1].x) { + polygonSb.append("," + coordinates[0].y + " " + coordinates[0].x); + } + polygonSb.append(")))"); + + resultList.add(polygonSb.toString()); + } + + return resultList; + + } + /** * 递归删除目录 + * * @param directory 要删除的目录 */ private static void deleteDirectory(File directory) { @@ -356,6 +390,7 @@ public class ShpAnalysisUtil { /** * 在指定目录中查找第一个.shp文件 + * * @param directory 搜索目录 * @return 找到的第一个.shp文件,未找到返回null */ diff --git a/dk-modules/system/src/main/resources/mapper/system/SysDepartBoundaryMapper.xml b/dk-modules/system/src/main/resources/mapper/system/SysDepartBoundaryMapper.xml index 9d2a302..9c87bd2 100644 --- a/dk-modules/system/src/main/resources/mapper/system/SysDepartBoundaryMapper.xml +++ b/dk-modules/system/src/main/resources/mapper/system/SysDepartBoundaryMapper.xml @@ -3,28 +3,61 @@ @@ -33,8 +66,8 @@ db.id, db.dept_id, db.dept_name, - db.type, - db.community_name, + db.area_type, + db.name_path, CONCAT( REPLACE ( REPLACE ( REPLACE ( REPLACE ( ST_AsText ( db.boundary ), 'GEOMETRYCOLLECTION(POLYGON((', '[[' ), ')))', ']]' ), ',', '],[' ), ' ', ',' ) ) AS boundary, @@ -62,8 +95,8 @@ db.id, db.dept_id, db.dept_name, - db.type, - db.community_name, + db.area_type, + db.name_path, CONCAT( REPLACE ( REPLACE ( REPLACE ( REPLACE ( ST_AsText ( db.boundary ), 'GEOMETRYCOLLECTION(POLYGON((', '[[' ), ')))', ']]' ), ',', '],[' ), ' ', ',' ) ) AS boundary, @@ -79,13 +112,10 @@ INSERT INTO sys_depart_boundary ( dept_id, dept_name, - community_name, + name_path, boundary, - perimeter, - area, - area_mu, - shp_no, - village_type, + area_type, + parent_id, create_by, create_time, update_by, @@ -96,13 +126,10 @@ (#{item.deptId}, #{item.deptName}, - #{item.communityName}, + #{item.namePath}, ST_GeomFromText(#{item.boundary}), - #{item.perimeter}, - #{item.area}, - #{item.areaMu}, - #{item.shpNo}, - #{item.villageType}, + #{item.areaType}, + #{item.parentId}, #{item.createBy}, #{item.createTime}, #{item.updateBy}, @@ -126,9 +153,8 @@ JSON_OBJECT( 'deptId', l.dept_id, 'deptName', l.dept_name, - 'adcode', l.shp_no, - 'name', l.community_name, - 'community_name', l.community_name + 'name', l.name_path, + 'community_name', l.name_path ), 'geometry', ST_AsGeoJSON(l.boundary) @@ -144,4 +170,17 @@ d.dept_id = #{deptId} + + diff --git a/dk-modules/system/src/main/resources/mapper/system/SysDeptMapper.xml b/dk-modules/system/src/main/resources/mapper/system/SysDeptMapper.xml index a0af8f3..bbb8d7c 100644 --- a/dk-modules/system/src/main/resources/mapper/system/SysDeptMapper.xml +++ b/dk-modules/system/src/main/resources/mapper/system/SysDeptMapper.xml @@ -52,7 +52,8 @@ sd.dept_name deptName, CAST(sd.dept_name AS CHAR(500)) AS namePath, sd.shp_no shpNo, - sd.tenant_id + sd.tenant_id, + sd.parent_id FROM sys_dept sd WHERE @@ -66,7 +67,8 @@ d.dept_name deptName, CONCAT(dp.namePath, '', d.dept_name) AS namePath, d.shp_no shpNo, - d.tenant_id + d.tenant_id, + d.parent_id FROM sys_dept d INNER JOIN @@ -77,9 +79,15 @@ namePath, shpNo, deptName, - tenant_id + tenant_id, + parent_id parentId FROM - DeptPath + DeptPath dp + + + dp.deptId = #{deptId} + + ORDER BY deptId @@ -104,4 +112,34 @@ )select * from warning_summary + + + diff --git a/dk-modules/system/src/main/resources/mapper/system/SysUserMapper.xml b/dk-modules/system/src/main/resources/mapper/system/SysUserMapper.xml index 4b35648..2e482a2 100644 --- a/dk-modules/system/src/main/resources/mapper/system/SysUserMapper.xml +++ b/dk-modules/system/src/main/resources/mapper/system/SysUserMapper.xml @@ -17,7 +17,7 @@ ${ew.getSqlSelect} - u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex, + u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex,u.notice_type, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,u.product_name from sys_user u diff --git a/dk-modules/workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java b/dk-modules/workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java index f705e55..d8d4e04 100644 --- a/dk-modules/workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java +++ b/dk-modules/workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java @@ -222,8 +222,8 @@ public class FlwTaskServiceImpl implements IFlwTaskService { return String.valueOf(ins.getId()); } catch (Exception e) { log.error(e.getMessage(), e); - throw new ServiceException(e.getMessage()); } + return ""; } /** @@ -953,13 +953,12 @@ public class FlwTaskServiceImpl implements IFlwTaskService { flwTaskService.taskOperation(taskOperationBo,"addSignature"); } - return true; } catch (Exception e) { - e.printStackTrace(); log.error(e.getMessage(), e); - return false; } + + return true; } } diff --git a/dk-visual/nacos/src/main/resources/application.properties b/dk-visual/nacos/src/main/resources/application.properties index 44fe8a3..972740f 100644 --- a/dk-visual/nacos/src/main/resources/application.properties +++ b/dk-visual/nacos/src/main/resources/application.properties @@ -40,9 +40,9 @@ spring.sql.init.platform=mysql db.num=1 ### Connect URL of DB: -db.url.0=jdbc:mysql://114.235.183.147:3306/dk_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true +db.url.0=jdbc:mysql://127.0.0.1:3306/dk_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true db.user.0=root -db.password.0=dkcy@yf +db.password.0=123456 ### the maximum retry times for push nacos.config.push.maxRetryTime=50