From a9187da8138ce4c62a628c1c46388b9eb530b5d3 Mon Sep 17 00:00:00 2001 From: tianyongbao Date: Fri, 24 Oct 2025 20:44:36 +0800 Subject: [PATCH 1/4] =?UTF-8?q?feat:=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=8C=E8=AE=BE=E5=A4=87=E6=8A=A5=E8=AD=A6=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E3=80=81=E5=BE=AE=E4=BF=A1=E7=BC=93=E5=AD=98=E7=94=A8=E6=88=B7?= =?UTF-8?q?=EF=BC=8C=E6=93=8D=E4=BD=9C=E8=AE=B0=E5=BD=95=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=EF=BC=8C=E4=BB=A3=E7=A0=81=E6=8F=90=E4=BA=A4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- intc-admin/Dockerfile | 10 +- .../java/com/intc/IntcUltraApplication.java | 2 +- .../DeviceWarnCombineController.java | 104 ++++++++++ .../controller/DeviceWarnOneController.java | 106 +++++++++++ .../controller/MessageOpRecordController.java | 104 ++++++++++ .../controller/TecentUserCacheController.java | 104 ++++++++++ .../fishery/domain/DeviceWarnCombine.java | 83 ++++++++ .../intc/fishery/domain/DeviceWarnOne.java | 83 ++++++++ .../intc/fishery/domain/MessageOpRecord.java | 61 ++++++ .../intc/fishery/domain/TecentUserCache.java | 46 +++++ .../domain/bo/DeviceWarnCombineBo.java | 87 +++++++++ .../domain/bo/DeviceWarnOneBatchUpdateBo.java | 52 +++++ .../fishery/domain/bo/DeviceWarnOneBo.java | 89 +++++++++ .../fishery/domain/bo/MessageOpRecordBo.java | 63 +++++++ .../fishery/domain/bo/TecentUserCacheBo.java | 46 +++++ .../domain/vo/DeviceWarnCombineVo.java | 99 ++++++++++ .../fishery/domain/vo/DeviceWarnOneVo.java | 120 ++++++++++++ .../fishery/domain/vo/MessageOpRecordVo.java | 101 ++++++++++ .../fishery/domain/vo/TecentUserCacheVo.java | 58 ++++++ .../mapper/DeviceWarnCombineMapper.java | 15 ++ .../fishery/mapper/DeviceWarnOneMapper.java | 15 ++ .../fishery/mapper/MessageOpRecordMapper.java | 15 ++ .../fishery/mapper/TecentUserCacheMapper.java | 15 ++ .../service/IDeviceWarnCombineService.java | 68 +++++++ .../service/IDeviceWarnOneService.java | 70 +++++++ .../service/IMessageOpRecordService.java | 68 +++++++ .../service/ITecentUserCacheService.java | 68 +++++++ .../impl/DeviceWarnCombineServiceImpl.java | 177 ++++++++++++++++++ .../impl/DeviceWarnOneServiceImpl.java | 154 +++++++++++++++ .../impl/MessageOpRecordServiceImpl.java | 159 ++++++++++++++++ .../impl/TecentUserCacheServiceImpl.java | 131 +++++++++++++ .../fishery/DeviceWarnCombineMapper.xml | 6 + .../mapper/fishery/DeviceWarnOneMapper.xml | 6 + .../mapper/fishery/MessageOpRecordMapper.xml | 6 + .../mapper/fishery/TecentUserCacheMapper.xml | 6 + 35 files changed, 2391 insertions(+), 6 deletions(-) create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/DeviceWarnCombineController.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/DeviceWarnOneController.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/MessageOpRecordController.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/TecentUserCacheController.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/DeviceWarnCombine.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/DeviceWarnOne.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/MessageOpRecord.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/TecentUserCache.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/DeviceWarnCombineBo.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/DeviceWarnOneBatchUpdateBo.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/DeviceWarnOneBo.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/MessageOpRecordBo.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/TecentUserCacheBo.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/DeviceWarnCombineVo.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/DeviceWarnOneVo.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/MessageOpRecordVo.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/TecentUserCacheVo.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/DeviceWarnCombineMapper.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/DeviceWarnOneMapper.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/MessageOpRecordMapper.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/TecentUserCacheMapper.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/IDeviceWarnCombineService.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/IDeviceWarnOneService.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/IMessageOpRecordService.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/ITecentUserCacheService.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/DeviceWarnCombineServiceImpl.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/DeviceWarnOneServiceImpl.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/MessageOpRecordServiceImpl.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/TecentUserCacheServiceImpl.java create mode 100644 intc-modules/intc-fishery/src/main/resources/mapper/fishery/DeviceWarnCombineMapper.xml create mode 100644 intc-modules/intc-fishery/src/main/resources/mapper/fishery/DeviceWarnOneMapper.xml create mode 100644 intc-modules/intc-fishery/src/main/resources/mapper/fishery/MessageOpRecordMapper.xml create mode 100644 intc-modules/intc-fishery/src/main/resources/mapper/fishery/TecentUserCacheMapper.xml diff --git a/intc-admin/Dockerfile b/intc-admin/Dockerfile index 0394ccb..f033571 100644 --- a/intc-admin/Dockerfile +++ b/intc-admin/Dockerfile @@ -5,11 +5,11 @@ FROM bellsoft/liberica-openjdk-rocky:17.0.16-cds LABEL maintainer="Lion Li" -RUN mkdir -p /ruoyi/server/logs \ - /ruoyi/server/temp \ - /ruoyi/skywalking/agent +RUN mkdir -p /intc/server/logs \ + /intc/server/temp \ + /intc/skywalking/agent -WORKDIR /ruoyi/server +WORKDIR /intc/server ENV SERVER_PORT=8080 SNAIL_PORT=28080 LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS="" @@ -17,7 +17,7 @@ EXPOSE ${SERVER_PORT} # 暴露 snail job 客户端端口 用于定时任务调度中心通信 EXPOSE ${SNAIL_PORT} -ADD ./target/ruoyi-admin.jar ./app.jar +ADD ./target/intc-admin.jar ./app.jar SHELL ["/bin/bash", "-c"] diff --git a/intc-admin/src/main/java/com/intc/IntcUltraApplication.java b/intc-admin/src/main/java/com/intc/IntcUltraApplication.java index 2cfd5bd..2479cb9 100644 --- a/intc-admin/src/main/java/com/intc/IntcUltraApplication.java +++ b/intc-admin/src/main/java/com/intc/IntcUltraApplication.java @@ -17,7 +17,7 @@ public class IntcUltraApplication { SpringApplication application = new SpringApplication(IntcUltraApplication.class); application.setApplicationStartup(new BufferingApplicationStartup(2048)); application.run(args); - System.out.println("(♥◠‿◠)ノ゙ Intc-Vue-Plus启动成功 ლ(´ڡ`ლ)゙"); + System.out.println("(♥◠‿◠)ノ゙ Intc-Vue-Ultra启动成功 ლ(´ڡ`ლ)゙"); } } diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/DeviceWarnCombineController.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/DeviceWarnCombineController.java new file mode 100644 index 0000000..32902ce --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/DeviceWarnCombineController.java @@ -0,0 +1,104 @@ +package com.intc.fishery.controller; + +import java.util.List; +import com.intc.common.excel.utils.ExcelUtil; +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import com.intc.common.idempotent.annotation.RepeatSubmit; +import com.intc.common.log.annotation.Log; +import com.intc.common.web.core.BaseController; +import com.intc.common.mybatis.core.page.PageQuery; +import com.intc.common.core.domain.R; +import com.intc.common.core.validate.AddGroup; +import com.intc.common.core.validate.EditGroup; +import com.intc.common.log.enums.BusinessType; +import com.intc.fishery.domain.vo.DeviceWarnCombineVo; +import com.intc.fishery.domain.bo.DeviceWarnCombineBo; +import com.intc.fishery.service.IDeviceWarnCombineService; +import com.intc.common.mybatis.core.page.TableDataInfo; + +/** + * 设备告警信息 + * + * @author intc + * @date 2025-10-23 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/fishery/deviceWarnCombine") +public class DeviceWarnCombineController extends BaseController { + + private final IDeviceWarnCombineService deviceWarnCombineService; + + /** + * 查询设备告警信息列表 + */ + @SaCheckPermission("fishery:deviceWarnCombine:list") + @GetMapping("/list") + public TableDataInfo list(DeviceWarnCombineBo bo, PageQuery pageQuery) { + return deviceWarnCombineService.queryPageList(bo, pageQuery); + } + + /** + * 导出设备告警信息列表 + */ + @SaCheckPermission("fishery:deviceWarnCombine:export") + @Log(title = "设备告警信息", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(DeviceWarnCombineBo bo, HttpServletResponse response) { + List list = deviceWarnCombineService.queryList(bo); + ExcelUtil.exportExcel(list, "设备告警信息", DeviceWarnCombineVo.class, response); + } + + /** + * 获取设备告警信息详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("fishery:deviceWarnCombine:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(deviceWarnCombineService.queryById(id)); + } + + /** + * 新增设备告警信息 + */ + @SaCheckPermission("fishery:deviceWarnCombine:add") + @Log(title = "设备告警信息", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody DeviceWarnCombineBo bo) { + return toAjax(deviceWarnCombineService.insertByBo(bo)); + } + + /** + * 修改设备告警信息 + */ + @SaCheckPermission("fishery:deviceWarnCombine:edit") + @Log(title = "设备告警信息", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody DeviceWarnCombineBo bo) { + return toAjax(deviceWarnCombineService.updateByBo(bo)); + } + + /** + * 删除设备告警信息 + * + * @param ids 主键串 + */ + @SaCheckPermission("fishery:deviceWarnCombine:remove") + @Log(title = "设备告警信息", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(deviceWarnCombineService.deleteWithValidByIds(List.of(ids), true)); + } +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/DeviceWarnOneController.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/DeviceWarnOneController.java new file mode 100644 index 0000000..1533bc2 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/DeviceWarnOneController.java @@ -0,0 +1,106 @@ +package com.intc.fishery.controller; + +import java.util.List; +import com.intc.common.excel.utils.ExcelUtil; +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import com.intc.common.idempotent.annotation.RepeatSubmit; +import com.intc.common.log.annotation.Log; +import com.intc.common.web.core.BaseController; +import com.intc.common.mybatis.core.page.PageQuery; +import com.intc.common.core.domain.R; +import com.intc.common.core.validate.AddGroup; +import com.intc.common.core.validate.EditGroup; +import com.intc.common.log.enums.BusinessType; +import com.intc.fishery.domain.vo.DeviceWarnOneVo; +import com.intc.fishery.domain.bo.DeviceWarnOneBo; +import com.intc.fishery.domain.bo.DeviceWarnOneBatchUpdateBo; +import com.intc.fishery.service.IDeviceWarnOneService; +import com.intc.common.mybatis.core.page.TableDataInfo; + +/** + * 设备报警明细 + * + * @author intc + * @date 2025-10-23 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/fishery/deviceWarnOne") +public class DeviceWarnOneController extends BaseController { + + private final IDeviceWarnOneService deviceWarnOneService; + + /** + * 查询设备报警明细列表 + */ + @SaCheckPermission("fishery:deviceWarnOne:list") + @GetMapping("/list") + public TableDataInfo list(DeviceWarnOneBo bo, PageQuery pageQuery) { + return deviceWarnOneService.queryPageList(bo, pageQuery); + } + + /** + * 导出设备报警明细列表 + */ + @SaCheckPermission("fishery:deviceWarnOne:export") + @Log(title = "设备报警明细", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(DeviceWarnOneBo bo, HttpServletResponse response) { + List list = deviceWarnOneService.queryList(bo); + ExcelUtil.exportExcel(list, "设备报警明细", DeviceWarnOneVo.class, response); + } + + /** + * 获取设备报警明细详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("fishery:deviceWarnOne:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(deviceWarnOneService.queryById(id)); + } + + /** + * 新增设备报警明细 + */ + @SaCheckPermission("fishery:deviceWarnOne:add") + @Log(title = "设备报警明细", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody DeviceWarnOneBo bo) { + return toAjax(deviceWarnOneService.insertByBo(bo)); + } + + /** + * 修改设备报警明细 + */ + @SaCheckPermission("fishery:deviceWarnOne:edit") + @Log(title = "设备报警明细", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody DeviceWarnOneBo bo) { + return toAjax(deviceWarnOneService.updateByBo(bo)); + } + + /** + * 删除设备报警明细 + * + * @param ids 主键串 + */ + @SaCheckPermission("fishery:deviceWarnOne:remove") + @Log(title = "设备报警明细", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(deviceWarnOneService.deleteWithValidByIds(List.of(ids), true)); + } + +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/MessageOpRecordController.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/MessageOpRecordController.java new file mode 100644 index 0000000..e1a0be0 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/MessageOpRecordController.java @@ -0,0 +1,104 @@ +package com.intc.fishery.controller; + +import java.util.List; +import com.intc.common.excel.utils.ExcelUtil; +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import com.intc.common.idempotent.annotation.RepeatSubmit; +import com.intc.common.log.annotation.Log; +import com.intc.common.web.core.BaseController; +import com.intc.common.mybatis.core.page.PageQuery; +import com.intc.common.core.domain.R; +import com.intc.common.core.validate.AddGroup; +import com.intc.common.core.validate.EditGroup; +import com.intc.common.log.enums.BusinessType; +import com.intc.fishery.domain.vo.MessageOpRecordVo; +import com.intc.fishery.domain.bo.MessageOpRecordBo; +import com.intc.fishery.service.IMessageOpRecordService; +import com.intc.common.mybatis.core.page.TableDataInfo; + +/** + * 用户操作记录 + * + * @author intc + * @date 2025-10-23 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/fishery/messageOpRecord") +public class MessageOpRecordController extends BaseController { + + private final IMessageOpRecordService messageOpRecordService; + + /** + * 查询用户操作记录列表 + */ + @SaCheckPermission("fishery:messageOpRecord:list") + @GetMapping("/list") + public TableDataInfo list(MessageOpRecordBo bo, PageQuery pageQuery) { + return messageOpRecordService.queryPageList(bo, pageQuery); + } + + /** + * 导出用户操作记录列表 + */ + @SaCheckPermission("fishery:messageOpRecord:export") + @Log(title = "用户操作记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(MessageOpRecordBo bo, HttpServletResponse response) { + List list = messageOpRecordService.queryList(bo); + ExcelUtil.exportExcel(list, "用户操作记录", MessageOpRecordVo.class, response); + } + + /** + * 获取用户操作记录详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("fishery:messageOpRecord:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(messageOpRecordService.queryById(id)); + } + + /** + * 新增用户操作记录 + */ + @SaCheckPermission("fishery:messageOpRecord:add") + @Log(title = "用户操作记录", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody MessageOpRecordBo bo) { + return toAjax(messageOpRecordService.insertByBo(bo)); + } + + /** + * 修改用户操作记录 + */ + @SaCheckPermission("fishery:messageOpRecord:edit") + @Log(title = "用户操作记录", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody MessageOpRecordBo bo) { + return toAjax(messageOpRecordService.updateByBo(bo)); + } + + /** + * 删除用户操作记录 + * + * @param ids 主键串 + */ + @SaCheckPermission("fishery:messageOpRecord:remove") + @Log(title = "用户操作记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(messageOpRecordService.deleteWithValidByIds(List.of(ids), true)); + } +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/TecentUserCacheController.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/TecentUserCacheController.java new file mode 100644 index 0000000..b1b7b97 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/TecentUserCacheController.java @@ -0,0 +1,104 @@ +package com.intc.fishery.controller; + +import java.util.List; +import com.intc.common.excel.utils.ExcelUtil; +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import com.intc.common.idempotent.annotation.RepeatSubmit; +import com.intc.common.log.annotation.Log; +import com.intc.common.web.core.BaseController; +import com.intc.common.mybatis.core.page.PageQuery; +import com.intc.common.core.domain.R; +import com.intc.common.core.validate.AddGroup; +import com.intc.common.core.validate.EditGroup; +import com.intc.common.log.enums.BusinessType; +import com.intc.fishery.domain.vo.TecentUserCacheVo; +import com.intc.fishery.domain.bo.TecentUserCacheBo; +import com.intc.fishery.service.ITecentUserCacheService; +import com.intc.common.mybatis.core.page.TableDataInfo; + +/** + * 公众号用户缓存 + * + * @author intc + * @date 2025-10-23 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/fishery/tecentUserCache") +public class TecentUserCacheController extends BaseController { + + private final ITecentUserCacheService tecentUserCacheService; + + /** + * 查询公众号用户缓存列表 + */ + @SaCheckPermission("fishery:tecentUserCache:list") + @GetMapping("/list") + public TableDataInfo list(TecentUserCacheBo bo, PageQuery pageQuery) { + return tecentUserCacheService.queryPageList(bo, pageQuery); + } + + /** + * 导出公众号用户缓存列表 + */ + @SaCheckPermission("fishery:tecentUserCache:export") + @Log(title = "公众号用户缓存", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(TecentUserCacheBo bo, HttpServletResponse response) { + List list = tecentUserCacheService.queryList(bo); + ExcelUtil.exportExcel(list, "公众号用户缓存", TecentUserCacheVo.class, response); + } + + /** + * 获取公众号用户缓存详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("fishery:tecentUserCache:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(tecentUserCacheService.queryById(id)); + } + + /** + * 新增公众号用户缓存 + */ + @SaCheckPermission("fishery:tecentUserCache:add") + @Log(title = "公众号用户缓存", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody TecentUserCacheBo bo) { + return toAjax(tecentUserCacheService.insertByBo(bo)); + } + + /** + * 修改公众号用户缓存 + */ + @SaCheckPermission("fishery:tecentUserCache:edit") + @Log(title = "公众号用户缓存", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody TecentUserCacheBo bo) { + return toAjax(tecentUserCacheService.updateByBo(bo)); + } + + /** + * 删除公众号用户缓存 + * + * @param ids 主键串 + */ + @SaCheckPermission("fishery:tecentUserCache:remove") + @Log(title = "公众号用户缓存", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(tecentUserCacheService.deleteWithValidByIds(List.of(ids), true)); + } +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/DeviceWarnCombine.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/DeviceWarnCombine.java new file mode 100644 index 0000000..fd66478 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/DeviceWarnCombine.java @@ -0,0 +1,83 @@ +package com.intc.fishery.domain; + +import com.baomidou.mybatisplus.annotation.*; +import com.intc.common.tenant.core.TenantEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serial; + +/** + * 设备告警信息对象 mgr_device_warn_combine + * + * @author intc + * @date 2025-10-23 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("mgr_device_warn_combine") +public class DeviceWarnCombine extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id") + private Long id; + + /** + * 设备编号 + */ + private String deviceSerialNum; + + /** + * 设备类型 + */ + private Integer deviceType; + + /** + * 参数类型 + */ + private Integer thresholdType; + + /** + * 进展状态 + */ + private Integer processStatus; + + /** + * 故障类型 + */ + private Integer warnType; + + /** + * 告警总数量 + */ + private Integer totalCount; + + /** + * 备注 + */ + private String remarkContent; + + /** + * 处理人 + */ + private String handlerName; + + /** + * 处理时间 + */ + private Date processTime; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/DeviceWarnOne.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/DeviceWarnOne.java new file mode 100644 index 0000000..b9fa30b --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/DeviceWarnOne.java @@ -0,0 +1,83 @@ +package com.intc.fishery.domain; + +import com.baomidou.mybatisplus.annotation.*; +import com.intc.common.tenant.core.TenantEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serial; + +/** + * 设备报警明细对象 mgr_device_warn_one + * + * @author intc + * @date 2025-10-23 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("mgr_device_warn_one") +public class DeviceWarnOne extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id") + private Long id; + + /** + * 报警主表id + */ + private Long warnCombineId; + + /** + * 用户id + */ + private Long userId; + + /** + * 告警最大值 + */ + private Double limitUpper; + + /** + * 告警最小值 + */ + private Double limitLower; + + /** + * 告警当前值 + */ + private Double curValue; + + /** + * 进展状态 + */ + private Integer processStatus; + + /** + * 故障类型 + */ + private Integer warnType; + + /** + * 处理人 + */ + private String handlerName; + + /** + * 处理时间 + */ + private Date processTime; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/MessageOpRecord.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/MessageOpRecord.java new file mode 100644 index 0000000..310585c --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/MessageOpRecord.java @@ -0,0 +1,61 @@ +package com.intc.fishery.domain; + +import com.baomidou.mybatisplus.annotation.*; +import com.intc.common.tenant.core.TenantEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; + +/** + * 用户操作记录对象 aqu_message_op_record + * + * @author intc + * @date 2025-10-23 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("aqu_message_op_record") +public class MessageOpRecord extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id") + private Long id; + + /** + * 用户id + */ + private Long userId; + + /** + * 操作用户id + */ + private Long opUserId; + + /** + * 操作标题 + */ + private String title; + + /** + * 操作内容 + */ + private String message; + + /** + * 操作方式 + */ + private Integer opType; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/TecentUserCache.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/TecentUserCache.java new file mode 100644 index 0000000..6e3de43 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/TecentUserCache.java @@ -0,0 +1,46 @@ +package com.intc.fishery.domain; + +import com.baomidou.mybatisplus.annotation.*; +import com.intc.common.tenant.core.TenantEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; + +/** + * 公众号用户缓存对象 aqu_tecent_user_cache + * + * @author intc + * @date 2025-10-23 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("aqu_tecent_user_cache") +public class TecentUserCache extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id") + private Long id; + + /** + * openId + */ + private String openId; + + /** + * unionId + */ + private String unionId; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/DeviceWarnCombineBo.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/DeviceWarnCombineBo.java new file mode 100644 index 0000000..34e325d --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/DeviceWarnCombineBo.java @@ -0,0 +1,87 @@ +package com.intc.fishery.domain.bo; +import com.intc.common.core.validate.AddGroup; +import com.intc.common.core.validate.EditGroup; +import com.intc.fishery.domain.DeviceWarnCombine; +import com.intc.common.mybatis.core.domain.BaseEntity; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +/** + * 设备告警信息业务对象 mgr_device_warn_combine + * + * @author intc + * @date 2025-10-23 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = DeviceWarnCombine.class, reverseConvertGenerate = false) +public class DeviceWarnCombineBo extends BaseEntity { + + /** + * 主键id + */ + @NotNull(message = "主键id不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 设备编号 + */ + @NotBlank(message = "设备编号不能为空", groups = { AddGroup.class, EditGroup.class }) + private String deviceSerialNum; + + /** + * 设备类型 + */ + @NotNull(message = "设备类型不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer deviceType; + + /** + * 参数类型 + */ + @NotNull(message = "参数类型不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer thresholdType; + + /** + * 进展状态 + */ + @NotNull(message = "进展状态不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer processStatus; + + /** + * 故障类型 + */ + @NotNull(message = "故障类型不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer warnType; + + /** + * 告警总数量 + */ + @NotNull(message = "告警总数量不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer totalCount; + + /** + * 备注 + */ + private String remarkContent; + + /** + * 处理人 + */ + private String handlerName; + + /** + * 处理时间 + */ + private Date processTime; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/DeviceWarnOneBatchUpdateBo.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/DeviceWarnOneBatchUpdateBo.java new file mode 100644 index 0000000..bc47ef6 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/DeviceWarnOneBatchUpdateBo.java @@ -0,0 +1,52 @@ +package com.intc.fishery.domain.bo; + +import java.util.Date; + +import com.intc.common.mybatis.core.domain.BaseEntity; + +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 设备报警明细批量更新业务对象 + * + * @author intc + * @date 2025-10-23 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class DeviceWarnOneBatchUpdateBo extends BaseEntity { + + /** + * 报警主表id(必填,用于批量更新条件) + */ + @NotNull(message = "报警主表id不能为空") + private Long warnCombineId; + + /** + * 进展状态 + */ + private Integer processStatus; + + /** + * 故障类型 + */ + private Integer warnType; + + /** + * 处理人 + */ + private String handlerName; + + /** + * 处理时间 + */ + private Date processTime; + + /** + * 备注 + */ + private String remark; + +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/DeviceWarnOneBo.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/DeviceWarnOneBo.java new file mode 100644 index 0000000..71178a6 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/DeviceWarnOneBo.java @@ -0,0 +1,89 @@ +package com.intc.fishery.domain.bo; +import java.util.Date; + +import com.intc.common.core.validate.AddGroup; +import com.intc.common.core.validate.EditGroup; +import com.intc.common.mybatis.core.domain.BaseEntity; +import com.intc.fishery.domain.DeviceWarnOne; + +import io.github.linpeilie.annotations.AutoMapper; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 设备报警明细业务对象 mgr_device_warn_one + * + * @author intc + * @date 2025-10-23 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = DeviceWarnOne.class, reverseConvertGenerate = false) +public class DeviceWarnOneBo extends BaseEntity { + + /** + * 主键id + */ + @NotNull(message = "主键id不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 报警主表id + */ + @NotNull(message = "报警主表id不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long warnCombineId; + + /** + * 用户id + */ + @NotNull(message = "用户id不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long userId; + + /** + * 告警最大值 + */ + @NotNull(message = "告警最大值不能为空", groups = { AddGroup.class, EditGroup.class }) + private Double limitUpper; + + /** + * 告警最小值 + */ + @NotNull(message = "告警最小值不能为空", groups = { AddGroup.class, EditGroup.class }) + private Double limitLower; + + /** + * 告警当前值 + */ + @NotNull(message = "告警当前值不能为空", groups = { AddGroup.class, EditGroup.class }) + private Double curValue; + + /** + * 进展状态 + */ + @NotNull(message = "进展状态不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer processStatus; + + /** + * 故障类型 + */ + @NotNull(message = "故障类型不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer warnType; + + /** + * 处理人 + */ + private String handlerName; + + /** + * 处理时间 + */ + private Date processTime; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/MessageOpRecordBo.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/MessageOpRecordBo.java new file mode 100644 index 0000000..a7e4979 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/MessageOpRecordBo.java @@ -0,0 +1,63 @@ +package com.intc.fishery.domain.bo; +import com.intc.common.core.validate.AddGroup; +import com.intc.common.core.validate.EditGroup; +import com.intc.fishery.domain.MessageOpRecord; +import com.intc.common.mybatis.core.domain.BaseEntity; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; + +/** + * 用户操作记录业务对象 aqu_message_op_record + * + * @author intc + * @date 2025-10-23 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = MessageOpRecord.class, reverseConvertGenerate = false) +public class MessageOpRecordBo extends BaseEntity { + + /** + * 主键id + */ + @NotNull(message = "主键id不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 用户id + */ + @NotNull(message = "用户id不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long userId; + + /** + * 操作用户id + */ + private Long opUserId; + + /** + * 操作标题 + */ + @NotBlank(message = "操作标题不能为空", groups = { AddGroup.class, EditGroup.class }) + private String title; + + /** + * 操作内容 + */ + @NotBlank(message = "操作内容不能为空", groups = { AddGroup.class, EditGroup.class }) + private String message; + + /** + * 操作方式 + */ + @NotNull(message = "操作方式不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer opType; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/TecentUserCacheBo.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/TecentUserCacheBo.java new file mode 100644 index 0000000..0ff4318 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/TecentUserCacheBo.java @@ -0,0 +1,46 @@ +package com.intc.fishery.domain.bo; +import com.intc.common.core.validate.AddGroup; +import com.intc.common.core.validate.EditGroup; +import com.intc.fishery.domain.TecentUserCache; +import com.intc.common.mybatis.core.domain.BaseEntity; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; + +/** + * 公众号用户缓存业务对象 aqu_tecent_user_cache + * + * @author intc + * @date 2025-10-23 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = TecentUserCache.class, reverseConvertGenerate = false) +public class TecentUserCacheBo extends BaseEntity { + + /** + * 主键id + */ + @NotNull(message = "主键id不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * openId + */ + @NotBlank(message = "openId不能为空", groups = { AddGroup.class, EditGroup.class }) + private String openId; + + /** + * unionId + */ + @NotBlank(message = "unionId不能为空", groups = { AddGroup.class, EditGroup.class }) + private String unionId; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/DeviceWarnCombineVo.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/DeviceWarnCombineVo.java new file mode 100644 index 0000000..f125ece --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/DeviceWarnCombineVo.java @@ -0,0 +1,99 @@ +package com.intc.fishery.domain.vo; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.intc.fishery.domain.DeviceWarnCombine; +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import com.intc.common.excel.annotation.ExcelDictFormat; +import com.intc.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + + +/** + * 设备告警信息视图对象 mgr_device_warn_combine + * + * @author intc + * @date 2025-10-23 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = DeviceWarnCombine.class) +public class DeviceWarnCombineVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @ExcelProperty(value = "主键id") + private Long id; + + /** + * 设备编号 + */ + @ExcelProperty(value = "设备编号") + private String deviceSerialNum; + + /** + * 设备类型 + */ + @ExcelProperty(value = "设备类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "aqu_device_type") + private Integer deviceType; + + /** + * 参数类型 + */ + @ExcelProperty(value = "参数类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "threshold_type") + private Integer thresholdType; + + /** + * 进展状态 + */ + @ExcelProperty(value = "进展状态", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "process_status") + private Integer processStatus; + + /** + * 故障类型 + */ + @ExcelProperty(value = "故障类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "risk_type") + private Integer warnType; + + /** + * 告警总数量 + */ + @ExcelProperty(value = "告警总数量") + private Integer totalCount; + + /** + * 处理人 + */ + @ExcelProperty(value = "处理人") + private String handlerName; + + /** + * 处理时间 + */ + @ExcelProperty(value = "处理时间") + private Date processTime; + + /** + * 创建时间 + */ + @ExcelProperty(value = "创建时间") + private Date createTime; + + + private Date updateTime; +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/DeviceWarnOneVo.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/DeviceWarnOneVo.java new file mode 100644 index 0000000..e80506c --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/DeviceWarnOneVo.java @@ -0,0 +1,120 @@ +package com.intc.fishery.domain.vo; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.intc.common.excel.annotation.ExcelDictFormat; +import com.intc.common.excel.convert.ExcelDictConvert; +import com.intc.common.json.handler.DoubleSerializer; +import com.intc.fishery.domain.DeviceWarnOne; + +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + + + +/** + * 设备报警明细视图对象 mgr_device_warn_one + * + * @author intc + * @date 2025-10-23 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = DeviceWarnOne.class) +public class DeviceWarnOneVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @ExcelProperty(value = "主键id") + private Long id; + + /** + * 报警主表id + */ + @ExcelProperty(value = "报警主表id") + private Long warnCombineId; + + /** + * 用户id + */ + @ExcelProperty(value = "用户id") + private Long userId; + + /** + * 告警最大值 + */ + @ExcelProperty(value = "告警最大值") + private Double limitUpper; + + /** + * 告警最小值 + */ + @ExcelProperty(value = "告警最小值") + private Double limitLower; + + /** + * 告警当前值 + */ + @ExcelProperty(value = "告警当前值") + @JsonSerialize(using = DoubleSerializer.class) + private Double curValue; + + /** + * 进展状态 + */ + @ExcelProperty(value = "进展状态", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "process_status") + private Integer processStatus; + + /** + * 故障类型 + */ + @ExcelProperty(value = "故障类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "risk_type") + private Integer warnType; + + /** + * 处理人 + */ + @ExcelProperty(value = "处理人") + private String handlerName; + + /** + * 处理时间 + */ + @ExcelProperty(value = "处理时间") + private Date processTime; + + /** + * 设备编号 + */ + @ExcelProperty(value = "设备编号") + private String deviceSerialNum; + + /** + * 设备类型 + */ + @ExcelProperty(value = "设备类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "aqu_device_type") + private Integer deviceType; + + /** + * 参数类型 + */ + @ExcelProperty(value = "参数类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "threshold_type") + private Integer thresholdType; + + private Date createTime; + + private Date updateTime; +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/MessageOpRecordVo.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/MessageOpRecordVo.java new file mode 100644 index 0000000..17caae9 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/MessageOpRecordVo.java @@ -0,0 +1,101 @@ +package com.intc.fishery.domain.vo; + +import com.intc.fishery.domain.MessageOpRecord; +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import com.intc.common.excel.annotation.ExcelDictFormat; +import com.intc.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + + +/** + * 用户操作记录视图对象 aqu_message_op_record + * + * @author intc + * @date 2025-10-23 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = MessageOpRecord.class) +public class MessageOpRecordVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @ExcelProperty(value = "主键id") + private Long id; + + /** + * 用户id + */ + @ExcelProperty(value = "用户id") + private Long userId; + + /** + * 操作用户id + */ + @ExcelProperty(value = "操作用户id") + private Long opUserId; + + /** + * 操作标题 + */ + @ExcelProperty(value = "操作标题") + private String title; + + /** + * 操作内容 + */ + @ExcelProperty(value = "操作内容") + private String message; + + /** + * 操作方式 + */ + @ExcelProperty(value = "操作方式", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "op_type") + private Integer opType; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + /** + * 用户名(关联查询) + */ + @ExcelProperty(value = "用户名") + private String userName; + + /** + * 用户手机号(关联查询) + */ + @ExcelProperty(value = "用户手机号") + private String userPhonenumber; + + /** + * 操作用户名(关联查询) + */ + @ExcelProperty(value = "操作用户名") + private String opUserName; + + /** + * 操作用户手机号(关联查询) + */ + @ExcelProperty(value = "操作用户手机号") + private String opUserPhonenumber; + + private Date createTime; + + private Date updateTime; +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/TecentUserCacheVo.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/TecentUserCacheVo.java new file mode 100644 index 0000000..19e210d --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/TecentUserCacheVo.java @@ -0,0 +1,58 @@ +package com.intc.fishery.domain.vo; + +import com.intc.fishery.domain.TecentUserCache; +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import com.intc.common.excel.annotation.ExcelDictFormat; +import com.intc.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + + +/** + * 公众号用户缓存视图对象 aqu_tecent_user_cache + * + * @author intc + * @date 2025-10-23 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = TecentUserCache.class) +public class TecentUserCacheVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @ExcelProperty(value = "主键id") + private Long id; + + /** + * openId + */ + @ExcelProperty(value = "openId") + private String openId; + + /** + * unionId + */ + @ExcelProperty(value = "unionId") + private String unionId; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + private Date createTime; + + private Date updateTime; +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/DeviceWarnCombineMapper.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/DeviceWarnCombineMapper.java new file mode 100644 index 0000000..d12e532 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/DeviceWarnCombineMapper.java @@ -0,0 +1,15 @@ +package com.intc.fishery.mapper; + +import com.intc.common.mybatis.core.mapper.BaseMapperPlusJoin; +import com.intc.fishery.domain.DeviceWarnCombine; +import com.intc.fishery.domain.vo.DeviceWarnCombineVo; + +/** + * 设备告警信息Mapper接口 + * + * @author intc + * @date 2025-10-23 + */ +public interface DeviceWarnCombineMapper extends BaseMapperPlusJoin { + +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/DeviceWarnOneMapper.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/DeviceWarnOneMapper.java new file mode 100644 index 0000000..9f77c3e --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/DeviceWarnOneMapper.java @@ -0,0 +1,15 @@ +package com.intc.fishery.mapper; + +import com.intc.common.mybatis.core.mapper.BaseMapperPlusJoin; +import com.intc.fishery.domain.DeviceWarnOne; +import com.intc.fishery.domain.vo.DeviceWarnOneVo; + +/** + * 设备报警明细Mapper接口 + * + * @author intc + * @date 2025-10-23 + */ +public interface DeviceWarnOneMapper extends BaseMapperPlusJoin { + +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/MessageOpRecordMapper.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/MessageOpRecordMapper.java new file mode 100644 index 0000000..93adba9 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/MessageOpRecordMapper.java @@ -0,0 +1,15 @@ +package com.intc.fishery.mapper; + +import com.intc.fishery.domain.MessageOpRecord; +import com.intc.fishery.domain.vo.MessageOpRecordVo; +import com.intc.common.mybatis.core.mapper.BaseMapperPlusJoin; + +/** + * 用户操作记录Mapper接口 + * + * @author intc + * @date 2025-10-23 + */ +public interface MessageOpRecordMapper extends BaseMapperPlusJoin { + +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/TecentUserCacheMapper.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/TecentUserCacheMapper.java new file mode 100644 index 0000000..16be422 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/TecentUserCacheMapper.java @@ -0,0 +1,15 @@ +package com.intc.fishery.mapper; + +import com.intc.fishery.domain.TecentUserCache; +import com.intc.fishery.domain.vo.TecentUserCacheVo; +import com.intc.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 公众号用户缓存Mapper接口 + * + * @author intc + * @date 2025-10-23 + */ +public interface TecentUserCacheMapper extends BaseMapperPlus { + +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/IDeviceWarnCombineService.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/IDeviceWarnCombineService.java new file mode 100644 index 0000000..9a8f407 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/IDeviceWarnCombineService.java @@ -0,0 +1,68 @@ +package com.intc.fishery.service; + +import com.intc.fishery.domain.vo.DeviceWarnCombineVo; +import com.intc.fishery.domain.bo.DeviceWarnCombineBo; +import com.intc.common.mybatis.core.page.TableDataInfo; +import com.intc.common.mybatis.core.page.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 设备告警信息Service接口 + * + * @author intc + * @date 2025-10-23 + */ +public interface IDeviceWarnCombineService { + + /** + * 查询设备告警信息 + * + * @param id 主键 + * @return 设备告警信息 + */ + DeviceWarnCombineVo queryById(Long id); + + /** + * 分页查询设备告警信息列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 设备告警信息分页列表 + */ + TableDataInfo queryPageList(DeviceWarnCombineBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的设备告警信息列表 + * + * @param bo 查询条件 + * @return 设备告警信息列表 + */ + List queryList(DeviceWarnCombineBo bo); + + /** + * 新增设备告警信息 + * + * @param bo 设备告警信息 + * @return 是否新增成功 + */ + Boolean insertByBo(DeviceWarnCombineBo bo); + + /** + * 修改设备告警信息 + * + * @param bo 设备告警信息 + * @return 是否修改成功 + */ + Boolean updateByBo(DeviceWarnCombineBo bo); + + /** + * 校验并批量删除设备告警信息信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/IDeviceWarnOneService.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/IDeviceWarnOneService.java new file mode 100644 index 0000000..decd3b9 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/IDeviceWarnOneService.java @@ -0,0 +1,70 @@ +package com.intc.fishery.service; + +import com.intc.fishery.domain.vo.DeviceWarnOneVo; +import com.intc.fishery.domain.bo.DeviceWarnOneBo; +import com.intc.fishery.domain.bo.DeviceWarnOneBatchUpdateBo; +import com.intc.common.mybatis.core.page.TableDataInfo; +import com.intc.common.mybatis.core.page.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 设备报警明细Service接口 + * + * @author intc + * @date 2025-10-23 + */ +public interface IDeviceWarnOneService { + + /** + * 查询设备报警明细 + * + * @param id 主键 + * @return 设备报警明细 + */ + DeviceWarnOneVo queryById(Long id); + + /** + * 分页查询设备报警明细列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 设备报警明细分页列表 + */ + TableDataInfo queryPageList(DeviceWarnOneBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的设备报警明细列表 + * + * @param bo 查询条件 + * @return 设备报警明细列表 + */ + List queryList(DeviceWarnOneBo bo); + + /** + * 新增设备报警明细 + * + * @param bo 设备报警明细 + * @return 是否新增成功 + */ + Boolean insertByBo(DeviceWarnOneBo bo); + + /** + * 修改设备报警明细 + * + * @param bo 设备报警明细 + * @return 是否修改成功 + */ + Boolean updateByBo(DeviceWarnOneBo bo); + + /** + * 校验并批量删除设备报警明细信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/IMessageOpRecordService.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/IMessageOpRecordService.java new file mode 100644 index 0000000..f137e64 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/IMessageOpRecordService.java @@ -0,0 +1,68 @@ +package com.intc.fishery.service; + +import com.intc.fishery.domain.vo.MessageOpRecordVo; +import com.intc.fishery.domain.bo.MessageOpRecordBo; +import com.intc.common.mybatis.core.page.TableDataInfo; +import com.intc.common.mybatis.core.page.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 用户操作记录Service接口 + * + * @author intc + * @date 2025-10-23 + */ +public interface IMessageOpRecordService { + + /** + * 查询用户操作记录 + * + * @param id 主键 + * @return 用户操作记录 + */ + MessageOpRecordVo queryById(Long id); + + /** + * 分页查询用户操作记录列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 用户操作记录分页列表 + */ + TableDataInfo queryPageList(MessageOpRecordBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的用户操作记录列表 + * + * @param bo 查询条件 + * @return 用户操作记录列表 + */ + List queryList(MessageOpRecordBo bo); + + /** + * 新增用户操作记录 + * + * @param bo 用户操作记录 + * @return 是否新增成功 + */ + Boolean insertByBo(MessageOpRecordBo bo); + + /** + * 修改用户操作记录 + * + * @param bo 用户操作记录 + * @return 是否修改成功 + */ + Boolean updateByBo(MessageOpRecordBo bo); + + /** + * 校验并批量删除用户操作记录信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/ITecentUserCacheService.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/ITecentUserCacheService.java new file mode 100644 index 0000000..659f937 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/ITecentUserCacheService.java @@ -0,0 +1,68 @@ +package com.intc.fishery.service; + +import com.intc.fishery.domain.vo.TecentUserCacheVo; +import com.intc.fishery.domain.bo.TecentUserCacheBo; +import com.intc.common.mybatis.core.page.TableDataInfo; +import com.intc.common.mybatis.core.page.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 公众号用户缓存Service接口 + * + * @author intc + * @date 2025-10-23 + */ +public interface ITecentUserCacheService { + + /** + * 查询公众号用户缓存 + * + * @param id 主键 + * @return 公众号用户缓存 + */ + TecentUserCacheVo queryById(Long id); + + /** + * 分页查询公众号用户缓存列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 公众号用户缓存分页列表 + */ + TableDataInfo queryPageList(TecentUserCacheBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的公众号用户缓存列表 + * + * @param bo 查询条件 + * @return 公众号用户缓存列表 + */ + List queryList(TecentUserCacheBo bo); + + /** + * 新增公众号用户缓存 + * + * @param bo 公众号用户缓存 + * @return 是否新增成功 + */ + Boolean insertByBo(TecentUserCacheBo bo); + + /** + * 修改公众号用户缓存 + * + * @param bo 公众号用户缓存 + * @return 是否修改成功 + */ + Boolean updateByBo(TecentUserCacheBo bo); + + /** + * 校验并批量删除公众号用户缓存信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/DeviceWarnCombineServiceImpl.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/DeviceWarnCombineServiceImpl.java new file mode 100644 index 0000000..5fbcd99 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/DeviceWarnCombineServiceImpl.java @@ -0,0 +1,177 @@ +package com.intc.fishery.service.impl; + +import com.intc.common.core.utils.MapstructUtils; +import com.intc.common.core.utils.StringUtils; +import com.intc.common.mybatis.core.page.TableDataInfo; +import com.intc.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.github.yulichang.wrapper.MPJLambdaWrapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import com.intc.fishery.domain.bo.DeviceWarnCombineBo; +import com.intc.fishery.domain.vo.DeviceWarnCombineVo; +import com.intc.fishery.domain.DeviceWarnCombine; +import com.intc.fishery.domain.DeviceWarnOne; +import com.intc.fishery.mapper.DeviceWarnCombineMapper; +import com.intc.fishery.mapper.DeviceWarnOneMapper; +import com.intc.fishery.service.IDeviceWarnCombineService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 设备告警信息Service业务层处理 + * + * @author intc + * @date 2025-10-23 + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class DeviceWarnCombineServiceImpl implements IDeviceWarnCombineService { + + private final DeviceWarnCombineMapper baseMapper; + private final DeviceWarnOneMapper deviceWarnOneMapper; + + /** + * 查询设备告警信息 + * + * @param id 主键 + * @return 设备告警信息 + */ + @Override + public DeviceWarnCombineVo queryById(Long id){ + return baseMapper.selectVoById(id); + } + + /** + * 分页查询设备告警信息列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 设备告警信息分页列表 + */ + @Override + public TableDataInfo queryPageList(DeviceWarnCombineBo bo, PageQuery pageQuery) { + MPJLambdaWrapper wrapper = buildJoinQueryWrapper(bo); + Page result = baseMapper.selectJoinPage(pageQuery.build(), DeviceWarnCombineVo.class, wrapper); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的设备告警信息列表 + * + * @param bo 查询条件 + * @return 设备告警信息列表 + */ + @Override + public List queryList(DeviceWarnCombineBo bo) { + MPJLambdaWrapper wrapper = buildJoinQueryWrapper(bo); + return baseMapper.selectJoinList(DeviceWarnCombineVo.class, wrapper); + } + + private MPJLambdaWrapper buildJoinQueryWrapper(DeviceWarnCombineBo bo) { + Map params = bo.getParams(); + MPJLambdaWrapper wrapper = new MPJLambdaWrapper() + .selectAll(DeviceWarnCombine.class) + .selectCount(DeviceWarnOne::getId, DeviceWarnCombineVo::getTotalCount) + .leftJoin(DeviceWarnOne.class, DeviceWarnOne::getWarnCombineId, DeviceWarnCombine::getId) + .eq(StringUtils.isNotBlank(bo.getDeviceSerialNum()), DeviceWarnCombine::getDeviceSerialNum, bo.getDeviceSerialNum()) + .eq(bo.getDeviceType() != null, DeviceWarnCombine::getDeviceType, bo.getDeviceType()) + .eq(bo.getThresholdType() != null, DeviceWarnCombine::getThresholdType, bo.getThresholdType()) + .eq(bo.getProcessStatus() != null, DeviceWarnCombine::getProcessStatus, bo.getProcessStatus()) + .eq(bo.getWarnType() != null, DeviceWarnCombine::getWarnType, bo.getWarnType()) + .groupBy(DeviceWarnCombine::getId) + .orderByDesc(DeviceWarnCombine::getUpdateTime); + return wrapper; + } + + /** + * 新增设备告警信息 + * + * @param bo 设备告警信息 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(DeviceWarnCombineBo bo) { + DeviceWarnCombine add = MapstructUtils.convert(bo, DeviceWarnCombine.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改设备告警信息 + * + * @param bo 设备告警信息 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(DeviceWarnCombineBo bo) { + DeviceWarnCombine update = MapstructUtils.convert(bo, DeviceWarnCombine.class); + validEntityBeforeSave(update); + boolean result = baseMapper.updateById(update) > 0; + + // 如果更新成功,同时批量更新关联的DeviceWarnOne记录 + if (result) { + LambdaUpdateWrapper updateWrapper = Wrappers.lambdaUpdate(); + updateWrapper.eq(DeviceWarnOne::getWarnCombineId, bo.getId()); + + // 只更新非空字段 + updateWrapper.set(bo.getProcessStatus() != null, DeviceWarnOne::getProcessStatus, bo.getProcessStatus()); + updateWrapper.set(bo.getWarnType() != null, DeviceWarnOne::getWarnType, bo.getWarnType()); + updateWrapper.set(StringUtils.isNotBlank(bo.getHandlerName()), DeviceWarnOne::getHandlerName, bo.getHandlerName()); + updateWrapper.set(bo.getProcessTime() != null, DeviceWarnOne::getProcessTime, bo.getProcessTime()); + updateWrapper.set(StringUtils.isNotBlank(bo.getRemark()), DeviceWarnOne::getRemark, bo.getRemark()); + + int updatedCount = deviceWarnOneMapper.update(null, updateWrapper); + log.info("更新DeviceWarnCombine[id={}]成功,同时批量更新了{}条DeviceWarnOne记录", bo.getId(), updatedCount); + } + + return result; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(DeviceWarnCombine entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除设备告警信息信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + + // 先删除关联的DeviceWarnOne记录 + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + queryWrapper.in(DeviceWarnOne::getWarnCombineId, ids); + int deletedDetailCount = deviceWarnOneMapper.delete(queryWrapper); + log.info("删除DeviceWarnCombine记录前,先删除了{}条关联的DeviceWarnOne记录", deletedDetailCount); + + // 再删除主表DeviceWarnCombine记录 + boolean result = baseMapper.deleteByIds(ids) > 0; + + if (result) { + log.info("成功删除{}条DeviceWarnCombine记录", ids.size()); + } + + return result; + } +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/DeviceWarnOneServiceImpl.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/DeviceWarnOneServiceImpl.java new file mode 100644 index 0000000..225b1b4 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/DeviceWarnOneServiceImpl.java @@ -0,0 +1,154 @@ +package com.intc.fishery.service.impl; + +import com.intc.common.core.utils.MapstructUtils; +import com.intc.common.core.utils.StringUtils; +import com.intc.common.mybatis.core.page.TableDataInfo; +import com.intc.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.github.yulichang.wrapper.MPJLambdaWrapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import com.intc.fishery.domain.bo.DeviceWarnOneBo; +import com.intc.fishery.domain.bo.DeviceWarnOneBatchUpdateBo; +import com.intc.fishery.domain.vo.DeviceWarnOneVo; +import com.intc.fishery.domain.DeviceWarnOne; +import com.intc.fishery.domain.DeviceWarnCombine; +import com.intc.fishery.mapper.DeviceWarnOneMapper; +import com.intc.fishery.service.IDeviceWarnOneService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 设备报警明细Service业务层处理 + * + * @author intc + * @date 2025-10-23 + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class DeviceWarnOneServiceImpl implements IDeviceWarnOneService { + + private final DeviceWarnOneMapper baseMapper; + + /** + * 查询设备报警明细 + * + * @param id 主键 + * @return 设备报警明细 + */ + @Override + public DeviceWarnOneVo queryById(Long id){ + return baseMapper.selectVoById(id); + } + + /** + * 分页查询设备报警明细列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 设备报警明细分页列表 + */ + @Override + public TableDataInfo queryPageList(DeviceWarnOneBo bo, PageQuery pageQuery) { + MPJLambdaWrapper wrapper = buildJoinQueryWrapper(bo); + Page result = baseMapper.selectJoinPage(pageQuery.build(), DeviceWarnOneVo.class, wrapper); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的设备报警明细列表 + * + * @param bo 查询条件 + * @return 设备报警明细列表 + */ + @Override + public List queryList(DeviceWarnOneBo bo) { + MPJLambdaWrapper wrapper = buildJoinQueryWrapper(bo); + return baseMapper.selectJoinList(DeviceWarnOneVo.class, wrapper); + } + + private MPJLambdaWrapper buildJoinQueryWrapper(DeviceWarnOneBo bo) { + Map params = bo.getParams(); + + // 从params中获取关联表查询条件并转换类型 + String deviceSerialNum = (String) params.get("deviceSerialNum"); + Integer deviceType = params.get("deviceType") != null ? Integer.parseInt(params.get("deviceType").toString()) : null; + Integer thresholdType = params.get("thresholdType") != null ? Integer.parseInt(params.get("thresholdType").toString()) : null; + + MPJLambdaWrapper wrapper = new MPJLambdaWrapper() + .selectAll(DeviceWarnOne.class) + .select(DeviceWarnCombine::getDeviceSerialNum) + .select(DeviceWarnCombine::getDeviceType) + .select(DeviceWarnCombine::getThresholdType) + .leftJoin(DeviceWarnCombine.class, DeviceWarnCombine::getId, DeviceWarnOne::getWarnCombineId) + .eq(bo.getWarnCombineId() != null, DeviceWarnOne::getWarnCombineId, bo.getWarnCombineId()) + .eq(bo.getUserId() != null, DeviceWarnOne::getUserId, bo.getUserId()) + .eq(bo.getProcessStatus() != null, DeviceWarnOne::getProcessStatus, bo.getProcessStatus()) + .eq(bo.getWarnType() != null, DeviceWarnOne::getWarnType, bo.getWarnType()) + .like(StringUtils.isNotBlank(bo.getHandlerName()), DeviceWarnOne::getHandlerName, bo.getHandlerName()) + .like(StringUtils.isNotBlank(deviceSerialNum), DeviceWarnCombine::getDeviceSerialNum, deviceSerialNum) + .eq(deviceType != null, DeviceWarnCombine::getDeviceType, deviceType) + .eq(thresholdType != null, DeviceWarnCombine::getThresholdType, thresholdType) + .orderByDesc(DeviceWarnOne::getUpdateTime); + return wrapper; + } + + /** + * 新增设备报警明细 + * + * @param bo 设备报警明细 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(DeviceWarnOneBo bo) { + DeviceWarnOne add = MapstructUtils.convert(bo, DeviceWarnOne.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改设备报警明细 + * + * @param bo 设备报警明细 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(DeviceWarnOneBo bo) { + DeviceWarnOne update = MapstructUtils.convert(bo, DeviceWarnOne.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(DeviceWarnOne entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除设备报警明细信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/MessageOpRecordServiceImpl.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/MessageOpRecordServiceImpl.java new file mode 100644 index 0000000..a38bdce --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/MessageOpRecordServiceImpl.java @@ -0,0 +1,159 @@ +package com.intc.fishery.service.impl; + +import com.intc.common.core.utils.MapstructUtils; +import com.intc.common.core.utils.StringUtils; +import com.intc.common.mybatis.core.page.TableDataInfo; +import com.intc.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.github.yulichang.wrapper.MPJLambdaWrapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import com.intc.fishery.domain.bo.MessageOpRecordBo; +import com.intc.fishery.domain.vo.MessageOpRecordVo; +import com.intc.fishery.domain.MessageOpRecord; +import com.intc.fishery.domain.AquUser; +import com.intc.fishery.mapper.MessageOpRecordMapper; +import com.intc.fishery.service.IMessageOpRecordService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 用户操作记录Service业务层处理 + * + * @author intc + * @date 2025-10-23 + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class MessageOpRecordServiceImpl implements IMessageOpRecordService { + + private final MessageOpRecordMapper baseMapper; + + /** + * 查询用户操作记录 + * + * @param id 主键 + * @return 用户操作记录 + */ + @Override + public MessageOpRecordVo queryById(Long id){ + return baseMapper.selectVoById(id); + } + + /** + * 分页查询用户操作记录列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 用户操作记录分页列表 + */ + @Override + public TableDataInfo queryPageList(MessageOpRecordBo bo, PageQuery pageQuery) { + MPJLambdaWrapper wrapper = buildJoinQueryWrapper(bo); + Page result = baseMapper.selectJoinPage(pageQuery.build(), MessageOpRecordVo.class, wrapper); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的用户操作记录列表 + * + * @param bo 查询条件 + * @return 用户操作记录列表 + */ + @Override + public List queryList(MessageOpRecordBo bo) { + MPJLambdaWrapper wrapper = buildJoinQueryWrapper(bo); + return baseMapper.selectJoinList(MessageOpRecordVo.class, wrapper); + } + + private MPJLambdaWrapper buildJoinQueryWrapper(MessageOpRecordBo bo) { + Map params = bo.getParams(); + + // 获取用户关键字搜索参数 + String userKeyword = params.get("userKeyword") != null ? params.get("userKeyword").toString() : null; + + MPJLambdaWrapper wrapper = new MPJLambdaWrapper() + .selectAll(MessageOpRecord.class) + // 关联查询AquUser用户信息 + .selectAs("u1.user_name", MessageOpRecordVo::getUserName) + .selectAs("u1.mobile_phone", MessageOpRecordVo::getUserPhonenumber) + // 关联查询操作用户信息 + .selectAs("u2.user_name", MessageOpRecordVo::getOpUserName) + .selectAs("u2.mobile_phone", MessageOpRecordVo::getOpUserPhonenumber) + // 关联aqu_user表(用户) + .leftJoin("aqu_user u1 on u1.id = t.user_id") + // 关联aqu_user表(操作用户) + .leftJoin("aqu_user u2 on u2.id = t.op_user_id") + .eq(bo.getUserId() != null, MessageOpRecord::getUserId, bo.getUserId()) + .eq(bo.getOpUserId() != null, MessageOpRecord::getOpUserId, bo.getOpUserId()) + .like(StringUtils.isNotBlank(bo.getTitle()), MessageOpRecord::getTitle, bo.getTitle()) + .like(StringUtils.isNotBlank(bo.getMessage()), MessageOpRecord::getMessage, bo.getMessage()) + .eq(bo.getOpType() != null, MessageOpRecord::getOpType, bo.getOpType()) + // 根据用户关键字模糊查询用户名或手机号 + .and(StringUtils.isNotBlank(userKeyword), w -> w + .like("u1.user_name", userKeyword) + .or() + .like("u1.mobile_phone", userKeyword) + ) + .orderByDesc(MessageOpRecord::getCreateTime); + return wrapper; + } + + /** + * 新增用户操作记录 + * + * @param bo 用户操作记录 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(MessageOpRecordBo bo) { + MessageOpRecord add = MapstructUtils.convert(bo, MessageOpRecord.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改用户操作记录 + * + * @param bo 用户操作记录 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(MessageOpRecordBo bo) { + MessageOpRecord update = MapstructUtils.convert(bo, MessageOpRecord.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(MessageOpRecord entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除用户操作记录信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/TecentUserCacheServiceImpl.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/TecentUserCacheServiceImpl.java new file mode 100644 index 0000000..56d17d4 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/TecentUserCacheServiceImpl.java @@ -0,0 +1,131 @@ +package com.intc.fishery.service.impl; + +import com.intc.common.core.utils.MapstructUtils; +import com.intc.common.core.utils.StringUtils; +import com.intc.common.mybatis.core.page.TableDataInfo; +import com.intc.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import com.intc.fishery.domain.bo.TecentUserCacheBo; +import com.intc.fishery.domain.vo.TecentUserCacheVo; +import com.intc.fishery.domain.TecentUserCache; +import com.intc.fishery.mapper.TecentUserCacheMapper; +import com.intc.fishery.service.ITecentUserCacheService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 公众号用户缓存Service业务层处理 + * + * @author intc + * @date 2025-10-23 + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class TecentUserCacheServiceImpl implements ITecentUserCacheService { + + private final TecentUserCacheMapper baseMapper; + + /** + * 查询公众号用户缓存 + * + * @param id 主键 + * @return 公众号用户缓存 + */ + @Override + public TecentUserCacheVo queryById(Long id){ + return baseMapper.selectVoById(id); + } + + /** + * 分页查询公众号用户缓存列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 公众号用户缓存分页列表 + */ + @Override + public TableDataInfo queryPageList(TecentUserCacheBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的公众号用户缓存列表 + * + * @param bo 查询条件 + * @return 公众号用户缓存列表 + */ + @Override + public List queryList(TecentUserCacheBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(TecentUserCacheBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.orderByDesc(TecentUserCache::getCreateTime); + return lqw; + } + + /** + * 新增公众号用户缓存 + * + * @param bo 公众号用户缓存 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(TecentUserCacheBo bo) { + TecentUserCache add = MapstructUtils.convert(bo, TecentUserCache.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改公众号用户缓存 + * + * @param bo 公众号用户缓存 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(TecentUserCacheBo bo) { + TecentUserCache update = MapstructUtils.convert(bo, TecentUserCache.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(TecentUserCache entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除公众号用户缓存信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } +} diff --git a/intc-modules/intc-fishery/src/main/resources/mapper/fishery/DeviceWarnCombineMapper.xml b/intc-modules/intc-fishery/src/main/resources/mapper/fishery/DeviceWarnCombineMapper.xml new file mode 100644 index 0000000..b262939 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/resources/mapper/fishery/DeviceWarnCombineMapper.xml @@ -0,0 +1,6 @@ + + + + diff --git a/intc-modules/intc-fishery/src/main/resources/mapper/fishery/DeviceWarnOneMapper.xml b/intc-modules/intc-fishery/src/main/resources/mapper/fishery/DeviceWarnOneMapper.xml new file mode 100644 index 0000000..8e984b6 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/resources/mapper/fishery/DeviceWarnOneMapper.xml @@ -0,0 +1,6 @@ + + + + diff --git a/intc-modules/intc-fishery/src/main/resources/mapper/fishery/MessageOpRecordMapper.xml b/intc-modules/intc-fishery/src/main/resources/mapper/fishery/MessageOpRecordMapper.xml new file mode 100644 index 0000000..1539e82 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/resources/mapper/fishery/MessageOpRecordMapper.xml @@ -0,0 +1,6 @@ + + + + diff --git a/intc-modules/intc-fishery/src/main/resources/mapper/fishery/TecentUserCacheMapper.xml b/intc-modules/intc-fishery/src/main/resources/mapper/fishery/TecentUserCacheMapper.xml new file mode 100644 index 0000000..c312cf4 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/resources/mapper/fishery/TecentUserCacheMapper.xml @@ -0,0 +1,6 @@ + + + + From 1d2e2e251356997f07450a11ad5ff1b5d1d9f606 Mon Sep 17 00:00:00 2001 From: tianyongbao Date: Thu, 30 Oct 2025 11:19:50 +0800 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20=E6=96=B0=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=BC=80=E5=8F=91=EF=BC=8C=E8=AE=BE=E5=A4=87=E5=91=8A=E8=AD=A6?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E3=80=81=E8=AE=BE=E5=A4=87=E5=AE=9E=E6=97=B6?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=9F=A5=E7=9C=8B=E7=AD=89=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- intc-admin/pom.xml | 2 +- .../controller/CallNoticeController.java | 104 ++++++++ .../MapMessageWarnCallNoticeController.java | 104 ++++++++ .../controller/MessageWarnController.java | 104 ++++++++ .../com/intc/fishery/domain/CallNotice.java | 128 +++++++++ .../domain/MapMessageWarnCallNotice.java | 46 ++++ .../com/intc/fishery/domain/MessageWarn.java | 71 +++++ .../intc/fishery/domain/bo/CallNoticeBo.java | 132 ++++++++++ .../domain/bo/MapMessageWarnCallNoticeBo.java | 46 ++++ .../intc/fishery/domain/bo/MessageWarnBo.java | 75 ++++++ .../intc/fishery/domain/vo/CallNoticeVo.java | 196 ++++++++++++++ .../domain/vo/MapMessageWarnCallNoticeVo.java | 58 +++++ .../intc/fishery/domain/vo/MessageWarnVo.java | 121 +++++++++ .../intc/fishery/mapper/CallNoticeMapper.java | 15 ++ .../MapMessageWarnCallNoticeMapper.java | 15 ++ .../fishery/mapper/MessageWarnMapper.java | 15 ++ .../fishery/service/ICallNoticeService.java | 68 +++++ .../IMapMessageWarnCallNoticeService.java | 68 +++++ .../fishery/service/IMessageWarnService.java | 68 +++++ .../service/impl/CallNoticeServiceImpl.java | 243 ++++++++++++++++++ .../MapMessageWarnCallNoticeServiceImpl.java | 133 ++++++++++ .../service/impl/MessageWarnServiceImpl.java | 200 ++++++++++++++ .../mapper/fishery/CallNoticeMapper.xml | 6 + .../MapMessageWarnCallNoticeMapper.xml | 6 + .../mapper/fishery/MessageWarnMapper.xml | 6 + .../DeviceSensorDataController.java | 34 +++ .../tdengine/domain/DeviceSensorData.java | 33 +++ .../mapper/DeviceSensorDataMapper.java | 58 +++++ .../service/IDeviceSensorDataService.java | 37 +++ .../service/impl/DeviceSensorDataService.java | 54 ++++ .../tdengine/DeviceSensorDataMapper.xml | 65 +++++ 31 files changed, 2310 insertions(+), 1 deletion(-) create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/CallNoticeController.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/MapMessageWarnCallNoticeController.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/MessageWarnController.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/CallNotice.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/MapMessageWarnCallNotice.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/MessageWarn.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/CallNoticeBo.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/MapMessageWarnCallNoticeBo.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/MessageWarnBo.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/CallNoticeVo.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/MapMessageWarnCallNoticeVo.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/MessageWarnVo.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/CallNoticeMapper.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/MapMessageWarnCallNoticeMapper.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/MessageWarnMapper.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/ICallNoticeService.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/IMapMessageWarnCallNoticeService.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/IMessageWarnService.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/CallNoticeServiceImpl.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/MapMessageWarnCallNoticeServiceImpl.java create mode 100644 intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/MessageWarnServiceImpl.java create mode 100644 intc-modules/intc-fishery/src/main/resources/mapper/fishery/CallNoticeMapper.xml create mode 100644 intc-modules/intc-fishery/src/main/resources/mapper/fishery/MapMessageWarnCallNoticeMapper.xml create mode 100644 intc-modules/intc-fishery/src/main/resources/mapper/fishery/MessageWarnMapper.xml create mode 100644 intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/controller/DeviceSensorDataController.java create mode 100644 intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/domain/DeviceSensorData.java create mode 100644 intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/mapper/DeviceSensorDataMapper.java create mode 100644 intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/service/IDeviceSensorDataService.java create mode 100644 intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/service/impl/DeviceSensorDataService.java create mode 100644 intc-modules/intc-tdengine/src/main/resources/mapper/tdengine/DeviceSensorDataMapper.xml diff --git a/intc-admin/pom.xml b/intc-admin/pom.xml index 3e99ddd..99e51cd 100644 --- a/intc-admin/pom.xml +++ b/intc-admin/pom.xml @@ -92,7 +92,7 @@ intc-fishery ${revision} - + com.intc intc-tdengine diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/CallNoticeController.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/CallNoticeController.java new file mode 100644 index 0000000..756f930 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/CallNoticeController.java @@ -0,0 +1,104 @@ +package com.intc.fishery.controller; + +import java.util.List; +import com.intc.common.excel.utils.ExcelUtil; +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import com.intc.common.idempotent.annotation.RepeatSubmit; +import com.intc.common.log.annotation.Log; +import com.intc.common.web.core.BaseController; +import com.intc.common.mybatis.core.page.PageQuery; +import com.intc.common.core.domain.R; +import com.intc.common.core.validate.AddGroup; +import com.intc.common.core.validate.EditGroup; +import com.intc.common.log.enums.BusinessType; +import com.intc.fishery.domain.vo.CallNoticeVo; +import com.intc.fishery.domain.bo.CallNoticeBo; +import com.intc.fishery.service.ICallNoticeService; +import com.intc.common.mybatis.core.page.TableDataInfo; + +/** + * 告警电话通知记录 + * + * @author intc + * @date 2025-10-25 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/fishery/callNotice") +public class CallNoticeController extends BaseController { + + private final ICallNoticeService callNoticeService; + + /** + * 查询告警电话通知记录列表 + */ + @SaCheckPermission("fishery:callNotice:list") + @GetMapping("/list") + public TableDataInfo list(CallNoticeBo bo, PageQuery pageQuery) { + return callNoticeService.queryPageList(bo, pageQuery); + } + + /** + * 导出告警电话通知记录列表 + */ + @SaCheckPermission("fishery:callNotice:export") + @Log(title = "告警电话通知记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(CallNoticeBo bo, HttpServletResponse response) { + List list = callNoticeService.queryList(bo); + ExcelUtil.exportExcel(list, "告警电话通知记录", CallNoticeVo.class, response); + } + + /** + * 获取告警电话通知记录详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("fishery:callNotice:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(callNoticeService.queryById(id)); + } + + /** + * 新增告警电话通知记录 + */ + @SaCheckPermission("fishery:callNotice:add") + @Log(title = "告警电话通知记录", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody CallNoticeBo bo) { + return toAjax(callNoticeService.insertByBo(bo)); + } + + /** + * 修改告警电话通知记录 + */ + @SaCheckPermission("fishery:callNotice:edit") + @Log(title = "告警电话通知记录", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody CallNoticeBo bo) { + return toAjax(callNoticeService.updateByBo(bo)); + } + + /** + * 删除告警电话通知记录 + * + * @param ids 主键串 + */ + @SaCheckPermission("fishery:callNotice:remove") + @Log(title = "告警电话通知记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(callNoticeService.deleteWithValidByIds(List.of(ids), true)); + } +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/MapMessageWarnCallNoticeController.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/MapMessageWarnCallNoticeController.java new file mode 100644 index 0000000..8e1e75b --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/MapMessageWarnCallNoticeController.java @@ -0,0 +1,104 @@ +package com.intc.fishery.controller; + +import java.util.List; +import com.intc.common.excel.utils.ExcelUtil; +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import com.intc.common.idempotent.annotation.RepeatSubmit; +import com.intc.common.log.annotation.Log; +import com.intc.common.web.core.BaseController; +import com.intc.common.mybatis.core.page.PageQuery; +import com.intc.common.core.domain.R; +import com.intc.common.core.validate.AddGroup; +import com.intc.common.core.validate.EditGroup; +import com.intc.common.log.enums.BusinessType; +import com.intc.fishery.domain.vo.MapMessageWarnCallNoticeVo; +import com.intc.fishery.domain.bo.MapMessageWarnCallNoticeBo; +import com.intc.fishery.service.IMapMessageWarnCallNoticeService; +import com.intc.common.mybatis.core.page.TableDataInfo; + +/** + * 告警消息和电话告警通知关系表 + * + * @author intc + * @date 2025-10-25 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/fishery/mapMessageWarnCallNotice") +public class MapMessageWarnCallNoticeController extends BaseController { + + private final IMapMessageWarnCallNoticeService mapMessageWarnCallNoticeService; + + /** + * 查询告警消息和电话告警通知关系表列表 + */ + @SaCheckPermission("fishery:mapMessageWarnCallNotice:list") + @GetMapping("/list") + public TableDataInfo list(MapMessageWarnCallNoticeBo bo, PageQuery pageQuery) { + return mapMessageWarnCallNoticeService.queryPageList(bo, pageQuery); + } + + /** + * 导出告警消息和电话告警通知关系表列表 + */ + @SaCheckPermission("fishery:mapMessageWarnCallNotice:export") + @Log(title = "告警消息和电话告警通知关系表", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(MapMessageWarnCallNoticeBo bo, HttpServletResponse response) { + List list = mapMessageWarnCallNoticeService.queryList(bo); + ExcelUtil.exportExcel(list, "告警消息和电话告警通知关系表", MapMessageWarnCallNoticeVo.class, response); + } + + /** + * 获取告警消息和电话告警通知关系表详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("fishery:mapMessageWarnCallNotice:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(mapMessageWarnCallNoticeService.queryById(id)); + } + + /** + * 新增告警消息和电话告警通知关系表 + */ + @SaCheckPermission("fishery:mapMessageWarnCallNotice:add") + @Log(title = "告警消息和电话告警通知关系表", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody MapMessageWarnCallNoticeBo bo) { + return toAjax(mapMessageWarnCallNoticeService.insertByBo(bo)); + } + + /** + * 修改告警消息和电话告警通知关系表 + */ + @SaCheckPermission("fishery:mapMessageWarnCallNotice:edit") + @Log(title = "告警消息和电话告警通知关系表", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody MapMessageWarnCallNoticeBo bo) { + return toAjax(mapMessageWarnCallNoticeService.updateByBo(bo)); + } + + /** + * 删除告警消息和电话告警通知关系表 + * + * @param ids 主键串 + */ + @SaCheckPermission("fishery:mapMessageWarnCallNotice:remove") + @Log(title = "告警消息和电话告警通知关系表", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(mapMessageWarnCallNoticeService.deleteWithValidByIds(List.of(ids), true)); + } +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/MessageWarnController.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/MessageWarnController.java new file mode 100644 index 0000000..039d670 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/MessageWarnController.java @@ -0,0 +1,104 @@ +package com.intc.fishery.controller; + +import java.util.List; +import com.intc.common.excel.utils.ExcelUtil; +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import com.intc.common.idempotent.annotation.RepeatSubmit; +import com.intc.common.log.annotation.Log; +import com.intc.common.web.core.BaseController; +import com.intc.common.mybatis.core.page.PageQuery; +import com.intc.common.core.domain.R; +import com.intc.common.core.validate.AddGroup; +import com.intc.common.core.validate.EditGroup; +import com.intc.common.log.enums.BusinessType; +import com.intc.fishery.domain.vo.MessageWarnVo; +import com.intc.fishery.domain.bo.MessageWarnBo; +import com.intc.fishery.service.IMessageWarnService; +import com.intc.common.mybatis.core.page.TableDataInfo; + +/** + * 设备告警记录 + * + * @author intc + * @date 2025-10-25 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/fishery/messageWarn") +public class MessageWarnController extends BaseController { + + private final IMessageWarnService messageWarnService; + + /** + * 查询设备告警记录列表 + */ + @SaCheckPermission("fishery:messageWarn:list") + @GetMapping("/list") + public TableDataInfo list(MessageWarnBo bo, PageQuery pageQuery) { + return messageWarnService.queryPageList(bo, pageQuery); + } + + /** + * 导出设备告警记录列表 + */ + @SaCheckPermission("fishery:messageWarn:export") + @Log(title = "设备告警记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(MessageWarnBo bo, HttpServletResponse response) { + List list = messageWarnService.queryList(bo); + ExcelUtil.exportExcel(list, "设备告警记录", MessageWarnVo.class, response); + } + + /** + * 获取设备告警记录详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("fishery:messageWarn:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(messageWarnService.queryById(id)); + } + + /** + * 新增设备告警记录 + */ + @SaCheckPermission("fishery:messageWarn:add") + @Log(title = "设备告警记录", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody MessageWarnBo bo) { + return toAjax(messageWarnService.insertByBo(bo)); + } + + /** + * 修改设备告警记录 + */ + @SaCheckPermission("fishery:messageWarn:edit") + @Log(title = "设备告警记录", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody MessageWarnBo bo) { + return toAjax(messageWarnService.updateByBo(bo)); + } + + /** + * 删除设备告警记录 + * + * @param ids 主键串 + */ + @SaCheckPermission("fishery:messageWarn:remove") + @Log(title = "设备告警记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(messageWarnService.deleteWithValidByIds(List.of(ids), true)); + } +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/CallNotice.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/CallNotice.java new file mode 100644 index 0000000..c71adb1 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/CallNotice.java @@ -0,0 +1,128 @@ +package com.intc.fishery.domain; + +import com.baomidou.mybatisplus.annotation.*; +import com.intc.common.tenant.core.TenantEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serial; + +/** + * 告警电话通知记录对象 aqu_call_notice + * + * @author intc + * @date 2025-10-25 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("aqu_call_notice") +public class CallNotice extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id") + private Long id; + + /** + * 用户id + */ + private Long userId; + + /** + * 通知手机号 + */ + private String mobilePhone; + + /** + * 设备id + */ + private Long deviceId; + + /** + * 设定的呼叫时间 + */ + private Date callTime; + + /** + * 呼叫的CallId + */ + private String callId; + + /** + * 呼叫状态 + */ + private Integer callStatus; + + /** + * 主叫号码 + */ + private String caller; + + /** + * 通话时长 + */ + private String duration; + + /** + * 通话结束时间 + */ + private String endTime; + + /** + * 挂断方向 + */ + private String hangupDirection; + + /** + * 呼叫发起时间 + */ + private String originateTime; + + /** + * 扩展字段回传 + */ + private String outId; + + /** + * 被叫响铃时间 + */ + private String ringTime; + + /** + * 通话接通时间 + */ + private String startTime; + + /** + * 呼叫结果状态码 + */ + private String statusCode; + + /** + * 结果描述 + */ + private String statusMsg; + + /** + * 通话类型 + */ + private String tollType; + + /** + * 话单类型 + */ + private String voiceType; + + /** + * 塘口名称 + */ + private String pondName; + + +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/MapMessageWarnCallNotice.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/MapMessageWarnCallNotice.java new file mode 100644 index 0000000..bcc175e --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/MapMessageWarnCallNotice.java @@ -0,0 +1,46 @@ +package com.intc.fishery.domain; + +import com.baomidou.mybatisplus.annotation.*; +import com.intc.common.tenant.core.TenantEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; + +/** + * 告警消息和电话告警通知关系表对象 aqu_map_message_warn_call_notice + * + * @author intc + * @date 2025-10-25 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("aqu_map_message_warn_call_notice") +public class MapMessageWarnCallNotice extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id") + private Long id; + + /** + * 告警消息Id + */ + private Long messageWarnId; + + /** + * 电话通知id + */ + private Long callNoticeId; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/MessageWarn.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/MessageWarn.java new file mode 100644 index 0000000..5a949e5 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/MessageWarn.java @@ -0,0 +1,71 @@ +package com.intc.fishery.domain; + +import com.baomidou.mybatisplus.annotation.*; +import com.intc.common.tenant.core.TenantEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; + +/** + * 设备告警记录对象 aqu_message_warn + * + * @author intc + * @date 2025-10-25 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("aqu_message_warn") +public class MessageWarn extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id") + private Long id; + + /** + * 用户id + */ + private Long userId; + + /** + * 设备id + */ + private Long deviceId; + + /** + * 消息标题 + */ + private String title; + + /** + * 消息内容 + */ + private String message; + + /** + * 是否已读 + */ + private Integer isRead; + + /** + * 告警类型 + */ + private Integer warnType; + + /** + * 塘口名称 + */ + private String pondName; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/CallNoticeBo.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/CallNoticeBo.java new file mode 100644 index 0000000..5d96fca --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/CallNoticeBo.java @@ -0,0 +1,132 @@ +package com.intc.fishery.domain.bo; +import com.intc.common.core.validate.AddGroup; +import com.intc.common.core.validate.EditGroup; +import com.intc.fishery.domain.CallNotice; +import com.intc.common.mybatis.core.domain.BaseEntity; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +/** + * 告警电话通知记录业务对象 aqu_call_notice + * + * @author intc + * @date 2025-10-25 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = CallNotice.class, reverseConvertGenerate = false) +public class CallNoticeBo extends BaseEntity { + + /** + * 主键id + */ + @NotNull(message = "主键id不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 用户id + */ + @NotNull(message = "用户id不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long userId; + + /** + * 通知手机号 + */ + @NotBlank(message = "通知手机号不能为空", groups = { AddGroup.class, EditGroup.class }) + private String mobilePhone; + + /** + * 设备id + */ + @NotNull(message = "设备id不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long deviceId; + + /** + * 设定的呼叫时间 + */ + @NotNull(message = "设定的呼叫时间不能为空", groups = { AddGroup.class, EditGroup.class }) + private Date callTime; + + /** + * 呼叫的CallId + */ + private String callId; + + /** + * 呼叫状态 + */ + @NotNull(message = "呼叫状态不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer callStatus; + + /** + * 主叫号码 + */ + private String caller; + + /** + * 通话时长 + */ + private String duration; + + /** + * 通话结束时间 + */ + private String endTime; + + /** + * 挂断方向 + */ + private String hangupDirection; + + /** + * 呼叫发起时间 + */ + private String originateTime; + + /** + * 扩展字段回传 + */ + private String outId; + + /** + * 被叫响铃时间 + */ + private String ringTime; + + /** + * 通话接通时间 + */ + private String startTime; + + /** + * 呼叫结果状态码 + */ + private String statusCode; + + /** + * 结果描述 + */ + private String statusMsg; + + /** + * 通话类型 + */ + private String tollType; + + /** + * 话单类型 + */ + private String voiceType; + + /** + * 塘口名称 + */ + @NotBlank(message = "塘口名称不能为空", groups = { AddGroup.class }) + private String pondName; + + +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/MapMessageWarnCallNoticeBo.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/MapMessageWarnCallNoticeBo.java new file mode 100644 index 0000000..0baa693 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/MapMessageWarnCallNoticeBo.java @@ -0,0 +1,46 @@ +package com.intc.fishery.domain.bo; +import com.intc.common.core.validate.AddGroup; +import com.intc.common.core.validate.EditGroup; +import com.intc.fishery.domain.MapMessageWarnCallNotice; +import com.intc.common.mybatis.core.domain.BaseEntity; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; + +/** + * 告警消息和电话告警通知关系表业务对象 aqu_map_message_warn_call_notice + * + * @author intc + * @date 2025-10-25 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = MapMessageWarnCallNotice.class, reverseConvertGenerate = false) +public class MapMessageWarnCallNoticeBo extends BaseEntity { + + /** + * 主键id + */ + @NotNull(message = "主键id不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 告警消息Id + */ + @NotNull(message = "告警消息Id不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long messageWarnId; + + /** + * 电话通知id + */ + @NotNull(message = "电话通知id不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long callNoticeId; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/MessageWarnBo.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/MessageWarnBo.java new file mode 100644 index 0000000..649d2c6 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/bo/MessageWarnBo.java @@ -0,0 +1,75 @@ +package com.intc.fishery.domain.bo; +import com.intc.common.core.validate.AddGroup; +import com.intc.common.core.validate.EditGroup; +import com.intc.fishery.domain.MessageWarn; +import com.intc.common.mybatis.core.domain.BaseEntity; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; + +/** + * 设备告警记录业务对象 aqu_message_warn + * + * @author intc + * @date 2025-10-25 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = MessageWarn.class, reverseConvertGenerate = false) +public class MessageWarnBo extends BaseEntity { + + /** + * 主键id + */ + @NotNull(message = "主键id不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 用户id + */ + @NotNull(message = "用户id不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long userId; + + /** + * 设备id + */ + @NotNull(message = "设备id不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long deviceId; + + /** + * 消息标题 + */ + @NotBlank(message = "消息标题不能为空", groups = { AddGroup.class, EditGroup.class }) + private String title; + + /** + * 消息内容 + */ + @NotBlank(message = "消息内容不能为空", groups = { AddGroup.class, EditGroup.class }) + private String message; + + /** + * 是否已读 + */ + @NotNull(message = "是否已读不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer isRead; + + /** + * 告警类型 + */ + @NotNull(message = "告警类型不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer warnType; + + /** + * 塘口名称 + */ + private String pondName; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/CallNoticeVo.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/CallNoticeVo.java new file mode 100644 index 0000000..e6ebdad --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/CallNoticeVo.java @@ -0,0 +1,196 @@ +package com.intc.fishery.domain.vo; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.intc.fishery.domain.CallNotice; +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import com.intc.common.excel.annotation.ExcelDictFormat; +import com.intc.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + + +/** + * 告警电话通知记录视图对象 aqu_call_notice + * + * @author intc + * @date 2025-10-25 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = CallNotice.class) +public class CallNoticeVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @ExcelProperty(value = "主键id") + private Long id; + + /** + * 用户id + */ + @ExcelProperty(value = "用户id") + private Long userId; + + /** + * 通知手机号 + */ + @ExcelProperty(value = "通知手机号") + private String mobilePhone; + + /** + * 设备id + */ + @ExcelProperty(value = "设备id") + private Long deviceId; + + /** + * 呼叫状态 + */ + @ExcelProperty(value = "呼叫状态", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "call_status") + private Integer callStatus; + + /** + * 主叫号码 + */ + @ExcelProperty(value = "主叫号码") + private String caller; + + /** + * 通话时长 + */ + @ExcelProperty(value = "通话时长") + private String duration; + + /** + * 通话结束时间 + */ + @ExcelProperty(value = "通话结束时间") + private String endTime; + + /** + * 挂断方向 + */ + @ExcelProperty(value = "挂断方向") + private String hangupDirection; + + /** + * 呼叫发起时间 + */ + @ExcelProperty(value = "呼叫发起时间") + private String originateTime; + + /** + * 扩展字段回传 + */ + @ExcelProperty(value = "扩展字段回传") + private String outId; + + /** + * 被叫响铃时间 + */ + @ExcelProperty(value = "被叫响铃时间") + private String ringTime; + + /** + * 通话接通时间 + */ + @ExcelProperty(value = "通话接通时间") + private String startTime; + + /** + * 呼叫结果状态码 + */ + @ExcelProperty(value = "呼叫结果状态码") + private String statusCode; + + /** + * 设定的呼叫时间 + */ + private Date callTime; + + /** + * 结果描述 + */ + @ExcelProperty(value = "结果描述") + private String statusMsg; + + /** + * 通话类型 + */ + @ExcelProperty(value = "通话类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "toll_type") + private String tollType; + + /** + * 话单类型 + */ + @ExcelProperty(value = "话单类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "voice_type") + private String voiceType; + + private Date createTime; + + private Date updateTime; + + /** + * 用户名(关联查询) + */ + @ExcelProperty(value = "用户名") + private String userName; + + /** + * 用户手机号(关联查询) + */ + @ExcelProperty(value = "用户手机号") + private String userMobilePhone; + + /** + * 设备名称(关联查询) + */ + @ExcelProperty(value = "设备名称") + private String deviceName; + + /** + * 设备编号(关联查询) + */ + @ExcelProperty(value = "设备编号") + private String serialNum; + + /** + * 设备类型(关联查询) + */ + @ExcelProperty(value = "设备类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "aqu_device_type") + private Integer deviceType; + + /** + * 告警类型(关联查询) + */ + @ExcelProperty(value = "告警类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "warn_type") + private Integer warnType; + + /** + * 告警标题(关联查询) + */ + @ExcelProperty(value = "告警标题") + private String warnTitle; + + /** + * 告警内容(关联查询) + */ + @ExcelProperty(value = "告警内容") + private String warnMessage; +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/MapMessageWarnCallNoticeVo.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/MapMessageWarnCallNoticeVo.java new file mode 100644 index 0000000..fa729d8 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/MapMessageWarnCallNoticeVo.java @@ -0,0 +1,58 @@ +package com.intc.fishery.domain.vo; + +import com.intc.fishery.domain.MapMessageWarnCallNotice; +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import com.intc.common.excel.annotation.ExcelDictFormat; +import com.intc.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + + +/** + * 告警消息和电话告警通知关系表视图对象 aqu_map_message_warn_call_notice + * + * @author intc + * @date 2025-10-25 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = MapMessageWarnCallNotice.class) +public class MapMessageWarnCallNoticeVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @ExcelProperty(value = "主键id") + private Long id; + + /** + * 告警消息Id + */ + @ExcelProperty(value = "告警消息Id") + private Long messageWarnId; + + /** + * 电话通知id + */ + @ExcelProperty(value = "电话通知id") + private Long callNoticeId; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + private Date createTime; + + private Date updateTime; +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/MessageWarnVo.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/MessageWarnVo.java new file mode 100644 index 0000000..f589471 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/domain/vo/MessageWarnVo.java @@ -0,0 +1,121 @@ +package com.intc.fishery.domain.vo; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + +import com.intc.common.excel.annotation.ExcelDictFormat; +import com.intc.common.excel.convert.ExcelDictConvert; +import com.intc.fishery.domain.MessageWarn; + +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + + + +/** + * 设备告警记录视图对象 aqu_message_warn + * + * @author intc + * @date 2025-10-25 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = MessageWarn.class) +public class MessageWarnVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @ExcelProperty(value = "主键id") + private Long id; + + /** + * 用户id + */ + @ExcelProperty(value = "用户id") + private Long userId; + + /** + * 设备id + */ + @ExcelProperty(value = "设备id") + private Long deviceId; + + /** + * 消息标题 + */ + @ExcelProperty(value = "消息标题") + private String title; + + /** + * 消息内容 + */ + @ExcelProperty(value = "消息内容") + private String message; + + /** + * 是否已读 + */ + @ExcelProperty(value = "是否已读", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "yes_no") + private Integer isRead; + + /** + * 告警类型 + */ + @ExcelProperty(value = "告警类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "warn_type") + private Integer warnType; + + /** + * 塘口名称 + */ + @ExcelProperty(value = "塘口名称") + private String pondName; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + private Date createTime; + + private Date updateTime; + + /** + * 用户名(关联查询) + */ + @ExcelProperty(value = "用户名") + private String userName; + + /** + * 用户手机号(关联查询) + */ + @ExcelProperty(value = "用户手机号") + private String mobilePhone; + + /** + * 设备名称(关联查询) + */ + @ExcelProperty(value = "设备名称") + private String deviceName; + + /** + * 设备编号(关联查询) + */ + @ExcelProperty(value = "设备编号") + private String serialNum; + + /** + * 电话通知次数(统计查询) + */ + @ExcelProperty(value = "电话通知次数") + private Long callNoticeCount; +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/CallNoticeMapper.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/CallNoticeMapper.java new file mode 100644 index 0000000..c1ffad5 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/CallNoticeMapper.java @@ -0,0 +1,15 @@ +package com.intc.fishery.mapper; + +import com.intc.fishery.domain.CallNotice; +import com.intc.fishery.domain.vo.CallNoticeVo; +import com.intc.common.mybatis.core.mapper.BaseMapperPlusJoin; + +/** + * 告警电话通知记录Mapper接口 + * + * @author intc + * @date 2025-10-25 + */ +public interface CallNoticeMapper extends BaseMapperPlusJoin { + +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/MapMessageWarnCallNoticeMapper.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/MapMessageWarnCallNoticeMapper.java new file mode 100644 index 0000000..d3f811a --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/MapMessageWarnCallNoticeMapper.java @@ -0,0 +1,15 @@ +package com.intc.fishery.mapper; + +import com.intc.fishery.domain.MapMessageWarnCallNotice; +import com.intc.fishery.domain.vo.MapMessageWarnCallNoticeVo; +import com.intc.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 告警消息和电话告警通知关系表Mapper接口 + * + * @author intc + * @date 2025-10-25 + */ +public interface MapMessageWarnCallNoticeMapper extends BaseMapperPlus { + +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/MessageWarnMapper.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/MessageWarnMapper.java new file mode 100644 index 0000000..37ae332 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/mapper/MessageWarnMapper.java @@ -0,0 +1,15 @@ +package com.intc.fishery.mapper; + +import com.intc.common.mybatis.core.mapper.BaseMapperPlusJoin; +import com.intc.fishery.domain.MessageWarn; +import com.intc.fishery.domain.vo.MessageWarnVo; + +/** + * 设备告警记录Mapper接口 + * + * @author intc + * @date 2025-10-25 + */ +public interface MessageWarnMapper extends BaseMapperPlusJoin { + +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/ICallNoticeService.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/ICallNoticeService.java new file mode 100644 index 0000000..4a1c35f --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/ICallNoticeService.java @@ -0,0 +1,68 @@ +package com.intc.fishery.service; + +import com.intc.fishery.domain.vo.CallNoticeVo; +import com.intc.fishery.domain.bo.CallNoticeBo; +import com.intc.common.mybatis.core.page.TableDataInfo; +import com.intc.common.mybatis.core.page.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 告警电话通知记录Service接口 + * + * @author intc + * @date 2025-10-25 + */ +public interface ICallNoticeService { + + /** + * 查询告警电话通知记录 + * + * @param id 主键 + * @return 告警电话通知记录 + */ + CallNoticeVo queryById(Long id); + + /** + * 分页查询告警电话通知记录列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 告警电话通知记录分页列表 + */ + TableDataInfo queryPageList(CallNoticeBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的告警电话通知记录列表 + * + * @param bo 查询条件 + * @return 告警电话通知记录列表 + */ + List queryList(CallNoticeBo bo); + + /** + * 新增告警电话通知记录 + * + * @param bo 告警电话通知记录 + * @return 是否新增成功 + */ + Boolean insertByBo(CallNoticeBo bo); + + /** + * 修改告警电话通知记录 + * + * @param bo 告警电话通知记录 + * @return 是否修改成功 + */ + Boolean updateByBo(CallNoticeBo bo); + + /** + * 校验并批量删除告警电话通知记录信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/IMapMessageWarnCallNoticeService.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/IMapMessageWarnCallNoticeService.java new file mode 100644 index 0000000..db7bc2a --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/IMapMessageWarnCallNoticeService.java @@ -0,0 +1,68 @@ +package com.intc.fishery.service; + +import com.intc.fishery.domain.vo.MapMessageWarnCallNoticeVo; +import com.intc.fishery.domain.bo.MapMessageWarnCallNoticeBo; +import com.intc.common.mybatis.core.page.TableDataInfo; +import com.intc.common.mybatis.core.page.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 告警消息和电话告警通知关系表Service接口 + * + * @author intc + * @date 2025-10-25 + */ +public interface IMapMessageWarnCallNoticeService { + + /** + * 查询告警消息和电话告警通知关系表 + * + * @param id 主键 + * @return 告警消息和电话告警通知关系表 + */ + MapMessageWarnCallNoticeVo queryById(Long id); + + /** + * 分页查询告警消息和电话告警通知关系表列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 告警消息和电话告警通知关系表分页列表 + */ + TableDataInfo queryPageList(MapMessageWarnCallNoticeBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的告警消息和电话告警通知关系表列表 + * + * @param bo 查询条件 + * @return 告警消息和电话告警通知关系表列表 + */ + List queryList(MapMessageWarnCallNoticeBo bo); + + /** + * 新增告警消息和电话告警通知关系表 + * + * @param bo 告警消息和电话告警通知关系表 + * @return 是否新增成功 + */ + Boolean insertByBo(MapMessageWarnCallNoticeBo bo); + + /** + * 修改告警消息和电话告警通知关系表 + * + * @param bo 告警消息和电话告警通知关系表 + * @return 是否修改成功 + */ + Boolean updateByBo(MapMessageWarnCallNoticeBo bo); + + /** + * 校验并批量删除告警消息和电话告警通知关系表信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/IMessageWarnService.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/IMessageWarnService.java new file mode 100644 index 0000000..2031cf2 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/IMessageWarnService.java @@ -0,0 +1,68 @@ +package com.intc.fishery.service; + +import com.intc.fishery.domain.vo.MessageWarnVo; +import com.intc.fishery.domain.bo.MessageWarnBo; +import com.intc.common.mybatis.core.page.TableDataInfo; +import com.intc.common.mybatis.core.page.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 设备告警记录Service接口 + * + * @author intc + * @date 2025-10-25 + */ +public interface IMessageWarnService { + + /** + * 查询设备告警记录 + * + * @param id 主键 + * @return 设备告警记录 + */ + MessageWarnVo queryById(Long id); + + /** + * 分页查询设备告警记录列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 设备告警记录分页列表 + */ + TableDataInfo queryPageList(MessageWarnBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的设备告警记录列表 + * + * @param bo 查询条件 + * @return 设备告警记录列表 + */ + List queryList(MessageWarnBo bo); + + /** + * 新增设备告警记录 + * + * @param bo 设备告警记录 + * @return 是否新增成功 + */ + Boolean insertByBo(MessageWarnBo bo); + + /** + * 修改设备告警记录 + * + * @param bo 设备告警记录 + * @return 是否修改成功 + */ + Boolean updateByBo(MessageWarnBo bo); + + /** + * 校验并批量删除设备告警记录信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/CallNoticeServiceImpl.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/CallNoticeServiceImpl.java new file mode 100644 index 0000000..e35d5ac --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/CallNoticeServiceImpl.java @@ -0,0 +1,243 @@ +package com.intc.fishery.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.github.yulichang.wrapper.MPJLambdaWrapper; +import com.intc.common.core.utils.MapstructUtils; +import com.intc.common.core.utils.StringUtils; +import com.intc.common.mybatis.core.page.TableDataInfo; +import com.intc.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import com.intc.fishery.domain.bo.CallNoticeBo; +import com.intc.fishery.domain.vo.CallNoticeVo; +import com.intc.fishery.domain.CallNotice; +import com.intc.fishery.domain.AquUser; +import com.intc.fishery.domain.Device; +import com.intc.fishery.domain.MapMessageWarnCallNotice; +import com.intc.fishery.domain.MessageWarn; +import com.intc.fishery.mapper.CallNoticeMapper; +import com.intc.fishery.mapper.MapMessageWarnCallNoticeMapper; +import com.intc.fishery.service.ICallNoticeService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 告警电话通知记录Service业务层处理 + * + * @author intc + * @date 2025-10-25 + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class CallNoticeServiceImpl implements ICallNoticeService { + + private final CallNoticeMapper baseMapper; + private final MapMessageWarnCallNoticeMapper mapMessageWarnCallNoticeMapper; + + /** + * 查询告警电话通知记录 + * + * @param id 主键 + * @return 告警电话通知记录 + */ + @Override + public CallNoticeVo queryById(Long id){ + MPJLambdaWrapper wrapper = new MPJLambdaWrapper() + .selectAll(CallNotice.class) + .selectAs(AquUser::getUserName, CallNoticeVo::getUserName) + .selectAs(AquUser::getMobilePhone, CallNoticeVo::getUserMobilePhone) + .selectAs(Device::getDeviceName, CallNoticeVo::getDeviceName) + .selectAs(Device::getSerialNum, CallNoticeVo::getSerialNum) + .selectAs(Device::getDeviceType, CallNoticeVo::getDeviceType) + .select("mw.warn_type AS warnType") + .select("mw.title AS warnTitle") + .select("mw.message AS warnMessage") + .leftJoin(AquUser.class, AquUser::getId, CallNotice::getUserId) + .leftJoin(Device.class, Device::getId, CallNotice::getDeviceId) + .leftJoin("aqu_map_message_warn_call_notice map ON map.call_notice_id = t.id") + .leftJoin("aqu_message_warn mw ON mw.id = map.message_warn_id") + .eq(CallNotice::getId, id); + return baseMapper.selectJoinOne(CallNoticeVo.class, wrapper); + } + + /** + * 分页查询告警电话通知记录列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 告警电话通知记录分页列表 + */ + @Override + public TableDataInfo queryPageList(CallNoticeBo bo, PageQuery pageQuery) { + MPJLambdaWrapper wrapper = buildJoinQueryWrapper(bo); + Page result = baseMapper.selectJoinPage(pageQuery.build(), CallNoticeVo.class, wrapper); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的告警电话通知记录列表 + * + * @param bo 查询条件 + * @return 告警电话通知记录列表 + */ + @Override + public List queryList(CallNoticeBo bo) { + MPJLambdaWrapper wrapper = buildJoinQueryWrapper(bo); + return baseMapper.selectJoinList(CallNoticeVo.class, wrapper); + } + + /** + * 构建关联查询条件 + * + * @param bo 查询条件 + * @return 关联查询Wrapper + */ + private MPJLambdaWrapper buildJoinQueryWrapper(CallNoticeBo bo) { + Map params = bo.getParams(); + MPJLambdaWrapper wrapper = new MPJLambdaWrapper() + .selectAll(CallNotice.class) + .selectAs(AquUser::getUserName, CallNoticeVo::getUserName) + .selectAs(AquUser::getMobilePhone, CallNoticeVo::getUserMobilePhone) + .selectAs(Device::getDeviceName, CallNoticeVo::getDeviceName) + .selectAs(Device::getSerialNum, CallNoticeVo::getSerialNum) + .selectAs(Device::getDeviceType, CallNoticeVo::getDeviceType) + .select("mw.warn_type AS warnType") + .select("mw.title AS warnTitle") + .select("mw.message AS warnMessage") + .leftJoin(AquUser.class, AquUser::getId, CallNotice::getUserId) + .leftJoin(Device.class, Device::getId, CallNotice::getDeviceId) + .leftJoin("aqu_map_message_warn_call_notice map ON map.call_notice_id = t.id") + .leftJoin("aqu_message_warn mw ON mw.id = map.message_warn_id") + .eq(bo.getUserId() != null, CallNotice::getUserId, bo.getUserId()) + .eq(bo.getCallStatus() != null, CallNotice::getCallStatus, bo.getCallStatus()) + .eq(StringUtils.isNotBlank(bo.getMobilePhone()), CallNotice::getMobilePhone, bo.getMobilePhone()) + .eq(bo.getDeviceId() != null, CallNotice::getDeviceId, bo.getDeviceId()) + .eq(StringUtils.isNotBlank(bo.getDuration()), CallNotice::getDuration, bo.getDuration()) + .eq(StringUtils.isNotBlank(bo.getEndTime()), CallNotice::getEndTime, bo.getEndTime()) + .eq(StringUtils.isNotBlank(bo.getHangupDirection()), CallNotice::getHangupDirection, bo.getHangupDirection()) + .eq(StringUtils.isNotBlank(bo.getTollType()), CallNotice::getTollType, bo.getTollType()) + .orderByDesc(CallNotice::getCallTime); + + // 处理额外的查询参数 + if (params != null && !params.isEmpty()) { + handleExtraParams(wrapper, params); + } + + return wrapper; + } + + /** + * 处理额外的查询参数 + * + * @param wrapper 查询包装器 + * @param params 额外参数 + */ + private void handleExtraParams(MPJLambdaWrapper wrapper, Map params) { + // 处理用户名或用户手机号模糊查询 + String userKeyword = (String) params.get("userKeyword"); + if (StringUtils.isNotBlank(userKeyword)) { + wrapper.and(w -> w.like(AquUser::getUserName, userKeyword) + .or() + .like(AquUser::getMobilePhone, userKeyword)); + } + + // 处理设备名称或设备编号模糊查询 + String deviceKeyword = (String) params.get("deviceKeyword"); + if (StringUtils.isNotBlank(deviceKeyword)) { + wrapper.and(w -> w.like(Device::getDeviceName, deviceKeyword) + .or() + .like(Device::getSerialNum, deviceKeyword)); + } + + // 处理设备类型精确查询 + Object deviceTypeObj = params.get("deviceType"); + if (deviceTypeObj != null) { + Integer deviceType = deviceTypeObj instanceof String ? + Integer.valueOf((String) deviceTypeObj) : (Integer) deviceTypeObj; + wrapper.eq(Device::getDeviceType, deviceType); + } + + // 处理告警类型精确查询 + Object warnTypeObj = params.get("warnType"); + if (warnTypeObj != null) { + Integer warnType = warnTypeObj instanceof String ? + Integer.valueOf((String) warnTypeObj) : (Integer) warnTypeObj; + wrapper.apply("mw.warn_type = {0}", warnType); + } + + // 处理告警ID精确查询 + Object messageWarnIdObj = params.get("messageWarnId"); + if (messageWarnIdObj != null) { + Long messageWarnId = messageWarnIdObj instanceof String ? + Long.valueOf((String) messageWarnIdObj) : (Long) messageWarnIdObj; + wrapper.eq("mw.id", messageWarnId); + } + } + + /** + * 新增告警电话通知记录 + * + * @param bo 告警电话通知记录 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(CallNoticeBo bo) { + CallNotice add = MapstructUtils.convert(bo, CallNotice.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改告警电话通知记录 + * + * @param bo 告警电话通知记录 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(CallNoticeBo bo) { + CallNotice update = MapstructUtils.convert(bo, CallNotice.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(CallNotice entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除告警电话通知记录信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + + // 先删除中间表的关联记录 + for (Long callNoticeId : ids) { + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + wrapper.eq(MapMessageWarnCallNotice::getCallNoticeId, callNoticeId); + mapMessageWarnCallNoticeMapper.delete(wrapper); + } + + // 再删除主表记录 + return baseMapper.deleteByIds(ids) > 0; + } +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/MapMessageWarnCallNoticeServiceImpl.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/MapMessageWarnCallNoticeServiceImpl.java new file mode 100644 index 0000000..653be4c --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/MapMessageWarnCallNoticeServiceImpl.java @@ -0,0 +1,133 @@ +package com.intc.fishery.service.impl; + +import com.intc.common.core.utils.MapstructUtils; +import com.intc.common.core.utils.StringUtils; +import com.intc.common.mybatis.core.page.TableDataInfo; +import com.intc.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import com.intc.fishery.domain.bo.MapMessageWarnCallNoticeBo; +import com.intc.fishery.domain.vo.MapMessageWarnCallNoticeVo; +import com.intc.fishery.domain.MapMessageWarnCallNotice; +import com.intc.fishery.mapper.MapMessageWarnCallNoticeMapper; +import com.intc.fishery.service.IMapMessageWarnCallNoticeService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 告警消息和电话告警通知关系表Service业务层处理 + * + * @author intc + * @date 2025-10-25 + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class MapMessageWarnCallNoticeServiceImpl implements IMapMessageWarnCallNoticeService { + + private final MapMessageWarnCallNoticeMapper baseMapper; + + /** + * 查询告警消息和电话告警通知关系表 + * + * @param id 主键 + * @return 告警消息和电话告警通知关系表 + */ + @Override + public MapMessageWarnCallNoticeVo queryById(Long id){ + return baseMapper.selectVoById(id); + } + + /** + * 分页查询告警消息和电话告警通知关系表列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 告警消息和电话告警通知关系表分页列表 + */ + @Override + public TableDataInfo queryPageList(MapMessageWarnCallNoticeBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的告警消息和电话告警通知关系表列表 + * + * @param bo 查询条件 + * @return 告警消息和电话告警通知关系表列表 + */ + @Override + public List queryList(MapMessageWarnCallNoticeBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(MapMessageWarnCallNoticeBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.orderByAsc(MapMessageWarnCallNotice::getId); + lqw.eq(bo.getMessageWarnId() != null, MapMessageWarnCallNotice::getMessageWarnId, bo.getMessageWarnId()); + lqw.eq(bo.getCallNoticeId() != null, MapMessageWarnCallNotice::getCallNoticeId, bo.getCallNoticeId()); + return lqw; + } + + /** + * 新增告警消息和电话告警通知关系表 + * + * @param bo 告警消息和电话告警通知关系表 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(MapMessageWarnCallNoticeBo bo) { + MapMessageWarnCallNotice add = MapstructUtils.convert(bo, MapMessageWarnCallNotice.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改告警消息和电话告警通知关系表 + * + * @param bo 告警消息和电话告警通知关系表 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(MapMessageWarnCallNoticeBo bo) { + MapMessageWarnCallNotice update = MapstructUtils.convert(bo, MapMessageWarnCallNotice.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(MapMessageWarnCallNotice entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除告警消息和电话告警通知关系表信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } +} diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/MessageWarnServiceImpl.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/MessageWarnServiceImpl.java new file mode 100644 index 0000000..ad24df2 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/service/impl/MessageWarnServiceImpl.java @@ -0,0 +1,200 @@ +package com.intc.fishery.service.impl; + +import com.github.yulichang.wrapper.MPJLambdaWrapper; +import com.intc.common.core.utils.MapstructUtils; +import com.intc.common.core.utils.StringUtils; +import com.intc.common.mybatis.core.page.TableDataInfo; +import com.intc.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import com.intc.fishery.domain.bo.MessageWarnBo; +import com.intc.fishery.domain.vo.MessageWarnVo; +import com.intc.fishery.domain.MessageWarn; +import com.intc.fishery.domain.AquUser; +import com.intc.fishery.domain.Device; +import com.intc.fishery.domain.Pond; +import com.intc.fishery.mapper.MessageWarnMapper; +import com.intc.fishery.service.IMessageWarnService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 设备告警记录Service业务层处理 + * + * @author intc + * @date 2025-10-25 + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class MessageWarnServiceImpl implements IMessageWarnService { + + private final MessageWarnMapper baseMapper; + + /** + * 查询设备告警记录 + * + * @param id 主键 + * @return 设备告警记录 + */ + @Override + public MessageWarnVo queryById(Long id){ + MPJLambdaWrapper wrapper = new MPJLambdaWrapper() + .selectAll(MessageWarn.class) + .selectAs(AquUser::getUserName, MessageWarnVo::getUserName) + .selectAs(AquUser::getMobilePhone, MessageWarnVo::getMobilePhone) + .selectAs(Device::getDeviceName, MessageWarnVo::getDeviceName) + .selectAs(Device::getSerialNum, MessageWarnVo::getSerialNum) + .selectAs(Pond::getPondName, MessageWarnVo::getPondName) + .select("(SELECT COUNT(*) FROM aqu_map_message_warn_call_notice map WHERE map.message_warn_id = t.id AND map.tenant_id = t.tenant_id) AS callNoticeCount") + .leftJoin(AquUser.class, AquUser::getId, MessageWarn::getUserId) + .leftJoin(Device.class, Device::getId, MessageWarn::getDeviceId) + .leftJoin(Pond.class, Pond::getId, Device::getPondId) + .eq(MessageWarn::getId, id); + return baseMapper.selectJoinOne(MessageWarnVo.class, wrapper); + } + + /** + * 分页查询设备告警记录列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 设备告警记录分页列表 + */ + @Override + public TableDataInfo queryPageList(MessageWarnBo bo, PageQuery pageQuery) { + MPJLambdaWrapper wrapper = buildJoinQueryWrapper(bo); + Page result = baseMapper.selectJoinPage(pageQuery.build(), MessageWarnVo.class, wrapper); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的设备告警记录列表 + * + * @param bo 查询条件 + * @return 设备告警记录列表 + */ + @Override + public List queryList(MessageWarnBo bo) { + MPJLambdaWrapper wrapper = buildJoinQueryWrapper(bo); + return baseMapper.selectJoinList(MessageWarnVo.class, wrapper); + } + + /** + * 构建关联查询条件 + * + * @param bo 查询条件 + * @return 关联查询Wrapper + */ + private MPJLambdaWrapper buildJoinQueryWrapper(MessageWarnBo bo) { + Map params = bo.getParams(); + MPJLambdaWrapper wrapper = new MPJLambdaWrapper() + .selectAll(MessageWarn.class) + .selectAs(AquUser::getUserName, MessageWarnVo::getUserName) + .selectAs(AquUser::getMobilePhone, MessageWarnVo::getMobilePhone) + .selectAs(Device::getDeviceName, MessageWarnVo::getDeviceName) + .selectAs(Device::getSerialNum, MessageWarnVo::getSerialNum) + .selectAs(Pond::getPondName, MessageWarnVo::getPondName) + .select("(SELECT COUNT(*) FROM aqu_map_message_warn_call_notice map WHERE map.message_warn_id = t.id AND map.tenant_id = t.tenant_id) AS callNoticeCount") + .leftJoin(AquUser.class, AquUser::getId, MessageWarn::getUserId) + .leftJoin(Device.class, Device::getId, MessageWarn::getDeviceId) + .leftJoin(Pond.class, Pond::getId, Device::getPondId) + .eq(bo.getUserId() != null, MessageWarn::getUserId, bo.getUserId()) + .eq(bo.getDeviceId() != null, MessageWarn::getDeviceId, bo.getDeviceId()) + .eq(StringUtils.isNotBlank(bo.getTitle()), MessageWarn::getTitle, bo.getTitle()) + .eq(StringUtils.isNotBlank(bo.getMessage()), MessageWarn::getMessage, bo.getMessage()) + .eq(bo.getIsRead() != null, MessageWarn::getIsRead, bo.getIsRead()) + .eq(bo.getWarnType() != null, MessageWarn::getWarnType, bo.getWarnType()) + .like(StringUtils.isNotBlank(bo.getPondName()), MessageWarn::getPondName, bo.getPondName()) + .orderByDesc(MessageWarn::getCreateTime); + + // 处理额外的查询参数 + if (params != null && !params.isEmpty()) { + handleExtraParams(wrapper, params); + } + + return wrapper; + } + + /** + * 处理额外的查询参数 + * + * @param wrapper 查询包装器 + * @param params 额外参数 + */ + private void handleExtraParams(MPJLambdaWrapper wrapper, Map params) { + // 处理用户名或用户手机号模糊查询 + String userKeyword = (String) params.get("userKeyword"); + if (StringUtils.isNotBlank(userKeyword)) { + wrapper.and(w -> w.like(AquUser::getUserName, userKeyword) + .or() + .like(AquUser::getMobilePhone, userKeyword)); + } + + // 处理设备名称或设备编号模糊查询 + String deviceKeyword = (String) params.get("deviceKeyword"); + if (StringUtils.isNotBlank(deviceKeyword)) { + wrapper.and(w -> w.like(Device::getDeviceName, deviceKeyword) + .or() + .like(Device::getSerialNum, deviceKeyword)); + } + } + + /** + * 新增设备告警记录 + * + * @param bo 设备告警记录 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(MessageWarnBo bo) { + MessageWarn add = MapstructUtils.convert(bo, MessageWarn.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改设备告警记录 + * + * @param bo 设备告警记录 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(MessageWarnBo bo) { + MessageWarn update = MapstructUtils.convert(bo, MessageWarn.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(MessageWarn entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除设备告警记录信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } +} diff --git a/intc-modules/intc-fishery/src/main/resources/mapper/fishery/CallNoticeMapper.xml b/intc-modules/intc-fishery/src/main/resources/mapper/fishery/CallNoticeMapper.xml new file mode 100644 index 0000000..eef36c2 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/resources/mapper/fishery/CallNoticeMapper.xml @@ -0,0 +1,6 @@ + + + + diff --git a/intc-modules/intc-fishery/src/main/resources/mapper/fishery/MapMessageWarnCallNoticeMapper.xml b/intc-modules/intc-fishery/src/main/resources/mapper/fishery/MapMessageWarnCallNoticeMapper.xml new file mode 100644 index 0000000..c2633e3 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/resources/mapper/fishery/MapMessageWarnCallNoticeMapper.xml @@ -0,0 +1,6 @@ + + + + diff --git a/intc-modules/intc-fishery/src/main/resources/mapper/fishery/MessageWarnMapper.xml b/intc-modules/intc-fishery/src/main/resources/mapper/fishery/MessageWarnMapper.xml new file mode 100644 index 0000000..72a4907 --- /dev/null +++ b/intc-modules/intc-fishery/src/main/resources/mapper/fishery/MessageWarnMapper.xml @@ -0,0 +1,6 @@ + + + + diff --git a/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/controller/DeviceSensorDataController.java b/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/controller/DeviceSensorDataController.java new file mode 100644 index 0000000..2c4d377 --- /dev/null +++ b/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/controller/DeviceSensorDataController.java @@ -0,0 +1,34 @@ +package com.intc.tdengine.controller; + + +import com.intc.common.web.core.BaseController; +import com.intc.tdengine.domain.DeviceSensorData; +import com.intc.tdengine.service.IDeviceSensorDataService; +import jakarta.annotation.Resource; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * TDEngines设备数据信息Controller + * + * @author Tianyongbao + * @date 2025-10-27 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/td/device") +public class DeviceSensorDataController extends BaseController +{ + @Resource + private IDeviceSensorDataService deviceSensorDataService; + + @GetMapping("/getHistoryData") + public List getHistoryData(@RequestParam("serialNum") String serialNum, @RequestParam("deviceId") Long deviceId, @RequestParam("mobilePhone") String mobilePhone, @RequestParam("deviceType") int deviceType, @RequestParam("startTime") String startTime, @RequestParam("endTime") String endTime) + { + return deviceSensorDataService.getHistoryDataList(serialNum,deviceId,mobilePhone,deviceType,startTime,endTime); + } +} diff --git a/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/domain/DeviceSensorData.java b/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/domain/DeviceSensorData.java new file mode 100644 index 0000000..c6d36d1 --- /dev/null +++ b/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/domain/DeviceSensorData.java @@ -0,0 +1,33 @@ +package com.intc.tdengine.domain; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import java.time.LocalDateTime; +@Data +@NoArgsConstructor // 生成无参构造方法 +@AllArgsConstructor // 生成全参构造方法 +public class DeviceSensorData { + + // 测量字段(随时间变化的数值) + private LocalDateTime time; // 时序主键时间戳 + private LocalDateTime createTime; // 数据创建时间 + private double dissolvedOxygen; // 溶解氧 + private double temperature; // 温度 + private double saturability; // 饱和度 + private double ph; // pH值 + private double salinity; // 盐度 + private double treference; // 参考值(具体含义需结合业务) + private double tfluorescence; // 荧光值 + private double phaseDifference; // 相位差 + private double battery; // 电池电量 + + // 标签字段(元数据,不随时间频繁变化) + private String serialNum; // 设备序列号 + private long deviceId; // 设备ID(对应TDengine的BIGINT) + private long userId; // 用户ID(对应TDengine的BIGINT) + private String userName; // 用户名 + private String mobilePhone; // 手机号 + private String deviceName; // 设备名称 + private int deviceType; // 设备类型 +} diff --git a/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/mapper/DeviceSensorDataMapper.java b/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/mapper/DeviceSensorDataMapper.java new file mode 100644 index 0000000..7efe2d3 --- /dev/null +++ b/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/mapper/DeviceSensorDataMapper.java @@ -0,0 +1,58 @@ +package com.intc.tdengine.mapper; + +import com.intc.tdengine.domain.DeviceSensorData; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +@Mapper +public interface DeviceSensorDataMapper { + + /** + * 删除数据库 + * + * @return 结果 + */ + void dropDB(); + + /** + * 创建数据库 + * + * @return 结果 + */ + void createDB(); + + /** + * 创建超级表 + * + * @return 结果 + */ + void createSuperTable(); + + /** + * 创建子表 + * + * @param deviceSensorData 数据信息 + * @return 结果 + */ + void createTable(DeviceSensorData deviceSensorData); + + /** + * 批量插入数据 + * + * @param dataList 数据列表 + * @return 影响行数 + */ + int batchInsertDeviceSensorData(@Param("dataList") List dataList); + + /** + * 查询数据 + * + * @return 影响行数 + */ + List getHistoryDataList(@Param("serialNum") String serialNum,@Param("deviceId") Long deviceId,@Param("mobilePhone") String mobilePhone,@Param("deviceType") int deviceType,@Param("startTime") String startTime,@Param("endTime") String endTime); + +} diff --git a/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/service/IDeviceSensorDataService.java b/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/service/IDeviceSensorDataService.java new file mode 100644 index 0000000..26dde71 --- /dev/null +++ b/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/service/IDeviceSensorDataService.java @@ -0,0 +1,37 @@ +package com.intc.tdengine.service; + +import com.intc.tdengine.domain.DeviceSensorData; +import org.springframework.scheduling.annotation.Async; + +import java.util.List; + +/** + * @author YaphetS + */ +public interface IDeviceSensorDataService { + + + /** + * 创建子表 + * + * @param deviceSensorData 数据信息 + * @return 结果 + */ + void createTable(DeviceSensorData deviceSensorData); + + /** + * 批量插入数据 + * + * @param dataList 数据列表 + * @return 影响行数 + */ + @Async + public void batchInsertDeviceSensorData(List dataList); + + /** + * 查询数据 + * + * @return 影响行数 + */ + public List getHistoryDataList(String serialNum, Long deviceId, String mobilePhone, int deviceType, String startTime, String endTime); +} diff --git a/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/service/impl/DeviceSensorDataService.java b/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/service/impl/DeviceSensorDataService.java new file mode 100644 index 0000000..819de7f --- /dev/null +++ b/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/service/impl/DeviceSensorDataService.java @@ -0,0 +1,54 @@ +package com.intc.tdengine.service.impl; + +import com.intc.tdengine.domain.DeviceSensorData; +import com.intc.tdengine.mapper.DeviceSensorDataMapper; +import com.intc.tdengine.service.IDeviceSensorDataService; +import jakarta.annotation.Resource; +import org.apache.ibatis.annotations.Param; + +import java.util.ArrayList; +import java.util.List; + +public class DeviceSensorDataService implements IDeviceSensorDataService { + @Resource + private DeviceSensorDataMapper deviceSensorDataMapper; + + + /** + * 创建子表 + * + * @param deviceSensorData 数据信息 + * @return 结果 + */ + @Override + public void createTable(DeviceSensorData deviceSensorData) { + deviceSensorDataMapper.createTable(deviceSensorData); + } + + /** + * 批量插入数据 + * + * @param dataList 数据列表 + * @return 影响行数 + */ + @Override + public void batchInsertDeviceSensorData(List dataList) { + deviceSensorDataMapper.batchInsertDeviceSensorData(dataList); + } + + /** + * 查询数据 + * + * @return 影响行数 + */ + @Override + public List getHistoryDataList(String serialNum,Long deviceId, String mobilePhone, int deviceType,String startTime, String endTime) { + List list=new ArrayList<>(); + try { + list=deviceSensorDataMapper.getHistoryDataList(serialNum,deviceId,mobilePhone,deviceType,startTime,endTime); + }catch (Exception e){ + + } + return list; + } +} diff --git a/intc-modules/intc-tdengine/src/main/resources/mapper/tdengine/DeviceSensorDataMapper.xml b/intc-modules/intc-tdengine/src/main/resources/mapper/tdengine/DeviceSensorDataMapper.xml new file mode 100644 index 0000000..908ed59 --- /dev/null +++ b/intc-modules/intc-tdengine/src/main/resources/mapper/tdengine/DeviceSensorDataMapper.xml @@ -0,0 +1,65 @@ + + + + + + + + + drop database if exists fishery + + + + create database if not exists fishery + + + + create table if not exists + fishery.device_sensor_data(time timestamp,createTime timestamp, dissolvedOxygen double, temperature double , saturability double , ph double , salinity double , treference double , tfluorescence double , phaseDifference double , battery double) + tags( + tenant_id nchar(50), + serialNum nchar(100), + deviceId BIGINT, + userId BIGINT, + userName nchar(100), + mobilePhone nchar(20), + deviceName nchar(100), + deviceType int + ) + + + + + create table if not exists + + `fishery`.t_#{serialNum} + + using fishery.device_sensor_data + + tags(#{tenantId},#{serialNum},#{deviceId},#{userId},#{userName},#{mobilePhone},#{deviceName},#{deviceType}) + + + + insert into + + `fishery`.t_#{serialNum} + + using fishery.device_sensor_data + + tags(#{data.tenantId},#{data.serialNum},#{data.deviceId},#{data.userId},#{data.userName},#{data.mobilePhone},#{data.deviceName},#{data.deviceType}) + + (time, createTime, dissolvedOxygen, temperature, saturability, ph, salinity, treference, tfluorescence, phaseDifference, battery) values (#{data.time}, ${data.createTime}, ${data.dissolvedOxygen}, ${data.temperature}, ${data.saturability}, ${data.ph}, ${data.salinity}, ${data.treference}, ${data.tfluorescence}, ${data.phaseDifference}, ${data.battery}) + + + + + From 05fb82274405bfb535b4d7984b3ed75eeb7093dc Mon Sep 17 00:00:00 2001 From: tianyongbao Date: Wed, 5 Nov 2025 00:35:23 +0800 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20=E6=96=B0=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=BC=80=E5=8F=91=EF=BC=8C=E7=9B=91=E6=B5=8B=E5=8E=86=E5=8F=B2?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E3=80=82=E5=BE=AE=E4=BF=A1=E5=92=8C=E7=89=A9?= =?UTF-8?q?=E8=81=94=E7=BD=91=E5=B9=B3=E5=8F=B0=EF=BC=8C=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E6=90=AD=E5=BB=BA=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- intc-admin/pom.xml | 5 + .../src/main/resources/application-dev.yml | 22 +- intc-modules/intc-iot/pom.xml | 91 ++++++++ .../iot/config/AliyunIotConfiguration.java | 41 ++++ .../intc/iot/config/AliyunIotProperties.java | 100 +++++++++ .../intc/iot/config/MqttConfiguration.java | 49 ++++ .../intc/iot/controller/IotController.java | 212 ++++++++++++++++++ .../java/com/intc/iot/domain/IotDevice.java | 69 ++++++ .../intc/iot/handler/DeviceDataHandler.java | 134 +++++++++++ .../intc/iot/service/DeviceDataService.java | 42 ++++ .../intc/iot/service/IotDeviceService.java | 70 ++++++ .../com/intc/iot/service/MqttService.java | 37 +++ .../service/impl/DeviceDataServiceImpl.java | 85 +++++++ .../service/impl/IotDeviceServiceImpl.java | 125 +++++++++++ .../iot/service/impl/MqttServiceImpl.java | 87 +++++++ .../src/main/resources/application.yml | 36 +++ intc-modules/intc-tdengine/pom.xml | 5 - .../DeviceSensorDataController.java | 7 +- .../tdengine/domain/DeviceSensorData.java | 73 +++++- .../mapper/DeviceSensorDataMapper.java | 18 +- .../service/IDeviceSensorDataService.java | 10 +- .../service/impl/DeviceSensorDataService.java | 72 +++++- .../tdengine/DeviceSensorDataMapper.xml | 61 ++++- intc-modules/intc-weixin/pom.xml | 88 ++++++++ .../intc/weixin/config/WxMaConfiguration.java | 37 +++ .../intc/weixin/config/WxMaProperties.java | 42 ++++ .../intc/weixin/config/WxMpConfiguration.java | 36 +++ .../intc/weixin/config/WxMpProperties.java | 37 +++ .../weixin/config/WxPayConfiguration.java | 39 ++++ .../intc/weixin/config/WxPayProperties.java | 52 +++++ .../weixin/controller/WeixinController.java | 109 +++++++++ .../java/com/intc/weixin/domain/WxUser.java | 74 ++++++ .../com/intc/weixin/service/WxMaService.java | 31 +++ .../com/intc/weixin/service/WxMpService.java | 31 +++ .../weixin/service/impl/WxMaServiceImpl.java | 38 ++++ .../weixin/service/impl/WxMpServiceImpl.java | 39 ++++ .../src/main/resources/application.yml | 42 ++++ intc-modules/pom.xml | 2 + 38 files changed, 2099 insertions(+), 49 deletions(-) create mode 100644 intc-modules/intc-iot/pom.xml create mode 100644 intc-modules/intc-iot/src/main/java/com/intc/iot/config/AliyunIotConfiguration.java create mode 100644 intc-modules/intc-iot/src/main/java/com/intc/iot/config/AliyunIotProperties.java create mode 100644 intc-modules/intc-iot/src/main/java/com/intc/iot/config/MqttConfiguration.java create mode 100644 intc-modules/intc-iot/src/main/java/com/intc/iot/controller/IotController.java create mode 100644 intc-modules/intc-iot/src/main/java/com/intc/iot/domain/IotDevice.java create mode 100644 intc-modules/intc-iot/src/main/java/com/intc/iot/handler/DeviceDataHandler.java create mode 100644 intc-modules/intc-iot/src/main/java/com/intc/iot/service/DeviceDataService.java create mode 100644 intc-modules/intc-iot/src/main/java/com/intc/iot/service/IotDeviceService.java create mode 100644 intc-modules/intc-iot/src/main/java/com/intc/iot/service/MqttService.java create mode 100644 intc-modules/intc-iot/src/main/java/com/intc/iot/service/impl/DeviceDataServiceImpl.java create mode 100644 intc-modules/intc-iot/src/main/java/com/intc/iot/service/impl/IotDeviceServiceImpl.java create mode 100644 intc-modules/intc-iot/src/main/java/com/intc/iot/service/impl/MqttServiceImpl.java create mode 100644 intc-modules/intc-iot/src/main/resources/application.yml create mode 100644 intc-modules/intc-weixin/pom.xml create mode 100644 intc-modules/intc-weixin/src/main/java/com/intc/weixin/config/WxMaConfiguration.java create mode 100644 intc-modules/intc-weixin/src/main/java/com/intc/weixin/config/WxMaProperties.java create mode 100644 intc-modules/intc-weixin/src/main/java/com/intc/weixin/config/WxMpConfiguration.java create mode 100644 intc-modules/intc-weixin/src/main/java/com/intc/weixin/config/WxMpProperties.java create mode 100644 intc-modules/intc-weixin/src/main/java/com/intc/weixin/config/WxPayConfiguration.java create mode 100644 intc-modules/intc-weixin/src/main/java/com/intc/weixin/config/WxPayProperties.java create mode 100644 intc-modules/intc-weixin/src/main/java/com/intc/weixin/controller/WeixinController.java create mode 100644 intc-modules/intc-weixin/src/main/java/com/intc/weixin/domain/WxUser.java create mode 100644 intc-modules/intc-weixin/src/main/java/com/intc/weixin/service/WxMaService.java create mode 100644 intc-modules/intc-weixin/src/main/java/com/intc/weixin/service/WxMpService.java create mode 100644 intc-modules/intc-weixin/src/main/java/com/intc/weixin/service/impl/WxMaServiceImpl.java create mode 100644 intc-modules/intc-weixin/src/main/java/com/intc/weixin/service/impl/WxMpServiceImpl.java create mode 100644 intc-modules/intc-weixin/src/main/resources/application.yml diff --git a/intc-admin/pom.xml b/intc-admin/pom.xml index 99e51cd..54c3ee2 100644 --- a/intc-admin/pom.xml +++ b/intc-admin/pom.xml @@ -22,6 +22,11 @@ com.mysql mysql-connector-j + + com.taosdata.jdbc + taos-jdbcdriver + 2.0.38 + diff --git a/intc-admin/src/main/resources/application-dev.yml b/intc-admin/src/main/resources/application-dev.yml index 4620112..643a963 100644 --- a/intc-admin/src/main/resources/application-dev.yml +++ b/intc-admin/src/main/resources/application-dev.yml @@ -54,14 +54,20 @@ spring: url: jdbc:postgresql://154.8.147.51:15432/fishery_dev?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true username: postgres password: intc@123987 -# # 从库数据源 -# slave: -# lazy: true -# type: ${spring.datasource.type} -# driverClassName: com.taosdata.jdbc.rs.RestfulDriver -# url: jdbc:TAOS-RS://117.72.197.29:6041/log?timezone=Shanghai&charset=UTF-8&locale=en_US.UTF-8 -# username: root -# password: taosdata + # 从库数据源 - TDengine + taos: + lazy: false + type: ${spring.datasource.type} + driverClassName: com.taosdata.jdbc.rs.RestfulDriver + # 不指定数据库名,在 SQL 中使用完整路径 fishery.table_name + url: jdbc:TAOS-RS://154.8.147.51:6041?timezone=Shanghai&charset=UTF-8&locale=en_US.UTF-8 + username: root + password: intc@123456 + hikari: + connection-timeout: 60000 + validation-timeout: 10000 + max-pool-size: 5 + min-idle: 2 # oracle: # type: ${spring.datasource.type} # driverClassName: oracle.jdbc.OracleDriver diff --git a/intc-modules/intc-iot/pom.xml b/intc-modules/intc-iot/pom.xml new file mode 100644 index 0000000..5f33d62 --- /dev/null +++ b/intc-modules/intc-iot/pom.xml @@ -0,0 +1,91 @@ + + + + com.intc + intc-modules + ${revision} + + 4.0.0 + + intc-iot + + + 阿里云生活物联网平台(飞燕平台)对接模块 + + + + + + + com.aliyun + aliyun-java-sdk-core + 4.6.4 + + + + + com.aliyun + aliyun-java-sdk-iot + 7.46.0 + + + + + org.eclipse.paho + org.eclipse.paho.client.mqttv3 + 1.2.5 + + + + + com.squareup.okhttp3 + okhttp + 4.12.0 + + + + + com.intc + intc-common-core + + + + com.intc + intc-common-doc + + + + com.intc + intc-common-redis + + + + com.intc + intc-common-mybatis + + + + com.intc + intc-common-log + + + + com.intc + intc-common-security + + + + com.intc + intc-common-web + + + + com.intc + intc-common-tenant + + + + + diff --git a/intc-modules/intc-iot/src/main/java/com/intc/iot/config/AliyunIotConfiguration.java b/intc-modules/intc-iot/src/main/java/com/intc/iot/config/AliyunIotConfiguration.java new file mode 100644 index 0000000..a8af4d3 --- /dev/null +++ b/intc-modules/intc-iot/src/main/java/com/intc/iot/config/AliyunIotConfiguration.java @@ -0,0 +1,41 @@ +package com.intc.iot.config; + +import com.aliyuncs.DefaultAcsClient; +import com.aliyuncs.IAcsClient; +import com.aliyuncs.profile.DefaultProfile; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 阿里云生活物联网平台(飞燕平台)配置 + * + * @author intc + */ +@Slf4j +@Configuration +@RequiredArgsConstructor +@ConditionalOnProperty(prefix = "aliyun.living-iot", name = "access-key-id") +public class AliyunIotConfiguration { + + private final AliyunIotProperties iotProperties; + + /** + * 创建阿里云飞燕平台客户端 + */ + @Bean + public IAcsClient livingIotClient() { + DefaultProfile profile = DefaultProfile.getProfile( + iotProperties.getRegionId(), + iotProperties.getAccessKeyId(), + iotProperties.getAccessKeySecret() + ); + + IAcsClient client = new DefaultAcsClient(profile); + log.info("阿里云生活物联网平台客户端初始化成功,RegionId: {}", iotProperties.getRegionId()); + return client; + } + +} diff --git a/intc-modules/intc-iot/src/main/java/com/intc/iot/config/AliyunIotProperties.java b/intc-modules/intc-iot/src/main/java/com/intc/iot/config/AliyunIotProperties.java new file mode 100644 index 0000000..475a573 --- /dev/null +++ b/intc-modules/intc-iot/src/main/java/com/intc/iot/config/AliyunIotProperties.java @@ -0,0 +1,100 @@ +package com.intc.iot.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * 阿里云生活物联网平台(飞燕平台)配置属性 + * + * @author intc + */ +@Data +@Component +@ConfigurationProperties(prefix = "aliyun.living-iot") +public class AliyunIotProperties { + + /** + * 阿里云AccessKey ID + */ + private String accessKeyId; + + /** + * 阿里云AccessKey Secret + */ + private String accessKeySecret; + + /** + * 地域节点(如:cn-shanghai) + */ + private String regionId; + + /** + * 飞燕平台项目ID(Project ID) + */ + private String projectId; + + /** + * App Key + */ + private String appKey; + + /** + * App Secret + */ + private String appSecret; + + /** + * 品类Key + */ + private String categoryKey; + + /** + * MQTT 配置 + */ + private MqttConfig mqtt = new MqttConfig(); + + @Data + public static class MqttConfig { + /** + * MQTT Broker 地址 + */ + private String brokerUrl; + + /** + * 客户端ID + */ + private String clientId; + + /** + * 用户名 + */ + private String username; + + /** + * 密码 + */ + private String password; + + /** + * 连接超时时间(秒) + */ + private Integer connectionTimeout = 30; + + /** + * 保活时间(秒) + */ + private Integer keepAliveInterval = 60; + + /** + * 自动重连 + */ + private Boolean autoReconnect = true; + + /** + * 清除会话 + */ + private Boolean cleanSession = true; + } + +} diff --git a/intc-modules/intc-iot/src/main/java/com/intc/iot/config/MqttConfiguration.java b/intc-modules/intc-iot/src/main/java/com/intc/iot/config/MqttConfiguration.java new file mode 100644 index 0000000..e768c07 --- /dev/null +++ b/intc-modules/intc-iot/src/main/java/com/intc/iot/config/MqttConfiguration.java @@ -0,0 +1,49 @@ +package com.intc.iot.config; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttConnectOptions; +import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * MQTT 客户端配置 + * + * @author intc + */ +@Slf4j +@Configuration +@RequiredArgsConstructor +@ConditionalOnProperty(prefix = "aliyun.living-iot.mqtt", name = "broker-url") +public class MqttConfiguration { + + private final AliyunIotProperties iotProperties; + + /** + * 创建 MQTT 客户端 + */ + @Bean + public MqttClient mqttClient() throws Exception { + AliyunIotProperties.MqttConfig mqtt = iotProperties.getMqtt(); + + MemoryPersistence persistence = new MemoryPersistence(); + MqttClient client = new MqttClient(mqtt.getBrokerUrl(), mqtt.getClientId(), persistence); + + MqttConnectOptions options = new MqttConnectOptions(); + options.setUserName(mqtt.getUsername()); + options.setPassword(mqtt.getPassword().toCharArray()); + options.setConnectionTimeout(mqtt.getConnectionTimeout()); + options.setKeepAliveInterval(mqtt.getKeepAliveInterval()); + options.setAutomaticReconnect(mqtt.getAutoReconnect()); + options.setCleanSession(mqtt.getCleanSession()); + + client.connect(options); + log.info("MQTT 客户端连接成功,Broker: {}", mqtt.getBrokerUrl()); + + return client; + } + +} diff --git a/intc-modules/intc-iot/src/main/java/com/intc/iot/controller/IotController.java b/intc-modules/intc-iot/src/main/java/com/intc/iot/controller/IotController.java new file mode 100644 index 0000000..ef79aac --- /dev/null +++ b/intc-modules/intc-iot/src/main/java/com/intc/iot/controller/IotController.java @@ -0,0 +1,212 @@ +package com.intc.iot.controller; + +import com.intc.common.core.domain.R; +import com.intc.common.web.core.BaseController; +import com.intc.iot.service.DeviceDataService; +import com.intc.iot.service.IotDeviceService; +import com.intc.iot.service.MqttService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + +/** + * 阿里云生活物联网平台(飞燕平台)控制器 + * + * @author intc + */ +@Slf4j +@RequiredArgsConstructor +@RestController +@RequestMapping("/iot") +@Tag(name = "生活物联网平台管理", description = "阿里云飞燕平台对接接口") +public class IotController extends BaseController { + + @Autowired(required = false) + private IotDeviceService iotDeviceService; + + @Autowired(required = false) + private MqttService mqttService; + + @Autowired(required = false) + private DeviceDataService deviceDataService; + + @Operation(summary = "测试接口") + @GetMapping("/test") + public R test() { + return R.ok("飞燕平台模块测试成功!"); + } + + @Operation(summary = "查询设备列表") + @GetMapping("/device/list") + public R> queryDeviceList( + @Parameter(description = "页码") @RequestParam(defaultValue = "1") Integer pageNo, + @Parameter(description = "每页大小") @RequestParam(defaultValue = "20") Integer pageSize) { + try { + if (iotDeviceService == null) { + return R.fail("飞燕平台配置未启用"); + } + Map response = iotDeviceService.queryDeviceList(pageNo, pageSize); + return R.ok(response); + } catch (Exception e) { + log.error("查询设备列表失败", e); + return R.fail("查询设备列表失败: " + e.getMessage()); + } + } + + @Operation(summary = "查询设备详情") + @GetMapping("/device/info") + public R> queryDeviceInfo( + @Parameter(description = "设备ID") @RequestParam String iotId) { + try { + if (iotDeviceService == null) { + return R.fail("飞燕平台配置未启用"); + } + Map response = iotDeviceService.queryDeviceInfo(iotId); + return R.ok(response); + } catch (Exception e) { + log.error("查询设备详情失败", e); + return R.fail("查询设备详情失败: " + e.getMessage()); + } + } + + @Operation(summary = "查询设备属性") + @GetMapping("/device/properties") + public R> queryDeviceProperties( + @Parameter(description = "设备ID") @RequestParam String iotId) { + try { + if (iotDeviceService == null) { + return R.fail("飞燕平台配置未启用"); + } + Map response = iotDeviceService.queryDeviceProperties(iotId); + return R.ok(response); + } catch (Exception e) { + log.error("查询设备属性失败", e); + return R.fail("查询设备属性失败: " + e.getMessage()); + } + } + + @Operation(summary = "设置设备属性") + @PostMapping("/device/property/set") + public R> setDeviceProperty( + @Parameter(description = "设备ID") @RequestParam String iotId, + @Parameter(description = "属性JSON") @RequestParam String properties) { + try { + if (iotDeviceService == null) { + return R.fail("飞燕平台配置未启用"); + } + Map response = iotDeviceService.setDeviceProperty(iotId, properties); + return R.ok(response); + } catch (Exception e) { + log.error("设置设备属性失败", e); + return R.fail("设置设备属性失败: " + e.getMessage()); + } + } + + @Operation(summary = "调用设备服务") + @PostMapping("/device/invoke") + public R> invokeService( + @Parameter(description = "设备ID") @RequestParam String iotId, + @Parameter(description = "服务标识符") @RequestParam String identifier, + @Parameter(description = "参数JSON") @RequestParam String args) { + try { + if (iotDeviceService == null) { + return R.fail("飞燕平台配置未启用"); + } + Map response = iotDeviceService.invokeService(iotId, identifier, args); + return R.ok(response); + } catch (Exception e) { + log.error("调用设备服务失败", e); + return R.fail("调用设备服务失败: " + e.getMessage()); + } + } + + @Operation(summary = "解绑设备") + @DeleteMapping("/device/unbind") + public R> unbindDevice( + @Parameter(description = "设备ID") @RequestParam String iotId) { + try { + if (iotDeviceService == null) { + return R.fail("飞燕平台配置未启用"); + } + Map response = iotDeviceService.unbindDevice(iotId); + return R.ok(response); + } catch (Exception e) { + log.error("解绑设备失败", e); + return R.fail("解绑设备失败: " + e.getMessage()); + } + } + + @Operation(summary = "发布MQTT消息") + @PostMapping("/mqtt/publish") + public R publishMqtt( + @Parameter(description = "主题") @RequestParam String topic, + @Parameter(description = "消息内容") @RequestParam String payload, + @Parameter(description = "QoS等级") @RequestParam(defaultValue = "1") int qos) { + try { + if (mqttService == null) { + return R.fail("MQTT配置未启用"); + } + mqttService.publish(topic, payload, qos); + return R.ok("消息发布成功"); + } catch (Exception e) { + log.error("发布MQTT消息失败", e); + return R.fail("发布MQTT消息失败: " + e.getMessage()); + } + } + + @Operation(summary = "订阅MQTT主题") + @PostMapping("/mqtt/subscribe") + public R subscribeMqtt( + @Parameter(description = "主题") @RequestParam String topic, + @Parameter(description = "QoS等级") @RequestParam(defaultValue = "1") int qos) { + try { + if (mqttService == null) { + return R.fail("MQTT配置未启用"); + } + mqttService.subscribe(topic, qos); + return R.ok("订阅成功"); + } catch (Exception e) { + log.error("订阅MQTT主题失败", e); + return R.fail("订阅MQTT主题失败: " + e.getMessage()); + } + } + + @Operation(summary = "取消订阅MQTT主题") + @PostMapping("/mqtt/unsubscribe") + public R unsubscribeMqtt( + @Parameter(description = "主题") @RequestParam String topic) { + try { + if (mqttService == null) { + return R.fail("MQTT配置未启用"); + } + mqttService.unsubscribe(topic); + return R.ok("取消订阅成功"); + } catch (Exception e) { + log.error("取消订阅MQTT主题失败", e); + return R.fail("取消订阅MQTT主题失败: " + e.getMessage()); + } + } + + @Operation(summary = "订阅设备实时数据(按产品)") + @PostMapping("/device/data/subscribe") + public R subscribeDeviceData( + @Parameter(description = "产品Key") @RequestParam String productKey) { + try { + if (deviceDataService == null) { + return R.fail("设备数据服务未启用"); + } + deviceDataService.subscribeAllDevices(productKey); + return R.ok("订阅成功,设备数据将实时推送"); + } catch (Exception e) { + log.error("订阅设备数据失败", e); + return R.fail("订阅设备数据失败: " + e.getMessage()); + } + } + +} diff --git a/intc-modules/intc-iot/src/main/java/com/intc/iot/domain/IotDevice.java b/intc-modules/intc-iot/src/main/java/com/intc/iot/domain/IotDevice.java new file mode 100644 index 0000000..231b7b3 --- /dev/null +++ b/intc-modules/intc-iot/src/main/java/com/intc/iot/domain/IotDevice.java @@ -0,0 +1,69 @@ +package com.intc.iot.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 物联网设备信息 + * + * @author intc + */ +@Data +@TableName("iot_device") +public class IotDevice implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @TableId + private Long id; + + /** + * 设备名称 + */ + private String deviceName; + + /** + * 产品Key + */ + private String productKey; + + /** + * 设备密钥 + */ + private String deviceSecret; + + /** + * 设备状态:0-未激活 1-在线 2-离线 3-已禁用 + */ + private Integer status; + + /** + * 设备备注 + */ + private String remark; + + /** + * 最后上线时间 + */ + private LocalDateTime lastOnlineTime; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + +} diff --git a/intc-modules/intc-iot/src/main/java/com/intc/iot/handler/DeviceDataHandler.java b/intc-modules/intc-iot/src/main/java/com/intc/iot/handler/DeviceDataHandler.java new file mode 100644 index 0000000..f70d590 --- /dev/null +++ b/intc-modules/intc-iot/src/main/java/com/intc/iot/handler/DeviceDataHandler.java @@ -0,0 +1,134 @@ +package com.intc.iot.handler; + +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 设备数据处理器 + * + * @author intc + */ +@Slf4j +@Component +public class DeviceDataHandler { + + /** + * 处理设备属性上报数据 + * + * @param topic 主题 + * @param payload 消息内容 + */ + public void handlePropertyPost(String topic, String payload) { + log.info("收到设备属性上报,Topic: {}", topic); + + try { + JSONObject data = JSONUtil.parseObj(payload); + + // 解析飞燕平台消息格式 + String method = data.getStr("method"); + String id = data.getStr("id"); + JSONObject params = data.getJSONObject("params"); + + log.info("设备属性数据 - Method: {}, ID: {}, Params: {}", method, id, params); + + // TODO: 这里添加您的业务逻辑 + // 1. 存储到数据库 + // 2. 触发告警 + // 3. 推送到前端(通过 WebSocket/SSE) + // 4. 数据分析处理 + + if (params != null) { + params.forEach((key, value) -> { + log.info("属性: {} = {}", key, value); + // 根据不同属性进行不同处理 + handleProperty(key, value); + }); + } + + } catch (Exception e) { + log.error("处理设备属性数据失败", e); + } + } + + /** + * 处理设备事件上报数据 + * + * @param topic 主题 + * @param payload 消息内容 + */ + public void handleEventPost(String topic, String payload) { + log.info("收到设备事件上报,Topic: {}", topic); + + try { + JSONObject data = JSONUtil.parseObj(payload); + + String method = data.getStr("method"); + String id = data.getStr("id"); + JSONObject params = data.getJSONObject("params"); + + log.info("设备事件数据 - Method: {}, ID: {}, Params: {}", method, id, params); + + // TODO: 处理设备事件 + // 例如:故障告警、状态变化等 + + } catch (Exception e) { + log.error("处理设备事件数据失败", e); + } + } + + /** + * 处理单个属性 + * + * @param propertyName 属性名称 + * @param propertyValue 属性值 + */ + private void handleProperty(String propertyName, Object propertyValue) { + // 根据属性名称进行不同的业务处理 + switch (propertyName) { + case "temperature": + handleTemperature(propertyValue); + break; + case "humidity": + handleHumidity(propertyValue); + break; + case "status": + handleStatus(propertyValue); + break; + default: + log.debug("未处理的属性: {} = {}", propertyName, propertyValue); + } + } + + /** + * 处理温度数据 + */ + private void handleTemperature(Object value) { + // 示例:温度告警 + if (value instanceof Number) { + double temp = ((Number) value).doubleValue(); + if (temp > 80) { + log.warn("温度过高告警: {}°C", temp); + // TODO: 发送告警通知 + } + } + } + + /** + * 处理湿度数据 + */ + private void handleHumidity(Object value) { + // 示例:湿度处理逻辑 + log.debug("湿度数据: {}", value); + } + + /** + * 处理状态数据 + */ + private void handleStatus(Object value) { + // 示例:设备状态变化 + log.info("设备状态变化: {}", value); + } + +} diff --git a/intc-modules/intc-iot/src/main/java/com/intc/iot/service/DeviceDataService.java b/intc-modules/intc-iot/src/main/java/com/intc/iot/service/DeviceDataService.java new file mode 100644 index 0000000..ec975c5 --- /dev/null +++ b/intc-modules/intc-iot/src/main/java/com/intc/iot/service/DeviceDataService.java @@ -0,0 +1,42 @@ +package com.intc.iot.service; + +/** + * 设备数据服务接口 + * + * @author intc + */ +public interface DeviceDataService { + + /** + * 订阅设备属性上报 + * + * @param iotId 设备ID + * @throws Exception 异常 + */ + void subscribeDeviceProperties(String iotId) throws Exception; + + /** + * 订阅设备事件上报 + * + * @param iotId 设备ID + * @throws Exception 异常 + */ + void subscribeDeviceEvents(String iotId) throws Exception; + + /** + * 订阅所有设备数据 + * + * @param productKey 产品Key + * @throws Exception 异常 + */ + void subscribeAllDevices(String productKey) throws Exception; + + /** + * 取消订阅设备数据 + * + * @param iotId 设备ID + * @throws Exception 异常 + */ + void unsubscribeDevice(String iotId) throws Exception; + +} diff --git a/intc-modules/intc-iot/src/main/java/com/intc/iot/service/IotDeviceService.java b/intc-modules/intc-iot/src/main/java/com/intc/iot/service/IotDeviceService.java new file mode 100644 index 0000000..3dd8aea --- /dev/null +++ b/intc-modules/intc-iot/src/main/java/com/intc/iot/service/IotDeviceService.java @@ -0,0 +1,70 @@ +package com.intc.iot.service; + +import java.util.Map; + +/** + * 阿里云生活物联网平台(飞燕平台)设备管理服务 + * + * @author intc + */ +public interface IotDeviceService { + + /** + * 查询设备列表 + * + * @param pageNo 页码 + * @param pageSize 每页大小 + * @return 设备列表 + * @throws Exception 异常 + */ + Map queryDeviceList(Integer pageNo, Integer pageSize) throws Exception; + + /** + * 查询设备详情 + * + * @param iotId 设备ID + * @return 设备详情 + * @throws Exception 异常 + */ + Map queryDeviceInfo(String iotId) throws Exception; + + /** + * 查询设备属性 + * + * @param iotId 设备ID + * @return 设备属性 + * @throws Exception 异常 + */ + Map queryDeviceProperties(String iotId) throws Exception; + + /** + * 设置设备属性 + * + * @param iotId 设备ID + * @param properties 属性JSON + * @return 设置结果 + * @throws Exception 异常 + */ + Map setDeviceProperty(String iotId, String properties) throws Exception; + + /** + * 调用设备服务 + * + * @param iotId 设备ID + * @param identifier 服务标识符 + * @param args 参数 + * @return 调用结果 + * @throws Exception 异常 + */ + Map invokeService(String iotId, String identifier, String args) throws Exception; + + /** + * 解绑设备 + * + * @param iotId 设备ID + * @return 解绑结果 + * @throws Exception 异常 + */ + Map unbindDevice(String iotId) throws Exception; + +} diff --git a/intc-modules/intc-iot/src/main/java/com/intc/iot/service/MqttService.java b/intc-modules/intc-iot/src/main/java/com/intc/iot/service/MqttService.java new file mode 100644 index 0000000..8b48a9b --- /dev/null +++ b/intc-modules/intc-iot/src/main/java/com/intc/iot/service/MqttService.java @@ -0,0 +1,37 @@ +package com.intc.iot.service; + +/** + * MQTT 消息服务 + * + * @author intc + */ +public interface MqttService { + + /** + * 发布消息 + * + * @param topic 主题 + * @param payload 消息内容 + * @param qos 服务质量等级(0/1/2) + * @throws Exception 异常 + */ + void publish(String topic, String payload, int qos) throws Exception; + + /** + * 订阅主题 + * + * @param topic 主题 + * @param qos 服务质量等级(0/1/2) + * @throws Exception 异常 + */ + void subscribe(String topic, int qos) throws Exception; + + /** + * 取消订阅 + * + * @param topic 主题 + * @throws Exception 异常 + */ + void unsubscribe(String topic) throws Exception; + +} diff --git a/intc-modules/intc-iot/src/main/java/com/intc/iot/service/impl/DeviceDataServiceImpl.java b/intc-modules/intc-iot/src/main/java/com/intc/iot/service/impl/DeviceDataServiceImpl.java new file mode 100644 index 0000000..3deaaeb --- /dev/null +++ b/intc-modules/intc-iot/src/main/java/com/intc/iot/service/impl/DeviceDataServiceImpl.java @@ -0,0 +1,85 @@ +package com.intc.iot.service.impl; + +import cn.hutool.json.JSONUtil; +import com.intc.iot.service.DeviceDataService; +import com.intc.iot.service.MqttService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.stereotype.Service; + +/** + * 设备数据服务实现 + * + * @author intc + */ +@Slf4j +@Service +@RequiredArgsConstructor +@ConditionalOnBean(MqttClient.class) +public class DeviceDataServiceImpl implements DeviceDataService { + + private final MqttService mqttService; + + /** + * 飞燕平台设备属性上报 Topic 格式 + * /sys/{productKey}/{deviceName}/thing/event/property/post + */ + private static final String PROPERTY_POST_TOPIC = "/sys/%s/%s/thing/event/property/post"; + + /** + * 飞燕平台设备事件上报 Topic 格式 + * /sys/{productKey}/{deviceName}/thing/event/{eventIdentifier}/post + */ + private static final String EVENT_POST_TOPIC = "/sys/%s/%s/thing/event/+/post"; + + /** + * 所有设备属性上报 Topic(使用通配符) + * /sys/{productKey}/+/thing/event/property/post + */ + private static final String ALL_DEVICES_PROPERTY_TOPIC = "/sys/%s/+/thing/event/property/post"; + + @Override + public void subscribeDeviceProperties(String iotId) throws Exception { + // 注意:需要根据 iotId 获取 productKey 和 deviceName + // 这里简化处理,实际应该从数据库或缓存中查询 + log.info("订阅设备属性上报,IotId: {}", iotId); + + // 示例:假设从设备信息中获取 + // String productKey = getProductKeyByIotId(iotId); + // String deviceName = getDeviceNameByIotId(iotId); + // String topic = String.format(PROPERTY_POST_TOPIC, productKey, deviceName); + + // mqttService.subscribe(topic, 1); + + log.warn("请先实现 iotId 到 productKey/deviceName 的映射逻辑"); + } + + @Override + public void subscribeDeviceEvents(String iotId) throws Exception { + log.info("订阅设备事件上报,IotId: {}", iotId); + + // 类似属性订阅,需要映射关系 + log.warn("请先实现 iotId 到 productKey/deviceName 的映射逻辑"); + } + + @Override + public void subscribeAllDevices(String productKey) throws Exception { + log.info("订阅产品下所有设备属性上报,ProductKey: {}", productKey); + + String topic = String.format(ALL_DEVICES_PROPERTY_TOPIC, productKey); + mqttService.subscribe(topic, 1); + + log.info("成功订阅 Topic: {}", topic); + } + + @Override + public void unsubscribeDevice(String iotId) throws Exception { + log.info("取消订阅设备数据,IotId: {}", iotId); + + // 需要取消对应的 Topic 订阅 + log.warn("请先实现 iotId 到 productKey/deviceName 的映射逻辑"); + } + +} diff --git a/intc-modules/intc-iot/src/main/java/com/intc/iot/service/impl/IotDeviceServiceImpl.java b/intc-modules/intc-iot/src/main/java/com/intc/iot/service/impl/IotDeviceServiceImpl.java new file mode 100644 index 0000000..7e194d7 --- /dev/null +++ b/intc-modules/intc-iot/src/main/java/com/intc/iot/service/impl/IotDeviceServiceImpl.java @@ -0,0 +1,125 @@ +package com.intc.iot.service.impl; + +import com.aliyuncs.IAcsClient; +import com.aliyuncs.iot.model.v20180120.*; +import com.intc.iot.config.AliyunIotProperties; +import com.intc.iot.service.IotDeviceService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.Map; + +/** + * 阿里云生活物联网平台(飞燕平台)设备管理服务实现 + * + * @author intc + */ +@Slf4j +@Service +@RequiredArgsConstructor +@ConditionalOnBean(IAcsClient.class) +public class IotDeviceServiceImpl implements IotDeviceService { + + private final IAcsClient acsClient; + private final AliyunIotProperties iotProperties; + + @Override + public Map queryDeviceList(Integer pageNo, Integer pageSize) throws Exception { + log.info("查询设备列表,页码: {}, 每页大小: {}", pageNo, pageSize); + + QueryDeviceRequest request = new QueryDeviceRequest(); + request.setCurrentPage(pageNo); + request.setPageSize(pageSize); + + QueryDeviceResponse response = acsClient.getAcsResponse(request); + + Map result = new HashMap<>(); + result.put("success", response.getSuccess()); + result.put("data", response.getData()); + result.put("total", response.getTotal()); + return result; + } + + @Override + public Map queryDeviceInfo(String iotId) throws Exception { + log.info("查询设备详情,IotId: {}", iotId); + + QueryDeviceDetailRequest request = new QueryDeviceDetailRequest(); + request.setIotId(iotId); + + QueryDeviceDetailResponse response = acsClient.getAcsResponse(request); + + Map result = new HashMap<>(); + result.put("success", response.getSuccess()); + result.put("data", response.getData()); + return result; + } + + @Override + public Map queryDeviceProperties(String iotId) throws Exception { + log.info("查询设备属性,IotId: {}", iotId); + + QueryDevicePropertyStatusRequest request = new QueryDevicePropertyStatusRequest(); + request.setIotId(iotId); + + QueryDevicePropertyStatusResponse response = acsClient.getAcsResponse(request); + + Map result = new HashMap<>(); + result.put("success", response.getSuccess()); + result.put("data", response.getData()); + return result; + } + + @Override + public Map setDeviceProperty(String iotId, String properties) throws Exception { + log.info("设置设备属性,IotId: {}, Properties: {}", iotId, properties); + + SetDevicePropertyRequest request = new SetDevicePropertyRequest(); + request.setIotId(iotId); + request.setItems(properties); + + SetDevicePropertyResponse response = acsClient.getAcsResponse(request); + + Map result = new HashMap<>(); + result.put("success", response.getSuccess()); + result.put("data", response.getData()); + return result; + } + + @Override + public Map invokeService(String iotId, String identifier, String args) throws Exception { + log.info("调用设备服务,IotId: {}, Identifier: {}", iotId, identifier); + + InvokeThingServiceRequest request = new InvokeThingServiceRequest(); + request.setIotId(iotId); + request.setIdentifier(identifier); + request.setArgs(args); + + InvokeThingServiceResponse response = acsClient.getAcsResponse(request); + + Map result = new HashMap<>(); + result.put("success", response.getSuccess()); + result.put("data", response.getData()); + return result; + } + + @Override + public Map unbindDevice(String iotId) throws Exception { + log.info("解绑设备,IotId: {}", iotId); + + // 注: 通用IoT SDK没有直接的解绑接口,这里使用删除设备 + DeleteDeviceRequest request = new DeleteDeviceRequest(); + request.setIotId(iotId); + + DeleteDeviceResponse response = acsClient.getAcsResponse(request); + + Map result = new HashMap<>(); + result.put("success", response.getSuccess()); + result.put("errorMessage", response.getErrorMessage()); + return result; + } + +} diff --git a/intc-modules/intc-iot/src/main/java/com/intc/iot/service/impl/MqttServiceImpl.java b/intc-modules/intc-iot/src/main/java/com/intc/iot/service/impl/MqttServiceImpl.java new file mode 100644 index 0000000..0896639 --- /dev/null +++ b/intc-modules/intc-iot/src/main/java/com/intc/iot/service/impl/MqttServiceImpl.java @@ -0,0 +1,87 @@ +package com.intc.iot.service.impl; + +import com.intc.iot.handler.DeviceDataHandler; +import com.intc.iot.service.MqttService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.paho.client.mqttv3.IMqttMessageListener; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.stereotype.Service; + +/** + * MQTT 消息服务实现 + * + * @author intc + */ +@Slf4j +@Service +@RequiredArgsConstructor +@ConditionalOnBean(MqttClient.class) +public class MqttServiceImpl implements MqttService { + + private final MqttClient mqttClient; + + @Autowired(required = false) + private DeviceDataHandler deviceDataHandler; + + @Override + public void publish(String topic, String payload, int qos) throws Exception { + if (!mqttClient.isConnected()) { + log.warn("MQTT 客户端未连接,尝试重连..."); + mqttClient.reconnect(); + } + + MqttMessage message = new MqttMessage(payload.getBytes()); + message.setQos(qos); + message.setRetained(false); + + mqttClient.publish(topic, message); + log.info("MQTT 消息发布成功,Topic: {}, Payload: {}", topic, payload); + } + + @Override + public void subscribe(String topic, int qos) throws Exception { + if (!mqttClient.isConnected()) { + log.warn("MQTT 客户端未连接,尝试重连..."); + mqttClient.reconnect(); + } + + mqttClient.subscribe(topic, qos, new IMqttMessageListener() { + @Override + public void messageArrived(String topic, MqttMessage message) throws Exception { + String payload = new String(message.getPayload()); + log.info("收到 MQTT 消息,Topic: {}, Payload: {}", topic, payload); + + // 根据 Topic 类型分发处理 + if (deviceDataHandler != null) { + if (topic.contains("/thing/event/property/post")) { + // 设备属性上报 + deviceDataHandler.handlePropertyPost(topic, payload); + } else if (topic.contains("/thing/event/") && topic.endsWith("/post")) { + // 设备事件上报 + deviceDataHandler.handleEventPost(topic, payload); + } else { + log.debug("未匹配的 Topic 类型: {}", topic); + } + } + } + }); + + log.info("MQTT 主题订阅成功,Topic: {}", topic); + } + + @Override + public void unsubscribe(String topic) throws Exception { + if (!mqttClient.isConnected()) { + log.warn("MQTT 客户端未连接"); + return; + } + + mqttClient.unsubscribe(topic); + log.info("MQTT 主题取消订阅成功,Topic: {}", topic); + } + +} diff --git a/intc-modules/intc-iot/src/main/resources/application.yml b/intc-modules/intc-iot/src/main/resources/application.yml new file mode 100644 index 0000000..f81482f --- /dev/null +++ b/intc-modules/intc-iot/src/main/resources/application.yml @@ -0,0 +1,36 @@ +# 阿里云生活物联网平台(飞燕平台)配置 +aliyun: + living-iot: + # 阿里云 AccessKey ID(必填) + access-key-id: LTAI5txxxxxxxxxxxxxxxxxx + # 阿里云 AccessKey Secret(必填) + access-key-secret: your_access_key_secret_here_32_chars + # 地域节点(必填,如:cn-shanghai) + region-id: cn-shanghai + # 飞燕平台项目ID(Project ID,必填) + project-id: a1xxxxxx + # App Key(必填) + app-key: your_app_key_here + # App Secret(必填) + app-secret: your_app_secret_here_32_characters + # 品类Key(选填) + category-key: + + # MQTT 配置(可选) + mqtt: + # MQTT Broker 地址(格式:ssl://实例ID.iot-as-mqtt.cn-shanghai.aliyuncs.com:1883) + broker-url: ssl://a1xxxxxx.iot-as-mqtt.cn-shanghai.aliyuncs.com:1883 + # 客户端ID(格式:{ClientID}|securemode=2,signmethod=hmacsha1|) + client-id: your_client_id|securemode=2,signmethod=hmacsha1| + # 用户名(设备名称&产品Key) + username: DeviceName&ProductKey + # 密码(通过MQTT密码工具生成) + password: your_mqtt_password_here + # 连接超时时间(秒) + connection-timeout: 30 + # 保活时间(秒) + keep-alive-interval: 60 + # 自动重连 + auto-reconnect: true + # 清除会话 + clean-session: true diff --git a/intc-modules/intc-tdengine/pom.xml b/intc-modules/intc-tdengine/pom.xml index b48b6d7..b8b4fe1 100644 --- a/intc-modules/intc-tdengine/pom.xml +++ b/intc-modules/intc-tdengine/pom.xml @@ -102,11 +102,6 @@ com.intc intc-common-websocket - - com.taosdata.jdbc - taos-jdbcdriver - 2.0.40 - diff --git a/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/controller/DeviceSensorDataController.java b/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/controller/DeviceSensorDataController.java index 2c4d377..20c3639 100644 --- a/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/controller/DeviceSensorDataController.java +++ b/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/controller/DeviceSensorDataController.java @@ -27,8 +27,11 @@ public class DeviceSensorDataController extends BaseController private IDeviceSensorDataService deviceSensorDataService; @GetMapping("/getHistoryData") - public List getHistoryData(@RequestParam("serialNum") String serialNum, @RequestParam("deviceId") Long deviceId, @RequestParam("mobilePhone") String mobilePhone, @RequestParam("deviceType") int deviceType, @RequestParam("startTime") String startTime, @RequestParam("endTime") String endTime) + public List getHistoryData(@RequestParam("serialNum") String serialNum, + @RequestParam("startTime") String startTime, + @RequestParam("endTime") String endTime, + @RequestParam(value = "intervalType", required = false, defaultValue = "1") Integer intervalType) { - return deviceSensorDataService.getHistoryDataList(serialNum,deviceId,mobilePhone,deviceType,startTime,endTime); + return deviceSensorDataService.getHistoryDataList(serialNum, startTime, endTime, intervalType); } } diff --git a/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/domain/DeviceSensorData.java b/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/domain/DeviceSensorData.java index c6d36d1..3a7bd16 100644 --- a/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/domain/DeviceSensorData.java +++ b/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/domain/DeviceSensorData.java @@ -1,8 +1,12 @@ package com.intc.tdengine.domain; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import java.math.BigDecimal; +import java.math.RoundingMode; import java.time.LocalDateTime; @Data @NoArgsConstructor // 生成无参构造方法 @@ -10,17 +14,64 @@ import java.time.LocalDateTime; public class DeviceSensorData { // 测量字段(随时间变化的数值) - private LocalDateTime time; // 时序主键时间戳 - private LocalDateTime createTime; // 数据创建时间 - private double dissolvedOxygen; // 溶解氧 - private double temperature; // 温度 - private double saturability; // 饱和度 - private double ph; // pH值 - private double salinity; // 盐度 - private double treference; // 参考值(具体含义需结合业务) - private double tfluorescence; // 荧光值 - private double phaseDifference; // 相位差 - private double battery; // 电池电量 + private String time; // 时序主键时间戳 + private String createTime; // 数据创建时间 + private Double dissolvedOxygen; // 溶解氧 + private Double temperature; // 温度 + private Double saturability; // 饱和度 + private Double ph; // pH值 + private Double salinity; // 盐度 + private Double treference; // 参考值(具体含义需结合业务) + private Double tfluorescence; // 荧光值 + private Double phaseDifference; // 相位差 + private Double battery; // 电池电量 + + // Getter 方法,返回保留两位小数的值 + public Double getDissolvedOxygen() { + return roundToTwoDecimals(dissolvedOxygen); + } + + public Double getTemperature() { + return roundToTwoDecimals(temperature); + } + + public Double getSaturability() { + return roundToTwoDecimals(saturability); + } + + public Double getPh() { + return roundToTwoDecimals(ph); + } + + public Double getSalinity() { + return roundToTwoDecimals(salinity); + } + + public Double getTreference() { + return roundToTwoDecimals(treference); + } + + public Double getTfluorescence() { + return roundToTwoDecimals(tfluorescence); + } + + public Double getPhaseDifference() { + return roundToTwoDecimals(phaseDifference); + } + + public Double getBattery() { + return roundToTwoDecimals(battery); + } + + // 工具方法:保留两位小数 + private Double roundToTwoDecimals(Double value) { + if (value == null) { + return null; + } + return BigDecimal.valueOf(value) + .setScale(2, RoundingMode.HALF_UP) + .doubleValue(); + } // 标签字段(元数据,不随时间频繁变化) private String serialNum; // 设备序列号 diff --git a/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/mapper/DeviceSensorDataMapper.java b/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/mapper/DeviceSensorDataMapper.java index 7efe2d3..794c476 100644 --- a/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/mapper/DeviceSensorDataMapper.java +++ b/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/mapper/DeviceSensorDataMapper.java @@ -1,5 +1,7 @@ package com.intc.tdengine.mapper; +import com.baomidou.dynamic.datasource.annotation.DS; +import com.baomidou.mybatisplus.annotation.InterceptorIgnore; import com.intc.tdengine.domain.DeviceSensorData; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -8,7 +10,6 @@ import org.springframework.stereotype.Repository; import java.util.List; @Repository -@Mapper public interface DeviceSensorDataMapper { /** @@ -46,13 +47,24 @@ public interface DeviceSensorDataMapper { * @param dataList 数据列表 * @return 影响行数 */ + @DS("taos") + @InterceptorIgnore(tenantLine = "true") int batchInsertDeviceSensorData(@Param("dataList") List dataList); /** * 查询数据 * - * @return 影响行数 + * @param serialNum 设备序列号 + * @param startTime 开始时间 + * @param endTime 结束时间 + * @param intervalType 间隔类型:1-原始数据,2-10分钟,3-30分钟,4-1小时,5-3小时,6-6小时 + * @return 设备传感器数据列表 */ - List getHistoryDataList(@Param("serialNum") String serialNum,@Param("deviceId") Long deviceId,@Param("mobilePhone") String mobilePhone,@Param("deviceType") int deviceType,@Param("startTime") String startTime,@Param("endTime") String endTime); + @DS("taos") + @InterceptorIgnore(tenantLine = "true") + List getHistoryDataList(@Param("serialNum") String serialNum, + @Param("startTime") String startTime, + @Param("endTime") String endTime, + @Param("intervalType") Integer intervalType); } diff --git a/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/service/IDeviceSensorDataService.java b/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/service/IDeviceSensorDataService.java index 26dde71..18976c9 100644 --- a/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/service/IDeviceSensorDataService.java +++ b/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/service/IDeviceSensorDataService.java @@ -29,9 +29,13 @@ public interface IDeviceSensorDataService { public void batchInsertDeviceSensorData(List dataList); /** - * 查询数据 + * 查询历史数据列表 * - * @return 影响行数 + * @param serialNum 设备序列号 + * @param startTime 开始时间 + * @param endTime 结束时间 + * @param intervalType 间隔类型:1-原始数据,2-10分钟,3-30分钟,4-1小时,5-3小时,6-6小时 + * @return 设备传感器数据列表 */ - public List getHistoryDataList(String serialNum, Long deviceId, String mobilePhone, int deviceType, String startTime, String endTime); + public List getHistoryDataList(String serialNum, String startTime, String endTime, Integer intervalType); } diff --git a/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/service/impl/DeviceSensorDataService.java b/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/service/impl/DeviceSensorDataService.java index 819de7f..bc62753 100644 --- a/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/service/impl/DeviceSensorDataService.java +++ b/intc-modules/intc-tdengine/src/main/java/com/intc/tdengine/service/impl/DeviceSensorDataService.java @@ -1,14 +1,19 @@ package com.intc.tdengine.service.impl; +import com.baomidou.dynamic.datasource.annotation.DS; import com.intc.tdengine.domain.DeviceSensorData; import com.intc.tdengine.mapper.DeviceSensorDataMapper; import com.intc.tdengine.service.IDeviceSensorDataService; import jakarta.annotation.Resource; -import org.apache.ibatis.annotations.Param; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; +@Slf4j +@Service +@DS("taos") // 指定使用 taos 数据源(TDengine) public class DeviceSensorDataService implements IDeviceSensorDataService { @Resource private DeviceSensorDataMapper deviceSensorDataMapper; @@ -37,18 +42,69 @@ public class DeviceSensorDataService implements IDeviceSensorDataService { } /** - * 查询数据 + * 查询历史数据列表 * - * @return 影响行数 + * @param serialNum 设备序列号 + * @param startTime 开始时间 + * @param endTime 结束时间 + * @param intervalType 间隔类型:1-原始数据,2-10分钟,3-30分钟,4-1小时,5-3小时,6-6小时 + * @return 设备传感器数据列表 */ @Override - public List getHistoryDataList(String serialNum,Long deviceId, String mobilePhone, int deviceType,String startTime, String endTime) { - List list=new ArrayList<>(); + public List getHistoryDataList(String serialNum, String startTime, String endTime, Integer intervalType) { + List list = new ArrayList<>(); try { - list=deviceSensorDataMapper.getHistoryDataList(serialNum,deviceId,mobilePhone,deviceType,startTime,endTime); - }catch (Exception e){ - + // 默认为原始数据 + if (intervalType == null) { + intervalType = 1; + } + + // 验证intervalType参数 + if (intervalType < 1 || intervalType > 6) { + log.error("无效的intervalType参数: {}, 使用默认值1", intervalType); + intervalType = 1; + } + + // 处理时间格式 + if (startTime != null && !startTime.contains(" ")) { + startTime = startTime + " 00:00:00"; + } + if (endTime != null && !endTime.contains(" ")) { + endTime = endTime + " 23:59:59"; + } + + String intervalDesc = getIntervalDesc(intervalType); + log.info("查询TDengine历史数据: serialNum={}, startTime={}, endTime={}, intervalType={} ({})", + serialNum, startTime, endTime, intervalType, intervalDesc); + + list = deviceSensorDataMapper.getHistoryDataList(serialNum, startTime, endTime, intervalType); + + log.info("查询到 {} 条历史数据 ({})", list.size(), intervalDesc); + } catch (Exception e) { + log.error("查询TDengine历史数据失败", e); + // 打印完整异常链 + Throwable cause = e; + int level = 0; + while (cause != null && level < 10) { + log.error("异常层级 {}: {}", level++, cause.getClass().getName() + ": " + cause.getMessage()); + cause = cause.getCause(); + } } return list; } + + /** + * 获取间隔类型描述 + */ + private String getIntervalDesc(Integer intervalType) { + switch (intervalType) { + case 1: return "原始数据"; + case 2: return "10分钟间隔"; + case 3: return "30分钟间隔"; + case 4: return "1小时间隔"; + case 5: return "3小时间隔"; + case 6: return "6小时间隔"; + default: return "未知"; + } + } } diff --git a/intc-modules/intc-tdengine/src/main/resources/mapper/tdengine/DeviceSensorDataMapper.xml b/intc-modules/intc-tdengine/src/main/resources/mapper/tdengine/DeviceSensorDataMapper.xml index 908ed59..518988c 100644 --- a/intc-modules/intc-tdengine/src/main/resources/mapper/tdengine/DeviceSensorDataMapper.xml +++ b/intc-modules/intc-tdengine/src/main/resources/mapper/tdengine/DeviceSensorDataMapper.xml @@ -52,14 +52,57 @@ - + + + SELECT + `time`, + createTime, + dissolvedOxygen, + temperature, + saturability, + ph, + salinity, + treference, + tfluorescence, + phaseDifference, + battery, + serialNum, + deviceId, + mobilePhone, + deviceType + FROM `fishery`.`t_${serialNum}` + + AND `time` >= #{startTime} + AND `time` <= #{endTime} + + + + + SELECT + _wstart as `time`, + _wstart as createTime, + AVG(dissolvedOxygen) as dissolvedOxygen, + AVG(temperature) as temperature, + AVG(saturability) as saturability, + AVG(ph) as ph, + AVG(salinity) as salinity, + AVG(treference) as treference, + AVG(tfluorescence) as tfluorescence, + AVG(phaseDifference) as phaseDifference, + AVG(battery) as battery + FROM `fishery`.`t_${serialNum}` + + AND `time` >= #{startTime} + AND `time` <= #{endTime} + + + INTERVAL(10m) + INTERVAL(30m) + INTERVAL(1h) + INTERVAL(3h) + INTERVAL(6h) + + diff --git a/intc-modules/intc-weixin/pom.xml b/intc-modules/intc-weixin/pom.xml new file mode 100644 index 0000000..90241a7 --- /dev/null +++ b/intc-modules/intc-weixin/pom.xml @@ -0,0 +1,88 @@ + + + + com.intc + intc-modules + ${revision} + + 4.0.0 + + intc-weixin + + + 微信对接模块 + + + + + + + com.github.binarywang + weixin-java-mp + 4.6.0 + + + + com.github.binarywang + weixin-java-miniapp + 4.6.0 + + + + com.github.binarywang + weixin-java-pay + 4.6.0 + + + + com.github.binarywang + weixin-java-open + 4.6.0 + + + + + com.intc + intc-common-core + + + + com.intc + intc-common-doc + + + + com.intc + intc-common-redis + + + + com.intc + intc-common-mybatis + + + + com.intc + intc-common-log + + + + com.intc + intc-common-security + + + + com.intc + intc-common-web + + + + com.intc + intc-common-tenant + + + + + diff --git a/intc-modules/intc-weixin/src/main/java/com/intc/weixin/config/WxMaConfiguration.java b/intc-modules/intc-weixin/src/main/java/com/intc/weixin/config/WxMaConfiguration.java new file mode 100644 index 0000000..3235874 --- /dev/null +++ b/intc-modules/intc-weixin/src/main/java/com/intc/weixin/config/WxMaConfiguration.java @@ -0,0 +1,37 @@ +package com.intc.weixin.config; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; +import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl; +import lombok.RequiredArgsConstructor; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 微信小程序配置 + * + * @author intc + */ +@Configuration +@RequiredArgsConstructor +@ConditionalOnProperty(prefix = "wx.miniapp", name = "app-id") +public class WxMaConfiguration { + + private final WxMaProperties wxMaProperties; + + @Bean + public WxMaService wxMaService() { + WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl(); + config.setAppid(wxMaProperties.getAppId()); + config.setSecret(wxMaProperties.getSecret()); + config.setToken(wxMaProperties.getToken()); + config.setAesKey(wxMaProperties.getAesKey()); + config.setMsgDataFormat(wxMaProperties.getMsgDataFormat()); + + WxMaService service = new WxMaServiceImpl(); + service.setWxMaConfig(config); + return service; + } + +} diff --git a/intc-modules/intc-weixin/src/main/java/com/intc/weixin/config/WxMaProperties.java b/intc-modules/intc-weixin/src/main/java/com/intc/weixin/config/WxMaProperties.java new file mode 100644 index 0000000..3e77490 --- /dev/null +++ b/intc-modules/intc-weixin/src/main/java/com/intc/weixin/config/WxMaProperties.java @@ -0,0 +1,42 @@ +package com.intc.weixin.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * 微信小程序配置属性 + * + * @author intc + */ +@Data +@Component +@ConfigurationProperties(prefix = "wx.miniapp") +public class WxMaProperties { + + /** + * 小程序appId + */ + private String appId; + + /** + * 小程序Secret + */ + private String secret; + + /** + * 小程序token + */ + private String token; + + /** + * 小程序EncodingAESKey + */ + private String aesKey; + + /** + * 消息格式,XML或者JSON + */ + private String msgDataFormat; + +} diff --git a/intc-modules/intc-weixin/src/main/java/com/intc/weixin/config/WxMpConfiguration.java b/intc-modules/intc-weixin/src/main/java/com/intc/weixin/config/WxMpConfiguration.java new file mode 100644 index 0000000..d9ca385 --- /dev/null +++ b/intc-modules/intc-weixin/src/main/java/com/intc/weixin/config/WxMpConfiguration.java @@ -0,0 +1,36 @@ +package com.intc.weixin.config; + +import lombok.RequiredArgsConstructor; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; +import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 微信公众号配置 + * + * @author intc + */ +@Configuration +@RequiredArgsConstructor +@ConditionalOnProperty(prefix = "wx.mp", name = "app-id") +public class WxMpConfiguration { + + private final WxMpProperties wxMpProperties; + + @Bean + public WxMpService wxMpService() { + WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl(); + config.setAppId(wxMpProperties.getAppId()); + config.setSecret(wxMpProperties.getSecret()); + config.setToken(wxMpProperties.getToken()); + config.setAesKey(wxMpProperties.getAesKey()); + + WxMpService service = new WxMpServiceImpl(); + service.setWxMpConfigStorage(config); + return service; + } + +} diff --git a/intc-modules/intc-weixin/src/main/java/com/intc/weixin/config/WxMpProperties.java b/intc-modules/intc-weixin/src/main/java/com/intc/weixin/config/WxMpProperties.java new file mode 100644 index 0000000..8fda6dc --- /dev/null +++ b/intc-modules/intc-weixin/src/main/java/com/intc/weixin/config/WxMpProperties.java @@ -0,0 +1,37 @@ +package com.intc.weixin.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * 微信公众号配置属性 + * + * @author intc + */ +@Data +@Component +@ConfigurationProperties(prefix = "wx.mp") +public class WxMpProperties { + + /** + * 公众号appId + */ + private String appId; + + /** + * 公众号Secret + */ + private String secret; + + /** + * 公众号token + */ + private String token; + + /** + * 公众号EncodingAESKey + */ + private String aesKey; + +} diff --git a/intc-modules/intc-weixin/src/main/java/com/intc/weixin/config/WxPayConfiguration.java b/intc-modules/intc-weixin/src/main/java/com/intc/weixin/config/WxPayConfiguration.java new file mode 100644 index 0000000..60f11b3 --- /dev/null +++ b/intc-modules/intc-weixin/src/main/java/com/intc/weixin/config/WxPayConfiguration.java @@ -0,0 +1,39 @@ +package com.intc.weixin.config; + +import com.github.binarywang.wxpay.config.WxPayConfig; +import com.github.binarywang.wxpay.service.WxPayService; +import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; +import lombok.RequiredArgsConstructor; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 微信支付配置 + * + * @author intc + */ +@Configuration +@RequiredArgsConstructor +@ConditionalOnProperty(prefix = "wx.pay", name = "mch-id") +public class WxPayConfiguration { + + private final WxPayProperties wxPayProperties; + + @Bean + public WxPayService wxPayService() { + WxPayConfig config = new WxPayConfig(); + config.setMchId(wxPayProperties.getMchId()); + config.setMchKey(wxPayProperties.getMchKey()); + config.setKeyPath(wxPayProperties.getKeyPath()); + config.setApiV3Key(wxPayProperties.getApiV3Key()); + config.setCertSerialNo(wxPayProperties.getCertSerialNo()); + config.setPrivateKeyPath(wxPayProperties.getPrivateKeyPath()); + config.setPrivateCertPath(wxPayProperties.getPrivateContent()); + + WxPayService service = new WxPayServiceImpl(); + service.setConfig(config); + return service; + } + +} diff --git a/intc-modules/intc-weixin/src/main/java/com/intc/weixin/config/WxPayProperties.java b/intc-modules/intc-weixin/src/main/java/com/intc/weixin/config/WxPayProperties.java new file mode 100644 index 0000000..37a911f --- /dev/null +++ b/intc-modules/intc-weixin/src/main/java/com/intc/weixin/config/WxPayProperties.java @@ -0,0 +1,52 @@ +package com.intc.weixin.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * 微信支付配置属性 + * + * @author intc + */ +@Data +@Component +@ConfigurationProperties(prefix = "wx.pay") +public class WxPayProperties { + + /** + * 商户号 + */ + private String mchId; + + /** + * 商户密钥 + */ + private String mchKey; + + /** + * apiclient_cert.p12文件的绝对路径或者以classpath:开头的类路径 + */ + private String keyPath; + + /** + * apiV3秘钥 + */ + private String apiV3Key; + + /** + * 证书序列号 + */ + private String certSerialNo; + + /** + * 私钥路径 + */ + private String privateKeyPath; + + /** + * 私钥内容 + */ + private String privateContent; + +} diff --git a/intc-modules/intc-weixin/src/main/java/com/intc/weixin/controller/WeixinController.java b/intc-modules/intc-weixin/src/main/java/com/intc/weixin/controller/WeixinController.java new file mode 100644 index 0000000..9764751 --- /dev/null +++ b/intc-modules/intc-weixin/src/main/java/com/intc/weixin/controller/WeixinController.java @@ -0,0 +1,109 @@ +package com.intc.weixin.controller; + +import com.intc.common.core.domain.R; +import com.intc.common.web.core.BaseController; +import com.intc.weixin.service.WxMaService; +import com.intc.weixin.service.WxMpService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.bean.result.WxMpUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.Optional; + +/** + * 微信对接控制器 + * + * @author intc + */ +@Slf4j +@RequiredArgsConstructor +@RestController +@RequestMapping("/weixin") +@Tag(name = "微信对接管理", description = "微信对接相关接口") +public class WeixinController extends BaseController { + + @Autowired(required = false) + private WxMpService wxMpService; + + @Autowired(required = false) + private WxMaService wxMaService; + + @Operation(summary = "测试接口") + @GetMapping("/test") + public R test() { + return R.ok("微信模块测试成功!"); + } + + @Operation(summary = "获取公众号用户信息") + @GetMapping("/mp/user/{openId}") + public R getMpUserInfo( + @Parameter(description = "用户openId") @PathVariable String openId) { + try { + if (wxMpService == null) { + return R.fail("公众号配置未启用"); + } + WxMpUser userInfo = wxMpService.getUserInfo(openId); + return R.ok(userInfo); + } catch (WxErrorException e) { + log.error("获取用户信息失败", e); + return R.fail("获取用户信息失败: " + e.getMessage()); + } + } + + @Operation(summary = "生成公众号二维码") + @GetMapping("/mp/qrcode") + public R createMpQrCode( + @Parameter(description = "场景值") @RequestParam String scene) { + try { + if (wxMpService == null) { + return R.fail("公众号配置未启用"); + } + String qrCodeUrl = wxMpService.createQrCode(scene); + return R.ok(qrCodeUrl); + } catch (WxErrorException e) { + log.error("生成二维码失败", e); + return R.fail("生成二维码失败: " + e.getMessage()); + } + } + + @Operation(summary = "小程序登录") + @GetMapping("/ma/login") + public R maLogin( + @Parameter(description = "登录code") @RequestParam String code) { + try { + if (wxMaService == null) { + return R.fail("小程序配置未启用"); + } + String openId = wxMaService.code2Session(code); + return R.ok(openId); + } catch (WxErrorException e) { + log.error("小程序登录失败", e); + return R.fail("小程序登录失败: " + e.getMessage()); + } + } + + @Operation(summary = "生成小程序码") + @GetMapping("/ma/qrcode") + public R createMaQrCode( + @Parameter(description = "场景值") @RequestParam String scene, + @Parameter(description = "页面路径") @RequestParam(required = false) String page) { + try { + if (wxMaService == null) { + return R.fail("小程序配置未启用"); + } + byte[] qrCodeBytes = wxMaService.getUnlimitedQrCode(scene, page); + // 这里可以将字节数组上传到OSS或者直接返回给前端 + return R.ok("二维码生成成功,大小: " + qrCodeBytes.length + " bytes"); + } catch (WxErrorException e) { + log.error("生成小程序码失败", e); + return R.fail("生成小程序码失败: " + e.getMessage()); + } + } + +} diff --git a/intc-modules/intc-weixin/src/main/java/com/intc/weixin/domain/WxUser.java b/intc-modules/intc-weixin/src/main/java/com/intc/weixin/domain/WxUser.java new file mode 100644 index 0000000..c45083a --- /dev/null +++ b/intc-modules/intc-weixin/src/main/java/com/intc/weixin/domain/WxUser.java @@ -0,0 +1,74 @@ +package com.intc.weixin.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 微信用户信息 + * + * @author intc + */ +@Data +@TableName("wx_user") +public class WxUser implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @TableId + private Long id; + + /** + * 微信openId + */ + private String openId; + + /** + * 微信unionId + */ + private String unionId; + + /** + * 昵称 + */ + private String nickname; + + /** + * 头像 + */ + private String avatar; + + /** + * 性别 0-未知 1-男 2-女 + */ + private Integer gender; + + /** + * 手机号 + */ + private String mobile; + + /** + * 来源类型:mp-公众号 ma-小程序 + */ + private String sourceType; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + +} diff --git a/intc-modules/intc-weixin/src/main/java/com/intc/weixin/service/WxMaService.java b/intc-modules/intc-weixin/src/main/java/com/intc/weixin/service/WxMaService.java new file mode 100644 index 0000000..8497a30 --- /dev/null +++ b/intc-modules/intc-weixin/src/main/java/com/intc/weixin/service/WxMaService.java @@ -0,0 +1,31 @@ +package com.intc.weixin.service; + +import me.chanjar.weixin.common.error.WxErrorException; + +/** + * 微信小程序服务接口 + * + * @author intc + */ +public interface WxMaService { + + /** + * 登录凭证校验 + * + * @param code 登录时获取的 code + * @return sessionKey和openId + * @throws WxErrorException 微信异常 + */ + String code2Session(String code) throws WxErrorException; + + /** + * 获取小程序码 + * + * @param scene 场景值 + * @param page 页面路径 + * @return 二进制图片数据 + * @throws WxErrorException 微信异常 + */ + byte[] getUnlimitedQrCode(String scene, String page) throws WxErrorException; + +} diff --git a/intc-modules/intc-weixin/src/main/java/com/intc/weixin/service/WxMpService.java b/intc-modules/intc-weixin/src/main/java/com/intc/weixin/service/WxMpService.java new file mode 100644 index 0000000..f66544a --- /dev/null +++ b/intc-modules/intc-weixin/src/main/java/com/intc/weixin/service/WxMpService.java @@ -0,0 +1,31 @@ +package com.intc.weixin.service; + +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.bean.result.WxMpUser; + +/** + * 微信公众号服务接口 + * + * @author intc + */ +public interface WxMpService { + + /** + * 获取用户信息 + * + * @param openId 用户openId + * @return 用户信息 + * @throws WxErrorException 微信异常 + */ + WxMpUser getUserInfo(String openId) throws WxErrorException; + + /** + * 生成二维码ticket + * + * @param sceneStr 场景值 + * @return ticket + * @throws WxErrorException 微信异常 + */ + String createQrCode(String sceneStr) throws WxErrorException; + +} diff --git a/intc-modules/intc-weixin/src/main/java/com/intc/weixin/service/impl/WxMaServiceImpl.java b/intc-modules/intc-weixin/src/main/java/com/intc/weixin/service/impl/WxMaServiceImpl.java new file mode 100644 index 0000000..1c27246 --- /dev/null +++ b/intc-modules/intc-weixin/src/main/java/com/intc/weixin/service/impl/WxMaServiceImpl.java @@ -0,0 +1,38 @@ +package com.intc.weixin.service.impl; + +import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; +import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; +import com.intc.weixin.service.WxMaService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.error.WxErrorException; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.stereotype.Service; + +/** + * 微信小程序服务实现 + * + * @author intc + */ +@Slf4j +@Service +@RequiredArgsConstructor +@ConditionalOnBean(cn.binarywang.wx.miniapp.api.WxMaService.class) +public class WxMaServiceImpl implements WxMaService { + + private final cn.binarywang.wx.miniapp.api.WxMaService wxMaService; + + @Override + public String code2Session(String code) throws WxErrorException { + log.info("小程序登录, code: {}", code); + WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(code); + return session.getOpenid(); + } + + @Override + public byte[] getUnlimitedQrCode(String scene, String page) throws WxErrorException { + log.info("生成小程序码, scene: {}, page: {}", scene, page); + return wxMaService.getQrcodeService().createWxaCodeUnlimitBytes(scene, page, false, null, 430, true, null, false); + } + +} diff --git a/intc-modules/intc-weixin/src/main/java/com/intc/weixin/service/impl/WxMpServiceImpl.java b/intc-modules/intc-weixin/src/main/java/com/intc/weixin/service/impl/WxMpServiceImpl.java new file mode 100644 index 0000000..739bfad --- /dev/null +++ b/intc-modules/intc-weixin/src/main/java/com/intc/weixin/service/impl/WxMpServiceImpl.java @@ -0,0 +1,39 @@ +package com.intc.weixin.service.impl; + +import com.intc.weixin.service.WxMpService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; +import me.chanjar.weixin.mp.bean.result.WxMpUser; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.stereotype.Service; + +/** + * 微信公众号服务实现 + * + * @author intc + */ +@Slf4j +@Service +@RequiredArgsConstructor +@ConditionalOnBean(me.chanjar.weixin.mp.api.WxMpService.class) +public class WxMpServiceImpl implements WxMpService { + + private final me.chanjar.weixin.mp.api.WxMpService wxMpService; + + @Override + public WxMpUser getUserInfo(String openId) throws WxErrorException { + log.info("获取微信用户信息, openId: {}", openId); + return wxMpService.getUserService().userInfo(openId); + } + + @Override + public String createQrCode(String sceneStr) throws WxErrorException { + log.info("创建微信二维码, sceneStr: {}", sceneStr); + WxMpQrCodeTicket ticket = wxMpService.getQrcodeService() + .qrCodeCreateTmpTicket(sceneStr, 2592000); + return ticket.getUrl(); + } + +} diff --git a/intc-modules/intc-weixin/src/main/resources/application.yml b/intc-modules/intc-weixin/src/main/resources/application.yml new file mode 100644 index 0000000..29f40dc --- /dev/null +++ b/intc-modules/intc-weixin/src/main/resources/application.yml @@ -0,0 +1,42 @@ +# 微信对接模块配置 +wx: + # 微信公众号配置 + mp: + # 公众号appId(必填) + app-id: wx1234567890abcdef + # 公众号Secret(必填) + secret: your_mp_secret_here_32_characters + # 公众号token(选填,用于消息加解密) + token: your_token_here + # 公众号EncodingAESKey(选填,用于消息加解密) + aes-key: your_aes_key_here_43_characters_base64 + + # 微信小程序配置 + miniapp: + # 小程序appId(必填) + app-id: wx0987654321fedcba + # 小程序Secret(必填) + secret: your_miniapp_secret_here_32_chars + # 小程序token(选填,用于消息加解密) + token: your_miniapp_token + # 小程序EncodingAESKey(选填,用于消息加解密) + aes-key: your_miniapp_aes_key_43_characters_b64 + # 消息格式,XML或者JSON + msg-data-format: JSON + + # 微信支付配置 + pay: + # 商户号(必填) + mch-id: 1234567890 + # 商户密钥(V2版本必填) + mch-key: your_mch_key_here_32_characters_md5 + # 证书路径(退款等操作需要,选填) + key-path: classpath:cert/apiclient_cert.p12 + # apiV3秘钥(V3版本必填) + api-v3-key: your_api_v3_key_here_32_characters + # 证书序列号(V3版本必填) + cert-serial-no: 1234567890ABCDEF1234567890ABCDEF12345678 + # 私钥路径(V3版本选填) + private-key-path: classpath:cert/apiclient_key.pem + # 私钥内容(V3版本选填,与private-key-path二选一) + private-content: diff --git a/intc-modules/pom.xml b/intc-modules/pom.xml index a99163b..9dee19d 100644 --- a/intc-modules/pom.xml +++ b/intc-modules/pom.xml @@ -17,6 +17,8 @@ intc-workflow intc-fishery intc-tdengine + intc-weixin + intc-iot intc-modules From d9ae196daf4f7f6ae95693007a2db482a885e3fd Mon Sep 17 00:00:00 2001 From: tianyongbao Date: Wed, 19 Nov 2025 18:45:10 +0800 Subject: [PATCH 4/4] =?UTF-8?q?fix:=20=E5=BE=AE=E4=BF=A1=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E9=AA=8C=E8=AF=81=E7=A0=81=E5=8F=8A=E9=85=8D=E7=BD=AE=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application-dev.yml | 6 +++--- .../src/main/resources/application.yml | 20 +++++++++++-------- .../tdengine/DeviceSensorDataMapper.xml | 6 +++--- .../src/main/resources/application.yml | 16 +++++++-------- 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/intc-admin/src/main/resources/application-dev.yml b/intc-admin/src/main/resources/application-dev.yml index 643a963..fd2f02d 100644 --- a/intc-admin/src/main/resources/application-dev.yml +++ b/intc-admin/src/main/resources/application-dev.yml @@ -182,10 +182,10 @@ sms: # 框架定义的厂商名称标识,标定此配置是哪个厂商,详细请看厂商标识介绍部分 supplier: alibaba # 有些称为accessKey有些称之为apiKey,也有称为sdkKey或者appId。 - access-key-id: 您的accessKey + access-key-id: LTAI5tRnPowmTLjH181nSbsR # 称为accessSecret有些称之为apiSecret - access-key-secret: 您的accessKeySecret - signature: 您的短信签名 + access-key-secret: Vh2LoAM1t3XuMUVy2wTWSACJ97kOUW + signature: 【鱼测云】 sdk-app-id: 您的sdkAppId config2: # 厂商标识,标定此配置是哪个厂商,详细请看厂商标识介绍部分 diff --git a/intc-modules/intc-iot/src/main/resources/application.yml b/intc-modules/intc-iot/src/main/resources/application.yml index f81482f..5fcf077 100644 --- a/intc-modules/intc-iot/src/main/resources/application.yml +++ b/intc-modules/intc-iot/src/main/resources/application.yml @@ -2,24 +2,28 @@ aliyun: living-iot: # 阿里云 AccessKey ID(必填) - access-key-id: LTAI5txxxxxxxxxxxxxxxxxx + access-key-id: LTAI5tRnPowmTLjH181nSbsR # 阿里云 AccessKey Secret(必填) - access-key-secret: your_access_key_secret_here_32_chars + access-key-secret: Vh2LoAM1t3XuMUVy2wTWSACJ97kOUW # 地域节点(必填,如:cn-shanghai) region-id: cn-shanghai # 飞燕平台项目ID(Project ID,必填) - project-id: a1xxxxxx + project-id: a123nMibvh0q4UnU + # 控制器key + controller-product-key: a1Xj9dagTIx, + # 检测仪key + detector-product-key: a15hA3oBPmB, # App Key(必填) - app-key: your_app_key_here + app-key: 334224397 # App Secret(必填) - app-secret: your_app_secret_here_32_characters + app-secret: 70de3018ec39423e9ca1e1b6a6a84ad6 # 品类Key(选填) - category-key: - + category-key: + # MQTT 配置(可选) mqtt: # MQTT Broker 地址(格式:ssl://实例ID.iot-as-mqtt.cn-shanghai.aliyuncs.com:1883) - broker-url: ssl://a1xxxxxx.iot-as-mqtt.cn-shanghai.aliyuncs.com:1883 + broker-url: ssl://1572610294777992.iot-amqp.cn-shanghai.aliyuncs.com # 客户端ID(格式:{ClientID}|securemode=2,signmethod=hmacsha1|) client-id: your_client_id|securemode=2,signmethod=hmacsha1| # 用户名(设备名称&产品Key) diff --git a/intc-modules/intc-tdengine/src/main/resources/mapper/tdengine/DeviceSensorDataMapper.xml b/intc-modules/intc-tdengine/src/main/resources/mapper/tdengine/DeviceSensorDataMapper.xml index 518988c..3e943f2 100644 --- a/intc-modules/intc-tdengine/src/main/resources/mapper/tdengine/DeviceSensorDataMapper.xml +++ b/intc-modules/intc-tdengine/src/main/resources/mapper/tdengine/DeviceSensorDataMapper.xml @@ -42,7 +42,7 @@ insert into - `fishery`.t_#{serialNum} + `fishery`.t_#{data.serialNum} using fishery.device_sensor_data @@ -55,7 +55,7 @@