diff --git a/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/UserInfo.java b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/UserInfo.java index 7c9b77e..97aaa48 100644 --- a/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/UserInfo.java +++ b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/UserInfo.java @@ -43,7 +43,7 @@ public class UserInfo extends TenantModel implements Id, Serializable { public static final int USER_TYPE_CLIENT = 1; private Long id; - + private Long tenantId; /** * 用户账号 */ @@ -82,7 +82,7 @@ public class UserInfo extends TenantModel implements Id, Serializable { * 当前家庭Id */ private String currHomeId; - + private Long deptAreaId; /** * 用户类型 * 0:平台用户 @@ -108,5 +108,5 @@ public class UserInfo extends TenantModel implements Id, Serializable { * 见:Constants.THIRD_PLAT */ private List usePlatforms = new ArrayList<>(); - + private List deptAreaIds = new ArrayList<>(); } diff --git a/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/alert/AlertConfig.java b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/alert/AlertConfig.java index 5e018a1..4d12554 100644 --- a/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/alert/AlertConfig.java +++ b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/alert/AlertConfig.java @@ -83,5 +83,6 @@ public class AlertConfig extends TenantModel implements Owned { * 0短信1微信小程序推送2语音,数据用,隔开 */ private String messagePush; - + private String messagePushIpone; + private String deviceName; } diff --git a/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/alert/AlertRecord.java b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/alert/AlertRecord.java index 420b9e0..6a92b7a 100644 --- a/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/alert/AlertRecord.java +++ b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/alert/AlertRecord.java @@ -72,11 +72,13 @@ public class AlertRecord extends TenantModel implements Owned { * 告警详情 */ private String details; - + private Long tenantId; + private Long deptAreaId; /** * 是否已读 */ private Boolean readFlg; + private Boolean statusFlg = false; /* @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") public Date getAlertTime() { return new Date(this.alertTime); diff --git a/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/device/DeviceDetectorInfo.java b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/device/DeviceDetectorInfo.java new file mode 100644 index 0000000..a4d9553 --- /dev/null +++ b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/device/DeviceDetectorInfo.java @@ -0,0 +1,75 @@ +/* + * + * * | Licensed 未经许可不能去掉「OPENIITA」相关版权 + * * +---------------------------------------------------------------------- + * * | Author: xw2sy@163.com + * * +---------------------------------------------------------------------- + * + * Copyright [2024] [OPENIITA] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * / + */ + +package cc.iotkit.model.device; + + +import cc.iotkit.model.Owned; +import cc.iotkit.model.TenantModel; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.github.linpeilie.annotations.AutoMapper; + +import lombok.*; +import org.hibernate.annotations.Filter; +import org.hibernate.annotations.FilterDef; +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.ParamDef; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.persistence.*; +import java.io.Serializable; +import java.util.Date; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class DeviceDetectorInfo extends TenantModel implements Owned,Serializable { + private static final long serialVersionUID = 1L; + + private String id; + + private String deviceId; + + private String productKey; + + private String deviceName; + + private String uid; + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + private Date createTime; + + private Long createAt; + /** + * 租户编号 + */ + + private Long tenantId; + + private String node; + private String gasTypeKey; + private String dataDetectorValue; +} diff --git a/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/device/DeviceInfo.java b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/device/DeviceInfo.java index 00341f4..6beed16 100644 --- a/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/device/DeviceInfo.java +++ b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/device/DeviceInfo.java @@ -38,16 +38,22 @@ import java.util.Map; @Builder @NoArgsConstructor @AllArgsConstructor -public class DeviceInfo extends TenantModel implements Owned { +public class DeviceInfo extends TenantModel implements Owned { private String id; private String deviceId; private String site; + private String name; - private Long deptAreaId; + private String signalStrength; + private String deviceVersion; + private Long deptAreaId; + private Long tenantId; + //设备状态0正常1故障2报警3离线 + private Integer deviceStatus; /** * 产品key */ @@ -55,12 +61,12 @@ public class DeviceInfo extends TenantModel implements Owned { private String productName; private String deviceName; - + private String tenantName; /** * 设备型号 */ private String model; - + private boolean flag; /** * 设备密钥 */ @@ -72,6 +78,23 @@ public class DeviceInfo extends TenantModel implements Owned { * 所属平台用户ID */ private String uid; + //安装信息 + private DeviceInstallInfo deviceInstallInfo; + private String nodeOne; + private String nodeTwo; + private String nodeThree; + private String nodeFour; + private String nodeFive; + private String nodeOneStatus; + private String nodeTwoStatus; + private String nodeThreeStatus; + private String nodeFourStatus; + private String nodeFiveStatus; + private String nodeOneDevice; + private String nodeTwoDevice; + private String nodeThreeDevice; + private String nodeFourDevice; + private String nodeFiveDevice; /** * 关联子用户ID列表 diff --git a/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/device/DeviceInstallInfo.java b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/device/DeviceInstallInfo.java new file mode 100644 index 0000000..f548dfd --- /dev/null +++ b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/device/DeviceInstallInfo.java @@ -0,0 +1,97 @@ +/* + * + * * | Licensed 未经许可不能去掉「OPENIITA」相关版权 + * * +---------------------------------------------------------------------- + * * | Author: xw2sy@163.com + * * +---------------------------------------------------------------------- + * + * Copyright [2024] [OPENIITA] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * / + */ + +package cc.iotkit.model.device; + + +import cc.iotkit.model.Owned; +import cc.iotkit.model.TenantModel; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.*; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class DeviceInstallInfo extends TenantModel implements Owned,Serializable { + private static final long serialVersionUID = 1L; + + private String id; + + // @ApiModelProperty(value = "设备名称(报警器编号)") + private String deviceName; + // @ApiModelProperty(value = "公司名称") + private String corporateName; + // @ApiModelProperty(value = "申请时间") + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + private Date proposerTime; + // @ApiModelProperty(value = "申请人") + private String proposer; + // @ApiModelProperty(value = "申请班组") + private String proposerTeam; + // @ApiModelProperty(value = "小区名称") + private String communityName; + // @ApiModelProperty(value = "用户名称") + private String userName; + // @ApiModelProperty(value = "用户电话") + private String userIpone; + // @ApiModelProperty(value = "楼栋单元号") + private String buildingUnit; + // @ApiModelProperty(value = "房间号") + private String roomNo; + // @ApiModelProperty(value = "切断阀编号") + private String shutValueNumber; + // @ApiModelProperty(value = "燃气表号") + private String gasMeterNumber; + // @ApiModelProperty(value = "备注") + private String remarks; + // @ApiModelProperty(value = "安装前图片") + private String beforeInstallationImage; + // @ApiModelProperty(value = "装完成探测器工作图片") + private String workingOfTheDetectorImage; + // @ApiModelProperty(value = "测漏图片") + private String sideLeakageImage; + // @ApiModelProperty(value = "点火图片") + private String ignitionPictureImage; + // @ApiModelProperty(value = "装完成全景图片") + private String installThePanoramicImage; + // @ApiModelProperty(value = "燃气表图片") + private String ofGasMeterImage; + //@ApiModelProperty(value = "工单图片") + private String workOrderImage; + //@ApiModelProperty(value = "打孔图片") + private String punchingImage; + // @ApiModelProperty(value = "用户id") + private String uid; + // @ApiModelProperty(value = "租户编号") + private Long tenantId; + // @ApiModelProperty(value = "装电源线照片") + private String fiexImage; + private Integer state; +} diff --git a/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/device/InstallationRecord.java b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/device/InstallationRecord.java new file mode 100644 index 0000000..27bce26 --- /dev/null +++ b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/device/InstallationRecord.java @@ -0,0 +1,25 @@ +package cc.iotkit.model.device; + +import lombok.Data; + +@Data +public class InstallationRecord { + + private String teamName; // 班组名称 + private String installer; // 安装人 + private String community; // 小区名称 + private String buildingNo; // 楼栋号 + private String unitNo; // 单元号 + private String roomNo; // 房号 + private String userName; // 用户姓名 + private String userPhone; // 用户电话 + private String stoveType; // 灶具类型 + private String installDate; // 安装时间 + // 材料使用相关字段 + private int ballValve; // 球阀 + private int drilling; // 打孔 + private String pipeType; // 管子使用类型及尺寸 + private int nonFixedPipe; // 非定尺管 + private int nut; // 螺母 + private int quickConnect; // 插入式快接 +} diff --git a/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/product/Category.java b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/product/Category.java index df5033c..c060f27 100644 --- a/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/product/Category.java +++ b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/product/Category.java @@ -26,6 +26,9 @@ import cc.iotkit.model.Id; import cc.iotkit.model.TenantModel; import lombok.Data; +import javax.persistence.Column; +import java.util.Date; + @Data public class Category extends TenantModel implements Id { @@ -34,5 +37,7 @@ public class Category extends TenantModel implements Id { private String name; private Long createAt; + @Column(name = "create_time", updatable = false) + private Date createTime; } diff --git a/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/rule/RuleInfo.java b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/rule/RuleInfo.java index a207e17..52610ed 100644 --- a/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/rule/RuleInfo.java +++ b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/rule/RuleInfo.java @@ -60,7 +60,8 @@ public class RuleInfo implements Owned { private String desc; private Long createAt; - + private Long tenantId; + private String tenantName; public List getListeners() { return listeners == null ? new ArrayList<>() : listeners; } diff --git a/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/stats/SysDeptDto.java b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/stats/SysDeptDto.java new file mode 100644 index 0000000..b487c14 --- /dev/null +++ b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/stats/SysDeptDto.java @@ -0,0 +1,52 @@ +/* + * + * * | Licensed 未经许可不能去掉「OPENIITA」相关版权 + * * +---------------------------------------------------------------------- + * * | Author: xw2sy@163.com + * * +---------------------------------------------------------------------- + * + * Copyright [2024] [OPENIITA] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * / + */ + +package cc.iotkit.model.stats; + +import cc.iotkit.common.api.BaseDto; +import cc.iotkit.model.system.SysDept; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 部门业务对象 sys_dept + * + * @author Michelle.Chung + */ + +@Data +public class SysDeptDto { + + + /** + * 部门与区域(默认0是部门,1是区域) + */ + private Integer areaType; + private Long normalCount; + private Long faultCount; + private Long alarmCount; + private Long onlineCount; + private Long expireCount; + +} diff --git a/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/system/SysDept.java b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/system/SysDept.java index 51993f5..c75a4fe 100644 --- a/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/system/SysDept.java +++ b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/system/SysDept.java @@ -25,6 +25,7 @@ package cc.iotkit.model.system; import cc.iotkit.model.BaseModel; import cc.iotkit.model.Id; +import cc.iotkit.model.TenantModel; import lombok.Data; import lombok.EqualsAndHashCode; @@ -38,7 +39,7 @@ import java.util.Date; */ @EqualsAndHashCode(callSuper = true) @Data -public class SysDept extends BaseModel implements Id, Serializable { +public class SysDept extends TenantModel implements Id, Serializable { private static final long serialVersionUID = 1L; /** @@ -105,4 +106,8 @@ public class SysDept extends BaseModel implements Id, Serializable { * 部门与区域(默认0是部门,1是区域) */ private Integer areaType; + private String latitude; + private String longitude; + private String site; + } diff --git a/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/system/SysRole.java b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/system/SysRole.java index cfaa605..a16ae62 100644 --- a/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/system/SysRole.java +++ b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/system/SysRole.java @@ -46,7 +46,7 @@ public class SysRole extends TenantModel implements Id,Serializable { * 角色ID */ private Long id; - + private Long tenantId; /** * 角色名称 */ diff --git a/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/system/SysUser.java b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/system/SysUser.java index 7f7b9be..e29d139 100644 --- a/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/system/SysUser.java +++ b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/system/SysUser.java @@ -148,4 +148,5 @@ public class SysUser extends TenantModel implements Id, Serializable { private Long roleId; private Long deptAreaId; + private boolean flag; } diff --git a/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IAlertConfigData.java b/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IAlertConfigData.java index 075ec60..66e497d 100644 --- a/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IAlertConfigData.java +++ b/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IAlertConfigData.java @@ -33,5 +33,7 @@ import java.util.List; public interface IAlertConfigData extends ICommonData { List findByUidAndRuleInfoId(String uid, String ruleInfoId); + List findByUidAndRuleInfoIdAndDeviceName(String uid, String ruleInfoId,String deviceName); + Paging selectAlertConfigPage(PageRequest request); } diff --git a/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IDIccidRecordData.java b/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IDIccidRecordData.java index be4925a..390ae46 100644 --- a/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IDIccidRecordData.java +++ b/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IDIccidRecordData.java @@ -31,6 +31,6 @@ import java.util.List; public interface IDIccidRecordData extends ICommonData { - + DIccidRecordDO findByImei(String Imei); } diff --git a/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IDeviceDetectorInfoData.java b/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IDeviceDetectorInfoData.java new file mode 100644 index 0000000..ebdfdb4 --- /dev/null +++ b/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IDeviceDetectorInfoData.java @@ -0,0 +1,35 @@ +/* + * + * * | Licensed 未经许可不能去掉「OPENIITA」相关版权 + * * +---------------------------------------------------------------------- + * * | Author: xw2sy@163.com + * * +---------------------------------------------------------------------- + * + * Copyright [2024] [OPENIITA] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * / + */ +package cc.iotkit.data.manager; + +import cc.iotkit.data.ICommonData; +import cc.iotkit.data.IOwnedData; +import cc.iotkit.model.device.DeviceDetectorInfo; +import cc.iotkit.model.iccid.DIccidRecordDO; + + +public interface IDeviceDetectorInfoData extends IOwnedData { + + + +} diff --git a/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IDeviceInfoData.java b/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IDeviceInfoData.java index ff3e68a..7acf455 100644 --- a/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IDeviceInfoData.java +++ b/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IDeviceInfoData.java @@ -29,6 +29,7 @@ import cc.iotkit.model.device.message.DevicePropertyCache; import cc.iotkit.model.stats.AlertStatDTO; import cc.iotkit.model.stats.DataItem; import cc.iotkit.model.stats.ProductKeyCountDTO; +import cc.iotkit.model.stats.SysDeptDto; import java.util.Date; import java.util.List; @@ -50,7 +51,7 @@ public interface IDeviceInfoData extends IOwnedData { * @param deviceId 设备id */ Map getProperties(String deviceId); - + SysDeptDto getStatsCount(Long deptAreaId); /** * 获取设备属性更新时间 * @@ -88,6 +89,7 @@ public interface IDeviceInfoData extends IOwnedData { */ List findByParentId(String parentId); public List findByConditionsList(String productKey); + public List findByConditionsList(String productKey,Boolean flag); /** * 根据父设备ID取子设备ID列表 * @@ -99,7 +101,7 @@ public interface IDeviceInfoData extends IOwnedData { * 根据deviceName查找设备 */ DeviceInfo findByDeviceName(String deviceName); - + List findByDeptAreaIdAndProductKey(Long areaDeptId,String productKey); /** * 按条件搜索设备 * @@ -115,7 +117,9 @@ public interface IDeviceInfoData extends IOwnedData { Paging findByConditions(String name,String uid, String subUid, String productKey, String groupId, Boolean online, String keyword, int page, int size,Long areaDepeId); - + Paging findByConditions1(String name,String uid, String subUid, String productKey, + String groupId, Boolean online, String keyword, + int page, int size,Long areaDepeId); /** * 更新设备标签 * @@ -134,6 +138,7 @@ public interface IDeviceInfoData extends IOwnedData { */ long countByGroupId(String groupId); + long countByUidAndState(String uid,String state); /** * 将设备添加到分组 * diff --git a/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IDeviceInstallInfoData.java b/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IDeviceInstallInfoData.java new file mode 100644 index 0000000..8efe3e7 --- /dev/null +++ b/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IDeviceInstallInfoData.java @@ -0,0 +1,36 @@ +/* + * + * * | Licensed 未经许可不能去掉「OPENIITA」相关版权 + * * +---------------------------------------------------------------------- + * * | Author: xw2sy@163.com + * * +---------------------------------------------------------------------- + * + * Copyright [2024] [OPENIITA] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * / + */ +package cc.iotkit.data.manager; + +import cc.iotkit.data.IOwnedData; +import cc.iotkit.model.device.DeviceDetectorInfo; +import cc.iotkit.model.device.DeviceInstallInfo; + + +public interface IDeviceInstallInfoData extends IOwnedData { + + + DeviceInstallInfo findByDeviceNameAndUid(String deviceName,String uid); + DeviceInstallInfo findByDeviceNameAndUidAndState(String deviceName,String uid,Integer state); + +} diff --git a/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IUserInfoData.java b/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IUserInfoData.java index af26b82..bb1216e 100644 --- a/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IUserInfoData.java +++ b/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IUserInfoData.java @@ -22,6 +22,8 @@ */ package cc.iotkit.data.manager; +import cc.iotkit.common.api.PageRequest; +import cc.iotkit.common.api.Paging; import cc.iotkit.data.ICommonData; import cc.iotkit.model.UserInfo; @@ -30,6 +32,8 @@ import java.util.List; public interface IUserInfoData extends ICommonData { UserInfo findByUid(String uid); - + UserInfo findByUidAndUserName(String uid,String userName); + UserInfo findByUserName(String userName); List findByType(int type); + Paging findAll(PageRequest pageRequest); } diff --git a/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/system/ISysDeptData.java b/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/system/ISysDeptData.java index 6774ea6..0be6bc7 100644 --- a/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/system/ISysDeptData.java +++ b/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/system/ISysDeptData.java @@ -47,6 +47,7 @@ public interface ISysDeptData extends ICommonData { */ List findDepts(SysDept dept); + /** * 根据角色ID查询部门树信息 * @@ -70,7 +71,7 @@ public interface ISysDeptData extends ICommonData { * @return 部门列表 */ List findByDeptId(Long deptId); - + List findByTenantId(Long tenantId); boolean checkDeptNameUnique(String deptName, Long parentId, Long deptId); diff --git a/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/system/ISysUserData.java b/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/system/ISysUserData.java index eda7b73..1090ae7 100644 --- a/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/system/ISysUserData.java +++ b/iot-dao/iot-data-service/src/main/java/cc/iotkit/data/system/ISysUserData.java @@ -28,6 +28,8 @@ import cc.iotkit.common.api.Paging; import cc.iotkit.data.ICommonData; import cc.iotkit.model.system.SysUser; +import java.util.List; + /** * 用户数据接口 * @@ -74,4 +76,6 @@ public interface ISysUserData extends ICommonData { Paging selectUnallocatedList(PageRequest to); SysUser findByPhonenumber(String phonenumber); + + List findByTenantId(Long tenantId); } diff --git a/iot-dao/iot-data-serviceImpl-cache/pom.xml b/iot-dao/iot-data-serviceImpl-cache/pom.xml index b8c54c2..31731b3 100644 --- a/iot-dao/iot-data-serviceImpl-cache/pom.xml +++ b/iot-dao/iot-data-serviceImpl-cache/pom.xml @@ -44,6 +44,10 @@ org.springframework.boot spring-boot-starter-cache + + org.springframework.data + spring-data-jpa + diff --git a/iot-dao/iot-data-serviceImpl-cache/src/main/java/cc/iotkit/data/service/CategoryDataCache.java b/iot-dao/iot-data-serviceImpl-cache/src/main/java/cc/iotkit/data/service/CategoryDataCache.java index 754d446..34aefdb 100644 --- a/iot-dao/iot-data-serviceImpl-cache/src/main/java/cc/iotkit/data/service/CategoryDataCache.java +++ b/iot-dao/iot-data-serviceImpl-cache/src/main/java/cc/iotkit/data/service/CategoryDataCache.java @@ -26,17 +26,18 @@ package cc.iotkit.data.service; import cc.iotkit.common.api.PageRequest; import cc.iotkit.common.api.Paging; import cc.iotkit.common.constant.Constants; +import cc.iotkit.common.utils.MapstructUtils; import cc.iotkit.data.cache.CategoryCacheEvict; import cc.iotkit.data.manager.ICategoryData; import cc.iotkit.model.product.Category; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; -import java.util.Collection; -import java.util.Collections; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; @Service @Qualifier("categoryDataCache") @@ -92,6 +93,9 @@ public class CategoryDataCache implements ICategoryData { @Override public Paging findAll(PageRequest pageRequest) { + pageRequest.setSortMap(new HashMap<>()); + pageRequest.getSortMap().put("createTime", "desc"); + return categoryData.findAll(pageRequest); } diff --git a/iot-dao/iot-data-serviceImpl-cache/src/main/java/cc/iotkit/data/service/DeviceInfoDataCache.java b/iot-dao/iot-data-serviceImpl-cache/src/main/java/cc/iotkit/data/service/DeviceInfoDataCache.java index 7518da3..6829773 100644 --- a/iot-dao/iot-data-serviceImpl-cache/src/main/java/cc/iotkit/data/service/DeviceInfoDataCache.java +++ b/iot-dao/iot-data-serviceImpl-cache/src/main/java/cc/iotkit/data/service/DeviceInfoDataCache.java @@ -34,6 +34,7 @@ import cc.iotkit.model.device.message.DevicePropertyCache; import cc.iotkit.model.stats.AlertStatDTO; import cc.iotkit.model.stats.DataItem; import cc.iotkit.model.stats.ProductKeyCountDTO; +import cc.iotkit.model.stats.SysDeptDto; import com.fasterxml.jackson.core.type.TypeReference; import lombok.AllArgsConstructor; import lombok.Data; @@ -137,6 +138,12 @@ public class DeviceInfoDataCache implements IDeviceInfoData, SmartInitializingSi public Map getProperties(String deviceId) { return getPropertyCacheInfo(deviceId).getProperties(); } + + @Override + public SysDeptDto getStatsCount(Long deptAreaId) { + return deviceInfoData.getStatsCount(deptAreaId); + } + @Override public List getProductDevice(Long deptAreaId,String startDate, String endDate){ @@ -181,6 +188,11 @@ public class DeviceInfoDataCache implements IDeviceInfoData, SmartInitializingSi public DeviceInfo findByDeviceName(String deviceName) { return deviceInfoData.findByDeviceName(deviceName); } + @Override + // @Cacheable(value = Constants.CACHE_DEVICE_INFO, key = "#root.method.name+#deviceName", unless = "#result == null") + public List findByDeptAreaIdAndProductKey(Long deviceId, String productKey) { + return deviceInfoData.findByDeptAreaIdAndProductKey(deviceId,productKey); + } @Override public List findByParentId(String parentId) { @@ -192,6 +204,11 @@ public class DeviceInfoDataCache implements IDeviceInfoData, SmartInitializingSi return deviceInfoData.findByConditionsList(productKey); } + @Override + public List findByConditionsList(String productKey, Boolean flag) { + return deviceInfoData.findByConditionsList(productKey,flag); + } + @Override public List findByProductNodeType(String uid) { return deviceInfoData.findByProductNodeType(uid); @@ -217,7 +234,10 @@ public class DeviceInfoDataCache implements IDeviceInfoData, SmartInitializingSi String groupId, Boolean state, String keyword, int page, int size,Long deptAreaId) { return deviceInfoData.findByConditions(name,uid, subUid, productKey, groupId, state, keyword, page, size,deptAreaId); } - + public Paging findByConditions1(String name,String uid, String subUid, String productKey, + String groupId, Boolean state, String keyword, int page, int size,Long deptAreaId) { + return deviceInfoData.findByConditions1(name,uid, subUid, productKey, groupId, state, keyword, page, size,deptAreaId); + } @Override public void updateTag(String deviceId, DeviceInfo.Tag tag) { deviceInfoData.updateTag(deviceId, tag); @@ -235,6 +255,10 @@ public class DeviceInfoDataCache implements IDeviceInfoData, SmartInitializingSi public long countByGroupId(String groupId) { return deviceInfoData.countByGroupId(groupId); } + @Override + public long countByUidAndState(String uid,String state) { + return deviceInfoData.countByUidAndState(uid,state); + } @Override public void addToGroup(String deviceId, DeviceInfo.Group group) { diff --git a/iot-dao/iot-data-serviceImpl-cache/src/main/java/cc/iotkit/data/service/DeviceInfoPropertyDataCache.java b/iot-dao/iot-data-serviceImpl-cache/src/main/java/cc/iotkit/data/service/DeviceInfoPropertyDataCache.java index 3b835ba..417269d 100644 --- a/iot-dao/iot-data-serviceImpl-cache/src/main/java/cc/iotkit/data/service/DeviceInfoPropertyDataCache.java +++ b/iot-dao/iot-data-serviceImpl-cache/src/main/java/cc/iotkit/data/service/DeviceInfoPropertyDataCache.java @@ -30,6 +30,7 @@ import cc.iotkit.model.device.message.DevicePropertyCache; import cc.iotkit.model.stats.AlertStatDTO; import cc.iotkit.model.stats.DataItem; import cc.iotkit.model.stats.ProductKeyCountDTO; +import cc.iotkit.model.stats.SysDeptDto; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; @@ -58,6 +59,12 @@ public class DeviceInfoPropertyDataCache implements IDeviceInfoData { public List findByConditionsList(String productKey){ return deviceInfoData.findByConditionsList(productKey); } + + @Override + public List findByConditionsList(String productKey, Boolean flag) { + return deviceInfoData.findByConditionsList(productKey,flag); + } + @Override public List findByIds(Collection id) { return null; @@ -118,6 +125,11 @@ public class DeviceInfoPropertyDataCache implements IDeviceInfoData { return deviceInfoData.getProperties(deviceId); } + @Override + public SysDeptDto getStatsCount(Long deptAreaId) { + return deviceInfoData.getStatsCount(deptAreaId); + } + @Override public long getPropertyUpdateTime(String deviceId) { return deviceInfoData.getPropertyUpdateTime(deviceId); @@ -149,6 +161,17 @@ public class DeviceInfoPropertyDataCache implements IDeviceInfoData { deviceInfo.setProperty(getProperties(deviceInfo.getDeviceId())); return deviceInfo; } + + @Override + public List findByDeptAreaIdAndProductKey(Long areaDeptId, String productKey) { + List deviceInfo = deviceInfoData.findByDeptAreaIdAndProductKey(areaDeptId, productKey); + if (deviceInfo == null) { + return null; + } + deviceInfo.forEach(deviceInfo1 -> deviceInfo1.setProperty(getProperties(deviceInfo1.getDeviceId()))); + // deviceInfo.setProperty(getProperties(deviceInfo.getDeviceId())); + return deviceInfo; + } @Override public List getDeviceRecord() { return deviceInfoData.getDeviceRecord(); @@ -167,7 +190,10 @@ public class DeviceInfoPropertyDataCache implements IDeviceInfoData { public Paging findByConditions(String name,String uid, String subUid, String productKey, String groupId, Boolean online, String keyword, int page, int size,Long deptAreaId) { return deviceInfoData.findByConditions(name,uid, subUid, productKey, groupId, online, keyword, page, size,deptAreaId); } - + @Override + public Paging findByConditions1(String name,String uid, String subUid, String productKey, String groupId, Boolean online, String keyword, int page, int size,Long deptAreaId) { + return deviceInfoData.findByConditions(name,uid, subUid, productKey, groupId, online, keyword, page, size,deptAreaId); + } @Override public void updateTag(String deviceId, DeviceInfo.Tag tag) { deviceInfoData.updateTag(deviceId, tag); @@ -182,6 +208,11 @@ public class DeviceInfoPropertyDataCache implements IDeviceInfoData { public long countByGroupId(String groupId) { return deviceInfoData.countByGroupId(groupId); } + @Override + public long countByUidAndState(String uid,String state) { + + return deviceInfoData.countByUidAndState(uid,state); + } @Override public void addToGroup(String deviceId, DeviceInfo.Group group) { diff --git a/iot-dao/iot-data-serviceImpl-cache/src/main/java/cc/iotkit/data/service/ProductDataCache.java b/iot-dao/iot-data-serviceImpl-cache/src/main/java/cc/iotkit/data/service/ProductDataCache.java index 5846d0e..e3c0e7b 100644 --- a/iot-dao/iot-data-serviceImpl-cache/src/main/java/cc/iotkit/data/service/ProductDataCache.java +++ b/iot-dao/iot-data-serviceImpl-cache/src/main/java/cc/iotkit/data/service/ProductDataCache.java @@ -135,7 +135,7 @@ public class ProductDataCache implements IProductData { @Override public List findAllByCondition(Product data) { - return null; + return productData.findAll(); } @Override diff --git a/iot-dao/iot-data-serviceImpl-cache/src/main/java/cc/iotkit/data/service/UserInfoDataCache.java b/iot-dao/iot-data-serviceImpl-cache/src/main/java/cc/iotkit/data/service/UserInfoDataCache.java index e4a86d5..d9f948e 100644 --- a/iot-dao/iot-data-serviceImpl-cache/src/main/java/cc/iotkit/data/service/UserInfoDataCache.java +++ b/iot-dao/iot-data-serviceImpl-cache/src/main/java/cc/iotkit/data/service/UserInfoDataCache.java @@ -29,9 +29,13 @@ import cc.iotkit.common.constant.Constants; import cc.iotkit.data.cache.UserInfoCacheEvict; import cc.iotkit.data.manager.IUserInfoData; import cc.iotkit.model.UserInfo; +import cc.iotkit.model.system.SysUser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; import java.util.Collection; @@ -61,6 +65,15 @@ public class UserInfoDataCache implements IUserInfoData { public UserInfo findById(Long s) { return userInfoData.findById(s); } + @Override + public UserInfo findByUidAndUserName(String uid,String userName) { + return userInfoData.findByUidAndUserName(uid,userName); + } + + @Override + public UserInfo findByUserName(String userName) { + return userInfoData.findByUserName(userName); + } @Override public List findByIds(Collection id) { @@ -103,6 +116,7 @@ public class UserInfoDataCache implements IUserInfoData { @Override public Paging findAll(PageRequest pageRequest) { return userInfoData.findAll(pageRequest); + // return userInfoData.findAll(pageRequest); } @Override diff --git a/iot-dao/iot-data-serviceImpl-rdb/pom.xml b/iot-dao/iot-data-serviceImpl-rdb/pom.xml index fc6c916..52517d3 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/pom.xml +++ b/iot-dao/iot-data-serviceImpl-rdb/pom.xml @@ -107,11 +107,38 @@ compile + org.apache.poi + poi-ooxml + 5.2.3 + + + org.apache.poi + poi-ooxml-schemas + + + + + org.apache.xmlbeans + xmlbeans + 5.1.1 + + + org.apache.xmlbeans + xmlbeans + + + + + diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/config/TenantAspect.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/config/TenantAspect.java index cc09881..b4574ef 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/config/TenantAspect.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/config/TenantAspect.java @@ -1,7 +1,10 @@ package cc.iotkit.data.config; +import cc.iotkit.common.redis.utils.RedisUtils; import cc.iotkit.common.satoken.utils.LoginHelper; +import cc.iotkit.common.tenant.helper.TenantHelper; import cc.iotkit.common.utils.StringUtils; +import cn.hutool.core.util.ObjectUtil; import com.querydsl.core.types.Predicate; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; @@ -30,6 +33,7 @@ import static cn.dev33.satoken.SaManager.log; public class TenantAspect { @PersistenceContext private EntityManager entityManager; + /** * 转换request 请求参数 * @@ -70,23 +74,30 @@ public class TenantAspect { }*/ @Around("execution(* org.springframework.data.jpa.repository.JpaRepository+.*(..)) || " + - "execution(* org.springframework.data.repository.query.QueryByExampleExecutor+.*(..))") + "execution(* org.springframework.data.repository.query.QueryByExampleExecutor+.*(..)) ||" + + "execution(* org.springframework.data.querydsl.QuerydslPredicateExecutor+.*(..))" ) public Object applyTenantFilter(ProceedingJoinPoint pjp) throws Throwable { - // System.out.println("111111111111Thread" + TenantContext.isFilterDisabled()); - if(LoginHelper.isSuperAdmin()){ - return pjp.proceed(); // 跳过租户过滤 - // TenantContext.disableTenantFilter(); - } - if(TenantContext.isFilterDisabled()) { - return pjp.proceed(); // 跳过租户过滤 - } - //放开租户 - Long tenantId= LoginHelper.getTenantId(); - // Long tenantId = 0L; // 实现租户ID获取逻辑 - if(ObjectUtils.isEmpty(tenantId)){ - tenantId = 0L; - } + // System.out.println("111111111111Thread" + TenantHelper.getTenantId()); + // System.out.println("222222222Thread" + LoginHelper.getTenantId()); + // System.out.println("33333333333Thread" + TenantHelper.getDynamic()); try { + // System.out.println("进入切面了~~~~~~~~~~~" + LoginHelper.isSuperAdmin()); + // System.out.println("进入切面了1~~~~~~~~~~~" + ObjectUtil.isNull(TenantHelper.getTenantId())); + if (LoginHelper.isSuperAdmin() && (ObjectUtil.isNull(TenantHelper.getTenantId()) || TenantHelper.getTenantId() == 0)) { + return pjp.proceed(); // 跳过租户过滤 + // TenantContext.disableTenantFilter(); + } + if (TenantContext.isFilterDisabled()) { + return pjp.proceed(); // 跳过租户过滤 + } + + //放开租户 + Long tenantId = TenantHelper.getTenantId(); + // Long tenantId = 0L; // 实现租户ID获取逻辑 + if (ObjectUtils.isEmpty(tenantId)) { + return pjp.proceed(); // 跳过租户过滤 + } + entityManager.unwrap(Session.class) .enableFilter("tenantFilter") .setParameter("tenantId", tenantId); diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/AlertConfigRepository.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/AlertConfigRepository.java index c3785ad..53e3ad4 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/AlertConfigRepository.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/AlertConfigRepository.java @@ -29,11 +29,14 @@ import com.querydsl.core.types.Predicate; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import org.springframework.data.querydsl.QuerydslPredicateExecutor; +import org.springframework.data.repository.query.Param; import java.util.List; public interface AlertConfigRepository extends JpaRepository, QuerydslPredicateExecutor { - List findByUidAndRuleInfoId(String uid, String ruleInfoId); + List findByUidAndRuleInfoId(String uid, String ruleInfoId); + List findByUidAndRuleInfoIdAndDeviceName(String uid, String ruleInfoId,String deviceName); } diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/CategoryRepository.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/CategoryRepository.java index 5b515f7..ecaf34a 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/CategoryRepository.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/CategoryRepository.java @@ -23,8 +23,10 @@ package cc.iotkit.data.dao; import cc.iotkit.data.model.TbCategory; +import cc.iotkit.data.model.TbDeviceInfo; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.querydsl.QuerydslPredicateExecutor; -public interface CategoryRepository extends JpaRepository { +public interface CategoryRepository extends JpaRepository, QuerydslPredicateExecutor { } diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/DeviceGroupMappingRepository.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/DeviceGroupMappingRepository.java index af2c294..09abd0a 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/DeviceGroupMappingRepository.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/DeviceGroupMappingRepository.java @@ -36,4 +36,5 @@ public interface DeviceGroupMappingRepository extends JpaRepository, QuerydslPredicateExecutor { + + /*TbDeviceInfo findByDeviceId(String deviceId); + + List findByParentId(String parentId); + + TbDeviceInfo findByDeviceName(String deviceName); + long countByUid(String uid); + long countByUidAndState(String uid,String state);*/ +} diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/DeviceInfoRepository.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/DeviceInfoRepository.java index 14d1205..4f91e6a 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/DeviceInfoRepository.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/DeviceInfoRepository.java @@ -36,5 +36,7 @@ public interface DeviceInfoRepository extends JpaRepository findByParentId(String parentId); TbDeviceInfo findByDeviceName(String deviceName); + List findByDeptAreaIdAndProductKey(Long deptAreaId,String productKey); long countByUid(String uid); + long countByUidAndState(String uid,String state); } diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/DeviceInstallInfoRepository.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/DeviceInstallInfoRepository.java new file mode 100644 index 0000000..ebcd08c --- /dev/null +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/DeviceInstallInfoRepository.java @@ -0,0 +1,45 @@ +/* + * + * * | Licensed 未经许可不能去掉「OPENIITA」相关版权 + * * +---------------------------------------------------------------------- + * * | Author: xw2sy@163.com + * * +---------------------------------------------------------------------- + * + * Copyright [2024] [OPENIITA] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * / + */ + +package cc.iotkit.data.dao; + +import cc.iotkit.data.model.TbDeviceDetectorInfo; +import cc.iotkit.data.model.TbDeviceInfo; +import cc.iotkit.data.model.TbDeviceInstallInfo; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.querydsl.QuerydslPredicateExecutor; + +public interface DeviceInstallInfoRepository extends JpaRepository, QuerydslPredicateExecutor { + + /*TbDeviceInfo findByDeviceId(String deviceId); + + List findByParentId(String parentId); + + TbDeviceInfo findByDeviceName(String deviceName); + long countByUid(String uid); + long countByUidAndState(String uid,String state);*/ + TbDeviceInstallInfo findByDeviceNameAndUid(String deviceName,String uid); + TbDeviceInstallInfo findByDeviceNameAndUidAndState(String deviceName,String uid,Integer state); + + +} diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/DiccidRecordRepository.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/DiccidRecordRepository.java index 23938e5..8ebd9c5 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/DiccidRecordRepository.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/DiccidRecordRepository.java @@ -23,11 +23,13 @@ package cc.iotkit.data.dao; import cc.iotkit.data.model.TbDIccidRecordDO; +import cc.iotkit.data.model.TbWorderDO; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.querydsl.QuerydslPredicateExecutor; import java.util.List; -public interface DiccidRecordRepository extends JpaRepository { +public interface DiccidRecordRepository extends JpaRepository, QuerydslPredicateExecutor { @@ -36,5 +38,5 @@ public interface DiccidRecordRepository extends JpaRepository findAll(); - + TbDIccidRecordDO findByImei(String imei); } diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/RuleInfoRepository.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/RuleInfoRepository.java index 038a141..69ca68d 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/RuleInfoRepository.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/RuleInfoRepository.java @@ -22,14 +22,16 @@ */ package cc.iotkit.data.dao; +import cc.iotkit.data.model.TbDeviceDetectorInfo; import cc.iotkit.data.model.TbRuleInfo; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.querydsl.QuerydslPredicateExecutor; import java.util.List; -public interface RuleInfoRepository extends JpaRepository { +public interface RuleInfoRepository extends JpaRepository, QuerydslPredicateExecutor { List findByUid(String uid); diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/SysConfigRepository.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/SysConfigRepository.java index 915f87c..70fe8a8 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/SysConfigRepository.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/SysConfigRepository.java @@ -30,5 +30,6 @@ import java.util.Optional; public interface SysConfigRepository extends JpaRepository, QuerydslPredicateExecutor { + Optional findByConfigKeyAndTenantId(String configKey, Long tenantId); Optional findByConfigKey(String configKey); } diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/SysDeptRepository.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/SysDeptRepository.java index ff01a10..66c18c6 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/SysDeptRepository.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/SysDeptRepository.java @@ -26,6 +26,8 @@ import cc.iotkit.data.model.TbSysDept; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.querydsl.QuerydslPredicateExecutor; -public interface SysDeptRepository extends JpaRepository, QuerydslPredicateExecutor { +import java.util.List; +public interface SysDeptRepository extends JpaRepository, QuerydslPredicateExecutor { + List findByTenantId(Long tenantId); } diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/SysUserRepository.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/SysUserRepository.java index 88981da..d5d89b7 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/SysUserRepository.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/SysUserRepository.java @@ -26,6 +26,8 @@ import cc.iotkit.data.model.TbSysUser; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.querydsl.QuerydslPredicateExecutor; -public interface SysUserRepository extends JpaRepository, QuerydslPredicateExecutor { +import java.util.List; +public interface SysUserRepository extends JpaRepository, QuerydslPredicateExecutor { + List findByTenantId(Long tenantId); } diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/UserInfoRepository.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/UserInfoRepository.java index 76d335d..34a8bbe 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/UserInfoRepository.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/UserInfoRepository.java @@ -22,14 +22,18 @@ */ package cc.iotkit.data.dao; +import cc.iotkit.data.model.TbSysDept; import cc.iotkit.data.model.TbUserInfo; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.querydsl.QuerydslPredicateExecutor; import java.util.List; -public interface UserInfoRepository extends JpaRepository { +public interface UserInfoRepository extends JpaRepository, QuerydslPredicateExecutor { TbUserInfo findByUid(String uid); + TbUserInfo findByUidAndUserName(String uid,String userName); + TbUserInfo findByUserName(String userName); List findByType(int type); diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbAlertConfig.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbAlertConfig.java index 3021fcf..bd28fae 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbAlertConfig.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbAlertConfig.java @@ -105,4 +105,6 @@ public class TbAlertConfig extends BaseEntity implements TenantAware { * 0短信1微信小程序推送2语音,数据用,隔开 */ private String messagePush; + private String messagePushIpone; + private String deviceName; } diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbAlertRecord.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbAlertRecord.java index 1e82868..ef02a66 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbAlertRecord.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbAlertRecord.java @@ -89,4 +89,6 @@ public class TbAlertRecord extends BaseEntity implements TenantAware { private Boolean readFlg; private Long tenantId; + + private Long deptAreaId; } diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbDeviceDetectorInfo.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbDeviceDetectorInfo.java new file mode 100644 index 0000000..0edb2ca --- /dev/null +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbDeviceDetectorInfo.java @@ -0,0 +1,77 @@ +/* + * + * * | Licensed 未经许可不能去掉「OPENIITA」相关版权 + * * +---------------------------------------------------------------------- + * * | Author: xw2sy@163.com + * * +---------------------------------------------------------------------- + * + * Copyright [2024] [OPENIITA] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * / + */ + +package cc.iotkit.data.model; + +import cc.iotkit.common.tenant.dao.TenantAware; +import cc.iotkit.common.tenant.listener.TenantListener; +import cc.iotkit.model.device.DeviceDetectorInfo; +import cc.iotkit.model.device.DeviceInfo; +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.annotations.ReverseAutoMapping; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.annotations.Filter; +import org.hibernate.annotations.FilterDef; +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.ParamDef; + +import javax.persistence.*; + +@Data +@Entity +@Table(name = "device_detector_info") +@ApiModel(value = "设备浓度信息") +@AutoMapper(target = DeviceDetectorInfo.class) +@FilterDef(name = "tenantFilter", parameters = {@ParamDef(name = "tenantId", type = "long")}) +@Filter(name = "tenantFilter", condition = "tenant_id = :tenantId") +@EntityListeners(TenantListener.class) +public class TbDeviceDetectorInfo extends BaseEntity implements TenantAware { + + @Id + @GeneratedValue(generator = "SnowflakeIdGenerator") + @GenericGenerator(name = "SnowflakeIdGenerator", strategy = "cc.iotkit.data.config.id.SnowflakeIdGenerator") + private String id; + @ApiModelProperty(value = "设备id") + private String deviceId; + @ApiModelProperty(value = "产品key") + private String productKey; + @ApiModelProperty(value = "设备名称") + private String deviceName; + @ApiModelProperty(value = "用户id") + private String uid; + + @ApiModelProperty(value = "创建时间") + private Long createAt; + /** + * 租户编号 + */ + @ApiModelProperty(value = "租户编号") + private Long tenantId; + + private String node; + private String gasTypeKey; + private String dataDetectorValue; +} diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbDeviceInfo.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbDeviceInfo.java index 2174839..098ca01 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbDeviceInfo.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbDeviceInfo.java @@ -104,4 +104,22 @@ public class TbDeviceInfo extends BaseEntity implements TenantAware { @ApiModelProperty(value = "区域id") private Long deptAreaId; private String name; + private String signalStrength; + private String deviceVersion; + private Integer deviceStatus; + private String nodeOne; + private String nodeTwo; + private String nodeThree; + private String nodeFour; + private String nodeFive; + private String nodeOneStatus; + private String nodeTwoStatus; + private String nodeThreeStatus; + private String nodeFourStatus; + private String nodeFiveStatus; + private String nodeOneDevice; + private String nodeTwoDevice; + private String nodeThreeDevice; + private String nodeFourDevice; + private String nodeFiveDevice; } diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbDeviceInstallInfo.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbDeviceInstallInfo.java new file mode 100644 index 0000000..acac545 --- /dev/null +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbDeviceInstallInfo.java @@ -0,0 +1,108 @@ +/* + * + * * | Licensed 未经许可不能去掉「OPENIITA」相关版权 + * * +---------------------------------------------------------------------- + * * | Author: xw2sy@163.com + * * +---------------------------------------------------------------------- + * + * Copyright [2024] [OPENIITA] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * / + */ + +package cc.iotkit.data.model; + +import cc.iotkit.common.tenant.dao.TenantAware; +import cc.iotkit.common.tenant.listener.TenantListener; +import cc.iotkit.model.device.DeviceDetectorInfo; +import cc.iotkit.model.device.DeviceInstallInfo; +import io.github.linpeilie.annotations.AutoMapper; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.annotations.Filter; +import org.hibernate.annotations.FilterDef; +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.ParamDef; + +import javax.persistence.*; +import java.util.Date; + +@Data +@Entity +@Table(name = "device_install_info") +@ApiModel(value = "设备安装信息") +@AutoMapper(target = DeviceInstallInfo.class) +@FilterDef(name = "tenantFilter", parameters = {@ParamDef(name = "tenantId", type = "long")}) +@Filter(name = "tenantFilter", condition = "tenant_id = :tenantId") +@EntityListeners(TenantListener.class) +public class TbDeviceInstallInfo extends BaseEntity implements TenantAware { + + @Id + @GeneratedValue(generator = "SnowflakeIdGenerator") + @GenericGenerator(name = "SnowflakeIdGenerator", strategy = "cc.iotkit.data.config.id.SnowflakeIdGenerator") + private String id; + + @ApiModelProperty(value = "设备名称(报警器编号)") + private String deviceName; + @ApiModelProperty(value = "公司名称") + private String corporateName; + @ApiModelProperty(value = "申请时间") + private Date proposerTime; + @ApiModelProperty(value = "申请人") + private String proposer; + @ApiModelProperty(value = "申请班组") + private String proposerTeam; + @ApiModelProperty(value = "小区名称") + private String communityName; + @ApiModelProperty(value = "用户名称") + private String userName; + @ApiModelProperty(value = "用户电话") + private String userIpone; + @ApiModelProperty(value = "楼栋单元号") + private String buildingUnit; + @ApiModelProperty(value = "房间号") + private String roomNo; + @ApiModelProperty(value = "切断阀编号") + private String shutValueNumber; + @ApiModelProperty(value = "燃气表号") + private String gasMeterNumber; + @ApiModelProperty(value = "备注") + private String remarks; + @ApiModelProperty(value = "安装前图片") + private String beforeInstallationImage; + @ApiModelProperty(value = "装完成探测器工作图片") + private String workingOfTheDetectorImage; + @ApiModelProperty(value = "测漏图片") + private String sideLeakageImage; + @ApiModelProperty(value = "点火图片") + private String ignitionPictureImage; + @ApiModelProperty(value = "装完成全景图片") + private String installThePanoramicImage; + @ApiModelProperty(value = "燃气表图片") + private String ofGasMeterImage; + @ApiModelProperty(value = "工单图片") + private String workOrderImage; + @ApiModelProperty(value = "打孔图片") + private String punchingImage; + @ApiModelProperty(value = "装电源线照片") + private String fiexImage; + + @ApiModelProperty(value = "用户id") + private String uid; + @ApiModelProperty(value = "租户编号") + private Long tenantId; + @ApiModelProperty(value = "0绑定1解绑") + private Integer state; +} diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbRuleInfo.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbRuleInfo.java index f213c7b..ca6fd65 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbRuleInfo.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbRuleInfo.java @@ -93,4 +93,5 @@ public class TbRuleInfo extends BaseEntity implements TenantAware { private Long createAt; private Long tenantId; + } diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbSysDept.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbSysDept.java index 57645b0..7030571 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbSysDept.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbSysDept.java @@ -70,7 +70,6 @@ public class TbSysDept extends BaseEntity implements TenantAware { * 租户编号 */ @ApiModelProperty(value = "租户ID") - @Column(name = "tenant_id") private Long tenantId; /** @@ -128,5 +127,7 @@ public class TbSysDept extends BaseEntity implements TenantAware { private String ancestors; @ApiModelProperty(value = "0部门1区域") private Integer areaType; - + private String latitude; + private String longitude; + private String site; } diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/AlertConfigDataImpl.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/AlertConfigDataImpl.java index 4f4b7df..1b30045 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/AlertConfigDataImpl.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/AlertConfigDataImpl.java @@ -38,6 +38,7 @@ import cc.iotkit.model.alert.AlertConfig; import cc.iotkit.model.system.SysDictData; import cn.hutool.core.util.ObjectUtil; import com.querydsl.core.types.Predicate; +import com.querydsl.jpa.impl.JPAQueryFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Primary; import org.springframework.data.domain.Page; @@ -57,7 +58,8 @@ public class AlertConfigDataImpl implements IAlertConfigData, IJPACommData findByUidAndRuleInfoId(String uid, String ruleInfoId) { - return alertConfigRepository.findByUidAndRuleInfoId(uid, ruleInfoId); + return MapstructUtils.convert(alertConfigRepository.findByUidAndRuleInfoId(uid, ruleInfoId), AlertConfig.class); // return new Paging<>(alertConfigPage.getTotalElements(), MapstructUtils.convert(alertConfigPage.getContent(), AlertConfig.class)); } + @Override + public List findByUidAndRuleInfoIdAndDeviceName(String uid, String ruleInfoId, String deviceName) { + return MapstructUtils.convert(alertConfigRepository.findByUidAndRuleInfoIdAndDeviceName(uid, ruleInfoId,deviceName), AlertConfig.class); + // return new Paging<>(alertConfigPage.getTotalElements(), MapstructUtils.convert(alertConfigPage.getContent(), AlertConfig.class)); + } + private Predicate buildQueryCondition(AlertConfig dictData) { return PredicateBuilder.instance() .and(dictData.getUid() != null, () -> tbAlertConfig.uid.eq(AuthUtil.getUserId())).build(); diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/AlertRecordDataImpl.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/AlertRecordDataImpl.java index e8573fa..d1d69a6 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/AlertRecordDataImpl.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/AlertRecordDataImpl.java @@ -27,6 +27,7 @@ import cc.iotkit.common.api.PageRequest; import cc.iotkit.common.api.Paging; import cc.iotkit.common.satoken.utils.AuthUtil; import cc.iotkit.common.satoken.utils.LoginHelper; +import cc.iotkit.common.tenant.helper.TenantHelper; import cc.iotkit.common.utils.MapstructUtils; import cc.iotkit.common.utils.StringUtils; import cc.iotkit.data.dao.AlertRecordRepository; @@ -57,6 +58,7 @@ import org.springframework.stereotype.Service; import java.time.Instant; import java.time.LocalDate; +import java.time.LocalDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.List; @@ -95,28 +97,60 @@ public class AlertRecordDataImpl implements IAlertRecordData, IJPACommData tbAlertRecord.name.like(data.getName())) - .and(StringUtils.isNotBlank(data.getLevel()), () -> tbAlertRecord.level.eq(data.getLevel())) - .and(StringUtils.isNotBlank(data.getUid()), () -> tbAlertRecord.uid.eq(data.getUid())) - .and(flag, () -> (BooleanExpression) genTimePredicate(data.getParams())) - - .build(); + if(!LoginHelper.isSuperAdmin()) { + return PredicateBuilder.instance() + .and(StringUtils.isNotBlank(data.getName()), () -> tbAlertRecord.name.like("%" + data.getName() + "%")) + .and(StringUtils.isNotBlank(data.getLevel()), () -> tbAlertRecord.level.eq(data.getLevel())) + .and(StringUtils.isNotBlank(data.getUid()), () -> tbAlertRecord.uid.eq(data.getUid())) + .and(ObjectUtil.isNotEmpty(TenantHelper.getTenantId()), () -> tbAlertRecord.tenantId.eq(TenantHelper.getTenantId())) + .and(flag, () -> (BooleanExpression) genTimePredicate(data.getParams())) + .build(); + }else{ + if(TenantHelper.getTenantId() != 0) { + return PredicateBuilder.instance() + .and(StringUtils.isNotBlank(data.getName()), () -> tbAlertRecord.name.like("%" + data.getName() + "%")) + .and(StringUtils.isNotBlank(data.getLevel()), () -> tbAlertRecord.level.eq(data.getLevel())) + .and(StringUtils.isNotBlank(data.getUid()), () -> tbAlertRecord.uid.eq(data.getUid())) + .and(ObjectUtil.isNotEmpty(TenantHelper.getTenantId()), () -> tbAlertRecord.tenantId.eq(TenantHelper.getTenantId())) + .and(flag, () -> (BooleanExpression) genTimePredicate(data.getParams())) + .build(); + }else{ + return PredicateBuilder.instance() + .and(StringUtils.isNotBlank(data.getName()), () -> tbAlertRecord.name.like("%" + data.getName() + "%")) + .and(StringUtils.isNotBlank(data.getLevel()), () -> tbAlertRecord.level.eq(data.getLevel())) + .and(StringUtils.isNotBlank(data.getUid()), () -> tbAlertRecord.uid.eq(data.getUid())) + // .and(ObjectUtil.isNotEmpty(TenantHelper.getTenantId()), () -> tbAlertRecord.tenantId.eq(TenantHelper.getTenantId())) + .and(flag, () -> (BooleanExpression) genTimePredicate(data.getParams())) + .build(); + } + } }else{ if(!LoginHelper.isSuperAdmin()){ return PredicateBuilder.instance() .and(StringUtils.isNotBlank(data.getUid()), () -> tbAlertRecord.uid.eq(data.getUid())) + .and(ObjectUtil.isNotEmpty(TenantHelper.getTenantId()), () -> tbAlertRecord.tenantId.eq(TenantHelper.getTenantId())) //.and(data != null && StringUtils.isNotBlank(data.getLevel()), () -> tbAlertRecord.level.eq(data.getLevel())) .build(); - } - return PredicateBuilder.instance() - //.and(data != null && StringUtils.isNotBlank(data.getLevel()), () -> tbAlertRecord.level.eq(data.getLevel())) - .build(); + }else { + if(TenantHelper.getTenantId() != 0) { + return PredicateBuilder.instance() + .and(ObjectUtil.isNotEmpty(TenantHelper.getTenantId()), () -> tbAlertRecord.tenantId.eq(TenantHelper.getTenantId())) + //.and(data != null && StringUtils.isNotBlank(data.getLevel()), () -> tbAlertRecord.level.eq(data.getLevel())) + .build(); + }else{ + return PredicateBuilder.instance() + // .and(ObjectUtil.isNotEmpty(TenantHelper.getTenantId()), () -> tbAlertRecord.tenantId.eq(TenantHelper.getTenantId())) + //.and(data != null && StringUtils.isNotBlank(data.getLevel()), () -> tbAlertRecord.level.eq(data.getLevel())) + .build(); + } + } } } @@ -138,7 +172,7 @@ public class AlertRecordDataImpl implements IAlertRecordData, IJPACommData + String beginTime = params.get("beginTime").toString(); + String endTime = params.get("endTime").toString(); + + LocalDateTime beginDateTime = LocalDateTime.parse(beginTime, formatter); + LocalDateTime endDateTime = LocalDateTime.parse(endTime, formatter); + + long beginMillis = beginDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); + long endMillis = endDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); /*return PredicateBuilder.instance() .and(tbAlertRecord.alertTime.between(beginSec, endSec));*/ - return tbAlertRecord.alertTime.between(beginSec, endSec); + return tbAlertRecord.alertTime.between(beginMillis, endMillis); } @Override @@ -181,6 +226,8 @@ public class AlertRecordDataImpl implements IAlertRecordData, IJPACommData findAll() { return categoryRepository.findAll().stream() .map(c -> MapstructUtils.convert(c, Category.class)) + .sorted(Comparator.comparing(Category::getCreateTime).reversed()) .collect(Collectors.toList()); } diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/DIccidRecordDataImpl.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/DIccidRecordDataImpl.java index 1fe6767..3e738fd 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/DIccidRecordDataImpl.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/DIccidRecordDataImpl.java @@ -31,8 +31,10 @@ import cc.iotkit.data.dao.IJPACommData; import cc.iotkit.data.manager.IDIccidRecordData; import cc.iotkit.data.manager.IHomeData; import cc.iotkit.data.model.TbDIccidRecordDO; +import cc.iotkit.data.model.TbDeviceInfo; import cc.iotkit.data.model.TbHome; import cc.iotkit.data.util.PredicateBuilder; +import cc.iotkit.model.device.DeviceInfo; import cc.iotkit.model.iccid.DIccidRecordDO; import cc.iotkit.model.space.Home; import com.querydsl.jpa.impl.JPAQueryFactory; @@ -73,6 +75,10 @@ public class DIccidRecordDataImpl implements IDIccidRecordData, IJPACommData { + + @Autowired + private DeviceIDetectornfoRepository homeRepository; + + private final JPAQueryFactory jpaQueryFactory; + + @Override + public JpaRepository getBaseRepository() { + return homeRepository; + } + + @Override + public Class getJpaRepositoryClass() { + return TbDeviceDetectorInfo.class; + } + + @Override + public Class getTClass() { + return DeviceDetectorInfo.class; + } + + +} diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/DeviceInfoDataImpl.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/DeviceInfoDataImpl.java index a22e7a5..811630c 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/DeviceInfoDataImpl.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/DeviceInfoDataImpl.java @@ -25,7 +25,9 @@ package cc.iotkit.data.service; import cc.iotkit.common.api.PageRequest; import cc.iotkit.common.api.Paging; +import cc.iotkit.common.enums.UserType; import cc.iotkit.common.satoken.utils.LoginHelper; +import cc.iotkit.common.tenant.helper.TenantHelper; import cc.iotkit.common.utils.MapstructUtils; import cc.iotkit.common.utils.ReflectUtil; import cc.iotkit.common.utils.StreamUtils; @@ -35,6 +37,8 @@ import cc.iotkit.data.manager.IDeviceInfoData; import cc.iotkit.data.manager.IProductData; import cc.iotkit.data.model.*; import cc.iotkit.data.system.ISysDeptData; +import cc.iotkit.data.system.ISysTenantData; +import cc.iotkit.data.system.ISysUserData; import cc.iotkit.data.util.PageBuilder; import cc.iotkit.data.util.PredicateBuilder; import cc.iotkit.model.alert.AlertRecord; @@ -42,12 +46,12 @@ import cc.iotkit.model.device.DeviceInfo; import cc.iotkit.model.device.message.DevicePropertyCache; import cc.iotkit.model.product.Category; import cc.iotkit.model.product.Product; -import cc.iotkit.model.stats.AlertStatDTO; -import cc.iotkit.model.stats.DataItem; -import cc.iotkit.model.stats.DeviceProduckDTO; -import cc.iotkit.model.stats.ProductKeyCountDTO; +import cc.iotkit.model.stats.*; import cc.iotkit.model.system.SysDept; +import cc.iotkit.model.system.SysTenant; +import cc.iotkit.model.system.SysUser; import cn.hutool.core.util.ObjectUtil; +import com.querydsl.core.Tuple; import com.querydsl.core.types.Predicate; import com.querydsl.core.types.Projections; import com.querydsl.core.types.dsl.BooleanExpression; @@ -57,6 +61,7 @@ import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Primary; import org.springframework.data.domain.Page; @@ -77,6 +82,7 @@ import static cc.iotkit.data.model.QTbDeviceGroupMapping.tbDeviceGroupMapping; import static cc.iotkit.data.model.QTbDeviceInfo.tbDeviceInfo; import static cc.iotkit.data.model.QTbDeviceSubUser.tbDeviceSubUser; import static cc.iotkit.data.model.QTbProduct.tbProduct; +import static cc.iotkit.data.model.QTbSysTenant.tbSysTenant; import static cc.iotkit.data.model.QTbSysUser.tbSysUser; @Primary @@ -84,7 +90,9 @@ import static cc.iotkit.data.model.QTbSysUser.tbSysUser; @RequiredArgsConstructor public class DeviceInfoDataImpl implements IDeviceInfoData, IJPACommData { + private final ISysUserData isSysUserData; private final ISysDeptData sysDeptData; + private final ISysTenantData isSysTenantData; private final DeviceInfoRepository deviceInfoRepository; private final DeviceSubUserRepository deviceSubUserRepository; @@ -127,6 +135,101 @@ public class DeviceInfoDataImpl implements IDeviceInfoData, IJPACommData(); } + public SysDeptDto getStatsCount(Long deptAreaId){ + SysDeptDto statistics = new SysDeptDto(); + List areaIds = null; + List results = null; + if (ObjectUtil.isNotNull(deptAreaId)) { + + // if (Objects.nonNull(user) && Objects.nonNull(user.getDeptAreaId())) { + Long areaId = deptAreaId; + List depts = sysDeptData.findByDeptId(areaId); + areaIds = StreamUtils.toList(depts, SysDept::getId); + areaIds.add(areaId); + /* if (ObjectUtil.isNotEmpty(areaIds)) { + query.where(tbDeviceInfo.deptAreaId.in(areaIds)); + }*/ + }else{ + if(!LoginHelper.isSuperAdmin()) { + SysUser user = isSysUserData.findById(LoginHelper.getUserId()); + if (ObjectUtil.isNotNull(user)) { + if(ObjectUtil.isNotNull(user.getDeptAreaId())) { + + // if (Objects.nonNull(user) && Objects.nonNull(user.getDeptAreaId())) { + Long areaId = user.getDeptAreaId(); + List depts = sysDeptData.findByDeptId(areaId); + areaIds = StreamUtils.toList(depts, SysDept::getId); + areaIds.add(areaId); + } + /* if (ObjectUtil.isNotEmpty(areaIds)) { + query.where(tbDeviceInfo.deptAreaId.in(areaIds)); + } + }else{ + //没有绑定区域查不到设备 + query.where(tbDeviceInfo.id.eq("0")); + }*/ + } + + + } + } + + //JPAQuery query = jpaQueryFactory.selectFrom(tbDeviceInfo); + if(ObjectUtil.isNotEmpty(areaIds)) { + results = jpaQueryFactory + .select( + tbDeviceInfo.deviceStatus, + tbDeviceInfo.count() + ) + .from(tbDeviceInfo) + .where(tbDeviceInfo.deptAreaId.in(areaIds)) + .groupBy(tbDeviceInfo.deviceStatus) + .fetch(); + }else{ + if(LoginHelper.isSuperAdmin()) { + results = jpaQueryFactory + .select( + tbDeviceInfo.deviceStatus, + tbDeviceInfo.count() + ) + .from(tbDeviceInfo) + // .where(tbDeviceInfo.deptAreaId.in(areaIds)) + .groupBy(tbDeviceInfo.deviceStatus) + .fetch(); + } + } + for (Tuple tuple : results) { + Integer status = ObjectUtil.isNotNull(tuple.get(tbDeviceInfo.deviceStatus)) ?tuple.get(tbDeviceInfo.deviceStatus) :0; + Long count = tuple.get(tbDeviceInfo.count()); + switch (status) { + case 0: + statistics.setNormalCount(count); + //设备状态0:正常 + break; + case 1: + statistics.setFaultCount( count); + //设备状态1:故障 + break; + case 2: + statistics.setAlarmCount( count); + //设备状态2:告警 + break; + case 3: + statistics.setOnlineCount( count); + //设备状态3:离线 + break; + case 4: + statistics.setExpireCount( count); + //设备状态:到期 + break; + default: + break; + } + System.out.println(status + ": " + count); + } + return statistics; + + }; @Override public long getPropertyUpdateTime(String deviceId) { return 0; @@ -182,12 +285,59 @@ public class DeviceInfoDataImpl implements IDeviceInfoData, IJPACommData groupMappings = deviceGroupMappingRepository.findByDeviceId(deviceId); + Map groups = new HashMap<>(); + for (TbDeviceGroupMapping mapping : groupMappings) { + TbDeviceGroup deviceGroup = deviceGroupRepository.findById(mapping.getGroupId()).orElse(null); + if (deviceGroup == null) { + continue; + } + groups.put(deviceGroup.getId(), new DeviceInfo.Group(deviceGroup.getId(), deviceGroup.getName())); + } + dto.setGroup(groups); + //取设备标签 + List deviceTags = deviceTagRepository.findByDeviceId(deviceId); + Map tagMap = new HashMap<>(); + for (TbDeviceTag tag : deviceTags) { + tagMap.put(tag.getCode(), new DeviceInfo.Tag(tag.getCode(), tag.getName(), tag.getValue())); + } + dto.setTag(tagMap); + if (ObjectUtil.isNotNull(vo.getTenantId())) { + SysTenant sysTenant = new SysTenant(); + sysTenant.setTenantId(vo.getTenantId()); + SysTenant sysTenant1 = isSysTenantData.findOneByCondition(sysTenant); + if (sysTenant1 != null) { + dto.setTenantName(sysTenant1.getCompanyName()); + } + + }*/ + //将设备状态从vo转为dto的 + parseStateToDto(vo, dto); + return dto; + } /** * 将设备状态从vo转为dto的 */ @@ -240,6 +390,10 @@ public class DeviceInfoDataImpl implements IDeviceInfoData, IJPACommData findByDeptAreaIdAndProductKey(Long deptAreaId, String productKey) { + return parseVoToDto(deviceInfoRepository.findByDeptAreaIdAndProductKey(deptAreaId, productKey)); + } @Override public List findByParentId(String parentId) { @@ -268,13 +422,21 @@ public class DeviceInfoDataImpl implements IDeviceInfoData, IJPACommData findNeverUsedDevices() { JPAQuery query = jpaQueryFactory.selectFrom(tbDeviceInfo); query.where(tbDeviceInfo.onlineTime.isNull()); + if(ObjectUtil.isNotNull(TenantHelper.getTenantId())) { + if (!LoginHelper.isSuperAdmin()) { + + query.where(tbDeviceInfo.tenantId.eq(TenantHelper.getTenantId())); + } else if (LoginHelper.isSuperAdmin() && TenantHelper.getTenantId() != 0) { + query.where(tbDeviceInfo.tenantId.eq(TenantHelper.getTenantId())); + } + } List devices = query.fetch(); return MapstructUtils.convert(devices, DeviceInfo.class); } @Override public List getDeviceRecord() { - QTbDeviceInfo device = QTbDeviceInfo.tbDeviceInfo; - QTbProduct product = QTbProduct.tbProduct; + QTbDeviceInfo device = tbDeviceInfo; + QTbProduct product = tbProduct; // 在线设备统计 List onlineStats = jpaQueryFactory .select(Projections.constructor( @@ -340,15 +502,16 @@ public class DeviceInfoDataImpl implements IDeviceInfoData, IJPACommData areaIds; @@ -360,6 +523,32 @@ public class DeviceInfoDataImpl implements IDeviceInfoData, IJPACommData areaIds; + // if (Objects.nonNull(user) && Objects.nonNull(user.getDeptAreaId())) { + Long areaId = user.getDeptAreaId(); + List depts = sysDeptData.findByDeptId(areaId); + areaIds = StreamUtils.toList(depts, SysDept::getId); + areaIds.add(areaId); + if (ObjectUtil.isNotEmpty(areaIds)) { + query.where(tbDeviceInfo.deptAreaId.in(areaIds)); + } + } else { + if(ObjectUtil.isNotEmpty(LoginHelper.getUserType()) && !LoginHelper.getUserType().equals(UserType.APP_USER)) { + //没有绑定区域查不到设备 + query.where(tbDeviceInfo.id.eq("0")); + } + } + } + } + + } } if (StringUtils.isNotBlank(subUid)) { query.join(tbDeviceSubUser).on(tbDeviceSubUser.deviceId.eq(tbDeviceInfo.deviceId)); @@ -392,7 +581,81 @@ public class DeviceInfoDataImpl implements IDeviceInfoData, IJPACommData(total, deviceInfos); } + @Override + public Paging findByConditions1(String name, String uid, String subUid, + String productKey, String groupId, + Boolean online, String keyword, + int page, int size, Long deptAreaId) { + JPAQuery query = jpaQueryFactory.selectFrom(tbDeviceInfo); + + // 根据groupId, 如果groupId存在,则关联查询TbDeviceGroupMapping, 根据groupId,查询对应的devices + if (StringUtils.isNotBlank(groupId)) { + query.join(tbDeviceGroupMapping).on(tbDeviceGroupMapping.deviceId.eq(tbDeviceInfo.deviceId)); + query.where(tbDeviceGroupMapping.groupId.eq(groupId)); + } + + if (StringUtils.isNotBlank(uid)) { + query.where(tbDeviceInfo.uid.eq(uid)); + } + if (StringUtils.isNotBlank(name)) { + query.where(tbDeviceInfo.name.like("%" + name + "%")); + } + System.out.println(TenantHelper.getTenantId()); + if (ObjectUtil.isNotNull(TenantHelper.getTenantId()) && (!LoginHelper.isSuperAdmin() || TenantHelper.getTenantId()!=0)) { + query.where(tbDeviceInfo.tenantId.eq(TenantHelper.getTenantId())); + } + if (ObjectUtil.isNotNull(deptAreaId)) { + query.where(tbDeviceInfo.deptAreaId.eq(deptAreaId)); + }else{ + if(!LoginHelper.isSuperAdmin()) { + if(ObjectUtil.isNotEmpty(LoginHelper.getUserId())) { + SysUser user = isSysUserData.findById(LoginHelper.getUserId()); + if (ObjectUtil.isNotNull(user)) { + if (ObjectUtil.isNotNull(user.getDeptAreaId())) { + query.where(tbDeviceInfo.deptAreaId.eq(user.getDeptAreaId())); + } else { + if(ObjectUtil.isNotEmpty(LoginHelper.getUserType()) && !LoginHelper.getUserType().equals(UserType.APP_USER)) { + //没有绑定区域查不到设备 + query.where(tbDeviceInfo.id.eq("0")); + } + } + } + } + + } + } + if (StringUtils.isNotBlank(subUid)) { + query.join(tbDeviceSubUser).on(tbDeviceSubUser.deviceId.eq(tbDeviceInfo.deviceId)); + query.where(tbDeviceSubUser.uid.eq(subUid)); + } + + if (StringUtils.isNotBlank(productKey)) { + query.where(tbDeviceInfo.productKey.eq(productKey)); + } + + if (online != null) { + query.where(tbDeviceInfo.state.eq(online ? "online" : "offline")); + } + + if (StringUtils.isNotBlank(keyword)) { + query.where(tbDeviceInfo.deviceId.like("%" + keyword + "%") + .or(tbDeviceInfo.deviceName.like("%" + keyword + "%"))); + } + + query.orderBy(tbDeviceInfo.createAt.desc()); + query.offset((page - 1) * size).limit(size); + + List tbDeviceInfos = query.fetch(); + long total = query.fetchCount(); + List deviceInfos = new ArrayList<>(tbDeviceInfos.size()); + for (TbDeviceInfo tbDeviceInfo : tbDeviceInfos) { + DeviceInfo deviceInfo = MapstructUtils.convert(tbDeviceInfo, DeviceInfo.class); + fillDeviceInfo(tbDeviceInfo.getDeviceId(), tbDeviceInfo, deviceInfo); + deviceInfos.add(deviceInfo); + } + return new Paging<>(total, deviceInfos); + } @Override public List findByConditionsList(String productKey) { JPAQuery query = jpaQueryFactory.selectFrom(tbDeviceInfo); @@ -441,7 +704,30 @@ public class DeviceInfoDataImpl implements IDeviceInfoData, IJPACommData findByConditionsList(String productKey,Boolean flag) { + JPAQuery query = jpaQueryFactory.selectFrom(tbDeviceInfo); + if (flag) { + query.where(tbDeviceInfo.latitude.isNotNull()); + } + + if (StringUtils.isNotBlank(productKey)) { + query.where(tbDeviceInfo.productKey.eq(productKey)); + } + query.orderBy(tbDeviceInfo.createAt.desc()); + // query.offset((page - 1) * size).limit(size); + + List tbDeviceInfos = query.fetch(); + long total = query.fetchCount(); + List deviceInfos = new ArrayList<>(tbDeviceInfos.size()); + for (TbDeviceInfo tbDeviceInfo : tbDeviceInfos) { + DeviceInfo deviceInfo = MapstructUtils.convert(tbDeviceInfo, DeviceInfo.class); + fillDeviceInfo1(tbDeviceInfo.getDeviceId(), tbDeviceInfo, deviceInfo); + deviceInfos.add(deviceInfo); + } + return deviceInfos; + } @Override public void updateTag(String deviceId, DeviceInfo.Tag tag) { TbDeviceTag deviceTag = deviceTagRepository.findByDeviceIdAndCode(deviceId, tag.getId()); @@ -502,6 +788,11 @@ public class DeviceInfoDataImpl implements IDeviceInfoData, IJPACommData deptAreaId,String startDate, String endDate) { boolean hasValidConditions = false; PredicateBuilder builder = PredicateBuilder.instance(); @@ -509,7 +800,10 @@ public class DeviceInfoDataImpl implements IDeviceInfoData, IJPACommData tbDeviceInfo.deptAreaId.in(deptAreaId)); } - if (ObjectUtil.isNotNull(endDate)) { + if(!LoginHelper.isSuperAdmin()) { + builder.and(ObjectUtil.isNotEmpty(TenantHelper.getTenantId()), () -> tbDeviceInfo.tenantId.eq(TenantHelper.getTenantId())); + hasValidConditions = true; + } if (ObjectUtil.isNotNull(endDate)) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); Date beginDate = Date.from(LocalDate.parse(startDate).atStartOfDay(ZoneId.systemDefault()).toInstant()); @@ -539,8 +833,8 @@ public class DeviceInfoDataImpl implements IDeviceInfoData, IJPACommData getProductDevice(Long deptAreaId,String startDate, String endDate) { - QTbDeviceInfo record = QTbDeviceInfo.tbDeviceInfo; - QTbProduct product = QTbProduct.tbProduct; + QTbDeviceInfo record = tbDeviceInfo; + QTbProduct product = tbProduct; List areaIds = new ArrayList<>(); if (ObjectUtil.isNotNull(deptAreaId)) { // if (Objects.nonNull(user) && Objects.nonNull(user.getDeptAreaId())) { @@ -551,6 +845,22 @@ public class DeviceInfoDataImpl implements IDeviceInfoData, IJPACommData depts = sysDeptData.findByDeptId(sysUser.getDeptAreaId()); + areaIds = StreamUtils.toList(depts, SysDept::getId); + areaIds.add(sysUser.getDeptAreaId()); + } + } + } + } + if(ObjectUtil.isNull(deptAreaId) && LoginHelper.isSuperAdmin() && ObjectUtil.isNotNull(TenantHelper.getTenantId()) && TenantHelper.getTenantId() != 0) { + List depts = sysDeptData.findByTenantId(TenantHelper.getTenantId()); + areaIds = StreamUtils.toList(depts, SysDept::getId); + //areaIds.add(sysUser.getDeptAreaId()); } return jpaQueryFactory @@ -572,7 +882,7 @@ public class DeviceInfoDataImpl implements IDeviceInfoData, IJPACommData buildQuery(Predicate predicate) { List devices = jpaQueryFactory.select(Projections.bean(TbDeviceInfo.class, tbDeviceInfo.uid, tbDeviceInfo.deviceId, tbDeviceInfo.productKey, tbDeviceInfo.deviceName, tbDeviceInfo.state, tbDeviceInfo.createAt, - tbDeviceInfo.id, tbDeviceInfo.onlineTime, tbDeviceInfo.parentId, tbDeviceInfo.latitude, tbDeviceInfo.longitude, tbDeviceInfo.model, + tbDeviceInfo.id, tbDeviceInfo.onlineTime, tbDeviceInfo.parentId, tbDeviceInfo.tenantId, tbDeviceInfo.deptAreaId,tbDeviceInfo.latitude, tbDeviceInfo.longitude, tbDeviceInfo.model, tbDeviceInfo.offlineTime, tbDeviceInfo.secret)) .from(tbDeviceInfo) .where(predicate).fetch(); @@ -729,11 +1039,30 @@ public class DeviceInfoDataImpl implements IDeviceInfoData, IJPACommData tbDeviceInfo.id.eq(device.getId())) - .and(ObjectUtil.isNotNull(device.getDeviceName()), () -> tbDeviceInfo.deviceName.eq(device.getDeviceName())) - .and(ObjectUtil.isNotNull(device.getState()), () -> tbDeviceInfo.state.eq(device.getState().isOnline() ? "online" : "offline")) - .build(); + if(LoginHelper.isSuperAdmin() && TenantHelper.getTenantId() !=0) { + return PredicateBuilder.instance() + .and(ObjectUtil.isNotNull(device.getId()), () -> tbDeviceInfo.id.eq(device.getId())) + .and(ObjectUtil.isNotNull(TenantHelper.getTenantId()), () -> tbDeviceInfo.tenantId.eq(TenantHelper.getTenantId())) + .and(ObjectUtil.isNotNull(device.getDeviceName()), () -> tbDeviceInfo.deviceName.eq(device.getDeviceName())) + .and(ObjectUtil.isNotNull(device.getState()), () -> tbDeviceInfo.state.eq(device.getState().isOnline() ? "online" : "offline")) + //.and(device.isFlag(), tbDeviceInfo.latitude::isNotNull) + .build(); + }else if(LoginHelper.isSuperAdmin()) { + return PredicateBuilder.instance() + .and(ObjectUtil.isNotNull(device.getId()), () -> tbDeviceInfo.id.eq(device.getId())) + .and(ObjectUtil.isNotNull(device.getDeviceName()), () -> tbDeviceInfo.deviceName.eq(device.getDeviceName())) + .and(ObjectUtil.isNotNull(device.getState()), () -> tbDeviceInfo.state.eq(device.getState().isOnline() ? "online" : "offline")) + // .and(device.isFlag(), tbDeviceInfo.latitude::isNotNull) + .build(); + } else{ + return PredicateBuilder.instance() + .and(ObjectUtil.isNotNull(device.getId()), () -> tbDeviceInfo.id.eq(device.getId())) + .and(ObjectUtil.isNotNull(TenantHelper.getTenantId()), () -> tbDeviceInfo.tenantId.eq(TenantHelper.getTenantId())) + .and(ObjectUtil.isNotNull(device.getDeviceName()), () -> tbDeviceInfo.deviceName.eq(device.getDeviceName())) + .and(ObjectUtil.isNotNull(device.getState()), () -> tbDeviceInfo.state.eq(device.getState().isOnline() ? "online" : "offline")) + // .and(device.isFlag(), tbDeviceInfo.latitude::isNotNull) + .build(); + } } } diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/DeviceInstallInfoDataImpl.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/DeviceInstallInfoDataImpl.java new file mode 100644 index 0000000..4d7d912 --- /dev/null +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/DeviceInstallInfoDataImpl.java @@ -0,0 +1,80 @@ +/* + * + * * | Licensed 未经许可不能去掉「OPENIITA」相关版权 + * * +---------------------------------------------------------------------- + * * | Author: xw2sy@163.com + * * +---------------------------------------------------------------------- + * + * Copyright [2024] [OPENIITA] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * / + */ + +package cc.iotkit.data.service; + +import cc.iotkit.common.utils.MapstructUtils; +import cc.iotkit.data.dao.DeviceIDetectornfoRepository; +import cc.iotkit.data.dao.DeviceInstallInfoRepository; +import cc.iotkit.data.dao.IJPACommData; +import cc.iotkit.data.manager.IDeviceDetectorInfoData; +import cc.iotkit.data.manager.IDeviceInstallInfoData; +import cc.iotkit.data.model.TbDeviceDetectorInfo; +import cc.iotkit.data.model.TbDeviceInstallInfo; +import cc.iotkit.model.device.DeviceConfig; +import cc.iotkit.model.device.DeviceDetectorInfo; +import cc.iotkit.model.device.DeviceInstallInfo; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Service; + +@Primary +@Service +@RequiredArgsConstructor +public class DeviceInstallInfoDataImpl implements IDeviceInstallInfoData, IJPACommData { + + @Autowired + private DeviceInstallInfoRepository homeRepository; + + private final JPAQueryFactory jpaQueryFactory; + + @Override + public JpaRepository getBaseRepository() { + return homeRepository; + } + + @Override + public Class getJpaRepositoryClass() { + return TbDeviceInstallInfo.class; + } + + @Override + public Class getTClass() { + return DeviceInstallInfo.class; + } + + + @Override + public DeviceInstallInfo findByDeviceNameAndUid(String deviceName,String uid) { + return MapstructUtils.convert(homeRepository.findByDeviceNameAndUid(deviceName,uid), DeviceInstallInfo.class); + // return homeRepository.findByDeviceName(deviceName); + } + + @Override + public DeviceInstallInfo findByDeviceNameAndUidAndState(String deviceName, String uid, Integer state) { + return MapstructUtils.convert(homeRepository.findByDeviceNameAndUidAndState(deviceName,uid,state), DeviceInstallInfo.class); + } +} diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/RuleInfoDataImpl.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/RuleInfoDataImpl.java index e5df003..7a913f2 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/RuleInfoDataImpl.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/RuleInfoDataImpl.java @@ -31,10 +31,13 @@ import cc.iotkit.data.dao.RuleInfoRepository; import cc.iotkit.data.model.TbRuleInfo; import cc.iotkit.common.api.Paging; import cc.iotkit.data.model.TbTaskInfo; +import cc.iotkit.data.system.ISysTenantData; import cc.iotkit.data.util.PageBuilder; import cc.iotkit.model.rule.FilterConfig; import cc.iotkit.model.rule.RuleAction; import cc.iotkit.model.rule.RuleInfo; +import cc.iotkit.model.system.SysTenant; +import cn.hutool.core.util.ObjectUtil; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Primary; @@ -55,7 +58,8 @@ public class RuleInfoDataImpl implements IRuleInfoData, IJPACommData findByType(String type, int page, int size) { Page paged = ruleInfoRepository.findByType(type, Pageable.ofSize(size).withPage(page - 1)); + List ruleInfoList = fromTb(paged.getContent()); + for (RuleInfo tbRule :ruleInfoList) { + if (ObjectUtil.isNotNull(tbRule.getTenantId())) { + SysTenant sysTenant = new SysTenant(); + sysTenant.setTenantId(tbRule.getTenantId()); + SysTenant sysTenant1 = isSysTenantData.findOneByCondition(sysTenant); + if (sysTenant1 != null) { + tbRule.setTenantName(sysTenant1.getCompanyName()); + } + } + + } + return new Paging<>(paged.getTotalElements(), - fromTb(paged.getContent())); + ruleInfoList); } @Override diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysConfigDataImpl.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysConfigDataImpl.java index e1cdf56..2473a23 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysConfigDataImpl.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysConfigDataImpl.java @@ -28,6 +28,7 @@ import cc.iotkit.common.api.PageRequest; import cc.iotkit.common.api.Paging; import cc.iotkit.common.enums.ErrCode; import cc.iotkit.common.exception.BizException; +import cc.iotkit.common.tenant.helper.TenantHelper; import cc.iotkit.common.utils.MapstructUtils; import cc.iotkit.common.utils.StringUtils; import cc.iotkit.data.dao.IJPACommData; @@ -107,9 +108,9 @@ public class SysConfigDataImpl implements ISysConfigData, IJPACommData findAll(PageRequest pageRequest) { SysConfig query = pageRequest.getData(); Predicate predicate = PredicateBuilder.instance() - .and(StringUtils.isNotEmpty(query.getConfigName()), () -> tbSysConfig.configName.like(query.getConfigName())) + .and(StringUtils.isNotEmpty(query.getConfigName()), () -> tbSysConfig.configName.like("%"+query.getConfigName()+"%")) .and(StringUtils.isNotEmpty(query.getConfigType()), () -> tbSysConfig.configType.eq(query.getConfigType())) - .and(StringUtils.isNotEmpty(query.getConfigKey()), () -> tbSysConfig.configKey.like(query.getConfigKey())) + .and(StringUtils.isNotEmpty(query.getConfigKey()), () -> tbSysConfig.configKey.like("%"+query.getConfigKey()+"%")) .build(); Page all = baseRepository.findAll(predicate, PageBuilder.toPageable(pageRequest)); return PageBuilder.toPaging(all, SysConfig.class); @@ -140,7 +141,7 @@ public class SysConfigDataImpl implements ISysConfigData, IJPACommData tbSysConfig.configKey.eq(data.getConfigKey())) - .and(StringUtils.isNotEmpty(data.getConfigName()), () -> tbSysConfig.configName.like(data.getConfigName())) + .and(StringUtils.isNotEmpty(data.getConfigName()), () -> tbSysConfig.configName.like("%"+data.getConfigName()+"%")) .and(StringUtils.isNotEmpty(data.getConfigType()), () -> tbSysConfig.configType.eq(data.getConfigType())) .build(); } diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysDeptDataImpl.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysDeptDataImpl.java index bbdb687..51f4ae8 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysDeptDataImpl.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysDeptDataImpl.java @@ -24,14 +24,21 @@ package cc.iotkit.data.service; import cc.iotkit.common.constant.UserConstants; +import cc.iotkit.common.enums.UserType; +import cc.iotkit.common.satoken.utils.LoginHelper; +import cc.iotkit.common.tenant.helper.TenantHelper; import cc.iotkit.common.utils.MapstructUtils; +import cc.iotkit.common.utils.StreamUtils; import cc.iotkit.common.utils.StringUtils; import cc.iotkit.data.dao.IJPACommData; import cc.iotkit.data.dao.SysDeptRepository; +import cc.iotkit.data.dao.SysUserRepository; import cc.iotkit.data.model.TbSysDept; +import cc.iotkit.data.model.TbSysUser; import cc.iotkit.data.system.ISysDeptData; import cc.iotkit.data.util.PredicateBuilder; import cc.iotkit.model.system.SysDept; +import cc.iotkit.model.system.SysUser; import cn.hutool.core.util.ObjectUtil; import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; @@ -41,6 +48,7 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Service; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.StreamSupport; @@ -58,6 +66,8 @@ public class SysDeptDataImpl implements ISysDeptData, IJPACommData findDepts(SysDept dept) { PredicateBuilder predicateBuilder = PredicateBuilder.instance() .and(ObjectUtil.isNotNull(dept.getId()), () -> tbSysDept.id.eq(dept.getId())) - .and(StringUtils.isNotEmpty(dept.getDeptName()), () -> tbSysDept.deptName.like(dept.getDeptName())) + .and(StringUtils.isNotEmpty(dept.getDeptName()), () -> tbSysDept.deptName.like("%" + dept.getDeptName() + "%")) .and(ObjectUtil.isNotNull(dept.getParentId()), () -> tbSysDept.parentId.eq(dept.getParentId())) .and(StringUtils.isNotEmpty(dept.getStatus()), () -> tbSysDept.status.eq(dept.getStatus())); - if(ObjectUtil.isNotNull(dept.getAreaType()) && dept.getAreaType() == 1){ + if (ObjectUtil.isNotNull(dept.getAreaType()) && dept.getAreaType() == 1) { //查询区域(需要查询parentId为0的顶级部门) predicateBuilder.and(ObjectUtil.isNotNull(dept.getAreaType()), () -> tbSysDept.areaType.eq(dept.getAreaType()).or(tbSysDept.parentId.eq(0L))); - }else if(ObjectUtil.isNotNull(dept.getAreaType()) && dept.getAreaType() == 0){ + } else if (ObjectUtil.isNotNull(dept.getAreaType()) && dept.getAreaType() == 0) { //查询部门 predicateBuilder.and(ObjectUtil.isNotNull(dept.getAreaType()), () -> tbSysDept.areaType.eq(dept.getAreaType())); + } else { + // if(ObjectUtil.isNull(dept.getFlag())) { + //查询部门 + predicateBuilder.and(tbSysDept.areaType.eq(0)); + // } } + + /* if(ObjectUtil.isNull(dept.getAreaType()) && ObjectUtil.isNull(dept.getParentId())){ + predicateBuilder.or(tbSysDept.parentId.eq(0L)); + }*/ + if (!LoginHelper.isSuperAdmin()) { + predicateBuilder.and(ObjectUtil.isNotNull(dept.getTenantId()), () -> tbSysDept.tenantId.eq(dept.getTenantId())); + Optional tbSysUser = sysUserData.findById(LoginHelper.getUserId()); + List areaIds; + // if (Objects.nonNull(user) && Objects.nonNull(user.getDeptAreaId())) { + + if (ObjectUtil.isNotEmpty(tbSysUser) && ObjectUtil.isNotEmpty(LoginHelper.getUserType()) && !LoginHelper.getUserType().equals(UserType.APP_USER)) { + if (ObjectUtil.isNotNull(dept.getAreaType()) && dept.getAreaType() == 1) { + //查询区域 + Long areaId = tbSysUser.get().getDeptAreaId(); + List depts = this.findByDeptId(areaId); + List filteredIds = depts.stream() + .filter(dept1 -> dept1.getAreaType() == 1) + .map(SysDept::getId) + .collect(Collectors.toList()); + filteredIds.add(areaId); + + //areaIds = StreamUtils.toList(depts, SysDept::getId); + // areaIds.add(areaId); + predicateBuilder.and(ObjectUtil.isNotNull(tbSysUser.get().getDeptAreaId()), () -> tbSysDept.id.in(filteredIds)); + } else { + /* Long areaId = tbSysUser.get().getDeptId(); + List depts = iSysDeptData.findByDeptId(areaId); + areaIds = StreamUtils.toList(depts, SysDept::getId); + areaIds.add(areaId);*/ + // if(ObjectUtil.isNull(dept.getFlag())) { + Long areaId = tbSysUser.get().getDeptId(); + List depts = this.findByDeptId(areaId); + List filteredIds = depts.stream() + .filter(dept1 -> dept1.getAreaType() == 0) + .map(SysDept::getId) + .collect(Collectors.toList()); + filteredIds.add(areaId); + predicateBuilder.and(ObjectUtil.isNotNull(tbSysUser.get().getDeptId()), () -> tbSysDept.id.in(filteredIds)); + // } + } + predicateBuilder.and(ObjectUtil.isNotNull(TenantHelper.getTenantId()), () -> tbSysDept.tenantId.eq(TenantHelper.getTenantId())); + } + + }/*else{ + if (ObjectUtil.isNotNull(dept.getAreaType()) && dept.getAreaType() == 1) { + + } + }*/ + if (LoginHelper.isSuperAdmin() && TenantHelper.getTenantId() != 0) { + predicateBuilder.and(ObjectUtil.isNotNull(TenantHelper.getTenantId()), () -> tbSysDept.tenantId.eq(TenantHelper.getTenantId())); + } + + return MapstructUtils.convert(StreamSupport.stream(deptRepository.findAll(predicateBuilder.build()).spliterator(), false).collect(Collectors.toList()), SysDept.class); } @@ -114,6 +182,11 @@ public class SysDeptDataImpl implements ISysDeptData, IJPACommData findByTenantId(Long tenantId) { + return MapstructUtils.convert(deptRepository.findByTenantId(tenantId), SysDept.class); + } + @Override public boolean checkDeptNameUnique(String deptName, Long parentId, Long deptId) { PredicateBuilder predicateBuilder = PredicateBuilder.instance().and(tbSysDept.deptName.eq(deptName)) diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysDictDataImpl.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysDictDataImpl.java index 7b182c7..7149314 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysDictDataImpl.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysDictDataImpl.java @@ -116,7 +116,7 @@ public class SysDictDataImpl implements ISysDictData, IJPACommData tbSysDictData.dictSort.eq(dictData.getDictSort())) - .and(StringUtils.isNotEmpty(dictData.getDictLabel()), () -> tbSysDictData.dictLabel.like(dictData.getDictLabel())) + .and(StringUtils.isNotEmpty(dictData.getDictLabel()), () -> tbSysDictData.dictLabel.like("%"+dictData.getDictLabel()+"%")) .and(StringUtils.isNotEmpty(dictData.getDictType()), () -> tbSysDictData.dictType.eq(dictData.getDictType())) .and(StringUtils.isNotEmpty(dictData.getStatus()), () -> tbSysDictData.status.eq(dictData.getStatus())) .and(ObjectUtil.isNotNull(dictData.getTenantId()), () -> tbSysDictData.tenantId.eq(dictData.getTenantId())).build(); diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysDictTypeDataImpl.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysDictTypeDataImpl.java index 6206369..8ec870d 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysDictTypeDataImpl.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysDictTypeDataImpl.java @@ -119,8 +119,8 @@ public class SysDictTypeDataImpl implements ISysDictTypeData, IJPACommData tbSysDictType.dictName.like(dictType.getDictName())) - .and(StringUtils.isNotEmpty(dictType.getDictType()), () -> tbSysDictType.dictType.like(dictType.getDictType())) + .and(StringUtils.isNotEmpty(dictType.getDictName()), () -> tbSysDictType.dictName.like("%"+dictType.getDictName()+"%")) + .and(StringUtils.isNotEmpty(dictType.getDictType()), () -> tbSysDictType.dictType.like("%"+dictType.getDictType()+"%")) .and(StringUtils.isNotEmpty(dictType.getStatus()), () -> tbSysDictType.status.eq(dictType.getStatus())) .and(ObjectUtil.isNotNull(dictType.getTenantId()), () -> tbSysDictType.tenantId.eq(dictType.getTenantId())).build(); } diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysLogininfoDataImpl.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysLogininfoDataImpl.java index 67c40ee..4eb386b 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysLogininfoDataImpl.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysLogininfoDataImpl.java @@ -90,9 +90,9 @@ public class SysLogininfoDataImpl implements ISysLogininforData, IJPACommData tbSysLogininfor.ipaddr.like(data.getIpaddr())) + .and(StringUtils.isNotBlank(data.getIpaddr()), () -> tbSysLogininfor.ipaddr.like("%"+data.getIpaddr()+"%")) .and(StringUtils.isNotBlank(data.getStatus()), () -> tbSysLogininfor.status.eq(data.getStatus())) - .and(StringUtils.isNotBlank(data.getUserName()), () -> tbSysLogininfor.userName.like(data.getUserName())) + .and(StringUtils.isNotBlank(data.getUserName()), () -> tbSysLogininfor.userName.like("%"+data.getUserName()+"%")) .build(); } diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysMenuDataImpl.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysMenuDataImpl.java index d4fcfdb..a3c1987 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysMenuDataImpl.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysMenuDataImpl.java @@ -126,7 +126,7 @@ public class SysMenuDataImpl implements ISysMenuData, IJPACommData selectMenuList(SysMenu menu, Long userId, boolean isSuperAdmin) { PredicateBuilder predicateBuilder = PredicateBuilder.instance() - .and(StringUtils.isNotBlank(menu.getMenuName()), () -> tbSysMenu.menuName.like(menu.getMenuName())) + .and(StringUtils.isNotBlank(menu.getMenuName()), () -> tbSysMenu.menuName.like("%"+menu.getMenuName()+"%")) .and(StringUtils.isNotBlank(menu.getVisible()), () -> tbSysMenu.visible.eq(menu.getVisible())) .and(StringUtils.isNotBlank(menu.getStatus()), () -> tbSysMenu.status.eq(menu.getStatus())); diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysNoticeDataImpl.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysNoticeDataImpl.java index 4ef3ebc..3d60585 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysNoticeDataImpl.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysNoticeDataImpl.java @@ -85,13 +85,13 @@ public class SysNoticeDataImpl implements ISysNoticeData, IJPACommData - tbSysNotice.noticeTitle.like(query.getNoticeTitle())) + tbSysNotice.noticeTitle.like("%"+query.getNoticeTitle()+"%")) .and(StringUtils.isNotBlank(query.getNoticeType()), ()-> tbSysNotice.noticeType.eq(query.getNoticeType())) .and(StringUtils.isNotBlank(query.getStatus()), ()-> tbSysNotice.status.eq(query.getStatus())) .and(StringUtils.isNotBlank(query.getCreateByName()), ()->( - tbSysNotice.createBy.like(query.getCreateByName()))) + tbSysNotice.createBy.like("%"+query.getCreateByName()+"%"))) .build(); } } diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysOperLogDataImpl.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysOperLogDataImpl.java index 7c4ebdf..9f39673 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysOperLogDataImpl.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysOperLogDataImpl.java @@ -110,11 +110,11 @@ public class SysOperLogDataImpl implements ISysOperLogData, IJPACommData tbSysOperLog.title.like(data.getTitle())) + .and(StringUtils.isNotBlank(data.getTitle()), () -> tbSysOperLog.title.like("%"+data.getTitle()+"%")) .and(data.getBusinessType() != null && data.getBusinessType() > 0, () -> tbSysOperLog.businessType.eq(data.getBusinessType())) .and(ArrayUtil.isNotEmpty(data.getBusinessTypes()), () -> tbSysOperLog.businessType.in(Arrays.asList(data.getBusinessTypes()))) .and(data.getStatus() != null && data.getStatus() > 0, () -> tbSysOperLog.status.eq(data.getStatus())) - .and(StringUtils.isNotBlank(data.getOperName()), () -> tbSysOperLog.operName.like(data.getOperName())) + .and(StringUtils.isNotBlank(data.getOperName()), () -> tbSysOperLog.operName.like("%"+data.getOperName() +"%")) .build(); } } diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysPostDataImpl.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysPostDataImpl.java index 3325b2b..cc8a455 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysPostDataImpl.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysPostDataImpl.java @@ -126,8 +126,8 @@ public class SysPostDataImpl implements ISysPostData, IJPACommData tbSysPost.postCode.like(post.getPostCode())) - .and(StringUtils.isNotBlank(post.getPostName()), () -> tbSysPost.postName.like(post.getPostName())) + .and(StringUtils.isNotBlank(post.getPostCode()), () -> tbSysPost.postCode.like("%"+post.getPostCode()+"%")) + .and(StringUtils.isNotBlank(post.getPostName()), () -> tbSysPost.postName.like("%"+post.getPostName()+"%")) .and(StringUtils.isNotBlank(post.getStatus()), () -> tbSysPost.status.eq(post.getStatus())).build(); } } diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysRoleDataImpl.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysRoleDataImpl.java index d795c6b..eb60a58 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysRoleDataImpl.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysRoleDataImpl.java @@ -26,6 +26,8 @@ package cc.iotkit.data.service; import cc.iotkit.common.api.PageRequest; import cc.iotkit.common.api.Paging; import cc.iotkit.common.constant.UserConstants; +import cc.iotkit.common.satoken.utils.LoginHelper; +import cc.iotkit.common.tenant.helper.TenantHelper; import cc.iotkit.common.utils.MapstructUtils; import cc.iotkit.data.dao.IJPACommData; import cc.iotkit.data.dao.SysRoleRepository; @@ -129,21 +131,54 @@ public class SysRoleDataImpl implements ISysRoleData, IJPACommData tbSysRole.id.ne(role.getId())) + .and(Objects.nonNull(role.getTenantId()), () -> tbSysRole.tenantId.eq(role.getTenantId())) .build()).fetchOne(); + /* if(ObjectUtil.isNotNull(tbSysRoleRes)){ + if(tbSysRoleRes.getRoleName().equals(role.getRoleName())){ + return true; + } + }*/ return Objects.isNull(tbSysRoleRes); } @Override public boolean checkRoleKeyUnique(SysRole role) { + if(ObjectUtil.isNull(role.getTenantId())){ + role.setTenantId(TenantHelper.getTenantId()); + } + // Long tenantId = role.getTenantId(); + else if(TenantHelper.getTenantId() != 0 && ObjectUtil.isNotNull(role.getTenantId())){ + role.setTenantId(TenantHelper.getTenantId()); + } final TbSysRole tbSysRoleRes = jpaQueryFactory.select(tbSysRole).from(tbSysRole) .where(PredicateBuilder.instance() .and(tbSysRole.roleKey.eq(role.getRoleKey())) .and(Objects.nonNull(role.getId()), () -> tbSysRole.id.ne(role.getId())) + .and(Objects.nonNull(role.getTenantId()), () -> tbSysRole.tenantId.eq(role.getTenantId())) .build()).fetchOne(); + /* if(ObjectUtil.isNotNull(tbSysRoleRes)){ + if(tbSysRoleRes.getRoleKey().equals(role.getRoleKey())){ + return true; + } + }*/ return Objects.isNull(tbSysRoleRes); } @@ -174,6 +209,7 @@ public class SysRoleDataImpl implements ISysRoleData, IJPACommData selectRoleList(SysRole role) { + return buildQueryTitle(buildQueryWrapper(role)); } @@ -200,14 +236,39 @@ public class SysRoleDataImpl implements ISysRoleData, IJPACommData tbSysRole.id.eq(role.getId())) - .and(StringUtils.isNotBlank(role.getRoleName()), () -> tbSysRole.roleName.like(role.getRoleName())) - .and(StringUtils.isNotBlank(role.getStatus()), () -> tbSysRole.roleName.eq(role.getStatus())) - .and(StringUtils.isNotBlank(role.getRoleKey()), () -> tbSysRole.roleKey.like(role.getRoleKey())) - .and(ObjectUtil.isNotNull(role.getTenantId()), () -> tbSysRole.tenantId.eq(role.getTenantId())) - .build(); + + if(LoginHelper.isSuperAdmin()) { + if(ObjectUtil.isNull(role.getTenantId())){ + role.setTenantId(TenantHelper.getTenantId()); + } + // Long tenantId = role.getTenantId(); + else if(TenantHelper.getTenantId() != 0 && ObjectUtil.isNotNull(role.getTenantId())){ + role.setTenantId(TenantHelper.getTenantId()); + } + if(TenantHelper.getTenantId() == 0 && LoginHelper.isSuperAdmin()){ + role.setTenantId(null); + } + return PredicateBuilder.instance() + .and(tbSysRole.delFlag.eq(UserConstants.ROLE_NORMAL)) + .and(Objects.nonNull(role.getId()), () -> tbSysRole.id.eq(role.getId())) + .and(StringUtils.isNotBlank(role.getRoleName()), () -> tbSysRole.roleName.like("%"+role.getRoleName()+"%")) + .and(StringUtils.isNotBlank(role.getStatus()), () -> tbSysRole.roleName.eq(role.getStatus())) + .and(StringUtils.isNotBlank(role.getRoleKey()), () -> tbSysRole.roleKey.like("%"+role.getRoleKey()+"%")) + .and(ObjectUtil.isNotNull(role.getTenantId()), () -> tbSysRole.tenantId.eq(role.getTenantId())) + .build(); + }else{ + if(ObjectUtil.isNull(role.getTenantId())){ + role.setTenantId(TenantHelper.getTenantId()); + } + return PredicateBuilder.instance() + .and(tbSysRole.delFlag.eq(UserConstants.ROLE_NORMAL)) + .and(Objects.nonNull(role.getId()), () -> tbSysRole.id.eq(role.getId())) + .and(StringUtils.isNotBlank(role.getRoleName()), () -> tbSysRole.roleName.like("%"+role.getRoleName()+"%")) + .and(StringUtils.isNotBlank(role.getStatus()), () -> tbSysRole.roleName.eq(role.getStatus())) + .and(StringUtils.isNotBlank(role.getRoleKey()), () -> tbSysRole.roleKey.like("%"+role.getRoleKey()+"%")) + .and(ObjectUtil.isNotNull(role.getTenantId()), () -> tbSysRole.tenantId.eq(role.getTenantId())) + .build(); + } } diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysRoleMenuDataImpl.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysRoleMenuDataImpl.java index 8ab4217..3edf006 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysRoleMenuDataImpl.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysRoleMenuDataImpl.java @@ -36,6 +36,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Primary; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.Collection; import java.util.List; @@ -89,6 +90,7 @@ public class SysRoleMenuDataImpl implements ISysRoleMenuData, IJPACommData ids) { return jpaQueryFactory.delete(tbSysRoleMenu).where(tbSysRoleMenu.roleId.in(ids)).execute(); } diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysTenantDataImpl.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysTenantDataImpl.java index 7322218..e358d13 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysTenantDataImpl.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysTenantDataImpl.java @@ -82,13 +82,13 @@ public class SysTenantDataImpl implements ISysTenantData, IJPACommData findAllByCondition(SysTenant data) { List ret=jpaQueryFactory.selectFrom(tbSysTenant).where(PredicateBuilder.instance() - .and(StringUtils.isNotBlank(data.getContactUserName()),()->tbSysTenant.contactUserName.like(data.getContactUserName())) + .and(StringUtils.isNotBlank(data.getContactUserName()),()->tbSysTenant.contactUserName.like("%"+data.getContactUserName()+"%")) .and(StringUtils.isNotBlank(data.getContactPhone()),()->tbSysTenant.contactPhone.eq(data.getContactPhone())) - .and(StringUtils.isNotBlank(data.getCompanyName()),()->tbSysTenant.companyName.like(data.getCompanyName())) + .and(StringUtils.isNotBlank(data.getCompanyName()),()->tbSysTenant.companyName.like("%"+data.getCompanyName()+"%")) .and(StringUtils.isNotBlank(data.getLicenseNumber()),()->tbSysTenant.licenseNumber.eq(data.getLicenseNumber())) .and(StringUtils.isNotBlank(data.getAddress()),()->tbSysTenant.address.eq(data.getAddress())) .and(StringUtils.isNotBlank(data.getIntro()),()->tbSysTenant.intro.eq(data.getIntro())) - .and(StringUtils.isNotBlank(data.getDomain()),()->tbSysTenant.domain.like(data.getDomain())) + .and(StringUtils.isNotBlank(data.getDomain()),()->tbSysTenant.domain.like("%"+data.getDomain()+"%")) .and(data.getPackageId() != null,()->tbSysTenant.packageId.eq(data.getPackageId())) .and(data.getExpireTime() != null,()->tbSysTenant.expireTime.eq(data.getExpireTime())) .and(data.getAccountCount() != null,()->tbSysTenant.accountCount.eq(data.getAccountCount())) diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysUserDataImpl.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysUserDataImpl.java index d9b2a8d..08813b7 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysUserDataImpl.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/SysUserDataImpl.java @@ -26,12 +26,14 @@ package cc.iotkit.data.service; import cc.iotkit.common.api.PageRequest; import cc.iotkit.common.api.Paging; import cc.iotkit.common.constant.UserConstants; +import cc.iotkit.common.satoken.utils.LoginHelper; import cc.iotkit.common.tenant.helper.TenantHelper; import cc.iotkit.common.utils.MapstructUtils; import cc.iotkit.common.utils.StreamUtils; import cc.iotkit.common.utils.StringUtils; import cc.iotkit.data.dao.IJPACommData; import cc.iotkit.data.dao.SysUserRepository; +import cc.iotkit.data.model.QTbSysUser; import cc.iotkit.data.model.TbSysPost; import cc.iotkit.data.model.TbSysRole; import cc.iotkit.data.model.TbSysUser; @@ -54,6 +56,7 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Service; import java.sql.Date; +import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -257,8 +260,8 @@ public class SysUserDataImpl implements ISysUserData, IJPACommData tbSysUser.phonenumber.like(data.getPhonenumber())) - .and(StringUtils.isNotBlank(data.getUserName()), () -> tbSysUser.userName.like(data.getUserName())) + .and(StringUtils.isNotBlank(data.getPhonenumber()), () -> tbSysUser.phonenumber.like("%"+data.getPhonenumber()+"%")) + .and(StringUtils.isNotBlank(data.getUserName()), () -> tbSysUser.userName.like("%"+data.getUserName()+"%")) .and(StringUtils.isNotBlank(data.getStatus()), () -> tbSysUser.status.eq(data.getStatus())) .and(Objects.nonNull(data.getDeptId()), () -> tbSysUser.deptId.eq(data.getDeptId())) .and(tbSysUser.delFlag.eq(UserConstants.ROLE_NORMAL)) @@ -300,13 +303,15 @@ public class SysUserDataImpl implements ISysUserData, IJPACommData tbSysUser.phonenumber.like(data.getPhonenumber())) - .and(StringUtils.isNotBlank(data.getUserName()), () -> tbSysUser.userName.like(data.getUserName())) + builder.and(StringUtils.isNotBlank(data.getPhonenumber()), () -> tbSysUser.phonenumber.like("%"+data.getPhonenumber()+"%")) + .and(StringUtils.isNotBlank(data.getUserName()), () -> tbSysUser.userName.like("%"+data.getUserName()+"%")) .and(StringUtils.isNotBlank(data.getStatus()), () -> tbSysUser.status.eq(data.getStatus())) .and(Objects.nonNull(data.getDeptId()), () -> tbSysUser.deptId.eq(data.getDeptId())) .and(tbSysUser.delFlag.eq(UserConstants.ROLE_NORMAL)); } - + if(!LoginHelper.isSuperAdmin()) { + builder.and(tbSysUser.tenantId.eq(TenantHelper.getTenantId())); + } QueryResults sysUserQueryResults = jpaQueryFactory.select(Projections.bean(SysUser.class, tbSysUser.id, tbSysUser.deptId, tbSysUser.userName, tbSysUser.nickName, tbSysUser.email, tbSysUser.phonenumber, tbSysUser.createTime)).from(tbSysUser) .leftJoin(tbSysDept).on(tbSysUser.deptId.eq(tbSysDept.id)) @@ -324,6 +329,12 @@ public class SysUserDataImpl implements ISysUserData, IJPACommData findByTenantId(Long tenantId) { + + + return MapstructUtils.convert(userRepository.findByTenantId(tenantId), SysUser.class); + } @Override public Paging findAll(PageRequest pageRequest) { @@ -359,8 +370,12 @@ public class SysUserDataImpl implements ISysUserData, IJPACommData areaIds; if (Objects.nonNull(user) && Objects.nonNull(user.getDeptAreaId())) { Long deptId = user.getDeptAreaId(); - List depts = sysDeptData.findByDeptId(deptId); - areaIds = StreamUtils.toList(depts, SysDept::getId); + if(!user.isFlag()) { + List depts = sysDeptData.findByDeptId(deptId); + areaIds = StreamUtils.toList(depts, SysDept::getId); + } else { + areaIds = new ArrayList<>(); + } areaIds.add(deptId); } else { areaIds = null; diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/UserInfoDataImpl.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/UserInfoDataImpl.java index 5ff8798..2184d47 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/UserInfoDataImpl.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/UserInfoDataImpl.java @@ -22,19 +22,42 @@ */ package cc.iotkit.data.service; +import cc.iotkit.common.api.PageRequest; +import cc.iotkit.common.api.Paging; +import cc.iotkit.common.satoken.utils.LoginHelper; +import cc.iotkit.common.tenant.helper.TenantHelper; import cc.iotkit.common.utils.MapstructUtils; +import cc.iotkit.common.utils.StringUtils; import cc.iotkit.data.dao.IJPACommData; import cc.iotkit.data.dao.UserInfoRepository; import cc.iotkit.data.manager.IUserInfoData; import cc.iotkit.data.model.TbUserInfo; +import cc.iotkit.data.util.PageBuilder; +import cc.iotkit.data.util.PredicateBuilder; import cc.iotkit.model.UserInfo; +import cn.hutool.core.util.ObjectUtil; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.dsl.Expressions; import lombok.RequiredArgsConstructor; +import org.apache.poi.ss.formula.functions.T; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Primary; +import org.springframework.data.domain.Example; +import org.springframework.data.domain.ExampleMatcher; +import org.springframework.data.domain.Page; +import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.QueryHints; import org.springframework.stereotype.Service; +import javax.persistence.QueryHint; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Objects; + +import static cc.iotkit.data.model.QTbSysDept.tbSysDept; +import static cc.iotkit.data.model.QTbUserInfo.tbUserInfo; @Primary @Service @@ -48,12 +71,40 @@ public class UserInfoDataImpl implements IUserInfoData, IJPACommData findByType(int type) { return MapstructUtils.convert(userInfoRepository.findByType(type), UserInfo.class); } - + @Override + @QueryHints(@QueryHint(name = "org.hibernate.fetchSize", value = "1000")) + public Paging findAll(PageRequest pageRequest) { + // PredicateBuilder predicateBuilder = new PredicateBuilder(tbUserInfo.id.isNotNull()); + PredicateBuilder predicateBuilder = PredicateBuilder.instance(); + predicateBuilder.and(ObjectUtil.isNotNull(pageRequest.getData().getUserName()), () -> tbUserInfo.userName.like("%"+pageRequest.getData().getUserName() +"%")); + predicateBuilder.and(ObjectUtil.isNotNull(pageRequest.getData().getNickName()), () -> tbUserInfo.nickName.like("%"+pageRequest.getData().getNickName()+"%")); + predicateBuilder.and(ObjectUtil.isNotNull(pageRequest.getData().getEmail()), () -> tbUserInfo.email.like("%"+pageRequest.getData().getEmail()+"%")); + predicateBuilder.and(ObjectUtil.isNotNull(pageRequest.getData().getType()), () -> tbUserInfo.type.eq(pageRequest.getData().getType())); + predicateBuilder.and(ObjectUtil.isNotEmpty(pageRequest.getData().getDeptAreaIds()), () -> tbUserInfo.deptAreaId.in(pageRequest.getData().getDeptAreaIds())); + if(!LoginHelper.isSuperAdmin()){ + predicateBuilder.and(ObjectUtil.isNotNull(pageRequest.getData().getTenantId()), () -> tbUserInfo.tenantId.eq(pageRequest.getData().getTenantId())); + } + if(LoginHelper.isSuperAdmin() && TenantHelper.getTenantId() != 0) { + predicateBuilder.and(ObjectUtil.isNotNull(TenantHelper.getTenantId()), () -> tbUserInfo.tenantId.eq(TenantHelper.getTenantId())); + } + /* if(LoginHelper.isSuperAdmin()){ + predicateBuilder.or(ObjectUtil.isNotNull(pageRequest.getData().getType()), () ->tbUserInfo.id.ne(1L) ); + }*/ + return PageBuilder.toPaging(userInfoRepository.findAll(predicateBuilder.build(), PageBuilder.toPageable(pageRequest)), UserInfo.class); + } @Override public JpaRepository getBaseRepository() { return userInfoRepository; diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/VirtualDeviceDataImpl.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/VirtualDeviceDataImpl.java index 501075b..3bb6baf 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/VirtualDeviceDataImpl.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/VirtualDeviceDataImpl.java @@ -23,6 +23,7 @@ package cc.iotkit.data.service; import cc.iotkit.common.satoken.utils.LoginHelper; +import cc.iotkit.common.tenant.helper.TenantHelper; import cc.iotkit.data.dao.IJPACommData; import cc.iotkit.data.manager.IVirtualDeviceData; import cc.iotkit.data.dao.VirtualDeviceMappingRepository; @@ -131,7 +132,7 @@ public class VirtualDeviceDataImpl implements IVirtualDeviceData, IJPACommData new TbVirtualDeviceMapping( IdUtil.simpleUUID(), data.getId(), - d, LoginHelper.getTenantId() + d, TenantHelper.getTenantId() )).collect(Collectors.toList()) ); return data; diff --git a/iot-module/iot-manager/pom.xml b/iot-module/iot-manager/pom.xml index f50cc9c..e6c88d1 100644 --- a/iot-module/iot-manager/pom.xml +++ b/iot-module/iot-manager/pom.xml @@ -23,6 +23,35 @@ cc.iotkit iot-common-core + + org.apache.pdfbox + pdfbox + 2.0.27 + + + + + com.itextpdf + itext7-core + 7.2.5 + pom + + + + + + cc.iotkit @@ -107,6 +136,14 @@ + + + src/main/java/cc/fonts + + fonts/*.ttf + + + org.apache.maven.plugins diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/config/GasInstallationPDFGenerator.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/config/GasInstallationPDFGenerator.java new file mode 100644 index 0000000..ce29dfa --- /dev/null +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/config/GasInstallationPDFGenerator.java @@ -0,0 +1,291 @@ +package cc.iotkit.manager.config; + +import cc.iotkit.model.device.DeviceInstallInfo; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDPageContentStream; +import org.apache.pdfbox.pdmodel.common.PDRectangle; +import org.apache.pdfbox.pdmodel.font.PDType0Font; +import org.apache.pdfbox.pdmodel.font.PDType1Font; +import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Arrays; +import java.util.List; + +public class GasInstallationPDFGenerator { + private static final float IMAGE_MARGIN = 50f; + private static final float TITLE_HEIGHT = 600f; + public static void main(String[] args) { + File fontFile = new File("D:\\simsun.ttf"); + if(fontFile.exists()) { + System.out.println("Actual font path: " + fontFile.getAbsolutePath()); + } + + } + /* private static void drawTable(PDPageContentStream contentStream, PDType0Font font, + float startX, float startY, + String[][] data, float[] columnWidths) throws IOException { + contentStream.setFont(font, 12); + float rowHeight = 20f; + float tableWidth = 0; + for (float width : columnWidths) { + tableWidth += width; + } + + // 绘制表格边框 + contentStream.setLineWidth(1f); + contentStream.addRect(startX, startY - rowHeight * data.length, tableWidth, rowHeight * data.length); + contentStream.stroke(); + + // 绘制单元格 + float nextX = startX; + for (int i = 0; i < data.length; i++) { + nextX = startX; + for (int j = 0; j < data[i].length; j++) { + // 绘制垂直线 + if (j > 0) { + contentStream.moveTo(nextX, startY - rowHeight * i); + contentStream.lineTo(nextX, startY - rowHeight * (i + 1)); + contentStream.stroke(); + } + + // 写入文本 + contentStream.beginText(); + contentStream.newLineAtOffset(nextX + 5, startY - rowHeight * (i + 1) + 5); + contentStream.showText(data[i][j]); + contentStream.endText(); + + nextX += columnWidths[j]; + } + } + }*/ + /* private static void drawTable(PDPageContentStream cs, PDType0Font font, + float x, float y, String[][] data, float[] colWidths) throws IOException { + float rowHeight = 20f; + float tableWidth = 0; + for (float width : colWidths) { + tableWidth += width; + } + // 绘制表格线 + cs.setLineWidth(1f); + cs.addRect(x, y - rowHeight * data.length, tableWidth, rowHeight * data.length); + cs.stroke(); + // 绘制单元格内容 + for (int i = 0; i < data.length; i++) { + float nextX = x; + for (int j = 0; j < data[i].length; j++) { + if (j > 0) { + cs.moveTo(nextX, y - rowHeight * i); + cs.lineTo(nextX, y - rowHeight * (i + 1)); + cs.stroke(); + } + drawText(cs, data[i][j], nextX + 5, y - rowHeight * i + 5); + nextX += colWidths[j]; + } + } + }*/ + + /** + + 绘制PDF表格(支持中文) + + @param cs PDF内容流 + + @param font 中文字体对象 + + @param x 起始X坐标 + + @param y 起始Y坐标(表格顶部位置) + + @param data 表格数据(二维数组) + + @param colWidths 每列宽度数组 + */ + private static void drawTable(PDPageContentStream cs, PDType0Font font, + float x, float y, String[][] data, float[] colWidths) throws IOException { + +// 修改后的表格绘制代码 + if (data == null || data.length == 0 || colWidths == null) return; + + final float ROW_HEIGHT = 35f; // 增大行高以适应更大字体 + final float FONT_SIZE = 14f; // 增大字体大小 + final float PADDING = 5f; + +// 计算表格总宽度 + float tableWidth = 0; + for (float width : colWidths) { + tableWidth += width; + } + +// 绘制表格边框和分隔线(保持不变) + cs.setLineWidth(1f); + cs.addRect(x, y - ROW_HEIGHT * data.length, tableWidth, ROW_HEIGHT * data.length); + cs.stroke(); + +// 绘制列分隔线 + float currentX = x; + for (int i = 1; i < colWidths.length; i++) { + currentX += colWidths[i-1]; + cs.moveTo(currentX, y); + cs.lineTo(currentX, y - ROW_HEIGHT * data.length); + cs.stroke(); + } + +// 绘制行分隔线 + for (int i = 1; i <= data.length; i++) { + cs.moveTo(x, y - ROW_HEIGHT * i); + cs.lineTo(x + tableWidth, y - ROW_HEIGHT * i); + cs.stroke(); + } + +// 填写表格内容(关键修改部分) + cs.setFont(font, FONT_SIZE); + for (int row = 0; row < data.length; row++) { + currentX = x; + for (int col = 0; col < data[row].length; col++) { + String text = data[row][col] != null ? data[row][col] : ""; + // 计算文本宽度 + float textWidth = font.getStringWidth(text) / 1000 * FONT_SIZE; + float centerOffset = (colWidths[col] - textWidth) / 2; + // 修正垂直居中计算(关键修改) + float baselineOffset = (ROW_HEIGHT - FONT_SIZE) / 3; // 更精确的基线计算 + cs.beginText(); + cs.newLineAtOffset( + currentX + centerOffset, + y - (ROW_HEIGHT * row) - FONT_SIZE - baselineOffset // 修正垂直位置 + ); + cs.showText(text); + cs.endText(); + currentX += colWidths[col]; + } + } + } + public static void generateInstallationPDF(DeviceInstallInfo entity, OutputStream outputPath) throws IOException { + try (PDDocument document = new PDDocument()) { + // 创建第一页 - 基本信息 + PDPage page1 = new PDPage(PDRectangle.A4); + document.addPage(page1); + try (PDPageContentStream contentStream = new PDPageContentStream(document, page1)) { + File fontFile = new File("D:/simsun.ttf"); + PDType0Font yaHeiFont = PDType0Font.load(document, fontFile); + // 绘制标题(居中) + contentStream.setFont(yaHeiFont, 26f); + float titleWidth = yaHeiFont.getStringWidth("贵阳户内安装信息录入表") / 1000 * 26f; + contentStream.beginText(); + contentStream.newLineAtOffset((PDRectangle.A4.getWidth() - titleWidth)/2, 750); + contentStream.showText("贵阳户内安装信息录入表"); + contentStream.endText(); + // 基本信息表格 + String[][] baseInfo = { + {"安装班组", entity.getProposerTeam()}, + {"安装人", entity.getProposer()}, + {"安装时间", entity.getProposerTime().toString()}, + {"小区名称", entity.getCommunityName()}, + {"楼栋号", entity.getBuildingUnit()}, + {"单元号", entity.getBuildingUnit() != null ? entity.getBuildingUnit().split("-")[0] : ""}, + {"房号", entity.getRoomNo()}, + {"用户姓名", entity.getUserName()}, + {"联系方式", entity.getUserIpone()}, + {"灶具类型", entity.getDeviceName() != null ? + (entity.getDeviceName().contains("台式") ? "台式灶" : "嵌入式灶") : ""} + }; + drawTable(contentStream, yaHeiFont, 100, 700, baseInfo, new float[]{80f, 300f}); + } catch (Exception e) { + throw new RuntimeException(e); + } + // 创建后续页面 - 图片部分 + addImagePages(document, entity); + // 保存到D盘 + document.save("D:/output.pdf"); + document.save(outputPath); + PDRectangle mediaBox = page1.getMediaBox(); + System.out.printf("页面尺寸: %.1f x %.1f%n", mediaBox.getWidth(), mediaBox.getHeight()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + + private static void addImagePages(PDDocument document, DeviceInstallInfo entity) throws IOException { + // 安装前图片页 + if (entity.getBeforeInstallationImage() != null) { + addImagePage(document, "安装前图片(拍清晰、无遮挡)", + entity.getBeforeInstallationImage()); + } + // 安装后图片页 + if (entity.getInstallThePanoramicImage() != null) { + addImagePage(document, "安装后图片(拍清晰、无遮挡)", + entity.getInstallThePanoramicImage()); + } + // 测漏图片页 + if (entity.getSideLeakageImage() != null) { + addImagePage(document, "灶具接口测漏图片(拍清晰、无遮挡)", + entity.getSideLeakageImage()); + } + // 点火图片页 + if (entity.getIgnitionPictureImage() != null) { + addImagePage(document, "安装后点火图片(拍清晰、无遮挡)", + entity.getIgnitionPictureImage()); + } + // 工单签字页 + if (entity.getWorkOrderImage() != null) { + addImagePage(document, "工单用户签字图片(拍清晰、无遮挡)", + entity.getWorkOrderImage()); + } + // 打孔图片页 + if (entity.getPunchingImage() != null) { + addImagePage(document, "打孔图片(拍清晰、无遮挡)", + entity.getPunchingImage()); + } + } + private static void addImagePage(PDDocument document, String title, String imagePath) throws IOException { + PDPage page = new PDPage(PDRectangle.A4); + document.addPage(page); + // PDPage page = document.getPage(document.getNumberOfPages()-1); + // 创建表格样式 + float margin = 50; + float yPosition = 700; + float tableWidth = 380; + float rowHeight = 40; + try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) { + File fontFile = new File("D:/simsun.ttf"); + PDType0Font yaHeiFont = PDType0Font.load(document, fontFile); + // 左侧标题列 + // 绘制表格边框 + // 绘制表格边框 + contentStream.setFont(yaHeiFont, 14); + contentStream.setLineWidth(1f); + contentStream.addRect(margin, yPosition - rowHeight, tableWidth, rowHeight); + contentStream.stroke(); + // 居中显示标题 + float titleWidth = yaHeiFont.getStringWidth(title) / 1000 * 14; + float titleX = margin + (tableWidth - titleWidth) / 2; + float titleY = yPosition - rowHeight / 2 - 5; // 垂直居中微调 + contentStream.beginText(); + contentStream.newLineAtOffset(titleX, titleY); + contentStream.showText(title); + contentStream.endText(); + // 计算图片位置(表格下方) + float imageY = yPosition - rowHeight - 20; + // 添加图片(居中显示) + URL imageUrl = new URL(imagePath); + PDImageXObject image = PDImageXObject.createFromByteArray(document, + imageUrl.openStream().readAllBytes(),"minio-image"); + float scale = calculateScale(image, page); + float imageX = (page.getMediaBox().getWidth() - image.getWidth()*scale) / 2; + contentStream.drawImage(image, imageX, imageY - image.getHeight()*scale, + image.getWidth()*scale, image.getHeight()*scale); + } + } + + private static float calculateScale(PDImageXObject image, PDPage page) { + float pageWidth = page.getMediaBox().getWidth() - 2*IMAGE_MARGIN; + return Math.min(1f, pageWidth / image.getWidth()); + } +} diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/config/PDFGenerator.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/config/PDFGenerator.java new file mode 100644 index 0000000..eca9495 --- /dev/null +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/config/PDFGenerator.java @@ -0,0 +1,708 @@ +package cc.iotkit.manager.config; + + +import cc.iotkit.model.device.DeviceInstallInfo; +import cn.hutool.core.util.ObjectUtil; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDPageContentStream; +import org.apache.pdfbox.pdmodel.common.PDRectangle; +import org.apache.pdfbox.pdmodel.font.PDFont; +import org.apache.pdfbox.pdmodel.font.PDType0Font; +import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.*; +import java.net.URL; +import java.util.*; +import java.util.stream.Collectors; + +import static cc.iotkit.manager.config.PDFUtils.drawAlignedText; + + +public class PDFGenerator { + // 1. 表格参数配置 + + // 参数配置(优化后) + private static final float FONT_SIZE = 11f; + private static final float ROW_HEIGHT = 35f; + private static final float TABLE_MARGIN = 50f; + private static final float LEFT_COL_WIDTH = 130f; + private static final float RIGHT_COL_WIDTH = 350f; + private static final float LINE_HEIGHT = FONT_SIZE * 1.2f; + private static final float CELL_PADDING = 5; + private static final float[] COLUMN_WIDTHS = {LEFT_COL_WIDTH, RIGHT_COL_WIDTH}; + private static final float MIN_IMAGE_HEIGHT = 50; + public static void generateInstallationPDF(DeviceInstallInfo entity, OutputStream outputStream) throws IOException { + try (PDDocument document = new PDDocument()) { + // 加载字体(需替换实际路径) + //PDType0Font font = PDType0Font.load(document, new File("D:\\simsun.ttf")); + PDType0Font font = PDType0Font.load(document, new File("/ttf/simsun.ttf")); + + // 初始化第一页 + PDPage currentPage = new PDPage(PDRectangle.A4); + document.addPage(currentPage); + PDPageContentStream cs = new PDPageContentStream(document, currentPage); + float currentY = PDRectangle.A4.getHeight() - TABLE_MARGIN; + + try { + // 1. 绘制标题(居中) + drawCenteredText(cs, font, FONT_SIZE+10, + "安装信息录入表", + PDRectangle.A4.getWidth()/2, currentY); + currentY -= ROW_HEIGHT * 1.5f; + + // 2. 绘制基本信息表格 + String[][] baseData = { + // {"公司名称", entity.getCorporateName()}, + {"申请时间", entity.getProposerTime().toString()}, + {"申请人", entity.getProposer()}, + {"申请人班组", entity.getProposerTeam()}, + {"小区名字", entity.getCommunityName()}, + {"用户姓名", entity.getUserName()}, + {"电话", entity.getUserIpone()}, + {"楼栋单元号", entity.getBuildingUnit()}, + {"房间号", entity.getRoomNo()}, + {"报警器编号", entity.getDeviceName()}, + {"切断阀编号", entity.getShutValueNumber()}, + {"燃气表号", entity.getGasMeterNumber()}, + {"备注", entity.getBuildingUnit()} + + }; + drawTable(cs, font, TABLE_MARGIN, currentY, baseData, COLUMN_WIDTHS); + currentY -= (ROW_HEIGHT * baseData.length) + 20f; +// @ApiModelProperty(value = "安装前图片") + // 创建后续页面 - 图片部分 + // 图片处理(带自动分页) + // 图片处理(带自动分页) + List imageGroups = Arrays.asList( + new String[]{entity.getBeforeInstallationImage(), "安装前图片"}, + new String[]{entity.getWorkingOfTheDetectorImage(), "安装完成探测器工作图片"}, + new String[]{entity.getSideLeakageImage(), "测漏图片"}, + new String[]{entity.getIgnitionPictureImage(), "点火图片"}, + new String[]{entity.getInstallThePanoramicImage(), "安装完成全景图片"}, + new String[]{entity.getOfGasMeterImage(), "燃气表图片"}, + new String[]{entity.getWorkOrderImage(), "工单图片"}, + new String[]{entity.getPunchingImage(), "打孔图片"}, + new String[]{entity.getFiexImage(), "安装电源线图片"} + ); + + for (String[] group : imageGroups) { + String urls = group[0]; + String title = group[1]; + + if (urls != null && !urls.trim().isEmpty()) { + List validUrls = Arrays.stream(urls.split(",")) + .map(String::trim) + .filter(url -> !url.isEmpty() && url.startsWith("http")) + .collect(Collectors.toList()); + + if (!validUrls.isEmpty()) { + // float totalHeight = calculateTotalHeight(validUrls); + List wrappedTitleLines = wrapText(title,LEFT_COL_WIDTH - 2 * CELL_PADDING); + float titleHeight = wrappedTitleLines.size() * LINE_HEIGHT; + // 计算图片组的自适应高度 + float imagesHeight = calculateAdjustedImagesHeight(document, validUrls, + RIGHT_COL_WIDTH - 2 * CELL_PADDING, + PDRectangle.A4.getHeight() - 2 * TABLE_MARGIN - titleHeight); + + float totalHeight = Math.max(imagesHeight, titleHeight); + + if (currentY < TABLE_MARGIN + Math.max(totalHeight, titleHeight)) { + cs.close(); + currentPage = new PDPage(PDRectangle.A4); + document.addPage(currentPage); + cs = new PDPageContentStream(document, currentPage); + currentY = PDRectangle.A4.getHeight() - TABLE_MARGIN; + } + + drawImageGroup(cs, document, font, wrappedTitleLines, validUrls, currentY, + Math.max(totalHeight, titleHeight)); + currentY -= Math.max(totalHeight, titleHeight); + } + } + } + + } finally { + cs.close(); + } + // document.save("D:/output.pdf"); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + document.save(baos); + outputStream.flush(); + baos.writeTo(outputStream); + // document.save(outputStream); + } + } + private static List wrapText(String text, float maxWidth) { + List lines = new ArrayList<>(); + int maxCharsPerLine = (int)(maxWidth / (FONT_SIZE * 0.5f)); // 中文字符估算 + + StringBuilder currentLine = new StringBuilder(); + for (String word : text.split("")) { + if (currentLine.length() + word.length() <= maxCharsPerLine) { + currentLine.append(word); + } else { + lines.add(currentLine.toString()); + currentLine = new StringBuilder(word); + } + } + if (currentLine.length() > 0) { + lines.add(currentLine.toString()); + } + return lines; + } + + + private static float calculateTotalHeight(List imageUrls) throws IOException { + float totalHeight = 0; + for (String url : imageUrls) { + totalHeight += estimateImageHeight(url, RIGHT_COL_WIDTH - 10) + 10; + } + return totalHeight; + } + /* private static float calculateAdjustedImagesHeight(PDDocument doc, List imageUrls, + float maxWidth, float maxHeight) throws IOException { + if (imageUrls.isEmpty()) return 0; + + // 1. 预加载所有图片并收集尺寸信息 + List images = new ArrayList<>(); + for (String url : imageUrls) { + try { + PDImageXObject image = PDImageXObject.createFromByteArray(doc, + new URL(url).openStream().readAllBytes(), "embedded-image"); + images.add(image); + } catch (IOException e) { + // 跳过加载失败的图片 + continue; + } + } + + // 2. 计算统一缩放比例 + float uniformScale = Float.MAX_VALUE; + int validImageCount = images.size(); + float availableHeightPerImage = (maxHeight - (validImageCount-1)*10f) / validImageCount; // 10为图片间距 + + for (PDImageXObject image : images) { + // 计算当前图片的最大允许缩放比例 + float widthScale = maxWidth / image.getWidth(); + float heightScale = availableHeightPerImage / image.getHeight(); + float minScale = Math.min(widthScale, heightScale); + + // 取所有图片中最小的缩放比例作为统一比例 + uniformScale = Math.min(uniformScale, minScale); + } + + // 3. 应用最小高度限制 + uniformScale = Math.max(uniformScale, MIN_IMAGE_HEIGHT / + images.stream().map(img -> (float)img.getHeight()).max(Float::compare).orElse(1f)); + // images.stream().mapToFloat(PDImageXObject::getHeight).max().orElse(1f)); + + // 4. 计算总高度(所有图片统一缩放后的高度 + 间距) + float totalHeight = 0; + for (PDImageXObject image : images) { + float scaledHeight = image.getHeight() * uniformScale; + totalHeight += scaledHeight + 10; // 10为图片间距 + if (totalHeight > maxHeight) { + totalHeight -= scaledHeight + 10; // 移除超出的部分 + break; + } + } + + return totalHeight; + }*/ + + private static float calculateAdjustedImagesHeight(PDDocument doc, List imageUrls, + float maxWidth, float maxHeight) throws IOException { + float totalHeight = 0; + float remainingHeight = maxHeight; + + for (String url : imageUrls) { + PDImageXObject image = PDImageXObject.createFromByteArray(doc, + new URL(url).openStream().readAllBytes(), "embedded-image"); + + // 计算图片的缩放比例 + float scale = Math.min( + maxWidth / image.getWidth(), + remainingHeight / image.getHeight() + ); + + // 确保图片高度不小于最小值 + float scaledHeight = Math.max( + image.getHeight() * scale, + MIN_IMAGE_HEIGHT + ); + + totalHeight += scaledHeight + 10; // 10是图片间距 + remainingHeight -= scaledHeight + 10; + + if (remainingHeight <= 0) { + break; // 超出可用高度则停止添加图片 + } + } + + return totalHeight; + } + + private static void drawImageGroup(PDPageContentStream cs, PDDocument doc, PDType0Font font, + List titleLines, List imageUrls, + float startY, float totalHeight) throws IOException { + // float currentImageY = startY - CELL_PADDING; + + // 绘制单元格边框 + cs.setLineWidth(0.5f); + cs.addRect(TABLE_MARGIN, startY - totalHeight, LEFT_COL_WIDTH, totalHeight); + cs.addRect(TABLE_MARGIN + LEFT_COL_WIDTH, startY - totalHeight, RIGHT_COL_WIDTH, totalHeight); + cs.stroke(); + + // 计算文本总高度 + float textHeight = titleLines.size() * LINE_HEIGHT; + float textStartY = startY - (totalHeight / 2) + (textHeight / 2); + + // 在左侧单元格绘制标题(带自动换行) + cs.beginText(); + cs.setFont(font, FONT_SIZE); + for (String line : titleLines) { + // 检查文本是否超出单元格宽度 + /* float textWidth = font.getStringWidth(line) / 1000 * FONT_SIZE; + if (textWidth > LEFT_COL_WIDTH - 2*CELL_PADDING) { + line = TextUtils.truncateWithEllipsis(line, font,LEFT_COL_WIDTH - 2*CELL_PADDING); + }*/ + + cs.newLineAtOffset(TABLE_MARGIN + CELL_PADDING, textStartY); + cs.showText(line); + textStartY -= LINE_HEIGHT; + } + cs.endText(); + float availableWidth = RIGHT_COL_WIDTH - 2 * CELL_PADDING; + float remainingHeight = totalHeight - 2 * CELL_PADDING; + // 在右侧单元格绘制图片 + float currentImageY = startY - 10; + for (String url : imageUrls) { + PDImageXObject image = PDImageXObject.createFromByteArray(doc, + new URL(url).openStream().readAllBytes(), "embedded-image"); + // 计算图片的缩放比例 + float scale = Math.min( + availableWidth / image.getWidth(), + remainingHeight / image.getHeight() + ); + // 确保图片高度不小于最小值 + float scaledHeight = Math.max( + image.getHeight() * scale, + MIN_IMAGE_HEIGHT + ); + float scaledWidth = image.getWidth() * scale; + cs.drawImage(image, + TABLE_MARGIN + LEFT_COL_WIDTH + CELL_PADDING, + currentImageY - scaledHeight, + scaledWidth, scaledHeight); + + currentImageY -= scaledHeight + CELL_PADDING; + remainingHeight -= scaledHeight + CELL_PADDING; + + if (remainingHeight <= 0) { + break; // 超出可用高度则停止绘制 + } + + /* float imageWidth = RIGHT_COL_WIDTH - 10; + float height = imageWidth * image.getHeight() / image.getWidth(); + + cs.drawImage(image, + TABLE_MARGIN + LEFT_COL_WIDTH + 5, + currentImageY - height, + imageWidth, height); + + currentImageY -= height + 10;*/ + } + } + + + // 截断超长文本 + private static String truncateText(PDType0Font font,String text, float maxWidth) throws IOException { + // PDType0Font font = ...; // 获取字体对象 + StringBuilder sb = new StringBuilder(); + float currentWidth = 0; + + for (int i = 0; i < text.length(); i++) { + char c = text.charAt(i); + float charWidth = font.getStringWidth(String.valueOf(c)) / 1000 * FONT_SIZE; + + if (currentWidth + charWidth > maxWidth) { + break; + } + sb.append(c); + currentWidth += charWidth; + } + return sb.toString(); + } + + + // 新增方法:计算文本高度(考虑换行) + private static float getTextHeight(String text, float maxWidth, PDType0Font font, float fontSize) throws IOException { + if (text == null || text.isEmpty()) { + return 0; + } + + // 简单估算:假设每个中文字符宽度等于字体大小 + int charsPerLine = (int)(maxWidth / fontSize); + int lineCount = (int)Math.ceil((double)text.length() / charsPerLine); + + return lineCount * fontSize * 1.2f; // 行间距1.2倍 + } + + // 改进方法:绘制自动换行文本 + private static void drawWrappedText(PDPageContentStream cs, PDType0Font font, + float fontSize, String text, + float startX, float startY, float maxWidth) throws IOException { + cs.setFont(font, fontSize); + cs.setLeading(fontSize * 1.2f); // 行间距 + + // 简单换行实现 + int charsPerLine = (int)(maxWidth / (fontSize * 0.8)); // 中文字符估算 + int pos = 0; + float currentY = startY; + + while (pos < text.length()) { + int endPos = Math.min(pos + charsPerLine, text.length()); + String line = text.substring(pos, endPos); + + cs.beginText(); + cs.newLineAtOffset(startX, currentY); + cs.showText(line); + cs.endText(); + + pos = endPos; + currentY -= fontSize * 1.2f; + } + } + // 图片高度预估方法 + private static float estimateImageHeight(String imageUrl, float targetWidth) throws IOException { + try (InputStream is = new URL(imageUrl).openStream()) { + BufferedImage img = ImageIO.read(is); + return img.getHeight() * (targetWidth / img.getWidth()); + } + } + + /* public static void generateInstallationPDF(DeviceInstallInfo entity, OutputStream outputStream) throws IOException { + try (PDDocument document = new PDDocument()) { +// 加载中文字体(需确保D:/simsun.ttc存在) + PDType0Font font = PDType0Font.load(document, new File("D:\\simsun.ttf")); + + // 创建单页文档 + PDPage page = new PDPage(PDRectangle.A4); + document.addPage(page); + PDPageContentStream cs = new PDPageContentStream(document, page); + + float currentY = PDRectangle.A4.getHeight() - TABLE_MARGIN; + + // 3. 绘制标题(居中) + drawCenteredText(cs, font, FONT_SIZE + 6, + "贵阳户内安装信息录入表", + PDRectangle.A4.getWidth() / 2, currentY); + currentY -= ROW_HEIGHT * 1.5f; + + // 4. 基本信息表格 + String[][] baseData = { + {"安装班组", entity.getProposerTeam()}, + {"安装人", entity.getProposer()}, + {"安装时间", entity.getProposerTime().toString()}, + {"小区名称", entity.getCommunityName()}, + {"楼栋号", entity.getBuildingUnit()}, + {"单元号", entity.getBuildingUnit() != null ? + entity.getBuildingUnit().split("-")[0] : ""}, + {"房号", entity.getRoomNo()}, + {"用户姓名", entity.getUserName()}, + {"联系方式", entity.getUserIpone()}, + {"灶具类型", entity.getDeviceName() != null ? + (entity.getDeviceName().contains("台式") ? "台式灶" : "嵌入式灶") : ""} + }; + drawTable(cs, font, TABLE_MARGIN, currentY, baseData, + new float[]{COLUMN_LEFT_WIDTH, COLUMN_WIDTH}); + currentY -= (ROW_HEIGHT * baseData.length) + 20f; + + // 5. 图片处理(内嵌到表格) + if (entity.getBeforeInstallationImage() != null) { + if (currentY < TABLE_MARGIN + 150) { + cs.close(); + page = new PDPage(PDRectangle.A4); + document.addPage(page); + cs = new PDPageContentStream(document, page); + currentY = PDRectangle.A4.getHeight() - TABLE_MARGIN; + } + //page = new PDPage(PDRectangle.A4); + // document.addPage(page); + currentY = addImageRow(cs, document, font, "安装前图片", + entity.getBeforeInstallationImage(), TABLE_MARGIN, currentY); + // currentY -= ROW_HEIGHT * 3; // 图片行高是普通行的3倍 + } + // 其他图片处理同理... + + document.save("D:/output.pdf"); + document.save(outputStream); + } + + + }*/ + + /* private static void drawTable(PDPageContentStream cs, PDType0Font font, + float x, float y, String[][] data, float[] colWidths) throws IOException { + +// 计算表格总宽度 + float tableWidth = 0; + for (float width : colWidths) tableWidth += width; + +// 绘制外边框 + cs.setLineWidth(1.5f); + cs.addRect(x, y - ROW_HEIGHT * data.length, tableWidth, ROW_HEIGHT * data.length); + cs.stroke(); + +// 绘制列线 + float currentX = x; + for (int i = 0; i < colWidths.length - 1; i++) { + currentX += colWidths[i]; + cs.moveTo(currentX, y); + cs.lineTo(currentX, y - ROW_HEIGHT * data.length); + cs.stroke(); + } + +// 绘制行线 + for (int i = 1; i < data.length; i++) { + cs.moveTo(x, y - ROW_HEIGHT * i); + cs.lineTo(x + tableWidth, y - ROW_HEIGHT * i); + cs.stroke(); + } + // 改进的文本定位 + for (int row = 0; row < data.length; row++) { + for (int col = 0; col < data[row].length; col++) { + // 方案1:手动求和(推荐) + float sum = 0; + for (int i = 0; i < col; i++) { + sum += colWidths[i]; + } + + String text = data[row][col] != null ? data[row][col] : ""; + float textWidth = font.getStringWidth(text) / 1000 * FONT_SIZE; + float textX = x + sum + + (colWidths[col] - textWidth)/2; + float textY = y - (row * ROW_HEIGHT) - (ROW_HEIGHT/2 - FONT_SIZE/4); + + cs.beginText(); + cs.newLineAtOffset(textX, textY); + cs.showText(text); + cs.endText(); + } + }*/ +// 填写内容(严格居中) + /* for (int row = 0; row < data.length; row++) { + currentX = x; + for (int col = 0; col < data[row].length; col++) { + String text = data[row][col] != null ? data[row][col] : ""; + float textWidth = font.getStringWidth(text) / 1000 * FONT_SIZE; + + cs.beginText(); + cs.newLineAtOffset( + currentX + (colWidths[col] - textWidth) / 2, + y - (ROW_HEIGHT * row) - (ROW_HEIGHT / 2 + FONT_SIZE / 3) + ); + cs.showText(text); + cs.endText(); + + currentX += colWidths[col]; + } + }*/ + + + + + private static void drawTable(PDPageContentStream cs, PDType0Font font, + float x, float y, String[][] data, float[] colWidths) throws IOException { + +// 修改后的表格绘制代码 + if (data == null || data.length == 0 || colWidths == null) return; + + final float ROW_HEIGHT = 35f; // 增大行高以适应更大字体 + final float FONT_SIZE = 14f; // 增大字体大小 + final float PADDING = 5f; + +// 计算表格总宽度 + float tableWidth = 0; + for (float width : colWidths) { + tableWidth += width; + } + +// 绘制表格边框和分隔线(保持不变) + cs.setLineWidth(1f); + cs.addRect(x, y - ROW_HEIGHT * data.length, tableWidth, ROW_HEIGHT * data.length); + cs.stroke(); + +// 绘制列分隔线 + float currentX = x; + for (int i = 1; i < colWidths.length; i++) { + currentX += colWidths[i-1]; + cs.moveTo(currentX, y); + cs.lineTo(currentX, y - ROW_HEIGHT * data.length); + cs.stroke(); + } + +// 绘制行分隔线 + for (int i = 1; i <= data.length; i++) { + cs.moveTo(x, y - ROW_HEIGHT * i); + cs.lineTo(x + tableWidth, y - ROW_HEIGHT * i); + cs.stroke(); + } + +// 填写表格内容(关键修改部分) + cs.setFont(font, FONT_SIZE); + for (int row = 0; row < data.length; row++) { + currentX = x; + for (int col = 0; col < data[row].length; col++) { + String text = data[row][col] != null ? data[row][col] : ""; + // 计算文本宽度 + float textWidth = font.getStringWidth(text) / 1000 * FONT_SIZE; + float centerOffset = (colWidths[col] - textWidth) / 2; + // 修正垂直居中计算(关键修改) + float baselineOffset = (ROW_HEIGHT - FONT_SIZE) / 3; // 更精确的基线计算 + cs.beginText(); + cs.newLineAtOffset( + currentX + centerOffset, + y - (ROW_HEIGHT * row) - FONT_SIZE - baselineOffset // 修正垂直位置 + ); + cs.showText(text); + cs.endText(); + currentX += colWidths[col]; + } + } + } + + + + private static float addImageRow(PDPageContentStream cs, PDDocument doc, + PDType0Font font, String title, String imageUrl, + float startX, float startY) throws IOException { + // 加载图片 + PDImageXObject image = PDImageXObject.createFromByteArray(doc, + new URL(imageUrl).openStream().readAllBytes(), "embedded-image"); + // 动态计算尺寸 + float imageWidth = RIGHT_COL_WIDTH - 10; + float scale = imageWidth / image.getWidth(); + float imageHeight = image.getHeight() * scale; + float rowHeight = imageHeight + 20; + + // 绘制单元格边框 + cs.setLineWidth(0.5f); + cs.addRect(startX, startY - rowHeight, LEFT_COL_WIDTH, rowHeight); + cs.addRect(startX + LEFT_COL_WIDTH, startY - rowHeight, RIGHT_COL_WIDTH, rowHeight); + cs.stroke(); + + // 垂直居中文本(改进算法) + float textY = startY - rowHeight/2 + FONT_SIZE/2; + //String title = "安装完成探测器工作图片\n检测时间:2025-08-14"; + + /* if(title.contains("\n")){ + String[] lines = title.split("\n"); + textY = startY - rowHeight/2 + FONT_SIZE/2 + (lines.length-1)*FONT_SIZE/2; + }*/ + drawCenteredText(cs, font, FONT_SIZE, title, + startX + LEFT_COL_WIDTH/2, textY); + + // 绘制图片(带5pt边距) + cs.drawImage(image, + startX + LEFT_COL_WIDTH + 5, + startY - rowHeight + 10, + imageWidth, imageHeight); + + return startY - rowHeight - 10; + /*// 计算图片尺寸(保持比例) + float imageWidth = RIGHT_COL_WIDTH - 10; + float scale = imageWidth / image.getWidth(); + float imageHeight = image.getHeight() * scale; + + // 动态计算行高(图片高度+上下边距20) + float dynamicRowHeight = imageHeight + 20; + + // 绘制左侧标题单元格 + cs.setLineWidth(0.5f); + cs.addRect(TABLE_MARGIN, startY - dynamicRowHeight, LEFT_COL_WIDTH, dynamicRowHeight); + + // 绘制右侧图片单元格(高度与左侧同步) + cs.addRect(TABLE_MARGIN + LEFT_COL_WIDTH, startY - dynamicRowHeight, RIGHT_COL_WIDTH, dynamicRowHeight); + cs.stroke(); + + // 居中绘制标题文本 + float titleWidth = font.getStringWidth(title) / 1000 * FONT_SIZE; + float titleX = TABLE_MARGIN + (LEFT_COL_WIDTH - titleWidth) / 2; + float titleY = startY - (dynamicRowHeight / 2) - (FONT_SIZE / 3); + + cs.beginText(); + cs.setFont(font, FONT_SIZE); + cs.newLineAtOffset(titleX, titleY); + cs.showText(title); + cs.endText(); + + // 居中绘制图片 + float imageX = TABLE_MARGIN + LEFT_COL_WIDTH + 5; + float imageY = startY - dynamicRowHeight + 10; + cs.drawImage(image, imageX, imageY, imageWidth, imageHeight); + + // 返回新的Y坐标(当前位置减去行高和间距) + return startY - dynamicRowHeight - 10;*/ + } + + /* private static float addImageRow(PDPageContentStream cs, PDDocument doc, + PDType0Font font, String title, String imageUrl, float x, float y) throws IOException { +// 绘制标题行 + +// 加载并绘制图片(居中) + PDImageXObject image = PDImageXObject.createFromByteArray(doc, + new URL(imageUrl).openStream().readAllBytes(), "embedded-image"); + // 计算图片尺寸(保持比例) + +// 加载并绘制图片 + + // 计算图片缩放比例 + float imageWidth = RIGHT_COL_WIDTH - 10; + float scale = imageWidth / image.getWidth(); + float imageHeight = image.getHeight() * scale; + float rowHeight = Math.max(ROW_HEIGHT, imageHeight + 10); + + // 绘制图片行边框 + cs.setLineWidth(0.5f); + cs.addRect(TABLE_MARGIN, y - rowHeight, LEFT_COL_WIDTH, rowHeight); + cs.addRect(TABLE_MARGIN + LEFT_COL_WIDTH, y - rowHeight, RIGHT_COL_WIDTH, rowHeight); + cs.stroke(); + String[][] titleData = {{title, ""}}; + // drawTable(cs, font, x, y, titleData, new float[]{COLUMN_LEFT_WIDTH, COLUMN_WIDTH}); + // 写入标题文本 + // 新代码(居中显示) + float titleWidth = font.getStringWidth(title) / 1000 * 20; // 计算文本宽度 + float centerX = TABLE_MARGIN + (LEFT_COL_WIDTH - titleWidth) / 2; // 计算居中位置 + + cs.beginText(); + cs.setFont(font, 20); + cs.newLineAtOffset(centerX, y - 15); // 使用计算出的居中位置 + cs.showText(title); + cs.endText(); + // 绘制图片(居中显示) + float imageY = y - (rowHeight/2) - (imageHeight/2); + cs.drawImage(image, TABLE_MARGIN + LEFT_COL_WIDTH + 5, imageY, imageWidth, imageHeight); + + y -= rowHeight + 10; + return y - rowHeight - 10; // 返回新的Y坐标 + }*/ + + + private static void drawCenteredText(PDPageContentStream cs, PDType0Font font, + float fontSize, String text, float centerX, float baselineY) throws IOException { + + float textWidth = font.getStringWidth(text) / 1000 * fontSize; + cs.setFont(font, fontSize); + cs.beginText(); + // 原始调用改进为 + cs.newLineAtOffset(centerX - textWidth / 2, baselineY); + cs.showText(text); + cs.endText(); + } + + +} diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/config/PDFGenerator11.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/config/PDFGenerator11.java new file mode 100644 index 0000000..bb49a8e --- /dev/null +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/config/PDFGenerator11.java @@ -0,0 +1,474 @@ +package cc.iotkit.manager.config; + + +import cc.iotkit.model.device.DeviceInstallInfo; +import cn.hutool.core.util.ObjectUtil; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDPageContentStream; +import org.apache.pdfbox.pdmodel.common.PDRectangle; +import org.apache.pdfbox.pdmodel.font.PDType0Font; +import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.*; +import java.net.URL; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +public class PDFGenerator11 { + // 1. 表格参数配置 + + // 参数配置(优化后) + private static final float FONT_SIZE = 14f; + private static final float ROW_HEIGHT = 35f; + private static final float TABLE_MARGIN = 50f; + private static final float LEFT_COL_WIDTH = 130f; + private static final float RIGHT_COL_WIDTH = 350f; + private static final float[] COLUMN_WIDTHS = {LEFT_COL_WIDTH, RIGHT_COL_WIDTH}; + + public static void generateInstallationPDF(DeviceInstallInfo entity, OutputStream outputStream) throws IOException { + try (PDDocument document = new PDDocument()) { + // 加载字体(需替换实际路径) + // PDType0Font font = PDType0Font.load(document, new File("D:\\simsun.ttf")); + PDType0Font font = PDType0Font.load(document, new File("/ttf/simsun.ttf")); + + // 初始化第一页 + PDPage currentPage = new PDPage(PDRectangle.A4); + document.addPage(currentPage); + PDPageContentStream cs = new PDPageContentStream(document, currentPage); + float currentY = PDRectangle.A4.getHeight() - TABLE_MARGIN; + + try { + // 1. 绘制标题(居中) + drawCenteredText(cs, font, FONT_SIZE+10, + "安装信息录入表", + PDRectangle.A4.getWidth()/2, currentY); + currentY -= ROW_HEIGHT * 1.5f; + + // 2. 绘制基本信息表格 + String[][] baseData = { + // {"公司名称", entity.getCorporateName()}, + {"申请时间", entity.getProposerTime().toString()}, + {"申请人", entity.getProposer()}, + {"申请人班组", entity.getProposerTeam()}, + {"小区名字", entity.getCommunityName()}, + {"用户姓名", entity.getUserName()}, + {"电话", entity.getUserIpone()}, + {"楼栋单元号", entity.getBuildingUnit()}, + {"房间号", entity.getRoomNo()}, + {"报警器编号", entity.getDeviceName()}, + {"切断阀编号", entity.getShutValueNumber()}, + {"燃气表号", entity.getGasMeterNumber()}, + {"备注", entity.getBuildingUnit()} + + }; + drawTable(cs, font, TABLE_MARGIN, currentY, baseData, COLUMN_WIDTHS); + currentY -= (ROW_HEIGHT * baseData.length) + 20f; +// @ApiModelProperty(value = "安装前图片") + // 创建后续页面 - 图片部分 + + // 3. 图片处理(带自动分页) + List imageUrls = Arrays.asList( + entity.getBeforeInstallationImage(), + entity.getWorkingOfTheDetectorImage(), + entity.getSideLeakageImage(), + entity.getIgnitionPictureImage(), + entity.getInstallThePanoramicImage(), + entity.getOfGasMeterImage(), + entity.getWorkOrderImage(), + entity.getPunchingImage(), + entity.getFiexImage() + + ).stream().filter(Objects::nonNull).collect(Collectors.toList()); + + for (String url : imageUrls) { + // 空间检查(动态计算所需高度) + if (ObjectUtil.isNotNull(url) && !"".equals(url) && url.startsWith("http")) { + float requiredHeight = estimateImageHeight(url, RIGHT_COL_WIDTH - 10) + 30; + if (currentY < TABLE_MARGIN + requiredHeight) { + cs.close(); + currentPage = new PDPage(PDRectangle.A4); + document.addPage(currentPage); + cs = new PDPageContentStream(document, currentPage); + currentY = PDRectangle.A4.getHeight() - TABLE_MARGIN; + } + String title = ""; + // 安装前图片页 + if (entity.getBeforeInstallationImage() != null && entity.getBeforeInstallationImage().equals(url)) { + title = "安装前图片"; + } else if (entity.getWorkingOfTheDetectorImage() != null && entity.getWorkingOfTheDetectorImage().equals(url)) { + title = "安装完成探测器工作图片"; + + } + // 测漏图片页 + else if (entity.getSideLeakageImage() != null && entity.getSideLeakageImage().equals(url)) { + title = "测漏图片"; + } + // 点火图片页 + else if (entity.getIgnitionPictureImage() != null && entity.getIgnitionPictureImage().equals(url)) { + title = "点火图片"; + } else if (entity.getInstallThePanoramicImage() != null && entity.getInstallThePanoramicImage().equals(url)) { + title = "安装完成全景图片"; + } else if (entity.getOfGasMeterImage() != null && entity.getOfGasMeterImage().equals(url)) { + title = "燃气表图片"; + } + // 工单签字页 + else if (entity.getWorkOrderImage() != null && entity.getWorkOrderImage().equals(url)) { + title = "工单图片"; + } + // 打孔图片页 + else if (entity.getPunchingImage() != null && entity.getPunchingImage().equals(url)) { + title = "打孔图片"; + } else if (entity.getFiexImage() != null && entity.getFiexImage().equals(url)) { + title = "安装电源线图片"; + } + if (ObjectUtil.isNotNull(title) && !"".equals(title)) + currentY = addImageRow(cs, document, font, title, url, TABLE_MARGIN, currentY); + } + } + } finally { + cs.close(); + } + // document.save("D:/output.pdf"); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + document.save(baos); + outputStream.flush(); + baos.writeTo(outputStream); + // document.save(outputStream); + } + } + + // 图片高度预估方法 + private static float estimateImageHeight(String imageUrl, float targetWidth) throws IOException { + try (InputStream is = new URL(imageUrl).openStream()) { + BufferedImage img = ImageIO.read(is); + return img.getHeight() * (targetWidth / img.getWidth()); + } + } + + /* public static void generateInstallationPDF(DeviceInstallInfo entity, OutputStream outputStream) throws IOException { + try (PDDocument document = new PDDocument()) { +// 加载中文字体(需确保D:/simsun.ttc存在) + PDType0Font font = PDType0Font.load(document, new File("D:\\simsun.ttf")); + + // 创建单页文档 + PDPage page = new PDPage(PDRectangle.A4); + document.addPage(page); + PDPageContentStream cs = new PDPageContentStream(document, page); + + float currentY = PDRectangle.A4.getHeight() - TABLE_MARGIN; + + // 3. 绘制标题(居中) + drawCenteredText(cs, font, FONT_SIZE + 6, + "贵阳户内安装信息录入表", + PDRectangle.A4.getWidth() / 2, currentY); + currentY -= ROW_HEIGHT * 1.5f; + + // 4. 基本信息表格 + String[][] baseData = { + {"安装班组", entity.getProposerTeam()}, + {"安装人", entity.getProposer()}, + {"安装时间", entity.getProposerTime().toString()}, + {"小区名称", entity.getCommunityName()}, + {"楼栋号", entity.getBuildingUnit()}, + {"单元号", entity.getBuildingUnit() != null ? + entity.getBuildingUnit().split("-")[0] : ""}, + {"房号", entity.getRoomNo()}, + {"用户姓名", entity.getUserName()}, + {"联系方式", entity.getUserIpone()}, + {"灶具类型", entity.getDeviceName() != null ? + (entity.getDeviceName().contains("台式") ? "台式灶" : "嵌入式灶") : ""} + }; + drawTable(cs, font, TABLE_MARGIN, currentY, baseData, + new float[]{COLUMN_LEFT_WIDTH, COLUMN_WIDTH}); + currentY -= (ROW_HEIGHT * baseData.length) + 20f; + + // 5. 图片处理(内嵌到表格) + if (entity.getBeforeInstallationImage() != null) { + if (currentY < TABLE_MARGIN + 150) { + cs.close(); + page = new PDPage(PDRectangle.A4); + document.addPage(page); + cs = new PDPageContentStream(document, page); + currentY = PDRectangle.A4.getHeight() - TABLE_MARGIN; + } + //page = new PDPage(PDRectangle.A4); + // document.addPage(page); + currentY = addImageRow(cs, document, font, "安装前图片", + entity.getBeforeInstallationImage(), TABLE_MARGIN, currentY); + // currentY -= ROW_HEIGHT * 3; // 图片行高是普通行的3倍 + } + // 其他图片处理同理... + + document.save("D:/output.pdf"); + document.save(outputStream); + } + + + }*/ + + /* private static void drawTable(PDPageContentStream cs, PDType0Font font, + float x, float y, String[][] data, float[] colWidths) throws IOException { + +// 计算表格总宽度 + float tableWidth = 0; + for (float width : colWidths) tableWidth += width; + +// 绘制外边框 + cs.setLineWidth(1.5f); + cs.addRect(x, y - ROW_HEIGHT * data.length, tableWidth, ROW_HEIGHT * data.length); + cs.stroke(); + +// 绘制列线 + float currentX = x; + for (int i = 0; i < colWidths.length - 1; i++) { + currentX += colWidths[i]; + cs.moveTo(currentX, y); + cs.lineTo(currentX, y - ROW_HEIGHT * data.length); + cs.stroke(); + } + +// 绘制行线 + for (int i = 1; i < data.length; i++) { + cs.moveTo(x, y - ROW_HEIGHT * i); + cs.lineTo(x + tableWidth, y - ROW_HEIGHT * i); + cs.stroke(); + } + // 改进的文本定位 + for (int row = 0; row < data.length; row++) { + for (int col = 0; col < data[row].length; col++) { + // 方案1:手动求和(推荐) + float sum = 0; + for (int i = 0; i < col; i++) { + sum += colWidths[i]; + } + + String text = data[row][col] != null ? data[row][col] : ""; + float textWidth = font.getStringWidth(text) / 1000 * FONT_SIZE; + float textX = x + sum + + (colWidths[col] - textWidth)/2; + float textY = y - (row * ROW_HEIGHT) - (ROW_HEIGHT/2 - FONT_SIZE/4); + + cs.beginText(); + cs.newLineAtOffset(textX, textY); + cs.showText(text); + cs.endText(); + } + }*/ +// 填写内容(严格居中) + /* for (int row = 0; row < data.length; row++) { + currentX = x; + for (int col = 0; col < data[row].length; col++) { + String text = data[row][col] != null ? data[row][col] : ""; + float textWidth = font.getStringWidth(text) / 1000 * FONT_SIZE; + + cs.beginText(); + cs.newLineAtOffset( + currentX + (colWidths[col] - textWidth) / 2, + y - (ROW_HEIGHT * row) - (ROW_HEIGHT / 2 + FONT_SIZE / 3) + ); + cs.showText(text); + cs.endText(); + + currentX += colWidths[col]; + } + }*/ + + + + + private static void drawTable(PDPageContentStream cs, PDType0Font font, + float x, float y, String[][] data, float[] colWidths) throws IOException { + +// 修改后的表格绘制代码 + if (data == null || data.length == 0 || colWidths == null) return; + + final float ROW_HEIGHT = 35f; // 增大行高以适应更大字体 + final float FONT_SIZE = 14f; // 增大字体大小 + final float PADDING = 5f; + +// 计算表格总宽度 + float tableWidth = 0; + for (float width : colWidths) { + tableWidth += width; + } + +// 绘制表格边框和分隔线(保持不变) + cs.setLineWidth(1f); + cs.addRect(x, y - ROW_HEIGHT * data.length, tableWidth, ROW_HEIGHT * data.length); + cs.stroke(); + +// 绘制列分隔线 + float currentX = x; + for (int i = 1; i < colWidths.length; i++) { + currentX += colWidths[i-1]; + cs.moveTo(currentX, y); + cs.lineTo(currentX, y - ROW_HEIGHT * data.length); + cs.stroke(); + } + +// 绘制行分隔线 + for (int i = 1; i <= data.length; i++) { + cs.moveTo(x, y - ROW_HEIGHT * i); + cs.lineTo(x + tableWidth, y - ROW_HEIGHT * i); + cs.stroke(); + } + +// 填写表格内容(关键修改部分) + cs.setFont(font, FONT_SIZE); + for (int row = 0; row < data.length; row++) { + currentX = x; + for (int col = 0; col < data[row].length; col++) { + String text = data[row][col] != null ? data[row][col] : ""; + // 计算文本宽度 + float textWidth = font.getStringWidth(text) / 1000 * FONT_SIZE; + float centerOffset = (colWidths[col] - textWidth) / 2; + // 修正垂直居中计算(关键修改) + float baselineOffset = (ROW_HEIGHT - FONT_SIZE) / 3; // 更精确的基线计算 + cs.beginText(); + cs.newLineAtOffset( + currentX + centerOffset, + y - (ROW_HEIGHT * row) - FONT_SIZE - baselineOffset // 修正垂直位置 + ); + cs.showText(text); + cs.endText(); + currentX += colWidths[col]; + } + } + } + + + + private static float addImageRow(PDPageContentStream cs, PDDocument doc, + PDType0Font font, String title, String imageUrl, + float startX, float startY) throws IOException { + // 加载图片 + PDImageXObject image = PDImageXObject.createFromByteArray(doc, + new URL(imageUrl).openStream().readAllBytes(), "embedded-image"); + // 动态计算尺寸 + float imageWidth = RIGHT_COL_WIDTH - 10; + float scale = imageWidth / image.getWidth(); + float imageHeight = image.getHeight() * scale; + float rowHeight = imageHeight + 20; + + // 绘制单元格边框 + cs.setLineWidth(0.5f); + cs.addRect(startX, startY - rowHeight, LEFT_COL_WIDTH, rowHeight); + cs.addRect(startX + LEFT_COL_WIDTH, startY - rowHeight, RIGHT_COL_WIDTH, rowHeight); + cs.stroke(); + + // 垂直居中文本(改进算法) + float textY = startY - rowHeight/2 + FONT_SIZE/2; + //String title = "安装完成探测器工作图片\n检测时间:2025-08-14"; + + /* if(title.contains("\n")){ + String[] lines = title.split("\n"); + textY = startY - rowHeight/2 + FONT_SIZE/2 + (lines.length-1)*FONT_SIZE/2; + }*/ + drawCenteredText(cs, font, FONT_SIZE, title, + startX + LEFT_COL_WIDTH/2, textY); + + // 绘制图片(带5pt边距) + cs.drawImage(image, + startX + LEFT_COL_WIDTH + 5, + startY - rowHeight + 10, + imageWidth, imageHeight); + + return startY - rowHeight - 10; + /*// 计算图片尺寸(保持比例) + float imageWidth = RIGHT_COL_WIDTH - 10; + float scale = imageWidth / image.getWidth(); + float imageHeight = image.getHeight() * scale; + + // 动态计算行高(图片高度+上下边距20) + float dynamicRowHeight = imageHeight + 20; + + // 绘制左侧标题单元格 + cs.setLineWidth(0.5f); + cs.addRect(TABLE_MARGIN, startY - dynamicRowHeight, LEFT_COL_WIDTH, dynamicRowHeight); + + // 绘制右侧图片单元格(高度与左侧同步) + cs.addRect(TABLE_MARGIN + LEFT_COL_WIDTH, startY - dynamicRowHeight, RIGHT_COL_WIDTH, dynamicRowHeight); + cs.stroke(); + + // 居中绘制标题文本 + float titleWidth = font.getStringWidth(title) / 1000 * FONT_SIZE; + float titleX = TABLE_MARGIN + (LEFT_COL_WIDTH - titleWidth) / 2; + float titleY = startY - (dynamicRowHeight / 2) - (FONT_SIZE / 3); + + cs.beginText(); + cs.setFont(font, FONT_SIZE); + cs.newLineAtOffset(titleX, titleY); + cs.showText(title); + cs.endText(); + + // 居中绘制图片 + float imageX = TABLE_MARGIN + LEFT_COL_WIDTH + 5; + float imageY = startY - dynamicRowHeight + 10; + cs.drawImage(image, imageX, imageY, imageWidth, imageHeight); + + // 返回新的Y坐标(当前位置减去行高和间距) + return startY - dynamicRowHeight - 10;*/ + } + + /* private static float addImageRow(PDPageContentStream cs, PDDocument doc, + PDType0Font font, String title, String imageUrl, float x, float y) throws IOException { +// 绘制标题行 + +// 加载并绘制图片(居中) + PDImageXObject image = PDImageXObject.createFromByteArray(doc, + new URL(imageUrl).openStream().readAllBytes(), "embedded-image"); + // 计算图片尺寸(保持比例) + +// 加载并绘制图片 + + // 计算图片缩放比例 + float imageWidth = RIGHT_COL_WIDTH - 10; + float scale = imageWidth / image.getWidth(); + float imageHeight = image.getHeight() * scale; + float rowHeight = Math.max(ROW_HEIGHT, imageHeight + 10); + + // 绘制图片行边框 + cs.setLineWidth(0.5f); + cs.addRect(TABLE_MARGIN, y - rowHeight, LEFT_COL_WIDTH, rowHeight); + cs.addRect(TABLE_MARGIN + LEFT_COL_WIDTH, y - rowHeight, RIGHT_COL_WIDTH, rowHeight); + cs.stroke(); + String[][] titleData = {{title, ""}}; + // drawTable(cs, font, x, y, titleData, new float[]{COLUMN_LEFT_WIDTH, COLUMN_WIDTH}); + // 写入标题文本 + // 新代码(居中显示) + float titleWidth = font.getStringWidth(title) / 1000 * 20; // 计算文本宽度 + float centerX = TABLE_MARGIN + (LEFT_COL_WIDTH - titleWidth) / 2; // 计算居中位置 + + cs.beginText(); + cs.setFont(font, 20); + cs.newLineAtOffset(centerX, y - 15); // 使用计算出的居中位置 + cs.showText(title); + cs.endText(); + // 绘制图片(居中显示) + float imageY = y - (rowHeight/2) - (imageHeight/2); + cs.drawImage(image, TABLE_MARGIN + LEFT_COL_WIDTH + 5, imageY, imageWidth, imageHeight); + + y -= rowHeight + 10; + return y - rowHeight - 10; // 返回新的Y坐标 + }*/ + + + private static void drawCenteredText(PDPageContentStream cs, PDType0Font font, + float fontSize, String text, float centerX, float baselineY) throws IOException { + + float textWidth = font.getStringWidth(text) / 1000 * fontSize; + cs.setFont(font, fontSize); + cs.beginText(); + // 原始调用改进为 + cs.newLineAtOffset(centerX - textWidth / 2, baselineY); + cs.showText(text); + cs.endText(); + } + + +} diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/config/PDFUtils.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/config/PDFUtils.java new file mode 100644 index 0000000..aa6e574 --- /dev/null +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/config/PDFUtils.java @@ -0,0 +1,52 @@ +package cc.iotkit.manager.config; + + +import org.apache.pdfbox.pdmodel.PDPageContentStream; +import org.apache.pdfbox.pdmodel.font.PDType0Font; + +import java.io.IOException; + +public class PDFUtils { + // 计算文本居中位置(水平+垂直) + public static float[] calculateCenterPosition( + PDType0Font font, + float fontSize, + String text, + float rectX, float rectY, + float rectWidth, float rectHeight + ) { + try { + // 计算文本宽度 + float textWidth = font.getStringWidth(text) / 1000 * fontSize; + + // 计算垂直偏移(考虑字体基线) + float ascent = font.getFontDescriptor().getAscent() / 1000 * fontSize; + float descent = font.getFontDescriptor().getDescent() / 1000 * fontSize; + float textHeight = ascent - descent; + + return new float[]{ + rectX + (rectWidth - textWidth) / 2, // 水平居中X + rectY + (rectHeight + textHeight) / 2 - descent // 垂直居中Y + }; + } catch (IOException e) { + return new float[]{rectX, rectY}; + } + } + + // 绘制对齐文本(封装方法) + public static void drawAlignedText( + PDPageContentStream cs, + PDType0Font font, + float fontSize, + String text, + float x, float y, + float width, float height + ) throws IOException { + float[] pos = calculateCenterPosition(font, fontSize, text, x, y, width, height); + cs.setFont(font, fontSize); + cs.beginText(); + cs.newLineAtOffset(pos[0], pos[1]); + cs.showText(text); + cs.endText(); + } +} diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/AlertController.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/AlertController.java index 1a2fcc0..e1055a4 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/AlertController.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/AlertController.java @@ -28,6 +28,7 @@ import cc.iotkit.common.api.Request; import cc.iotkit.common.exception.BizException; import cc.iotkit.common.satoken.utils.AuthUtil; import cc.iotkit.common.satoken.utils.LoginHelper; +import cc.iotkit.manager.dto.bo.device.DeviceInfoBo; import cc.iotkit.manager.service.AlertService; import cc.iotkit.model.alert.AlertConfig; import cc.iotkit.model.alert.AlertRecord; @@ -64,9 +65,9 @@ public class AlertController { String uid = AuthUtil.getUserId(); request.getData().setUid(uid); } - if(ObjectUtils.isNotEmpty( alertService.getAlertConfig(request.getData()))){ + /* if(ObjectUtils.isNotEmpty( alertService.getAlertConfig(request.getData()))){ throw new BizException("该规则模版已存在"); - } + }*/ return alertService.createAlertConfig(request.getData()); } @@ -78,14 +79,14 @@ public class AlertController { String uid = AuthUtil.getUserId(); request.getData().setUid(uid); } - List list= alertService.getAlertConfig(request.getData()); + /* List list= alertService.getAlertConfig(request.getData()); if(ObjectUtils.isNotEmpty(list)){ for (int i = 0; i < list.size(); i++) { if(!list.get(i).getRuleInfoId().equals(request.getData().getRuleInfoId())){ throw new BizException("该规则模版已存在"); } } - } + }*/ return alertService.updateAlertConfig(request.getData()); } @@ -105,11 +106,18 @@ public class AlertController { @ApiOperation("查询告警消息分页") - @SaCheckPermission("iot:alert:query") + // @SaCheckPermission("iot:alert:query") @PostMapping("/selectAlertRecordPage") public Paging selectAlertRecordPage(@RequestBody @Validated PageRequest request) { + request.getData().setStatusFlg(true); return alertService.selectAlertRecordPage(request); } - + @ApiOperation("查询告警消息已读未读") + // @SaCheckPermission("iot:alert:query") + @PostMapping("/saveAlertRecord") + public void saveAlertRecord(@RequestBody @Validated Request bo) { + alertService.save(bo.getData()); + // return alertService.selectAlertRecordPage(request); + } } diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/DeviceController.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/DeviceController.java index 9369c86..fe08be0 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/DeviceController.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/DeviceController.java @@ -27,7 +27,12 @@ import cc.iotkit.common.api.Paging; import cc.iotkit.common.api.Request; import cc.iotkit.common.api.Response; import cc.iotkit.common.excel.utils.ExcelUtil; +import cc.iotkit.common.log.annotation.Log; +import cc.iotkit.common.log.enums.BusinessType; +import cc.iotkit.common.satoken.utils.LoginHelper; +import cc.iotkit.common.tenant.helper.TenantHelper; import cc.iotkit.common.thing.ThingModelMessage; +import cc.iotkit.common.utils.MapstructUtils; import cc.iotkit.common.validate.QueryGroup; import cc.iotkit.manager.dto.bo.device.*; import cc.iotkit.manager.dto.bo.deviceconfig.DeviceConfigAddBo; @@ -37,6 +42,7 @@ import cc.iotkit.manager.dto.bo.thingmodel.ThingModelMessageBo; import cc.iotkit.manager.dto.vo.deviceconfig.DeviceConfigVo; import cc.iotkit.manager.dto.vo.devicegroup.DeviceGroupImportVo; import cc.iotkit.manager.dto.vo.devicegroup.DeviceGroupVo; +import cc.iotkit.manager.dto.vo.deviceinfo.DeviceInfoExpordVo; import cc.iotkit.manager.dto.vo.deviceinfo.DeviceInfoImportVo; import cc.iotkit.manager.dto.vo.deviceinfo.DeviceInfoVo; import cc.iotkit.manager.dto.vo.deviceinfo.ParentDeviceVo; @@ -51,6 +57,7 @@ import cc.iotkit.model.device.DeviceInfo; import cc.iotkit.model.device.message.DeviceProperty; import cn.dev33.satoken.annotation.SaCheckPermission; import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.ObjectUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; @@ -64,6 +71,8 @@ import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.List; +import static cc.iotkit.common.web.core.BaseController.fail; + @Api(tags = {"设备"}) @Slf4j @RestController @@ -107,7 +116,12 @@ public class DeviceController { public Paging getDevices(@Validated @RequestBody PageRequest pageRequest) { return deviceServiceImpl.getDevices(pageRequest); } - + @ApiOperation(value = "联动设备列表", notes = "设备列表", httpMethod = "POST") + //@SaCheckPermission("iot:device:query") + @PostMapping("/listNode") + public Paging getDevices1(@Validated @RequestBody PageRequest pageRequest) { + return deviceServiceImpl.getDevices1(pageRequest); + } @ApiOperation(value = "创建设备") @SaCheckPermission("iot:device:add") @PostMapping("/add") @@ -182,13 +196,33 @@ public class DeviceController { @ApiOperation("下载设备模板") @PostMapping("/exportData") public void exportDeviceTemplate(HttpServletResponse response) { + //System.setProperty("org.apache.poi.util.POILogger", "org.apache.poi.util.NullLogger"); + ExcelUtil.exportExcel(new ArrayList<>(), "设备分组", DeviceInfoImportVo.class, response); } + @ApiOperation("导出设备列表") + @Log(title = "设备管理", businessType = BusinessType.EXPORT) + // @SaCheckPermission("system:user:export")@RequestBody Request + @PostMapping("/export") + public void export(DeviceQueryBo deviceQueryBo, + HttpServletResponse response) { + if(ObjectUtil.isEmpty(deviceQueryBo)){ + if(LoginHelper.isSuperAdmin() && TenantHelper.getTenantId() == 0){ + deviceQueryBo.setTenantId(null); + }else{ + deviceQueryBo.setTenantId(TenantHelper.getTenantId()); + } + } + List list = deviceServiceImpl.getDevicess(deviceQueryBo); + List listVo = MapstructUtils.convert(list, DeviceInfoExpordVo.class); + ExcelUtil.exportExcel(listVo, "设备数据", DeviceInfoExpordVo.class, response); + } @ApiOperation("设备物模型日志") @SaCheckPermission("iot:deviceLog:query") @PostMapping("/deviceLogs/list") public Paging logs(@Validated(QueryGroup.class) @RequestBody PageRequest request) { + Paging summary = deviceServiceImpl.logs(request); return deviceServiceImpl.logs(request); } @@ -205,13 +239,18 @@ public class DeviceController { return deviceServiceImpl.getPropertyHistory(deviceId, name, start, end, 10000); } - @ApiOperation("设备解绑") + @ApiOperation("设备解绑(子设备)") @SaCheckPermission("iot:device:edit") @PostMapping("/unbind") public boolean unbindDevice(@Validated @RequestBody Request request) { return deviceServiceImpl.unbindDevice(request.getData()); } - + @ApiOperation(value = "设备解绑(解绑客户)") + @SaCheckPermission("iot:device:unbind") + @PostMapping("/unbindUser") + public boolean unbindDevice1(@Validated @RequestBody Request request) { + return deviceServiceImpl.unbindDeviceXcx(request.getData()); + } @ApiOperation("获取设备物模型") @SaCheckPermission("iot:thingModel:query") @PostMapping("/getThingModel") @@ -377,5 +416,14 @@ public class DeviceController { String deviceId = bo.getData(); return new InvokeResult(deviceCtrlService.sendConfig(deviceId)); } - + @ApiOperation(value = "配置获取", notes = "属性获取", httpMethod = "POST") + //@SaCheckPermission("iot:device:ctrl") + @PostMapping("/service/config/get") + public InvokeResult getConfig1(@RequestBody @Validated Request bo) { + String deviceId = bo.getData(); + if(ObjectUtil.isNull(deviceId)){ + fail("设备id不能为null"); + } + return new InvokeResult(deviceCtrlService.getConfig(deviceId)); + } } diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/DeviceDetectorController.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/DeviceDetectorController.java new file mode 100644 index 0000000..416e9ae --- /dev/null +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/DeviceDetectorController.java @@ -0,0 +1,98 @@ +/* + * + * * | Licensed 未经许可不能去掉「OPENIITA」相关版权 + * * +---------------------------------------------------------------------- + * * | Author: xw2sy@163.com + * * +---------------------------------------------------------------------- + * + * Copyright [2024] [OPENIITA] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * / + */ +package cc.iotkit.manager.controller; + +import cc.iotkit.common.api.PageRequest; +import cc.iotkit.common.api.Paging; +import cc.iotkit.common.api.Request; +import cc.iotkit.common.api.Response; +import cc.iotkit.common.excel.utils.ExcelUtil; +import cc.iotkit.common.thing.ThingModelMessage; +import cc.iotkit.common.validate.QueryGroup; +import cc.iotkit.data.service.DeviceDetectorInfoDataImpl; +import cc.iotkit.manager.dto.bo.device.*; +import cc.iotkit.manager.dto.bo.deviceconfig.DeviceConfigAddBo; +import cc.iotkit.manager.dto.bo.devicegroup.DeviceAddGroupBo; +import cc.iotkit.manager.dto.bo.devicegroup.DeviceGroupBo; +import cc.iotkit.manager.dto.bo.thingmodel.ThingModelMessageBo; +import cc.iotkit.manager.dto.vo.deviceconfig.DeviceConfigVo; +import cc.iotkit.manager.dto.vo.devicegroup.DeviceGroupImportVo; +import cc.iotkit.manager.dto.vo.devicegroup.DeviceGroupVo; +import cc.iotkit.manager.dto.vo.deviceinfo.DeviceInfoImportVo; +import cc.iotkit.manager.dto.vo.deviceinfo.DeviceInfoVo; +import cc.iotkit.manager.dto.vo.deviceinfo.ParentDeviceVo; +import cc.iotkit.manager.dto.vo.thingmodel.ThingModelVo; +import cc.iotkit.manager.service.DeviceCtrlService; +import cc.iotkit.manager.service.IDeviceDetectorInfoService; +import cc.iotkit.manager.service.IDeviceManagerService; +import cc.iotkit.manager.service.IProductService; +import cc.iotkit.model.InvokeResult; +import cc.iotkit.model.device.DeviceConfig; +import cc.iotkit.model.device.DeviceDetectorInfo; +import cc.iotkit.model.device.DeviceGroup; +import cc.iotkit.model.device.DeviceInfo; +import cc.iotkit.model.device.message.DeviceProperty; +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.util.ObjectUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.context.request.async.DeferredResult; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.List; + +import static cc.iotkit.common.web.core.BaseController.fail; + +@Api(tags = {"设备浓度变化"}) +@Slf4j +@RestController +@RequestMapping("/deviceDetector") +public class DeviceDetectorController { + + + + @Autowired + private IDeviceDetectorInfoService deviceServiceImpl; + + + + @ApiOperation(value = "浓度列表", notes = "设备列表", httpMethod = "POST") + //@SaCheckPermission("iot:device:query") + @PostMapping("/page") + public Paging getDevices(@Validated @RequestBody PageRequest pageRequest) { + return deviceServiceImpl.getPage(pageRequest); + } + @ApiOperation(value = "浓度列表", notes = "设备列表", httpMethod = "POST") + //@SaCheckPermission("iot:device:query") + @PostMapping("/list") + public List getDevices1(@Validated @RequestBody PageRequest pageRequest) { + return deviceServiceImpl.getList(pageRequest); + } + +} diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/DeviceInstallInfoController.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/DeviceInstallInfoController.java new file mode 100644 index 0000000..730ab9c --- /dev/null +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/DeviceInstallInfoController.java @@ -0,0 +1,458 @@ +/* + * + * * | Licensed 未经许可不能去掉「OPENIITA」相关版权 + * * +---------------------------------------------------------------------- + * * | Author: xw2sy@163.com + * * +---------------------------------------------------------------------- + * + * Copyright [2024] [OPENIITA] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * / + */ +package cc.iotkit.manager.controller; + +import cc.iotkit.common.api.PageRequest; +import cc.iotkit.common.api.Paging; +import cc.iotkit.common.api.Request; +import cc.iotkit.common.constant.Constants; +import cc.iotkit.common.enums.ErrCode; +import cc.iotkit.common.exception.BizException; +import cc.iotkit.common.satoken.utils.LoginHelper; +import cc.iotkit.common.tenant.helper.TenantHelper; +import cc.iotkit.data.manager.IDeviceInstallInfoData; +import cc.iotkit.manager.config.GasInstallationPDFGenerator; +import cc.iotkit.manager.config.PDFGenerator; +import cc.iotkit.manager.dto.bo.device.DeviceDetectorQueryBo; +import cc.iotkit.manager.dto.bo.device.DeviceInstallInfoQueryBo; +import cc.iotkit.manager.service.IDeviceDetectorInfoService; +import cc.iotkit.manager.service.IDeviceInstallInfoService; +import cc.iotkit.model.UserInfo; +import cc.iotkit.model.device.DeviceDetectorInfo; +import cc.iotkit.model.device.DeviceInfo; +import cc.iotkit.model.device.DeviceInstallInfo; +import cc.iotkit.model.device.InstallationRecord; +import cc.iotkit.model.space.Home; +import cc.iotkit.model.space.Space; +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.io.IoUtil; +import cn.hutool.core.util.ObjectUtil; + +import com.itextpdf.io.font.PdfEncodings; +import com.itextpdf.io.font.constants.StandardFonts; +import com.itextpdf.io.image.ImageDataFactory; +import com.itextpdf.kernel.colors.ColorConstants; +import com.itextpdf.kernel.colors.DeviceRgb; + + +import com.itextpdf.kernel.font.PdfFont; +import com.itextpdf.kernel.font.PdfFontFactory; +import com.itextpdf.kernel.geom.PageSize; +import com.itextpdf.kernel.pdf.PdfDocument; +import com.itextpdf.kernel.pdf.PdfWriter; +import com.itextpdf.layout.Document; +import com.itextpdf.layout.element.*; +import com.itextpdf.io.image.ImageData; +import com.itextpdf.io.image.ImageDataFactory; + +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URISyntaxException; +import java.net.URL; + +import com.itextpdf.layout.properties.AreaBreakType; +import com.itextpdf.layout.properties.HorizontalAlignment; +import com.itextpdf.layout.properties.TextAlignment; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.net.URLEncoder; +import java.security.SecureRandom; +import java.util.Collections; +import java.util.List; + +import static cc.iotkit.data.model.QTbDeviceInstallInfo.tbDeviceInstallInfo; +import static com.itextpdf.kernel.pdf.PdfName.*; + + +@Api(tags = {"设备安装信息"}) +@Slf4j +@RestController +@RequestMapping("/deviceInstallInfo") +public class DeviceInstallInfoController { + + @Autowired + private IDeviceInstallInfoService deviceServiceImpl; + @Autowired + private IDeviceInstallInfoData iDeviceInstallInfoData; + + @ApiOperation(value = "安装列表", notes = "设备列表", httpMethod = "POST") + //@SaCheckPermission("iot:device:query") + @PostMapping("/page") + public Paging getDevices(@Validated @RequestBody PageRequest pageRequest) { + + return deviceServiceImpl.getPage(pageRequest); + } + + @PostMapping("/add") + @SaCheckPermission("device:install:add") + public void addClientUser(@RequestBody Request deviceInstallInfo) throws Exception { + /* user.getData().setType(UserInfo.USER_TYPE_CLIENT); + user.getData().setRoles(Collections.singletonList(Constants.ROLE_CLIENT)); + user.getData().setSecret(null);*/ + TenantHelper.enableIgnore(); + if (ObjectUtil.isNull(deviceInstallInfo.getData()) || ObjectUtil.isNull(deviceInstallInfo.getData().getDeviceName())) { + throw new BizException(ErrCode.PARAMS_EXCEPTION); + } + DeviceInstallInfo deviceRepetition = iDeviceInstallInfoData.findByDeviceNameAndUid(deviceInstallInfo.getData().getDeviceName(), deviceInstallInfo.getData().getUid()); + if (deviceRepetition != null) { + throw new BizException(ErrCode.MODEL_DEVICE_ALREADY); + } + if (LoginHelper.isSuperAdmin() && TenantHelper.getTenantId() != 0) { + deviceInstallInfo.getData().setTenantId(TenantHelper.getTenantId()); + // query.where(tbDeviceInstallInfo.tenantId.eq(TenantHelper.getTenantId())); + } +/* if(!LoginHelper.isSuperAdmin() && ObjectUtil.isNotNull(pageReqVO.getData().getTenantId())){ + query.where(tbDeviceInstallInfo.tenantId.eq(pageReqVO.getData().getTenantId())); + }*/ + iDeviceInstallInfoData.save(deviceInstallInfo.getData()); + + /* if(LoginHelper.isSuperAdmin() && TenantHelper.getTenantId() != 0) { + userInfoData.save(user.getData()); + }else{ + user.getData().setTenantId(null); + userInfoData.save(user.getData()); + }*/ + } + + @PostMapping("/edit") + @SaCheckPermission("device:install:edit") + public void editClientUser(@RequestBody Request deviceInstallInfo) throws Exception { + + TenantHelper.enableIgnore(); + if (ObjectUtil.isNull(deviceInstallInfo.getData()) || ObjectUtil.isNull(deviceInstallInfo.getData().getDeviceName()) || ObjectUtil.isNull(deviceInstallInfo.getData().getId())) { + throw new BizException(ErrCode.PARAMS_EXCEPTION); + } + if (LoginHelper.isSuperAdmin() && TenantHelper.getTenantId() != 0) { + deviceInstallInfo.getData().setTenantId(TenantHelper.getTenantId()); + // query.where(tbDeviceInstallInfo.tenantId.eq(TenantHelper.getTenantId())); + } + iDeviceInstallInfoData.save(deviceInstallInfo.getData()); + + } + + @PostMapping("/device/{id}/delete") + @SaCheckPermission("device:install:delete") + public void deleteClientUser(@PathVariable("id") String id) { + DeviceInstallInfo user = iDeviceInstallInfoData.findById(id); + if (user == null) { + throw new BizException(ErrCode.RECORD_NOT_FOUND); + } + iDeviceInstallInfoData.deleteById(id); + } + + /* @PostMapping("/getDeviceInstallInfo") + public DeviceInstallInfo getUserInfo() { + return iDeviceInstallInfoData.findById(LoginHelper.getUserId()); + }*/ + @PostMapping("/getDetail") + @SaCheckPermission("device:install:query") + public DeviceInstallInfo getDetail(@Validated @RequestBody Request request) { + return iDeviceInstallInfoData.findById(request.getData()); + } + @PostMapping("/getPdf") + @SaCheckPermission("device:install:upload") + public void getPdf(@Validated @RequestBody Request request, HttpServletResponse response) throws Exception { + DeviceInstallInfo data = iDeviceInstallInfoData.findById(request.getData()); + response.setContentType("application/pdf"); + response.setHeader("Content-Disposition", "attachment; filename=\"installation_info.pdf\""); + + // 生成PDF并写入响应流 + PDFGenerator.generateInstallationPDF(data, response.getOutputStream()); + + } + // @PostMapping("/getPdf") + @SaCheckPermission("device:install:upload") + public void getPdf1(@Validated @RequestBody Request request, HttpServletResponse response) throws Exception { + DeviceInstallInfo data = iDeviceInstallInfoData.findById(request.getData()); + // 2. 创建PDF文档 + // 1. 准备数据(实际应从数据库获取) + InstallationRecord record = new InstallationRecord(); + record.setTeamName("徐峰伟班组"); + record.setInstaller("梁立国"); + record.setCommunity("二七路"); + record.setBuildingNo("3"); + record.setUnitNo("1"); + record.setRoomNo("701"); + record.setUserName("陈明珍"); + record.setUserPhone("+86-13378574419"); + record.setStoveType("台式灶"); + record.setInstallDate("2025-07-07"); + record.setBallValve(1); + record.setDrilling(0); + record.setPipeType("包覆管2米"); + record.setNonFixedPipe(0); + record.setNut(0); + record.setQuickConnect(0); + + // 2. 设置响应头 + response.setContentType("application/pdf"); + response.setHeader("Content-Disposition", "attachment; filename=\"installation_record.pdf\""); + + // 3. 生成并输出PDF + try (OutputStream out = response.getOutputStream()) { + byte[] pdfBytes = generateInstallationPdf(record); + out.write(pdfBytes); + out.flush(); + } + /* response.setContentType("application/pdf"); + response.setHeader("Cache-Control", "no-store"); + response.setHeader("Pragma", "no-cache"); + response.setHeader("Content-Disposition", + "attachment;filename=" + URLEncoder.encode("贵阳户内燃气安装信息表.pdf", "UTF-8")); + response.setDateHeader("Expires", 0); + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); + OutputStream out = response.getOutputStream()) { + + PdfDocument pdf = new PdfDocument(new PdfWriter(baos)); + Document document = new Document(pdf, PageSize.A4.rotate()); + + // PdfFont font = PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H"); + PdfFont font = PdfFontFactory.createFont(StandardFonts.HELVETICA_BOLD); + document.setFont(font); + + // 3. 添加标题 + Paragraph title = new Paragraph("贵阳户内燃气安装信息表") + .setFontSize(18) + .setBold(); + // .setTextAlignment(TextAlignment.CENTER); + document.add(title);*/ + + // 4. 创建信息表格 + /* float[] columnWidths = {2, 3, 2, 3}; + Table table = new Table(columnWidths); + // 基本信息行 + table.addCell(createCell("安装班组", true)); + table.addCell(createCell(data.getProposerTeam(), false)); + table.addCell(createCell("安装人", true)); + table.addCell(createCell(data.getProposer(), false)); + // 用户信息行 + table.addCell(createCell("用户姓名", true)); + table.addCell(createCell(data.getUserName(), false)); + table.addCell(createCell("联系电话", true)); + table.addCell(createCell(data.getUserIpone(), false)); + // 地址信息行 + table.addCell(createCell("小区名称", true)); + table.addCell(createCell(data.getCommunityName(), false)); + table.addCell(createCell("详细地址", true)); + table.addCell(createCell(data.getBuildingUnit() + data.getRoomNo(), false)); + document.add(table);*/ + + /* document.close(); + // 4. 输出到响应流 + baos.writeTo(out); + out.flush();*/ + + + // 5. 处理图片字段 + /* addImageSection(document, "安装前图片", data.getBeforeInstallationImage()); + addImageSection(document, "安装完成探测图片", data.getWorkingOfTheDetectorImage()); + addImageSection(document, "测漏图片", data.getSideLeakageImage()); + addImageSection(document, "点火图片", data.getIgnitionPictureImage()); + + IoUtil.write(response.getOutputStream(), false, content);*/ + //document.close(); + /*} catch (Exception e) { + try { + response.reset(); + response.setContentType("application/json"); + response.getWriter().write("{\"status\":500,\"message\":\"生成失败\"}"); + } catch (IOException ioException) { + log.error("错误响应失败", ioException); + } + }*/ + } + public byte[] generateInstallationPdf(InstallationRecord record) throws IOException, URISyntaxException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PdfDocument pdf = new PdfDocument(new PdfWriter(baos)); + Document document = new Document(pdf); + + // 加载字体文件 + //String fontPath = getClass().getClassLoader().getResource("fonts/STSong-Light.ttf").toURI().getPath(); + PdfFont font = PdfFontFactory.createFont( + "D:/SimsunExtG.ttf", + PdfEncodings.IDENTITY_H, + PdfFontFactory.EmbeddingStrategy.FORCE_EMBEDDED + ); + // 设置中文字体 + // PdfFont font = PdfFontFactory.createFont(StandardFonts.HELVETICA); + document.setFont(font); + System.out.println("Font embedded: " + font.isEmbedded()); + + // 添加标题 + document.add(new Paragraph("贵阳户内安装信息录入表") + .setFontSize(18) + .setBold() + .setTextAlignment(TextAlignment.CENTER)); + + // 添加安装班组信息 + document.add(new Paragraph("安装班组").setBold()); + document.add(createInstallationInfoTable(record)); + + // 添加材料使用信息 + document.add(new Paragraph("材料使用").setBold()); + document.add(createMaterialUsageTable(record)); + + // 添加图片占位提示 + for (int i = 1; i <= 4; i++) { + document.add(new Paragraph("第 " + i + " 页").setTextAlignment(TextAlignment.CENTER)); + document.add(new Paragraph("(图片占位区域)").setItalic().setTextAlignment(TextAlignment.CENTER)); + if (i < 4) { + document.add(new AreaBreak(AreaBreakType.NEXT_PAGE)); + } + } + + document.close(); + return baos.toByteArray(); + } + + private Table createInstallationInfoTable(InstallationRecord record) { + float[] columnWidths = {1.5f, 1.5f, 1.5f, 1.5f, 1.5f, 1.5f, 2f, 1.5f}; + Table table = new Table(columnWidths); + + // 表头 + table.addHeaderCell(createCell("安装人", true)); + table.addHeaderCell(createCell("小区名称", true)); + table.addHeaderCell(createCell("楼栋号", true)); + table.addHeaderCell(createCell("单元号", true)); + table.addHeaderCell(createCell("房号", true)); + table.addHeaderCell(createCell("用户姓名", true)); + table.addHeaderCell(createCell("用户电话", true)); + table.addHeaderCell(createCell("灶具类型", true)); + + // 数据行 + table.addCell(createCell(record.getInstaller(), false)); + table.addCell(createCell(record.getCommunity(), false)); + table.addCell(createCell(record.getBuildingNo(), false)); + table.addCell(createCell(record.getUnitNo(), false)); + table.addCell(createCell(record.getRoomNo(), false)); + table.addCell(createCell(record.getUserName(), false)); + table.addCell(createCell(record.getUserPhone(), false)); + table.addCell(createCell(record.getStoveType(), false)); + + return table; + } + + private Table createMaterialUsageTable(InstallationRecord record) { + float[] columnWidths = {1f, 1f, 2f, 1.5f, 1f, 1.5f}; + Table table = new Table(columnWidths); + + // 表头 + table.addHeaderCell(createCell("序号", true)); + table.addHeaderCell(createCell("球阀", true)); + table.addHeaderCell(createCell("打孔", true)); + table.addHeaderCell(createCell("管子使用类型及尺寸", true)); + table.addHeaderCell(createCell("非定尺管", true)); + table.addHeaderCell(createCell("螺母", true)); + + // 数据行 + table.addCell(createCell("1", false)); + table.addCell(createCell(String.valueOf(record.getBallValve()), false)); + table.addCell(createCell(String.valueOf(record.getDrilling()), false)); + table.addCell(createCell(record.getPipeType(), false)); + table.addCell(createCell(String.valueOf(record.getNonFixedPipe()), false)); + table.addCell(createCell(String.valueOf(record.getNut()), false)); + + return table; + } + + private Cell createCell(String text, boolean isHeader) { + Paragraph p = new Paragraph(text); + Cell cell = new Cell().add(p); + if (isHeader) { + p.setBold(); + cell.setBackgroundColor(new DeviceRgb(240, 240, 240)); + } + cell.setPadding(5); + return cell; + } + + + + /*private Cell createCell(String text, boolean isHeader) { + Paragraph p = new Paragraph(text); + Cell cell = new Cell().add(p); + if (isHeader) { + p.setBold(); + cell.setBackgroundColor(new DeviceGray(0.9f)); + } + cell.setPadding(5); + return cell; + } + + + + private Cell createCell(String text, boolean isHeader) { + Cell cell = new Cell().add(new Paragraph(text)); + if (isHeader) { + cell.setBackgroundColor(new DeviceRgb(240, 240, 240)); + cell.setBold(); + } + return cell; + } + + private void addImageSection(Document doc, String title, String imageUrl) throws IOException { + if (imageUrl != null) { + try { + String im = imageUrl.replaceFirst("^https://", "http://"); + URL url = new URL(im); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setConnectTimeout(5000); + conn.setReadTimeout(5000); + if (conn.getResponseCode() != 200) { + throw new IOException("HTTP " + conn.getResponseCode()); + } + ImageData imageData = ImageDataFactory.create(url.toString()); + Image image = new Image(imageData).setAutoScale(true).setHorizontalAlignment(HorizontalAlignment.CENTER); + doc.add(new Paragraph(title).setBold().setMarginTop(10)); + doc.add(image); + *//* ImageData imageData = ImageDataFactory.create(new URL(imageUrl)); + Image image = new Image(imageData); + image.setAutoScale(true); + image.setHorizontalAlignment(HorizontalAlignment.CENTER); + doc.add(new Paragraph(title).setBold().setMarginTop(10)); + doc.add(image);*//* + } catch (Exception e) { + doc.add(new Paragraph(title + "【图片加载失败】").setFontColor(ColorConstants.RED)); + } + } + }*/ + /* @ApiOperation(value = "浓度列表", notes = "设备列表", httpMethod = "POST") + //@SaCheckPermission("iot:device:query") + @PostMapping("/list") + public List getDevices1(@Validated @RequestBody PageRequest pageRequest) { + return deviceServiceImpl.getList(pageRequest); + }*/ + +} diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/IccidRecordController.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/IccidRecordController.java index 913649a..d14551a 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/IccidRecordController.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/IccidRecordController.java @@ -34,7 +34,7 @@ import static cc.iotkit.common.api.Response.success; public class IccidRecordController { - @Resource + @Resource private DIccidRecordService dIccidRecordService; @PostMapping("/add") @@ -80,8 +80,8 @@ public class IccidRecordController { @PostMapping("/list") // @Operation(summary = "获得物联网卡分页") - public Paging getDIccidRecordPage( @Validated @RequestBody PageRequest pageReqVO) { - Paging pageResult = dIccidRecordService.getDIccidRecordPage(pageReqVO); + public Paging getDIccidRecordPage( @Validated @RequestBody PageRequest pageReqVO) { + Paging pageResult = dIccidRecordService.getDIccidRecordPage(pageReqVO); return pageResult; } diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/NotifyController.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/NotifyController.java index d68ae5b..6f8f010 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/NotifyController.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/NotifyController.java @@ -149,7 +149,7 @@ public class NotifyController { } @ApiOperation("消息列表") - @SaCheckPermission("iot:channelMsg:query") + //@SaCheckPermission("iot:channelMsg:query") @PostMapping("/message/getList") public Paging messageList(@RequestBody @Validated(QueryGroup.class) PageRequest request) { return notifyService.getNotifyMessageList(request); diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/ProductController.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/ProductController.java index 47acf22..45af421 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/ProductController.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/ProductController.java @@ -25,18 +25,26 @@ package cc.iotkit.manager.controller; import cc.iotkit.common.api.PageRequest; import cc.iotkit.common.api.Paging; import cc.iotkit.common.api.Request; +import cc.iotkit.common.excel.utils.ExcelUtil; import cc.iotkit.common.log.annotation.Log; import cc.iotkit.common.log.enums.BusinessType; +import cc.iotkit.common.satoken.utils.LoginHelper; +import cc.iotkit.common.tenant.helper.TenantHelper; +import cc.iotkit.common.utils.MapstructUtils; import cc.iotkit.common.validate.AddGroup; import cc.iotkit.common.validate.EditGroup; import cc.iotkit.common.validate.QueryGroup; +import cc.iotkit.data.config.TenantContext; import cc.iotkit.manager.dto.bo.category.CategoryBo; +import cc.iotkit.manager.dto.bo.device.DeviceQueryBo; import cc.iotkit.manager.dto.bo.product.IconBo; import cc.iotkit.manager.dto.bo.product.IconTypeBo; import cc.iotkit.manager.dto.bo.product.ProductBo; import cc.iotkit.manager.dto.bo.productmodel.ProductModelBo; import cc.iotkit.manager.dto.bo.thingmodel.ThingModelBo; import cc.iotkit.manager.dto.vo.category.CategoryVo; +import cc.iotkit.manager.dto.vo.deviceinfo.DeviceInfoImportVo; +import cc.iotkit.manager.dto.vo.deviceinfo.DeviceInfoVo; import cc.iotkit.manager.dto.vo.product.IconTypeVo; import cc.iotkit.manager.dto.vo.product.IconVo; import cc.iotkit.manager.dto.vo.product.ProductVo; @@ -44,6 +52,7 @@ import cc.iotkit.manager.dto.vo.productmodel.ProductModelVo; import cc.iotkit.manager.dto.vo.thingmodel.ThingModelVo; import cc.iotkit.manager.service.IProductService; import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.util.ObjectUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiOperation; @@ -53,6 +62,7 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletResponse; import java.util.List; @Api(tags = {"产品"}) @@ -70,9 +80,29 @@ public class ProductController { @PostMapping("/list") public Paging getProducts(@Validated(QueryGroup.class) @RequestBody PageRequest request) { + TenantContext.disableTenantFilter(); + request.getData().setTenantId(null); return productService.selectPageList(request); } + @ApiOperation("导出产品列表") + @Log(title = "产品管理", businessType = BusinessType.EXPORT) + // @SaCheckPermission("system:user:export") + @PostMapping("/export") + public void export(ProductBo productBo, + HttpServletResponse response) { + if(ObjectUtil.isEmpty(productBo)){ + if(LoginHelper.isSuperAdmin() && TenantHelper.getTenantId() == 0){ + productBo.setTenantId(null); + }else{ + productBo.setTenantId(TenantHelper.getTenantId()); + } + } + List list = productService.selectPageList(productBo); + // List listVo = MapstructUtils.convert(list, ProductVo.class); + ExcelUtil.exportExcel(list, "产品数据", ProductVo.class, response); + } + @ApiOperation("新建") @SaCheckPermission("iot:product:add") @PostMapping(value = "/add") @@ -107,6 +137,7 @@ public class ProductController { @SaCheckPermission("iot:iconType:query") @PostMapping("/icon/getAllIconType") public List getAllIconType() { + TenantContext.disableTenantFilter(); return productService.selectIconTypeList(); } @@ -128,6 +159,7 @@ public class ProductController { @SaCheckPermission("iot:icon:query") @PostMapping("/icon/getAllIcon") public Paging getAllIcon(@Validated @RequestBody PageRequest request) { + TenantContext.disableTenantFilter(); return productService.selectIconPageList(request); } @@ -171,6 +203,7 @@ public class ProductController { @SaCheckPermission("iot:category:query") @PostMapping("/category/list") public Paging getCategories(@Validated @RequestBody PageRequest request) { + TenantContext.disableTenantFilter(); return productService.selectCategoryPageList(request); } @@ -178,16 +211,22 @@ public class ProductController { @SaCheckPermission("iot:category:query") @PostMapping("/category/getAll") public List getCategorieList() { + TenantContext.disableTenantFilter(); return productService.selectCategoryList(); } @ApiOperation("品类编辑") @SaCheckPermission("iot:category:edit") @PostMapping("/category/edit") - public boolean saveCategory(@Validated @RequestBody Request req) { + public boolean editCategory(@Validated @RequestBody Request req) { return productService.editCategory(req.getData()); } - + @ApiOperation("品类添加") + @SaCheckPermission("iot:category:save") + @PostMapping("/category/save") + public boolean saveCategory(@Validated @RequestBody Request req) { + return productService.saveCategory(req.getData()); + } @ApiOperation("删除品类") @SaCheckPermission("iot:category:remove") @PostMapping("/category/delete") diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/RuleEngineController.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/RuleEngineController.java index b50402f..f602dae 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/RuleEngineController.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/RuleEngineController.java @@ -25,6 +25,8 @@ package cc.iotkit.manager.controller; import cc.iotkit.common.api.PageRequest; import cc.iotkit.common.api.Paging; import cc.iotkit.common.api.Request; +import cc.iotkit.common.satoken.utils.LoginHelper; +import cc.iotkit.common.tenant.helper.TenantHelper; import cc.iotkit.manager.dto.bo.ruleinfo.RuleInfoBo; import cc.iotkit.manager.dto.bo.ruleinfo.RuleLogBo; import cc.iotkit.manager.dto.bo.taskinfo.TaskInfoBo; @@ -35,6 +37,7 @@ import cc.iotkit.manager.dto.vo.taskinfo.TaskInfoVo; import cc.iotkit.manager.dto.vo.taskinfo.TaskLogVo; import cc.iotkit.manager.service.IRuleEngineService; import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.util.ObjectUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; @@ -68,21 +71,27 @@ public class RuleEngineController { @SaCheckPermission("iot:rule:eidt") @PostMapping("/edit") public boolean saveRule(@RequestBody @Validated Request ruleInfoBo) { + TenantHelper.enableIgnore(); + if (LoginHelper.isSuperAdmin() && ObjectUtil.isNotNull(TenantHelper.getTenantId()) && TenantHelper.getTenantId()!=0) { + ruleInfoBo.getData().setTenantId(TenantHelper.getTenantId()); + } return ruleEngineService.saveRule(ruleInfoBo.getData()); } @ApiOperation("暂停规则") - @SaCheckPermission("iot:rule:edit") + @SaCheckPermission("iot:rule:stop") @PostMapping("/pause") public boolean pauseRule(@Validated @RequestBody Request request) { String ruleId = request.getData(); + TenantHelper.enableIgnore(); return ruleEngineService.pauseRule(ruleId); } @ApiOperation("恢复规则") - @SaCheckPermission("iot:rule:edit") + @SaCheckPermission("iot:rule:start") @PostMapping("/resume") public boolean resumeRule(@Validated @RequestBody Request request) { String ruleId = request.getData(); + TenantHelper.enableIgnore(); return ruleEngineService.resumeRule(ruleId); } diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/StatsController.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/StatsController.java index 6dfa2b7..0d312f8 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/StatsController.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/StatsController.java @@ -24,12 +24,18 @@ package cc.iotkit.manager.controller; import cc.iotkit.common.api.PageRequest; import cc.iotkit.common.api.Paging; +import cc.iotkit.common.api.Request; import cc.iotkit.common.satoken.utils.AuthUtil; +import cc.iotkit.common.satoken.utils.LoginHelper; +import cc.iotkit.common.utils.StreamUtils; import cc.iotkit.data.config.TenantContext; import cc.iotkit.data.manager.IAlertRecordData; import cc.iotkit.data.manager.ICategoryData; import cc.iotkit.data.manager.IDeviceInfoData; import cc.iotkit.data.manager.IProductData; +import cc.iotkit.data.system.ISysDeptData; +import cc.iotkit.data.system.ISysUserData; + import cc.iotkit.manager.dto.bo.device.DeviceQueryBo; import cc.iotkit.manager.dto.vo.deviceinfo.DeviceInfoVo; import cc.iotkit.manager.model.stats.MainStats; @@ -38,11 +44,16 @@ import cc.iotkit.manager.service.IDeviceManagerService; import cc.iotkit.model.alert.AlertRecord; import cc.iotkit.model.device.DeviceInfo; import cc.iotkit.model.stats.AlertStatDTO; +import cc.iotkit.model.stats.SysDeptDto; +import cc.iotkit.model.system.SysDept; +import cc.iotkit.model.system.SysUser; +import cc.iotkit.plugin.core.thing.actions.DeviceState; import cc.iotkit.temporal.IThingModelMessageData; import cn.dev33.satoken.annotation.SaCheckPermission; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import io.swagger.annotations.Api; @@ -84,6 +95,13 @@ public class StatsController { private AlertService alertService; @Autowired private IDeviceManagerService deviceServiceImpl; + + @Autowired + private ISysDeptData isysDeptData; + + @Autowired + private ISysUserData isSysUserData; + @PostMapping("/main") public MainStats getMainStats() { MainStats mainStats = new MainStats(); @@ -93,8 +111,10 @@ public class StatsController { TenantContext.isFilterDisabled()); long now = System.currentTimeMillis(); if (AuthUtil.isAdmin()) { + TenantContext.disableTenantFilter(); mainStats.setCategoryTotal(ICategoryData.count()); mainStats.setProductTotal(productData.count()); + TenantContext.enableTenantFilter(); mainStats.setDeviceTotal(deviceInfoData.count()); DeviceInfo condition = new DeviceInfo(); @@ -118,9 +138,26 @@ public class StatsController { //产品数量统计 mainStats.setDeviceStatsOfCategory(deviceInfoData.getDeviceStatsByCategory("")); } else { + TenantContext.disableTenantFilter(); + //TenantContext.enableTenantFilter(); mainStats.setCategoryTotal(ICategoryData.count()); -// mainStats.setProductTotal(productData.countByUid(uid)); - mainStats.setDeviceTotal(deviceInfoData.countByUid(uid)); + mainStats.setProductTotal(productData.count()); + TenantContext.enableTenantFilter(); + mainStats.setDeviceTotal(deviceInfoData.count()); + + DeviceInfo condition = new DeviceInfo(); + DeviceInfo.State state = new DeviceInfo.State(); + state.setOnline(true); + condition.setState(state); + mainStats.setOnlineTotal(deviceInfoData.findAllByCondition(condition).size()); + + state.setOnline(false); + condition.setState(state); + mainStats.setOfflineTotal(deviceInfoData.findAllByCondition(condition).size()); + + // 待激活设备 + mainStats.setNeverOnlineTotal(deviceInfoData.findNeverUsedDevices().size()); + // mainStats.setReportTotal(deviceReportRepository.countByUid(uid)); //上报数据统计 mainStats.setReportDataStats(thingModelMessageData.getDeviceMessageStatsWithUid(uid, now - 48 * 3600 * 1000, now)); @@ -134,20 +171,22 @@ public class StatsController { @PostMapping("/mainAlertRecord") public String getAlertRecord() { - List list = iAlertRecordData.getAlertRecord(); - // jpaQueryFactory - // iAlertRecordData.findAll(); - return JSONUtil.toJsonPrettyStr(list); - // return list; + List list = iAlertRecordData.getAlertRecord(); + // jpaQueryFactory + // iAlertRecordData.findAll(); + return JSONUtil.toJsonPrettyStr(list); + // return list; } + @PostMapping("/deviceRecord") public String getDeviceRecord() { - List list = deviceInfoData.getDeviceRecord(); + List list = deviceInfoData.getDeviceRecord(); // jpaQueryFactory // iAlertRecordData.findAll(); - return JSONUtil.toJsonPrettyStr(list); + return JSONUtil.toJsonPrettyStr(list); // return list; } + @PostMapping("/mainTop") public String getMainTop() { //过滤租户开启 @@ -186,15 +225,16 @@ public class StatsController { //告警总数 mainStats.setAlertCount(iAlertRecordData.count()); - mainStats.setProductKeyCount(deviceInfoData.getProductDevice(null,null,null)); + mainStats.setProductKeyCount(deviceInfoData.getProductDevice(null, null, null)); // jpaQueryFactory // iAlertRecordData.findAll(); //过滤租户关 //TenantContext.enableTenantFilter(); - return JSONUtil.toJsonPrettyStr(mainStats); + return JSONUtil.toJsonPrettyStr(mainStats); } + @PostMapping("/mainListProduct") - public String mainListProduct(Long deptAreaId,String startDate, String endDate) { + public String mainListProduct(Long deptAreaId, String startDate, String endDate) { //过滤租户开启 TenantContext.disableTenantFilter(); @@ -204,41 +244,45 @@ public class StatsController { MainStats mainStats = new MainStats(); - mainStats.setProductKeyCount(deviceInfoData.getProductDevice(deptAreaId,startDate,endDate)); + mainStats.setProductKeyCount(deviceInfoData.getProductDevice(deptAreaId, startDate, endDate)); // jpaQueryFactory // iAlertRecordData.findAll(); //过滤租户关 //TenantContext.enableTenantFilter(); - return JSONUtil.toJsonPrettyStr(mainStats.getProductKeyCount()); + return JSONUtil.toJsonPrettyStr(mainStats.getProductKeyCount()); } @ApiOperation(value = "设备列表", notes = "设备列表", httpMethod = "POST") //@SaCheckPermission("iot:device:query") @PostMapping("/list") - public String getDevices(String productKey,Integer type) { + public String getDevices(String productKey, Integer type) { List list = new ArrayList<>(); List list1 = new ArrayList<>(); - if(ObjectUtils.isNotEmpty(type) && type==0) { - PageRequest pageRequest = new PageRequest<>(20, 1, null); - pageRequest.setData(new DeviceQueryBo()); + if (ObjectUtils.isNotEmpty(type) && type == 0) { + /* PageRequest pageRequest = new PageRequest<>(-1, 1, null); + // DeviceQueryBo pageRequest = new DeviceQueryBo(); pageRequest.getData().setProductKey(productKey); - list1 = deviceServiceImpl.getDevices(pageRequest).getRows(); + pageRequest.getData().setFlag(true);*/ + //pageRequest.getData().setProductKey(productKey); + list1 = deviceServiceImpl.findByConditionsList(productKey, true); for (DeviceInfoVo deviceInfoVo : list1) { - deviceInfoVo.setOnlineStatus(deviceInfoVo.getOnline()?"在线":"离线"); - deviceInfoVo.setProductName(ObjectUtils.isNotEmpty(deviceInfoVo.getProduct().getName()) ? deviceInfoVo.getProduct().getName():""); + deviceInfoVo.setOnlineStatus(deviceInfoVo.getOnline() ? "在线" : "离线"); + deviceInfoVo.setProduct(productData.findByProductKey(deviceInfoVo.getProductKey())); + deviceInfoVo.setProductName(ObjectUtils.isNotEmpty(deviceInfoVo.getProduct().getName()) ? deviceInfoVo.getProduct().getName() : ""); } - return JSONUtil.toJsonPrettyStr(list1); + return JSONUtil.toJsonPrettyStr(list1); } /* for (DeviceInfo deviceInfo : list) { deviceInfo.setOnlineStatus(deviceInfo.getOnline()?"在线":"离线"); }*/ - return JSONUtil.toJsonPrettyStr(deviceInfoData.findByConditionsList(productKey)); + return JSONUtil.toJsonPrettyStr(deviceInfoData.findByConditionsList(productKey)); } + @ApiOperation("查询告警消息分页") - // @SaCheckPermission("iot:alert:query") + // @SaCheckPermission("iot:alert:query") @PostMapping("/mainListAlert") public String selectAlertRecordList() { - PageRequest request = new PageRequest<>(20, 1, null); + PageRequest request = new PageRequest<>(20, 1, null); request.setData(new AlertRecord()); /* DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of("Asia/Shanghai")); @@ -248,9 +292,77 @@ public class StatsController { String formattedTime = Instant.ofEpochMilli(record.getAlertTime()).atZone(ZoneId.of("Asia/Shanghai")) .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); //String formattedTime = zonedDateTime.format(formatter); - record.setAlertTimeStats(formattedTime - ); + record.setAlertTimeStats(formattedTime); + record.setLevel(getSeverityLight(record.getLevel())); + // getSeverityLight } return JSONUtil.toJsonPrettyStr(list); } + + public String getSeverityLight(String level) { + switch (level) { + case "1": + return "严重"; // 严重 + case "2": + return "紧急"; // 紧急 + case "3": + return "较重"; // 较重 + case "4": + return "一般"; // 一般 + case "5": + return "提示"; // 提示 + default: + return "未知"; + } + //return null; + } + + @PostMapping("/webhook") + public void handleEvent(@RequestBody String payload) { + JSONObject data = new JSONObject(payload); + String event = data.get("event").toString(); // "client_connected"或"client_disconnected" + String clientId = data.get("clientid").toString(); + boolean flag = false; + if ("client.connected".equals(event)) { + //链接 + flag = true; + }/*else if("client_disconnected".equals(event)){ + //断开 + }*/ + DeviceInfo deviceInfo = deviceInfoData.findByDeviceName(clientId); + if (ObjectUtils.isNotEmpty(deviceInfo)) { + Long onlineTime = System.currentTimeMillis(); + Long offlineTime = System.currentTimeMillis(); + deviceInfo.getState().setOnline(flag); + if (flag) { + deviceInfo.getState().setOnlineTime(onlineTime); + if (ObjectUtil.isNull(deviceInfo.getDeviceStatus())) { + deviceInfo.setDeviceStatus(0); + } else if (!deviceInfo.getDeviceStatus().equals(1) && !deviceInfo.getDeviceStatus().equals(2)) { + deviceInfo.setDeviceStatus(0); + } + } else { + //离线 + deviceInfo.getState().setOfflineTime(offlineTime); + if (ObjectUtil.isNull(deviceInfo.getDeviceStatus())) { + deviceInfo.setDeviceStatus(0); + } else if (!deviceInfo.getDeviceStatus().equals(1) && !deviceInfo.getDeviceStatus().equals(2)) { + deviceInfo.setDeviceStatus(3); + } + } + deviceInfoData.save(deviceInfo); + } + System.out.println("设备状态变更: " + clientId + " -> " + event); + } + + /** + * 设备地图页 + */ + @PostMapping("/getAreaDept") + public SysDeptDto getAreaDept(@Validated @RequestBody PageRequest pageRequest) { + + return deviceInfoData.getStatsCount(pageRequest.getData()); + //long countByUid(String uid); + } + } diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/UserInfoController.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/UserInfoController.java index 4598d59..ea81f39 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/UserInfoController.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/UserInfoController.java @@ -30,11 +30,16 @@ import cc.iotkit.common.enums.ErrCode; import cc.iotkit.common.exception.BizException; import cc.iotkit.common.satoken.utils.AuthUtil; import cc.iotkit.common.satoken.utils.LoginHelper; +import cc.iotkit.common.tenant.helper.TenantHelper; import cc.iotkit.common.utils.ReflectUtil; +import cc.iotkit.common.utils.StreamUtils; +import cc.iotkit.data.config.TenantContext; import cc.iotkit.data.manager.IDeviceInfoData; import cc.iotkit.data.manager.IHomeData; import cc.iotkit.data.manager.ISpaceData; import cc.iotkit.data.manager.IUserInfoData; +import cc.iotkit.data.system.ISysDeptData; +import cc.iotkit.data.system.ISysUserData; import cc.iotkit.manager.dto.vo.category.vo.DIccidRecordPageReqVO; import cc.iotkit.manager.dto.vo.product.ProductVo; import cc.iotkit.manager.dto.vo.userInfo.UserInfoPageReqVO; @@ -43,14 +48,18 @@ import cc.iotkit.model.UserInfo; import cc.iotkit.model.device.DeviceInfo; import cc.iotkit.model.space.Home; import cc.iotkit.model.space.Space; +import cc.iotkit.model.system.SysDept; +import cc.iotkit.model.system.SysUser; import cn.hutool.core.util.ObjectUtil; import io.swagger.annotations.Api; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.util.Collections; import java.util.List; +import java.util.Objects; @Api(tags = {"用户"}) @RestController @@ -67,6 +76,10 @@ public class UserInfoController { private IHomeData homeData; @Autowired private ISpaceData spaceData; + @Autowired + private ISysDeptData sysDeptData; + @Autowired + private ISysUserData sysUserData; /** * 平台用户列表 @@ -124,6 +137,18 @@ public class UserInfoController { public Paging clientUsersList( @Validated @RequestBody PageRequest pageReqVO) { pageReqVO.getData().setType(UserInfo.USER_TYPE_CLIENT); + if (!LoginHelper.isSuperAdmin() && Objects.nonNull(LoginHelper.getUserId())) { + List areaIds = null; + SysUser user = sysUserData.findById(LoginHelper.getUserId()); + Long deptId = user.getDeptAreaId(); + // sysDeptData.findByTenantId() + List depts = sysDeptData.findByDeptId(deptId); + areaIds = StreamUtils.toList(depts, SysDept::getId); + areaIds.add(deptId); + if(ObjectUtil.isNotNull(areaIds)) { + pageReqVO.getData().setDeptAreaIds(areaIds); + } + } Paging Paging = userInfoData.findAll(pageReqVO.to(UserInfo.class)); @@ -141,8 +166,15 @@ public class UserInfoController { public void addClientUser(@RequestBody Request user) throws Exception { user.getData().setType(UserInfo.USER_TYPE_CLIENT); user.getData().setRoles(Collections.singletonList(Constants.ROLE_CLIENT)); - user.getData().setSecret(AuthUtil.enCryptPwd(Constants.PWD_CLIENT_USER)); - userInfoData.save(user.getData()); + user.getData().setSecret(null); + TenantHelper.enableIgnore(); + userInfoData.save(user.getData()); + /* if(LoginHelper.isSuperAdmin() && TenantHelper.getTenantId() != 0) { + userInfoData.save(user.getData()); + }else{ + user.getData().setTenantId(null); + userInfoData.save(user.getData()); + }*/ //添加默认家庭 Home home = homeData.save(Home.builder() @@ -166,7 +198,16 @@ public class UserInfoController { /* user.getData().setType(UserInfo.USER_TYPE_CLIENT); user.getData().setRoles(Collections.singletonList(Constants.ROLE_CLIENT)); user.getData().setSecret(AuthUtil.enCryptPwd(Constants.PWD_CLIENT_USER));*/ - userInfoData.save(user.getData()); + user.getData().setSecret(null); + TenantHelper.enableIgnore(); + userInfoData.save(user.getData()); + /* if(LoginHelper.isSuperAdmin() && TenantHelper.getTenantId() != 0) { + userInfoData.save(user.getData()); + }else{ + user.getData().setTenantId(null); + userInfoData.save(user.getData()); + }*/ + /* //添加默认家庭 Home home = homeData.save(Home.builder() .name("我的家庭") @@ -220,7 +261,9 @@ public class UserInfoController { if (user == null) { throw new BizException(ErrCode.USER_NOT_FOUND); } - if (!AuthUtil.getUserId().equals(user.getId())) { + System.out.println(AuthUtil.getUserId()); + + if (!AuthUtil.getUserId().equals(user.getId().toString())) { throw new BizException(ErrCode.UNAUTHORIZED_EXCEPTION); } @@ -237,5 +280,32 @@ public class UserInfoController { throw new BizException(ErrCode.UPDATE_PWD_ERROR, e); } } + /** + * 修改密码 + */ + @PostMapping("/{uid}/modifyPwdId") + public void modifyPwd(@PathVariable("uid") Long uid, String oldPwd, String newPwd) { + UserInfo user = userInfoData.findById(uid); + if (user == null) { + throw new BizException(ErrCode.USER_NOT_FOUND); + } + System.out.println(AuthUtil.getUserId()); + + if (!AuthUtil.getUserId().equals(user.getId().toString())) { + throw new BizException(ErrCode.UNAUTHORIZED_EXCEPTION); + } + + try { + if (!AuthUtil.checkPwd(oldPwd, user.getSecret())) { + throw new BizException(ErrCode.PWD_ERROR); + } + user.setSecret(AuthUtil.enCryptPwd(newPwd)); + userInfoData.save(user); + } catch (BizException e) { + throw e; + } catch (Throwable e) { + throw new BizException(ErrCode.UPDATE_PWD_ERROR, e); + } + } } diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/XcxDeviceController.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/XcxDeviceController.java index 147fdee..88541b4 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/XcxDeviceController.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/XcxDeviceController.java @@ -28,11 +28,13 @@ import cc.iotkit.common.api.Request; import cc.iotkit.common.exception.BizException; import cc.iotkit.common.satoken.utils.AuthUtil; import cc.iotkit.common.satoken.utils.LoginHelper; +import cc.iotkit.common.tenant.helper.TenantHelper; import cc.iotkit.common.thing.ThingModelMessage; import cc.iotkit.common.validate.QueryGroup; import cc.iotkit.data.config.TenantContext; import cc.iotkit.data.manager.IAlertRecordData; import cc.iotkit.data.manager.IDeviceInfoData; +import cc.iotkit.data.manager.IDeviceInstallInfoData; import cc.iotkit.data.manager.IProductData; import cc.iotkit.manager.dto.bo.channel.ChannelTemplateBo; import cc.iotkit.manager.dto.bo.device.*; @@ -52,11 +54,14 @@ import cc.iotkit.model.InvokeResult; import cc.iotkit.model.alert.AlertConfig; import cc.iotkit.model.device.DeviceConfig; import cc.iotkit.model.device.DeviceInfo; +import cc.iotkit.model.device.DeviceInstallInfo; import cc.iotkit.model.device.message.DeviceProperty; import cc.iotkit.model.product.Product; +import cc.iotkit.model.rule.RuleInfo; import cc.iotkit.temporal.IThingModelMessageData; import cn.dev33.satoken.annotation.SaCheckPermission; import cn.hutool.core.lang.tree.Tree; +import cn.hutool.core.util.ObjectUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; @@ -70,14 +75,20 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.List; +import static cc.iotkit.common.web.core.BaseController.fail; + @Api(tags = {"小程序-我的设备"}) @Slf4j @RestController @RequestMapping("/xcxDevice") public class XcxDeviceController { + // @Autowired + // private IDeviceInstallInfoService deviceServiceImpl; @Autowired IProductService productService; @@ -90,7 +101,8 @@ public class XcxDeviceController { @Autowired private IProductData productData; - + @Autowired + private IDeviceInstallInfoData iDeviceInstallInfoData; @Resource private NotifyService notifyService; @Autowired @@ -114,20 +126,20 @@ public class XcxDeviceController { String uid = AuthUtil.getUserId(); pageRequest.getData().setUid(uid); } - Paging d= deviceServiceImpl.getDevices(pageRequest); + // Paging d= deviceServiceImpl.getDevices(pageRequest); return deviceServiceImpl.getDevices(pageRequest); } - /* @ApiOperation(value = "创建设备") - @SaCheckPermission("iot:device:add") - @PostMapping("/add") + @ApiOperation(value = "创建设备") + // @SaCheckPermission("iot:device:add") + @PostMapping("/edit") public boolean createDevice(@RequestBody @Validated Request bo) { - return deviceServiceImpl.addDevice(bo.getData()); - }*/ + return deviceServiceImpl.saveDevice1(bo.getData()); + } @ApiOperation(value = "保存与绑定设备") @PostMapping("/save") - public boolean saveDevice(@RequestBody @Validated Request bo) { + public Long saveDevice(@RequestBody @Validated Request bo) { return deviceServiceImpl.editBandDeviceInfo(bo.getData()); } @@ -135,7 +147,8 @@ public class XcxDeviceController { // @SaCheckPermission("iot:device:edit") @PostMapping("/unbind") public boolean unbindDevice(@Validated @RequestBody Request request) { - return deviceServiceImpl.unbindDevice(request.getData()); + + return deviceServiceImpl.unbindDeviceXcx(request.getData()); } @ApiOperation(value = "获取子设备", notes = "获取子设备") // @SaCheckPermission("iot:device:query") @@ -156,9 +169,18 @@ public class XcxDeviceController { // @SaCheckPermission("iot:device:query") @PostMapping("/detail") public DeviceInfo getDetail(@RequestBody @Validated Request request) { + if(ObjectUtil.isNull(request.getData())){ + return null; + } DeviceInfo deviceInfo = deviceServiceImpl.getDetail(request.getData()); - Product product= productData.findByProductKey(deviceInfo.getProductKey()); - deviceInfo.setProductName(product.getName()); + if(ObjectUtil.isNotEmpty(deviceInfo)) { + Product product = productData.findByProductKey(deviceInfo.getProductKey()); + if(product!=null && ObjectUtil.isNotNull(product.getName())) { + deviceInfo.setProductName(product.getName()); + } + } + DeviceInstallInfo deviceRepetition1 = iDeviceInstallInfoData.findByDeviceNameAndUidAndState(deviceInfo.getDeviceName(),deviceInfo.getUid(),0); + deviceInfo.setDeviceInstallInfo(deviceRepetition1); return deviceInfo; } @@ -238,11 +260,11 @@ public class XcxDeviceController { * **********************************************************************/ @ApiOperation("规则列表") @PostMapping("/rulelist") - public Paging rules( + public List rules( @Validated @RequestBody PageRequest request ) { - return ruleEngineService.selectPageList(request); + return ruleEngineService.selectPageList1(request); } @ApiOperation("产品列表") //@SaCheckPermission("iot:product:query") @@ -261,17 +283,20 @@ public class XcxDeviceController { @PostMapping("/pause") public boolean pauseRule(@Validated @RequestBody Request request) { String ruleId = request.getData(); + TenantHelper.enableIgnore(); return ruleEngineService.pauseRule(ruleId); } @ApiOperation("恢复规则") @PostMapping("/resume") public boolean resumeRule(@Validated @RequestBody Request request) { String ruleId = request.getData(); + TenantHelper.enableIgnore(); return ruleEngineService.resumeRule(ruleId); } @ApiOperation("保存规则") @PostMapping("/ruleEdit") public boolean saveRule(@RequestBody @Validated Request ruleInfoBo) { + TenantHelper.enableIgnore(); return ruleEngineService.saveRule(ruleInfoBo.getData()); } @ApiOperation("删除规则") @@ -286,6 +311,7 @@ public class XcxDeviceController { @PostMapping("/channel/template/getList") public Paging getChannelTemplateList(@RequestBody @Validated(QueryGroup.class) PageRequest request) { //方案1 admin设置好之后,过滤租户id,所有租户都可以用该模版. + TenantContext.disableTenantFilter(); return notifyService.getChannelTemplateList(request); } @@ -297,15 +323,32 @@ public class XcxDeviceController { String uid = AuthUtil.getUserId(); request.getData().setUid(uid); } - List list= alertService.getAlertConfig(request.getData()); + if(ObjectUtil.isNotNull(request.getData().getDeviceName())) { + String date= LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + request.getData().setName(request.getData().getDeviceName() + "_" + date); + }else{ + request.getData().setName("imei_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + } + /* List list= alertService.getAlertConfig(request.getData()); if(ObjectUtils.isNotEmpty(list)){ for (int i = 0; i < list.size(); i++) { if(!list.get(i).getRuleInfoId().equals(request.getData().getRuleInfoId())){ - throw new BizException("该规则模版已存在"); + // throw new BizException("该规则模版已存在"); + fail("该规则模版已存在"); } } + }*/ + AlertConfig alertConfig = alertService.createAlertConfig(request.getData()); + try { + if(ObjectUtils.isNotEmpty(request.getData().getRuleInfoId()) && !"".equals(request.getData().getRuleInfoId())) { + String ruleId = request.getData().getRuleInfoId(); + TenantHelper.enableIgnore(); + ruleEngineService.pauseRule(ruleId); + ruleEngineService.resumeRule(ruleId); + } + }catch (Exception e){ } - return alertService.createAlertConfig(request.getData()); + return alertConfig; } @ApiOperation("查询告警中心配置分页") @@ -329,4 +372,6 @@ public class XcxDeviceController { public AlertConfig updateAlertConfig(@RequestBody @Validated Request request) { return alertService.updateAlertConfig(request.getData()); }*/ + + } diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/XcxIndexController.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/XcxIndexController.java index 5601c82..b99ea15 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/XcxIndexController.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/XcxIndexController.java @@ -122,8 +122,9 @@ public class XcxIndexController { condition.setState(state); condition.setUid(uid); - mainStats.setOnlineTotal(deviceInfoData.findAllByCondition(condition).size()); + mainStats.setOnlineTotal(deviceInfoData.countByUidAndState(uid, "online")); mainStats.setAlertCount(iAlertRecordData.countByUid(uid)); + //上报数据统计 /* mainStats.setReportDataStats(thingModelMessageData.getDeviceMessageStatsWithUid(uid, now - 48 * 3600 * 1000, now)); //产品数量统计 diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/device/DeviceDetectorQueryBo.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/device/DeviceDetectorQueryBo.java new file mode 100644 index 0000000..e407641 --- /dev/null +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/device/DeviceDetectorQueryBo.java @@ -0,0 +1,88 @@ +/* + * + * * | Licensed 未经许可不能去掉「OPENIITA」相关版权 + * * +---------------------------------------------------------------------- + * * | Author: xw2sy@163.com + * * +---------------------------------------------------------------------- + * + * Copyright [2024] [OPENIITA] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * / + */ +package cc.iotkit.manager.dto.bo.device; + +import cc.iotkit.common.api.BaseDto; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.annotations.ReverseAutoMapping; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.Size; +import java.util.Date; + +@ApiModel(value = "DeviceDetectorQueryBo") +@Data +@EqualsAndHashCode(callSuper = true) +public class DeviceDetectorQueryBo extends BaseDto { + + + /* @ApiModelProperty(value="关键字") + private String keyword; + + @ApiModelProperty(value="分组") + @AutoMapping(ignore = true) + @ReverseAutoMapping(ignore = true) + private String group; + + @ApiModelProperty(value="设备id") + @Size(max = 255, message = "设备id长度不正确") + private String deviceId; + + @ApiModelProperty(value="设备名称特殊编码") + @Size(max = 255, message = "设备名称长度不正确") + private String deviceName; + + @ApiModelProperty(value="设备类型") + @Size(max = 255, message = "设备类型长度不正确") + private String model; + + @ApiModelProperty(value="父级id") + @Size(max = 255, message = "父级id长度不正确") + private String parentId; + + @ApiModelProperty(value="产品key") + @Size(max = 255, message = "产品key长度不正确") + private String productKey; + + + @ApiModelProperty(value="设备状态") + @AutoMapping(ignore = true) + @ReverseAutoMapping(ignore = true) + private Boolean online; + + @ApiModelProperty(value="用户id") + @Size(max = 255, message = "用户id长度不正确") + private String uid; + private Long deptAreaId; + private Long tenantId; + @ApiModelProperty(value="设备名称") + private String name;*/ + @ApiModelProperty(value="设备名称") + private String startTime; + @ApiModelProperty(value="设备名称") + private String endTime; + private String deviceId; +} diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/device/DeviceInfoBo.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/device/DeviceInfoBo.java index 930ffb4..3af9444 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/device/DeviceInfoBo.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/device/DeviceInfoBo.java @@ -25,6 +25,7 @@ package cc.iotkit.manager.dto.bo.device; import cc.iotkit.common.api.BaseDto; import cc.iotkit.model.device.DeviceInfo; +import cc.iotkit.model.device.DeviceInstallInfo; import io.github.linpeilie.annotations.AutoMapper; import io.github.linpeilie.annotations.AutoMapping; import io.github.linpeilie.annotations.ReverseAutoMapping; @@ -35,6 +36,9 @@ import javax.validation.constraints.Size; import lombok.Data; import lombok.EqualsAndHashCode; +import java.util.HashMap; +import java.util.Map; + @ApiModel(value = "DeviceInfoBo") @Data @@ -93,5 +97,23 @@ public class DeviceInfoBo extends BaseDto { @ApiModelProperty(value = "用户id") @Size(max = 255, message = "用户id长度不正确") private String uid; - + private Long tenantId; + private String groupId; + + private DeviceInstallInfo deviceInstallInfo; + private String nodeOne; + private String nodeTwo; + private String nodeThree; + private String nodeFour; + private String nodeFive; + private String nodeOneStatus; + private String nodeTwoStatus; + private String nodeThreeStatus; + private String nodeFourStatus; + private String nodeFiveStatus; + private String nodeOneDevice; + private String nodeTwoDevice; + private String nodeThreeDevice; + private String nodeFourDevice; + private String nodeFiveDevice; } diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/device/DeviceInstallInfoQueryBo.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/device/DeviceInstallInfoQueryBo.java new file mode 100644 index 0000000..e01da29 --- /dev/null +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/device/DeviceInstallInfoQueryBo.java @@ -0,0 +1,105 @@ +/* + * + * * | Licensed 未经许可不能去掉「OPENIITA」相关版权 + * * +---------------------------------------------------------------------- + * * | Author: xw2sy@163.com + * * +---------------------------------------------------------------------- + * + * Copyright [2024] [OPENIITA] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * / + */ +package cc.iotkit.manager.dto.bo.device; + +import cc.iotkit.common.api.BaseDto; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +@ApiModel(value = "DeviceInstallInfoQueryBo") +@Data +@EqualsAndHashCode(callSuper = true) +public class DeviceInstallInfoQueryBo extends BaseDto { + + + /* @ApiModelProperty(value="关键字") + private String keyword; + + @ApiModelProperty(value="分组") + @AutoMapping(ignore = true) + @ReverseAutoMapping(ignore = true) + private String group; + + @ApiModelProperty(value="设备id") + @Size(max = 255, message = "设备id长度不正确") + private String deviceId; + + @ApiModelProperty(value="设备名称特殊编码") + @Size(max = 255, message = "设备名称长度不正确") + private String deviceName; + + @ApiModelProperty(value="设备类型") + @Size(max = 255, message = "设备类型长度不正确") + private String model; + + @ApiModelProperty(value="父级id") + @Size(max = 255, message = "父级id长度不正确") + private String parentId; + + @ApiModelProperty(value="产品key") + @Size(max = 255, message = "产品key长度不正确") + private String productKey; + + + @ApiModelProperty(value="设备状态") + @AutoMapping(ignore = true) + @ReverseAutoMapping(ignore = true) + private Boolean online; + + @ApiModelProperty(value="用户id") + @Size(max = 255, message = "用户id长度不正确") + private String uid; + private Long deptAreaId; + private Long tenantId; + @ApiModelProperty(value="设备名称") + private String name;*/ + @ApiModelProperty(value = "设备名称") + private String startTime; + @ApiModelProperty(value = "设备名称") + private String endTime; + private String deviceName; + private String uid; + private Long tenantId; + + + // @ApiModelProperty(value = "公司名称") + private String corporateName; + // @ApiModelProperty(value = "申请时间") + + // @ApiModelProperty(value = "申请人") + private String proposer; + // @ApiModelProperty(value = "申请班组") + private String proposerTeam; + // @ApiModelProperty(value = "小区名称") + private String communityName; + // @ApiModelProperty(value = "用户名称") + private String userName; + // @ApiModelProperty(value = "用户电话") + private String userIpone; +} diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/device/DeviceQueryBo.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/device/DeviceQueryBo.java index bc83976..57074f1 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/device/DeviceQueryBo.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/device/DeviceQueryBo.java @@ -24,6 +24,7 @@ package cc.iotkit.manager.dto.bo.device; import cc.iotkit.common.api.BaseDto; import cc.iotkit.model.device.DeviceInfo; +import cc.iotkit.model.system.SysApp; import io.github.linpeilie.annotations.AutoMapper; import io.github.linpeilie.annotations.AutoMapping; import io.github.linpeilie.annotations.ReverseAutoMapping; @@ -36,6 +37,7 @@ import lombok.EqualsAndHashCode; @ApiModel(value = "DeviceQueryBo") @Data @EqualsAndHashCode(callSuper = true) +@AutoMapper(target = DeviceInfo.class, reverseConvertGenerate = false) public class DeviceQueryBo extends BaseDto { @@ -77,7 +79,8 @@ public class DeviceQueryBo extends BaseDto { @Size(max = 255, message = "用户id长度不正确") private String uid; private Long deptAreaId; - + private Long tenantId; @ApiModelProperty(value="设备名称") private String name; + private Boolean flag = false; } diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/product/ProductBo.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/product/ProductBo.java index a5db850..435140f 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/product/ProductBo.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/product/ProductBo.java @@ -58,7 +58,7 @@ public class ProductBo extends BaseDto { @ApiModelProperty(value = "创建时间") private Long createAt; - + private Long tenantId; @ApiModelProperty(value = "图片") @Size(max = 255, message = "图片长度不正确") private String img; diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/ruleinfo/RuleInfoBo.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/ruleinfo/RuleInfoBo.java index f347029..7e04bfc 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/ruleinfo/RuleInfoBo.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/ruleinfo/RuleInfoBo.java @@ -78,5 +78,5 @@ public class RuleInfoBo extends BaseDto { @ApiModelProperty(value = "用户id") @Size(max = 255, message = "用户id长度不正确") private String uid; - + private Long tenantId; } diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/FeedBackEvaluation/FeedBackEvaluationSaveReqVO.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/FeedBackEvaluation/FeedBackEvaluationSaveReqVO.java index 554cc4d..81fde4c 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/FeedBackEvaluation/FeedBackEvaluationSaveReqVO.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/FeedBackEvaluation/FeedBackEvaluationSaveReqVO.java @@ -44,4 +44,5 @@ public class FeedBackEvaluationSaveReqVO { // @Schema(description = "客户电话") private String customerPhone; private Long customerId; + private Long tenantId; } \ No newline at end of file diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/category/vo/DIccidRecordPageReqVO.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/category/vo/DIccidRecordPageReqVO.java index 607d92e..3d23c35 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/category/vo/DIccidRecordPageReqVO.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/category/vo/DIccidRecordPageReqVO.java @@ -16,6 +16,7 @@ import org.springframework.format.annotation.DateTimeFormat; import java.io.Serializable; import java.time.LocalDateTime; +import java.util.Date; //@Schema(description = "管理后台 - 物联网卡分页 Request VO") @@ -71,4 +72,7 @@ public class DIccidRecordPageReqVO extends BaseDto implements Serializable { @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") private LocalDateTime expirationTime; + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + private LocalDateTime expirationTimeEnd; } \ No newline at end of file diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/category/vo/DIccidRecordRespVO.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/category/vo/DIccidRecordRespVO.java index 82c322b..9ddc95f 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/category/vo/DIccidRecordRespVO.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/category/vo/DIccidRecordRespVO.java @@ -75,5 +75,5 @@ public class DIccidRecordRespVO implements Serializable { private Integer validDays; @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") - private LocalDateTime expirationTime; + private String expirationTime; } \ No newline at end of file diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/deviceinfo/DeviceInfoExpordVo.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/deviceinfo/DeviceInfoExpordVo.java new file mode 100644 index 0000000..a2aaebd --- /dev/null +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/deviceinfo/DeviceInfoExpordVo.java @@ -0,0 +1,59 @@ +/* + * + * * | Licensed 未经许可不能去掉「OPENIITA」相关版权 + * * +---------------------------------------------------------------------- + * * | Author: xw2sy@163.com + * * +---------------------------------------------------------------------- + * + * Copyright [2024] [OPENIITA] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * / + */ + +package cc.iotkit.manager.dto.vo.deviceinfo; + +import cc.iotkit.model.device.DeviceInfo; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serializable; + + +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = DeviceInfoVo.class,convertGenerate = false) +public class DeviceInfoExpordVo implements Serializable { + private static final long serialVersionUID = -1L; + + @ExcelProperty(value = "IMEI(设备编号)") + private String deviceName; + + @ExcelProperty(value = "设备型号") + private String model; + + @ExcelProperty(value = "父级id") + private String parentId; + + @ExcelProperty(value = "产品key") + private String productKey; + + // @ExcelProperty(value = "设备分组") + // private String deviceGroup; + @ExcelProperty(value = "租户编号") + private Long tenantId; + @ExcelProperty(value = "设备区域") + private Long deptAreaId; +} diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/deviceinfo/DeviceInfoImportVo.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/deviceinfo/DeviceInfoImportVo.java index 893744d..c17575e 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/deviceinfo/DeviceInfoImportVo.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/deviceinfo/DeviceInfoImportVo.java @@ -23,6 +23,7 @@ package cc.iotkit.manager.dto.vo.deviceinfo; +import cc.iotkit.data.model.TbDeviceInfo; import cc.iotkit.model.device.DeviceInfo; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; @@ -38,7 +39,7 @@ import java.io.Serializable; public class DeviceInfoImportVo implements Serializable { private static final long serialVersionUID = -1L; - @ExcelProperty(value = "设备名称") + @ExcelProperty(value = "IMEI(设备编号)") private String deviceName; @ExcelProperty(value = "设备型号") @@ -52,4 +53,8 @@ public class DeviceInfoImportVo implements Serializable { @ExcelProperty(value = "设备分组") private String deviceGroup; + @ExcelProperty(value = "租户编号") + private Long tenantId; + @ExcelProperty(value = "设备区域") + private Long deptAreaId; } diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/deviceinfo/DeviceInfoVo.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/deviceinfo/DeviceInfoVo.java index 92c30f1..529f7c0 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/deviceinfo/DeviceInfoVo.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/deviceinfo/DeviceInfoVo.java @@ -111,4 +111,25 @@ public class DeviceInfoVo implements Serializable { private String productName; private String site; private String name; + private String uid; + private String signalStrength; + private String deviceVersion; + private String tenantName; + private String deviceStatus; + private Long tenantId; + private String nodeOne; + private String nodeTwo; + private String nodeThree; + private String nodeFour; + private String nodeFive; + private String nodeOneStatus; + private String nodeTwoStatus; + private String nodeThreeStatus; + private String nodeFourStatus; + private String nodeFiveStatus; + private String nodeOneDevice; + private String nodeTwoDevice; + private String nodeThreeDevice; + private String nodeFourDevice; + private String nodeFiveDevice; } diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/product/ProductVo.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/product/ProductVo.java index 93ac445..b80ad0a 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/product/ProductVo.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/product/ProductVo.java @@ -44,15 +44,15 @@ public class ProductVo implements Serializable { private static final long serialVersionUID = -1L; @ApiModelProperty(value = "产品id") - @ExcelProperty(value = "产品id") + // @ExcelProperty(value = "产品id") private Long id; @ApiModelProperty(value = "产品id") - @ExcelProperty(value = "产品id") + @ExcelProperty(value = "产品key") private String productKey; @ApiModelProperty(value = "产品密钥") - @ExcelProperty(value = "产品密钥") + //@ExcelProperty(value = "产品密钥") private String productSecret; @ApiModelProperty(value = "品类") diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/ruleinfo/RuleInfoVo.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/ruleinfo/RuleInfoVo.java index cbdfccd..f438c54 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/ruleinfo/RuleInfoVo.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/ruleinfo/RuleInfoVo.java @@ -85,6 +85,6 @@ public class RuleInfoVo implements Serializable { @ApiModelProperty(value = "用户id") @ExcelProperty(value = "用户id") private String uid; - - + private String tenantName; + private Long tenantId; } diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/userInfo/UserInfoPageReqVO.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/userInfo/UserInfoPageReqVO.java index f0fcbff..801b9b3 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/userInfo/UserInfoPageReqVO.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/userInfo/UserInfoPageReqVO.java @@ -11,6 +11,7 @@ import lombok.EqualsAndHashCode; import lombok.ToString; import java.io.Serializable; +import java.util.List; @ApiModel(value = "UserInfoPageReqVO") @Data @@ -38,12 +39,12 @@ public class UserInfoPageReqVO extends BaseDto implements Serializable { * 用户昵称 */ private String nickName; - + private String userName; /** * 性别 0-未知 1-male,2-female */ private Integer gender; - + private List deptAreaIds; /** * 头像地址 */ @@ -64,5 +65,5 @@ public class UserInfoPageReqVO extends BaseDto implements Serializable { * 1:终端用户 */ private Integer type; - + private Long tenantId; } diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/worder/WorderSaveReqVO.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/worder/WorderSaveReqVO.java index ad6c5cb..d183ed8 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/worder/WorderSaveReqVO.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/worder/WorderSaveReqVO.java @@ -110,5 +110,5 @@ public class WorderSaveReqVO { * 指派人电话 */ private String assignPhone; - + private Long tenantId; } \ No newline at end of file diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/listener/DeviceInfoImportListener.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/listener/DeviceInfoImportListener.java index cd844aa..7dbb956 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/listener/DeviceInfoImportListener.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/listener/DeviceInfoImportListener.java @@ -110,7 +110,9 @@ public class DeviceInfoImportListener extends AnalysisEventListener selectAlertRecordPage(PageRequest request) { return alertRecordData.selectAlertConfigPage(request); } - + public void save(AlertRecord request) { + alertRecordData.save(request); + } public void addAlert(AlertConfig config, String content) { alertRecordData.save(AlertRecord.builder() .level(config.getLevel()) @@ -76,4 +78,17 @@ public class AlertService { .details(content) .build()); } + public void addAlert(AlertConfig config, String content,Long tenandId, String uid,Long deptAreaId) { + alertRecordData.save(AlertRecord.builder() + .level(config.getLevel()) + .name(config.getName()) + .tenantId(tenandId) + .uid(uid) + .deptAreaId(deptAreaId) + .readFlg(false) + .alertTime(System.currentTimeMillis()) + .details(content) + .build()); + } + } diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/DIccidRecordService.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/DIccidRecordService.java index e0ff4cc..d4b1383 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/DIccidRecordService.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/DIccidRecordService.java @@ -53,7 +53,7 @@ public interface DIccidRecordService { * @param pageReqVO 分页查询 * @return 物联网卡分页 */ - Paging getDIccidRecordPage(PageRequest pageReqVO); + Paging getDIccidRecordPage(PageRequest pageReqVO); String createList(DIccidRecordListSaveReqVO createReqVO, Integer num); diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/DeviceCtrlService.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/DeviceCtrlService.java index 7ae0ec8..4e6e9c2 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/DeviceCtrlService.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/DeviceCtrlService.java @@ -34,6 +34,7 @@ import cc.iotkit.model.device.DeviceConfig; import cc.iotkit.model.device.DeviceInfo; import cc.iotkit.temporal.IThingModelMessageData; import cc.iotkit.virtualdevice.VirtualManager; +import cn.hutool.core.util.ObjectUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -44,6 +45,7 @@ import java.util.Map; import static cc.iotkit.common.enums.ErrCode.DEVICE_NOT_FOUND; import static cc.iotkit.common.enums.ErrCode.DEVICE_OFFLINE; +import static cc.iotkit.common.web.core.BaseController.fail; @Slf4j @Service @@ -101,6 +103,12 @@ public class DeviceCtrlService { ThingModelMessage.TYPE_PROPERTY, ThingModelMessage.ID_PROPERTY_GET); } + /** + * 设备配置下发获取 + */ + public String getConfig(String deviceId) { + return getConfig(deviceId, true); + } /** * 设备属性设置 */ @@ -131,7 +139,21 @@ public class DeviceCtrlService { return send(deviceId, device.getProductKey(), device.getDeviceName(), data, ThingModelMessage.TYPE_CONFIG, ThingModelMessage.ID_CONFIG_SET); } + /** + * 设备配置下发-读取设备配置 + */ + public String getConfig(String deviceId, boolean checkOwner) { + DeviceInfo device = getAndCheckDevice(deviceId, checkOwner); + DeviceConfig config = deviceConfigData.findByDeviceId(deviceId); + if (config == null || ObjectUtil.isEmpty(config)) { + fail("设备未配置"); + } + Map data = JsonUtils.parseObject(config.getConfig(), Map.class); + + return send(deviceId, device.getProductKey(), device.getDeviceName(), data, + ThingModelMessage.TYPE_CONFIG, ThingModelMessage.ID_CONFIG_GET); + } /** * 设备配置下发 */ @@ -197,6 +219,7 @@ public class DeviceCtrlService { .identifier(identifier) .params(data) .build(); + System.out.println("thingService++++++++++++++++++++++++" + thingService); if (!ThingModelMessage.TYPE_CONFIG.equals(type) && !ThingModelMessage.TYPE_LIFETIME.equals(type) && !ThingModelMessage.TYPE_OTA.equals(type) diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/DeviceStateCheckTask.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/DeviceStateCheckTask.java index f891bc5..07421f3 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/DeviceStateCheckTask.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/DeviceStateCheckTask.java @@ -32,6 +32,7 @@ import cc.iotkit.model.product.Product; import cc.iotkit.plugin.core.thing.IThingService; import cc.iotkit.plugin.core.thing.actions.DeviceState; import cc.iotkit.plugin.core.thing.actions.up.DeviceStateChange; +import cn.hutool.core.util.ObjectUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -67,7 +68,16 @@ public class DeviceStateCheckTask { all = deviceInfoData.findByConditions("","","","","",true,"",pn,1000,null); //判断属性更新时间是否大于产品定义保活时长 for (DeviceInfo device : all.getRows()) { + if(ObjectUtil.isNull(device)){ + continue; + } + if(ObjectUtil.isNull(device.getProductKey())){ + continue; + } Product product = productData.findByProductKey(device.getProductKey()); + if(ObjectUtil.isNull(product)){ + continue; + } Long keepAliveTime = product.getKeepAliveTime(); if (keepAliveTime == null || keepAliveTime <= 0) { continue; diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IDeviceDetectorInfoService.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IDeviceDetectorInfoService.java new file mode 100644 index 0000000..ed5278b --- /dev/null +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IDeviceDetectorInfoService.java @@ -0,0 +1,55 @@ +/* + * + * * | Licensed 未经许可不能去掉「OPENIITA」相关版权 + * * +---------------------------------------------------------------------- + * * | Author: xw2sy@163.com + * * +---------------------------------------------------------------------- + * + * Copyright [2024] [OPENIITA] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * / + */ + +package cc.iotkit.manager.service; + +import cc.iotkit.common.api.PageRequest; +import cc.iotkit.common.api.Paging; +import cc.iotkit.common.thing.ThingModelMessage; +import cc.iotkit.manager.dto.bo.device.*; +import cc.iotkit.manager.dto.bo.devicegroup.DeviceAddGroupBo; +import cc.iotkit.manager.dto.bo.devicegroup.DeviceGroupBo; +import cc.iotkit.manager.dto.vo.deviceconfig.DeviceConfigVo; +import cc.iotkit.manager.dto.vo.devicegroup.DeviceGroupVo; +import cc.iotkit.manager.dto.vo.deviceinfo.DeviceInfoVo; +import cc.iotkit.manager.dto.vo.deviceinfo.ParentDeviceVo; +import cc.iotkit.model.device.DeviceConfig; +import cc.iotkit.model.device.DeviceDetectorInfo; +import cc.iotkit.model.device.DeviceGroup; +import cc.iotkit.model.device.DeviceInfo; +import cc.iotkit.model.device.message.DeviceProperty; +import org.springframework.web.context.request.async.DeferredResult; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +/** + * @Author: jay + * @Date: 2023/5/31 11:05 + * @Version: V1.0 + * @Description: 设备服务接口 + */ +public interface IDeviceDetectorInfoService { + Paging getPage(PageRequest pageRequest); + List getList(PageRequest pageRequest); +} diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IDeviceInstallInfoService.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IDeviceInstallInfoService.java new file mode 100644 index 0000000..f9f3888 --- /dev/null +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IDeviceInstallInfoService.java @@ -0,0 +1,44 @@ +/* + * + * * | Licensed 未经许可不能去掉「OPENIITA」相关版权 + * * +---------------------------------------------------------------------- + * * | Author: xw2sy@163.com + * * +---------------------------------------------------------------------- + * + * Copyright [2024] [OPENIITA] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * / + */ + +package cc.iotkit.manager.service; + +import cc.iotkit.common.api.PageRequest; +import cc.iotkit.common.api.Paging; +import cc.iotkit.manager.dto.bo.device.DeviceDetectorQueryBo; +import cc.iotkit.manager.dto.bo.device.DeviceInstallInfoQueryBo; +import cc.iotkit.model.device.DeviceDetectorInfo; +import cc.iotkit.model.device.DeviceInstallInfo; + +import java.util.List; + +/** + * @Author: jay + * @Date: 2023/5/31 11:05 + * @Version: V1.0 + * @Description: 设备服务接口 + */ +public interface IDeviceInstallInfoService { + Paging getPage(PageRequest pageRequest); + // List getList(PageRequest pageRequest); +} diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IDeviceManagerService.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IDeviceManagerService.java index f785f72..a6a7589 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IDeviceManagerService.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IDeviceManagerService.java @@ -53,7 +53,9 @@ import java.util.List; */ public interface IDeviceManagerService { Paging getDevices(PageRequest pageRequest); - + Paging getDevices1(PageRequest pageRequest); + public List findByConditionsList(String productKey,boolean flag); + List getDevicess(DeviceQueryBo pageRequest); boolean addDevice(DeviceInfoBo data); List selectChildrenPageList(String deviceId); @@ -73,7 +75,7 @@ public interface IDeviceManagerService { List getPropertyHistory(String deviceId, String name, long start, long end,int size); boolean unbindDevice(String data); - + boolean unbindDeviceXcx(String data); boolean addTag(DeviceTagAddBo bo); boolean simulateSend(ThingModelMessage message); @@ -99,8 +101,9 @@ public interface IDeviceManagerService { DeviceConfigVo getConfig(String deviceId); boolean saveDevice(DeviceInfoBo data); + boolean saveDevice1(DeviceInfoBo data); boolean editDeviceInfo(DeviceInfoBo data); - boolean editBandDeviceInfo(DeviceInfoBo data); + Long editBandDeviceInfo(DeviceInfoBo data); String importGroup(MultipartFile file); diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IProductService.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IProductService.java index 48b5244..f81bbfb 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IProductService.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IProductService.java @@ -65,11 +65,12 @@ public interface IProductService { boolean deleteCategory(String data); boolean editCategory(CategoryBo req); + boolean saveCategory(CategoryBo req); String uploadImg(String productKey, MultipartFile file); Paging selectPageList(PageRequest request); - + List selectPageList(ProductBo request); Paging selectCategoryPageList(PageRequest request); List selectCategoryList(); diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IRuleEngineService.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IRuleEngineService.java index e333b1f..02f0819 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IRuleEngineService.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IRuleEngineService.java @@ -33,6 +33,9 @@ import cc.iotkit.manager.dto.vo.ruleinfo.RuleInfoVo; import cc.iotkit.manager.dto.vo.ruleinfo.RuleLogVo; import cc.iotkit.manager.dto.vo.taskinfo.TaskInfoVo; import cc.iotkit.manager.dto.vo.taskinfo.TaskLogVo; +import cc.iotkit.model.rule.RuleInfo; + +import java.util.List; /** * @Author: jay @@ -42,6 +45,7 @@ import cc.iotkit.manager.dto.vo.taskinfo.TaskLogVo; */ public interface IRuleEngineService { Paging selectPageList(PageRequest request); + List selectPageList1(PageRequest request); boolean saveRule(RuleInfoBo ruleInfoBo); diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/OtaService.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/OtaService.java index c2138b2..29ee3e5 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/OtaService.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/OtaService.java @@ -29,6 +29,7 @@ import cc.iotkit.common.enums.ErrCode; import cc.iotkit.common.exception.BizException; import cc.iotkit.common.oss.core.OssClient; import cc.iotkit.common.oss.factory.OssFactory; +import cc.iotkit.common.oss.minio.MinioUtil; import cc.iotkit.common.utils.StringUtils; import cc.iotkit.data.manager.IDeviceInfoData; import cc.iotkit.data.manager.IDeviceOtaDetailData; @@ -50,6 +51,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.FileUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; @@ -83,34 +85,31 @@ public class OtaService { private final IDeviceInfoData deviceInfoData; private final IDeviceOtaDetailData deviceOtaDetailData; private final ISysOssData sysOssData; - + private final MinioUtil minioUtil; public OtaPackageUploadVo uploadFile(MultipartFile file) throws Exception { String originalFileName = file.getOriginalFilename(); if (originalFileName == null) { throw new BizException("文件名为空,获取失败"); } String suffix = StringUtils.substring(originalFileName, originalFileName.lastIndexOf("."), originalFileName.length()); - OssClient storage = OssFactory.instance(); - UploadResult uploadResult; - try { - uploadResult = storage.uploadSuffix(file.getBytes(), suffix, file.getContentType()); - } catch (IOException e) { - throw new BizException(e.getMessage()); - } + //OssClient storage = OssFactory.instance(); + String url = minioUtil.upload(file); + // uploadResult = storage.uploadSuffix(file.getBytes(), suffix, file.getContentType()); + // 保存文件信息 SysOss oss = new SysOss(); - oss.setUrl(uploadResult.getUrl()); + oss.setUrl(url); oss.setFileSuffix(suffix); - oss.setFileName(uploadResult.getFilename()); + oss.setFileName(file.getName()); oss.setOriginalName(originalFileName); - oss.setService(storage.getConfigKey()); + oss.setService("oss-embed"); oss = sysOssData.save(oss); - String md5 = md5OfFile(file); + // String md5 = md5OfFile(file); OtaPackageUploadVo otaPackageUploadVo = new OtaPackageUploadVo(); - otaPackageUploadVo.setUrl(uploadResult.getUrl()); + otaPackageUploadVo.setUrl(url); otaPackageUploadVo.setSize(file.getSize()); - otaPackageUploadVo.setMd5(md5); + // otaPackageUploadVo.setMd5(md5); otaPackageUploadVo.setOriginalName(originalFileName); otaPackageUploadVo.setOssId(oss.getId()); return otaPackageUploadVo; diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/DIccidRecordServiceImpl.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/DIccidRecordServiceImpl.java index ed5fc3b..67343fe 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/DIccidRecordServiceImpl.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/DIccidRecordServiceImpl.java @@ -3,14 +3,21 @@ package cc.iotkit.manager.service.impl; import cc.iotkit.common.api.PageRequest; import cc.iotkit.common.api.Paging; +import cc.iotkit.data.dao.DiccidRecordRepository; import cc.iotkit.data.manager.IDIccidRecordData; +import cc.iotkit.data.model.QTbDIccidRecordDO; +import cc.iotkit.data.model.TbDIccidRecordDO; +import cc.iotkit.data.util.PageBuilder; +import cc.iotkit.data.util.PredicateBuilder; import cc.iotkit.manager.config.BeanUtils; import cc.iotkit.manager.dto.vo.category.vo.*; import cc.iotkit.manager.dto.vo.taskinfo.TaskInfoVo; +import cc.iotkit.manager.dto.vo.worder.WorderPageReqVO; import cc.iotkit.manager.service.DIccidRecordService; import cc.iotkit.model.iccid.DIccidRecordDO; import cc.iotkit.model.rule.TaskInfo; +import cc.iotkit.model.worder.WorderDO; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.lang.Assert; @@ -18,6 +25,7 @@ import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.db.PageResult; +import com.querydsl.core.types.Predicate; import lombok.extern.slf4j.Slf4j; import org.apache.poi.ss.formula.functions.T; import org.hibernate.service.spi.ServiceException; @@ -30,6 +38,8 @@ import javax.annotation.Resource; import java.util.*; import java.util.stream.Collectors; +import static cc.iotkit.data.model.QTbDIccidRecordDO.tbDIccidRecordDO; +import static cc.iotkit.data.model.QTbWorderDO.tbWorderDO; /** @@ -43,6 +53,8 @@ public class DIccidRecordServiceImpl implements DIccidRecordService { @Autowired private IDIccidRecordData idIccidRecordData; + @Autowired + private DiccidRecordRepository diccidRecordRepository; @@ -52,8 +64,16 @@ public class DIccidRecordServiceImpl implements DIccidRecordService { // TenantContextHolder.setIgnore(true); // 插入 DIccidRecordDO dIccidRecord = BeanUtils.toBean(createReqVO, DIccidRecordDO.class); - DIccidRecordDO dIccidRecordDO = idIccidRecordData.findOneByCondition(dIccidRecord); + DIccidRecordDO diccidRecordDO = new DIccidRecordDO(); + diccidRecordDO.setIccid(createReqVO.getIccid()); + + DIccidRecordDO dIccidRecordDO = idIccidRecordData.findOneByCondition(diccidRecordDO); Assert.isNull(dIccidRecordDO, "厂商物联网卡iccid已经存在"); + + diccidRecordDO.setImei(createReqVO.getImei()); + diccidRecordDO.setIccid(null); + DIccidRecordDO dIccidRecordDO1 = idIccidRecordData.findOneByCondition(diccidRecordDO); + Assert.isNull(dIccidRecordDO1, "厂商物联网卡imei已经存在"); // dIccidRecord.setState(0); // dIccidRecord.setOrderId(String.valueOf(IdUtil.getSnowflake(1, 1).nextId())); //修改厂商物联网数量 @@ -77,6 +97,17 @@ public class DIccidRecordServiceImpl implements DIccidRecordService { // TenantContextHolder.setIgnore(true); // 校验存在 validateDIccidRecordExists(updateReqVO.getId()); + DIccidRecordDO dIccidRecordDO = idIccidRecordData.findById(updateReqVO.getId()); + DIccidRecordDO dIccidRecordDO1 = new DIccidRecordDO(); + if(!dIccidRecordDO.getIccid().equals(updateReqVO.getIccid())){ + dIccidRecordDO1.setIccid(updateReqVO.getIccid()); + idIccidRecordData.findAllByCondition(dIccidRecordDO1); + Assert.isNull(dIccidRecordDO1, "厂商物联网卡iccid已经存在"); + }else if(!dIccidRecordDO.getImei().equals(updateReqVO.getImei())){ + dIccidRecordDO1.setImei(updateReqVO.getImei()); + idIccidRecordData.findAllByCondition(dIccidRecordDO1); + Assert.isNull(dIccidRecordDO1, "厂商物联网卡imei已经存在"); + } //TenantDO tenantDO = tenantMapper.selectOne(new QueryWrapper().lambda().eq(TenantDO::getId, updateReqVO.getUserCode())); // 更新 DIccidRecordDO updateObj = BeanUtils.toBean(updateReqVO, DIccidRecordDO.class); @@ -148,10 +179,19 @@ public class DIccidRecordServiceImpl implements DIccidRecordService { } @Override - public Paging getDIccidRecordPage(PageRequest pageReqVO) { - - return idIccidRecordData.findAll(pageReqVO.to(DIccidRecordDO.class)).to(DIccidRecordRespVO.class); - + public Paging getDIccidRecordPage(PageRequest pageReqVO) { + //return idIccidRecordData.findAll(pageReqVO.to(DIccidRecordDO.class)).to(DIccidRecordRespVO.class); + return PageBuilder.toPaging(diccidRecordRepository.findAll( + buildQueryCondition(pageReqVO.getData()), + PageBuilder.toPageable(pageReqVO) + )).to(DIccidRecordDO.class); } + private Predicate buildQueryCondition(DIccidRecordPageReqVO dictData) { + return PredicateBuilder.instance() + .and(dictData.getIccid() != null, () -> tbDIccidRecordDO.iccid.like("%" + dictData.getIccid() +"%")) + .and(dictData.getImei() != null, () -> tbDIccidRecordDO.imei.like("%" + dictData.getImei()+"%")) + .and(dictData.getExpirationTime() != null, () -> tbDIccidRecordDO.expirationTime.between(dictData.getExpirationTime(),dictData.getExpirationTimeEnd())) + .build(); + } } \ No newline at end of file diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/DeviceDetectorInfoServiceImpl.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/DeviceDetectorInfoServiceImpl.java new file mode 100644 index 0000000..f32ed8c --- /dev/null +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/DeviceDetectorInfoServiceImpl.java @@ -0,0 +1,164 @@ +package cc.iotkit.manager.service.impl; + + +import cc.iotkit.common.api.PageRequest; +import cc.iotkit.common.api.Paging; +import cc.iotkit.common.utils.MapstructUtils; +import cc.iotkit.data.dao.DeviceIDetectornfoRepository; +import cc.iotkit.data.dao.DiccidRecordRepository; +import cc.iotkit.data.manager.IDIccidRecordData; +import cc.iotkit.data.manager.IDeviceDetectorInfoData; +import cc.iotkit.data.model.QTbDeviceDetectorInfo; +import cc.iotkit.data.model.TbDeviceDetectorInfo; +import cc.iotkit.data.model.TbDeviceInfo; +import cc.iotkit.data.model.TbSysConfig; +import cc.iotkit.data.util.PageBuilder; +import cc.iotkit.data.util.PredicateBuilder; +import cc.iotkit.manager.config.BeanUtils; +import cc.iotkit.manager.dto.bo.device.DeviceDetectorQueryBo; +import cc.iotkit.manager.dto.vo.category.vo.DIccidRecordListSaveReqVO; +import cc.iotkit.manager.dto.vo.category.vo.DIccidRecordPageReqVO; +import cc.iotkit.manager.dto.vo.category.vo.DIccidRecordSaveReqVO; +import cc.iotkit.manager.service.DIccidRecordService; +import cc.iotkit.manager.service.IDeviceDetectorInfoService; +import cc.iotkit.model.device.DeviceDetectorInfo; +import cc.iotkit.model.device.DeviceInfo; +import cc.iotkit.model.iccid.DIccidRecordDO; +import cc.iotkit.model.system.SysConfig; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.ObjectUtil; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.jpa.impl.JPAQuery; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.IteratorUtils; +import org.hibernate.service.spi.ServiceException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.stream.Collectors; + +import static cc.iotkit.data.model.QTbDIccidRecordDO.tbDIccidRecordDO; +import static cc.iotkit.data.model.QTbDeviceDetectorInfo.tbDeviceDetectorInfo; +import static cc.iotkit.data.model.QTbDeviceInfo.tbDeviceInfo; +import static cc.iotkit.data.model.QTbSysDictData.tbSysDictData; + + +/** + * 物联网卡 Service 实现类 + * + * @author 芋道源码 + */ +@Slf4j +@Service +@Primary +@RequiredArgsConstructor +public class DeviceDetectorInfoServiceImpl implements IDeviceDetectorInfoService { + + @Autowired + private IDeviceDetectorInfoData iDeviceDetectorInfoData; + @Autowired + private DeviceIDetectornfoRepository deviceIDetectornfoRepository; + private final JPAQueryFactory jpaQueryFactory; + + + + @Override + public Paging getPage(PageRequest pageReqVO) { + //return idIccidRecordData.findAll(pageReqVO.to(DIccidRecordDO.class)).to(DIccidRecordRespVO.class); + // 构建分页时指定排序规则 + /* Pageable pageable = PageRequest.of( + pageReqVO..getPage(), + pageReqVO.getSize(), + Sort.by(Sort.Direction.DESC, "createTime") // 按创建时间降序 + );*/ + JPAQuery query = jpaQueryFactory.selectFrom(tbDeviceDetectorInfo); + + if (ObjectUtil.isNotNull(pageReqVO.getData().getStartTime())&& ObjectUtil.isNotNull(pageReqVO.getData().getEndTime())) { + try { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date startDateTime = sdf.parse(pageReqVO.getData().getStartTime()); + Date dateTime = sdf.parse(pageReqVO.getData().getEndTime()); + // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + // LocalDateTime startDateTime = LocalDateTime.parse(dictData.getStartTime() , formatter); + // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + // LocalDateTime dateTime = LocalDateTime.parse(dictData.getEndTime(), formatter); + query.where(tbDeviceDetectorInfo.createTime.between(startDateTime, dateTime)); + } catch (Exception e) { + + } + } + if(ObjectUtil.isNotNull(pageReqVO.getData().getDeviceId())) { + query.where(tbDeviceDetectorInfo.deviceId.eq(pageReqVO.getData().getDeviceId())); + } + query.orderBy(tbDeviceDetectorInfo.createTime.desc()); + Integer page = ObjectUtil.isNotNull(pageReqVO.getPageNum()) ?pageReqVO.getPageNum():1; + Integer size = ObjectUtil.isNotNull(pageReqVO.getPageSize()) ?pageReqVO.getPageSize():10; + query.offset((page - 1) * size).limit(size); + List tbDeviceInfos = query.fetch(); + List deviceInfos = new ArrayList<>(tbDeviceInfos.size()); + long total = query.fetchCount(); + for (TbDeviceDetectorInfo tbDeviceInfo : tbDeviceInfos) { + DeviceDetectorInfo deviceInfo = MapstructUtils.convert(tbDeviceInfo, DeviceDetectorInfo.class); + //fillDeviceInfo(tbDeviceInfo.getDeviceId(), tbDeviceInfo, deviceInfo); + deviceInfos.add(deviceInfo); + } + return new Paging<>(total, deviceInfos); + /* return PageBuilder.toPaging(deviceIDetectornfoRepository.findAll( + buildQueryCondition(pageReqVO.getData()), + PageBuilder.toPageable(pageReqVO) + )).to(DeviceDetectorInfo.class);*/ + } + // 构建动态查询条件(含排序) + + + @Override + public List getList(PageRequest pageReqVO) { + //return idIccidRecordData.findAll(pageReqVO.to(DIccidRecordDO.class)).to(DIccidRecordRespVO.class); + Iterator iterator = deviceIDetectornfoRepository.findAll(buildQueryCondition(pageReqVO.getData())).iterator(); + //Iterator iterator = baseRepository.findAll(predicate).iterator(); + return MapstructUtils.convert(IteratorUtils.toList(iterator), DeviceDetectorInfo.class); + } + /* private Predicate buildQueryCondition(DeviceDetectorQueryBo dictData) { + return PredicateBuilder.instance() + .and(dictData.getIccid() != null, () -> tbDIccidRecordDO.iccid.like("%" + dictData.getIccid() +"%")) + .and(dictData.getImei() != null, () -> tbDIccidRecordDO.imei.like("%" + dictData.getImei()+"%")) + .and(dictData.getExpirationTime() != null, () -> tbDIccidRecordDO.expirationTime.between(dictData.getExpirationTime(),dictData.getExpirationTimeEnd())) + .build(); + }*/ + + private Predicate buildQueryCondition(DeviceDetectorQueryBo dictData) { + PredicateBuilder predicate = PredicateBuilder.instance(); + if (dictData.getStartTime() != null && dictData.getEndTime() != null) { + try { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date startDateTime = sdf.parse(dictData.getStartTime()); + Date dateTime = sdf.parse(dictData.getEndTime()); + // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + // LocalDateTime startDateTime = LocalDateTime.parse(dictData.getStartTime() , formatter); + // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + // LocalDateTime dateTime = LocalDateTime.parse(dictData.getEndTime(), formatter); + predicate.and(true, () -> tbDeviceDetectorInfo.createTime.between(startDateTime, dateTime)); + } catch (Exception e) { + + } + } + predicate.and(ObjectUtil.isNotNull(dictData.getDeviceId()), () -> tbDeviceDetectorInfo.deviceId.eq(dictData.getDeviceId())); + + return predicate.build(); + } + +} \ No newline at end of file diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/DeviceInstallInfoServiceImpl.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/DeviceInstallInfoServiceImpl.java new file mode 100644 index 0000000..956d3b6 --- /dev/null +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/DeviceInstallInfoServiceImpl.java @@ -0,0 +1,175 @@ +package cc.iotkit.manager.service.impl; + + +import cc.iotkit.common.api.PageRequest; +import cc.iotkit.common.api.Paging; +import cc.iotkit.common.satoken.utils.LoginHelper; +import cc.iotkit.common.tenant.helper.TenantHelper; +import cc.iotkit.common.utils.MapstructUtils; +import cc.iotkit.data.dao.DeviceIDetectornfoRepository; +import cc.iotkit.data.dao.DeviceInstallInfoRepository; +import cc.iotkit.data.manager.IDeviceDetectorInfoData; +import cc.iotkit.data.manager.IDeviceInstallInfoData; +import cc.iotkit.data.model.TbDeviceDetectorInfo; +import cc.iotkit.data.model.TbDeviceInstallInfo; +import cc.iotkit.data.util.PredicateBuilder; +import cc.iotkit.manager.dto.bo.device.DeviceDetectorQueryBo; +import cc.iotkit.manager.dto.bo.device.DeviceInstallInfoQueryBo; +import cc.iotkit.manager.service.IDeviceDetectorInfoService; +import cc.iotkit.manager.service.IDeviceInstallInfoService; +import cc.iotkit.model.device.DeviceDetectorInfo; +import cc.iotkit.model.device.DeviceInstallInfo; +import cn.hutool.core.util.ObjectUtil; +import com.querydsl.core.types.Predicate; +import com.querydsl.jpa.impl.JPAQuery; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.IteratorUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; + +import static cc.iotkit.data.model.QTbDeviceDetectorInfo.tbDeviceDetectorInfo; +import static cc.iotkit.data.model.QTbDeviceInstallInfo.tbDeviceInstallInfo; + + +/** + * 物联网卡 Service 实现类 + * + * @author 芋道源码 + */ +@Slf4j +@Service +@Primary +@RequiredArgsConstructor +public class DeviceInstallInfoServiceImpl implements IDeviceInstallInfoService { + + @Autowired + private IDeviceInstallInfoData iDeviceInstallInfoData; + @Autowired + private DeviceInstallInfoRepository deviceInstallInfoRepository; + private final JPAQueryFactory jpaQueryFactory; + + + + @Override + public Paging getPage(PageRequest pageReqVO) { + //return idIccidRecordData.findAll(pageReqVO.to(DIccidRecordDO.class)).to(DIccidRecordRespVO.class); + // 构建分页时指定排序规则 + /* Pageable pageable = PageRequest.of( + pageReqVO..getPage(), + pageReqVO.getSize(), + Sort.by(Sort.Direction.DESC, "createTime") // 按创建时间降序 + );*/ + JPAQuery query = jpaQueryFactory.selectFrom(tbDeviceInstallInfo); + + if (ObjectUtil.isNotNull(pageReqVO.getData().getStartTime())&& ObjectUtil.isNotNull(pageReqVO.getData().getEndTime())) { + try { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date startDateTime = sdf.parse(pageReqVO.getData().getStartTime()); + Date dateTime = sdf.parse(pageReqVO.getData().getEndTime()); + // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + // LocalDateTime startDateTime = LocalDateTime.parse(dictData.getStartTime() , formatter); + // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + // LocalDateTime dateTime = LocalDateTime.parse(dictData.getEndTime(), formatter); + query.where(tbDeviceInstallInfo.proposerTime.between(startDateTime, dateTime)); + } catch (Exception e) { + + } + } + if(ObjectUtil.isNotNull(pageReqVO.getData().getDeviceName())) { + query.where(tbDeviceInstallInfo.deviceName.like("%" + pageReqVO.getData().getDeviceName() +"%")); + } + if(ObjectUtil.isNotNull(pageReqVO.getData().getUid())) { + query.where(tbDeviceInstallInfo.uid.eq(pageReqVO.getData().getUid())); + } + + if(ObjectUtil.isNotNull(pageReqVO.getData().getCorporateName())) { + query.where(tbDeviceInstallInfo.corporateName.like("%" + pageReqVO.getData().getCorporateName() +"%")); + } + if(ObjectUtil.isNotNull(pageReqVO.getData().getProposer())) { + query.where(tbDeviceInstallInfo.proposer.like("%" + pageReqVO.getData().getProposer() +"%")); + } + if(ObjectUtil.isNotNull(pageReqVO.getData().getProposerTeam())) { + query.where(tbDeviceInstallInfo.proposerTeam.like("%" + pageReqVO.getData().getProposerTeam() +"%")); + } + if(ObjectUtil.isNotNull(pageReqVO.getData().getCommunityName())) { + query.where(tbDeviceInstallInfo.communityName.like("%" + pageReqVO.getData().getCommunityName() +"%")); + } + if(ObjectUtil.isNotNull(pageReqVO.getData().getUserName())) { + query.where(tbDeviceInstallInfo.userName.like("%" + pageReqVO.getData().getUserName() +"%")); + } + if(ObjectUtil.isNotNull(pageReqVO.getData().getUserIpone())) { + query.where(tbDeviceInstallInfo.userIpone.like("%" + pageReqVO.getData().getUserIpone() +"%")); + } + if(LoginHelper.isSuperAdmin() && TenantHelper.getTenantId() != 0){ + query.where(tbDeviceInstallInfo.tenantId.eq(TenantHelper.getTenantId())); + } + if(!LoginHelper.isSuperAdmin() && ObjectUtil.isNotNull(pageReqVO.getData().getTenantId())){ + query.where(tbDeviceInstallInfo.tenantId.eq(pageReqVO.getData().getTenantId())); + } + query.orderBy(tbDeviceInstallInfo.createTime.desc()); + Integer page = ObjectUtil.isNotNull(pageReqVO.getPageNum()) ?pageReqVO.getPageNum():1; + Integer size = ObjectUtil.isNotNull(pageReqVO.getPageSize()) ?pageReqVO.getPageSize():10; + query.offset((page - 1) * size).limit(size); + List tbDeviceInfos = query.fetch(); + List deviceInfos = new ArrayList<>(tbDeviceInfos.size()); + long total = query.fetchCount(); + for (TbDeviceInstallInfo tbDeviceInfo : tbDeviceInfos) { + DeviceInstallInfo deviceInfo = MapstructUtils.convert(tbDeviceInfo, DeviceInstallInfo.class); + //fillDeviceInfo(tbDeviceInfo.getDeviceId(), tbDeviceInfo, deviceInfo); + deviceInfos.add(deviceInfo); + } + return new Paging<>(total, deviceInfos); + /* return PageBuilder.toPaging(deviceIDetectornfoRepository.findAll( + buildQueryCondition(pageReqVO.getData()), + PageBuilder.toPageable(pageReqVO) + )).to(DeviceDetectorInfo.class);*/ + } + // 构建动态查询条件(含排序) + + + /* @Override + public List getList(PageRequest pageReqVO) { + //return idIccidRecordData.findAll(pageReqVO.to(DIccidRecordDO.class)).to(DIccidRecordRespVO.class); + Iterator iterator = deviceIDetectornfoRepository.findAll(buildQueryCondition(pageReqVO.getData())).iterator(); + //Iterator iterator = baseRepository.findAll(predicate).iterator(); + return MapstructUtils.convert(IteratorUtils.toList(iterator), DeviceDetectorInfo.class); + } + *//* private Predicate buildQueryCondition(DeviceDetectorQueryBo dictData) { + return PredicateBuilder.instance() + .and(dictData.getIccid() != null, () -> tbDIccidRecordDO.iccid.like("%" + dictData.getIccid() +"%")) + .and(dictData.getImei() != null, () -> tbDIccidRecordDO.imei.like("%" + dictData.getImei()+"%")) + .and(dictData.getExpirationTime() != null, () -> tbDIccidRecordDO.expirationTime.between(dictData.getExpirationTime(),dictData.getExpirationTimeEnd())) + .build(); + }*//* + + private Predicate buildQueryCondition(DeviceDetectorQueryBo dictData) { + PredicateBuilder predicate = PredicateBuilder.instance(); + if (dictData.getStartTime() != null && dictData.getEndTime() != null) { + try { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date startDateTime = sdf.parse(dictData.getStartTime()); + Date dateTime = sdf.parse(dictData.getEndTime()); + // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + // LocalDateTime startDateTime = LocalDateTime.parse(dictData.getStartTime() , formatter); + // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + // LocalDateTime dateTime = LocalDateTime.parse(dictData.getEndTime(), formatter); + predicate.and(true, () -> tbDeviceDetectorInfo.createTime.between(startDateTime, dateTime)); + } catch (Exception e) { + + } + } + predicate.and(ObjectUtil.isNotNull(dictData.getDeviceId()), () -> tbDeviceDetectorInfo.deviceId.eq(dictData.getDeviceId())); + + return predicate.build(); + }*/ + +} \ No newline at end of file diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/DeviceManagerServiceImpl.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/DeviceManagerServiceImpl.java index e4c704d..7e130b2 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/DeviceManagerServiceImpl.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/DeviceManagerServiceImpl.java @@ -31,12 +31,15 @@ import cc.iotkit.common.excel.core.ExcelResult; import cc.iotkit.common.excel.utils.ExcelUtil; import cc.iotkit.common.exception.BizException; import cc.iotkit.common.satoken.utils.AuthUtil; +import cc.iotkit.common.satoken.utils.LoginHelper; +import cc.iotkit.common.tenant.helper.TenantHelper; import cc.iotkit.common.thing.ThingModelMessage; import cc.iotkit.common.utils.*; -import cc.iotkit.data.manager.IDeviceConfigData; -import cc.iotkit.data.manager.IDeviceGroupData; -import cc.iotkit.data.manager.IDeviceInfoData; -import cc.iotkit.data.manager.IProductData; +import cc.iotkit.data.config.TenantContext; +import cc.iotkit.data.dao.DeviceInfoRepository; +import cc.iotkit.data.manager.*; +import cc.iotkit.data.model.TbDeviceInfo; +import cc.iotkit.data.system.ISysDeptData; import cc.iotkit.manager.dto.bo.device.DeviceInfoBo; import cc.iotkit.manager.dto.bo.device.DeviceLogQueryBo; import cc.iotkit.manager.dto.bo.device.DeviceQueryBo; @@ -55,15 +58,21 @@ import cc.iotkit.manager.service.DataOwnerService; import cc.iotkit.manager.service.DeferredDataConsumer; import cc.iotkit.manager.service.DeviceCtrlService; import cc.iotkit.manager.service.IDeviceManagerService; +import cc.iotkit.model.UserInfo; import cc.iotkit.model.device.DeviceConfig; import cc.iotkit.model.device.DeviceGroup; import cc.iotkit.model.device.DeviceInfo; +import cc.iotkit.model.device.DeviceInstallInfo; import cc.iotkit.model.device.message.DeviceProperty; import cc.iotkit.model.product.Product; +import cc.iotkit.model.system.SysApp; +import cc.iotkit.model.system.SysDept; +import cc.iotkit.model.system.SysLoginInfo; import cc.iotkit.mq.MqProducer; import cc.iotkit.temporal.IDevicePropertyData; import cc.iotkit.temporal.IThingModelMessageData; import cn.hutool.core.util.ObjectUtil; +import com.querydsl.jpa.impl.JPAQuery; import lombok.SneakyThrows; import org.apache.commons.lang3.RandomStringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -73,9 +82,16 @@ import org.springframework.stereotype.Service; import org.springframework.web.context.request.async.DeferredResult; import org.springframework.web.multipart.MultipartFile; +import java.time.Instant; +import java.util.ArrayList; import java.util.List; +import java.util.UUID; import java.util.stream.Collectors; +import static cc.iotkit.common.web.core.BaseController.fail; +import static cc.iotkit.data.model.QTbDeviceInfo.tbDeviceInfo; + + /** * @Author: jay * @Date: 2023/5/31 11:06 @@ -92,12 +108,14 @@ public class DeviceManagerServiceImpl implements IDeviceManagerService { @Autowired @Qualifier("deviceInfoDataCache") private IDeviceInfoData deviceInfoData; + @Autowired @Qualifier("productDataCache") private IProductData productData; @Autowired private DataOwnerService dataOwnerService; - + @Autowired + private IDeviceInstallInfoData iDeviceInstallInfoData; @Lazy @Autowired private IThingModelMessageData thingModelMessageData; @@ -110,9 +128,14 @@ public class DeviceManagerServiceImpl implements IDeviceManagerService { private IDeviceGroupData deviceGroupData; @Autowired private IDeviceConfigData deviceConfigData; - + @Autowired + private ISysDeptData iSystemData; @Autowired private MqProducer producer; + @Autowired + private IUserInfoData iUserInfoData; + @Autowired + private IDeviceInfoData iDeviceInfoData; @Override public Paging getDevices(PageRequest pageRequest) { @@ -127,7 +150,27 @@ public class DeviceManagerServiceImpl implements IDeviceManagerService { String group = query.getGroup(); Boolean online = query.getOnline(); Long areaDepeId = query.getDeptAreaId(); - Paging result = MapstructUtils.convert(deviceInfoData.findByConditions(name,uid, subUid, pk, group, + Paging result = MapstructUtils.convert(deviceInfoData.findByConditions(name, uid, subUid, pk, group, + online, keyword, pageRequest.getPageNum(), pageRequest.getPageSize(), areaDepeId), DeviceInfoVo.class); + for (DeviceInfoVo row : result.getRows()) { + row.setProduct(productData.findByProductKey(row.getProductKey())); + } + return result; + } + @Override + public Paging getDevices1(PageRequest pageRequest) { + DeviceQueryBo query = pageRequest.getData(); + + String uid = query.getUid(); + String subUid = ""; + String name = query.getName(); + String pk = query.getProductKey(); + //关键字查询 + String keyword = query.getKeyword(); + String group = query.getGroup(); + Boolean online = query.getOnline(); + Long areaDepeId = query.getDeptAreaId(); + Paging result = MapstructUtils.convert(deviceInfoData.findByConditions1(name, uid, subUid, pk, group, online, keyword, pageRequest.getPageNum(), pageRequest.getPageSize(), areaDepeId), DeviceInfoVo.class); for (DeviceInfoVo row : result.getRows()) { row.setProduct(productData.findByProductKey(row.getProductKey())); @@ -135,6 +178,23 @@ public class DeviceManagerServiceImpl implements IDeviceManagerService { return result; } + public List getDevicess(DeviceQueryBo pageRequest) { + DeviceInfo deviceInfo = pageRequest.to(DeviceInfo.class); + deviceInfo.setState(null); + List selectedDevices = MapstructUtils.convert(deviceInfoData.findAllByCondition(deviceInfo), DeviceInfoVo.class); + + /* for (DeviceInfoVo row : selectedDevices) { + row.setProduct(productData.findByProductKey(row.getProductKey())); + }*/ + return selectedDevices; + } + + @Override + public List findByConditionsList(String productKey, boolean flag) { + return MapstructUtils.convert(iDeviceInfoData.findByConditionsList(productKey, flag), DeviceInfoVo.class); + // return deviceInfos; + } + @Override public boolean addDevice(DeviceInfoBo deviceInfo) { @@ -158,10 +218,31 @@ public class DeviceManagerServiceImpl implements IDeviceManagerService { for (var i = 0; i < 16; i++) { secret.append(chars.charAt((int) Math.floor(Math.random() * maxPos))); } + SysDept sysDept = new SysDept(); + if (ObjectUtil.isNotNull(deviceInfo.getDeptAreaId())) { + sysDept = iSystemData.findById(deviceInfo.getDeptAreaId()); + } DeviceInfo device = new DeviceInfo(); + /* if(ObjectUtil.isNotNull(sysDept) && ObjectUtil.isNull(deviceInfo.getTenantId())) { + device.setTenantId(sysDept.getTenantId()); + }*/ + if (ObjectUtil.isNotNull(sysDept)) { + device.setTenantId(sysDept.getTenantId()); + } + if (LoginHelper.isSuperAdmin() && TenantHelper.getTenantId() == 0) { + if (ObjectUtil.isNotNull(sysDept)) { + device.setTenantId(sysDept.getTenantId()); + } + } + + /*else if(ObjectUtil.isNotNull(deviceInfo.getTenantId())){ + device.setTenantId(deviceInfo.getTenantId()); + }*/ device.setId(DeviceUtil.newDeviceId(deviceName)); device.setUid(product.getUid()); + device.setDeptAreaId(deviceInfo.getDeptAreaId()); + device.setDeviceStatus(3); device.setDeviceId(device.getId()); device.setProductKey(productKey); device.setDeviceName(deviceName); @@ -172,7 +253,13 @@ public class DeviceManagerServiceImpl implements IDeviceManagerService { if (StringUtils.isNotBlank(parentId)) { device.setParentId(parentId); } + if (ObjectUtil.isNotNull(deviceInfo.getGroupId())) { + device.getGroup().put(deviceInfo.getGroupId(), new DeviceInfo.Group( + deviceInfo.getGroupId(), deviceInfo.getDeviceId())); + } + TenantHelper.enableIgnore(); deviceInfoData.save(device); + return true; } @@ -254,6 +341,23 @@ public class DeviceManagerServiceImpl implements IDeviceManagerService { return true; } + @Override + public boolean unbindDeviceXcx(String deviceId) { + TenantContext.disableTenantFilter(); + DeviceInfo deviceInfo = deviceInfoData.findByDeviceId(deviceId); + DeviceInstallInfo deviceInstallInfo = iDeviceInstallInfoData.findByDeviceNameAndUidAndState(deviceInfo.getDeviceName(), deviceInfo.getUid(),0); + if(ObjectUtil.isNotEmpty(deviceInstallInfo)){ + //解绑 + deviceInstallInfo.setState(1); + iDeviceInstallInfoData.save(deviceInstallInfo); + } + deviceInfo.setUid(""); + deviceInfo.setName(""); + deviceInfoData.save(deviceInfo); + + return true; + } + @Override public boolean addTag(DeviceTagAddBo bo) { String deviceId = bo.getDeviceId(); @@ -277,7 +381,7 @@ public class DeviceManagerServiceImpl implements IDeviceManagerService { @Override public DeferredResult addConsumer(String deviceId, String clientId) { - //修改为通过websocket下发给app + //修改为通过websocket下发给app DeferredResult result = new DeferredResult<>(0L); String uid = AuthUtil.getUserId(); DeviceInfo deviceInfo = deviceInfoData.findByDeviceId(deviceId); @@ -297,6 +401,7 @@ public class DeviceManagerServiceImpl implements IDeviceManagerService { @Override public boolean addGroup(DeviceGroup group) { group.setUid(AuthUtil.getUserId()); + group.setId(String.valueOf(Instant.now().toEpochMilli())); if (deviceGroupData.findById(group.getId()) != null) { throw new BizException(ErrCode.GROUP_ALREADY); } @@ -445,18 +550,71 @@ public class DeviceManagerServiceImpl implements IDeviceManagerService { @Override public boolean saveDevice(DeviceInfoBo data) { DeviceInfo di = data.to(DeviceInfo.class); + if (ObjectUtil.isNotNull(data.getGroupId()) && !data.getGroupId().equals("{}")) { + di.getGroup().put(data.getGroupId(), new DeviceInfo.Group( + data.getGroupId(), data.getDeviceId())); + } di.setLocate(new DeviceInfo.Locate(data.getLongitude(), data.getLatitude())); if (StringUtils.isBlank(data.getSecret())) { data.setSecret(RandomStringUtils.random(16)); } + SysDept sysDept = new SysDept(); + if (ObjectUtil.isNotNull(data.getDeptAreaId())) { + sysDept = iSystemData.findById(data.getDeptAreaId()); + } + if (ObjectUtil.isNotNull(sysDept)) { + + di.setTenantId(sysDept.getTenantId()); + } + if (LoginHelper.isSuperAdmin() && TenantHelper.getTenantId() == 0) { + if (ObjectUtil.isNotNull(sysDept)) { + di.setTenantId(sysDept.getTenantId()); + } + }/*else if(LoginHelper.isSuperAdmin() && TenantHelper.getTenantId() != 0) { + + }*//*else if(ObjectUtil.isNotNull(data.getTenantId())){ + di.setTenantId(data.getTenantId()); + }*/ + //deviceName不可重复 DeviceInfo deviceRepetition = deviceInfoData.findByDeviceName(data.getDeviceName()); if (deviceRepetition != null && !deviceRepetition.getDeviceId().equals(di.getDeviceId())) { throw new BizException(ErrCode.MODEL_DEVICE_ALREADY); } + if(ObjectUtil.isNotNull(deviceRepetition.getState())) { + di.setState(deviceRepetition.getState()); + } + /* if(ObjectUtil.isNotNull(data.getGroup())){ + + }*/ + // iSystemData.findById(); + TenantHelper.enableIgnore(); return deviceInfoData.save(di) != null; } @Override + public boolean saveDevice1(DeviceInfoBo data) { + + DeviceInfo di = new DeviceInfo(); + if(ObjectUtil.isNull(data) || ObjectUtil.isNull(data.getId())){ + fail("修改失败"); + } + DeviceInfo deviceInfo = deviceInfoData.findByDeviceId(data.getId()); + if(ObjectUtil.isEmpty(deviceInfo)){ + fail("设备不存在"); + } + + deviceInfo.setSite(data.getSite()); + // DeviceInfo.Locate locate = deviceInfo.getLocate(); + /* deviceInfo.getLocate().setLatitude(deviceInfo.getLatitude()); + deviceInfo.getLocate().setLongitude(deviceInfo.getLongitude());*/ + + deviceInfo.setDeptAreaId(data.getDeptAreaId()); + // di.setId(data.getId()); + + TenantHelper.enableIgnore(); + return deviceInfoData.save(deviceInfo) != null; + } + @Override public boolean editDeviceInfo(DeviceInfoBo data) { String uid = AuthUtil.getUserId(); data.setUid(uid); @@ -466,37 +624,93 @@ public class DeviceManagerServiceImpl implements IDeviceManagerService { if (StringUtils.isBlank(data.getSecret())) { data.setSecret(RandomStringUtils.random(16)); } + di.setState(null); //deviceName不可重复 DeviceInfo deviceRepetition = deviceInfoData.findByDeviceName(data.getDeviceName()); if (deviceRepetition != null && !deviceRepetition.getDeviceId().equals(di.getDeviceId())) { throw new BizException(ErrCode.MODEL_DEVICE_ALREADY); } - if(ObjectUtil.isNotNull(deviceRepetition.getUid()) && !deviceRepetition.getUid().equals(di.getUid())){ + if (ObjectUtil.isNotNull(deviceRepetition.getUid()) && !deviceRepetition.getUid().equals(di.getUid())) { throw new BizException("设备已绑定"); } return deviceInfoData.save(di) != null; } + @Override - public boolean editBandDeviceInfo(DeviceInfoBo data) { + public Long editBandDeviceInfo(DeviceInfoBo data) { String uid = AuthUtil.getUserId(); data.setUid(uid); - - DeviceInfo di = data.to(DeviceInfo.class); + TenantContext.disableTenantFilter(); + /* DeviceInfo di = data.to(DeviceInfo.class); di.setLocate(new DeviceInfo.Locate(data.getLongitude(), data.getLatitude())); if (StringUtils.isBlank(data.getSecret())) { data.setSecret(RandomStringUtils.random(16)); - } + }*/ //deviceName不可重复 DeviceInfo deviceRepetition = deviceInfoData.findByDeviceName(data.getDeviceName()); if (deviceRepetition == null || ObjectUtil.isEmpty(deviceRepetition)) { - throw new BizException(ErrCode.DEVICE_NOT_FOUND); + + fail(ErrCode.DEVICE_NOT_FOUND); } - if(ObjectUtil.isNotNull(deviceRepetition.getUid()) && !deviceRepetition.getUid().equals(di.getUid())){ - throw new BizException(ErrCode.DEVICE_HAS_ASSOCIATED); + deviceRepetition = deviceInfoData.findByDeviceId(deviceRepetition.getId()); + + if (ObjectUtil.isNull(deviceRepetition.getTenantId())) { + fail("租户未指定"); } - di.setId(deviceRepetition.getId()); - return deviceInfoData.save(di) != null; + if (ObjectUtil.isNotNull(deviceRepetition.getUid()) && !"".equals(deviceRepetition.getUid()) && !deviceRepetition.getUid().equals(data.getUid())) { + // throw new BizException(ErrCode.DEVICE_HAS_ASSOCIATED); + fail(ErrCode.DEVICE_HAS_ASSOCIATED); + } + deviceRepetition.setUid(uid); + deviceRepetition.setName(data.getName()); + UserInfo userInfo = new UserInfo(); + if (ObjectUtil.isNotNull(LoginHelper.getUserId())) { + userInfo = iUserInfoData.findById(LoginHelper.getUserId()); + } + TenantHelper.enableIgnore(); + if (ObjectUtil.isNotNull(userInfo)) { + Long count = deviceInfoData.countByUid(AuthUtil.getUserId()); + if (count == 0 || ObjectUtil.isNull(userInfo.getTenantId()) || userInfo.getTenantId() == 0) { + //把客户切换到绑定设备的租户下 + LoginHelper.getLoginUser().setTenantId(deviceRepetition.getTenantId()); + LoginHelper.setTenantId(deviceRepetition.getTenantId()); + TenantHelper.setDynamic(deviceRepetition.getTenantId()); + userInfo.setTenantId(deviceRepetition.getTenantId()); + userInfo.setDeptAreaId(deviceRepetition.getDeptAreaId()); + iUserInfoData.save(userInfo); + } else { + if (!userInfo.getTenantId().equals(deviceRepetition.getTenantId())) { + fail("设备租户不一致"); + } + } + + + } else { + fail("未找到该用户"); + } + if (ObjectUtil.isNotNull(data.getDeviceInstallInfo())) { + data.getDeviceInstallInfo().setUid(uid); + data.getDeviceInstallInfo().setTenantId(deviceRepetition.getTenantId()); + deviceRepetition.setSite(data.getDeviceInstallInfo().getCommunityName() + + data.getDeviceInstallInfo().getBuildingUnit() + + data.getDeviceInstallInfo().getRoomNo()); + // deviceRepetition.getLocate().setLatitude(deviceRepetition.getLatitude()); + // deviceRepetition.getLocate().setLongitude(deviceRepetition.getLongitude()); + DeviceInstallInfo deviceRepetition1 = iDeviceInstallInfoData.findByDeviceNameAndUidAndState(deviceRepetition.getDeviceName(), uid,0); + if (deviceRepetition1 != null) { + throw new BizException("安装信息已存在"); + } + data.getDeviceInstallInfo().setState(0); + data.getDeviceInstallInfo().setId(DeviceUtil.newDeviceId(uid)); + iDeviceInstallInfoData.save(data.getDeviceInstallInfo()); + } + + // di.setId(deviceRepetition.getId()); + + deviceInfoData.save(deviceRepetition); + return userInfo.getTenantId(); } + @SneakyThrows @Override public String importGroup(MultipartFile file) { diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/ProductServiceImpl.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/ProductServiceImpl.java index eb710ab..85ce9b4 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/ProductServiceImpl.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/ProductServiceImpl.java @@ -31,6 +31,7 @@ import cc.iotkit.common.oss.entity.UploadResult; import cc.iotkit.common.oss.factory.OssFactory; import cc.iotkit.common.utils.JsonUtils; import cc.iotkit.common.utils.MapstructUtils; +import cc.iotkit.data.config.TenantContext; import cc.iotkit.data.manager.*; import cc.iotkit.manager.config.AliyunConfig; import cc.iotkit.manager.dto.bo.category.CategoryBo; @@ -40,6 +41,7 @@ import cc.iotkit.manager.dto.bo.product.ProductBo; import cc.iotkit.manager.dto.bo.productmodel.ProductModelBo; import cc.iotkit.manager.dto.bo.thingmodel.ThingModelBo; import cc.iotkit.manager.dto.vo.category.CategoryVo; +import cc.iotkit.manager.dto.vo.deviceinfo.DeviceInfoVo; import cc.iotkit.manager.dto.vo.product.IconTypeVo; import cc.iotkit.manager.dto.vo.product.IconVo; import cc.iotkit.manager.dto.vo.product.ProductVo; @@ -47,6 +49,7 @@ import cc.iotkit.manager.dto.vo.productmodel.ProductModelVo; import cc.iotkit.manager.dto.vo.thingmodel.ThingModelVo; import cc.iotkit.manager.service.DataOwnerService; import cc.iotkit.manager.service.IProductService; +import cc.iotkit.model.device.DeviceInfo; import cc.iotkit.model.product.*; import cc.iotkit.temporal.IDbStructureData; import cn.hutool.core.lang.UUID; @@ -61,6 +64,7 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; +import java.time.Instant; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -221,11 +225,19 @@ public class ProductServiceImpl implements IProductService { @Override public boolean editCategory(CategoryBo req) { Category cate = req.to(Category.class); + + cate.setCreateAt(System.currentTimeMillis()); + categoryData.save(cate); + return true; + } + @Override + public boolean saveCategory(CategoryBo req) { + Category cate = req.to(Category.class); + cate.setId(String.valueOf(Instant.now().toEpochMilli())); cate.setCreateAt(System.currentTimeMillis()); categoryData.save(cate); return true; } - @Override @SneakyThrows public String uploadImg(String productKey, MultipartFile file) { @@ -246,6 +258,7 @@ public class ProductServiceImpl implements IProductService { @Override public Paging selectPageList(PageRequest request) { + Paging result =productData.findAll(request.to(Product.class)).to(ProductVo.class); for (ProductVo row : result.getRows()) { if(ObjectUtil.isNotNull(row.getIconId())){ @@ -254,6 +267,10 @@ public class ProductServiceImpl implements IProductService { } return result; } + @Override + public List selectPageList(ProductBo request) { + return MapstructUtils.convert(productData.findAllByCondition(request.to(Product .class)), ProductVo .class); + } @Override public Paging selectCategoryPageList(PageRequest request) { diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/RuleEngineServiceImpl.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/RuleEngineServiceImpl.java index db2fe28..ad4cd5d 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/RuleEngineServiceImpl.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/RuleEngineServiceImpl.java @@ -30,8 +30,14 @@ import cc.iotkit.common.exception.BizException; import cc.iotkit.common.satoken.utils.AuthUtil; import cc.iotkit.common.utils.MapstructUtils; import cc.iotkit.common.utils.ReflectUtil; +import cc.iotkit.data.dao.RuleInfoRepository; import cc.iotkit.data.manager.IRuleInfoData; import cc.iotkit.data.manager.ITaskInfoData; +import cc.iotkit.data.model.QTbRuleInfo; +import cc.iotkit.data.model.TbDeviceDetectorInfo; +import cc.iotkit.data.model.TbRuleInfo; +import cc.iotkit.data.util.PredicateBuilder; +import cc.iotkit.manager.dto.bo.device.DeviceDetectorQueryBo; import cc.iotkit.manager.dto.bo.ruleinfo.RuleInfoBo; import cc.iotkit.manager.dto.bo.ruleinfo.RuleLogBo; import cc.iotkit.manager.dto.bo.taskinfo.TaskInfoBo; @@ -42,6 +48,7 @@ import cc.iotkit.manager.dto.vo.taskinfo.TaskInfoVo; import cc.iotkit.manager.dto.vo.taskinfo.TaskLogVo; import cc.iotkit.manager.service.DataOwnerService; import cc.iotkit.manager.service.IRuleEngineService; +import cc.iotkit.model.device.DeviceDetectorInfo; import cc.iotkit.model.rule.RuleInfo; import cc.iotkit.model.rule.RuleLog; import cc.iotkit.model.rule.TaskInfo; @@ -50,15 +57,25 @@ import cc.iotkit.ruleengine.rule.RuleManager; import cc.iotkit.ruleengine.task.TaskManager; import cc.iotkit.temporal.IRuleLogData; import cc.iotkit.temporal.ITaskLogData; +import cn.hutool.core.util.ObjectUtil; +import com.querydsl.core.types.Predicate; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.IteratorUtils; import org.apache.commons.lang3.StringUtils; import org.quartz.SchedulerException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Iterator; +import java.util.List; import java.util.UUID; +import static cc.iotkit.data.model.QTbDeviceDetectorInfo.tbDeviceDetectorInfo; +import static cc.iotkit.data.model.QTbRuleInfo.tbRuleInfo; + /** * @Author: jay * @Date: 2023/5/30 18:15 @@ -75,7 +92,8 @@ public class RuleEngineServiceImpl implements IRuleEngineService { @Autowired private IRuleInfoData ruleInfoData; - + @Autowired + private RuleInfoRepository ruleInfoRepository; @Autowired private IRuleLogData ruleLogData; @@ -103,7 +121,28 @@ public class RuleEngineServiceImpl implements IRuleEngineService { return MapstructUtils.convert(ruleInfoData.findByUidAndType(AuthUtil.getUserId(), type, page, size), RuleInfoVo.class); } } + @Override + public List selectPageList1(PageRequest request) { + RuleInfoBo data = request.getData(); + + Iterator iterator = ruleInfoRepository.findAll(buildQueryCondition(data)).iterator(); + return MapstructUtils.convert(IteratorUtils.toList(iterator), RuleInfo.class); + //ruleInfoData.findAllByCondition(request.getData()) + } + private Predicate buildQueryCondition(RuleInfoBo dictData) { + PredicateBuilder predicate = PredicateBuilder.instance(); + if (dictData.getType() != null && dictData.getType() != null) { + // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + // LocalDateTime startDateTime = LocalDateTime.parse(dictData.getStartTime() , formatter); + // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + // LocalDateTime dateTime = LocalDateTime.parse(dictData.getEndTime(), formatter); + predicate.and(true, () -> tbRuleInfo.type.eq(dictData.getType())); + // predicate.and(ObjectUtil.isNotNull(dictData.getTenantId()), () -> tbRuleInfo.tenantId.eq(dictData.getTenantId())); + } + // predicate.and(ObjectUtil.isNotNull(dictData.getDeviceId()), () -> tbDeviceDetectorInfo.deviceId.eq(dictData.getDeviceId())); + return predicate.build(); + } @Override public boolean saveRule(RuleInfoBo ruleInfoBo) { RuleInfo rule = ruleInfoBo.to(RuleInfo.class); @@ -130,7 +169,7 @@ public class RuleEngineServiceImpl implements IRuleEngineService { ruleInfo.setActions(rule.getActions()); ruleInfo.setName(rule.getName()); ruleInfo.setDesc(rule.getDesc()); - + ruleInfo.setTenantId(rule.getTenantId()); ruleInfoData.save(ruleInfo); } return true; diff --git a/iot-module/iot-message-notify/src/main/java/cc/iotkit/message/model/Message.java b/iot-module/iot-message-notify/src/main/java/cc/iotkit/message/model/Message.java index 55cdcb4..4156bb4 100644 --- a/iot-module/iot-message-notify/src/main/java/cc/iotkit/message/model/Message.java +++ b/iot-module/iot-message-notify/src/main/java/cc/iotkit/message/model/Message.java @@ -48,7 +48,9 @@ public class Message implements Serializable { private String channel; private String channelConfig; private Long alertConfigId; - + private Long tenantId; + private String uid; + private String deviceId; public String getFormatContent() { String fmt = content; for (String key : param.keySet()) { diff --git a/iot-module/iot-message-notify/src/main/java/cc/iotkit/message/service/MessageService.java b/iot-module/iot-message-notify/src/main/java/cc/iotkit/message/service/MessageService.java index 9e5438d..e2b9596 100644 --- a/iot-module/iot-message-notify/src/main/java/cc/iotkit/message/service/MessageService.java +++ b/iot-module/iot-message-notify/src/main/java/cc/iotkit/message/service/MessageService.java @@ -43,6 +43,7 @@ public class MessageService { private ApplicationEventPublisher applicationEventPublisher; public void sendMessage(Message message) { + applicationEventPublisher.publishEvent(new MessageEvent(message)); } diff --git a/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/PluginMainImpl.java b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/PluginMainImpl.java index 0220a53..af2bda3 100644 --- a/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/PluginMainImpl.java +++ b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/PluginMainImpl.java @@ -46,6 +46,7 @@ import cc.iotkit.plugin.core.thing.actions.down.PropertySet; import cc.iotkit.plugin.core.thing.actions.down.ServiceInvoke; import cc.iotkit.plugin.main.script.PluginScriptServer; import cc.iotkit.script.IScriptEngine; +import cn.hutool.core.util.ObjectUtil; import com.gitee.starblues.integration.user.PluginUser; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -73,7 +74,6 @@ public class PluginMainImpl implements IPluginMain, DeviceService { @Autowired @Qualifier("productDataCache") IProductData productData; - @Autowired @Qualifier("deviceInfoDataCache") private IDeviceInfoData deviceInfoData; @@ -84,8 +84,8 @@ public class PluginMainImpl implements IPluginMain, DeviceService { @Autowired private PluginUser pluginUser; - @Autowired - private IThingService thingService; + /* @Autowired + private IThingService thingService;*/ @Autowired private MqProducer producer; @@ -187,16 +187,39 @@ public class PluginMainImpl implements IPluginMain, DeviceService { break; case ThingService.TYPE_CONFIG: + Map map = (Map) service.getParams(); // 下发配置: - DeviceConfig actionConfigSet = DeviceConfig.builder() - .id(service.getMid()) - .productKey(linkPk) - .deviceName(linkDn) - .config((Map) service.getParams()) - .build(); - //调用插件设备服务接口 - result = deviceService.config(actionConfigSet); - publish(service, deviceInfo.getDeviceId(), result.getCode()); + if ("set".equals(identifier)) { + System.out.println("config++++++++++++++++++++" + identifier); + DeviceConfig actionConfigSet = DeviceConfig.builder() + .id(service.getMid()) + .productKey(linkPk) + .deviceName(linkDn) + .module("set") + .config(map) + .build(); + //调用插件设备服务接口 + result = deviceService.config(actionConfigSet); + /* if(!map.isEmpty() && ObjectUtil.isNotNull(map.get("card"))){ + map.put("card", "card" + map.get("card")); + }*/ + publish(service, deviceInfo.getDeviceId(), result.getCode()); + }else if ("get".equals(identifier)) { + System.out.println("configget++++++++++++++++++++" + identifier); + DeviceConfig actionConfigSet = DeviceConfig.builder() + .id(service.getMid()) + .productKey(linkPk) + .deviceName(linkDn) + .module("get") + .config(map) + .build(); + //调用插件设备服务接口 + result = deviceService.config(actionConfigSet); + /* if(!map.isEmpty() && ObjectUtil.isNotNull(map.get("card"))){ + map.put("card", "card" + map.get("card")); + }*/ + publish(service, deviceInfo.getDeviceId(), result.getCode()); + } break; default: break; diff --git a/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/ThingServiceImpl.java b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/ThingServiceImpl.java index 2ac77ed..e91472d 100644 --- a/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/ThingServiceImpl.java +++ b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/ThingServiceImpl.java @@ -26,29 +26,44 @@ package cc.iotkit.plugin.main; import cc.iotkit.common.constant.Constants; import cc.iotkit.common.enums.ErrCode; import cc.iotkit.common.exception.BizException; +import cc.iotkit.common.redis.utils.RedisUtils; +import cc.iotkit.common.thing.DeviceService; import cc.iotkit.common.thing.ThingModelMessage; +import cc.iotkit.common.thing.ThingService; import cc.iotkit.common.utils.DeviceUtil; import cc.iotkit.common.utils.JsonUtils; import cc.iotkit.common.utils.StringUtils; import cc.iotkit.common.utils.UniqueIdUtil; -import cc.iotkit.data.manager.IDeviceInfoData; -import cc.iotkit.data.manager.IProductData; +import cc.iotkit.data.manager.*; +import cc.iotkit.model.device.DeviceDetectorInfo; import cc.iotkit.model.device.DeviceInfo; +import cc.iotkit.model.iccid.DIccidRecordDO; import cc.iotkit.model.product.Product; import cc.iotkit.mq.MqProducer; import cc.iotkit.plugin.core.thing.IThingService; import cc.iotkit.plugin.core.thing.actions.*; +import cc.iotkit.plugin.core.thing.actions.down.DeviceConfig; import cc.iotkit.plugin.core.thing.actions.up.*; import cc.iotkit.plugin.core.thing.model.ThingDevice; import cc.iotkit.plugin.core.thing.model.ThingProduct; +import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjectUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.RandomStringUtils; +import org.redisson.api.RMap; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Service; +import javax.annotation.security.PermitAll; +import java.time.LocalDateTime; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +import static cc.iotkit.common.redis.utils.RedisUtils.setCacheMapValue; +import static com.ibm.icu.impl.Assert.fail; /** * @author sjg @@ -67,9 +82,16 @@ public class ThingServiceImpl implements IThingService { @Autowired private MqProducer producer; - + @Autowired + private DeviceService deviceService; @Autowired private DeviceRouter deviceRouter; + @Autowired + private IDeviceConfigData idDeviceConfigData; + @Autowired + private IDIccidRecordData idIccidRecordData; + @Autowired + private IDeviceDetectorInfoData iDeviceDetectorInfoData; @Override public ActionResult post(String pluginId, IDeviceAction action) { @@ -77,14 +99,14 @@ public class ThingServiceImpl implements IThingService { log.info("receive plugin:{}, action:{}", pluginId, action); String deviceName = action.getDeviceName(); - if(!"NONE".equals(pluginId)){ + if (!"NONE".equals(pluginId)) { //添加设备路由 deviceRouter.putRouter(deviceName, new PluginRouter(IPluginMain.MAIN_ID, pluginId)); } long lastTime = System.currentTimeMillis(); DeviceInfo device = getDeviceInfo(deviceName); - DeviceStateChange deviceInfo = ((DeviceStateChange) action); - if(ObjectUtil.isNotNull(deviceInfo.getState())){ + // DeviceStateChange deviceInfo = ((DeviceStateChange) action); + /* if(ObjectUtil.isNotNull(deviceInfo.getState())){ if (deviceInfo.getState().equals(DeviceState.ONLINE)) { device.getState().setOnline(true); device.getState().setOnlineTime(System.currentTimeMillis()); @@ -92,14 +114,19 @@ public class ThingServiceImpl implements IThingService { device.getState().setOnline(false); device.getState().setOfflineTime(System.currentTimeMillis()); } - } + }*/ if (Objects.isNull(device)) { log.warn("device:{} is not found.", deviceName); - }else { + } else { deviceUpdateLastTime(device, lastTime); } ActionType type = action.getType(); + + log.warn("type:{} is not found.", type); + System.out.println("type+++++++++++++++++++++" + type); + System.out.println("action+++++++++++++++++++++" + action); + System.out.println("device+++++++++++++++++++++" + device); switch (type) { case REGISTER: //设备注册 @@ -115,6 +142,10 @@ public class ThingServiceImpl implements IThingService { subRegisterDevice(pluginId, device, (SubDeviceRegister) action); break; case STATE_CHANGE: + //状态变更 + if (ObjectUtil.isNull(device)) { + break; + } deviceStateChange(device, (DeviceStateChange) action); //父设备ID不为空说明是子设备 if (Objects.isNull(device.getParentId())) { @@ -126,12 +157,13 @@ public class ThingServiceImpl implements IThingService { Boolean transparent = product.getTransparent(); //透传设备父设备上线,子设备也上线。非透传设备父设备离线,子设备才离线 if (transparent != null && transparent || !((DeviceStateChange) action).getState().equals(DeviceState.ONLINE)) { - deviceStateChange(subDevice, (DeviceStateChange)action); + deviceStateChange(subDevice, (DeviceStateChange) action); } } } break; case EVENT_REPORT: + //事件上报 EventReport eventReport = (EventReport) action; publishMsg( device, action, @@ -144,6 +176,7 @@ public class ThingServiceImpl implements IThingService { ); break; case PROPERTY_REPORT: + //属性上报 PropertyReport propertyReport = (PropertyReport) action; publishMsg( device, action, @@ -155,8 +188,14 @@ public class ThingServiceImpl implements IThingService { .occurred(propertyReport.getTime()) .build() ); + //根据事件变更设备状态,如果是浓度需要额外添加到指定表 + Map map = propertyReport.getParams(); + deviceStatusUpdate(device, map); + break; + case SERVICE_REPLY: + //服务 ServiceReply serviceReply = (ServiceReply) action; publishMsg( device, action, @@ -174,6 +213,19 @@ public class ThingServiceImpl implements IThingService { case TOPOLOGY: deviceTopologyUpdate(device, (DeviceTopology) action); break; + case CONFIG: + //读取的配置 + DeviceConfig deviceConfig = (DeviceConfig) action; + deviceTopologyUpdate(device, deviceConfig); + publishMsg( + device, action, + ThingModelMessage.builder() + .type(ThingModelMessage.TYPE_CONFIG) + .data(deviceConfig.getConfig()) + .time(deviceConfig.getTime()) + .build() + ); + break; default: return ActionResult.builder().code(ErrCode.PARAMS_EXCEPTION.getKey()).build(); } @@ -186,11 +238,224 @@ public class ThingServiceImpl implements IThingService { } private void deviceUpdateLastTime(DeviceInfo device, long lastTime) { - deviceUpdateLastTime(device.getDeviceId(),lastTime); + deviceUpdateLastTime(device.getDeviceId(), lastTime); + } + + //根据属性传来的值更新设备状态 + private void deviceStatusUpdate(DeviceInfo device, Map map) { + //变更状态 + DeviceInfo.State state = device.getState(); + Integer status = ObjectUtil.isNotNull(device.getDeviceStatus()) ? device.getDeviceStatus() : 0; + if (!status.equals(1) && !status.equals(2)) { + device.setDeviceStatus(0); + } + //设备在线发生了故障或者报警 + if (state.isOnline()) { + if (isMapValid(map, "eventTypeValue")) { + if (map.get("eventTypeValue").toString().contains("寿命到期")) { + device.setDeviceStatus(4); + } + if (map.get("eventTypeValue").toString().contains("故障") && !map.get("eventTypeValue").toString().contains("故障恢复")) { + device.setDeviceStatus(1); + } else if (map.get("eventTypeValue").toString().contains("故障恢复")) { + device.setDeviceStatus(0); + } + if (map.get("eventTypeValue").toString().contains("警") && !map.get("eventTypeValue").toString().contains("正常") && !map.get("eventTypeValue").toString().contains("报警恢复")) { + //如果该区域有控制箱,设备发生告警发送控制箱控制 + try { + deviceLinkageControl(device); + }catch (Exception e){ + log.error("设备控制异常",e); + } + + device.setDeviceStatus(2); + } else if (map.get("eventTypeValue").toString().contains("报警恢复")) { + device.setDeviceStatus(0); + } + if (map.get("eventTypeValue").toString().contains("自检完成") || + map.get("eventTypeValue").toString().contains("预热完成") || + map.get("eventTypeValue").toString().contains("控制器复位") || + map.get("eventTypeValue").toString().contains("控制器开机")) { + device.setDeviceStatus(0); + } + } + } else { + if (!status.equals(1) && !status.equals(2)) { + device.setDeviceStatus(3); + } + } + + if (ObjectUtil.isNotNull(device.getDeviceStatus()) && !status.equals(device.getDeviceStatus())) { + deviceInfoData.save(device); + } + //存入浓度变化 + extractDetectorData(device, map); + + } + /** + * 设备告警,下发设备联动控制 + * */ + private void deviceLinkageControl(DeviceInfo device) { + List deviceInfo1 = new ArrayList<>(); + deviceInfo1 = getDeviceInfo(device.getDeptAreaId(),"MQFejp7cyDMH3enG"); + if(deviceInfo1 != null && !deviceInfo1.isEmpty()) { + for (DeviceInfo deviceInfo2 : deviceInfo1) { + if(ObjectUtil.isNotNull(deviceInfo2.getNodeOne()) && ObjectUtil.isNotNull(deviceInfo2.getNodeOneStatus()) && ObjectUtil.isNotNull(deviceInfo2.getNodeOneDevice())) { + if (deviceInfo2.getNodeOneStatus().equals("1")) { + //选中的任意一个设备报警就发送联动控制指令 + deviceLinkageControlSend(deviceInfo2, deviceInfo2.getNodeOne()); + }else{ + //满足所有的设备告警才触发联动控制 + String [] nodeOneDevice = deviceInfo2.getNodeOneDevice().split(","); + handleDeviceAlert(deviceInfo2,deviceInfo2.getNodeOne(),nodeOneDevice); + } + } + if(ObjectUtil.isNotNull(deviceInfo2.getNodeTwo()) && ObjectUtil.isNotNull(deviceInfo2.getNodeTwoStatus()) && ObjectUtil.isNotNull(deviceInfo2.getNodeTwoDevice())) { + //deviceLinkageControlSend(deviceInfo2,deviceInfo2.getNodeTwo()); + if (deviceInfo2.getNodeTwoStatus().equals("1")) { + //选中的任意一个设备报警就发送联动控制指令 + deviceLinkageControlSend(deviceInfo2, deviceInfo2.getNodeTwo()); + }else{ + //满足所有的设备告警才触发联动控制 + String [] nodeOneDevice = deviceInfo2.getNodeTwoDevice().split(","); + handleDeviceAlert(deviceInfo2,deviceInfo2.getNodeTwo(),nodeOneDevice); + } + } + if(ObjectUtil.isNotNull(deviceInfo2.getNodeThree()) && ObjectUtil.isNotNull(deviceInfo2.getNodeThreeStatus()) && ObjectUtil.isNotNull(deviceInfo2.getNodeThreeDevice())) { + // deviceLinkageControlSend(deviceInfo2,deviceInfo2.getNodeThree()); + if (deviceInfo2.getNodeThreeStatus().equals("1")) { + //选中的任意一个设备报警就发送联动控制指令 + deviceLinkageControlSend(deviceInfo2, deviceInfo2.getNodeThree()); + }else{ + //满足所有的设备告警才触发联动控制 + String [] nodeOneDevice = deviceInfo2.getNodeThreeDevice().split(","); + handleDeviceAlert(deviceInfo2,deviceInfo2.getNodeThree(),nodeOneDevice); + } + } + if(ObjectUtil.isNotNull(deviceInfo2.getNodeFour()) && ObjectUtil.isNotNull(deviceInfo2.getNodeFourStatus()) && ObjectUtil.isNotNull(deviceInfo2.getNodeFourDevice())) { + // deviceLinkageControlSend(deviceInfo2,deviceInfo2.getNodeFour()); + if (deviceInfo2.getNodeFourStatus().equals("1")) { + //选中的任意一个设备报警就发送联动控制指令 + deviceLinkageControlSend(deviceInfo2, deviceInfo2.getNodeFour()); + }else{ + //满足所有的设备告警才触发联动控制 + String [] nodeOneDevice = deviceInfo2.getNodeFourDevice().split(","); + handleDeviceAlert(deviceInfo2,deviceInfo2.getNodeFour(),nodeOneDevice); + } + } + if(ObjectUtil.isNotNull(deviceInfo2.getNodeFive()) && ObjectUtil.isNotNull(deviceInfo2.getNodeFiveStatus()) && ObjectUtil.isNotNull(deviceInfo2.getNodeFiveDevice())) { + // deviceLinkageControlSend(deviceInfo2,deviceInfo2.getNodeFive()); + if (deviceInfo2.getNodeFiveStatus().equals("1")) { + //选中的任意一个设备报警就发送联动控制指令 + deviceLinkageControlSend(deviceInfo2, deviceInfo2.getNodeFive()); + }else{ + //满足所有的设备告警才触发联动控制 + String [] nodeOneDevice = deviceInfo2.getNodeFiveDevice().split(","); + handleDeviceAlert(deviceInfo2,deviceInfo2.getNodeFive(),nodeOneDevice); + } + } + } + } + /* //下发联动控制箱控制输出 + send(device.getDeviceId(), device.getProductKey(), device.getDeviceName(), + Map.of( + "controlOutput", "1", + "outputValue", "1" + ), + ThingModelMessage.TYPE_SERVICE, ThingModelMessage.ID_ONLINE); + + DeviceConfig actionConfigSet = DeviceConfig.builder() + .id(service.getMid()) + .productKey(linkPk) + .deviceName(linkDn) + .module("set") + .config(map) + .build(); + //调用插件设备服务接口 + result = deviceService.config(actionConfigSet); + *//* if(!map.isEmpty() && ObjectUtil.isNotNull(map.get("card"))){ + map.put("card", "card" + map.get("card")); + }*//* + publish(service, deviceInfo.getDeviceId(), result.getCode());*/ + + } + + + + public void handleDeviceAlert(DeviceInfo deviceInfo,String node,String[] device) { + String ALERT_MAP_KEY = "device:alert:map" +":" +node; + // 记录设备告警状态 + setCacheMapValue(ALERT_MAP_KEY, deviceInfo.getDeviceName(), System.currentTimeMillis()); + + // 获取当前告警设备数 + RMap alertMap = RedisUtils.getClient().getMap(ALERT_MAP_KEY); + if (alertMap.size() >= device.length) { + deviceLinkageControlSend(deviceInfo,node); + // triggerCommand(new ArrayList<>(alertMap.keySet())); + alertMap.clear(); + } + } + + + private void deviceLinkageControlSend(DeviceInfo device,String node) { + ThingService thingService = ThingService.builder() + .mid(UniqueIdUtil.newRequestId()) + .productKey(device.getProductKey()) + .deviceName(device.getDeviceName()) + .type(ThingModelMessage.TYPE_CONFIG) + .identifier(ThingModelMessage.ID_CONFIG_SET) + .params(Map.of( + "controlOutput", node + "0001" + )) + .build(); + //联动控制箱下发指令 + deviceService.invoke(thingService); + } + //浓度变化 + public void extractDetectorData(DeviceInfo device, Map baseInfo) { + for (Map.Entry entry : baseInfo.entrySet()) { + if (entry.getKey().startsWith("dataDetectorValue")) { + String suffix = entry.getKey().substring(17); // 去掉前缀"dataDetectorValue" + String value = entry.getValue().toString(); + // 获取对应节点信息 + String nodeIdKey = "nodeId" + suffix; + String gasTypeKey = "gasType" + suffix; + DeviceDetectorInfo detectorInfo = new DeviceDetectorInfo(); + detectorInfo.setId(DeviceUtil.newDeviceId(device.getDeviceName())); + detectorInfo.setUid(device.getUid()); + detectorInfo.setTenantId(device.getTenantId()); + detectorInfo.setProductKey(device.getProductKey()); + detectorInfo.setDeviceId(device.getId()); + detectorInfo.setDeviceName(device.getDeviceName()); + detectorInfo.setDataDetectorValue(value); + if (ObjectUtil.isNotNull(baseInfo.get(nodeIdKey))) { + detectorInfo.setNode(baseInfo.get(nodeIdKey).toString()); + } + if (ObjectUtil.isNotNull(baseInfo.get(gasTypeKey))) { + detectorInfo.setGasTypeKey(baseInfo.get(gasTypeKey).toString()); + } + iDeviceDetectorInfoData.save(detectorInfo); +/* + System.out.println("NodeID: " + baseInfo.get(nodeIdKey) + + ", GasType: " + baseInfo.get(gasTypeKey) + + ", DetectorValue: " + value);*/ + } + } + } + + /** + * 检查Map是否非空且包含指定key + * + * @param map 待检查的Map + * @param key 需要检查的key + * @return 符合条件返回true + */ + public static boolean isMapValid(Map map, Object key) { + return map != null && !map.isEmpty() && map.containsKey(key) && map.get(key) != null; } private void deviceUpdateLastTime(String deviceId, long lastTime) { - deviceInfoData.setLastTime(deviceId,lastTime); + deviceInfoData.setLastTime(deviceId, lastTime); } @Override @@ -221,7 +486,14 @@ public class ThingServiceImpl implements IThingService { return null; } } - + public List getDeviceInfo(Long areaDeptId,String productKey) { + try { + return deviceInfoData.findByDeptAreaIdAndProductKey(areaDeptId,productKey); + } catch (Throwable e) { + log.error("get device error", e); + return null; + } + } @Override public ThingDevice getDevice(String dn) { DeviceInfo deviceInfo = getDeviceInfo(dn); @@ -249,7 +521,10 @@ public class ThingServiceImpl implements IThingService { private void deviceStateChange(DeviceInfo device, DeviceStateChange action) { DeviceState state = action.getState(); - if ( (device.getState().isOnline() && state.equals(DeviceState.ONLINE) || + if (ObjectUtil.isEmpty(device)) { + return; + } + if ((device.getState().isOnline() && state.equals(DeviceState.ONLINE) || (!device.getState().isOnline() && state.equals(DeviceState.OFFLINE)))) { return; } @@ -276,6 +551,40 @@ public class ThingServiceImpl implements IThingService { private String registerDevice(DeviceInfo device, DeviceRegister register, String parentId) { String productKey = register.getProductKey(); + Map params = register.getParams(); + try { + if (params != null && !params.isEmpty()) { + if (ObjectUtil.isNotNull(params.get("imei"))) { + DIccidRecordDO dIccidRecordDO = idIccidRecordData.findByImei(params.get("imei").toString()); + if (ObjectUtil.isEmpty(dIccidRecordDO)) { + dIccidRecordDO = new DIccidRecordDO(); + dIccidRecordDO.setIccid(params.get("iccid").toString()); + dIccidRecordDO.setImei(params.get("imei").toString()); + dIccidRecordDO.setState(0); + dIccidRecordDO.setSource(1); + dIccidRecordDO.setExpirationTime(LocalDateTime.now().plusDays(365)); + dIccidRecordDO.setValidDays(365); + idIccidRecordData.save(dIccidRecordDO); + } + } + } + } catch (Exception e) { + log.error("注册iccid error", e); + } + /* // 解析软件版本 (4字节) + byte[] versionBytes = new byte[4]; + buffer.get(versionBytes); + result.put("version", bytesToVersion(versionBytes)); + + // 解析通信模式 (1字节) + int commMode = buffer.get() & 0xFF; + result.put("communicationMode", commMode); + + // 解析信号强度 (1字节) + int signal = buffer.get() & 0xFF; + result.put("signalStrength", signal);*/ + + // idIccidRecordData.findById() //指定了pk需验证 if (StringUtils.isNotBlank(productKey)) { ThingProduct product = getProduct(productKey); @@ -285,15 +594,34 @@ public class ThingServiceImpl implements IThingService { } if (device != null) { + //随便写写 + if (params != null && !params.isEmpty()) { + if (ObjectUtil.isNotNull(params.get("signalStrength"))) { + device.setSignalStrength(params.get("signalStrength").toString()); + } + if (ObjectUtil.isNotNull(params.get("version"))) { + device.setDeviceVersion(params.get("version").toString()); + } + deviceInfoData.save(device); + } + log.info("device already registered"); if (parentId != null) { device.setParentId(parentId); deviceInfoData.save(device); } + if (productKey != null && device.getProductKey() != null + && !device.getProductKey().equals(productKey)) { + //防止设备变更了产品key + device.setProductKey(productKey); + // device.setModel(register.getModel()); + deviceInfoData.save(device); + } return device.getDeviceId(); } else { //不存在,注册新设备 DeviceInfo deviceInfo = new DeviceInfo(); + deviceInfo.setDeviceStatus(0); deviceInfo.setId(DeviceUtil.newDeviceId(register.getDeviceName())); deviceInfo.setDeviceId(deviceInfo.getId()); deviceInfo.setProductKey(productKey); @@ -302,8 +630,18 @@ public class ThingServiceImpl implements IThingService { deviceInfo.setParentId(parentId); deviceInfo.setSecret(RandomStringUtils.randomAlphabetic(16)); //默认离线 - deviceInfo.setState(new DeviceInfo.State(false, null, null)); + deviceInfo.setState(new DeviceInfo.State(true, null, null)); deviceInfo.setCreateAt(System.currentTimeMillis()); + // Map params = register.getParams(); + //随便写写 + if (params != null && !params.isEmpty()) { + if (ObjectUtil.isNotNull(params.get("signalStrength"))) { + deviceInfo.setSignalStrength(params.get("signalStrength").toString()); + } + if (ObjectUtil.isNotNull(params.get("version"))) { + deviceInfo.setDeviceVersion(params.get("version").toString()); + } + } deviceInfoData.save(deviceInfo); log.info("device registered:{}", JsonUtils.toJsonString(device)); @@ -358,6 +696,62 @@ public class ThingServiceImpl implements IThingService { } } + public static Map mergeMaps(Map primaryMap, + Map secondaryMap) { + Map result = new ConcurrentHashMap<>(); + // 先放入secondaryMap的所有条目 + result.putAll(secondaryMap); + // 遍历primaryMap,只添加secondaryMap中不存在的key + for (Map.Entry entry : primaryMap.entrySet()) { + if (!result.containsKey(entry.getKey())) { + result.put(entry.getKey(), entry.getValue()); + } + } + return result; + } + + private void deviceTopologyUpdate(DeviceInfo deviceInfo, DeviceConfig topology) { + //设备拓扑关系更新 + System.out.println("topology++++++++++++++++++++++++++++++++" + topology); + cc.iotkit.model.device.DeviceConfig config = idDeviceConfigData.findByDeviceName(topology.getDeviceName()); + if (config == null || ObjectUtil.isEmpty(config)) { + // DeviceInfo deviceInfo = deviceInfoData.findByDeviceName(topology.getDeviceName()); + if (ObjectUtil.isNotNull(deviceInfo)) { + cc.iotkit.model.device.DeviceConfig config1 = new cc.iotkit.model.device.DeviceConfig(); + config1.setDeviceName(topology.getDeviceName()); + config1.setProductKey(topology.getProductKey()); + config1.setConfig(topology.getConfig().toString()); + config1.setDeviceId(deviceInfo.getDeviceId()); + config1.setTenantId(deviceInfo.getTenantId()); + idDeviceConfigData.save(config1); + System.out.println("收到的配置mergedMap1++++++++++++++++++++++++++++++++" + config1); + } + // fail("设备未配置"); + } else { + if (ObjectUtil.isNull(config.getConfig())) { + fail("设备未配置"); + } + Map configMap = JsonUtils.parseObject(config.getConfig(), Map.class); + Map topologyMap = topology.getConfig(); + System.out.println("收到的配置config++++++++++++++++++++++++++++++++" + config); + Map map = new HashMap(); + if (ObjectUtil.isNull(topologyMap.get("key"))) { + return; + } + map.put(topologyMap.get("key"), topologyMap.get("value")); + System.out.println("收到的配置map++++++++++++++++++++++++++++++++" + map); + Map mergedMap = mergeMaps(configMap, map); + config.setConfig(JsonUtils.toJsonString(mergedMap)); + idDeviceConfigData.save(config); + System.out.println("收到的配置mergedMap++++++++++++++++++++++++++++++++" + mergedMap); + /* for (String deviceName : topology.getSubDevices()) { + DeviceInfo subDevice = getDeviceInfo(deviceName); + subDevice.setParentId(device.getDeviceId()); + deviceInfoData.save(subDevice); + }*/ + } + } + private void publishMsg(DeviceInfo device, IDeviceAction action, ThingModelMessage message) { try { message.setId(UUID.randomUUID().toString()); diff --git a/iot-module/iot-rule-engine/pom.xml b/iot-module/iot-rule-engine/pom.xml index 6c8f0e9..f2192bd 100644 --- a/iot-module/iot-rule-engine/pom.xml +++ b/iot-module/iot-rule-engine/pom.xml @@ -131,7 +131,22 @@ cc.iotkit iot-plugin-core - + + org.dromara.sms4j + sms4j-spring-boot-starter + 2.2.0 + + + com.aliyun + aliyun-java-sdk-core + 4.5.17 + compile + + + com.aliyun + aliyun-java-sdk-dyvmsapi + 3.0.2 + diff --git a/iot-module/iot-rule-engine/src/main/java/cc/iotkit/ruleengine/action/alert/AlertService.java b/iot-module/iot-rule-engine/src/main/java/cc/iotkit/ruleengine/action/alert/AlertService.java index 922a4cb..04006b3 100644 --- a/iot-module/iot-rule-engine/src/main/java/cc/iotkit/ruleengine/action/alert/AlertService.java +++ b/iot-module/iot-rule-engine/src/main/java/cc/iotkit/ruleengine/action/alert/AlertService.java @@ -57,6 +57,8 @@ public class AlertService extends ScriptService implements Serializable { log.warn("execScript result is null"); return "execScript result is null"; } + message.setUid(msg.getUid()); + message.setDeviceId(msg.getDeviceId()); message.setParam(result); messageService.sendMessage(message); return "ok"; diff --git a/iot-module/iot-rule-engine/src/main/java/cc/iotkit/ruleengine/config/CallRateLimiter.java b/iot-module/iot-rule-engine/src/main/java/cc/iotkit/ruleengine/config/CallRateLimiter.java new file mode 100644 index 0000000..00b4c9a --- /dev/null +++ b/iot-module/iot-rule-engine/src/main/java/cc/iotkit/ruleengine/config/CallRateLimiter.java @@ -0,0 +1,35 @@ +package cc.iotkit.ruleengine.config; + +import redis.clients.jedis.Jedis; +import redis.clients.jedis.Pipeline; +import redis.clients.jedis.Response; + +public class CallRateLimiter { + private static final String REDIS_KEY_PREFIX = "call:limit:"; + + private static final Jedis jedis = new Jedis("123.57.78.108",6379,10000); // 需配置实际Redis地址 + + public static boolean checkRateLimit(String calledNumber) { + String minuteKey = REDIS_KEY_PREFIX + "minute:" + calledNumber; + String hourKey = REDIS_KEY_PREFIX + "hour:" + calledNumber; + String dayKey = REDIS_KEY_PREFIX + "day:" + calledNumber; + jedis.auth("HMkj@2023"); + Pipeline pipeline = jedis.pipelined(); + Response minuteCount = pipeline.incr(minuteKey); + Response hourCount = pipeline.incr(hourKey); + Response dayCount = pipeline.incr(dayKey); + + pipeline.expire(minuteKey, 60); // 1分钟过期 + pipeline.expire(hourKey, 3600); // 1小时过期 + pipeline.expire(dayKey, 86400); // 24小时过期 + pipeline.sync(); + + return minuteCount.get() <= 1 && + hourCount.get() <= 5 && + dayCount.get() <= 20; + } + + public static void main(String[] args) { + System.out.println(CallRateLimiter.checkRateLimit("19118345694"));; + } +} diff --git a/iot-module/iot-rule-engine/src/main/java/cc/iotkit/ruleengine/expression/Expression.java b/iot-module/iot-rule-engine/src/main/java/cc/iotkit/ruleengine/expression/Expression.java index 269303d..b4c5d26 100644 --- a/iot-module/iot-rule-engine/src/main/java/cc/iotkit/ruleengine/expression/Expression.java +++ b/iot-module/iot-rule-engine/src/main/java/cc/iotkit/ruleengine/expression/Expression.java @@ -32,6 +32,7 @@ import org.apache.commons.io.IOUtils; import java.io.IOException; import java.nio.charset.Charset; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -52,6 +53,7 @@ public class Expression { COMPARATOR_MAP.put("<", "lt"); COMPARATOR_MAP.put("<=", "le"); COMPARATOR_MAP.put("!=", "neq"); + COMPARATOR_MAP.put("in", "in"); try { String script = IOUtils.resourceToString("script.js", Charset.defaultCharset(), Expression.class.getClassLoader()); engine.setScript(script); @@ -68,7 +70,25 @@ public class Expression { for (int i = 0; i < args.length; i++) { args[i] = convertIfNumeric(args[i]); } - + if ("in".equals(name)) { + if (args.length % 2 != 0) { + return false; + // throw new IllegalArgumentException("参数数量必须为偶数"); + } + for (int i = 0; i < args.length; i += 2) { + if (args[i].toString().contains(args[i+1].toString())) { + if(args[i].toString().contains("恢复") + || args[i].toString().contains("正常")){ + return false; + } + return true; + } + } + // 手动实现包含逻辑:ml-citation{ref="3,5" data="citationList"} + } + if ("in".equals(name)) { + return false; + } return engine.invokeMethod(new TypeReference<>() { }, name, args); } diff --git a/iot-module/iot-rule-engine/src/main/java/cc/iotkit/ruleengine/rule/RuleExecutor.java b/iot-module/iot-rule-engine/src/main/java/cc/iotkit/ruleengine/rule/RuleExecutor.java index bd23d32..463fde0 100644 --- a/iot-module/iot-rule-engine/src/main/java/cc/iotkit/ruleengine/rule/RuleExecutor.java +++ b/iot-module/iot-rule-engine/src/main/java/cc/iotkit/ruleengine/rule/RuleExecutor.java @@ -22,6 +22,8 @@ */ package cc.iotkit.ruleengine.rule; +import cc.iotkit.common.constant.Constants; +import cc.iotkit.common.constant.GlobalConstants; import cc.iotkit.common.thing.ThingModelMessage; import cc.iotkit.common.utils.JsonUtils; import cc.iotkit.data.manager.IAlertConfigData; @@ -33,6 +35,7 @@ import cc.iotkit.model.device.DeviceInfo; import cc.iotkit.model.rule.RuleLog; import cc.iotkit.model.worder.WorderDO; import cc.iotkit.ruleengine.action.Action; +import cc.iotkit.ruleengine.config.CallRateLimiter; import cc.iotkit.ruleengine.filter.Filter; import cc.iotkit.ruleengine.listener.Listener; import cc.iotkit.temporal.IRuleLogData; @@ -41,11 +44,24 @@ import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage; import cn.binarywang.wx.miniapp.config.impl.WxMaRedisBetterConfigImpl; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.RandomUtil; +import com.alibaba.fastjson.JSONObject; +import com.aliyuncs.DefaultAcsClient; +import com.aliyuncs.IAcsClient; +import com.aliyuncs.dyvmsapi.model.v20170525.SingleCallByTtsRequest; +import com.aliyuncs.dyvmsapi.model.v20170525.SingleCallByTtsResponse; +import com.aliyuncs.exceptions.ClientException; +import com.aliyuncs.profile.DefaultProfile; +import com.aliyuncs.profile.IClientProfile; import com.binarywang.spring.starter.wxjava.miniapp.properties.WxMaProperties; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.common.redis.RedisTemplateWxRedisOps; +import org.dromara.sms4j.api.SmsBlend; +import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.core.factory.SmsFactory; +import org.dromara.sms4j.provider.enumerate.SupplierType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.data.redis.core.StringRedisTemplate; @@ -83,6 +99,7 @@ public class RuleExecutor { private StringRedisTemplate stringRedisTemplate; // WxMpService 需要使用到,所以在 Servi @Resource private WxMaService wxMaService; + public void execute(ThingModelMessage message, Rule rule) { if (!doListeners(message, rule)) { log.info("The listener did not match the appropriate content,rule:{},{}", rule.getId(), rule.getName()); @@ -94,7 +111,7 @@ public class RuleExecutor { ruleLog.setId(UUID.randomUUID().toString()); ruleLog.setRuleId(rule.getId()); ruleLog.setState(RuleLog.STATE_MATCHED_LISTENER); - + DeviceInfo deviceInfo = iDeviceInfoData.findByDeviceId(message.getDeviceId()); try { if (!doFilters(rule, message)) { ruleLog.setState(RuleLog.STATE_UNMATCHED_FILTER); @@ -103,6 +120,9 @@ public class RuleExecutor { } ruleLog.setState(RuleLog.STATE_MATCHED_FILTER); + if (ObjectUtil.isNotNull(deviceInfo)) { + message.setUid(deviceInfo.getUid()); + } //执行动作返回执行内容 List results = doActions(rule, message); //保存动作内容和状态 @@ -118,44 +138,44 @@ public class RuleExecutor { // 注入 WxMaService 后直接调用 String appId = wxMaService.getWxMaConfig().getAppid(); System.out.println("当前小程序AppID: " + appId); + Map alertData = message.dataToMap(); + System.out.println("messagePushalertData+++++++++++++++++++++++++++++" + alertData); + // String alertData = processData(message); + // String deviceName = message.getDeviceName(); + try { + // DeviceInfo deviceInfo = iDeviceInfoData.findByDeviceId(message.getDeviceId()); + if (ObjectUtil.isNotNull(deviceInfo) && ObjectUtil.isNotNull(deviceInfo.getUid())) { + UserInfo userInfo = iUserInfoData.findById(Long.valueOf(deviceInfo.getUid())); + if (ObjectUtil.isNull(userInfo)) { + return; + } + List listAlertConfigs = iAlertConfigData.findByUidAndRuleInfoIdAndDeviceName(deviceInfo.getUid(), ruleLog.getRuleId(), deviceInfo.getDeviceName()); - String alertData = processData(message); - String deviceName=message.getDeviceName(); - try { - DeviceInfo deviceInfo = iDeviceInfoData.findByDeviceId(message.getDeviceId()); - if(ObjectUtil.isNotNull(deviceInfo) && ObjectUtil.isNotNull(deviceInfo.getUid())){ - UserInfo userInfo= iUserInfoData.findById(Long.valueOf(deviceInfo.getUid())); - List listAlertConfigs = iAlertConfigData.findByUidAndRuleInfoId(deviceInfo.getUid(), ruleLog.getRuleId()); - for (AlertConfig alertConfig : listAlertConfigs){ - String [] messagePush = alertConfig.getMessagePush().split(","); - for (int i = 0; i < messagePush.length; i++) { - switch (messagePush[i]){ - case "0": - //发送短信 - break; - case "1": - //发送微信小程序 - String openid = userInfo.getUid(); - Date date = new Date(message.getTime()); - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - Map map = new HashMap(); - map.put("openid",openid); - map.put("alertData", alertData); - map.put("deviceName", deviceName); - map.put("level",getSeverityLight(alertConfig.getLevel())); - map.put("time", sdf.format(date)); - messageReminder(map); - break; - case "2": - //语音 - break; - } - } + for (AlertConfig alertConfig : listAlertConfigs) { + if (ObjectUtil.isNotNull(alertConfig.getMessagePushIpone())) { + String[] messagePushIpone = alertConfig.getMessagePushIpone().split(","); + // System.out.println("messagePushIpone+++++++++++++++++++++++++++++" + messagePushIpone); + // System.out.println("messagePushIpone.length+++++++++++++++++++++++++++++" + messagePushIpone.length); + for (int i = 0; i < messagePushIpone.length; i++) { + if (isValid(messagePushIpone[i])) { + String[] messagePush = alertConfig.getMessagePush().split(","); + UserInfo userInfo1 = new UserInfo(); + userInfo1.setUserName(messagePushIpone[i]); + userInfo1.setUid(userInfo.getUid()); + sendMessage(messagePush, message, deviceInfo, userInfo1, alertData, alertConfig, i); + } + } - } + } else { + String[] messagePush = alertConfig.getMessagePush().split(","); + // System.out.println("messagePush+++++++++++++++++++++++++++++" + messagePush); + sendMessage(messagePush, message, deviceInfo, userInfo, alertData, alertConfig, 0); + } + } - } - }catch (Exception e){} + } + } catch (Exception e) { + } //进行报警 //告警配置中心的rule_info_id 根据这个与uid查询出对应的报警等级 ruleLog.getRuleId(); @@ -164,48 +184,177 @@ public class RuleExecutor { } } + public boolean isValid(String phone) { + return phone != null && phone.matches("^\\d{11}$"); + } + + public void sendMessage(String[] messagePush, + ThingModelMessage message, + DeviceInfo deviceInfo, + UserInfo userInfo, + Map alertData + , AlertConfig alertConfig, int j) throws ClientException { + + for (int i = 0; i < messagePush.length; i++) { + switch (messagePush[i]) { + case "0": + //发送短信 + try { + Date date = new Date(message.getTime()); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String templateId = "SMS_492470379"; + LinkedHashMap map = new LinkedHashMap<>(1); + /* if (ObjectUtil.isNotNull(deviceInfo.getName()) && !"".equals(deviceInfo.getName())) { + map.put("deviceName", deviceInfo.getName()); + } else {*/ + String site = ObjectUtil.isNotNull(deviceInfo.getSite()) ? deviceInfo.getSite() : "无"; + map.put("deviceName", deviceInfo.getDeviceName()); + map.put("deviceSite", site); + // } + map.put("time", sdf.format(date)); + if (ObjectUtil.isNotNull(alertData) && !alertData.isEmpty()) { + if (ObjectUtil.isNotNull(alertData.get("eventTypeValue"))) { + map.put("reason", alertData.get("eventTypeValue").toString()); + } + } else { + map.put("reason", "异常通知"); + } + SmsBlend smsBlend = SmsFactory.createSmsBlend(SupplierType.ALIBABA); + SmsResponse smsResponse = smsBlend.sendMessage(userInfo.getUserName(), templateId, map); + System.out.println("短信接口返回的数据:" + smsResponse); + /* if (!"OK".equals(smsResponse.getCode())) { + }*/ + } catch (Exception e) { + e.printStackTrace(); + } + break; + case "1": + //发送微信小程序 + try { + if (ObjectUtil.isNotNull(userInfo.getUid()) && j == 0) { + String openid = userInfo.getUid(); + Date date = new Date(message.getTime()); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Map map = new HashMap(); + map.put("openid", openid); + + if (ObjectUtil.isNotNull(alertData) && !alertData.isEmpty()) { + if (ObjectUtil.isNotNull(alertData.get("eventTypeValue"))) { + map.put("alertData", alertData.get("eventTypeValue")); + } + } else { + map.put("alertData", "设备通知"); + } + map.put("deviceName", deviceInfo.getDeviceName()); + map.put("level", getSeverityLight(alertConfig.getLevel())); + map.put("time", sdf.format(date)); + System.out.println("messagePushMap+++++++++++++++++++++++++++++" + map); + messageReminder(map); + } + } catch (Exception e) { + e.printStackTrace(); + } + break; + case "2": + if (!CallRateLimiter.checkRateLimit(userInfo.getUserName())) { + System.out.println("触发流控限制,停止呼叫"); + break; + } + //语音 + // 设置超时时间与产品域名 + IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", "LTAI5tRvZgzGtmvTgmL3Zxre", "FkHPDXJ8l3RRTRUqa4wDf8c3DIoZqI"); + DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", "Dysmsapi", "dysmsapi.aliyuncs.com"); + IAcsClient acsClient = new DefaultAcsClient(profile); + Map mapData = new HashMap(); + + /* if (ObjectUtil.isNotNull(deviceInfo.getName()) && !"".equals(deviceInfo.getName())) { + mapData.put("deviceName", deviceInfo.getName()); + } else {*/ + String site = ObjectUtil.isNotNull(deviceInfo.getSite()) ? deviceInfo.getSite() : "无"; + mapData.put("deviceName", deviceInfo.getDeviceName() + ",位于" + site); + //} + if (ObjectUtil.isNotNull(alertData) && !alertData.isEmpty()) { + if (ObjectUtil.isNotNull(alertData.get("eventTypeValue"))) { + mapData.put("reason", alertData.get("eventTypeValue").toString()); + } + } else { + mapData.put("reason", "异常通知"); + } + // "{ \"deviceName\": \"李白\", \"reason\": \"施工\" }" + // 组装请求对象 + SingleCallByTtsRequest request = new SingleCallByTtsRequest(); + // 使用UTF-8编码确保中文字符正常发送,注意替换下面的参数为实际值 + request.setRegionId("cn-hangzhou"); + request.setEndpoint("dyvmsapi.aliyuncs.com"); + request.setVersion("2017-05-25"); + request.setCalledNumber(userInfo.getUserName()); + request.setTtsCode("TTS_323100011"); + request.setTtsParam(new JSONObject(mapData).toString()); + request.setPlayTimes(2); + request.setSpeed(0); + try { + SingleCallByTtsResponse sendSmsResponse = acsClient.getAcsResponse(request); + System.out.println("语音接口返回的数据----------------"); + System.out.println("Code=" + sendSmsResponse.getCode()); + System.out.println("Message=" + sendSmsResponse.getMessage()); + System.out.println("RequestId=" + sendSmsResponse.getRequestId()); + + } catch (ClientException e) { + e.printStackTrace(); + } + break; + } + } + } public static String getSeverityLight(String level) { switch (level) { - case "1": return "严重"; // 严重 - case "2": return "紧急"; // 紧急 - case "3": return "较重"; // 较重 - case "4": return "一般"; // 一般 - case "5": return "提示"; // 提示 - default: return null; + case "1": + return "严重"; // 严重 + case "2": + return "紧急"; // 紧急 + case "3": + return "较重"; // 较重 + case "4": + return "一般"; // 一般 + case "5": + return "提示"; // 提示 + default: + return null; } //return null; } - public void messageReminder(Map map){ + + public void messageReminder(Map map) { try { //MemberUserDO memberUserDO = memberUserMapper.selectById(orDefault1.getMasteruser()); if (ObjectUtil.isNotNull(map)) { - //封装推送信息 - // wxMaSubMsgList组装示例,在业务里组装好,再调用系统消息发送工具,系统消息判断是否需要发送小程序订阅消息进行分发,此处不做展示 - ArrayList wxMaSubscribeData = new ArrayList<>(); - WxMaSubscribeMessage.MsgData thing13 = new WxMaSubscribeMessage.MsgData(); + //封装推送信息 + // wxMaSubMsgList组装示例,在业务里组装好,再调用系统消息发送工具,系统消息判断是否需要发送小程序订阅消息进行分发,此处不做展示 + ArrayList wxMaSubscribeData = new ArrayList<>(); + WxMaSubscribeMessage.MsgData thing13 = new WxMaSubscribeMessage.MsgData(); thing13.setName("thing13"); thing13.setValue(map.get("deviceName")); - wxMaSubscribeData.add(thing13); - WxMaSubscribeMessage.MsgData short_thing18 = new WxMaSubscribeMessage.MsgData(); - short_thing18.setName("short_thing18"); - short_thing18.setValue(map.get("level")); - wxMaSubscribeData.add(short_thing18); - WxMaSubscribeMessage.MsgData time7 = new WxMaSubscribeMessage.MsgData(); + wxMaSubscribeData.add(thing13); + WxMaSubscribeMessage.MsgData short_thing18 = new WxMaSubscribeMessage.MsgData(); + short_thing18.setName("short_thing18"); + short_thing18.setValue(map.get("level")); + wxMaSubscribeData.add(short_thing18); + WxMaSubscribeMessage.MsgData time7 = new WxMaSubscribeMessage.MsgData(); time7.setName("time7"); time7.setValue(map.get("time")); - wxMaSubscribeData.add(time7); - WxMaSubscribeMessage.MsgData thing11 = new WxMaSubscribeMessage.MsgData(); + wxMaSubscribeData.add(time7); + WxMaSubscribeMessage.MsgData thing11 = new WxMaSubscribeMessage.MsgData(); thing11.setName("thing11"); thing11.setValue(map.get("alertData")); - wxMaSubscribeData.add(thing11); + wxMaSubscribeData.add(thing11); - sendWechatAppSubMessage(map.get("openid"), - "formal", - "H89Wdr3oPVbEbe4kamZUKeCt7i5pqmDe2sfaOlvPqR0", - "\"pages/index/index\"", - wxMaSubscribeData); + sendWechatAppSubMessage(map.get("openid"), + "trial", + "2-pE7Xrx4XmTGIOZoTXE1iWt0cOY3obL-EYou8cOBXg", + "\"pages/index/index\"", + wxMaSubscribeData); } } catch (Exception e) { @@ -230,7 +379,7 @@ public class RuleExecutor { public void sendWechatAppSubMessage(String openId, String appletsSubType, String appSubTempId, String appSubPagePath, ArrayList wxMaSubMsgList) throws Exception { //AuthConfig - // WxMaService wxMaService = buildWxMaService("wx756050a3772987c8","4dc7df1922d7cf210ccbc086bc473de8"); + // WxMaService wxMaService = buildWxMaService("wx756050a3772987c8","4dc7df1922d7cf210ccbc086bc473de8"); // TODO:根据用户id获取OpenId,测试时写死 WxMaSubscribeMessage subscribeMessage = new WxMaSubscribeMessage(); // 要推送的用户openid @@ -244,21 +393,22 @@ public class RuleExecutor { // 消息列表(组装示例请看方法开始注释部分) subscribeMessage.setData(wxMaSubMsgList); try { + System.out.println("subscribeMessage+++++++++++++++++++++++++++++" + subscribeMessage); // 发送订阅消息 wxMaService.getMsgService().sendSubscribeMsg(subscribeMessage); } catch (Exception e) { } } - public static String processData(ThingModelMessage message) { - Map data = message.dataToMap(); - StringJoiner result = new StringJoiner("、"); - for (Map.Entry entry : data.entrySet()) { - result.add(entry.getKey() + "=" + entry.getValue()); - } + /* public static String processData(ThingModelMessage message) { + Map data = message.dataToMap(); + StringJoiner result = new StringJoiner("、"); + for (Map.Entry entry : data.entrySet()) { + result.add(entry.getKey() + "=" + entry.getValue()); + } - return result.toString(); - } + return result.toString(); + }*/ private boolean doListeners(ThingModelMessage message, Rule rule) { List> listeners = rule.getListeners(); for (Listener listener : listeners) { diff --git a/iot-module/iot-rule-engine/src/main/java/cc/iotkit/ruleengine/rule/RuleMessageHandler.java b/iot-module/iot-rule-engine/src/main/java/cc/iotkit/ruleengine/rule/RuleMessageHandler.java index fc06eba..25c12b5 100644 --- a/iot-module/iot-rule-engine/src/main/java/cc/iotkit/ruleengine/rule/RuleMessageHandler.java +++ b/iot-module/iot-rule-engine/src/main/java/cc/iotkit/ruleengine/rule/RuleMessageHandler.java @@ -24,20 +24,18 @@ package cc.iotkit.ruleengine.rule; import cc.iotkit.common.thing.ThingModelMessage; import cc.iotkit.ruleengine.action.Action; -import cc.iotkit.ruleengine.action.alert.AlertAction; import cc.iotkit.ruleengine.action.alert.AlertService; import cc.iotkit.ruleengine.handler.DeviceMessageHandler; import cc.iotkit.ruleengine.listener.DeviceCondition; import cc.iotkit.ruleengine.listener.Listener; -import org.apache.commons.lang3.SerializationUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.tomcat.util.digester.Rules; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -45,12 +43,16 @@ import java.util.regex.Pattern; @Component public class RuleMessageHandler implements DeviceMessageHandler { - private final Map> deviceRuleMap = new HashMap<>(); + private final ConcurrentMap> deviceRuleMap = new ConcurrentHashMap<>(); @Autowired private RuleExecutor ruleExecutor; + public RuleMessageHandler(ExecutorService executor) { + this.executor = executor; + } + public synchronized void putRule(Rule rule) { //先删除已经存在的规则 removeRule(rule.getId()); @@ -84,45 +86,131 @@ public class RuleMessageHandler implements DeviceMessageHandler { } } + // 使用并发安全的缓存结构 + private final ConcurrentMap ruleCache = new ConcurrentHashMap<>(1024); + private final ExecutorService executor; + private final AtomicInteger concurrentTasks = new AtomicInteger(0); + + public RuleMessageHandler() { + this.executor = new ThreadPoolExecutor( + Runtime.getRuntime().availableProcessors(), + Runtime.getRuntime().availableProcessors() * 2, + 60, TimeUnit.SECONDS, + new ArrayBlockingQueue<>(10000), + new ThreadPoolExecutor.CallerRunsPolicy()); + } + @Override public void handle(ThingModelMessage message) { + concurrentTasks.incrementAndGet(); + executor.execute(() -> { + try { + processMessage(message); + /* String pk = message.getProductKey(); + String dn = message.getDeviceName(); + List rules = new ArrayList<>(); + //仅用PK匹配 + List foundRules = deviceRuleMap.get(pk + "/#"); + if (foundRules != null) { + if (foundRules.get(0).getListeners().size() == 1) { + rules.add(foundRules.get(0)); + } else { + rules.addAll(foundRules); + } + } + //用PK和DN匹配 + foundRules = deviceRuleMap.get(pk + "/" + dn); + if (foundRules != null) { + if (foundRules.get(0).getListeners().size() == 1) { + rules.add(foundRules.get(0)); + } else { + rules.addAll(foundRules); + } + // rules.addAll(foundRules); + } + // 创建一个集合用于存储待删除的服务 + List servicesToRemove = new ArrayList<>(); + for (Rule rule : rules) { + clearUnmatchedScripts(rule, message, servicesToRemove); + ruleExecutor.execute(message, rule); + } + // 处理完所有规则后,恢复被删除的服务 + if (ObjectUtils.isNotEmpty(servicesToRemove)) + for (Rule rule : rules) { + restoreDeletedServices(rule, servicesToRemove); + }*/ + } finally { + concurrentTasks.decrementAndGet(); + } + }); + } + private void processMessage(ThingModelMessage message) { + // Rule[] rules = getRulesForMessage(message); + String pk = message.getProductKey(); String dn = message.getDeviceName(); List rules = new ArrayList<>(); //仅用PK匹配 List foundRules = deviceRuleMap.get(pk + "/#"); if (foundRules != null) { - if(foundRules.get(0).getListeners().size() == 1){ - rules.add(foundRules.get(0)); - }else{ + if (foundRules.get(0).getListeners().size() == 1) { + rules.add(foundRules.get(0)); + } else { rules.addAll(foundRules); } } //用PK和DN匹配 foundRules = deviceRuleMap.get(pk + "/" + dn); if (foundRules != null) { - if(foundRules.get(0).getListeners().size() == 1){ + if (foundRules.get(0).getListeners().size() == 1) { rules.add(foundRules.get(0)); - }else{ + } else { rules.addAll(foundRules); } - // rules.addAll(foundRules); + // rules.addAll(foundRules); } - // 创建一个集合用于存储待删除的服务 - List servicesToRemove = new ArrayList<>(); + + List tempServices = new ArrayList<>(rules.size()); + for (Rule rule : rules) { - clearUnmatchedScripts(rule, message,servicesToRemove); - ruleExecutor.execute(message, rule); + clearUnmatchedScripts(rule, message, tempServices); + ruleExecutor.execute(message, rule); } - // 处理完所有规则后,恢复被删除的服务 - for (Rule rule : rules) { - restoreDeletedServices(rule, servicesToRemove); + + if (!tempServices.isEmpty()) { + restoreServices(rules, tempServices); } } - public void clearUnmatchedScripts(Rule rule, ThingModelMessage message, List servicesToRemove) { + private Rule[] getRulesForMessage(ThingModelMessage message) { + String pk = message.getProductKey(); + String dn = message.getDeviceName(); + String cacheKey = pk + "/" + dn; + + return ruleCache.computeIfAbsent(cacheKey, k -> { + List rules = new ArrayList<>(4); + addMatchingRules(pk + "/#", rules); + addMatchingRules(cacheKey, rules); + return rules.toArray(new Rule[0]); + }); + } + + private void addMatchingRules(String key, List rules) { + Rule[] existing = ruleCache.get(key); + if (existing != null) { + Collections.addAll(rules, existing); + } + } + + private void restoreServices(List rules, List services) { + for (Rule rule : rules) { + restoreDeletedServices(rule, services); + } + } + + public void clearUnmatchedScripts(Rule rule, ThingModelMessage message, List servicesToRemove) { // 获取message中的data key集合 Set messageKeys = message.dataToMap().keySet(); @@ -153,6 +241,7 @@ public class RuleMessageHandler implements DeviceMessageHandler { } } } + public void restoreDeletedServices(Rule rule, List servicesToAdd) { // 创建服务副本避免修改原集合 // 将待添加的服务转换为列表保持顺序 diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/config/MinIoClientConfig.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/config/MinIoClientConfig.java deleted file mode 100644 index 364000e..0000000 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/config/MinIoClientConfig.java +++ /dev/null @@ -1,40 +0,0 @@ -package cc.iotkit.system.config; - -import io.minio.MinioClient; -import lombok.Data; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.stereotype.Component; - -@Data -@Component -@ConfigurationProperties(prefix = "minio") -public class MinIoClientConfig { - @Value("${minio.server}") - private String server; - @Value("${minio.port}") - private int port; - @Value("${minio.endpoint}") - private String endpoint; - @Value("${minio.access-key}") - private String accessKey; - @Value("${minio.secret-key}") - private String secretKey; - @Value("${minio.bucket}") - private String bucket; - - /** - * 创建minio连接对象 - * - * @return - */ - @Bean - public MinioClient minioClient() { - - return MinioClient.builder() - .endpoint(server, port,false) - .credentials(accessKey, secretKey) - .build(); - } -} diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/config/MinioUtil.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/config/MinioUtil.java deleted file mode 100644 index d9232a0..0000000 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/config/MinioUtil.java +++ /dev/null @@ -1,264 +0,0 @@ -package cc.iotkit.system.config; - -import cn.hutool.core.util.ObjectUtil; -import io.minio.*; -import io.minio.http.Method; -import io.minio.messages.Bucket; -import io.minio.messages.DeleteError; -import io.minio.messages.DeleteObject; -import io.minio.messages.Item; -import lombok.SneakyThrows; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.EnableAspectJAutoProxy; -import org.springframework.context.annotation.Lazy; -import org.springframework.stereotype.Component; -import org.springframework.web.multipart.MultipartFile; - -import java.io.InputStream; -import java.text.SimpleDateFormat; -import java.util.*; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -@Component -public class MinioUtil { - - @Autowired - @Lazy - private MinioClient minioClient; - @Value("${minio.bucket}") - // @Lazy - private String bucket; - - @Value("${minio.endpoint}") - // @Lazy - private String endpoint; - - /** - * description: 判断bucket是否存在,不存在则创建 - */ - @SneakyThrows - public boolean existBucket(String name) { - boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(name).build()); - if (!exists) { - minioClient.makeBucket(MakeBucketArgs.builder().bucket(name).build()); - } - return exists; - } - - /** - * 创建存储bucket - * - * @param bucketName 存储bucket名称 - * @return Boolean - */ - @SneakyThrows - public Boolean makeBucket(String bucketName) { - boolean exist = existBucket(bucketName); - if (!exist) { - minioClient.makeBucket(MakeBucketArgs.builder() - .bucket(bucketName) - .build()); - return true; - } - return false; - } - - /** - * 删除存储bucket - * - * @param bucketName 存储bucket名称 - * @return Boolean - */ - @SneakyThrows - public Boolean removeBucket(String bucketName) { - boolean exist = existBucket(bucketName); - if (!exist) return false; - - Iterable> results = - minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build()); - for (Result result : results) { - Item item = result.get(); - // 桶不为空不允许删除 - if (item.size() > 0) { - return false; - } - } - minioClient.removeBucket(RemoveBucketArgs.builder() - .bucket(bucketName) - .build()); - return true; - } - - /** - * 列出所有存储桶 - */ - @SneakyThrows - public List listBuckets() { - return minioClient.listBuckets(); - } - - /** - * 列出所有存储桶名称 - */ - public List listBucketNames() { - List bucketList = listBuckets(); - if (ObjectUtil.isEmpty(bucketList)) - return null; - List bucketListName = new ArrayList<>(); - for (Bucket bucket : bucketList) { - bucketListName.add(bucket.name()); - } - return bucketListName; - } - - /** - * 列出存储桶中的所有对象名称 - * - * @param bucketName 存储桶名称 - */ - @SneakyThrows - public List listObjectNames(String bucketName) { - boolean exist = existBucket(bucketName); - if (!exist) return null; - - List listObjectNames = new ArrayList<>(); - Iterable> results = - minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build()); - for (Result result : results) { - Item item = result.get(); - listObjectNames.add(item.objectName()); - } - return listObjectNames; - } - - /** - * 查看文件对象 - * - * @param bucketName 存储bucket名称 - * @return 存储bucket内文件对象信息 - */ - public Map listObjects(String bucketName) { - boolean exist = existBucket(bucketName); - if (!exist) return null; - - Iterable> results = - minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build()); - Map map = new HashMap<>(); - try { - for (Result result : results) { - Item item = result.get(); - map.put(item.objectName(), item); - } - } catch (Exception e) { - e.printStackTrace(); - return null; - } - return map; - } - - /** - * 文件访问路径 - * - * @param bucketName 存储桶名称 - * @param objectName 存储桶里的对象名称 - */ - @SneakyThrows - public String getObjectUrl(String bucketName, String objectName) { - boolean exist = existBucket(bucketName); - if (!exist) return null; - - return minioClient.getPresignedObjectUrl( - GetPresignedObjectUrlArgs.builder() - .method(Method.GET) - .bucket(bucketName) - .object(objectName) - .expiry(2, TimeUnit.MINUTES) - .build()); - } - - /** - * 删除一个对象 - * - * @param bucketName 存储桶名称 - * @param objectName 存储桶里的对象名称 - */ - @SneakyThrows - public boolean removeObject(String bucketName, String objectName) { - boolean exist = existBucket(bucketName); - if (!exist) return false; - - minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build()); - return true; - } - - /** - * 删除指定桶的多个文件对象 - * - * @param bucketName 存储桶名称 - * @param objectNames 含有要删除的多个object名称的迭代器对象 - */ - @SneakyThrows - public boolean removeObject(String bucketName, List objectNames) { - boolean exist = existBucket(bucketName); - if (!exist) return false; - - List objects = new LinkedList<>(); - for (String objectName : objectNames) { - objects.add(new DeleteObject(objectName)); - } - minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(objects).build()); - return true; - } - - /** - * 批量删除文件对象 - * - * @param bucketName 存储bucket名称 - * @param objects 对象名称集合 - */ - public Iterable> removeObjects(String bucketName, List objects) { - List dos = objects.stream().map(DeleteObject::new).collect(Collectors.toList()); - return minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(dos).build()); - } - - /** - * 文件上传 - */ - public String upload(MultipartFile multipartFile) { - String fileName = multipartFile.getOriginalFilename(); - // 注意,这里需要加上 \\ 将 特殊字符 . 转意 \\. ,否则异常 - assert fileName != null; - String[] fileArray = fileName.split("\\."); - - // 获取当前日期 - Date now = new Date(); - SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); - String format = sdf.format(now); - - fileName = format + "/" + fileArray[0] + System.currentTimeMillis() + "." + fileArray[1]; - - try (InputStream inputStream = multipartFile.getInputStream()) { - minioClient.putObject( - PutObjectArgs.builder() - .bucket(bucket) - .object(fileName) - .stream(inputStream, -1L, 10485760L) - .contentType(multipartFile.getContentType()) - .build() - ); - } catch (Exception e) { - throw new RuntimeException("文件上传失败: " + e.getMessage()); - } - // 返回地址 - return endpoint+bucket+"/"+fileName; - } - - /** - * 文件下载 - * - * @param fileName 文件名 - * @param delete 是否删除 - */ -} diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysDeptController.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysDeptController.java index 28ad4e4..575631b 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysDeptController.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysDeptController.java @@ -38,6 +38,7 @@ import cc.iotkit.system.dto.vo.SysDeptVo; import cc.iotkit.system.service.ISysDeptService; import cn.dev33.satoken.annotation.SaCheckPermission; import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.ObjectUtil; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; @@ -64,7 +65,7 @@ public class SysDeptController extends BaseController { /** * 获取部门列表 */ - @SaCheckPermission("system:dept:list") + // @SaCheckPermission("system:dept:list") @ApiOperation("获取部门列表") @PostMapping("/list") public List list(@RequestBody @Validated(QueryGroup.class) PageRequest dept) { @@ -81,10 +82,17 @@ public class SysDeptController extends BaseController { public List excludeChild(@Validated @RequestBody Request request) { Long deptId = request.getData(); - List depts = deptService.selectDeptList(new SysDeptBo()); - depts.removeIf(d -> d.getId().equals(deptId) - || StringUtils.splitList(d.getAncestors()).contains(Convert.toStr(deptId))); - return depts; + SysDeptBo deptBo = new SysDeptBo(); + SysDeptVo sysDeptVo = deptService.selectDeptById(deptId); + if(sysDeptVo != null) { + deptBo.setAreaType(sysDeptVo.getAreaType()); + // deptBo.setFlag(0L); + List depts = deptService.selectDeptList(deptBo); + depts.removeIf(d -> d.getId().equals(deptId) + || StringUtils.splitList(d.getAncestors()).contains(Convert.toStr(deptId))); + return depts; + } + return null; } /** @@ -131,6 +139,9 @@ public class SysDeptController extends BaseController { && deptService.selectNormalChildrenDeptById(deptId) > 0) { fail("该部门包含未停用的子部门!"); } + if(ObjectUtil.isNotEmpty(dept) && ObjectUtil.isNotNull(dept.getParentId()) && dept.getParentId() == 0){ + dept.setAreaType(0); + } deptService.updateDept(dept); } diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysOssController.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysOssController.java index b69d860..26707f3 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysOssController.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysOssController.java @@ -41,11 +41,12 @@ import cn.dev33.satoken.annotation.SaCheckPermission; import cn.hutool.core.io.IoUtil; import cn.hutool.core.util.ObjectUtil; import com.amazonaws.services.s3.model.ObjectMetadata; +import io.minio.StatObjectResponse; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.output.CountingOutputStream; +import org.springframework.http.*; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -54,9 +55,15 @@ import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBo import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; +import java.net.SocketException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.List; +import static cn.dev33.satoken.SaManager.log; + /** * 文件上传 控制层 * @@ -110,16 +117,131 @@ public class SysOssController extends BaseController { uploadVo.setOssId(oss.getId().toString()); return uploadVo; } + @SaCheckPermission("system:oss:download") + @PostMapping("/downloadById") + @ApiOperation(value = "下载OSS对象", notes = "下载OSS对象") + public ResponseEntity download(@RequestBody @Validated Request bo) throws Exception { + SysOssVo ossVo = ossService.getById(bo.getData()); + + InputStream stream = ossService.downloadGetObject(ossVo); + + StatObjectResponse metadata = ossService.downloadStatObject(ossVo); + + + + // 获取并编码文件名 + + String rawFileName = ossVo.getOriginalName(); + + String encodedFileName = URLEncoder.encode(rawFileName, StandardCharsets.UTF_8) + + .replace("+", "%20"); + + // 构建响应头 + + HttpHeaders headers = new HttpHeaders(); + + // headers.setAcceptRanges("bytes"); + + headers.setContentDisposition( + + ContentDisposition.attachment() + + .filename(rawFileName) + + .filename(encodedFileName, StandardCharsets.UTF_8) + + .build()); + + headers.setContentLength(metadata.size()); + + headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); + + + // 输出响应头(调试用) + + System.out.println("Response Headers: " + headers); + + + + return new ResponseEntity<>( + + out -> IoUtil.copy(stream, out), + + headers, + + HttpStatus.OK); + + /* return ResponseEntity.ok() + + .header(HttpHeaders.ACCEPT_RANGES, "bytes") + + .header(HttpHeaders.CONTENT_DISPOSITION, + + "attachment; filename=\"" + rawFileName + "\"; filename*=UTF-8''" + encodedFileName) + + .contentLength(metadata.size()) + + .contentType(MediaType.APPLICATION_OCTET_STREAM) + + .body(out -> IoUtil.copy(stream, out));*/ + + } /** * 下载OSS对象 */ - @SaCheckPermission("system:oss:download") + /* @SaCheckPermission("system:oss:download") @PostMapping("/downloadById") @ApiOperation(value = "下载OSS对象", notes = "下载OSS对象") - public ResponseEntity download(@RequestBody @Validated Request bo) throws IOException { + public ResponseEntity download(@RequestBody @Validated Request bo) throws Exception { SysOssVo ossVo = ossService.getById(bo.getData()); - OssClient storage = OssFactory.instance(); + InputStream stream = ossService.downloadGetObject(ossVo); + StatObjectResponse metadata = ossService.downloadStatObject(ossVo); + *//* response.setHeader("Content-Disposition", "attachment;filename=" + fileName); + response.setContentType("application/force-download"); + response.setCharacterEncoding("UTF-8"); + IOUtils.copy(fileInputStream, response.getOutputStream());*//* + String headerValue = String.format("attachment; filename=\"%s\"; filename*=UTF-8''%s", + ossVo.getOriginalName(), ossVo.getOriginalName()); + return ResponseEntity + .ok() + .header(HttpHeaders.ACCEPT_RANGES, "bytes") + // .header("download-filename", ossVo.getFileName()) + .header(HttpHeaders.CONTENT_DISPOSITION, headerValue) + .contentLength(metadata.size()) + .contentType(MediaType.APPLICATION_OCTET_STREAM) + .body(out -> IoUtil.copy(stream, out)); + *//* try (InputStream stream = ossService.downloadGetObject(ossVo)) { + StatObjectResponse metadata = ossService.downloadStatObject(ossVo); + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_DISPOSITION, + "attachment; filename=" + URLEncoder.encode(ossVo.getFileName(), "UTF-8")) + .header("Connection", "close") + .contentLength(metadata.size()) + .contentType(MediaType.APPLICATION_OCTET_STREAM) + .body(out -> { + byte[] buffer = new byte[metadata.size() < 102400 ? 4096 : 8192]; + // byte[] buffer = new byte[65536]; // 64KB缓冲 + try { + int bytesRead; + while ((bytesRead = stream.read(buffer)) != -1) { + out.write(buffer, 0, bytesRead); + out.flush(); // 强制刷新保证实时传输 + } + } catch (SocketException e) { + log.warn("客户端中断下载 | 文件={} | 已传输={}%", + ossVo.getFileName(), + calculateProgress(out, metadata.size())); + } catch (IOException e) { + log.error("OSS传输失败 | 错误类型={}", e.getClass().getSimpleName(), e); + throw new RuntimeException("文件传输异常", e); + } + }); + } catch (IOException e) { + throw new RuntimeException("连接建立失败", e); + }*//* + *//* OssClient storage = OssFactory.instance(); ObjectMetadata objectMetadata = storage.getObjectMetadata(ossVo.getUrl()); InputStream objectContent = storage.getObjectContent(ossVo.getUrl()); return ResponseEntity @@ -128,7 +250,16 @@ public class SysOssController extends BaseController { .header("download-filename", ossVo.getFileName()) .contentLength(objectMetadata.getContentLength()) .contentType(MediaType.APPLICATION_OCTET_STREAM) - .body(out -> IoUtil.copy(objectContent, out)); + .body(out -> IoUtil.copy(objectContent, out));*//* + }*/ + // 进度计算工具方法 + private int calculateProgress(OutputStream out, long totalSize) { + try { + if (out instanceof CountingOutputStream) { + return (int) (((CountingOutputStream) out).getCount() * 100 / totalSize); + } + } catch (Exception ignored) {} + return -1; } /** diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysRoleController.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysRoleController.java index 8816239..a920d94 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysRoleController.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysRoleController.java @@ -29,6 +29,7 @@ import cc.iotkit.common.api.Request; import cc.iotkit.common.excel.utils.ExcelUtil; import cc.iotkit.common.log.annotation.Log; import cc.iotkit.common.log.enums.BusinessType; +import cc.iotkit.common.satoken.utils.LoginHelper; import cc.iotkit.common.web.core.BaseController; import cc.iotkit.model.system.SysUserRole; import cc.iotkit.system.dto.bo.SysDeptBo; @@ -75,6 +76,7 @@ public class SysRoleController extends BaseController { @SaCheckPermission("system:role:list") @PostMapping("/list") public Paging list(@RequestBody @Validated PageRequest query) { + return roleService.selectPageRoleList(query); } diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysTenantController.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysTenantController.java index 1be2492..a4a6305 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysTenantController.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysTenantController.java @@ -35,6 +35,7 @@ import cc.iotkit.common.validate.AddGroup; import cc.iotkit.common.validate.EditGroup; import cc.iotkit.common.web.core.BaseController; import cc.iotkit.system.dto.bo.SysTenantBo; +import cc.iotkit.system.dto.bo.SysTenantUpdateBo; import cc.iotkit.system.dto.vo.SysTenantVo; import cc.iotkit.system.service.ISysTenantService; import cn.dev33.satoken.annotation.SaCheckPermission; @@ -43,6 +44,7 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.hibernate.validator.constraints.NotBlank; import lombok.RequiredArgsConstructor; +import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -74,6 +76,7 @@ public class SysTenantController extends BaseController { @SaCheckPermission("system:tenant:list") @PostMapping("/list") public Paging list(@Validated @RequestBody PageRequest query) { + query.getData().setTenantId(null); return tenantService.queryPageList(query); } @@ -115,6 +118,7 @@ public class SysTenantController extends BaseController { fail("新增租户'" + data.getCompanyName() + "'失败,企业名称已存在"); } TenantHelper.ignore(()->tenantService.insertByBo(data)); + } /** @@ -166,7 +170,9 @@ public class SysTenantController extends BaseController { @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) @PostMapping("/dynamic") public void dynamicTenant(@Validated @RequestBody Request bo) { + TenantHelper.setDynamic(bo.getData()); + System.out.println(TenantHelper.getDynamic()); } /** @@ -191,8 +197,8 @@ public class SysTenantController extends BaseController { @SaCheckPermission("system:tenant:edit") @Log(title = "租户", businessType = BusinessType.UPDATE) @PostMapping("/syncTenantPackage") - public void syncTenantPackage(@NotBlank(message = "租户ID不能为空") Long tenantId, @NotBlank(message = "套餐ID不能为空") String packageId) { - //TenantHelper.ignore(() -> tenantService.syncTenantPackage(tenantId, packageId)); + public void syncTenantPackage(@Validated @RequestBody Request sysTenantBo) { + TenantHelper.ignore(() -> tenantService.syncTenantPackage(sysTenantBo.getData())); } } diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysTenantPackageController.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysTenantPackageController.java index 4d78a1f..3c505ff 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysTenantPackageController.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysTenantPackageController.java @@ -38,6 +38,7 @@ import cc.iotkit.system.dto.vo.SysTenantPackageVo; import cc.iotkit.system.service.ISysTenantPackageService; import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckRole; +import cn.hutool.core.util.ObjectUtil; import io.swagger.annotations.ApiOperation; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; @@ -142,6 +143,11 @@ public class SysTenantPackageController extends BaseController { @Log(title = "租户套餐", businessType = BusinessType.UPDATE) @PostMapping("/changeStatus") public void changeStatus(@RequestBody Request bo) { + if(ObjectUtil.isNotNull(bo.getData())){ + if(ObjectUtil.isNotNull(bo.getData().getPackageId()) && ObjectUtil.isNull(bo.getData().getId()) ){ + bo.getData().setId(bo.getData().getPackageId()); + } + } tenantPackageService.updatePackageStatus(bo.getData()); } diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysUserController.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysUserController.java index 55ed837..43a15bb 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysUserController.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysUserController.java @@ -41,6 +41,8 @@ import cc.iotkit.common.validate.EditGroup; import cc.iotkit.common.validate.QueryGroup; import cc.iotkit.common.web.core.BaseController; import cc.iotkit.data.config.TenantContext; +import cc.iotkit.data.manager.IDeviceInfoData; +import cc.iotkit.model.stats.SysDeptDto; import cc.iotkit.system.dto.bo.SysDeptBo; import cc.iotkit.system.dto.bo.SysUserBo; import cc.iotkit.system.dto.bo.SysUserRolesBo; @@ -50,18 +52,21 @@ import cc.iotkit.system.service.*; import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.secure.BCrypt; import cn.hutool.core.lang.tree.Tree; +import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ObjectUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.MediaType; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; -import java.util.ArrayList; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; /** * 用户信息 @@ -80,7 +85,9 @@ public class SysUserController extends BaseController { private final ISysPostService postService; private final ISysDeptService deptService; private final ISysTenantService tenantService; - + @Autowired + @Qualifier("deviceInfoDataCache") + private IDeviceInfoData deviceInfoData; @ApiOperation("获取用户列表") @SaCheckPermission("system:user:list") @PostMapping("/list") @@ -189,9 +196,22 @@ public class SysUserController extends BaseController { if (!tenantService.checkAccountBalance(TenantHelper.getTenantId())) { fail("当前租户下用户名额不足,请联系管理员"); } - user.setPassword(BCrypt.hashpw(user.getPassword())); - user.setUserType("sys_user"); - userService.insertUser(user); + if(LoginHelper.isSuperAdmin()) { + SysDeptVo sysDeptVo = deptService.selectDeptById(user.getDeptId()); + SysDeptVo sysDeptVo1 = deptService.selectDeptById(user.getDeptAreaId()); + if (ObjectUtil.isNotEmpty(sysDeptVo1) && ObjectUtil.isNotEmpty(sysDeptVo)) { + if (!sysDeptVo1.getTenantId().equals(sysDeptVo.getTenantId())) { + fail("设备与区域不为同一租户下"); + } + } else { + fail("请选择部门与区域"); + } + user.setTenantId(sysDeptVo.getTenantId()); + TenantHelper.enableIgnore(); + } + user.setPassword(BCrypt.hashpw(user.getPassword())); + user.setUserType("sys_user"); + userService.insertUser(user); } /** @@ -205,6 +225,7 @@ public class SysUserController extends BaseController { SysUserBo user = reqUser.getData(); userService.checkUserAllowed(user); userService.checkUserDataScope(user.getId()); + if (!userService.checkUserNameUnique(user)) { fail("修改用户'" + user.getUserName() + "'失败,登录账号已存在"); } else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) { @@ -212,6 +233,25 @@ public class SysUserController extends BaseController { } else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) { fail("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); } + if(LoginHelper.isSuperAdmin()) { + SysDeptVo sysDeptVo = deptService.selectDeptById(user.getDeptId()); + SysDeptVo sysDeptVo1 = deptService.selectDeptById(user.getDeptAreaId()); + if (ObjectUtil.isNotEmpty(sysDeptVo1) && ObjectUtil.isNotEmpty(sysDeptVo)) { + if (!sysDeptVo1.getTenantId().equals(sysDeptVo.getTenantId())) { + fail("设备与区域不为同一租户下"); + } + } else { + fail("请选择部门与区域"); + } + if(user.getUserName().equals("admin")){ + user.setTenantId(0L); + }else{ + user.setTenantId(sysDeptVo.getTenantId()); + } + + TenantHelper.enableIgnore(); + } + user.setPassword(null); userService.updateUser(user); } @@ -298,8 +338,32 @@ public class SysUserController extends BaseController { //@SaCheckPermission("system:user:list") @PostMapping("/deptTree") public List> deptTree(@RequestBody @Validated(QueryGroup.class) Request reqDept) { + if(reqDept.getData().isFlag()){ + List> treeList = deptService.selectDeptTreeList(reqDept.getData()); + // List result = new ArrayList<>(); + Queue> queue = new LinkedList<>(treeList); + + while (!queue.isEmpty()) { + Tree node = queue.poll(); + // result.add(node.getId()); + /* if (node.getChildren() != null) { + queue.addAll(node.getChildren()); + }*/ + SysDeptDto sysDeptDto = deviceInfoData.getStatsCount(node.getId()); + if(ObjectUtil.isNotNull(sysDeptDto)) { + Map map = MapUtil.of(node.getId().toString(), sysDeptDto); + node.putAll(map); + } + // 将子节点加入队列 + if (node.hasChild()) { + queue.addAll(node.getChildren()); + } + } - return deptService.selectDeptTreeList(reqDept.getData()); + return treeList; + }else{ + return deptService.selectDeptTreeList(reqDept.getData()); + } } @ApiOperation("根据部门编号获取详细信息") diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/LoginBody.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/LoginBody.java index 8b9e670..6942dff 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/LoginBody.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/LoginBody.java @@ -40,7 +40,7 @@ public class LoginBody { /** * 租户ID */ - @NotNull(message = "{tenant.number.not.blank}") + // @NotNull(message = "{tenant.number.not.blank}") private Long tenantId; /** diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysConfigBo.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysConfigBo.java index 4f62151..a53fb2a 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysConfigBo.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysConfigBo.java @@ -48,28 +48,28 @@ public class SysConfigBo extends BaseDto { /** * 参数主键 */ - @NotNull(message = "参数主键不能为空", groups = {EditGroup.class}) + //@NotNull(message = "参数主键不能为空", groups = {EditGroup.class}) private Long id; /** * 参数名称 */ - @NotBlank(message = "参数名称不能为空", groups = {AddGroup.class, EditGroup.class}) - @Size(min = 0, max = 100, message = "参数名称不能超过{max}个字符") + // @NotBlank(message = "参数名称不能为空", groups = {AddGroup.class, EditGroup.class}) + //@Size(min = 0, max = 100, message = "参数名称不能超过{max}个字符") private String configName; /** * 参数键名 */ - @NotBlank(message = "参数键名不能为空", groups = {AddGroup.class, EditGroup.class}) - @Size(min = 0, max = 100, message = "参数键名长度不能超过{max}个字符") + // @NotBlank(message = "参数键名不能为空", groups = {AddGroup.class, EditGroup.class}) + // @Size(min = 0, max = 100, message = "参数键名长度不能超过{max}个字符") private String configKey; /** * 参数键值 */ - @NotBlank(message = "参数键值不能为空", groups = {AddGroup.class, EditGroup.class}) - @Size(min = 0, max = 500, message = "参数键值长度不能超过{max}个字符") + //@NotBlank(message = "参数键值不能为空", groups = {AddGroup.class, EditGroup.class}) + //@Size(min = 0, max = 500, message = "参数键值长度不能超过{max}个字符") private String configValue; /** diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysDeptBo.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysDeptBo.java index ee7d771..e73662f 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysDeptBo.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysDeptBo.java @@ -96,4 +96,12 @@ public class SysDeptBo extends BaseDto { * 部门与区域(默认0是部门,1是区域) */ private Integer areaType; + /** + * 租户编号 + */ + private Long tenantId; + private String latitude; + private String longitude; + private String site; + private boolean flag; } diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysRoleBo.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysRoleBo.java index f65bc13..e0bbe3d 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysRoleBo.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysRoleBo.java @@ -53,7 +53,7 @@ public class SysRoleBo extends BaseDto { */ @NotNull(message = "角色ID不能为空", groups = { EditGroup.class }) private Long id; - + private Long tenantId; /** * 角色名称 */ diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysTenantBo.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysTenantBo.java index 78e58be..f2f79d7 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysTenantBo.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysTenantBo.java @@ -28,6 +28,7 @@ import cc.iotkit.common.utils.DateUtils; import cc.iotkit.common.validate.AddGroup; import cc.iotkit.common.validate.EditGroup; import cc.iotkit.model.system.SysTenant; +import com.fasterxml.jackson.annotation.JsonFormat; import io.github.linpeilie.annotations.AutoMapper; import org.hibernate.validator.constraints.NotBlank; import javax.validation.constraints.NotNull; @@ -124,6 +125,7 @@ public class SysTenantBo extends BaseDto { * 过期时间 */ @DateTimeFormat(pattern = DateUtils.YYYY_MM_DD_HH_MM_SS) + @JsonFormat(pattern = DateUtils.YYYY_MM_DD_HH_MM_SS) private Date expireTime; /** diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysTenantPackageBo.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysTenantPackageBo.java index 1d63ee8..acecd45 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysTenantPackageBo.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysTenantPackageBo.java @@ -48,9 +48,9 @@ public class SysTenantPackageBo extends BaseDto { /** * 租户套餐id */ - @NotNull(message = "租户套餐id不能为空", groups = {EditGroup.class}) + //@NotNull(message = "租户套餐id不能为空", groups = {EditGroup.class}) + private Long id; private Long packageId; - /** * 套餐名称 */ diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysTenantUpdateBo.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysTenantUpdateBo.java new file mode 100644 index 0000000..8f8ad43 --- /dev/null +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysTenantUpdateBo.java @@ -0,0 +1,73 @@ +/* + * + * * | Licensed 未经许可不能去掉「OPENIITA」相关版权 + * * +---------------------------------------------------------------------- + * * | Author: xw2sy@163.com + * * +---------------------------------------------------------------------- + * + * Copyright [2024] [OPENIITA] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * / + */ + +package cc.iotkit.system.dto.bo; + +import cc.iotkit.common.api.BaseDto; +import cc.iotkit.common.utils.DateUtils; +import cc.iotkit.common.validate.AddGroup; +import cc.iotkit.common.validate.EditGroup; +import cc.iotkit.model.system.SysTenant; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.hibernate.validator.constraints.NotBlank; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.validation.constraints.NotNull; +import java.util.Date; + +/** + * 租户业务对象 sys_tenant + * + * @author Michelle.Chung + */ + +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = SysTenant.class, reverseConvertGenerate = false) +public class SysTenantUpdateBo extends BaseDto { + + /** + * id + */ + private Long id; + + /** + * 租户编号 + */ + private Long tenantId; + + + + /** + * 租户套餐编号 + */ + @NotNull(message = "租户套餐不能为空", groups = { AddGroup.class }) + private Long packageId; + + + + +} diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysUserBo.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysUserBo.java index 88dfeda..13d7381 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysUserBo.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/bo/SysUserBo.java @@ -57,7 +57,7 @@ public class SysUserBo extends BaseDto { /** * 用户ID */ - @NotNull(message = "用户ID不能为空", groups = {EditGroup.class}) + //@NotNull(message = "用户ID不能为空", groups = {EditGroup.class}) private Long id; /** @@ -68,7 +68,7 @@ public class SysUserBo extends BaseDto { /** * 用户账号 */ - @NotBlank(message = "用户账号不能为空") + // @NotBlank(message = "用户账号不能为空") @Size(min = 0, max = 30, message = "用户账号长度不能超过{max}个字符") private String userName; //@Size(min = 0, max = 30, message = "用户账号长度不能超过{max}个字符") @@ -132,7 +132,8 @@ public class SysUserBo extends BaseDto { * 数据权限 当前角色ID */ private Long roleId; - + private Long tenantId; + private boolean flag; public SysUserBo(Long id) { this.id = id; } diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/vo/SysDeptVo.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/vo/SysDeptVo.java index 1da7cc0..cddf820 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/vo/SysDeptVo.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/vo/SysDeptVo.java @@ -50,7 +50,7 @@ public class SysDeptVo implements Serializable { */ @ExcelProperty(value = "部门id") private Long id; - + private Long tenantId; /** * 父部门id */ @@ -111,4 +111,7 @@ public class SysDeptVo implements Serializable { * 部门与区域(默认0是部门,1是区域) */ private Integer areaType; + private String latitude; + private String longitude; + private String site; } diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/vo/SysOssVo.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/vo/SysOssVo.java index 7982904..22c1a09 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/vo/SysOssVo.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/vo/SysOssVo.java @@ -85,5 +85,8 @@ public class SysOssVo implements Serializable { */ private String service; - + /** + * 文件大小 + */ + private Long size; } diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/vo/SysRoleVo.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/vo/SysRoleVo.java index 271ef29..d7f365a 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/vo/SysRoleVo.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/vo/SysRoleVo.java @@ -51,7 +51,7 @@ public class SysRoleVo implements Serializable { */ @ExcelProperty(value = "角色序号") private Long id; - + private Long tenantId; /** * 角色名称 */ diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/vo/SysUserVo.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/vo/SysUserVo.java index 5d3683f..ccfc53f 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/vo/SysUserVo.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/dto/vo/SysUserVo.java @@ -131,7 +131,10 @@ public class SysUserVo implements Serializable { * 部门对象 */ private SysDeptVo dept; - + /** + * 部门对象 + */ + private SysDeptVo areaDept; /** * 角色对象 */ diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/service/ISysOssService.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/service/ISysOssService.java index a2e87ea..870281d 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/service/ISysOssService.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/service/ISysOssService.java @@ -27,9 +27,11 @@ import cc.iotkit.common.api.PageRequest; import cc.iotkit.common.api.Paging; import cc.iotkit.system.dto.bo.SysOssBo; import cc.iotkit.system.dto.vo.SysOssVo; +import io.minio.StatObjectResponse; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; +import java.io.InputStream; import java.util.Collection; import java.util.List; @@ -49,7 +51,8 @@ public interface ISysOssService { SysOssVo upload(MultipartFile file); void download(Long ossId) throws IOException; - + InputStream downloadGetObject(SysOssVo sysOssVo) throws Exception; + StatObjectResponse downloadStatObject(SysOssVo sysOssVo) throws Exception; void deleteWithValidByIds(Collection ids, Boolean isValid); } diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/service/ISysTenantService.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/service/ISysTenantService.java index 2d9481d..98b53f8 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/service/ISysTenantService.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/service/ISysTenantService.java @@ -26,6 +26,7 @@ package cc.iotkit.system.service; import cc.iotkit.common.api.PageRequest; import cc.iotkit.common.api.Paging; import cc.iotkit.system.dto.bo.SysTenantBo; +import cc.iotkit.system.dto.bo.SysTenantUpdateBo; import cc.iotkit.system.dto.vo.SysTenantVo; import java.util.List; @@ -100,5 +101,5 @@ public interface ISysTenantService { /** * 同步租户套餐 */ - Boolean syncTenantPackage(Long tenantId, String packageId); + Boolean syncTenantPackage(SysTenantUpdateBo sysTenantUpdateBo); } diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/service/impl/SysConfigServiceImpl.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/service/impl/SysConfigServiceImpl.java index ab937bf..b82ce7c 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/service/impl/SysConfigServiceImpl.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/service/impl/SysConfigServiceImpl.java @@ -198,7 +198,7 @@ public class SysConfigServiceImpl implements ISysConfigService, ConfigService { @Override public boolean checkConfigKeyUnique(SysConfigBo config) { long configId = ObjectUtil.isNull(config.getId()) ? -1L : config.getId(); - SysConfig old = sysConfigData.findByConfigKey(config.getConfigKey()); + SysConfig old = sysConfigData.findById(configId); return !ObjectUtil.isNotNull(old) || old.getId() == configId; } diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/service/impl/SysDeptServiceImpl.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/service/impl/SysDeptServiceImpl.java index 2195463..7349009 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/service/impl/SysDeptServiceImpl.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/service/impl/SysDeptServiceImpl.java @@ -28,6 +28,7 @@ import cc.iotkit.common.enums.ErrCode; import cc.iotkit.common.exception.BizException; import cc.iotkit.common.satoken.utils.LoginHelper; import cc.iotkit.common.service.DeptService; +import cc.iotkit.common.tenant.helper.TenantHelper; import cc.iotkit.common.utils.MapstructUtils; import cc.iotkit.common.utils.SpringUtils; import cc.iotkit.common.utils.StringUtils; @@ -48,9 +49,13 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; +import static com.fasterxml.jackson.databind.type.LogicalType.Map; + /** * 部门管理 服务实现 * @@ -103,11 +108,17 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService { if (CollUtil.isEmpty(depts)) { return CollUtil.newArrayList(); } - return TreeBuildUtils.build(depts, (dept, tree) -> - tree.setId(dept.getId()) + return TreeBuildUtils.build(depts, (dept, tree) ->{ + java.util.Map extras = new HashMap<>(); + extras.put("latitude", dept.getLatitude()); + extras.put("longitude", dept.getLongitude()); + extras.put("site", dept.getSite()); + tree.setId(dept.getId()) .setParentId(dept.getParentId()) .setName(dept.getDeptName()) - .setWeight(dept.getOrderNum())); + .setWeight(dept.getOrderNum()) + .putAll(extras); + }); } /** @@ -235,7 +246,13 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService { throw new BizException("部门停用,不允许新增"); } SysDept dept = MapstructUtils.convert(bo, SysDept.class); + // parent.getTenantId(); + dept.setTenantId(parent.getTenantId()); dept.setAncestors(parent.getAncestors() + StringUtils.SEPARATOR + dept.getParentId()); + if(ObjectUtil.isNull(dept.getAreaType())){ + dept.setAreaType(0); + } + TenantHelper.enableIgnore(); sysDeptData.save(dept); } @@ -265,7 +282,7 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService { updateDeptChildren(dept.getId(), newAncestors, oldAncestors); } } - + TenantHelper.enableIgnore(); sysDeptData.save(dept); if (UserConstants.DEPT_NORMAL.equals(dept.getStatus()) && StringUtils.isNotEmpty(dept.getAncestors()) && !StringUtils.equals(UserConstants.DEPT_NORMAL, dept.getAncestors())) { diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/service/impl/SysOssServiceImpl.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/service/impl/SysOssServiceImpl.java index 954333a..19f12b0 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/service/impl/SysOssServiceImpl.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/service/impl/SysOssServiceImpl.java @@ -32,30 +32,34 @@ import cc.iotkit.common.oss.entity.UploadResult; import cc.iotkit.common.oss.enumd.AccessPolicyType; import cc.iotkit.common.oss.exception.OssException; import cc.iotkit.common.oss.factory.OssFactory; +import cc.iotkit.common.oss.minio.MinioUtil; import cc.iotkit.common.service.OssService; import cc.iotkit.common.utils.MapstructUtils; import cc.iotkit.common.utils.SpringUtils; import cc.iotkit.common.utils.StringUtils; +import cc.iotkit.data.model.QTbSysOss; +import cc.iotkit.data.model.TbSysOss; import cc.iotkit.data.system.ISysOssData; import cc.iotkit.model.system.SysOss; -import cc.iotkit.system.config.MinioUtil; + import cc.iotkit.system.dto.bo.SysOssBo; import cc.iotkit.system.dto.vo.SysOssVo; import cc.iotkit.system.service.ISysOssService; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.ObjectUtil; +import io.minio.StatObjectResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.querydsl.QSort; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; +import java.io.InputStream; +import java.util.*; /** * 文件上传 服务层实现 @@ -72,6 +76,10 @@ public class SysOssServiceImpl implements ISysOssService, OssService { private MinioUtil minioUtil; @Override public Paging queryPageList(PageRequest query) { + // QSort sort = new QSort(QTbSysOss.tbSysOss.createTime.desc()); + Map sortMap = new HashMap<>(); + sortMap.put("createTime","desc"); + query.setSortMap(sortMap); return sysOssData.findAll(query.to(SysOss.class)).to(SysOssVo.class); } @@ -108,6 +116,19 @@ public class SysOssServiceImpl implements ISysOssService, OssService { @Override public void download(Long ossId) { + + } + @Override + public InputStream downloadGetObject(SysOssVo sysOssVo) throws Exception{ + int startIndex = sysOssVo.getUrl().lastIndexOf("/feijialuo/") + "/feijialuo/".length(); + String result = sysOssVo.getUrl().substring(startIndex); + return minioUtil.downloadGetObject("feijialuo",result); + } + @Override + public StatObjectResponse downloadStatObject(SysOssVo sysOssVo) throws Exception{ + int startIndex = sysOssVo.getUrl().lastIndexOf("/feijialuo/") + "/feijialuo/".length(); + String result = sysOssVo.getUrl().substring(startIndex); + return minioUtil.downloadStatObject("feijialuo",result); } /* @Override @@ -160,6 +181,15 @@ public class SysOssServiceImpl implements ISysOssService, OssService { oss.setService("oss-embed"); oss = sysOssData.save(oss); SysOssVo sysOssVo = MapstructUtils.convert(oss, SysOssVo.class); + + /* OtaPackageUploadVo otaPackageUploadVo = new OtaPackageUploadVo(); + otaPackageUploadVo.setUrl(uploadResult.getUrl()); + otaPackageUploadVo.setSize(file.getSize()); + otaPackageUploadVo.setMd5(md5); + otaPackageUploadVo.setOriginalName(originalFileName); + otaPackageUploadVo.setOssId(oss.getId());*/ + sysOssVo.setSize(file.getSize()); + sysOssVo.setId(oss.getId()); return sysOssVo; } @Override @@ -169,8 +199,14 @@ public class SysOssServiceImpl implements ISysOssService, OssService { } List list = sysOssData.findByIds(ids); for (SysOss sysOss : list) { - OssClient storage = OssFactory.instance(sysOss.getService()); - storage.delete(sysOss.getUrl()); + if(ObjectUtil.isNotNull(sysOss.getUrl())){ + int startIndex = sysOss.getUrl().lastIndexOf("/feijialuo/") + "/feijialuo/".length(); + String result = sysOss.getUrl().substring(startIndex); + minioUtil.removeObject("feijialuo",result); + } + + /* OssClient storage = OssFactory.instance(sysOss.getService()); + storage.delete(sysOss.getUrl());*/ } sysOssData.deleteByIds(ids); } diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/service/impl/SysRoleServiceImpl.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/service/impl/SysRoleServiceImpl.java index 161ab1a..74f3264 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/service/impl/SysRoleServiceImpl.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/service/impl/SysRoleServiceImpl.java @@ -232,7 +232,8 @@ public class SysRoleServiceImpl implements ISysRoleService { SysRole role = iSysRoleData.save(bo.to(SysRole.class)); //TODO 后面再晚上插入菜单的,目前不知道逻辑 //return insertRoleMenu(bo); - + bo.setId(role.getId()); + insertRoleMenu(bo); return 1; } @@ -305,6 +306,7 @@ public class SysRoleServiceImpl implements ISysRoleService { return Integer.parseInt(rows + ""); } + /** * 新增角色部门信息(数据权限) * diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/service/impl/SysTenantServiceImpl.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/service/impl/SysTenantServiceImpl.java index 0c7edbc..c18adde 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/service/impl/SysTenantServiceImpl.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/service/impl/SysTenantServiceImpl.java @@ -32,11 +32,14 @@ import cc.iotkit.common.enums.ErrCode; import cc.iotkit.common.enums.UserType; import cc.iotkit.common.exception.BizException; import cc.iotkit.common.satoken.utils.LoginHelper; +import cc.iotkit.common.tenant.helper.TenantHelper; import cc.iotkit.common.utils.MapstructUtils; import cc.iotkit.common.utils.StringUtils; +import cc.iotkit.data.config.TenantContext; import cc.iotkit.data.system.*; import cc.iotkit.model.system.*; import cc.iotkit.system.dto.bo.SysTenantBo; +import cc.iotkit.system.dto.bo.SysTenantUpdateBo; import cc.iotkit.system.dto.vo.SysTenantVo; import cc.iotkit.system.service.ISysTenantService; import cn.dev33.satoken.secure.BCrypt; @@ -45,11 +48,21 @@ import cn.hutool.core.util.ObjectUtil; import com.github.yitter.idgen.YitIdHelper; import lombok.RequiredArgsConstructor; import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDateTime; +import java.time.ZonedDateTime; import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; import java.util.List; import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static cc.iotkit.common.web.core.BaseController.fail; + /** * 租户Service业务层处理 @@ -110,32 +123,59 @@ public class SysTenantServiceImpl implements ISysTenantService { } @Override + // @Transactional(rollbackFor = Error.class) public void insertByBo(SysTenantBo bo) { + TenantContext.disableTenantFilter(); + TenantHelper.enableIgnore(); long tenantId = YitIdHelper.nextId(); + SysUser user = new SysUser(); + user.setTenantId(tenantId); + user.setUserName(bo.getUsername()); + user.setNickName(bo.getUsername()); + user.setPhonenumber(bo.getContactPhone()); + if (!sysUserData.checkUserNameUnique(user)) { + fail("新增用户'" + user.getUserName() + "'失败,登录账号已存在"); + return; + } else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !sysUserData.checkPhoneUnique(user)) { + fail("新增用户'" + user.getUserName() + "'失败,手机号码已存在"); + return; + } else if (StringUtils.isNotEmpty(user.getEmail()) && !sysUserData.checkEmailUnique(user)) { + fail("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + return; + } bo.setId(tenantId); bo.setTenantId(tenantId); + if(ObjectUtil.isNull(bo.getExpireTime())){ + //不传过期时间默认100年后到期 + bo.setExpireTime(Date.from(ZonedDateTime.now().plusYears(100).toInstant())); + } SysTenant sysTenant=sysTenantData.save(bo.to(SysTenant.class)); // 根据套餐创建角色 - Long roleId = createTenantRole(sysTenant.getTenantId(), bo.getPackageId()); - + Long roleId = createTenantRole(sysTenant,sysTenant.getTenantId(), bo.getPackageId()); + //开启忽略租户 + // TenantHelper.enableIgnore(); // 创建部门: 公司名是部门名称 SysDept dept = new SysDept(); - dept.setTenantId(sysTenant.getTenantId()); + // dept.setTenantId(sysTenant.getTenantId()); dept.setDeptName(bo.getCompanyName()); dept.setParentId(0L); dept.setAncestors("0"); dept.setPhone(bo.getContactPhone()); + dept.setAreaType(0); dept.setStatus(TenantConstants.NORMAL); + dept.setTenantId(tenantId); SysDept retDept =sysDeptData.save(dept); Long deptId = retDept.getId(); - // 角色和部门关联表 SysRoleDept roleDept = new SysRoleDept(); roleDept.setRoleId(roleId); roleDept.setDeptId(deptId); roleDept.setTenantId(tenantId); sysRoleDeptData.save(roleDept); - + createTenantMenu(bo,sysTenant,roleId,deptId); + } + @Transactional + public void createTenantMenu(SysTenantBo bo,SysTenant sysTenant,Long roleId,Long deptId){ // 创建系统用户 SysUser user = new SysUser(); user.setTenantId(sysTenant.getTenantId()); @@ -143,22 +183,30 @@ public class SysTenantServiceImpl implements ISysTenantService { user.setNickName(bo.getUsername()); user.setPassword(BCrypt.hashpw(bo.getPassword())); user.setDeptId(deptId); + user.setDeptAreaId(deptId); user.setUserType(UserType.SYS_USER.getUserType()); user.setStatus(TenantConstants.NORMAL); user.setRemark(TenantConstants.TENANT_ADMIN_ROLE_NAME); + user.setPhonenumber(bo.getContactPhone()); + if (!sysUserData.checkUserNameUnique(user)) { + fail("新增用户'" + user.getUserName() + "'失败,登录账号已存在"); + } else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !sysUserData.checkPhoneUnique(user)) { + fail("新增用户'" + user.getUserName() + "'失败,手机号码已存在"); + } else if (StringUtils.isNotEmpty(user.getEmail()) && !sysUserData.checkEmailUnique(user)) { + fail("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + } SysUser retUser=sysUserData.save(user); - //新增系统用户后,默认当前用户为部门的负责人 - SysDept updateDept =sysDeptData.findById(retDept.getId()); + SysDept updateDept =sysDeptData.findById(deptId); updateDept.setLeader(retUser.getUserName()); + updateDept.setTenantId(sysTenant.getTenantId()); sysDeptData.save(updateDept); - // 用户和角色关联表 SysUserRole userRole = new SysUserRole(); userRole.setUserId(retUser.getId()); userRole.setRoleId(roleId); - userRole.setTenantId(tenantId); + userRole.setTenantId(sysTenant.getTenantId()); sysUserRoleData.save(userRole); Long defaultTenantId = TenantConstants.DEFAULT_TENANT_ID; @@ -188,6 +236,7 @@ public class SysTenantServiceImpl implements ISysTenantService { config.setTenantId(sysTenant.getTenantId()); } sysConfigData.batchSave(sysConfigList); + TenantHelper.disableIgnore(); } /** @@ -197,7 +246,7 @@ public class SysTenantServiceImpl implements ISysTenantService { * @param packageId 租户套餐id * @return 角色id */ - private Long createTenantRole(Long tenantId, Long packageId) { + private Long createTenantRole(SysTenant sysTenant,Long tenantId, Long packageId) { // 获取租户套餐 SysTenantPackage tenantPackage = sysTenantPackageData.findById(packageId); if (ObjectUtil.isNull(tenantPackage)) { @@ -209,7 +258,7 @@ public class SysTenantServiceImpl implements ISysTenantService { // 创建角色 SysRole role = new SysRole(); role.setTenantId(tenantId); - role.setRoleName(TenantConstants.TENANT_ADMIN_ROLE_NAME); + role.setRoleName(sysTenant.getCompanyName()+TenantConstants.TENANT_ADMIN_ROLE_NAME); role.setRoleKey(TenantConstants.TENANT_ADMIN_ROLE_KEY); role.setRoleSort(1); role.setRemark(TenantConstants.TENANT_ADMIN_ROLE_NAME); @@ -229,8 +278,66 @@ public class SysTenantServiceImpl implements ISysTenantService { return roleId; } + + /** + * 根据租户菜单修改租户角色 + * + * @param sysTenant 租户编号 + * @return 角色id + */ + @Transactional + public void updateTenantRole(SysTenantBo sysTenant) { + // 获取租户套餐 + SysTenantPackage tenantPackage = sysTenantPackageData.findById(sysTenant.getPackageId()); + if (ObjectUtil.isNull(tenantPackage)) { + throw new BizException(ErrCode.PACKAGE_NOT_FOUND); + } + SysTenant sysTenant1 = sysTenantData.findById(sysTenant.getId()); + if(ObjectUtil.isEmpty(sysTenant1)){ + return; + } + if(sysTenant1.getPackageId() == sysTenant.getPackageId() || sysTenant1.getPackageId().equals(sysTenant.getPackageId())){ + return; + } + // 获取套餐菜单id + List menuIds = StringUtils.splitTo(tenantPackage.getMenuIds(), Convert::toLong); + //查询角色 + + // 创建角色 + SysRole role = new SysRole(); + role.setTenantId(sysTenant.getId()); + //role.setRoleName(sysTenant.getCompanyName()+TenantConstants.TENANT_ADMIN_ROLE_NAME); + role.setRoleKey(TenantConstants.TENANT_ADMIN_ROLE_KEY); + // role.setRoleSort(1); + // role.setRemark(TenantConstants.TENANT_ADMIN_ROLE_NAME); + role.setStatus(TenantConstants.NORMAL); + SysRole retRole=sysRoleData.findOneByCondition(role); + if(ObjectUtil.isEmpty(retRole)){ + return; + } + Long roleId = retRole.getId(); + //先删除 + sysRoleMenuData.deleteByRoleId( Collections.singletonList(retRole.getId())); + // 创建角色菜单 + List roleMenus = new ArrayList<>(menuIds.size()); + menuIds.forEach(menuId -> { + SysRoleMenu roleMenu = new SysRoleMenu(); + roleMenu.setRoleId(roleId); + roleMenu.setMenuId(menuId); + roleMenus.add(roleMenu); + }); + sysRoleMenuData.insertBatch(roleMenus); + } @Override public void updateByBo(SysTenantBo bo) { + + updateTenantRole(bo); + // 获取租户套餐 + /* SysTenantPackage tenantPackage = sysTenantPackageData.findById(sysTenant.getPackageId()); + if (ObjectUtil.isNull(tenantPackage)) { + throw new BizException(ErrCode.PACKAGE_NOT_FOUND); + }*/ + sysTenantData.save(bo.to(SysTenant.class)); } @@ -251,18 +358,24 @@ public class SysTenantServiceImpl implements ISysTenantService { @Override public void deleteById(Long id) { - Long tenantId=LoginHelper.getTenantId(); + Long tenantId=id; //删除角色 SysRole querySysRole=new SysRole(); querySysRole.setTenantId(tenantId); List roles =sysRoleData.selectRoleList(querySysRole); sysRoleData.deleteByIds(roles.stream().map(SysRole::getId).collect(Collectors.toList())); //删除部门 + List lsDepts = sysDeptData.findByTenantId(tenantId); + sysDeptData.deleteByIds(lsDepts.stream().map(SysDept::getId).collect(Collectors.toList())); //删除系统用户 + List lsUserList = sysUserData.findByTenantId(tenantId); + sysUserData.deleteByIds(lsUserList.stream().map(SysUser::getId).collect(Collectors.toList())); + //删除字典类型 //删除字典数据 //删除系统配置 sysTenantData.deleteById(id); + } @Override @@ -288,7 +401,60 @@ public class SysTenantServiceImpl implements ISysTenantService { } @Override - public Boolean syncTenantPackage(Long tenantId, String packageId) { - return false; + public Boolean syncTenantPackage(SysTenantUpdateBo sysTenant) { + syncTenantRole(sysTenant); + return true; + } + + + /** + * 根据租户菜单修改租户角色 + * + * @param sysTenant 租户编号 + * @return 角色id + */ + @Transactional + @Modifying + public void syncTenantRole(SysTenantUpdateBo sysTenant) { + // 获取租户套餐 + SysTenantPackage tenantPackage = sysTenantPackageData.findById(sysTenant.getPackageId()); + if (ObjectUtil.isNull(tenantPackage)) { + throw new BizException(ErrCode.PACKAGE_NOT_FOUND); + } + SysTenant sysTenant1 = sysTenantData.findById(sysTenant.getTenantId()); + if(ObjectUtil.isEmpty(sysTenant1)){ + throw new BizException(ErrCode.TENANT_NOT_FOUND); + } + /* if(sysTenant1.getPackageId() == sysTenant.getPackageId() || sysTenant1.getPackageId().equals(sysTenant.getPackageId())){ + return; + }*/ + // 获取套餐菜单id + List menuIds = StringUtils.splitTo(tenantPackage.getMenuIds(), Convert::toLong); + //查询角色 + + // 创建角色 + SysRole role = new SysRole(); + role.setTenantId(sysTenant.getTenantId()); + //role.setRoleName(sysTenant.getCompanyName()+TenantConstants.TENANT_ADMIN_ROLE_NAME); + role.setRoleKey(TenantConstants.TENANT_ADMIN_ROLE_KEY); + // role.setRoleSort(1); + // role.setRemark(TenantConstants.TENANT_ADMIN_ROLE_NAME); + role.setStatus(TenantConstants.NORMAL); + SysRole retRole=sysRoleData.findOneByCondition(role); + if(ObjectUtil.isEmpty(retRole)){ + return; + } + Long roleId = retRole.getId(); + //先删除 + sysRoleMenuData.deleteByRoleId(Collections.singletonList(retRole.getId())); + // 创建角色菜单 + List roleMenus = new ArrayList<>(menuIds.size()); + menuIds.forEach(menuId -> { + SysRoleMenu roleMenu = new SysRoleMenu(); + roleMenu.setRoleId(roleId); + roleMenu.setMenuId(menuId); + roleMenus.add(roleMenu); + }); + sysRoleMenuData.insertBatch(roleMenus); } } diff --git a/iot-module/iot-system/src/main/java/cc/iotkit/system/service/impl/SysUserServiceImpl.java b/iot-module/iot-system/src/main/java/cc/iotkit/system/service/impl/SysUserServiceImpl.java index 5a01c4d..17d61b8 100644 --- a/iot-module/iot-system/src/main/java/cc/iotkit/system/service/impl/SysUserServiceImpl.java +++ b/iot-module/iot-system/src/main/java/cc/iotkit/system/service/impl/SysUserServiceImpl.java @@ -30,6 +30,7 @@ import cc.iotkit.common.enums.ErrCode; import cc.iotkit.common.exception.BizException; import cc.iotkit.common.satoken.utils.LoginHelper; import cc.iotkit.common.service.UserService; +import cc.iotkit.common.tenant.helper.TenantHelper; import cc.iotkit.common.utils.MapstructUtils; import cc.iotkit.common.utils.StreamUtils; import cc.iotkit.data.system.*; @@ -92,6 +93,13 @@ public class SysUserServiceImpl implements ISysUserService, UserService { if(ObjectUtil.isNotNull(query.getData().getParams()) && !"".equals(query.getData().getParams().get("endTime"))) { condition.getData().setParams(query.getData().getParams()); }// 手动补全Map字段 + if(!LoginHelper.isSuperAdmin()) { + SysUser sysUser = sysUserData.findById(LoginHelper.getUserId()); + condition.getData().setDeptId(sysUser.getDeptId()); + condition.getData().setDept(sysUser.getDept()); + condition.getData().setAreaDept(sysUser.getAreaDept()); + } + return sysUserData.findAll(condition).to(SysUserVo.class); } diff --git a/iot-starter/pom.xml b/iot-starter/pom.xml index 8616bf2..4df03fe 100644 --- a/iot-starter/pom.xml +++ b/iot-starter/pom.xml @@ -231,6 +231,7 @@ + diff --git a/iot-starter/src/main/java/cc/iotkit/web/controller/AuthController.java b/iot-starter/src/main/java/cc/iotkit/web/controller/AuthController.java index ac7d63e..26b47eb 100644 --- a/iot-starter/src/main/java/cc/iotkit/web/controller/AuthController.java +++ b/iot-starter/src/main/java/cc/iotkit/web/controller/AuthController.java @@ -31,13 +31,16 @@ import cc.iotkit.common.redis.utils.RedisUtils; import cc.iotkit.common.utils.StreamUtils; import cc.iotkit.common.utils.StringUtils; import cc.iotkit.data.manager.IDeviceInfoData; +import cc.iotkit.model.system.SysUser; import cc.iotkit.system.dto.LoginBody; import cc.iotkit.system.dto.RegisterBody; import cc.iotkit.system.dto.bo.SysTenantBo; import cc.iotkit.system.dto.bo.XcxLoginBo; import cc.iotkit.system.dto.vo.SysTenantVo; +import cc.iotkit.system.dto.vo.SysUserVo; import cc.iotkit.system.service.ISysConfigService; import cc.iotkit.system.service.ISysTenantService; +import cc.iotkit.system.service.ISysUserService; import cc.iotkit.web.domain.vo.LoginTenantVo; import cc.iotkit.web.domain.vo.LoginVo; import cc.iotkit.web.domain.vo.TenantListVo; @@ -64,6 +67,8 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import static cc.iotkit.common.web.core.BaseController.fail; + /** * 认证 * @@ -81,7 +86,7 @@ public class AuthController { private final SysRegisterService registerService; private final ISysConfigService configService; private final ISysTenantService tenantService; - + private final ISysUserService isUserService; /** * 登录方法 * @@ -94,11 +99,19 @@ public class AuthController { LoginBody loginBody = body.getData(); LoginVo loginVo = new LoginVo(); // 生成令牌 + SysUserVo sysUser = isUserService.selectUserByUserName(loginBody.getUsername()); + //SysUser sysUser = userData.selectUserByUserName(username); + if(sysUser==null){ + fail("用户不存在"); + } + loginBody.setTenantId(sysUser.getTenantId()); + // tenantId = sysUser.getTenantId(); String token = loginService.login( loginBody.getTenantId(), loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), loginBody.getUuid()); loginVo.setToken(token); + loginVo.setTenandtId(sysUser.getTenantId()); return loginVo; } /** @@ -136,7 +149,7 @@ public class AuthController { String code = RandomUtil.randomNumbers(4); RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION)); // 验证码模板id 自行处理 (查数据库或写死均可) - String templateId = "SMS_235815708"; + String templateId = "SMS_490830144"; LinkedHashMap map = new LinkedHashMap<>(1); map.put("code", code); SmsBlend smsBlend = SmsFactory.createSmsBlend(SupplierType.ALIBABA); diff --git a/iot-starter/src/main/java/cc/iotkit/web/domain/vo/LoginVo.java b/iot-starter/src/main/java/cc/iotkit/web/domain/vo/LoginVo.java index df74b13..943a29f 100644 --- a/iot-starter/src/main/java/cc/iotkit/web/domain/vo/LoginVo.java +++ b/iot-starter/src/main/java/cc/iotkit/web/domain/vo/LoginVo.java @@ -35,4 +35,5 @@ public class LoginVo { private String token; private String openid; + private Long tenandtId; } diff --git a/iot-starter/src/main/java/cc/iotkit/web/service/SysLoginService.java b/iot-starter/src/main/java/cc/iotkit/web/service/SysLoginService.java index 21ecedd..8936f92 100644 --- a/iot-starter/src/main/java/cc/iotkit/web/service/SysLoginService.java +++ b/iot-starter/src/main/java/cc/iotkit/web/service/SysLoginService.java @@ -39,6 +39,7 @@ import cc.iotkit.common.tenant.helper.TenantHelper; import cc.iotkit.common.utils.*; import cc.iotkit.common.web.config.properties.CaptchaProperties; import cc.iotkit.common.web.utils.ServletUtils; +import cc.iotkit.data.config.TenantContext; import cc.iotkit.data.manager.IUserInfoData; import cc.iotkit.data.system.ISysUserData; import cc.iotkit.manager.dto.bo.space.HomeBo; @@ -70,6 +71,8 @@ import java.time.Duration; import java.util.*; import java.util.function.Supplier; +import static cc.iotkit.common.web.core.BaseController.fail; + /** * 登录校验方法 * @@ -109,6 +112,7 @@ public class SysLoginService { public String login(Long tenantId, String username, String password, String code, String uuid) { boolean captchaEnabled = captchaProperties.getEnable(); // 验证码开关 + if (captchaEnabled) { validateCaptcha(tenantId, username, code, uuid); } @@ -167,29 +171,42 @@ public class SysLoginService { public LoginVo xcxLogin(String appId, String xcxCode, String username, String password) { // xcxCode 为 小程序调用 wx.login 授权后获取 + TenantContext.disableTenantFilter(); SysAppVo sysApp=appService.queryByAppId(appId); if(sysApp==null){ - throw new BizException("该应用未授权注册"); + fail("该应用未授权注册"); } LoginVo loginVo = new LoginVo(); String openid = WeChatUtil.getOpenId(appId,sysApp.getAppSecret(),xcxCode); + if(ObjectUtil.isNull(openid)){ + fail("获取用户openid失败"); + } loginVo.setOpenid(openid); UserInfo user = new UserInfo(); try { - LoginHelper.setTenantId(sysApp.getTenantId()); - user = loadUserByOpenid(openid,sysApp.getTenantId()); + + user = loadUserByOpenid(openid,username); + //UserInfo user1 = loadUserByOpenid(username,sysApp.getTenantId()); + /* if(ObjectUtil.isNotEmpty(user)){ + if(!user.getUserName().equals(username)){ + throw new BizException("该用户未注册"); + } + }*/ } catch (Exception e) { e.printStackTrace(); } if(ObjectUtil.isEmpty(user) || ObjectUtil.isNull(user)){ - throw new BizException("用户不存在,请先注册"); + fail("用户不存在,请先注册"); + } + LoginHelper.setTenantId(user.getTenantId()); UserInfo user1 = user; checkLogin(LoginType.PASSWORD, sysApp.getTenantId(), username, () -> { try { return !AuthUtil.checkPwd(password, user1.getSecret()); } catch (Exception e) { + fail("密码错误"); throw new BizException("密码错误"); } }); @@ -204,14 +221,14 @@ public class SysLoginService { loginUser.setUsername(user.getNickName()); loginUser.setUserType(UserType.APP_USER.getUserType()); loginUser.setOpenid(openid); - loginUser.setTenantId(sysApp.getTenantId()); + loginUser.setTenantId(user.getTenantId()); // 生成token LoginHelper.loginByDevice(loginUser, DeviceType.XCX); - recordLoginInfo(loginUser.getTenantId(), user.getNickName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); // recordLoginInfo(user.getId()); loginVo.setToken(StpUtil.getTokenValue()); + loginVo.setTenandtId(user.getTenantId()); return loginVo; } public String xcxRegister(String appId,String xcxCode,String username,String password,String smsCode) { @@ -220,13 +237,24 @@ public class SysLoginService { //校验验证码 validateSmsCode(sysApp.getTenantId(), username, smsCode); if(sysApp==null){ - throw new BizException("该应用未授权注册"); + fail("该应用未授权注册"); + // throw new BizException("该应用未授权注册"); + } + if("".equals(username) ||ObjectUtil.isNull(username)){ + fail("请输入账号"); + // throw new BizException("请输入账号"); } String openid = WeChatUtil.getOpenId(appId,sysApp.getAppSecret(),xcxCode); - UserInfo user=userInfoData.findByUid(openid); + // UserInfo user=userInfoData.findByUid(openid); + UserInfo user=userInfoData.findByUserName(username); if(ObjectUtil.isNotEmpty(user)){ - throw new BizException("该用户已存在"); + fail("该用户已存在"); + } + /* if(ObjectUtil.isNotEmpty(user)){ + if(user.getUserName().equals(username)) + throw new BizException("该用户已存在"); + }*/ // UserInfo user = new UserInfo(); try { LoginHelper.setTenantId(sysApp.getTenantId()); @@ -386,6 +414,7 @@ public class SysLoginService { private UserInfo loadUserByOpenid(String openid,Long tenantId) throws Exception { // 使用 openid 查询绑定用户 如未绑定用户 则根据业务自行处理 例如 创建默认用户 UserInfo user=userInfoData.findByUid(openid); + /* if (ObjectUtil.isNull(user)) { log.info("小程序用户:{} 不存在,开始初始化", openid); user=new UserInfo(); @@ -417,6 +446,13 @@ public class SysLoginService { }*/ return user; } + private UserInfo loadUserByOpenid(String openid,String username) throws Exception { + // 使用 openid 查询绑定用户 如未绑定用户 则根据业务自行处理 例如 创建默认用户 + UserInfo user=userInfoData.findByUserName(username); + + return user; + } + //小程序注册 private UserInfo loadUserByOpenidRegister(String openid,Long tenantId,String username,String password) throws Exception { // 使用 openid 查询绑定用户 如未绑定用户 则根据业务自行处理 例如 创建默认用户 diff --git a/iot-starter/src/main/resources/application-dev.yml b/iot-starter/src/main/resources/application-dev.yml index ef1d61d..fa0d306 100644 --- a/iot-starter/src/main/resources/application-dev.yml +++ b/iot-starter/src/main/resources/application-dev.yml @@ -45,13 +45,13 @@ spring: jpa: database: MySQL database-platform: org.hibernate.dialect.MySQL5InnoDBDialect - show-sql: true + show-sql: false hibernate: ddl-auto: update properties: hibernate: - format_sql: true - use_sql_comments: true # 输出SQL注释 + format_sql: false + use_sql_comments: false # 输出SQL注释 session_factory: # statement_inspector: com.example.TenantSQLInterceptor # dialect: org.hibernate.dialect.MySQL5Dialect @@ -59,9 +59,10 @@ spring: type: com.zaxxer.hikari.HikariDataSource driverClassName: com.mysql.cj.jdbc.Driver # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562 - url: jdbc:mysql://192.168.10.29:3306/hma_iot?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false + url: jdbc:mysql://123.57.78.108:3306/hma_iot?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useSSL=false username: root - password: CGKhbMfrdz6w3icX + password: 1093e4769496a6ed + #password: CGKhbMfrdz6w3icX hikari: connection-timeout: 10000 idle-timeout: 60000 # 经过idle-timeout时间如果连接还处于空闲状态, 该连接会被回收 @@ -80,9 +81,9 @@ spring: rest: #使用内置es的配置 #uris: http://elasticsearch:9200 - uris: http://192.168.10.14:9301 - username: - password: + uris: http://123.57.78.108:9301 + username: elastic + password: hmkj@2023 connection-timeout: 10s #================es时序数据配置结束===============>> @@ -108,7 +109,7 @@ spring: embedded: enabled: false #host: redis - host: 192.168.10.14 + host: 123.57.78.108 port: 6379 database: 11 password: HMkj@2023 @@ -164,7 +165,7 @@ captcha: user: password: # 密码最大错误次数 - maxRetryCount: 5 + maxRetryCount: 100 # 密码锁定时间(默认10分钟) lockTime: 10 @@ -220,11 +221,11 @@ sms: #请求地址 默认为 dysmsapi.aliyuncs.com 如无特殊改变可以不用设置 requestUrl: dysmsapi.aliyuncs.com #阿里云的accessKey - accessKeyId: LTAI5tC3orqkvCeHhihvfAet + accessKeyId: LTAI5tRvZgzGtmvTgmL3Zxre #阿里云的accessKeySecret - accessKeySecret: mTRyGL2J4IywsRWFu0ugMjncjQzAML + accessKeySecret: FkHPDXJ8l3RRTRUqa4wDf8c3DIoZqI #短信签名 - signature: 河南华码信息科技 + signature: 天津费加罗电子 tencent: #请求地址默认为 sms.tencentcloudapi.com 如无特殊改变可不用设置 requestUrl: sms.tencentcloudapi.com @@ -242,8 +243,8 @@ wx: mp: # 公众号配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md 文档 # app-id: wx041349c6f39b268b # 测试号(牛希尧提供的) # secret: 5abee519483bc9f8cb37ce280e814bd0 - app-id: wx5b23ba7a5589ecbb # 测试号(自己的) - secret: 2a7b3b20c537e52e74afd395eb85f61f + app-id: wxe91b094575c77799 # 测试号(自己的) + secret: f82e4e73c8d5f3ff2ee2e3c128b88a66 # app-id: wxa69ab825b163be19 # 测试号(Kongdy 提供的) # secret: bd4f9fab889591b62aeac0d7b8d8b4a0 # 存储配置,解决 AccessToken 的跨节点的共享 @@ -256,8 +257,8 @@ wx: # secret: 333ae72f41552af1e998fe1f54e1584a #appid: wx53b5ac263b9cdb5b # wenhualian的接口测试号 #secret: baa127ca662344cf9b0b8e52b26bac9d - appid: wx756050a3772987c8 # 安强净水的接口测试号 - secret: 4dc7df1922d7cf210ccbc086bc473de8 + appid: wxe91b094575c77799 # 测试号 + secret: f82e4e73c8d5f3ff2ee2e3c128b88a66 # appid: wxc4598c446f8a9cb3 # 测试号(Kongdy 提供的) # secret: 4a1a04e07f6a4a0751b39c3064a92c8b config-storage: diff --git a/iot-starter/src/main/resources/application.yml b/iot-starter/src/main/resources/application.yml index 2c9e3fc..e535528 100644 --- a/iot-starter/src/main/resources/application.yml +++ b/iot-starter/src/main/resources/application.yml @@ -6,9 +6,9 @@ spring: # active: test # 使用application-test.yml 配置 # active: mysql # 使用application-mysql.yml 配置 minio: - server: http://221.176.140.236 - port: 9200 - endpoint: http://mini.huamar.com/ + server: http://123.57.78.108 + port: 19000 + endpoint: https://minio.tjfserver.com/ access-key: ruoyi secret-key: ruoyi123 bucket: feijialuo diff --git a/pom.xml b/pom.xml index 10ccb76..7c3a11b 100644 --- a/pom.xml +++ b/pom.xml @@ -436,6 +436,7 @@ + org.apache.maven.plugins