org.springframework.boot
diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/MobileController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/MobileController.java
deleted file mode 100644
index b38e863c7..000000000
--- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/MobileController.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2018-2025, lengleng All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
- */
-
-package com.pig4cloud.pigx.admin.controller;
-
-import com.pig4cloud.pigx.admin.service.MobileService;
-import com.pig4cloud.pigx.common.core.util.R;
-import com.pig4cloud.pigx.common.security.annotation.Inner;
-import io.swagger.v3.oas.annotations.security.SecurityRequirement;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import lombok.AllArgsConstructor;
-import org.springframework.http.HttpHeaders;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * @author lengleng
- * @date 2018/11/14
- *
- * 手机验证码
- */
-@RestController
-@AllArgsConstructor
-@RequestMapping("/mobile")
-@Tag(description = "mobile", name = "手机管理模块")
-@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
-public class MobileController {
-
- private final MobileService mobileService;
-
- @Inner(value = false)
- @GetMapping("/{mobile}")
- public R sendSmsCode(@PathVariable String mobile) {
- return mobileService.sendSmsCode(mobile);
- }
-
-}
diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysMessageController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysMessageController.java
index 4d0b2bf2b..844f2810a 100644
--- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysMessageController.java
+++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysMessageController.java
@@ -6,15 +6,20 @@ import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.pig4cloud.pigx.admin.api.dto.MessageEmailDTO;
+import com.pig4cloud.pigx.admin.api.dto.MessageHookDTO;
+import com.pig4cloud.pigx.admin.api.dto.MessageSmsDTO;
import com.pig4cloud.pigx.admin.api.entity.SysMessageEntity;
import com.pig4cloud.pigx.admin.api.vo.SysMessageVO;
import com.pig4cloud.pigx.admin.service.SysMessageService;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
import com.pig4cloud.pigx.common.log.annotation.SysLog;
+import com.pig4cloud.pigx.common.security.annotation.Inner;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.http.HttpHeaders;
@@ -36,134 +41,188 @@ import java.util.List;
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysMessageController {
- private final SysMessageService sysMessageService;
+ private final SysMessageService sysMessageService;
- /**
- * 分页查询
- * @param page 分页对象
- * @param sysMessage 站内信息
- * @return
- */
- @Operation(summary = "分页查询", description = "分页查询")
- @GetMapping("/page")
- @PreAuthorize("@pms.hasPermission('sys_message_view')")
- public R getSysMessagePage(@ParameterObject Page page, @ParameterObject SysMessageEntity sysMessage) {
- LambdaQueryWrapper wrapper = Wrappers.lambdaQuery();
- wrapper.like(StrUtil.isNotBlank(sysMessage.getTitle()), SysMessageEntity::getTitle, sysMessage.getTitle());
- return R.ok(sysMessageService.page(page, wrapper));
- }
+ /**
+ * 分页查询
+ *
+ * @param page 分页对象
+ * @param sysMessage 站内信息
+ * @return
+ */
+ @Operation(summary = "分页查询", description = "分页查询")
+ @GetMapping("/page")
+ @PreAuthorize("@pms.hasPermission('sys_message_view')")
+ public R getSysMessagePage(@ParameterObject Page page, @ParameterObject SysMessageEntity sysMessage) {
+ LambdaQueryWrapper wrapper = Wrappers.lambdaQuery();
+ wrapper.like(StrUtil.isNotBlank(sysMessage.getTitle()), SysMessageEntity::getTitle, sysMessage.getTitle());
+ return R.ok(sysMessageService.page(page, wrapper));
+ }
- /**
- * 通过id查询站内信息
- * @param id id
- * @return R
- */
- @Operation(summary = "通过id查询", description = "通过id查询")
- @GetMapping("/{id}")
- @PreAuthorize("@pms.hasPermission('sys_message_view')")
- public R getById(@PathVariable("id") Long id) {
- return R.ok(sysMessageService.getMessage(id));
- }
+ /**
+ * 通过id查询站内信息
+ *
+ * @param id id
+ * @return R
+ */
+ @Operation(summary = "通过id查询", description = "通过id查询")
+ @GetMapping("/{id}")
+ @PreAuthorize("@pms.hasPermission('sys_message_view')")
+ public R getById(@PathVariable("id") Long id) {
+ return R.ok(sysMessageService.getMessage(id));
+ }
- /**
- * 新增站内信息
- * @param sysMessage 站内信息
- * @return R
- */
- @Operation(summary = "新增站内信息", description = "新增站内信息")
- @SysLog("新增站内信息")
- @PostMapping
- @PreAuthorize("@pms.hasPermission('sys_message_add')")
- public R save(@RequestBody SysMessageVO sysMessage) {
- return R.ok(sysMessageService.saveOrUpdateMessage(sysMessage));
- }
+ /**
+ * 新增站内信息
+ *
+ * @param sysMessage 站内信息
+ * @return R
+ */
+ @Operation(summary = "新增站内信息", description = "新增站内信息")
+ @SysLog("新增站内信息")
+ @PostMapping
+ @PreAuthorize("@pms.hasPermission('sys_message_add')")
+ public R save(@RequestBody SysMessageVO sysMessage) {
+ return R.ok(sysMessageService.saveOrUpdateMessage(sysMessage));
+ }
- /**
- * 修改站内信息
- * @param sysMessage 站内信息
- * @return R
- */
- @Operation(summary = "修改站内信息", description = "修改站内信息")
- @SysLog("修改站内信息")
- @PutMapping
- @PreAuthorize("@pms.hasPermission('sys_message_edit')")
- public R updateById(@RequestBody SysMessageVO sysMessage) {
- return R.ok(sysMessageService.saveOrUpdateMessage(sysMessage));
- }
+ /**
+ * 修改站内信息
+ *
+ * @param sysMessage 站内信息
+ * @return R
+ */
+ @Operation(summary = "修改站内信息", description = "修改站内信息")
+ @SysLog("修改站内信息")
+ @PutMapping
+ @PreAuthorize("@pms.hasPermission('sys_message_edit')")
+ public R updateById(@RequestBody SysMessageVO sysMessage) {
+ return R.ok(sysMessageService.saveOrUpdateMessage(sysMessage));
+ }
- /**
- * 通过id删除站内信息
- * @param ids id列表
- * @return R
- */
- @Operation(summary = "通过id删除站内信息", description = "通过id删除站内信息")
- @SysLog("通过id删除站内信息")
- @DeleteMapping
- @PreAuthorize("@pms.hasPermission('sys_message_del')")
- public R removeById(@RequestBody Long[] ids) {
- return R.ok(sysMessageService.removeBatchByIds(CollUtil.toList(ids)));
- }
+ /**
+ * 通过id删除站内信息
+ *
+ * @param ids id列表
+ * @return R
+ */
+ @Operation(summary = "通过id删除站内信息", description = "通过id删除站内信息")
+ @SysLog("通过id删除站内信息")
+ @DeleteMapping
+ @PreAuthorize("@pms.hasPermission('sys_message_del')")
+ public R removeById(@RequestBody Long[] ids) {
+ return R.ok(sysMessageService.removeBatchByIds(CollUtil.toList(ids)));
+ }
- /**
- * 导出excel 表格
- * @param sysMessage 查询条件
- * @param ids 导出指定ID
- * @return excel 文件流
- */
- @ResponseExcel
- @GetMapping("/export")
- @PreAuthorize("@pms.hasPermission('sys_message_export')")
- public List export(SysMessageEntity sysMessage, Long[] ids) {
- return sysMessageService
- .list(Wrappers.lambdaQuery(sysMessage).in(ArrayUtil.isNotEmpty(ids), SysMessageEntity::getId, ids));
- }
+ /**
+ * 导出excel 表格
+ *
+ * @param sysMessage 查询条件
+ * @param ids 导出指定ID
+ * @return excel 文件流
+ */
+ @ResponseExcel
+ @GetMapping("/export")
+ @PreAuthorize("@pms.hasPermission('sys_message_export')")
+ public List export(SysMessageEntity sysMessage, Long[] ids) {
+ return sysMessageService
+ .list(Wrappers.lambdaQuery(sysMessage).in(ArrayUtil.isNotEmpty(ids), SysMessageEntity::getId, ids));
+ }
- /**
- * 发送站内信息
- * @param id 站内信息
- * @return R
- */
- @Operation(summary = "发送站内信息", description = "发送站内信息")
- @SysLog("发送站内信息")
- @PostMapping("/send")
- @PreAuthorize("@pms.hasPermission('sys_message_add')")
- public R send(Long id) {
- return R.ok(sysMessageService.sendMessage(id));
- }
+ /**
+ * 发送站内信息
+ *
+ * @param id 站内信息
+ * @return R
+ */
+ @Operation(summary = "发送站内信息", description = "发送站内信息")
+ @SysLog("发送站内信息")
+ @PostMapping("/send")
+ @PreAuthorize("@pms.hasPermission('sys_message_add')")
+ public R send(Long id) {
+ return R.ok(sysMessageService.sendMessage(id));
+ }
- /**
- * 读取站内信息
- * @param id 站内信息
- * @return R
- */
- @Operation(summary = "读取站内信息", description = "读取站内信息")
- @SysLog("发送站内信息")
- @PostMapping("/read")
- public R read(Long id) {
- return R.ok(sysMessageService.readMessage(id));
- }
+ /**
+ * 读取站内信息
+ *
+ * @param id 站内信息
+ * @return R
+ */
+ @Operation(summary = "读取站内信息", description = "读取站内信息")
+ @SysLog("发送站内信息")
+ @PostMapping("/read")
+ public R read(Long id) {
+ return R.ok(sysMessageService.readMessage(id));
+ }
- /**
- * 查询用户公告
- * @param page 分页条件
- * @param sysMessage 查询条件
- * @return list
- */
- @Operation(summary = "查询用户信", description = "查询用户信")
- @GetMapping("/user/page")
- public R getUserMessageList(@ParameterObject Page page, SysMessageVO sysMessage) {
- return R.ok(sysMessageService.pageUserMessage(page, sysMessage));
- }
+ /**
+ * 查询用户公告
+ *
+ * @param page 分页条件
+ * @param sysMessage 查询条件
+ * @return list
+ */
+ @Operation(summary = "查询用户信", description = "查询用户信")
+ @GetMapping("/user/page")
+ public R getUserMessageList(@ParameterObject Page page, SysMessageVO sysMessage) {
+ return R.ok(sysMessageService.pageUserMessage(page, sysMessage));
+ }
- /**
- * 查询信息阅读列表
- * @return list
- */
- @Operation(summary = "查询用户阅读情况", description = "查询用户阅读情况")
- @GetMapping("/user/read/page")
- public R getUserMessageList(@ParameterObject Page page, @ParameterObject Long messageId,
- @ParameterObject @RequestParam(required = false) String name) {
- return R.ok(sysMessageService.pageUserRead(page, messageId, name));
- }
+ /**
+ * 查询信息阅读列表
+ *
+ * @return list
+ */
+ @Operation(summary = "查询用户阅读情况", description = "查询用户阅读情况")
+ @GetMapping("/user/read/page")
+ public R getUserMessageList(@ParameterObject Page page, @ParameterObject Long messageId,
+ @ParameterObject @RequestParam(required = false) String name) {
+ return R.ok(sysMessageService.pageUserRead(page, messageId, name));
+ }
+ /**
+ * 发送短信验证码
+ *
+ * @param mobile 手机号
+ * @return {@link R }
+ */
+ @Inner(value = false)
+ @GetMapping("/send/smsCode")
+ public R sendSmsCode(@RequestParam String mobile) {
+ return sysMessageService.sendSmsCode(mobile);
+ }
+
+ /**
+ * 发送短信
+ *
+ * @param messageSmsDTO 消息 短信 DTO
+ * @return {@link R }
+ */
+ @PostMapping("/send/sms")
+ public R sendSms(@Valid @RequestBody MessageSmsDTO messageSmsDTO) {
+ return sysMessageService.sendSms(messageSmsDTO);
+ }
+
+ /**
+ * 发送邮件
+ *
+ * @param messageEmailDTO 留言内容 电子邮件 DTO
+ * @return {@link R }
+ */
+ @PostMapping("/send/email")
+ public R sendEmail(@Valid @RequestBody MessageEmailDTO messageEmailDTO) {
+ return sysMessageService.sendEmail(messageEmailDTO);
+ }
+
+ /**
+ * 发送 webhook
+ *
+ * @param messageHookDTO 消息挂钩 DTO
+ * @return {@link R }
+ */
+ @PostMapping("/send/webhook")
+ public R sendWebhook(@Valid @RequestBody MessageHookDTO messageHookDTO) {
+ return sysMessageService.sendHook(messageHookDTO);
+ }
}
diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysSystemConfigController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysSystemConfigController.java
new file mode 100644
index 000000000..312b2e8d1
--- /dev/null
+++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysSystemConfigController.java
@@ -0,0 +1,122 @@
+package com.pig4cloud.pigx.admin.controller;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ArrayUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.pig4cloud.pigx.admin.api.entity.SysSystemConfigEntity;
+import com.pig4cloud.pigx.admin.service.SysSystemConfigService;
+import com.pig4cloud.pigx.common.core.util.R;
+import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
+import com.pig4cloud.pigx.common.log.annotation.SysLog;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import org.springdoc.core.annotations.ParameterObject;
+import org.springframework.http.HttpHeaders;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 系统配置
+ *
+ * @author pig
+ * @date 2024-07-14 20:58:54
+ */
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/system-config")
+@Tag(description = "sysSystemConfig", name = "系统配置管理")
+@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
+public class SysSystemConfigController {
+
+ private final SysSystemConfigService sysSystemConfigService;
+
+ /**
+ * 分页查询
+ *
+ * @param page 分页对象
+ * @param sysSystemConfig 系统配置
+ * @return
+ */
+ @Operation(summary = "分页查询", description = "分页查询")
+ @GetMapping("/page")
+ @PreAuthorize("@pms.hasPermission('sys_message_view')")
+ public R getSysSystemConfigPage(@ParameterObject Page page, @ParameterObject SysSystemConfigEntity sysSystemConfig) {
+ return sysSystemConfigService.pageSystemConfig(page, sysSystemConfig);
+ }
+
+
+ /**
+ * 通过条件查询系统配置
+ *
+ * @param sysSystemConfig 查询条件
+ * @return R 对象列表
+ */
+ @Operation(summary = "通过条件查询", description = "通过条件查询对象")
+ @GetMapping("/details")
+ @PreAuthorize("@pms.hasPermission('sys_message_view')")
+ public R getDetails(@ParameterObject SysSystemConfigEntity sysSystemConfig) {
+ return sysSystemConfigService.listSystemConfig(sysSystemConfig);
+ }
+
+ /**
+ * 新增系统配置
+ *
+ * @param sysSystemConfig 系统配置
+ * @return R
+ */
+ @Operation(summary = "新增系统配置", description = "新增系统配置")
+ @SysLog("新增系统配置")
+ @PostMapping
+ @PreAuthorize("@pms.hasPermission('sys_message_add')")
+ public R save(@RequestBody SysSystemConfigEntity sysSystemConfig) {
+ return R.ok(sysSystemConfigService.save(sysSystemConfig));
+ }
+
+ /**
+ * 修改系统配置
+ *
+ * @param sysSystemConfig 系统配置
+ * @return R
+ */
+ @Operation(summary = "修改系统配置", description = "修改系统配置")
+ @SysLog("修改系统配置")
+ @PutMapping
+ @PreAuthorize("@pms.hasPermission('sys_message_edit')")
+ public R updateById(@RequestBody SysSystemConfigEntity sysSystemConfig) {
+ return sysSystemConfigService.updateSystemConfig(sysSystemConfig);
+ }
+
+ /**
+ * 通过id删除系统配置
+ *
+ * @param ids id列表
+ * @return R
+ */
+ @Operation(summary = "通过id删除系统配置", description = "通过id删除系统配置")
+ @SysLog("通过id删除系统配置")
+ @DeleteMapping
+ @PreAuthorize("@pms.hasPermission('sys_message_del')")
+ public R removeById(@RequestBody Long[] ids) {
+ return R.ok(sysSystemConfigService.removeBatchByIds(CollUtil.toList(ids)));
+ }
+
+
+ /**
+ * 导出excel 表格
+ *
+ * @param sysSystemConfig 查询条件
+ * @param ids 导出指定ID
+ * @return excel 文件流
+ */
+ @ResponseExcel
+ @GetMapping("/export")
+ @PreAuthorize("@pms.hasPermission('sys_message_export')")
+ public List export(SysSystemConfigEntity sysSystemConfig, Long[] ids) {
+ return sysSystemConfigService.list(Wrappers.lambdaQuery(sysSystemConfig).in(ArrayUtil.isNotEmpty(ids), SysSystemConfigEntity::getId, ids));
+ }
+}
diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysSystemConfigMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysSystemConfigMapper.java
new file mode 100644
index 000000000..4602e8367
--- /dev/null
+++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysSystemConfigMapper.java
@@ -0,0 +1,10 @@
+package com.pig4cloud.pigx.admin.mapper;
+
+import com.pig4cloud.pigx.admin.api.entity.SysSystemConfigEntity;
+import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface SysSystemConfigMapper extends PigxBaseMapper {
+
+}
diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/MobileService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/MobileService.java
deleted file mode 100644
index 684446dc7..000000000
--- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/MobileService.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2018-2025, lengleng All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
- */
-
-package com.pig4cloud.pigx.admin.service;
-
-import com.pig4cloud.pigx.common.core.util.R;
-
-/**
- * @author lengleng
- * @date 2018/11/14
- */
-public interface MobileService {
-
- /**
- * 发送手机验证码
- * @param mobile mobile
- * @return code
- */
- R sendSmsCode(String mobile);
-
-}
diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysMessageService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysMessageService.java
index 886610514..3e27142da 100644
--- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysMessageService.java
+++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysMessageService.java
@@ -3,52 +3,93 @@ package com.pig4cloud.pigx.admin.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
+import com.pig4cloud.pigx.admin.api.dto.MessageEmailDTO;
+import com.pig4cloud.pigx.admin.api.dto.MessageHookDTO;
+import com.pig4cloud.pigx.admin.api.dto.MessageSmsDTO;
import com.pig4cloud.pigx.admin.api.entity.SysMessageEntity;
import com.pig4cloud.pigx.admin.api.vo.SysMessageVO;
+import com.pig4cloud.pigx.common.core.util.R;
public interface SysMessageService extends IService {
- /**
- * 发送信息
- * @param id 消息ID
- * @return true/false
- */
- Boolean sendMessage(Long id);
+ /**
+ * 发送信息
+ *
+ * @param id 消息ID
+ * @return true/false
+ */
+ Boolean sendMessage(Long id);
- /**
- * 保存
- * @param sysMessage 消息
- * @return true/false
- */
- Boolean saveOrUpdateMessage(SysMessageVO sysMessage);
+ /**
+ * 保存
+ *
+ * @param sysMessage 消息
+ * @return true/false
+ */
+ Boolean saveOrUpdateMessage(SysMessageVO sysMessage);
- /**
- * 获取用户的信息列表
- * @return list
- */
- IPage pageUserMessage(Page page, SysMessageVO sysMessage);
+ /**
+ * 获取用户的信息列表
+ *
+ * @return list
+ */
+ IPage pageUserMessage(Page page, SysMessageVO sysMessage);
- /**
- * 读取信息
- * @param id id
- * @return true/false
- */
- Boolean readMessage(Long id);
+ /**
+ * 读取信息
+ *
+ * @param id id
+ * @return true/false
+ */
+ Boolean readMessage(Long id);
- /**
- * 获取信息
- * @param id id
- * @return messageVO
- */
- SysMessageVO getMessage(Long id);
+ /**
+ * 获取信息
+ *
+ * @param id id
+ * @return messageVO
+ */
+ SysMessageVO getMessage(Long id);
- /**
- * 查询用户阅读情况
- * @param page 分页
- * @param messageId 消息ID
- * @param name 姓名
- * @return page
- */
- Page pageUserRead(Page page, Long messageId, String name);
+ /**
+ * 查询用户阅读情况
+ *
+ * @param page 分页
+ * @param messageId 消息ID
+ * @param name 姓名
+ * @return page
+ */
+ Page pageUserRead(Page page, Long messageId, String name);
+ /**
+ * 发送手机验证码
+ *
+ * @param mobile mobile
+ * @return code
+ */
+ R sendSmsCode(String mobile);
+
+ /**
+ * 发送短信
+ *
+ * @param messageSmsDTO 消息 短信 DTO
+ * @return {@link R }
+ */
+ R sendSms(MessageSmsDTO messageSmsDTO);
+
+ /**
+ * 发送邮件
+ *
+ * @param messageEmailDTO 留言内容 电子邮件 DTO
+ * @return {@link R }
+ */
+ R sendEmail(MessageEmailDTO messageEmailDTO);
+
+ /**
+ * 发送钩子消息
+ *
+ * @param messageHookDTO 消息挂钩 DTO
+ * @return {@link R }
+ */
+ R sendHook(MessageHookDTO messageHookDTO);
}
diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysSystemConfigService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysSystemConfigService.java
new file mode 100644
index 000000000..ae8d6c038
--- /dev/null
+++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysSystemConfigService.java
@@ -0,0 +1,40 @@
+package com.pig4cloud.pigx.admin.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.pig4cloud.pigx.admin.api.entity.SysSystemConfigEntity;
+import com.pig4cloud.pigx.common.core.util.R;
+
+/**
+ * SYS 系统配置服务
+ *
+ * @author lengleng
+ * @date 2024/07/18
+ */
+public interface SysSystemConfigService extends IService {
+
+ /**
+ * 列出系统配置
+ *
+ * @param query 查询
+ * @return {@link R }
+ */
+ R listSystemConfig(SysSystemConfigEntity query);
+
+ /**
+ * 系统配置
+ *
+ * @param page 页
+ * @param sysSystemConfig sys 系统配置
+ * @return {@link R }
+ */
+ R pageSystemConfig(Page page, SysSystemConfigEntity sysSystemConfig);
+
+ /**
+ * 更新系统配置
+ *
+ * @param sysSystemConfig sys 系统配置
+ * @return {@link R }
+ */
+ R updateSystemConfig(SysSystemConfigEntity sysSystemConfig);
+}
diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/MobileServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/MobileServiceImpl.java
deleted file mode 100644
index 487f82182..000000000
--- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/MobileServiceImpl.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2018-2025, lengleng All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
- */
-
-package com.pig4cloud.pigx.admin.service.impl;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.RandomUtil;
-import cn.hutool.core.util.StrUtil;
-import com.baomidou.mybatisplus.core.toolkit.StringPool;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.pig4cloud.pigx.admin.api.entity.SysUser;
-import com.pig4cloud.pigx.admin.mapper.SysUserMapper;
-import com.pig4cloud.pigx.admin.service.MobileService;
-import com.pig4cloud.pigx.common.core.constant.CacheConstants;
-import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
-import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum;
-import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
-import com.pig4cloud.pigx.common.core.util.MsgUtils;
-import com.pig4cloud.pigx.common.core.util.R;
-import lombok.AllArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.data.redis.core.StringRedisTemplate;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-/**
- * @author lengleng
- * @date 2018/11/14
- *
- * 手机登录相关业务实现
- */
-@Slf4j
-@Service
-@AllArgsConstructor
-public class MobileServiceImpl implements MobileService {
-
- private final StringRedisTemplate redisTemplate;
-
- private final SysUserMapper userMapper;
-
- /**
- * 发送手机验证码 TODO: 调用短信网关发送验证码,测试返回前端
- * @param mobile mobile
- * @return code
- */
- @Override
- public R sendSmsCode(String mobile) {
- List userList = userMapper
- .selectList(Wrappers.query().lambda().eq(SysUser::getPhone, mobile));
-
- if (CollUtil.isEmpty(userList)) {
- log.info("手机号未注册:{}", mobile);
- return R.ok(Boolean.FALSE, MsgUtils.getMessage(ErrorCodes.SYS_APP_PHONE_UNREGISTERED, mobile));
- }
-
- String codeObj = redisTemplate.opsForValue()
- .get(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + StringPool.AT + mobile);
-
- if (StrUtil.isNotBlank(codeObj)) {
- log.info("手机号验证码未过期:{},{}", mobile, codeObj);
- return R.ok(Boolean.FALSE, MsgUtils.getMessage(ErrorCodes.SYS_APP_SMS_OFTEN));
- }
-
- String code = RandomUtil.randomNumbers(Integer.parseInt(SecurityConstants.CODE_SIZE));
- log.debug("手机号生成验证码成功:{},{}", mobile, code);
- redisTemplate.opsForValue()
- .set(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + StringPool.AT + mobile, code,
- SecurityConstants.CODE_TIME, TimeUnit.SECONDS);
- return R.ok(Boolean.TRUE, code);
- }
-
-}
diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysMessageServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysMessageServiceImpl.java
index 2671d115d..a0cf24937 100644
--- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysMessageServiceImpl.java
+++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysMessageServiceImpl.java
@@ -1,31 +1,91 @@
package com.pig4cloud.pigx.admin.service.impl;
+import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.mail.MailAccount;
+import cn.hutool.extra.mail.MailUtil;
+import cn.hutool.extra.template.Template;
+import cn.hutool.extra.template.TemplateConfig;
+import cn.hutool.extra.template.TemplateEngine;
+import cn.hutool.extra.template.TemplateUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.amazonaws.services.s3.model.S3Object;
import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
-import com.pig4cloud.pigx.admin.api.entity.SysMessageEntity;
-import com.pig4cloud.pigx.admin.api.entity.SysMessageRelationEntity;
-import com.pig4cloud.pigx.admin.api.entity.SysUser;
+import com.pig4cloud.pigx.admin.api.constant.SmsBizCodeEnum;
+import com.pig4cloud.pigx.admin.api.constant.SystemConfigTypeEnum;
+import com.pig4cloud.pigx.admin.api.dto.MessageEmailDTO;
+import com.pig4cloud.pigx.admin.api.dto.MessageHookDTO;
+import com.pig4cloud.pigx.admin.api.dto.MessageSmsDTO;
+import com.pig4cloud.pigx.admin.api.dto.SysLogDTO;
+import com.pig4cloud.pigx.admin.api.entity.*;
+import com.pig4cloud.pigx.admin.api.feign.RemoteLogService;
import com.pig4cloud.pigx.admin.api.vo.OrgTreeVO;
import com.pig4cloud.pigx.admin.api.vo.SysMessageReadVO;
import com.pig4cloud.pigx.admin.api.vo.SysMessageVO;
-import com.pig4cloud.pigx.admin.mapper.SysMessageMapper;
-import com.pig4cloud.pigx.admin.mapper.SysMessageRelationMapper;
-import com.pig4cloud.pigx.admin.mapper.SysUserMapper;
+import com.pig4cloud.pigx.admin.mapper.*;
import com.pig4cloud.pigx.admin.service.SysMessageService;
+import com.pig4cloud.pigx.common.core.constant.CacheConstants;
+import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
+import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum;
import com.pig4cloud.pigx.common.core.constant.enums.YesNoEnum;
+import com.pig4cloud.pigx.common.core.exception.CheckedException;
+import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
+import com.pig4cloud.pigx.common.core.util.MsgUtils;
+import com.pig4cloud.pigx.common.core.util.R;
+import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder;
+import com.pig4cloud.pigx.common.file.core.FileTemplate;
+import com.pig4cloud.pigx.common.log.util.JacksonSensitiveFieldUtil;
+import com.pig4cloud.pigx.common.log.util.LogTypeEnum;
+import com.pig4cloud.pigx.common.log.util.SysLogUtils;
import com.pig4cloud.pigx.common.security.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.oa.api.OaSender;
+import org.dromara.oa.comm.entity.Request;
+import org.dromara.oa.comm.enums.MessageType;
+import org.dromara.oa.comm.enums.OaType;
+import org.dromara.oa.core.byteTalk.config.ByteTalkConfig;
+import org.dromara.oa.core.dingTalk.config.DingTalkConfig;
+import org.dromara.oa.core.provider.factory.OaFactory;
+import org.dromara.oa.core.weTalk.config.WeTalkConfig;
+import org.dromara.sms4j.aliyun.config.AlibabaConfig;
+import org.dromara.sms4j.api.SmsBlend;
+import org.dromara.sms4j.cloopen.config.CloopenConfig;
+import org.dromara.sms4j.core.factory.SmsFactory;
+import org.dromara.sms4j.ctyun.config.CtyunConfig;
+import org.dromara.sms4j.dingzhong.config.DingZhongConfig;
+import org.dromara.sms4j.emay.config.EmayConfig;
+import org.dromara.sms4j.huawei.config.HuaweiConfig;
+import org.dromara.sms4j.jdcloud.config.JdCloudConfig;
+import org.dromara.sms4j.netease.config.NeteaseConfig;
+import org.dromara.sms4j.provider.config.BaseConfig;
+import org.dromara.sms4j.qiniu.config.QiNiuConfig;
+import org.dromara.sms4j.tencent.config.TencentConfig;
+import org.dromara.sms4j.unisms.config.UniConfig;
+import org.dromara.sms4j.yunpian.config.YunpianConfig;
+import org.dromara.sms4j.zhutong.config.ZhutongConfig;
import org.springframework.beans.BeanUtils;
+import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Objects;
+import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
@@ -34,161 +94,381 @@ import java.util.stream.Collectors;
* @author pig
* @date 2023-10-25 13:37:25
*/
+@Slf4j
@Service
@RequiredArgsConstructor
-public class SysMessageServiceImpl extends ServiceImpl
- implements SysMessageService {
+public class SysMessageServiceImpl extends ServiceImpl implements SysMessageService {
- private final SysMessageRelationMapper relationMapper;
+ /**
+ * 支持短信服务商
+ */
+ private static final Class[] SUPPORT_CONFIG_CLAZZ = {AlibabaConfig.class, CloopenConfig.class, CtyunConfig.class, EmayConfig.class, HuaweiConfig.class, JdCloudConfig.class, NeteaseConfig.class, TencentConfig.class, UniConfig.class, YunpianConfig.class, ZhutongConfig.class, DingZhongConfig.class, QiNiuConfig.class};
- private final SysUserMapper userMapper;
+ private final RemoteLogService remoteLogService;
- /**
- * 发送信息
- * @param id id
- * @return true/false
- */
- @Override
- @Transactional(rollbackFor = Exception.class)
- public Boolean sendMessage(Long id) {
- // 更新信息状态
- SysMessageEntity sysMessage = new SysMessageEntity();
- sysMessage.setSendFlag(YesNoEnum.YES.getCode());
- baseMapper.update(sysMessage, Wrappers.lambdaQuery().eq(SysMessageEntity::getId, id));
- return Boolean.TRUE;
- }
+ private final SysSystemConfigMapper sysSystemConfigMapper;
- /**
- * 保存消息及其关联关系
- * @param sysMessage 消息对象
- * @return 是否保存成功
- */
- @Transactional(rollbackFor = Exception.class)
- public Boolean saveOrUpdateMessage(SysMessageVO sysMessage) {
- SysMessageEntity messageEntity = new SysMessageEntity();
- BeanUtils.copyProperties(sysMessage, messageEntity);
+ private final SysMessageRelationMapper relationMapper;
- if (Objects.isNull(sysMessage.getId())) {
- baseMapper.insert(messageEntity);
- }
- else {
- baseMapper.updateById(sysMessage);
- }
+ private final StringRedisTemplate redisTemplate;
- // 删除原有用户
- relationMapper.delete(Wrappers.lambdaQuery()
- .eq(SysMessageRelationEntity::getMsgId, messageEntity.getId()));
+ private final SysUserMapper userMapper;
- List userList = sysMessage.getUserList();
- if (CollUtil.isNotEmpty(userList)) {
- userList.forEach(user -> {
- SysMessageRelationEntity relationEntity = new SysMessageRelationEntity();
- relationEntity.setMsgId(messageEntity.getId());
- relationEntity.setUserId(user.getId());
- relationMapper.insert(relationEntity);
- });
- }
- else {
- userMapper.selectList(Wrappers.emptyWrapper()).stream().map(SysUser::getUserId).forEach(userId -> {
- SysMessageRelationEntity relationEntity = new SysMessageRelationEntity();
- relationEntity.setMsgId(messageEntity.getId());
- relationEntity.setUserId(userId);
- relationMapper.insert(relationEntity);
- });
- }
- return Boolean.TRUE;
- }
+ private final SysFileMapper fileMapper;
- /**
- * 获取用户的信息列表
- * @return list
- */
- @Override
- public IPage pageUserMessage(Page page, SysMessageVO sysMessage) {
- MPJLambdaWrapper wrapper = new MPJLambdaWrapper()
- .selectAll(SysMessageEntity.class)
- .select(SysMessageRelationEntity::getReadFlag)
- .leftJoin(SysMessageRelationEntity.class, SysMessageRelationEntity::getMsgId, SysMessageEntity::getId)
- .eq(SysMessageRelationEntity::getUserId, SecurityUtils.getUser().getId())
- .eq(SysMessageEntity::getSendFlag, YesNoEnum.YES.getCode())
- .eq(StrUtil.isNotBlank(sysMessage.getCategory()), SysMessageEntity::getCategory, sysMessage.getCategory())
- .eq(StrUtil.isNotBlank(sysMessage.getReadFlag()), SysMessageRelationEntity::getReadFlag,
- sysMessage.getReadFlag())
- .orderByDesc(SysMessageEntity::getSort)
- .orderByDesc(SysMessageEntity::getCreateTime);
- return baseMapper.selectJoinPage(page, SysMessageVO.class, wrapper);
- }
+ private final FileTemplate fileTemplate;
- /**
- * 读取信息
- * @param id id
- * @return true/false
- */
- @Override
- public Boolean readMessage(Long id) {
- SysMessageRelationEntity relationEntity = new SysMessageRelationEntity();
- relationEntity.setReadFlag(YesNoEnum.YES.getCode());
- relationMapper.update(relationEntity,
- Wrappers.lambdaQuery()
- .eq(SysMessageRelationEntity::getMsgId, id)
- .eq(SysMessageRelationEntity::getUserId, SecurityUtils.getUser().getId()));
- return Boolean.TRUE;
- }
+ /**
+ * 发送信息
+ *
+ * @param id id
+ * @return true/false
+ */
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public Boolean sendMessage(Long id) {
+ // 更新信息状态
+ SysMessageEntity sysMessage = new SysMessageEntity();
+ sysMessage.setSendFlag(YesNoEnum.YES.getCode());
+ baseMapper.update(sysMessage, Wrappers.lambdaQuery().eq(SysMessageEntity::getId, id));
+ return Boolean.TRUE;
+ }
- /**
- * 获取信息
- * @param id id
- * @return messageVO
- */
- @Override
- public SysMessageVO getMessage(Long id) {
- SysMessageEntity messageEntity = baseMapper.selectById(id);
- SysMessageVO SysMessageVO = new SysMessageVO();
- BeanUtils.copyProperties(messageEntity, SysMessageVO);
+ /**
+ * 保存消息及其关联关系
+ *
+ * @param sysMessage 消息对象
+ * @return 是否保存成功
+ */
+ @Transactional(rollbackFor = Exception.class)
+ public Boolean saveOrUpdateMessage(SysMessageVO sysMessage) {
+ SysMessageEntity messageEntity = new SysMessageEntity();
+ BeanUtils.copyProperties(sysMessage, messageEntity);
- // 全体通知
- if (messageEntity.getAllFlag().equals(YesNoEnum.YES.getCode())) {
- return SysMessageVO;
- }
- List userIdList = relationMapper
- .selectList(Wrappers.lambdaQuery().eq(SysMessageRelationEntity::getMsgId, id))
- .stream()
- .map(SysMessageRelationEntity::getUserId)
- .collect(Collectors.toList());
+ if (Objects.isNull(sysMessage.getId())) {
+ baseMapper.insert(messageEntity);
+ } else {
+ baseMapper.updateById(sysMessage);
+ }
- if (CollUtil.isNotEmpty(userIdList)) {
- List orgNodeUserVoList = userMapper.selectBatchIds(userIdList).stream().map(user -> {
- OrgTreeVO nodeUserVo = new OrgTreeVO();
- nodeUserVo.setId(user.getUserId());
- nodeUserVo.setAvatar(user.getAvatar());
- nodeUserVo.setName(user.getName());
- return nodeUserVo;
- }).collect(Collectors.toList());
+ // 删除原有用户
+ relationMapper.delete(Wrappers.lambdaQuery().eq(SysMessageRelationEntity::getMsgId, messageEntity.getId()));
- SysMessageVO.setUserList(orgNodeUserVoList);
- }
+ List userList = sysMessage.getUserList();
+ if (CollUtil.isNotEmpty(userList)) {
+ userList.forEach(user -> {
+ SysMessageRelationEntity relationEntity = new SysMessageRelationEntity();
+ relationEntity.setMsgId(messageEntity.getId());
+ relationEntity.setUserId(user.getId());
+ relationMapper.insert(relationEntity);
+ });
+ } else {
+ userMapper.selectList(Wrappers.emptyWrapper()).stream().map(SysUser::getUserId).forEach(userId -> {
+ SysMessageRelationEntity relationEntity = new SysMessageRelationEntity();
+ relationEntity.setMsgId(messageEntity.getId());
+ relationEntity.setUserId(userId);
+ relationMapper.insert(relationEntity);
+ });
+ }
+ return Boolean.TRUE;
+ }
- return SysMessageVO;
- }
+ /**
+ * 获取用户的信息列表
+ *
+ * @return list
+ */
+ @Override
+ public IPage pageUserMessage(Page page, SysMessageVO sysMessage) {
+ MPJLambdaWrapper wrapper = new MPJLambdaWrapper().selectAll(SysMessageEntity.class).select(SysMessageRelationEntity::getReadFlag).leftJoin(SysMessageRelationEntity.class, SysMessageRelationEntity::getMsgId, SysMessageEntity::getId).eq(SysMessageRelationEntity::getUserId, SecurityUtils.getUser().getId()).eq(SysMessageEntity::getSendFlag, YesNoEnum.YES.getCode()).eq(StrUtil.isNotBlank(sysMessage.getCategory()), SysMessageEntity::getCategory, sysMessage.getCategory()).eq(StrUtil.isNotBlank(sysMessage.getReadFlag()), SysMessageRelationEntity::getReadFlag, sysMessage.getReadFlag()).orderByDesc(SysMessageEntity::getSort).orderByDesc(SysMessageEntity::getCreateTime);
+ return baseMapper.selectJoinPage(page, SysMessageVO.class, wrapper);
+ }
- /**
- * 查询用户阅读情况
- * @param page 分页
- * @param messageId 消息ID
- * @param name 姓名
- * @return page
- */
- @Override
- public Page pageUserRead(Page page, Long messageId, String name) {
- MPJLambdaWrapper wrapper = new MPJLambdaWrapper()
- .selectAll(SysMessageRelationEntity.class)
- .select(SysUser::getUsername, SysUser::getName, SysUser::getUserId)
- .select(SysMessageEntity::getTitle)
- .leftJoin(SysUser.class, SysUser::getUserId, SysMessageRelationEntity::getUserId)
- .leftJoin(SysMessageEntity.class, SysMessageEntity::getId, SysMessageRelationEntity::getMsgId)
- .eq(SysMessageRelationEntity::getMsgId, messageId)
- .like(StrUtil.isNotBlank(name), SysUser::getName, name);
- return relationMapper.selectJoinPage(page, SysMessageReadVO.class, wrapper);
- }
+ /**
+ * 读取信息
+ *
+ * @param id id
+ * @return true/false
+ */
+ @Override
+ public Boolean readMessage(Long id) {
+ SysMessageRelationEntity relationEntity = new SysMessageRelationEntity();
+ relationEntity.setReadFlag(YesNoEnum.YES.getCode());
+ relationMapper.update(relationEntity, Wrappers.lambdaQuery().eq(SysMessageRelationEntity::getMsgId, id).eq(SysMessageRelationEntity::getUserId, SecurityUtils.getUser().getId()));
+ return Boolean.TRUE;
+ }
+ /**
+ * 获取信息
+ *
+ * @param id id
+ * @return messageVO
+ */
+ @Override
+ public SysMessageVO getMessage(Long id) {
+ SysMessageEntity messageEntity = baseMapper.selectById(id);
+ SysMessageVO SysMessageVO = new SysMessageVO();
+ BeanUtils.copyProperties(messageEntity, SysMessageVO);
+
+ // 全体通知
+ if (messageEntity.getAllFlag().equals(YesNoEnum.YES.getCode())) {
+ return SysMessageVO;
+ }
+ List userIdList = relationMapper.selectList(Wrappers.lambdaQuery().eq(SysMessageRelationEntity::getMsgId, id)).stream().map(SysMessageRelationEntity::getUserId).collect(Collectors.toList());
+
+ if (CollUtil.isNotEmpty(userIdList)) {
+ List orgNodeUserVoList = userMapper.selectBatchIds(userIdList).stream().map(user -> {
+ OrgTreeVO nodeUserVo = new OrgTreeVO();
+ nodeUserVo.setId(user.getUserId());
+ nodeUserVo.setAvatar(user.getAvatar());
+ nodeUserVo.setName(user.getName());
+ return nodeUserVo;
+ }).collect(Collectors.toList());
+
+ SysMessageVO.setUserList(orgNodeUserVoList);
+ }
+
+ return SysMessageVO;
+ }
+
+ /**
+ * 查询用户阅读情况
+ *
+ * @param page 分页
+ * @param messageId 消息ID
+ * @param name 姓名
+ * @return page
+ */
+ @Override
+ public Page pageUserRead(Page page, Long messageId, String name) {
+ MPJLambdaWrapper wrapper = new MPJLambdaWrapper().selectAll(SysMessageRelationEntity.class).select(SysUser::getUsername, SysUser::getName, SysUser::getUserId).select(SysMessageEntity::getTitle).leftJoin(SysUser.class, SysUser::getUserId, SysMessageRelationEntity::getUserId).leftJoin(SysMessageEntity.class, SysMessageEntity::getId, SysMessageRelationEntity::getMsgId).eq(SysMessageRelationEntity::getMsgId, messageId).like(StrUtil.isNotBlank(name), SysUser::getName, name);
+ return relationMapper.selectJoinPage(page, SysMessageReadVO.class, wrapper);
+ }
+
+ /**
+ * 发送手机验证码 TODO: 调用短信网关发送验证码,测试返回前端
+ *
+ * @param mobile mobile
+ * @return code
+ */
+ @Override
+ public R sendSmsCode(String mobile) {
+ List userList = userMapper.selectList(Wrappers.query().lambda().eq(SysUser::getPhone, mobile));
+
+ if (CollUtil.isEmpty(userList)) {
+ log.info("手机号未注册:{}", mobile);
+ return R.ok(Boolean.FALSE, MsgUtils.getMessage(ErrorCodes.SYS_APP_PHONE_UNREGISTERED, mobile));
+ }
+
+ String codeObj = redisTemplate.opsForValue().get(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + StringPool.AT + mobile);
+
+ if (StrUtil.isNotBlank(codeObj)) {
+ log.info("手机号验证码未过期:{},{}", mobile, codeObj);
+ return R.ok(Boolean.FALSE, MsgUtils.getMessage(ErrorCodes.SYS_APP_SMS_OFTEN));
+ }
+
+ String code = RandomUtil.randomNumbers(Integer.parseInt(SecurityConstants.CODE_SIZE));
+ log.debug("手机号生成验证码成功:{},{}", mobile, code);
+ redisTemplate.opsForValue().set(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + StringPool.AT + mobile, code, SecurityConstants.CODE_TIME, TimeUnit.SECONDS);
+
+ // 发送
+ return this.sendSms(MessageSmsDTO.builder().mobile(mobile).biz(SmsBizCodeEnum.SMS_NORMAL_CODE.getCode()).param(code).build());
+ }
+
+ /**
+ * 发送短信
+ *
+ * @param messageSmsDTO 消息 短信 DTO
+ * @return {@link R }
+ */
+ @Override
+ public R sendSms(MessageSmsDTO messageSmsDTO) {
+
+ // 根据业务编码获取短信通道配置
+ List configEntityList = sysSystemConfigMapper.selectList(Wrappers.lambdaQuery().eq(SysSystemConfigEntity::getConfigType, SystemConfigTypeEnum.SMS.getValue()).eq(SysSystemConfigEntity::getConfigStatus, YesNoEnum.YES.getCode()).eq(SysSystemConfigEntity::getConfigKey, messageSmsDTO.getBizCode()));
+ if (CollUtil.isEmpty(configEntityList)) {
+ return R.failed("发送失败,短信通道配置不存在");
+ }
+
+ SysSystemConfigEntity configEntity = configEntityList.get(0);
+ JSONObject configMap = JSONUtil.parseObj(configEntity.getConfigValue());
+
+ // 组装SMS4J 的发送对象
+ SmsBlend smsBlend = SmsFactory.getSmsBlend(messageSmsDTO.getBizCode());
+ if (Objects.isNull(smsBlend)) {
+ Class targetClass = Arrays.stream(SUPPORT_CONFIG_CLAZZ).filter(config -> config.getSimpleName().toLowerCase().contains(configMap.getStr(MessageSmsDTO.Fields.supplier))).findFirst().orElseThrow(() -> new CheckedException("发送失败,短信通道配置不存在"));
+ BaseConfig baseConfig = (BaseConfig) JSONUtil.toBean(configEntity.getConfigValue(), targetClass);
+
+ // 如果渠道扩展参数不为空则增加特性化参数
+ if (StrUtil.isNotBlank(configMap.getStr(MessageSmsDTO.Fields.extParams))) {
+ JSONObject extParams = configMap.getJSONObject(MessageSmsDTO.Fields.extParams);
+ BeanUtil.copyProperties(extParams, baseConfig);
+ }
+
+ baseConfig.setConfigId(configEntity.getConfigKey());
+ SmsFactory.createSmsBlend(baseConfig);
+ smsBlend = SmsFactory.getSmsBlend(messageSmsDTO.getBizCode());
+ }
+
+ // 异步发送短信
+ SysLogDTO sysLog = SysLogUtils.getSysLog();
+ Long start = System.currentTimeMillis();
+ sysLog.setTenantId(TenantContextHolder.getTenantId());
+ for (String mobile : messageSmsDTO.getMobiles()) {
+ smsBlend.sendMessageAsync(mobile, configMap.getStr(MessageSmsDTO.Fields.templateId), messageSmsDTO.getParams(), smsResponse -> {
+ log.info("发送短信结果:{}", smsResponse);
+ sysLog.setTitle(String.format("发送短信 %s", mobile));
+ sysLog.setLogType(LogTypeEnum.NORMAL.getType());
+ sysLog.setServiceId(SystemConfigTypeEnum.SMS.getValue());
+ sysLog.setParams(JacksonSensitiveFieldUtil.writeValueAsString(smsResponse));
+ sysLog.setTime(System.currentTimeMillis() - start);
+ sysLog.setException(JacksonSensitiveFieldUtil.writeValueAsString(smsResponse));
+ remoteLogService.saveLog(sysLog);
+ });
+ }
+ return R.ok();
+ }
+
+ /**
+ * 发送钩子消息
+ *
+ * @param messageHookDTO 消息挂钩 DTO
+ * @return {@link R }
+ */
+ @Override
+ public R sendHook(MessageHookDTO messageHookDTO) {
+
+ // 根据业务编码获取短信通道配置
+ List configEntityList = sysSystemConfigMapper.selectList(Wrappers.lambdaQuery()
+ .eq(SysSystemConfigEntity::getConfigType, SystemConfigTypeEnum.WEBHOOK.getValue())
+ .eq(SysSystemConfigEntity::getConfigStatus, YesNoEnum.YES.getCode())
+ .eq(SysSystemConfigEntity::getConfigKey, messageHookDTO.getBizCode()));
+ if (CollUtil.isEmpty(configEntityList)) {
+ return R.failed("发送失败,短信通道配置不存在");
+ }
+
+ SysSystemConfigEntity configEntity = configEntityList.get(0);
+ JSONObject configMap = JSONUtil.parseObj(configEntity.getConfigValue());
+ String supplier = configMap.getStr("supplier");
+
+ // 根据配置创建服务实例并注册
+ OaSender alarm = OaFactory.getSmsOaBlend(messageHookDTO.getBizCode());
+ if (Objects.isNull(alarm)) {
+ if (StrUtil.equalsAnyIgnoreCase(OaType.DING_TALK.toString(), supplier)) {
+ DingTalkConfig dingTalkConfig = new DingTalkConfig();
+ dingTalkConfig.setConfigId(messageHookDTO.getBizCode());
+ dingTalkConfig.setSign(configMap.getStr("sign"));
+ dingTalkConfig.setTokenId(configMap.getStr("tokenId"));
+ OaFactory.createAndRegisterOaSender(dingTalkConfig);
+ }
+ if (StrUtil.equalsAnyIgnoreCase(OaType.BYTE_TALK.toString(), supplier)) {
+ ByteTalkConfig byteTalkConfig = new ByteTalkConfig();
+ byteTalkConfig.setConfigId(messageHookDTO.getBizCode());
+ byteTalkConfig.setSign(configMap.getStr("sign"));
+ byteTalkConfig.setTokenId(configMap.getStr("tokenId"));
+ OaFactory.createAndRegisterOaSender(byteTalkConfig);
+ }
+
+
+ if (StrUtil.equalsAnyIgnoreCase(OaType.WE_TALK.toString(), supplier)) {
+ WeTalkConfig weTalkConfig = new WeTalkConfig();
+ weTalkConfig.setConfigId(messageHookDTO.getBizCode());
+ weTalkConfig.setSign(configMap.getStr("sign"));
+ weTalkConfig.setTokenId(configMap.getStr("tokenId"));
+ OaFactory.createAndRegisterOaSender(weTalkConfig);
+ }
+ alarm = OaFactory.getSmsOaBlend(messageHookDTO.getBizCode());
+ }
+
+
+ Request request = new Request();
+ request.setContent(messageHookDTO.getMessageContent());
+ request.setTitle(messageHookDTO.getMessageTitle());
+ request.setMessageUrl(messageHookDTO.getMessageUrl());
+ request.setPicUrl(messageHookDTO.getPicUrl());
+ request.setIsNoticeAll(messageHookDTO.isNoticeAll());
+ request.setPhoneList(messageHookDTO.getPhoneList());
+
+ SysLogDTO sysLog = SysLogUtils.getSysLog();
+ sysLog.setTenantId(TenantContextHolder.getTenantId());
+ Long start = System.currentTimeMillis();
+ alarm.senderAsync(request, MessageType.valueOf(String.format("%s_%s", supplier, messageHookDTO.getMessageType()).toUpperCase()), response -> {
+ log.info("发送Hook结果:{}", response);
+ sysLog.setTitle(String.format("发送Hook %s", messageHookDTO.getBizCode()));
+ sysLog.setLogType(LogTypeEnum.NORMAL.getType());
+ sysLog.setServiceId(SystemConfigTypeEnum.WEBHOOK.getValue());
+ sysLog.setParams(JacksonSensitiveFieldUtil.writeValueAsString(messageHookDTO));
+ sysLog.setTime(System.currentTimeMillis() - start);
+ sysLog.setException(JacksonSensitiveFieldUtil.writeValueAsString(response));
+ remoteLogService.saveLog(sysLog);
+ });
+ return R.ok();
+ }
+
+ /**
+ * 发送邮件
+ *
+ * @param messageEmailDTO 留言内容 电子邮件 DTO
+ * @return {@link R }
+ */
+ @SneakyThrows
+ @Override
+ public R sendEmail(MessageEmailDTO messageEmailDTO) {
+ // 根据业务编码获取短信通道配置
+ List configEntityList = sysSystemConfigMapper.selectList(Wrappers.lambdaQuery()
+ .eq(SysSystemConfigEntity::getConfigType, SystemConfigTypeEnum.EMAIL.getValue())
+ .eq(SysSystemConfigEntity::getConfigStatus, YesNoEnum.YES.getCode()).
+ eq(SysSystemConfigEntity::getConfigKey, messageEmailDTO.getBizCode()));
+ if (CollUtil.isEmpty(configEntityList)) {
+ return R.failed("发送失败,通道配置不存在");
+ }
+ SysSystemConfigEntity configEntity = configEntityList.get(0);
+ JSONObject configMap = JSONUtil.parseObj(configEntity.getConfigValue());
+
+
+ List tempFileList = new ArrayList<>();
+ if (CollUtil.isNotEmpty(messageEmailDTO.getAttachmentList())) {
+ TenantContextHolder.setTenantSkip();
+ for (String fileName : messageEmailDTO.getAttachmentList()) {
+ SysFile sysFile = fileMapper.selectOne(Wrappers.lambdaQuery().eq(SysFile::getFileName, fileName));
+ S3Object s3Object = fileTemplate.getObject(sysFile.getBucketName(), sysFile.getDir(), fileName);
+ File file = FileUtil.file(FileUtil.getTmpDirPath(), sysFile.getOriginal());
+ tempFileList.add(file);
+ IoUtil.copy(s3Object.getObjectContent(), FileUtil.getOutputStream(file));
+ }
+ }
+
+ MailAccount account = new MailAccount();
+ account.setHost(configMap.getStr("smtpServer"));
+ account.setPort(configMap.getInt("port"));
+ account.setAuth(configMap.getBool("isAuth"));
+ account.setSslEnable(configMap.getBool("isSSL"));
+ account.setFrom(configMap.getStr("username"));
+ account.setUser(configMap.getStr("username"));
+ account.setPass(configMap.getStr("password"));
+
+ // 渲染模板
+ TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig());
+ Template template = engine.getTemplate(configMap.getStr("html"));
+ String result = template.render(messageEmailDTO.getHtmlValues());
+
+ Long start = System.currentTimeMillis();
+ MailUtil.send(account, messageEmailDTO.getMailAddress(),
+ messageEmailDTO.getCcList(),
+ messageEmailDTO.getBccList(),
+ messageEmailDTO.getTitle(), result, true, tempFileList.toArray(new File[0]));
+ Long end = System.currentTimeMillis();
+ // 写入日志
+ SysLogDTO sysLog = SysLogUtils.getSysLog();
+ sysLog.setTitle(String.format("发送邮件 %s", messageEmailDTO.getTitle()));
+ sysLog.setLogType(LogTypeEnum.NORMAL.getType());
+ sysLog.setServiceId(SystemConfigTypeEnum.EMAIL.getValue());
+ sysLog.setParams(JacksonSensitiveFieldUtil.writeValueAsString(messageEmailDTO));
+ sysLog.setTenantId(TenantContextHolder.getTenantId());
+ sysLog.setTime(end - start);
+ remoteLogService.saveLog(sysLog);
+ // 删除临时文件
+ tempFileList.forEach(FileUtil::del);
+ return R.ok();
+ }
}
diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysSystemConfigServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysSystemConfigServiceImpl.java
new file mode 100644
index 000000000..fa032e8af
--- /dev/null
+++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysSystemConfigServiceImpl.java
@@ -0,0 +1,118 @@
+package com.pig4cloud.pigx.admin.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ReflectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.pig4cloud.pigx.admin.api.constant.SystemConfigTypeEnum;
+import com.pig4cloud.pigx.admin.api.entity.SysSystemConfigEntity;
+import com.pig4cloud.pigx.admin.mapper.SysSystemConfigMapper;
+import com.pig4cloud.pigx.admin.service.SysSystemConfigService;
+import com.pig4cloud.pigx.common.core.util.R;
+import com.pig4cloud.pigx.common.log.util.JacksonSensitiveFieldUtil;
+import lombok.SneakyThrows;
+import org.dromara.oa.api.OaSender;
+import org.dromara.oa.core.provider.factory.OaFactory;
+import org.dromara.sms4j.core.factory.SmsFactory;
+import org.springframework.stereotype.Service;
+
+import java.lang.reflect.Field;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * SYS 系统配置服务实现
+ *
+ * @author lengleng
+ * @date 2024/07/18
+ */
+@Service
+public class SysSystemConfigServiceImpl extends ServiceImpl implements SysSystemConfigService {
+
+ private final SysMessageServiceImpl sysMessageServiceImpl;
+
+ public SysSystemConfigServiceImpl(SysMessageServiceImpl sysMessageServiceImpl) {
+ this.sysMessageServiceImpl = sysMessageServiceImpl;
+ }
+
+ /**
+ * 列出系统配置
+ *
+ * @param query 查询
+ * @return {@link R }
+ */
+ @Override
+ public R listSystemConfig(SysSystemConfigEntity query) {
+ List configEntityList = baseMapper.selectList(Wrappers.query(query));
+ configEntityList.stream().forEach(systemConfig -> {
+ if (StrUtil.isNotBlank(systemConfig.getConfigValue())) {
+ systemConfig.setConfigValue(JacksonSensitiveFieldUtil.readStr(systemConfig.getConfigValue()));
+ }
+ });
+
+ return R.ok(configEntityList);
+ }
+
+ /**
+ * 系统配置
+ *
+ * @param page 页
+ * @param sysSystemConfig sys 系统配置
+ * @return {@link R }
+ */
+ @Override
+ public R pageSystemConfig(Page page, SysSystemConfigEntity sysSystemConfig) {
+ LambdaQueryWrapper wrapper = Wrappers.lambdaQuery();
+ wrapper.eq(StrUtil.isNotBlank(sysSystemConfig.getConfigType()), SysSystemConfigEntity::getConfigType, sysSystemConfig.getConfigType());
+ wrapper.like(StrUtil.isNotBlank(sysSystemConfig.getConfigName())
+ , SysSystemConfigEntity::getConfigName, sysSystemConfig.getConfigName());
+ Page pageResult = baseMapper.selectPage(page, wrapper);
+ pageResult.getRecords().forEach(systemConfig -> {
+ if (StrUtil.isNotBlank(systemConfig.getConfigValue())) {
+ systemConfig.setConfigValue(JacksonSensitiveFieldUtil.readStr(systemConfig.getConfigValue()));
+ }
+ });
+
+ return R.ok(pageResult);
+ }
+
+ /**
+ * 更新系统配置
+ *
+ * @param sysSystemConfig sys 系统配置
+ * @return {@link R }
+ */
+ @Override
+ @SneakyThrows
+ public R updateSystemConfig(SysSystemConfigEntity sysSystemConfig) {
+ // 更新configValue ,如果 accessSecret,tokenId,sign 属性为空,则不更新以上属性
+ SysSystemConfigEntity configEntity = baseMapper.selectById(sysSystemConfig.getId());
+ JSONObject oldValue = JSONUtil.parseObj(configEntity.getConfigValue());
+ JSONObject newValue = JSONUtil.parseObj(sysSystemConfig.getConfigValue());
+ BeanUtil.copyProperties(newValue, oldValue);
+
+ sysSystemConfig.setConfigValue(JSONUtil.toJsonPrettyStr(oldValue));
+
+ baseMapper.updateById(sysSystemConfig);
+ // 更新短信配置
+ if (SystemConfigTypeEnum.SMS.getValue().equals(sysSystemConfig.getConfigType())
+ && Objects.nonNull(SmsFactory.getSmsBlend(sysSystemConfig.getConfigKey()))) {
+ SmsFactory.unregister(sysSystemConfig.getConfigKey());
+ }
+
+ if (SystemConfigTypeEnum.WEBHOOK.getValue().equals(sysSystemConfig.getConfigType())) {
+ // 更新webhook配置, 官方工具类没有提供清除方法,只能通过反射清除
+ Field configsField = ReflectUtil.getField(OaFactory.class, "CONFIGS");
+ configsField.setAccessible(true);
+ Map configs = (Map) configsField.get(null);
+ configs.clear();
+ }
+ return R.ok();
+ }
+}
diff --git a/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysSystemConfigMapper.xml b/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysSystemConfigMapper.xml
new file mode 100644
index 000000000..96931db14
--- /dev/null
+++ b/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysSystemConfigMapper.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pigx-visual/pigx-codegen/pom.xml b/pigx-visual/pigx-codegen/pom.xml
index d75e07227..03fa294d4 100755
--- a/pigx-visual/pigx-codegen/pom.xml
+++ b/pigx-visual/pigx-codegen/pom.xml
@@ -159,12 +159,10 @@
org.apache.velocity
velocity-engine-core
- ${velocity.version}
org.apache.velocity.tools
velocity-tools-generic
- ${velocity.tool.version}
diff --git a/pom.xml b/pom.xml
index bdac12708..2fbf3720c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -51,8 +51,6 @@
2.0.0
3.0.0
3.0.5
- 2.3
- 3.1
3.0.5
2.12.6
2.3.5