diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index 924518fac..44f3555a0 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -121,6 +121,14 @@ 3.5.1 + + + + com.getui.push + restful-sdk + 1.0.5.0 + + diff --git a/ruoyi-admin/src/main/java/org/dromara/DromaraApplication.java b/ruoyi-admin/src/main/java/org/dromara/DromaraApplication.java index 8ef33fe5f..a45b40b96 100644 --- a/ruoyi-admin/src/main/java/org/dromara/DromaraApplication.java +++ b/ruoyi-admin/src/main/java/org/dromara/DromaraApplication.java @@ -3,6 +3,7 @@ package org.dromara; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup; +import org.springframework.scheduling.annotation.EnableScheduling; /** * 启动程序 @@ -10,6 +11,7 @@ import org.springframework.boot.context.metrics.buffering.BufferingApplicationSt * @author Lion Li */ +@EnableScheduling @SpringBootApplication public class DromaraApplication { diff --git a/ruoyi-admin/src/main/java/org/dromara/web/config/GeTuiConfig.java b/ruoyi-admin/src/main/java/org/dromara/web/config/GeTuiConfig.java new file mode 100644 index 000000000..968ecebb6 --- /dev/null +++ b/ruoyi-admin/src/main/java/org/dromara/web/config/GeTuiConfig.java @@ -0,0 +1,42 @@ +package org.dromara.web.config; + +import com.getui.push.v2.sdk.ApiHelper; +import com.getui.push.v2.sdk.GtApiConfiguration; +import com.getui.push.v2.sdk.api.PushApi; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; + +public class GeTuiConfig { + + @Value("${getui.baseUrl}") + private String baseUrl; + + @Value("${getui.appId}") + private String appId; + + @Value("${getui.appKey}") + private String appKey; + + @Value("${getui.appSecret}") + private String appSecret; + + @Value("${getui.masterSecret}") + private String masterSecret; + + @Bean(name = "pushApi") + public PushApi pushApi() { + GtApiConfiguration apiConfiguration = new GtApiConfiguration(); + //填写应用配置 + apiConfiguration.setAppId(appId); + apiConfiguration.setAppKey(appKey); + apiConfiguration.setMasterSecret(masterSecret); + // 接口调用前缀,请查看文档: 接口调用规范 -> 接口前缀, 可不填写appId + apiConfiguration.setDomain(baseUrl); + // 实例化ApiHelper对象,用于创建接口对象 + ApiHelper apiHelper = ApiHelper.build(apiConfiguration); + // 创建对象,建议复用。目前有PushApi、StatisticApi、UserApi + PushApi pushApi = apiHelper.creatApi(PushApi.class); + return pushApi; + } + +} diff --git a/ruoyi-admin/src/main/java/org/dromara/web/domain/vo/EqUserEquipmentVo.java b/ruoyi-admin/src/main/java/org/dromara/web/domain/vo/EqUserEquipmentVo.java index f06531828..11c5978ec 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/domain/vo/EqUserEquipmentVo.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/domain/vo/EqUserEquipmentVo.java @@ -41,6 +41,12 @@ public class EqUserEquipmentVo implements Serializable { @ExcelProperty(value = "绑定账号") private String userName; + /** + * 帐号状态(0正常 1停用) + */ + @ExcelProperty(value = "账号状态") + private String status; + /** * 绑定设备(个) */ diff --git a/ruoyi-admin/src/main/java/org/dromara/web/msg/Msg.java b/ruoyi-admin/src/main/java/org/dromara/web/msg/Msg.java new file mode 100644 index 000000000..b16a4865f --- /dev/null +++ b/ruoyi-admin/src/main/java/org/dromara/web/msg/Msg.java @@ -0,0 +1,19 @@ +package org.dromara.web.msg; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName : Msg + * @Author : ZZC + * @Date : 2024/10/20 20:39 + * @Description : + **/ +@Data +public class Msg implements Serializable { + private String cid; + private String title; + private String content; + private String uid; +} diff --git a/ruoyi-admin/src/main/java/org/dromara/web/msg/PushUtils.java b/ruoyi-admin/src/main/java/org/dromara/web/msg/PushUtils.java new file mode 100644 index 000000000..0edeaa9a4 --- /dev/null +++ b/ruoyi-admin/src/main/java/org/dromara/web/msg/PushUtils.java @@ -0,0 +1,150 @@ +package org.dromara.web.msg; + +import com.getui.push.v2.sdk.api.PushApi; +import com.getui.push.v2.sdk.api.UserApi; +import com.getui.push.v2.sdk.common.ApiResult; +import com.getui.push.v2.sdk.dto.CommonEnum; +import com.getui.push.v2.sdk.dto.req.Audience; +import com.getui.push.v2.sdk.dto.req.Settings; +import com.getui.push.v2.sdk.dto.req.Strategy; +import com.getui.push.v2.sdk.dto.req.message.PushChannel; +import com.getui.push.v2.sdk.dto.req.message.PushDTO; +import com.getui.push.v2.sdk.dto.req.message.PushMessage; +import com.getui.push.v2.sdk.dto.req.message.android.AndroidDTO; +import com.getui.push.v2.sdk.dto.req.message.android.ThirdNotification; +import com.getui.push.v2.sdk.dto.req.message.android.Ups; +import com.getui.push.v2.sdk.dto.req.message.ios.Alert; +import com.getui.push.v2.sdk.dto.req.message.ios.Aps; +import com.getui.push.v2.sdk.dto.req.message.ios.IosDTO; +import com.google.common.collect.Sets; +import org.dromara.common.core.domain.R; +import org.springframework.beans.factory.annotation.Autowired; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.Map; + +public class PushUtils { + + @Resource + PushApi pushApi; + + UserApi userApi; + + /** + * 查询用户状态 + * + * @param cid 客户端标识 + */ + public void queryUserStatus(String cid) { + System.out.println(userApi.queryUserStatus(Sets.newHashSet(cid))); + } + + /** + * 根据CID单推 + * + * @throws InterruptedException + */ + public R>> pushToSingleByCid(Msg msg) { + PushDTO pushDTO = pushDTO(msg); + // 设置接收人信息 + Audience audience = new Audience(); + // 客户端标记 + audience.addCid(msg.getCid()); + pushDTO.setAudience(audience); + + pushDTO.setRequestId(System.currentTimeMillis() + ""); + ApiResult>> apiResult = pushApi.pushToSingleByCid(pushDTO); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + } + if (apiResult.isSuccess()) { + return R.ok(apiResult.getMsg(), apiResult.getData()); + } else { + return R.warn(apiResult.getMsg(), apiResult.getData()); + } + } + + /** + * 个推CID + * + * @return + */ + private PushDTO pushDTO(Msg msg) { + // 根据CID进行单推 + PushDTO pushDTO = new PushDTO(); + // 设置推送参数 + pushDTO.setRequestId(System.currentTimeMillis() + ""); + pushDTO.setGroupName("g-name1"); + + Settings settings = new Settings(); + // 消息离线时间设置,单位毫秒,-1表示不设离线,-1 ~ 3 * 24 * 3600 * 1000(3天)之间 + settings.setTtl(3600000); + /** + * 【厂商通道策略】 + * + * 默认所有通道的策略选择1-4 + * 1: 表示该消息在用户在线时推送个推通道,用户离线时推送厂商通道; + * 2: 表示该消息只通过厂商通道策略下发,不考虑用户是否在线; + * 3: 表示该消息只通过个推通道下发,不考虑用户是否在线; + * 4: 表示该消息优先从厂商通道下发,若消息内容在厂商通道代发失败后会从个推通道下发。 + * */ + Strategy strategy = new Strategy(); + strategy.setSt(2); + settings.setStrategy(strategy); + + pushDTO.setSettings(settings); + /** 设置个推通道参数 */ + PushMessage pushMessage = new PushMessage(); + // 厂商消息内容 + pushMessage.setTransmission(" {title:\"" + msg.getTitle() + "\",content:\"" + msg.getContent() + "\",uid:\"" + msg.getUid() + "\",read:false}"); + pushDTO.setPushMessage(pushMessage); + // 厂商通道消息内容 + PushChannel pushChannel = new PushChannel(); + // 配置安卓产商参数 + AndroidDTO androidDTO = new AndroidDTO(); + Ups ups = new Ups(); + ThirdNotification thirdNotification = new ThirdNotification(); + thirdNotification.setClickType(CommonEnum.ClickTypeEnum.TYPE_STARTAPP.type); + // 离线消息【标题】 + thirdNotification.setTitle(msg.getTitle()); + // 离线消息【正文】 + thirdNotification.setBody(msg.getContent()); + ups.setNotification(thirdNotification); + + // 设置options 方式一 + ups.addOption("HW", "badgeAddNum", 3); + ups.addOption("HW", "badgeClass", "com.getui.demo.GetuiSdkDemoActivity"); + ups.addOption("OP", "app_message_id", 11); + ups.addOption("VV", "message_sort", 1); + ups.addOptionAll("channel", "default"); + + // 设置options 方式二 + Map> options = new HashMap>(); + Map all = new HashMap(); + all.put("channel", "default"); + options.put("ALL", all); + Map hw = new HashMap(); + all.put("badgeAddNum", 3); + all.put("badgeClass", "com.getui.demo.GetuiSdkDemoActivity"); + options.put("HW", hw); + ups.setOptions(options); + + androidDTO.setUps(ups); + pushChannel.setAndroid(androidDTO); + + IosDTO iosDTO = new IosDTO(); + Aps aps = new Aps(); + Alert alert = new Alert(); + alert.setTitle("title-" + System.currentTimeMillis()); + alert.setBody("ios_body"); + aps.setAlert(alert); + iosDTO.setAps(aps); + pushChannel.setIos(iosDTO); + pushDTO.setPushChannel(pushChannel); + + return pushDTO; + } + +} diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/IEqEquipmentLogService.java b/ruoyi-admin/src/main/java/org/dromara/web/service/IEqEquipmentLogService.java index aa3a5e536..5e3a4d1fa 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/service/IEqEquipmentLogService.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/service/IEqEquipmentLogService.java @@ -65,4 +65,11 @@ public interface IEqEquipmentLogService { * @return 是否删除成功 */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 删除指定日期之前的数据 + * @param date + * @return + */ + int deleteLogBeforeDate(String date); } diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/EqEquipmentLogServiceImpl.java b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/EqEquipmentLogServiceImpl.java index caa5707e5..afcdd0999 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/EqEquipmentLogServiceImpl.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/EqEquipmentLogServiceImpl.java @@ -140,4 +140,11 @@ public class EqEquipmentLogServiceImpl implements IEqEquipmentLogService { } return baseMapper.deleteByIds(ids) > 0; } + + @Override + public int deleteLogBeforeDate(String date) { + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.le(EqEquipmentLog::getCreatedYearDay,date); + return baseMapper.delete(lqw); + } } diff --git a/ruoyi-admin/src/main/java/org/dromara/web/task/DataTask.java b/ruoyi-admin/src/main/java/org/dromara/web/task/DataTask.java new file mode 100644 index 000000000..13dc9a962 --- /dev/null +++ b/ruoyi-admin/src/main/java/org/dromara/web/task/DataTask.java @@ -0,0 +1,55 @@ +package org.dromara.web.task; + +import lombok.extern.slf4j.Slf4j; +import org.dromara.web.service.IEqEquipmentLogService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.Date; + +/** + * @ClassName : DataTask + * @Author : ZZC + * @Date : 2024/10/18 23:53 + * @Description : 数据任务 + **/ +@Component +@Slf4j +public class DataTask { + + @Autowired + private IEqEquipmentLogService logService; + +// cron表达式 +// 秒,分,时,日,月,星期 + +// "0 0 * * * *" 表示每小时0分0秒执行一次 +// " */10 * * * * *" 表示每10秒执行一次 +// "0 0 8-10 * * *" 表示每天8,9,10点执行 +// "0 0/30 8-10 * * *" 表示每天8点到10点,每半小时执行 +// "0 0 9-17 * * MON-FRI" 表示每周一至周五,9点到17点的0分0秒执行 +// "0 0 0 25 12 ?" 表示每年圣诞节(12月25日)0时0分0秒执行 +// @Scheduled(fixedRate = 5000) 每隔5秒执行一次定时任务 +// @Scheduled(fixedRate = 5000) :上一次开始执行时间点之后5秒再执行 +// @Scheduled(fixedDelay = 5000) :上一次执行完毕时间点之后5秒再执行 +// @Scheduled(initialDelay=1000, fixedRate=5000) :第一次延迟1秒后执行,之后按fixedRate的规则每5秒执行一次 + + +// @Scheduled(cron = "0/5 * * * * ?") //每5秒执行一次 +// @Scheduled(cron = "0 0 * * * ?") //每小时执行一次(在每小时的开始处) +// @Scheduled(cron = "0 0 0 * * ?")//每天执行一次(在每天的开始处) + @Scheduled(cron = "0 0 0 1 * ?")//每月执行一次(在每月的第一天的开始处) +// @Scheduled(cron = "0 0 0 1 1 ?")//每年执行一次(在每年的1月1日的开始处) + public void timeTask(){ + log.info("定时任务:"+new Date()); + LocalDate currentDate = LocalDate.now(); + LocalDate startTime = currentDate.minusMonths(12);//获取当前日期的前12个月 + String yearMonthDay = startTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); + int deleteNum = logService.deleteLogBeforeDate(yearMonthDay); + log.info("定时删除日志数量:"+deleteNum); + } + +} diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml index 2bb1fa9a1..c854d2526 100644 --- a/ruoyi-admin/src/main/resources/application-dev.yml +++ b/ruoyi-admin/src/main/resources/application-dev.yml @@ -267,3 +267,12 @@ iot: operate: /api/plugins/rpc/oneway/{deviceId} device: /api/device/{deviceId} deviceByName: /api/tenant/devices?deviceName={deviceName} + +# 个推 +getui: + baseUrl: https://restapi.getui.com/v2/ + # 配置管理、应用配置中获取 + appId: npL6vVou0R9ht97RS78uG8 + appKey: v4bFxTyIbg58qrGuTH8N03 + appSecret: T5Rak0PGsc9ingNvrtSWo8 + masterSecret: Cejg8JZIH790HTeEaq20b1 diff --git a/ruoyi-admin/src/main/resources/mapper/device/EqEquipmentMapper.xml b/ruoyi-admin/src/main/resources/mapper/device/EqEquipmentMapper.xml index a28102342..1a903274c 100644 --- a/ruoyi-admin/src/main/resources/mapper/device/EqEquipmentMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/device/EqEquipmentMapper.xml @@ -28,6 +28,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" s.user_id, s.nick_name, s.user_name, + s.status, COUNT(e.equipment_id) AS bind_num, -- 设备总数 SUM(CASE WHEN e.line_status = 0 THEN 1 ELSE 0 END) AS offline_num, -- 离线个数 SUM(CASE WHEN e.line_status = 1 THEN 1 ELSE 0 END) AS online_num -- 在线个数 @@ -38,6 +39,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ON e.user_id = s.user_id s.user_type='app_user' + and s.del_flag = 0 AND s.nick_name like CONCAT('%', #{nickName}, '%')