diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceXinghanController.java b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceXinghanController.java index 85fb39a0..d60d321e 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceXinghanController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceXinghanController.java @@ -83,7 +83,7 @@ public class AppDeviceXinghanController extends BaseController { } /** - * SOS档位 + * SOS档位s * SOS档位,2,1,0, 分别表示红蓝模式/爆闪模式/关闭 */ @PostMapping("/SOSGradeSettings") diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/listener/RedisKeyExpirationListener.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/listener/RedisKeyExpirationListener.java index 11305d19..b3f64ecd 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/listener/RedisKeyExpirationListener.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/listener/RedisKeyExpirationListener.java @@ -1,5 +1,9 @@ package com.fuyuanshen.global.mqtt.listener; +import cn.hutool.core.thread.ThreadUtil; +import com.baomidou.lock.LockInfo; +import com.baomidou.lock.LockTemplate; +import com.baomidou.lock.executor.RedissonLockExecutor; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.fuyuanshen.common.core.constant.GlobalConstants; import com.fuyuanshen.common.redis.utils.RedisUtils; @@ -32,6 +36,9 @@ public class RedisKeyExpirationListener implements MessageListener { @Autowired private DeviceMapper deviceMapper; + @Autowired + private LockTemplate lockTemplate; + @Override public void onMessage(Message message, byte[] pattern) { String expiredKey = new String(message.getBody()); @@ -40,16 +47,43 @@ public class RedisKeyExpirationListener implements MessageListener { String element = expiredKey.substring(FUNCTION_ACCESS_KEY.length()); handleFunctionAccessExpired(element); } - if(expiredKey.endsWith(DEVICE_ONLINE_STATUS_KEY_PREFIX)){ + if(expiredKey.endsWith(DEVICE_ONLINE_STATUS_KEY_PREFIX)) { +// threadPoolTaskExecutor.execute(() -> { +// log.info("设备离线:{}", expiredKey); +// String element = expiredKey.substring(GlobalConstants.GLOBAL_REDIS_KEY.length() + DEVICE_KEY_PREFIX.length(), expiredKey.length() - DEVICE_ONLINE_STATUS_KEY_PREFIX.length()); +// UpdateWrapper deviceUpdateWrapper = new UpdateWrapper<>(); +// deviceUpdateWrapper.eq("device_imei", element); +// deviceUpdateWrapper.set("online_status", 0); +// deviceMapper.update(deviceUpdateWrapper); +// }); + threadPoolTaskExecutor.execute(() -> { log.info("设备离线:{}", expiredKey); String element = expiredKey.substring(GlobalConstants.GLOBAL_REDIS_KEY.length() + DEVICE_KEY_PREFIX.length(), expiredKey.length() - DEVICE_ONLINE_STATUS_KEY_PREFIX.length()); - UpdateWrapper deviceUpdateWrapper = new UpdateWrapper<>(); - deviceUpdateWrapper.eq("device_imei", element); - deviceUpdateWrapper.set("online_status", 0); - deviceMapper.update(deviceUpdateWrapper); + + // 构造设备锁键 + String deviceLockKey = GlobalConstants.GLOBAL_REDIS_KEY + ":device_lock:" + element; + + // 尝试获取Redis锁 + LockInfo lockInfo = lockTemplate.lock(deviceLockKey, 30000L, 5000L, RedissonLockExecutor.class); // 30秒过期 + + if (lockInfo != null) { + try { + UpdateWrapper deviceUpdateWrapper = new UpdateWrapper<>(); + deviceUpdateWrapper.eq("device_imei", element); + deviceUpdateWrapper.set("online_status", 0); + deviceMapper.update(deviceUpdateWrapper); + } finally { + //释放锁 + lockTemplate.releaseLock(lockInfo); + } + } else { + log.warn("无法获取设备锁,跳过设备离线处理: {}", element); + } }); } + + } /** * 访问key过期事件 diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceShareController.java b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceShareController.java index e271fc64..02790e67 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceShareController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceShareController.java @@ -1,20 +1,35 @@ package com.fuyuanshen.web.controller.device; +import cn.dev33.satoken.annotation.SaIgnore; +import cn.hutool.core.util.RandomUtil; import com.fuyuanshen.app.domain.bo.AppDeviceShareBo; import com.fuyuanshen.app.domain.vo.AppDeviceShareVo; +import com.fuyuanshen.common.core.constant.Constants; import com.fuyuanshen.common.core.domain.R; import com.fuyuanshen.common.core.validate.AddGroup; import com.fuyuanshen.common.idempotent.annotation.RepeatSubmit; import com.fuyuanshen.common.mybatis.core.page.PageQuery; import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; +import com.fuyuanshen.common.ratelimiter.annotation.RateLimiter; +import com.fuyuanshen.common.redis.utils.RedisUtils; import com.fuyuanshen.common.web.core.BaseController; import com.fuyuanshen.equipment.domain.bo.DeviceAlarmBo; import com.fuyuanshen.equipment.domain.vo.DeviceAlarmVo; import com.fuyuanshen.web.service.DeviceShareService; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; import lombok.RequiredArgsConstructor; +import org.dromara.sms4j.api.SmsBlend; +import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.core.factory.SmsFactory; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.time.Duration; +import java.util.LinkedHashMap; + +import static com.fuyuanshen.common.core.constant.GlobalConstants.DEVICE_SHARE_CODES_KEY; + /** * 设备分享管理 * @@ -31,12 +46,11 @@ public class DeviceShareController extends BaseController { /** - *查询设备分享列表(web) + * 分享管理列表 */ - // @SaCheckPermission("equipment:alarm:list") - @GetMapping("/list") + @GetMapping("/deviceShareList") public TableDataInfo list(AppDeviceShareBo bo, PageQuery pageQuery) { - return appDeviceShareService.queryWebList(bo, pageQuery); + return appDeviceShareService.queryWebPageList(bo, pageQuery); } @@ -48,4 +62,37 @@ public class DeviceShareController extends BaseController { public R deviceShare(@Validated(AddGroup.class) @RequestBody AppDeviceShareBo bo) { return toAjax(appDeviceShareService.deviceShare(bo)); } + + /** + * 移除分享用户 + * + * @param ids 主键串 + */ + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(appDeviceShareService.remove(ids)); + } + + /** + * 短信验证码 + * + * @param phonenumber 用户手机号 + */ + @SaIgnore + @RateLimiter(key = "#phonenumber", time = 60, count = 1) + @GetMapping("/sms/code") + public R smsCode(@NotBlank(message = "{user.phonenumber.not.blank}") String phonenumber) { + String key = DEVICE_SHARE_CODES_KEY + phonenumber; + String code = RandomUtil.randomNumbers(4); + RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION)); + LinkedHashMap map = new LinkedHashMap<>(1); + map.put("code", code); + SmsBlend smsBlend = SmsFactory.getSmsBlend("config1"); + SmsResponse smsResponse = smsBlend.sendMessage(phonenumber, map); + if (!smsResponse.isSuccess()) { + return R.fail(smsResponse.getData().toString()); + } + return R.ok(); + } } diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/service/DeviceShareService.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/DeviceShareService.java index 9e493b14..9983fc8f 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/service/DeviceShareService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/DeviceShareService.java @@ -60,6 +60,16 @@ public class DeviceShareService { return TableDataInfo.build(result); } + public TableDataInfo queryWebPageList(AppDeviceShareBo bo, PageQuery pageQuery) { +// Long userId = AppLoginHelper.getUserId(); +// bo.setCreateBy(userId); + Page page = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize()); + Page result = appDeviceShareMapper.selectWebDeviceShareList(bo, page); + List records = result.getRecords(); + records.forEach(DeviceShareService::buildDeviceStatus); + return TableDataInfo.build(result); + } + private static void buildDeviceStatus(AppDeviceShareVo item) { // 设备在线状态 String onlineStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + item.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX); diff --git a/fys-modules/fys-app/src/main/resources/mapper/app/AppDeviceShareMapper.xml b/fys-modules/fys-app/src/main/resources/mapper/app/AppDeviceShareMapper.xml index 0b76a8e3..9208f90a 100644 --- a/fys-modules/fys-app/src/main/resources/mapper/app/AppDeviceShareMapper.xml +++ b/fys-modules/fys-app/src/main/resources/mapper/app/AppDeviceShareMapper.xml @@ -50,18 +50,32 @@