Compare commits

..
49 Commits
Author SHA1 Message Date
timi 2b4089ef59 Merge pull request 'v1.0.38' (#50) from dev into master
Reviewed-on: #50
2026-09-09 17:33:25 +00:00
timi 20c3e1f422 Merge pull request 'v1.0.37' (#49) from dev into master
Reviewed-on: #49
2026-09-09 06:21:55 +00:00
timi 3b19d9e930 Merge pull request 'v1.0.36' (#48) from dev into master
Reviewed-on: #48
2026-09-08 17:52:47 +00:00
timi 5fd11e9caf Merge pull request 'v1.0.35' (#47) from dev into master
Reviewed-on: #47
2026-09-07 17:06:28 +00:00
timi 0b98dcdfe9 Merge pull request 'v1.0.34' (#46) from dev into master
Reviewed-on: #46
2026-09-07 15:11:06 +00:00
timi b373cbbe46 Merge pull request 'v1.0.33' (#45) from dev into master
Reviewed-on: #45
2026-09-07 09:40:39 +00:00
timi acd97c7b9b Merge pull request 'v1.0.32' (#44) from dev into master
Reviewed-on: #44
2026-09-07 08:42:29 +00:00
timi 118bdb1666 Merge pull request 'v1.0.31' (#43) from dev into master
Reviewed-on: #43
2026-09-07 07:40:03 +00:00
timi 944de228f7 Merge pull request 'v1.0.30' (#42) from dev into master
Reviewed-on: #42
2026-09-01 17:44:48 +00:00
timi 25c9cd4dfc Merge pull request 'v1.0.30' (#41) from dev into master
Reviewed-on: #41
2026-09-01 17:42:44 +00:00
timi 882cd226ec Merge pull request 'v1.0.30' (#40) from dev into master
Reviewed-on: #40
2026-09-01 17:38:50 +00:00
timi feb4d7af66 Merge pull request 'v1.0.28' (#38) from dev into master
Reviewed-on: #38
2026-08-30 15:51:37 +00:00
timi d75ab1ed5f Merge pull request 'v1.0.27' (#37) from dev into master
Reviewed-on: #37
2026-08-29 17:49:23 +00:00
timi a501eb7443 Merge pull request 'v1.0.26' (#36) from dev into master
Reviewed-on: #36
2026-08-28 16:52:15 +00:00
timi 19941d9480 Merge pull request 'v1.0.25' (#35) from dev into master
Reviewed-on: #35
2026-08-23 17:50:25 +00:00
timi cd3d522d4f Merge pull request 'v1.0.24' (#34) from dev into master
Reviewed-on: #34
2026-08-22 09:56:13 +00:00
timi 181c5078e9 Merge pull request 'v1.0.23' (#33) from dev into master
Reviewed-on: #33
2026-08-22 09:51:37 +00:00
timi e97f46e6b4 Merge pull request 'v1.0.22' (#32) from dev into master
Reviewed-on: #32
2026-08-21 17:31:33 +00:00
timi c0f89deb83 Merge pull request 'v1.0.22' (#31) from dev into master
Reviewed-on: #31
2026-08-21 17:28:32 +00:00
timi ce695463d3 Merge pull request 'v1.0.21' (#30) from dev into master
Reviewed-on: #30
2026-08-21 07:29:34 +00:00
timi 83c683d473 Merge pull request 'v1.0.20' (#29) from dev into master
Reviewed-on: #29
2026-08-21 07:25:32 +00:00
timi 9555474b0b Merge pull request 'v1.0.19' (#28) from dev into master
Reviewed-on: #28
2026-08-21 05:52:36 +00:00
timi a150f9e017 Merge pull request 'v1.0.18' (#27) from dev into master
Reviewed-on: #27
2026-08-20 17:40:22 +00:00
timi ecd2fa1c33 Merge pull request 'v1.0.17' (#26) from dev into master
Reviewed-on: #26
2026-08-19 17:30:35 +00:00
timi e3236d262d Merge pull request 'v1.0.16' (#25) from dev into master
Reviewed-on: #25
2026-08-16 03:37:08 +00:00
timi c8e2e16ba5 Merge pull request 'v1.0.15' (#24) from dev into master
Reviewed-on: #24
2026-08-15 17:49:51 +00:00
timi 99b44faf09 Merge pull request 'v1.0.15' (#23) from dev into master
Reviewed-on: #23
2026-08-15 17:45:26 +00:00
timi b3e3cbf84b Merge pull request 'v1.0.14' (#22) from dev into master
Reviewed-on: #22
2026-08-14 17:31:11 +00:00
timi 0aee11d824 Merge pull request 'v1.0.14' (#21) from dev into master
Reviewed-on: #21
2026-08-14 17:26:10 +00:00
timi fcf358a768 Merge pull request 'v1.0.13' (#20) from dev into master
Reviewed-on: #20
2026-08-13 09:52:26 +00:00
timi 619369104c Merge pull request 'v1.0.12' (#19) from dev into master
Reviewed-on: #19
2026-08-12 17:02:43 +00:00
timi 4f1408b9d0 Merge pull request 'v1.0.11' (#18) from dev into master
Reviewed-on: #18
2026-08-11 16:49:08 +00:00
timi 029eea70cc Merge pull request 'v1.0.10' (#17) from dev into master
Reviewed-on: #17
2026-08-11 16:45:36 +00:00
timi 22b1e65385 Merge pull request 'v1.0.9' (#16) from dev into master
Reviewed-on: #16
2026-08-11 16:01:10 +00:00
timi 2170c48763 Merge pull request 'v1.0.8' (#15) from dev into master
Reviewed-on: #15
2026-08-03 16:36:19 +00:00
timi c2d1c48aae Merge pull request 'v0.0.18' (#14) from dev into master
Reviewed-on: #14
2026-08-03 11:59:20 +00:00
timi e14958c643 Merge pull request 'v0.0.18' (#13) from dev into master
Reviewed-on: #13
2026-08-03 11:58:16 +00:00
timi da288338cd Merge pull request 'v1.0.7' (#12) from dev into master
Reviewed-on: #12
2026-08-01 09:34:18 +00:00
timi ea430f2468 Merge pull request 'v1.0.6' (#11) from dev into master
Reviewed-on: #11
2026-08-01 09:03:48 +00:00
timi f76f79744a Merge pull request 'v1.0.5' (#10) from dev into master
Reviewed-on: #10
2026-08-01 08:52:52 +00:00
timi 19daaff907 Merge pull request 'v1.0.4' (#9) from dev into master
Reviewed-on: #9
2026-08-01 03:13:00 +00:00
timi db94d8f932 Merge pull request 'v1.0.3' (#8) from dev into master
Reviewed-on: #8
2026-07-31 17:19:48 +00:00
timi 53618fe362 Merge pull request 'v1.0.3' (#7) from dev into master
Reviewed-on: #7
2026-07-31 17:13:37 +00:00
timi 523edffc4e Merge pull request 'v1.0.2' (#6) from dev into master
Reviewed-on: #6
2026-04-13 10:28:11 +00:00
timi c7ddb1a8b0 Merge pull request 'v1.0.1' (#5) from dev into master
Reviewed-on: #5
2026-04-12 16:17:02 +00:00
timi 45c9fc814a Merge pull request 'v1.0.0' (#4) from dev into master
Reviewed-on: #4
2026-04-09 05:16:04 +00:00
timi 407dc13ac4 Merge pull request 'v1.0.0' (#3) from dev into master
Reviewed-on: #3
2026-04-09 04:09:16 +00:00
timi 0c06bf16c2 Merge pull request 'v1.0.0' (#2) from dev into master
Reviewed-on: #2
2026-04-09 04:03:43 +00:00
timi 1db39e77d3 Merge pull request 'v1.0.0' (#1) from dev into master
Reviewed-on: #1
2026-04-08 08:48:12 +00:00
18 changed files with 151 additions and 243 deletions
+1 -1
View File
@@ -11,7 +11,7 @@
<groupId>com.imyeyu.timiserverapi</groupId> <groupId>com.imyeyu.timiserverapi</groupId>
<artifactId>TimiServerAPI</artifactId> <artifactId>TimiServerAPI</artifactId>
<version>1.0.39</version> <version>1.0.38</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>TimiServerAPI</name> <name>TimiServerAPI</name>
<description>imyeyu.com API</description> <description>imyeyu.com API</description>
@@ -15,12 +15,8 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
/** /**
* *
* *
@@ -30,30 +26,11 @@ import java.util.Map;
@Slf4j @Slf4j
@RestController @RestController
@RequiredArgsConstructor @RequiredArgsConstructor
@RequestMapping("/setting") @RequestMapping("/system/setting")
public class SettingController { public class SettingController {
private final SettingService service; private final SettingService service;
/**
* 查询公开配置映射
*
* @param bizType 业务类型
* @param bizId 业务 ID,可为空
* @param code 配置代码列表,可为空
* @return 公开配置映射
*/
@JsonView(ResponseView.Public.class)
@RequestRateLimit
@RequestMapping("/map")
public Map<String, Setting> map(
@RequestParam String bizType,
@RequestParam(required = false) String bizId,
@RequestParam(required = false) List<String> code
) {
return service.mapPublic(bizType, bizId, code);
}
/** /**
* 查询配置列表 * 查询配置列表
* *
@@ -20,11 +20,11 @@ public class Notify extends UUIDEntity {
/** 业务类型 */ /** 业务类型 */
private String bizType; private String bizType;
/** 业务提醒类型 */ /** 提醒业务类型 */
private String bizRemindedType; private String bizRemindedType;
/** 业务提醒查重键 */ /** 提醒业务 ID */
private String bizRemindedKey; private String bizRemindedId;
/** 参数 */ /** 参数 */
private String args; private String args;
@@ -2,8 +2,9 @@ package com.imyeyu.api.modules.common.mapper;
import com.imyeyu.api.modules.common.entity.Notify; import com.imyeyu.api.modules.common.entity.Notify;
import com.imyeyu.api.modules.common.vo.NotifyManagementItem; import com.imyeyu.api.modules.common.vo.NotifyManagementItem;
import com.imyeyu.spring.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import com.imyeyu.spring.mapper.BaseMapper;
import java.util.List; import java.util.List;
@@ -15,8 +16,9 @@ import java.util.List;
*/ */
public interface NotifyMapper extends BaseMapper<Notify, String> { public interface NotifyMapper extends BaseMapper<Notify, String> {
/// 原子创建业务提醒 /// 查询业务提醒是否已创建
int insertIfAbsent(Notify notify); @Select("SELECT EXISTS (SELECT 1 FROM `notify` WHERE `biz_type` = #{bizType} AND `biz_reminded_type` = #{bizRemindedType} AND `biz_reminded_id` = #{bizRemindedId} AND `deleted_at` IS NULL)")
boolean existsByBizReminded(@Param("bizType") String bizType, @Param("bizRemindedType") String bizRemindedType, @Param("bizRemindedId") String bizRemindedId);
/// 分页查询管理端通知 /// 分页查询管理端通知
/// ///
@@ -3,8 +3,6 @@ package com.imyeyu.api.modules.common.mapper;
import com.imyeyu.api.modules.common.entity.Setting; import com.imyeyu.api.modules.common.entity.Setting;
import com.imyeyu.spring.mapper.BaseMapper; import com.imyeyu.spring.mapper.BaseMapper;
import java.util.List;
/** /**
* 系统配置 * 系统配置
* *
@@ -12,6 +10,4 @@ import java.util.List;
* @since 2021-07-20 22:26 * @since 2021-07-20 22:26
*/ */
public interface SettingMapper extends BaseMapper<Setting, String> { public interface SettingMapper extends BaseMapper<Setting, String> {
List<Setting> selectPublicByQuery(String bizType, String bizId, List<String> codeList);
} }
@@ -14,10 +14,13 @@ import com.imyeyu.spring.service.BaseService;
*/ */
public interface NotifyService extends BaseService<Notify, String> { public interface NotifyService extends BaseService<Notify, String> {
/// 原子创建业务提醒,重复查重键不会创建通知详情 /// 查询业务提醒是否已创建
/// ///
/// @param notify 通知 /// @param bizType 业务类型
void createIfAbsent(Notify notify); /// @param bizRemindedType 被提醒业务类型
/// @param bizRemindedId 被提醒业务 ID
/// @return true 为已创建
boolean existsByBizReminded(String bizType, String bizRemindedType, String bizRemindedId);
/// 分页查询当前用户创建的通知 /// 分页查询当前用户创建的通知
/// ///
@@ -7,7 +7,6 @@ import com.imyeyu.java.TimiJava;
import com.imyeyu.spring.service.BaseService; import com.imyeyu.spring.service.BaseService;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 配置服务 * 配置服务
@@ -25,16 +24,6 @@ public interface SettingService extends BaseService<Setting, String> {
List<Setting> listByBizId(String bizType, String bizId); List<Setting> listByBizId(String bizType, String bizId);
/**
* 查询公开配置映射
*
* @param bizType 业务类型
* @param bizId 业务 ID,可为空
* @param code 配置代码列表,可为空
* @return 公开配置映射
*/
Map<String, Setting> mapPublic(String bizType, String bizId, List<String> code);
default List<Setting> listBySettingSupport(SettingSupport settingSupport) { default List<Setting> listBySettingSupport(SettingSupport settingSupport) {
String bizType = settingSupport.getClass().getSimpleName().toUpperCase(); String bizType = settingSupport.getClass().getSimpleName().toUpperCase();
return listByBizId(bizType, settingSupport.getId()); return listByBizId(bizType, settingSupport.getId());
@@ -7,8 +7,9 @@ import com.imyeyu.api.modules.common.mapper.NotifyMapper;
import com.imyeyu.api.modules.common.service.NotifyDetailService; import com.imyeyu.api.modules.common.service.NotifyDetailService;
import com.imyeyu.api.modules.common.service.NotifyService; import com.imyeyu.api.modules.common.service.NotifyService;
import com.imyeyu.api.modules.common.vo.NotifyManagementItem; import com.imyeyu.api.modules.common.vo.NotifyManagementItem;
import com.imyeyu.api.modules.system.audit.AuditOperation; import com.imyeyu.api.modules.system.entity.Logger;
import com.imyeyu.api.modules.system.audit.OperationAudit; import com.imyeyu.api.modules.system.service.LoggerService;
import com.imyeyu.api.modules.user.service.UserLoginService;
import com.imyeyu.java.TimiJava; import com.imyeyu.java.TimiJava;
import com.imyeyu.java.bean.timi.TimiCode; import com.imyeyu.java.bean.timi.TimiCode;
import com.imyeyu.java.bean.timi.TimiException; import com.imyeyu.java.bean.timi.TimiException;
@@ -16,13 +17,12 @@ import com.imyeyu.spring.bean.Page;
import com.imyeyu.spring.bean.PageResult; import com.imyeyu.spring.bean.PageResult;
import com.imyeyu.spring.mapper.BaseMapper; import com.imyeyu.spring.mapper.BaseMapper;
import com.imyeyu.spring.service.AbstractEntityService; import com.imyeyu.spring.service.AbstractEntityService;
import com.imyeyu.utils.Time;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.List; import java.util.List;
import java.util.UUID;
/** /**
* 通知服务实现 * 通知服务实现
@@ -30,10 +30,13 @@ import java.util.UUID;
* @author 夜雨 * @author 夜雨
* @since 2026-05-13 14:46 * @since 2026-05-13 14:46
*/ */
@Slf4j
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
public class NotifyServiceImplement extends AbstractEntityService<Notify, String> implements NotifyService { public class NotifyServiceImplement extends AbstractEntityService<Notify, String> implements NotifyService {
private final LoggerService loggerService;
private final UserLoginService userLoginService;
private final NotifyDetailService detailService; private final NotifyDetailService detailService;
private final NotifyMapper mapper; private final NotifyMapper mapper;
@@ -43,54 +46,44 @@ public class NotifyServiceImplement extends AbstractEntityService<Notify, String
return mapper; return mapper;
} }
@Override
public boolean existsByBizReminded(String bizType, String bizRemindedType, String bizRemindedId) {
return mapper.existsByBizReminded(bizType, bizRemindedType, bizRemindedId);
}
/// 创建通知并级联创建通知详情 /// 创建通知并级联创建通知详情
/// ///
/// @param notify 通知 /// @param notify 通知
@OperationAudit(AuditOperation.COMMON_NOTIFY_CREATE)
@Transactional(TimiServerDBConfig.ROLLBACKER) @Transactional(TimiServerDBConfig.ROLLBACKER)
@Override @Override
public void create(Notify notify) { public void create(Notify notify) {
prepareCreate(notify); Logger logger = new Logger(Logger.Module.COMMON, "COMMON_NOTIFY_CREATE");
super.create(notify); try {
createDetails(notify);
}
/// 原子创建业务提醒并级联创建通知详情
///
/// @param notify 通知
@OperationAudit(AuditOperation.COMMON_NOTIFY_CREATE)
@Transactional(TimiServerDBConfig.ROLLBACKER)
@Override
public void createIfAbsent(Notify notify) {
prepareCreate(notify);
if (mapper.insertIfAbsent(notify) == 0) {
return;
}
createDetails(notify);
}
/// 校验并补全通知创建字段
///
/// @param notify 通知
private void prepareCreate(Notify notify) {
TimiException.required(notify, "未找到通知"); TimiException.required(notify, "未找到通知");
TimiException.required(notify.getDetailList(), "未找到通知详情列表"); TimiException.required(notify.getDetailList(), "未找到通知详情列表");
notify.setId(TimiJava.defaultIfEmpty(notify.getId(), UUID.randomUUID().toString()));
notify.setCreatedBy(TimiJava.defaultIfEmpty(notify.getCreatedBy(), TimiJava.ZERO_UUID));
notify.setCreatedAt(TimiJava.defaultIfNull(notify.getCreatedAt(), Time.now()));
notify.setUpdatedAt(null);
notify.setDeletedAt(null);
}
/// 创建通知详情 notify.setCreatedBy(TimiJava.defaultIfEmpty(notify.getCreatedBy(), TimiJava.ZERO_UUID));
/// super.create(notify);
/// @param notify 通知
private void createDetails(Notify notify) {
for (NotifyDetail detail : notify.getDetailList()) { for (NotifyDetail detail : notify.getDetailList()) {
detail.setNotifyId(notify.getId()); detail.setNotifyId(notify.getId());
detail.setSendFrom(TimiJava.defaultIfEmpty(detail.getSendFrom(), TimiJava.ZERO_UUID)); detail.setSendFrom(TimiJava.defaultIfEmpty(detail.getSendFrom(), TimiJava.ZERO_UUID));
detailService.create(detail); detailService.create(detail);
} }
logger.setLevel(Logger.Level.INFO);
logger.setResult(notify.getId());
} catch (TimiException e) {
logger.setLevel(Logger.Level.WARN);
logger.setException(e.getMessage());
throw e;
} catch (Exception e) {
logger.setLevel(Logger.Level.ERROR);
logger.setException(TimiJava.serializeThrowable(e));
log.error("创建通知失败", e);
throw new TimiException(TimiCode.ERROR, "创建通知失败", e);
} finally {
loggerService.create(logger);
}
} }
/// 分页查询当前用户创建的通知 /// 分页查询当前用户创建的通知
@@ -127,8 +120,6 @@ public class NotifyServiceImplement extends AbstractEntityService<Notify, String
/// @param notifyId 通知 ID /// @param notifyId 通知 ID
/// @param userId 用户 ID /// @param userId 用户 ID
@Override @Override
@Transactional(TimiServerDBConfig.ROLLBACKER)
@OperationAudit(AuditOperation.COMMON_NOTIFY_DELETE)
public void deleteManagement(String notifyId, String userId) { public void deleteManagement(String notifyId, String userId) {
getManagement(notifyId, userId); getManagement(notifyId, userId);
delete(notifyId); delete(notifyId);
@@ -139,7 +130,6 @@ public class NotifyServiceImplement extends AbstractEntityService<Notify, String
/// @param notifyId 通知 ID /// @param notifyId 通知 ID
/// @param userId 用户 ID /// @param userId 用户 ID
@Override @Override
@Transactional(TimiServerDBConfig.ROLLBACKER)
public void cancelManagement(String notifyId, String userId) { public void cancelManagement(String notifyId, String userId) {
getManagement(notifyId, userId); getManagement(notifyId, userId);
cancel(notifyId); cancel(notifyId);
@@ -148,10 +138,11 @@ public class NotifyServiceImplement extends AbstractEntityService<Notify, String
/// 删除通知并级联软删除通知详情 /// 删除通知并级联软删除通知详情
/// ///
/// @param notifyId 通知 ID /// @param notifyId 通知 ID
@OperationAudit(AuditOperation.COMMON_NOTIFY_DELETE)
@Transactional(TimiServerDBConfig.ROLLBACKER) @Transactional(TimiServerDBConfig.ROLLBACKER)
@Override @Override
public void delete(String notifyId) { public void delete(String notifyId) {
Logger logger = new Logger(Logger.Module.COMMON, "COMMON_NOTIFY_DELETE");
try {
TimiException.required(notifyId, "未找到通知 ID"); TimiException.required(notifyId, "未找到通知 ID");
TimiException.required(get(notifyId), "未找到通知"); TimiException.required(get(notifyId), "未找到通知");
List<NotifyDetail> detailList = detailService.listByNotifyId(notifyId); List<NotifyDetail> detailList = detailService.listByNotifyId(notifyId);
@@ -159,6 +150,20 @@ public class NotifyServiceImplement extends AbstractEntityService<Notify, String
detailService.delete(detail.getId()); detailService.delete(detail.getId());
} }
super.delete(notifyId); super.delete(notifyId);
logger.setLevel(Logger.Level.INFO);
logger.setResult(notifyId);
} catch (TimiException e) {
logger.setLevel(Logger.Level.WARN);
logger.setException(e.getMessage());
throw e;
} catch (Exception e) {
logger.setLevel(Logger.Level.ERROR);
logger.setException(TimiJava.serializeThrowable(e));
log.error("删除通知失败", e);
throw new TimiException(TimiCode.ERROR, "删除通知失败", e);
} finally {
loggerService.create(logger);
}
} }
/// 取消通知中尚未成功发送的通知详情 /// 取消通知中尚未成功发送的通知详情
@@ -17,8 +17,6 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/** /**
* 系统配置服务实现 * 系统配置服务实现
@@ -55,12 +53,6 @@ public class SettingServiceImplement extends AbstractEntityService<Setting, Stri
return mapper.selectAllByExample(example); return mapper.selectAllByExample(example);
} }
@Override
public Map<String, Setting> mapPublic(String bizType, String bizId, List<String> code) {
TimiException.required(bizType, "not found bizType");
return mapper.selectPublicByQuery(bizType, bizId, code).stream().collect(Collectors.toMap(Setting::getCode, Function.identity()));
}
@Transactional(TimiServerDBConfig.ROLLBACKER) @Transactional(TimiServerDBConfig.ROLLBACKER)
@Override @Override
public void updateByBizId(String bizType, String bizId, List<Setting> list) { public void updateByBizId(String bizType, String bizId, List<Setting> list) {
@@ -55,5 +55,5 @@ public interface GaoCustomerMapper extends BaseMapper<GaoCustomer, String> {
/// @param customerId 客户 ID /// @param customerId 客户 ID
/// @param delta 变化量 /// @param delta 变化量
@Update("UPDATE `gao_customer` SET `invited_count` = GREATEST(IFNULL(`invited_count`, 0) + #{delta}, 0), `updated_at` = " + UNIX_TIME + " WHERE `id` = #{customerId}" + NOT_DELETE) @Update("UPDATE `gao_customer` SET `invited_count` = GREATEST(IFNULL(`invited_count`, 0) + #{delta}, 0), `updated_at` = " + UNIX_TIME + " WHERE `id` = #{customerId}" + NOT_DELETE)
void updateInvitedCountDelta(String customerId, Long delta); void updateInvitedCountDelta(@Param("customerId") String customerId, @Param("delta") Long delta);
} }
@@ -103,17 +103,20 @@ public class GaoOrderReminderServiceImplement implements GaoOrderReminderService
log.warn("GAO 订单提醒跳过不存在的店长用户: storeId[{}], userId[{}]", storeId, manager.getUserId()); log.warn("GAO 订单提醒跳过不存在的店长用户: storeId[{}], userId[{}]", storeId, manager.getUserId());
continue; continue;
} }
String remindedKey = "%s:%s:%s:%s".formatted(LocalDate.now(ZoneId.of(ZONE_ID)), storeId, manager.getUserId(), reminderType); String remindedId = "%s:%s:%s:%s".formatted(LocalDate.now(ZoneId.of(ZONE_ID)), storeId, manager.getUserId(), reminderType);
if (notifyService.existsByBizReminded(NOTIFY_BIZ_TYPE, reminderType, remindedId)) {
continue;
}
long sendAt = Time.now(); long sendAt = Time.now();
Notify notify = new Notify(); Notify notify = new Notify();
notify.setBizType(NOTIFY_BIZ_TYPE); notify.setBizType(NOTIFY_BIZ_TYPE);
notify.setBizRemindedType(reminderType); notify.setBizRemindedType(reminderType);
notify.setBizRemindedKey(remindedKey); notify.setBizRemindedId(remindedId);
notify.setDetailList(List.of( notify.setDetailList(List.of(
createInternalDetail(manager.getUserId(), content, sendAt), createInternalDetail(manager.getUserId(), content, sendAt),
createSmsDetail(user.getPhoneNo(), customerNames, action, content, sendAt) createSmsDetail(user.getPhoneNo(), customerNames, action, content, sendAt)
)); ));
notifyService.createIfAbsent(notify); notifyService.create(notify);
} catch (Exception e) { } catch (Exception e) {
log.error("GAO 订单提醒发送失败: storeId[{}], userId[{}], reminderType[{}]", storeId, manager.getUserId(), reminderType, e); log.error("GAO 订单提醒发送失败: storeId[{}], userId[{}], reminderType[{}]", storeId, manager.getUserId(), reminderType, e);
} }
@@ -1,7 +1,6 @@
package com.imyeyu.api.modules.gao.vo; package com.imyeyu.api.modules.gao.vo;
import com.imyeyu.api.modules.gao.entity.GaoCustomer; import com.imyeyu.java.bean.BasePage;
import com.imyeyu.spring.bean.Page;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -13,7 +12,7 @@ import java.util.List;
/// @since 2026-08-13 /// @since 2026-08-13
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class GaoCustomerPage extends Page<GaoCustomer> { public class GaoCustomerPage extends BasePage {
/// 门店 ID /// 门店 ID
private String storeId; private String storeId;
@@ -1,51 +1,66 @@
package com.imyeyu.api.modules.system.audit; package com.imyeyu.api.modules.system.audit;
import com.imyeyu.api.modules.system.entity.Logger; import com.imyeyu.api.modules.system.entity.Logger;
import lombok.AllArgsConstructor;
import lombok.Getter;
/// 操作审计编码 /// 操作审计编码
/// ///
/// @author Codex /// @author Codex
/// @since 2026-09-09 /// @since 2026-09-09
@Getter
@AllArgsConstructor
public enum AuditOperation { public enum AuditOperation {
COMMON_NOTIFY_CREATE(Logger.Module.COMMON), GAO_CUSTOMER_PACKAGE_PURCHASE(Logger.Module.GAO, "GAO_CUSTOMER_PACKAGE_PURCHASE"),
COMMON_NOTIFY_DELETE(Logger.Module.COMMON), GAO_CUSTOMER_PACKAGE_CANCEL(Logger.Module.GAO, "GAO_CUSTOMER_PACKAGE_CANCEL"),
GAO_CUSTOMER_PACKAGE_PURCHASE(Logger.Module.GAO), GAO_SALES_ORDER_PAYMENT_RECEIVE(Logger.Module.GAO, "GAO_SALES_ORDER_PAYMENT_RECEIVE"),
GAO_CUSTOMER_PACKAGE_CANCEL(Logger.Module.GAO), GAO_SALES_ORDER_PAYMENT_VERIFY(Logger.Module.GAO, "GAO_SALES_ORDER_PAYMENT_VERIFY"),
GAO_SALES_ORDER_PAYMENT_RECEIVE(Logger.Module.GAO), GAO_SALES_ORDER_REFUND(Logger.Module.GAO, "GAO_SALES_ORDER_REFUND"),
GAO_SALES_ORDER_PAYMENT_VERIFY(Logger.Module.GAO), GAO_SALES_ORDER_CONFIRM_NO_REFUND(Logger.Module.GAO, "GAO_SALES_ORDER_CONFIRM_NO_REFUND"),
GAO_SALES_ORDER_REFUND(Logger.Module.GAO), GAO_SALES_ORDER_FUND_REVOKE(Logger.Module.GAO, "GAO_SALES_ORDER_FUND_REVOKE"),
GAO_SALES_ORDER_CONFIRM_NO_REFUND(Logger.Module.GAO), GAO_ORDER_FULFILLMENT_CREATE(Logger.Module.GAO, "GAO_ORDER_FULFILLMENT_CREATE"),
GAO_SALES_ORDER_FUND_REVOKE(Logger.Module.GAO), GAO_ORDER_FULFILLMENT_PREPARE_STOCK(Logger.Module.GAO, "GAO_ORDER_FULFILLMENT_PREPARE_STOCK"),
GAO_ORDER_FULFILLMENT_CREATE(Logger.Module.GAO), GAO_ORDER_FULFILLMENT_VERIFY(Logger.Module.GAO, "GAO_ORDER_FULFILLMENT_VERIFY"),
GAO_ORDER_FULFILLMENT_PREPARE_STOCK(Logger.Module.GAO), GAO_ORDER_FULFILLMENT_REJECT(Logger.Module.GAO, "GAO_ORDER_FULFILLMENT_REJECT"),
GAO_ORDER_FULFILLMENT_VERIFY(Logger.Module.GAO), GAO_ORDER_FULFILLMENT_CANCEL(Logger.Module.GAO, "GAO_ORDER_FULFILLMENT_CANCEL"),
GAO_ORDER_FULFILLMENT_REJECT(Logger.Module.GAO), GAO_ORDER_FULFILLMENT_REVOKE(Logger.Module.GAO, "GAO_ORDER_FULFILLMENT_REVOKE"),
GAO_ORDER_FULFILLMENT_CANCEL(Logger.Module.GAO), GAO_PACKAGE_CONFIG_CREATE(Logger.Module.GAO, "GAO_PACKAGE_CONFIG_CREATE"),
GAO_ORDER_FULFILLMENT_REVOKE(Logger.Module.GAO), GAO_PACKAGE_CONFIG_UPDATE(Logger.Module.GAO, "GAO_PACKAGE_CONFIG_UPDATE"),
GAO_PACKAGE_CONFIG_CREATE(Logger.Module.GAO), GAO_PACKAGE_CONFIG_DELETE(Logger.Module.GAO, "GAO_PACKAGE_CONFIG_DELETE"),
GAO_PACKAGE_CONFIG_UPDATE(Logger.Module.GAO), GAO_PRODUCT_CATEGORY_SORT(Logger.Module.GAO, "GAO_PRODUCT_CATEGORY_SORT"),
GAO_PACKAGE_CONFIG_DELETE(Logger.Module.GAO), GAO_PRODUCT_CATEGORY_CREATE(Logger.Module.GAO, "GAO_PRODUCT_CATEGORY_CREATE"),
GAO_PRODUCT_CATEGORY_SORT(Logger.Module.GAO), GAO_PRODUCT_CATEGORY_UPDATE(Logger.Module.GAO, "GAO_PRODUCT_CATEGORY_UPDATE"),
GAO_PRODUCT_CATEGORY_CREATE(Logger.Module.GAO), GAO_PRODUCT_CATEGORY_DISABLE(Logger.Module.GAO, "GAO_PRODUCT_CATEGORY_DISABLE"),
GAO_PRODUCT_CATEGORY_UPDATE(Logger.Module.GAO), GAO_PRODUCT_CREATE(Logger.Module.GAO, "GAO_PRODUCT_CREATE"),
GAO_PRODUCT_CATEGORY_DISABLE(Logger.Module.GAO), GAO_PRODUCT_UPDATE(Logger.Module.GAO, "GAO_PRODUCT_UPDATE"),
GAO_PRODUCT_CREATE(Logger.Module.GAO), GAO_PRODUCT_DISABLE(Logger.Module.GAO, "GAO_PRODUCT_DISABLE"),
GAO_PRODUCT_UPDATE(Logger.Module.GAO), GAO_PRODUCT_STOCK_INITIAL_IN(Logger.Module.GAO, "GAO_PRODUCT_STOCK_INITIAL_IN"),
GAO_PRODUCT_DISABLE(Logger.Module.GAO), GAO_PRODUCT_STOCK_MANUAL_IN(Logger.Module.GAO, "GAO_PRODUCT_STOCK_MANUAL_IN"),
GAO_PRODUCT_STOCK_INITIAL_IN(Logger.Module.GAO), GAO_PRODUCT_STOCK_MANUAL_OUT(Logger.Module.GAO, "GAO_PRODUCT_STOCK_MANUAL_OUT"),
GAO_PRODUCT_STOCK_MANUAL_IN(Logger.Module.GAO), GAO_PRODUCT_STOCK_MANUAL_REVOKE(Logger.Module.GAO, "GAO_PRODUCT_STOCK_MANUAL_REVOKE"),
GAO_PRODUCT_STOCK_MANUAL_OUT(Logger.Module.GAO), GAO_PRODUCT_STOCK_STOCKTAKE_GAIN(Logger.Module.GAO, "GAO_PRODUCT_STOCK_STOCKTAKE_GAIN"),
GAO_PRODUCT_STOCK_MANUAL_REVOKE(Logger.Module.GAO), GAO_PRODUCT_STOCK_STOCKTAKE_LOSS(Logger.Module.GAO, "GAO_PRODUCT_STOCK_STOCKTAKE_LOSS"),
GAO_PRODUCT_STOCK_STOCKTAKE_GAIN(Logger.Module.GAO), GAO_SALES_ORDER_DIRECT_PRODUCT_CREATE(Logger.Module.GAO, "GAO_SALES_ORDER_DIRECT_PRODUCT_CREATE"),
GAO_PRODUCT_STOCK_STOCKTAKE_LOSS(Logger.Module.GAO), GAO_SALES_ORDER_UPDATE(Logger.Module.GAO, "GAO_SALES_ORDER_UPDATE"),
GAO_SALES_ORDER_DIRECT_PRODUCT_CREATE(Logger.Module.GAO), GAO_SALES_ORDER_CANCEL(Logger.Module.GAO, "GAO_SALES_ORDER_CANCEL");
GAO_SALES_ORDER_UPDATE(Logger.Module.GAO),
GAO_SALES_ORDER_CANCEL(Logger.Module.GAO);
final Logger.Module module; private final Logger.Module module;
private final String code;
AuditOperation(Logger.Module module, String code) {
this.module = module;
this.code = code;
}
/// 获取日志模块
///
/// @return 日志模块
public Logger.Module getModule() {
return module;
}
/// 获取操作编码
///
/// @return 操作编码
public String getCode() {
return code;
}
} }
@@ -1,7 +1,6 @@
package com.imyeyu.api.modules.system.audit; package com.imyeyu.api.modules.system.audit;
import com.imyeyu.api.modules.system.entity.Logger; import com.imyeyu.api.modules.system.entity.Logger;
import com.imyeyu.java.TimiJava;
import com.imyeyu.java.bean.timi.TimiException; import com.imyeyu.java.bean.timi.TimiException;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -39,7 +38,7 @@ public class OperationAuditAspect {
public Object around(ProceedingJoinPoint joinPoint, OperationAudit operationAudit) throws Throwable { public Object around(ProceedingJoinPoint joinPoint, OperationAudit operationAudit) throws Throwable {
AuditOperation operation = operationAudit.value(); AuditOperation operation = operationAudit.value();
Object[] arguments = joinPoint.getArgs(); Object[] arguments = joinPoint.getArgs();
Logger logger = new Logger(operation.getModule(), operation.name()); Logger logger = new Logger(operation.getModule(), operation.getCode());
logger.setContent(payloadSerializer.serializeArguments(arguments)); logger.setContent(payloadSerializer.serializeArguments(arguments));
long startNanos = System.nanoTime(); long startNanos = System.nanoTime();
try { try {
@@ -57,9 +56,9 @@ public class OperationAuditAspect {
throw e; throw e;
} catch (Throwable e) { } catch (Throwable e) {
logger.setLevel(Logger.Level.ERROR); logger.setLevel(Logger.Level.ERROR);
logger.setException(TimiJava.serializeThrowable(e)); logger.setException(serializeThrowable(e));
logger.setDuration(duration(startNanos)); logger.setDuration(duration(startNanos));
log.error("业务操作失败: {}", operation.name(), e); log.error("业务操作失败: {}", operation.getCode(), e);
record(logger); record(logger);
throw e; throw e;
} }
@@ -80,4 +79,12 @@ public class OperationAuditAspect {
} }
return (int) Math.max(0L, millis); return (int) Math.max(0L, millis);
} }
private String serializeThrowable(Throwable throwable) {
java.io.StringWriter stringWriter = new java.io.StringWriter();
try (java.io.PrintWriter printWriter = new java.io.PrintWriter(stringWriter)) {
throwable.printStackTrace(printWriter);
}
return stringWriter.toString();
}
} }
@@ -1,25 +0,0 @@
ALTER TABLE `notify`
CHANGE COLUMN `biz_reminded_id` `biz_reminded_key` VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT '业务提醒查重键',
ADD COLUMN `biz_reminded_active_key` TINYINT(1) GENERATED ALWAYS AS (IF(`deleted_at` IS NULL, 1, NULL)) STORED COMMENT '未删除查重键' INVISIBLE AFTER `deleted_at`,
DROP INDEX `idx_biz_reminded_created`,
ADD INDEX `idx_biz_reminded_key_created`(`biz_type` ASC, `biz_reminded_type` ASC, `biz_reminded_key` ASC, `created_at` ASC) USING BTREE;
UPDATE `notify` target
INNER JOIN (
SELECT
id,
ROW_NUMBER() OVER (
PARTITION BY biz_type, biz_reminded_type, biz_reminded_key
ORDER BY created_at DESC, id DESC
) AS rn
FROM `notify`
WHERE deleted_at IS NULL
AND biz_type IS NOT NULL
AND biz_reminded_type IS NOT NULL
AND biz_reminded_key IS NOT NULL
) duplicate ON duplicate.id = target.id
SET target.deleted_at = UNIX_TIMESTAMP() * 1000
WHERE duplicate.rn > 1;
ALTER TABLE `notify`
ADD UNIQUE INDEX `uk_biz_reminded_key_active`(`biz_type` ASC, `biz_reminded_type` ASC, `biz_reminded_key` ASC, `biz_reminded_active_key` ASC) USING BTREE;
@@ -1,31 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.imyeyu.api.modules.common.mapper.NotifyMapper"> <mapper namespace="com.imyeyu.api.modules.common.mapper.NotifyMapper">
<insert id="insertIfAbsent">
INSERT INTO `notify` (
`id`,
`biz_type`,
`biz_reminded_type`,
`biz_reminded_key`,
`args`,
`created_by`,
`created_at`,
`updated_at`,
`deleted_at`
) VALUES (
#{id},
#{bizType},
#{bizRemindedType},
#{bizRemindedKey},
#{args},
#{createdBy},
#{createdAt},
#{updatedAt},
#{deletedAt}
)
ON DUPLICATE KEY UPDATE `id` = `id`
</insert>
<select id="selectManagementPage" resultType="com.imyeyu.api.modules.common.vo.NotifyManagementItem"> <select id="selectManagementPage" resultType="com.imyeyu.api.modules.common.vo.NotifyManagementItem">
SELECT SELECT
n.`id`, n.`id`,
@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.imyeyu.api.modules.common.mapper.SettingMapper">
<select id="selectPublicByQuery" resultType="com.imyeyu.api.modules.common.entity.Setting">
SELECT *
FROM `setting`
WHERE `biz_type` = #{bizType}
AND `is_private` = 0
<if test="bizId != null and bizId != ''">
AND `biz_id` = #{bizId}
</if>
<if test="codeList != null and !codeList.isEmpty()">
AND `code` IN
<foreach collection="codeList" item="code" separator="," open="(" close=")">
#{code}
</foreach>
</if>
AND (`deleted_at` IS NULL OR FLOOR(UNIX_TIMESTAMP(NOW(3)) * 1000) &lt; `deleted_at`)
</select>
</mapper>
@@ -18,6 +18,7 @@
</if> </if>
AND `deleted_at` IS NULL AND `deleted_at` IS NULL
</select> </select>
<sql id="queryWhere"> <sql id="queryWhere">
`c`.`deleted_at` IS NULL `c`.`deleted_at` IS NULL
<if test="storeId != null and storeId != ''"> <if test="storeId != null and storeId != ''">
@@ -63,18 +64,7 @@
FROM `gao_customer` `c` FROM `gao_customer` `c`
WHERE WHERE
<include refid="queryWhere"/> <include refid="queryWhere"/>
<choose>
<when test="orderMap != null and !orderMap.isEmpty()">
ORDER BY
<foreach collection="orderMap" index="key" item="value" separator=",">
<bind name="underscoreKey" value="@com.imyeyu.utils.Text@camelCase2underscore(key)"/>
${underscoreKey} ${value}
</foreach>
</when>
<otherwise>
ORDER BY `c`.`created_at` DESC, `c`.`id` DESC ORDER BY `c`.`created_at` DESC, `c`.`id` DESC
</otherwise>
</choose>
LIMIT #{offset}, #{limit} LIMIT #{offset}, #{limit}
</select> </select>