Compare commits
11
Commits
v1.0.5
..
c49686c411
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c49686c411 | ||
|
|
65161a7fad | ||
|
|
187f270866 | ||
|
|
50d4bba045 | ||
|
|
6eedc06a07 | ||
|
|
b55b43eba4 | ||
|
|
20289a3168 | ||
|
|
d45bf11477 | ||
|
|
7370b2fc98 | ||
|
|
2f366fe219 | ||
|
|
f1715a3e32 |
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
<groupId>com.imyeyu.timiserverapi</groupId>
|
<groupId>com.imyeyu.timiserverapi</groupId>
|
||||||
<artifactId>TimiServerAPI</artifactId>
|
<artifactId>TimiServerAPI</artifactId>
|
||||||
<version>1.0.3</version>
|
<version>1.0.6</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<name>TimiServerAPI</name>
|
<name>TimiServerAPI</name>
|
||||||
<description>imyeyu.com API</description>
|
<description>imyeyu.com API</description>
|
||||||
@@ -173,7 +173,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.imyeyu.spring</groupId>
|
<groupId>com.imyeyu.spring</groupId>
|
||||||
<artifactId>timi-spring</artifactId>
|
<artifactId>timi-spring</artifactId>
|
||||||
<version>0.0.17</version>
|
<version>0.0.18</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.imyeyu.network</groupId>
|
<groupId>com.imyeyu.network</groupId>
|
||||||
@@ -188,7 +188,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.imyeyu.java</groupId>
|
<groupId>com.imyeyu.java</groupId>
|
||||||
<artifactId>timi-java</artifactId>
|
<artifactId>timi-java</artifactId>
|
||||||
<version>0.0.6</version>
|
<version>0.0.7</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.imyeyu.utils</groupId>
|
<groupId>com.imyeyu.utils</groupId>
|
||||||
@@ -230,6 +230,10 @@
|
|||||||
<artifactId>spring-boot-starter-freemarker</artifactId>
|
<artifactId>spring-boot-starter-freemarker</artifactId>
|
||||||
<version>${springboot.version}</version>
|
<version>${springboot.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||||
|
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-data-mongodb</artifactId>
|
<artifactId>spring-boot-starter-data-mongodb</artifactId>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||||||
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
|
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
|
||||||
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
|
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
|
||||||
import com.fasterxml.jackson.databind.json.JsonMapper;
|
import com.fasterxml.jackson.databind.json.JsonMapper;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
import com.imyeyu.utils.Time;
|
import com.imyeyu.utils.Time;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -22,6 +23,7 @@ public class BeanConfig {
|
|||||||
@Bean
|
@Bean
|
||||||
public ObjectMapper jackson() {
|
public ObjectMapper jackson() {
|
||||||
return JsonMapper.builder()
|
return JsonMapper.builder()
|
||||||
|
.addModule(new JavaTimeModule())
|
||||||
.serializationInclusion(JsonInclude.Include.NON_NULL)
|
.serializationInclusion(JsonInclude.Include.NON_NULL)
|
||||||
.defaultDateFormat(Time.dateTime)
|
.defaultDateFormat(Time.dateTime)
|
||||||
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
|
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature;
|
|||||||
import com.fasterxml.jackson.databind.MapperFeature;
|
import com.fasterxml.jackson.databind.MapperFeature;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.json.JsonMapper;
|
import com.fasterxml.jackson.databind.json.JsonMapper;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
import com.imyeyu.api.annotation.EnableSettingInterceptor;
|
import com.imyeyu.api.annotation.EnableSettingInterceptor;
|
||||||
import com.imyeyu.api.annotation.RequestRateLimitInterceptor;
|
import com.imyeyu.api.annotation.RequestRateLimitInterceptor;
|
||||||
import com.imyeyu.api.annotation.RequireCorePermissionInterceptor;
|
import com.imyeyu.api.annotation.RequireCorePermissionInterceptor;
|
||||||
@@ -78,6 +79,7 @@ public class WebConfig implements WebMvcConfigurer {
|
|||||||
@Override
|
@Override
|
||||||
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||||
JsonMapper jsonMapper = JsonMapper.builder()
|
JsonMapper jsonMapper = JsonMapper.builder()
|
||||||
|
.addModule(new JavaTimeModule())
|
||||||
// 设置默认属性包含规则:忽略 null 值
|
// 设置默认属性包含规则:忽略 null 值
|
||||||
.serializationInclusion(JsonInclude.Include.NON_NULL)
|
.serializationInclusion(JsonInclude.Include.NON_NULL)
|
||||||
// 日期格式化
|
// 日期格式化
|
||||||
|
|||||||
+4
-4
@@ -46,8 +46,8 @@ public class TempFileServiceImplement implements TempFileService {
|
|||||||
|
|
||||||
public List<TempFileResp> create(List<MultipartFile> files, Long ttl) throws TimiException {
|
public List<TempFileResp> create(List<MultipartFile> files, Long ttl) throws TimiException {
|
||||||
Logger logger = new Logger();
|
Logger logger = new Logger();
|
||||||
logger.setModule("TEMP_FILE");
|
logger.setModule(Logger.Module.COMMON);
|
||||||
logger.setOperation("STORE");
|
logger.setOperation("TEMP_FILE_STORE");
|
||||||
logger.setIp(TimiSpring.getRequestIP());
|
logger.setIp(TimiSpring.getRequestIP());
|
||||||
try {
|
try {
|
||||||
logger.setContent(jackson.writeValueAsString(logRequestArgs(files, ttl)));
|
logger.setContent(jackson.writeValueAsString(logRequestArgs(files, ttl)));
|
||||||
@@ -116,8 +116,8 @@ public class TempFileServiceImplement implements TempFileService {
|
|||||||
@Override
|
@Override
|
||||||
public void save(TempFileSaveReq request) {
|
public void save(TempFileSaveReq request) {
|
||||||
Logger logger = new Logger();
|
Logger logger = new Logger();
|
||||||
logger.setModule("TEMP_FILE");
|
logger.setModule(Logger.Module.COMMON);
|
||||||
logger.setOperation("SAVE");
|
logger.setOperation("TEMP_FILE_SAVE");
|
||||||
logger.setIp(TimiSpring.getRequestIP());
|
logger.setIp(TimiSpring.getRequestIP());
|
||||||
try {
|
try {
|
||||||
logger.setContent(jackson.writeValueAsString(request));
|
logger.setContent(jackson.writeValueAsString(request));
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.imyeyu.api.modules.forevermc.controller;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务器接口
|
||||||
|
*
|
||||||
|
* @author 夜雨
|
||||||
|
* @since 2024-08-06 17:20
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Validated
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RequestMapping("/fmc/server")
|
||||||
|
public class ServerController {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务器状态报告,由 FMCServer 服务端插件发送
|
||||||
|
*/
|
||||||
|
@PostMapping("/report")
|
||||||
|
public void report() {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,8 @@ public enum GaoPermissionCode implements BuiltinPermissionCode {
|
|||||||
|
|
||||||
CUSTOMER_READ("CUSTOMER:READ", "客户读取"),
|
CUSTOMER_READ("CUSTOMER:READ", "客户读取"),
|
||||||
|
|
||||||
|
CUSTOMER_EXPORT("CUSTOMER:EXPORT", "客户导出", true),
|
||||||
|
|
||||||
CUSTOMER_UPDATE("CUSTOMER:UPDATE", "客户修改"),
|
CUSTOMER_UPDATE("CUSTOMER:UPDATE", "客户修改"),
|
||||||
|
|
||||||
CUSTOMER_DELETE("CUSTOMER:DELETE", "客户删除"),
|
CUSTOMER_DELETE("CUSTOMER:DELETE", "客户删除"),
|
||||||
@@ -30,6 +32,8 @@ public enum GaoPermissionCode implements BuiltinPermissionCode {
|
|||||||
|
|
||||||
REGISTRATION_EVENT_RECORD_READ("REGISTRATION_EVENT_RECORD:READ", "登记事件记录读取"),
|
REGISTRATION_EVENT_RECORD_READ("REGISTRATION_EVENT_RECORD:READ", "登记事件记录读取"),
|
||||||
|
|
||||||
|
REGISTRATION_EVENT_RECORD_EXPORT("REGISTRATION_EVENT_RECORD:EXPORT", "登记事件记录导出", true),
|
||||||
|
|
||||||
REGISTRATION_EVENT_RECORD_UPDATE("REGISTRATION_EVENT_RECORD:UPDATE", "登记事件记录修改"),
|
REGISTRATION_EVENT_RECORD_UPDATE("REGISTRATION_EVENT_RECORD:UPDATE", "登记事件记录修改"),
|
||||||
|
|
||||||
REGISTRATION_EVENT_RECORD_DELETE("REGISTRATION_EVENT_RECORD:DELETE", "登记事件记录删除"),
|
REGISTRATION_EVENT_RECORD_DELETE("REGISTRATION_EVENT_RECORD:DELETE", "登记事件记录删除"),
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ public class GaoCustomerController {
|
|||||||
@AOPLog
|
@AOPLog
|
||||||
@RequestRateLimit
|
@RequestRateLimit
|
||||||
@IgnoreGlobalReturn
|
@IgnoreGlobalReturn
|
||||||
@RequireGaoPermission(GaoPermissionCode.CUSTOMER_READ)
|
@RequireGaoPermission(GaoPermissionCode.CUSTOMER_EXPORT)
|
||||||
@PostMapping("/export")
|
@PostMapping("/export")
|
||||||
public void export(@RequestBody GaoCustomerSearchReq req, HttpServletResponse resp) throws IOException {
|
public void export(@RequestBody GaoCustomerSearchReq req, HttpServletResponse resp) throws IOException {
|
||||||
String fileName = URLEncoder.encode("客户列表.xlsx", "UTF-8").replace("+", "%20");
|
String fileName = URLEncoder.encode("客户列表.xlsx", "UTF-8").replace("+", "%20");
|
||||||
|
|||||||
+8
@@ -72,6 +72,14 @@ public class GaoRegistrationEventController {
|
|||||||
service.update(registrationEvent);
|
service.update(registrationEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@AOPLog
|
||||||
|
@RequestRateLimit
|
||||||
|
@RequireGaoPermission(GaoPermissionCode.REGISTRATION_EVENT_UPDATE)
|
||||||
|
@PostMapping("/sort")
|
||||||
|
public void sort(@RequestBody List<String> idList) {
|
||||||
|
service.sort(idList);
|
||||||
|
}
|
||||||
|
|
||||||
@AOPLog
|
@AOPLog
|
||||||
@RequestRateLimit
|
@RequestRateLimit
|
||||||
@RequireGaoPermission(GaoPermissionCode.REGISTRATION_EVENT_DELETE)
|
@RequireGaoPermission(GaoPermissionCode.REGISTRATION_EVENT_DELETE)
|
||||||
|
|||||||
+13
-3
@@ -10,6 +10,7 @@ import com.imyeyu.api.modules.gao.entity.GaoRegistrationEventRecord;
|
|||||||
import com.imyeyu.api.modules.gao.service.GaoRegistrationEventRecordService;
|
import com.imyeyu.api.modules.gao.service.GaoRegistrationEventRecordService;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventPeriodStatView;
|
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventPeriodStatView;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerRegisterStatView;
|
import com.imyeyu.api.modules.gao.vo.GaoCustomerRegisterStatView;
|
||||||
|
import com.imyeyu.api.modules.gao.vo.GaoCustomerRegistrationRankView;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordCreateReq;
|
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordCreateReq;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordCalendarView;
|
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordCalendarView;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordDailyStatView;
|
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordDailyStatView;
|
||||||
@@ -79,8 +80,8 @@ public class GaoRegistrationEventRecordController {
|
|||||||
@RequestRateLimit
|
@RequestRateLimit
|
||||||
@PostMapping("/create")
|
@PostMapping("/create")
|
||||||
@JsonView(ResponseView.Public.class)
|
@JsonView(ResponseView.Public.class)
|
||||||
public GaoRegistrationEventRecord create(@RequestBody GaoRegistrationEventRecordCreateReq req) {
|
public List<GaoRegistrationEventRecord> create(@RequestBody GaoRegistrationEventRecordCreateReq req) {
|
||||||
return service.createRecord(req);
|
return service.createRecords(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AOPLog
|
@AOPLog
|
||||||
@@ -128,7 +129,7 @@ public class GaoRegistrationEventRecordController {
|
|||||||
@AOPLog
|
@AOPLog
|
||||||
@RequestRateLimit
|
@RequestRateLimit
|
||||||
@IgnoreGlobalReturn
|
@IgnoreGlobalReturn
|
||||||
@RequireGaoPermission(GaoPermissionCode.REGISTRATION_EVENT_RECORD_READ)
|
@RequireGaoPermission(GaoPermissionCode.REGISTRATION_EVENT_RECORD_EXPORT)
|
||||||
@PostMapping("/range/export")
|
@PostMapping("/range/export")
|
||||||
public void rangeExport(@RequestBody GaoRegistrationEventRecordRangeReq req, HttpServletResponse resp) throws IOException {
|
public void rangeExport(@RequestBody GaoRegistrationEventRecordRangeReq req, HttpServletResponse resp) throws IOException {
|
||||||
String fileName = URLEncoder.encode("登记事件记录.xlsx", "UTF-8").replace("+", "%20");
|
String fileName = URLEncoder.encode("登记事件记录.xlsx", "UTF-8").replace("+", "%20");
|
||||||
@@ -171,6 +172,15 @@ public class GaoRegistrationEventRecordController {
|
|||||||
return service.statAllCustomerByRange(req);
|
return service.statAllCustomerByRange(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@AOPLog
|
||||||
|
@RequestRateLimit
|
||||||
|
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
|
||||||
|
@PostMapping("/customer/registration-rank")
|
||||||
|
/// 按时间范围查询客户登记排行榜
|
||||||
|
public List<GaoCustomerRegistrationRankView> customerRegistrationRank(@RequestBody(required = false) GaoRegistrationEventRecordRangeReq req) {
|
||||||
|
return service.listCustomerRegistrationRank(req);
|
||||||
|
}
|
||||||
|
|
||||||
@AOPLog
|
@AOPLog
|
||||||
@RequestRateLimit
|
@RequestRateLimit
|
||||||
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
|
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.imyeyu.api.modules.gao.entity;
|
package com.imyeyu.api.modules.gao.entity;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.imyeyu.api.modules.common.entity.Attachment;
|
import com.imyeyu.api.modules.common.entity.Attachment;
|
||||||
import com.imyeyu.api.modules.user.entity.User;
|
import com.imyeyu.api.modules.user.entity.User;
|
||||||
@@ -9,6 +11,7 @@ import com.imyeyu.spring.entity.UUIDEntity;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -30,6 +33,18 @@ public class GaoCustomer extends UUIDEntity {
|
|||||||
PHOTO
|
PHOTO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// 出生日期使用的历法
|
||||||
|
///
|
||||||
|
public enum BirthdateCalendar {
|
||||||
|
|
||||||
|
/// 公历
|
||||||
|
SOLAR,
|
||||||
|
|
||||||
|
/// 农历
|
||||||
|
LUNAR
|
||||||
|
}
|
||||||
|
|
||||||
/// 客户编码
|
/// 客户编码
|
||||||
private String code;
|
private String code;
|
||||||
|
|
||||||
@@ -42,6 +57,22 @@ public class GaoCustomer extends UUIDEntity {
|
|||||||
/// 年龄
|
/// 年龄
|
||||||
private Integer age;
|
private Integer age;
|
||||||
|
|
||||||
|
/// 出生日期,数据库只保存公历日期
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
private LocalDate birthdate;
|
||||||
|
|
||||||
|
/// 出生日期录入时使用的历法
|
||||||
|
private BirthdateCalendar birthdateCalendar;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@Transient
|
||||||
|
private boolean birthdateProvided;
|
||||||
|
|
||||||
|
public void setBirthdate(LocalDate birthdate) {
|
||||||
|
this.birthdate = birthdate;
|
||||||
|
this.birthdateProvided = true;
|
||||||
|
}
|
||||||
|
|
||||||
/// 电话
|
/// 电话
|
||||||
private String telephone;
|
private String telephone;
|
||||||
|
|
||||||
|
|||||||
@@ -16,18 +16,82 @@ import java.util.List;
|
|||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public class GaoRegistrationEvent extends UUIDEntity {
|
public class GaoRegistrationEvent extends UUIDEntity {
|
||||||
|
|
||||||
|
///
|
||||||
|
/// 登记事件状态
|
||||||
|
///
|
||||||
|
/// @author Codex
|
||||||
|
/// @since 2026-08-01
|
||||||
|
public enum Status {
|
||||||
|
|
||||||
|
/// 草稿,未发布不可登记
|
||||||
|
DRAFT,
|
||||||
|
|
||||||
|
/// 可登记
|
||||||
|
ACTIVE,
|
||||||
|
|
||||||
|
/// 无效,不可登记但保留统计
|
||||||
|
INACTIVE,
|
||||||
|
|
||||||
|
/// 已删除,不可登记但保留统计
|
||||||
|
DELETED
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// 登记限制类型
|
||||||
|
///
|
||||||
|
/// @author Codex
|
||||||
|
/// @since 2026-08-01
|
||||||
|
public enum LimitType {
|
||||||
|
|
||||||
|
/// 不限制
|
||||||
|
NONE,
|
||||||
|
|
||||||
|
/// 每天上午、下午各一次
|
||||||
|
DAILY_HALF_DAY,
|
||||||
|
|
||||||
|
/// 每个自然日一次
|
||||||
|
NATURAL_DAY,
|
||||||
|
|
||||||
|
/// 每隔 N 小时一次
|
||||||
|
INTERVAL_HOUR,
|
||||||
|
|
||||||
|
/// 每个自然月一次
|
||||||
|
NATURAL_MONTH,
|
||||||
|
|
||||||
|
/// 事件总登记次数上限
|
||||||
|
TOTAL_LIMIT,
|
||||||
|
|
||||||
|
/// 单个客户总登记次数上限
|
||||||
|
CUSTOMER_TOTAL_LIMIT
|
||||||
|
}
|
||||||
|
|
||||||
/// 登记事件名称
|
/// 登记事件名称
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
/// 说明
|
/// 说明
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
/// true 为启用
|
/// 统计图表颜色
|
||||||
private Boolean enabled;
|
private String color;
|
||||||
|
|
||||||
|
/// 状态
|
||||||
|
private Status status;
|
||||||
|
|
||||||
/// true 为登记时要求拍照
|
/// true 为登记时要求拍照
|
||||||
private Boolean requirePhoto;
|
private Boolean requirePhoto;
|
||||||
|
|
||||||
|
/// 登记限制类型
|
||||||
|
private LimitType limitType;
|
||||||
|
|
||||||
|
/// 登记限制数值,按限制类型表示小时数或次数
|
||||||
|
private Integer limitValue;
|
||||||
|
|
||||||
|
/// 可登记起始时间戳,毫秒,空为不限制
|
||||||
|
private Long beginAt;
|
||||||
|
|
||||||
|
/// 可登记终止时间戳,毫秒,空为不限制
|
||||||
|
private Long endAt;
|
||||||
|
|
||||||
/// 排序值
|
/// 排序值
|
||||||
private Integer sort;
|
private Integer sort;
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package com.imyeyu.api.modules.gao.mapper;
|
|||||||
import com.imyeyu.api.modules.gao.entity.GaoRegistrationEvent;
|
import com.imyeyu.api.modules.gao.entity.GaoRegistrationEvent;
|
||||||
import com.imyeyu.spring.mapper.BaseMapper;
|
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 java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -16,6 +15,5 @@ public interface GaoRegistrationEventMapper extends BaseMapper<GaoRegistrationEv
|
|||||||
|
|
||||||
List<GaoRegistrationEvent> selectByIdList(@Param("idList") List<String> idList);
|
List<GaoRegistrationEvent> selectByIdList(@Param("idList") List<String> idList);
|
||||||
|
|
||||||
@Select("SELECT * FROM `gao_registration_event` WHERE `enabled` = TRUE AND `deleted_at` IS NULL ORDER BY `sort` ASC, `created_at` ASC")
|
List<GaoRegistrationEvent> selectEnabledList(@Param("now") Long now);
|
||||||
List<GaoRegistrationEvent> selectEnabledList();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.imyeyu.api.modules.gao.mapper;
|
|||||||
import com.imyeyu.api.modules.gao.entity.GaoRegistrationEventRecord;
|
import com.imyeyu.api.modules.gao.entity.GaoRegistrationEventRecord;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventPeriodStatView;
|
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventPeriodStatView;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerRegisterStatView;
|
import com.imyeyu.api.modules.gao.vo.GaoCustomerRegisterStatView;
|
||||||
|
import com.imyeyu.api.modules.gao.vo.GaoCustomerRegistrationDayStatView;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordCalendarView;
|
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordCalendarView;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordDailyStatView;
|
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordDailyStatView;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordListItemView;
|
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordListItemView;
|
||||||
@@ -27,6 +28,28 @@ public interface GaoRegistrationEventRecordMapper extends BaseMapper<GaoRegistra
|
|||||||
/// @return 最后登记事件记录列表
|
/// @return 最后登记事件记录列表
|
||||||
List<GaoRegistrationEventRecord> selectByRegistrationEventAndPeriod(@Param("registrationEventId") String registrationEventId, @Param("periodType") GaoRegistrationEventRecordPeriodReq.PeriodType periodType, @Param("periodValue") Integer periodValue);
|
List<GaoRegistrationEventRecord> selectByRegistrationEventAndPeriod(@Param("registrationEventId") String registrationEventId, @Param("periodType") GaoRegistrationEventRecordPeriodReq.PeriodType periodType, @Param("periodValue") Integer periodValue);
|
||||||
|
|
||||||
|
/// 统计客户指定登记事件在时间范围内的登记数
|
||||||
|
///
|
||||||
|
/// @param customerId 客户 ID
|
||||||
|
/// @param registrationEventId 登记事件 ID
|
||||||
|
/// @param beginRegisteredAt 开始登记时间
|
||||||
|
/// @param endRegisteredAt 结束登记时间
|
||||||
|
/// @return 登记数
|
||||||
|
Long countByCustomerIdAndRegistrationEventIdRange(@Param("customerId") String customerId, @Param("registrationEventId") String registrationEventId, @Param("beginRegisteredAt") Long beginRegisteredAt, @Param("endRegisteredAt") Long endRegisteredAt);
|
||||||
|
|
||||||
|
/// 统计客户指定登记事件总登记数
|
||||||
|
///
|
||||||
|
/// @param customerId 客户 ID
|
||||||
|
/// @param registrationEventId 登记事件 ID
|
||||||
|
/// @return 登记数
|
||||||
|
Long countByCustomerIdAndRegistrationEventId(@Param("customerId") String customerId, @Param("registrationEventId") String registrationEventId);
|
||||||
|
|
||||||
|
/// 统计登记事件总登记数
|
||||||
|
///
|
||||||
|
/// @param registrationEventId 登记事件 ID
|
||||||
|
/// @return 登记数
|
||||||
|
Long countByRegistrationEventId(@Param("registrationEventId") String registrationEventId);
|
||||||
|
|
||||||
/// 按周期统计登记事件记录
|
/// 按周期统计登记事件记录
|
||||||
///
|
///
|
||||||
/// @param registrationEventId 登记事件 ID
|
/// @param registrationEventId 登记事件 ID
|
||||||
@@ -55,6 +78,12 @@ public interface GaoRegistrationEventRecordMapper extends BaseMapper<GaoRegistra
|
|||||||
/// @return 统计结果
|
/// @return 统计结果
|
||||||
List<GaoCustomerRegisterStatView> statAllCustomerByRange(@Param("beginRegisteredAt") Long beginRegisteredAt, @Param("endRegisteredAt") Long endRegisteredAt);
|
List<GaoCustomerRegisterStatView> statAllCustomerByRange(@Param("beginRegisteredAt") Long beginRegisteredAt, @Param("endRegisteredAt") Long endRegisteredAt);
|
||||||
|
|
||||||
|
/// 按时间范围统计全部客户每日登记
|
||||||
|
///
|
||||||
|
/// @param req 范围查询请求
|
||||||
|
/// @return 每个有登记客户的每日统计
|
||||||
|
List<GaoCustomerRegistrationDayStatView> statCustomerRegistrationDay(@Param("req") GaoRegistrationEventRecordRangeReq req);
|
||||||
|
|
||||||
/// 统计单个客户单个登记事件的每日登记事件记录数
|
/// 统计单个客户单个登记事件的每日登记事件记录数
|
||||||
///
|
///
|
||||||
/// @param customerId 客户 ID
|
/// @param customerId 客户 ID
|
||||||
|
|||||||
+11
-4
@@ -3,6 +3,7 @@ package com.imyeyu.api.modules.gao.service;
|
|||||||
import com.imyeyu.api.modules.gao.entity.GaoRegistrationEventRecord;
|
import com.imyeyu.api.modules.gao.entity.GaoRegistrationEventRecord;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventPeriodStatView;
|
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventPeriodStatView;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerRegisterStatView;
|
import com.imyeyu.api.modules.gao.vo.GaoCustomerRegisterStatView;
|
||||||
|
import com.imyeyu.api.modules.gao.vo.GaoCustomerRegistrationRankView;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoQuickRegistrationEventRecordReq;
|
import com.imyeyu.api.modules.gao.vo.GaoQuickRegistrationEventRecordReq;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordCalendarView;
|
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordCalendarView;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordCreateReq;
|
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordCreateReq;
|
||||||
@@ -26,11 +27,11 @@ import java.util.List;
|
|||||||
/// @since 2026-07-27
|
/// @since 2026-07-27
|
||||||
public interface GaoRegistrationEventRecordService extends BaseService<GaoRegistrationEventRecord, String> {
|
public interface GaoRegistrationEventRecordService extends BaseService<GaoRegistrationEventRecord, String> {
|
||||||
|
|
||||||
/// 创建登记事件记录
|
/// 批量创建登记事件记录
|
||||||
///
|
///
|
||||||
/// @param req 创建请求
|
/// @param req 批量创建请求
|
||||||
/// @return 创建后的登记事件记录
|
/// @return 创建后的登记事件记录列表
|
||||||
GaoRegistrationEventRecord createRecord(GaoRegistrationEventRecordCreateReq req);
|
List<GaoRegistrationEventRecord> createRecords(GaoRegistrationEventRecordCreateReq req);
|
||||||
|
|
||||||
/// 快速录入客户并创建登记事件记录
|
/// 快速录入客户并创建登记事件记录
|
||||||
///
|
///
|
||||||
@@ -100,6 +101,12 @@ public interface GaoRegistrationEventRecordService extends BaseService<GaoRegist
|
|||||||
/// @return 统计结果
|
/// @return 统计结果
|
||||||
List<GaoCustomerRegisterStatView> statAllCustomerByRange(GaoRegistrationEventRecordStatReq req);
|
List<GaoCustomerRegisterStatView> statAllCustomerByRange(GaoRegistrationEventRecordStatReq req);
|
||||||
|
|
||||||
|
/// 按时间范围查询客户登记排行榜
|
||||||
|
///
|
||||||
|
/// @param req 范围查询请求,不传时间为全部时间
|
||||||
|
/// @return 客户登记排行榜
|
||||||
|
List<GaoCustomerRegistrationRankView> listCustomerRegistrationRank(GaoRegistrationEventRecordRangeReq req);
|
||||||
|
|
||||||
/// 按时间段统计单个客户单个登记事件每日趋势
|
/// 按时间段统计单个客户单个登记事件每日趋势
|
||||||
///
|
///
|
||||||
/// @param req 趋势统计请求
|
/// @param req 趋势统计请求
|
||||||
|
|||||||
@@ -30,4 +30,9 @@ public interface GaoRegistrationEventService extends BaseService<GaoRegistration
|
|||||||
/// @param registrationEventId 登记事件 ID
|
/// @param registrationEventId 登记事件 ID
|
||||||
/// @return 角色代码列表
|
/// @return 角色代码列表
|
||||||
List<String> listRoleCode(String registrationEventId);
|
List<String> listRoleCode(String registrationEventId);
|
||||||
|
|
||||||
|
/// 按客户端提交的顺序更新登记事件排序
|
||||||
|
///
|
||||||
|
/// @param idList 登记事件 ID 列表
|
||||||
|
void sort(List<String> idList);
|
||||||
}
|
}
|
||||||
|
|||||||
+142
-6
@@ -1,5 +1,6 @@
|
|||||||
package com.imyeyu.api.modules.gao.service.implement;
|
package com.imyeyu.api.modules.gao.service.implement;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
|
import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
|
||||||
import com.imyeyu.api.modules.common.entity.Attachment;
|
import com.imyeyu.api.modules.common.entity.Attachment;
|
||||||
import com.imyeyu.api.modules.common.service.AttachmentService;
|
import com.imyeyu.api.modules.common.service.AttachmentService;
|
||||||
@@ -7,21 +8,25 @@ import com.imyeyu.api.modules.common.vo.attach.BizUpdateReq;
|
|||||||
import com.imyeyu.api.modules.gao.entity.GaoCustomer;
|
import com.imyeyu.api.modules.gao.entity.GaoCustomer;
|
||||||
import com.imyeyu.api.modules.gao.mapper.GaoCustomerMapper;
|
import com.imyeyu.api.modules.gao.mapper.GaoCustomerMapper;
|
||||||
import com.imyeyu.api.modules.gao.service.GaoCustomerService;
|
import com.imyeyu.api.modules.gao.service.GaoCustomerService;
|
||||||
import com.imyeyu.api.modules.user.service.UserLoginService;
|
|
||||||
import com.imyeyu.api.modules.user.service.UserService;
|
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerDailyStatView;
|
import com.imyeyu.api.modules.gao.vo.GaoCustomerDailyStatView;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerGenderStatView;
|
import com.imyeyu.api.modules.gao.vo.GaoCustomerGenderStatView;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerInviteUpdateReq;
|
import com.imyeyu.api.modules.gao.vo.GaoCustomerInviteUpdateReq;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerSearchReq;
|
import com.imyeyu.api.modules.gao.vo.GaoCustomerSearchReq;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerTrendStatReq;
|
import com.imyeyu.api.modules.gao.vo.GaoCustomerTrendStatReq;
|
||||||
|
import com.imyeyu.api.modules.system.entity.Logger;
|
||||||
|
import com.imyeyu.api.modules.system.service.LoggerService;
|
||||||
|
import com.imyeyu.api.modules.user.service.UserLoginService;
|
||||||
|
import com.imyeyu.api.modules.user.service.UserService;
|
||||||
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;
|
||||||
|
import com.imyeyu.spring.TimiSpring;
|
||||||
import com.imyeyu.spring.bean.Page;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.poi.ss.usermodel.CellStyle;
|
import org.apache.poi.ss.usermodel.CellStyle;
|
||||||
import org.apache.poi.ss.usermodel.Font;
|
import org.apache.poi.ss.usermodel.Font;
|
||||||
import org.apache.poi.ss.usermodel.Row;
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
@@ -35,6 +40,7 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.time.Period;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
@@ -50,6 +56,7 @@ import java.util.stream.Collectors;
|
|||||||
///
|
///
|
||||||
/// @author Codex
|
/// @author Codex
|
||||||
/// @since 2026-07-27
|
/// @since 2026-07-27
|
||||||
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class GaoCustomerServiceImplement extends AbstractEntityService<GaoCustomer, String> implements GaoCustomerService {
|
public class GaoCustomerServiceImplement extends AbstractEntityService<GaoCustomer, String> implements GaoCustomerService {
|
||||||
@@ -58,7 +65,9 @@ public class GaoCustomerServiceImplement extends AbstractEntityService<GaoCustom
|
|||||||
private static final DateTimeFormatter EXPORT_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.systemDefault());
|
private static final DateTimeFormatter EXPORT_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.systemDefault());
|
||||||
|
|
||||||
private final GaoCustomerMapper mapper;
|
private final GaoCustomerMapper mapper;
|
||||||
|
private final ObjectMapper jackson;
|
||||||
private final AttachmentService attachmentService;
|
private final AttachmentService attachmentService;
|
||||||
|
private final LoggerService loggerService;
|
||||||
private final UserLoginService userLoginService;
|
private final UserLoginService userLoginService;
|
||||||
private final UserService userService;
|
private final UserService userService;
|
||||||
|
|
||||||
@@ -67,30 +76,96 @@ public class GaoCustomerServiceImplement extends AbstractEntityService<GaoCustom
|
|||||||
return mapper;
|
return mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<GaoCustomer> page(Page<GaoCustomer> page) {
|
||||||
|
PageResult<GaoCustomer> result = super.page(page);
|
||||||
|
loadListTransient(result.getList());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void create(GaoCustomer entity) {
|
public void create(GaoCustomer entity) {
|
||||||
|
Logger logger = new Logger(Logger.Module.GAO, "GAO_CUSTOMER_CREATE");
|
||||||
|
try {
|
||||||
|
logger.setContent(jackson.writeValueAsString(entity));
|
||||||
checkEntity(entity, false);
|
checkEntity(entity, false);
|
||||||
entity.setCreatorUserId(userLoginService.getRequireLoginUserId());
|
entity.setCreatorUserId(userLoginService.getRequireLoginUserId());
|
||||||
|
entity.setInvitedCount(0L);
|
||||||
super.create(entity);
|
super.create(entity);
|
||||||
saveAttachment(entity.getId(), resolveAttachmentList(entity));
|
saveAttachment(entity.getId(), resolveAttachmentList(entity));
|
||||||
changeInvitedCount(entity.getIntroducerCustomerId(), 1L);
|
changeInvitedCount(entity.getIntroducerCustomerId(), 1L);
|
||||||
loadDetailTransient(entity);
|
loadDetailTransient(entity);
|
||||||
|
logger.setLevel(Logger.Level.INFO);
|
||||||
|
logger.setResult(entity.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("新增 GAO 客户失败", e);
|
||||||
|
throw new TimiException(TimiCode.ERROR, "新增 GAO 客户失败", e);
|
||||||
|
} finally {
|
||||||
|
loggerService.create(logger);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(GaoCustomer entity) {
|
public void update(GaoCustomer entity) {
|
||||||
GaoCustomer dbCustomer = checkEntity(entity, true);
|
Logger logger = new Logger(Logger.Module.GAO, "GAO_CUSTOMER_UPDATE");
|
||||||
super.update(entity);
|
try {
|
||||||
|
logger.setContent(jackson.writeValueAsString(entity));
|
||||||
|
TimiException.required(entity, "not found customer");
|
||||||
|
TimiException.required(entity.getId(), "not found customer.id");
|
||||||
|
GaoCustomer dbCustomer = super.get(entity.getId());
|
||||||
|
if (!entity.isBirthdateProvided()) {
|
||||||
|
entity.setBirthdate(dbCustomer.getBirthdate());
|
||||||
|
entity.setBirthdateCalendar(dbCustomer.getBirthdateCalendar());
|
||||||
|
}
|
||||||
|
checkEntity(entity, true);
|
||||||
|
mapper.update(entity);
|
||||||
saveAttachment(entity.getId(), resolveAttachmentList(entity));
|
saveAttachment(entity.getId(), resolveAttachmentList(entity));
|
||||||
syncIntroducerInvitedCount(dbCustomer.getIntroducerCustomerId(), entity.getIntroducerCustomerId());
|
syncIntroducerInvitedCount(dbCustomer.getIntroducerCustomerId(), entity.getIntroducerCustomerId());
|
||||||
|
logger.setLevel(Logger.Level.INFO);
|
||||||
|
logger.setResult(entity.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("修改 GAO 客户失败", e);
|
||||||
|
throw new TimiException(TimiCode.ERROR, "修改 GAO 客户失败", e);
|
||||||
|
} finally {
|
||||||
|
loggerService.create(logger);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||||
@Override
|
@Override
|
||||||
public void delete(String id) {
|
public void delete(String id) {
|
||||||
|
Logger logger = new Logger(Logger.Module.GAO, "GAO_CUSTOMER_DELETE");
|
||||||
|
try {
|
||||||
|
logger.setContent(id);
|
||||||
GaoCustomer customer = super.get(id);
|
GaoCustomer customer = super.get(id);
|
||||||
super.delete(id);
|
super.delete(id);
|
||||||
changeInvitedCount(customer.getIntroducerCustomerId(), -1L);
|
changeInvitedCount(customer.getIntroducerCustomerId(), -1L);
|
||||||
|
logger.setLevel(Logger.Level.INFO);
|
||||||
|
logger.setResult(id);
|
||||||
|
} 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("删除 GAO 客户失败", e);
|
||||||
|
throw new TimiException(TimiCode.ERROR, "删除 GAO 客户失败", e);
|
||||||
|
} finally {
|
||||||
|
loggerService.create(logger);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -176,13 +251,15 @@ public class GaoCustomerServiceImplement extends AbstractEntityService<GaoCustom
|
|||||||
appendRow(sheet, 1, null, "生成时间", EXPORT_TIME_FORMATTER.format(Instant.now()));
|
appendRow(sheet, 1, null, "生成时间", EXPORT_TIME_FORMATTER.format(Instant.now()));
|
||||||
appendRow(sheet, 2, null, "关键词", req == null || req.getKeyword() == null || req.getKeyword().isBlank() ? "全部" : req.getKeyword().trim());
|
appendRow(sheet, 2, null, "关键词", req == null || req.getKeyword() == null || req.getKeyword().isBlank() ? "全部" : req.getKeyword().trim());
|
||||||
appendRow(sheet, 3, null, "记录总数", String.valueOf(list.size()));
|
appendRow(sheet, 3, null, "记录总数", String.valueOf(list.size()));
|
||||||
appendRow(sheet, 5, headerStyle, "客户编码", "姓名", "性别", "年龄", "电话", "地址", "病症", "备注", "邀请人", "邀请客户数", "创建时间");
|
appendRow(sheet, 5, headerStyle, "客户编码", "姓名", "性别", "出生日期(公历)", "出生日期历法", "年龄", "电话", "地址", "病症", "备注", "邀请人", "邀请客户数", "创建时间");
|
||||||
int rowIndex = 6;
|
int rowIndex = 6;
|
||||||
for (GaoCustomer customer : list) {
|
for (GaoCustomer customer : list) {
|
||||||
appendRow(sheet, rowIndex, null,
|
appendRow(sheet, rowIndex, null,
|
||||||
text(customer.getCode()),
|
text(customer.getCode()),
|
||||||
text(customer.getName()),
|
text(customer.getName()),
|
||||||
formatGender(customer),
|
formatGender(customer),
|
||||||
|
text(customer.getBirthdate()),
|
||||||
|
formatBirthdateCalendar(customer),
|
||||||
customer.getAge() == null ? "" : String.valueOf(customer.getAge()),
|
customer.getAge() == null ? "" : String.valueOf(customer.getAge()),
|
||||||
text(customer.getTelephone()),
|
text(customer.getTelephone()),
|
||||||
text(customer.getAddress()),
|
text(customer.getAddress()),
|
||||||
@@ -194,7 +271,7 @@ public class GaoCustomerServiceImplement extends AbstractEntityService<GaoCustom
|
|||||||
);
|
);
|
||||||
rowIndex++;
|
rowIndex++;
|
||||||
}
|
}
|
||||||
for (int index = 0; index < 11; index++) {
|
for (int index = 0; index < 13; index++) {
|
||||||
sheet.autoSizeColumn(index);
|
sheet.autoSizeColumn(index);
|
||||||
sheet.setColumnWidth(index, Math.min(Math.max(sheet.getColumnWidth(index), 10 * 256), 36 * 256));
|
sheet.setColumnWidth(index, Math.min(Math.max(sheet.getColumnWidth(index), 10 * 256), 36 * 256));
|
||||||
}
|
}
|
||||||
@@ -214,6 +291,9 @@ public class GaoCustomerServiceImplement extends AbstractEntityService<GaoCustom
|
|||||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||||
@Override
|
@Override
|
||||||
public void saveInviteRelation(GaoCustomerInviteUpdateReq req) {
|
public void saveInviteRelation(GaoCustomerInviteUpdateReq req) {
|
||||||
|
Logger logger = new Logger(Logger.Module.GAO, "GAO_CUSTOMER_SAVE_INVITE_RELATION");
|
||||||
|
try {
|
||||||
|
logger.setContent(jackson.writeValueAsString(req));
|
||||||
TimiException.required(req, "not found invite req");
|
TimiException.required(req, "not found invite req");
|
||||||
TimiException.required(req.getCustomerId(), "not found invite req.customerId");
|
TimiException.required(req.getCustomerId(), "not found invite req.customerId");
|
||||||
GaoCustomer customer = super.get(req.getCustomerId());
|
GaoCustomer customer = super.get(req.getCustomerId());
|
||||||
@@ -222,17 +302,48 @@ public class GaoCustomerServiceImplement extends AbstractEntityService<GaoCustom
|
|||||||
checkEntity(customer, true);
|
checkEntity(customer, true);
|
||||||
super.update(customer);
|
super.update(customer);
|
||||||
syncIntroducerInvitedCount(oldIntroducerCustomerId, customer.getIntroducerCustomerId());
|
syncIntroducerInvitedCount(oldIntroducerCustomerId, customer.getIntroducerCustomerId());
|
||||||
|
logger.setLevel(Logger.Level.INFO);
|
||||||
|
logger.setResult(req.getCustomerId());
|
||||||
|
} 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("保存 GAO 客户邀请关系失败", e);
|
||||||
|
throw new TimiException(TimiCode.ERROR, "保存 GAO 客户邀请关系失败", e);
|
||||||
|
} finally {
|
||||||
|
loggerService.create(logger);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||||
@Override
|
@Override
|
||||||
public void deleteInviteRelation(String customerId) {
|
public void deleteInviteRelation(String customerId) {
|
||||||
|
Logger logger = new Logger(Logger.Module.GAO, "GAO_CUSTOMER_DELETE_INVITE_RELATION");
|
||||||
|
try {
|
||||||
|
logger.setContent(customerId);
|
||||||
TimiException.required(customerId, "not found customerId");
|
TimiException.required(customerId, "not found customerId");
|
||||||
GaoCustomer customer = super.get(customerId);
|
GaoCustomer customer = super.get(customerId);
|
||||||
String oldIntroducerCustomerId = customer.getIntroducerCustomerId();
|
String oldIntroducerCustomerId = customer.getIntroducerCustomerId();
|
||||||
customer.setIntroducerCustomerId(null);
|
customer.setIntroducerCustomerId(null);
|
||||||
super.update(customer);
|
super.update(customer);
|
||||||
changeInvitedCount(oldIntroducerCustomerId, -1L);
|
changeInvitedCount(oldIntroducerCustomerId, -1L);
|
||||||
|
logger.setLevel(Logger.Level.INFO);
|
||||||
|
logger.setResult(customerId);
|
||||||
|
} 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("删除 GAO 客户邀请关系失败", e);
|
||||||
|
throw new TimiException(TimiCode.ERROR, "删除 GAO 客户邀请关系失败", e);
|
||||||
|
} finally {
|
||||||
|
loggerService.create(logger);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -285,6 +396,10 @@ public class GaoCustomerServiceImplement extends AbstractEntityService<GaoCustom
|
|||||||
GaoCustomer dbCustomer = null;
|
GaoCustomer dbCustomer = null;
|
||||||
entity.setCode(normalizeText(entity.getCode()));
|
entity.setCode(normalizeText(entity.getCode()));
|
||||||
entity.setIntroducerCustomerId(normalizeText(entity.getIntroducerCustomerId()));
|
entity.setIntroducerCustomerId(normalizeText(entity.getIntroducerCustomerId()));
|
||||||
|
if (entity.getBirthdateCalendar() == null) {
|
||||||
|
entity.setBirthdateCalendar(GaoCustomer.BirthdateCalendar.SOLAR);
|
||||||
|
}
|
||||||
|
refreshAge(entity);
|
||||||
if (requireId) {
|
if (requireId) {
|
||||||
TimiException.required(entity.getId(), "not found customer.id");
|
TimiException.required(entity.getId(), "not found customer.id");
|
||||||
dbCustomer = super.get(entity.getId());
|
dbCustomer = super.get(entity.getId());
|
||||||
@@ -314,6 +429,7 @@ public class GaoCustomerServiceImplement extends AbstractEntityService<GaoCustom
|
|||||||
if (customer == null) {
|
if (customer == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
refreshAge(customer);
|
||||||
loadIntroducerCustomer(List.of(customer));
|
loadIntroducerCustomer(List.of(customer));
|
||||||
if (TimiJava.isNotEmpty(customer.getCreatorUserId())) {
|
if (TimiJava.isNotEmpty(customer.getCreatorUserId())) {
|
||||||
customer.setCreatorUser(userService.get(customer.getCreatorUserId()));
|
customer.setCreatorUser(userService.get(customer.getCreatorUserId()));
|
||||||
@@ -322,9 +438,22 @@ public class GaoCustomerServiceImplement extends AbstractEntityService<GaoCustom
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void loadListTransient(List<GaoCustomer> customerList) {
|
private void loadListTransient(List<GaoCustomer> customerList) {
|
||||||
|
if (customerList != null) {
|
||||||
|
customerList.forEach(this::refreshAge);
|
||||||
|
}
|
||||||
loadAttachmentList(customerList);
|
loadAttachmentList(customerList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 根据出生日期计算当前周岁。出生日期为空时保留旧数据中的手工年龄。
|
||||||
|
private void refreshAge(GaoCustomer customer) {
|
||||||
|
if (customer.getBirthdate() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LocalDate today = LocalDate.now();
|
||||||
|
TimiException.requiredTrue(!customer.getBirthdate().isAfter(today), "customer.birthdate invalid");
|
||||||
|
customer.setAge(Period.between(customer.getBirthdate(), today).getYears());
|
||||||
|
}
|
||||||
|
|
||||||
private void loadIntroducerCustomer(List<GaoCustomer> customerList) {
|
private void loadIntroducerCustomer(List<GaoCustomer> customerList) {
|
||||||
if (customerList == null || customerList.isEmpty()) {
|
if (customerList == null || customerList.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
@@ -442,6 +571,13 @@ public class GaoCustomerServiceImplement extends AbstractEntityService<GaoCustom
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String formatBirthdateCalendar(GaoCustomer customer) {
|
||||||
|
if (customer.getBirthdateCalendar() == null) {
|
||||||
|
return "公历";
|
||||||
|
}
|
||||||
|
return customer.getBirthdateCalendar() == GaoCustomer.BirthdateCalendar.LUNAR ? "农历" : "公历";
|
||||||
|
}
|
||||||
|
|
||||||
private String formatExportTime(Long value) {
|
private String formatExportTime(Long value) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
return "";
|
return "";
|
||||||
|
|||||||
+289
-27
@@ -1,5 +1,6 @@
|
|||||||
package com.imyeyu.api.modules.gao.service.implement;
|
package com.imyeyu.api.modules.gao.service.implement;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
|
import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
|
||||||
import com.imyeyu.api.bean.ModuleCode;
|
import com.imyeyu.api.bean.ModuleCode;
|
||||||
import com.imyeyu.api.modules.common.entity.Attachment;
|
import com.imyeyu.api.modules.common.entity.Attachment;
|
||||||
@@ -16,6 +17,8 @@ import com.imyeyu.api.modules.gao.service.GaoRegistrationEventService;
|
|||||||
import com.imyeyu.api.modules.gao.service.GaoRegistrationEventRecordService;
|
import com.imyeyu.api.modules.gao.service.GaoRegistrationEventRecordService;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventPeriodStatView;
|
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventPeriodStatView;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerRegisterStatView;
|
import com.imyeyu.api.modules.gao.vo.GaoCustomerRegisterStatView;
|
||||||
|
import com.imyeyu.api.modules.gao.vo.GaoCustomerRegistrationDayStatView;
|
||||||
|
import com.imyeyu.api.modules.gao.vo.GaoCustomerRegistrationRankView;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoQuickRegistrationEventRecordReq;
|
import com.imyeyu.api.modules.gao.vo.GaoQuickRegistrationEventRecordReq;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordCalendarView;
|
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordCalendarView;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordCreateReq;
|
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordCreateReq;
|
||||||
@@ -25,18 +28,23 @@ import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordPeriodReq;
|
|||||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordRangeReq;
|
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordRangeReq;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordStatReq;
|
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordStatReq;
|
||||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordTrendStatReq;
|
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordTrendStatReq;
|
||||||
|
import com.imyeyu.api.modules.system.entity.Logger;
|
||||||
|
import com.imyeyu.api.modules.system.service.LoggerService;
|
||||||
import com.imyeyu.api.modules.user.service.RoleChecker;
|
import com.imyeyu.api.modules.user.service.RoleChecker;
|
||||||
import com.imyeyu.api.modules.user.service.UserLoginService;
|
import com.imyeyu.api.modules.user.service.UserLoginService;
|
||||||
import com.imyeyu.api.modules.user.service.UserService;
|
import com.imyeyu.api.modules.user.service.UserService;
|
||||||
import com.imyeyu.api.modules.user.mapper.UserMapper;
|
import com.imyeyu.api.modules.user.mapper.UserMapper;
|
||||||
import com.imyeyu.java.TimiJava;
|
import com.imyeyu.java.TimiJava;
|
||||||
|
import com.imyeyu.java.bean.timi.TimiCode;
|
||||||
import com.imyeyu.java.bean.timi.TimiException;
|
import com.imyeyu.java.bean.timi.TimiException;
|
||||||
|
import com.imyeyu.spring.TimiSpring;
|
||||||
import com.imyeyu.spring.bean.Page;
|
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 com.imyeyu.utils.Time;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.poi.ss.usermodel.CellStyle;
|
import org.apache.poi.ss.usermodel.CellStyle;
|
||||||
import org.apache.poi.ss.usermodel.Font;
|
import org.apache.poi.ss.usermodel.Font;
|
||||||
import org.apache.poi.ss.usermodel.Row;
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
@@ -47,6 +55,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
@@ -55,6 +64,7 @@ import java.time.temporal.ChronoUnit;
|
|||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -68,18 +78,21 @@ import java.util.stream.Collectors;
|
|||||||
///
|
///
|
||||||
/// @author Codex
|
/// @author Codex
|
||||||
/// @since 2026-07-27
|
/// @since 2026-07-27
|
||||||
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class GaoRegistrationEventRecordServiceImplement extends AbstractEntityService<GaoRegistrationEventRecord, String> implements GaoRegistrationEventRecordService {
|
public class GaoRegistrationEventRecordServiceImplement extends AbstractEntityService<GaoRegistrationEventRecord, String> implements GaoRegistrationEventRecordService {
|
||||||
|
|
||||||
private static final DateTimeFormatter DAY_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
|
private static final DateTimeFormatter DAY_FORMATTER = DateTimeFormatter.BASIC_ISO_DATE;
|
||||||
private static final DateTimeFormatter EXPORT_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.systemDefault());
|
private static final DateTimeFormatter EXPORT_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.systemDefault());
|
||||||
|
|
||||||
private final GaoRegistrationEventRecordMapper mapper;
|
private final GaoRegistrationEventRecordMapper mapper;
|
||||||
|
private final ObjectMapper jackson;
|
||||||
private final GaoCustomerMapper customerMapper;
|
private final GaoCustomerMapper customerMapper;
|
||||||
private final GaoRegistrationEventMapper registrationEventMapper;
|
private final GaoRegistrationEventMapper registrationEventMapper;
|
||||||
private final UserMapper userMapper;
|
private final UserMapper userMapper;
|
||||||
private final AttachmentService attachmentService;
|
private final AttachmentService attachmentService;
|
||||||
|
private final LoggerService loggerService;
|
||||||
private final RoleChecker roleChecker;
|
private final RoleChecker roleChecker;
|
||||||
private final UserLoginService userLoginService;
|
private final UserLoginService userLoginService;
|
||||||
private final UserService userService;
|
private final UserService userService;
|
||||||
@@ -93,45 +106,123 @@ public class GaoRegistrationEventRecordServiceImplement extends AbstractEntitySe
|
|||||||
|
|
||||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||||
@Override
|
@Override
|
||||||
public GaoRegistrationEventRecord createRecord(GaoRegistrationEventRecordCreateReq req) {
|
public List<GaoRegistrationEventRecord> createRecords(GaoRegistrationEventRecordCreateReq req) {
|
||||||
|
Logger logger = new Logger(Logger.Module.GAO, "GAO_REGISTRATION_EVENT_RECORD_BATCH_CREATE");
|
||||||
|
try {
|
||||||
TimiException.required(req, "not found req");
|
TimiException.required(req, "not found req");
|
||||||
TimiException.required(req.getRegistrationEventId(), "not found req.registrationEventId");
|
TimiException.requiredTrue(req.getCustomerIdList() != null && !req.getCustomerIdList().isEmpty(), "customerIdList is empty");
|
||||||
String customerId = resolveCustomerId(req);
|
logger.setContent(jackson.writeValueAsString(req));
|
||||||
GaoRegistrationEvent registrationEvent = registrationEventService.get(req.getRegistrationEventId());
|
List<GaoRegistrationEventRecord> recordList = new ArrayList<>();
|
||||||
checkRegistrationEventPermission(registrationEvent);
|
for (int index = 0; index < req.getCustomerIdList().size(); index++) {
|
||||||
if (Boolean.TRUE.equals(registrationEvent.getRequirePhoto())) {
|
String customerId = req.getCustomerIdList().get(index);
|
||||||
TimiException.requiredTrue(req.getAttachmentIdList() != null && !req.getAttachmentIdList().isEmpty(), "required record photo");
|
GaoRegistrationEventRecordCreateReq customerReq = copyCreateReq(req);
|
||||||
|
customerReq.setAttachmentIdList(0 == index && canUseSourceTempFileList(req.getAttachmentIdList())
|
||||||
|
? req.getAttachmentIdList()
|
||||||
|
: duplicateTempFileList(req.getAttachmentIdList()));
|
||||||
|
recordList.add(doCreateRecord(customerReq, customerId));
|
||||||
|
}
|
||||||
|
logger.setLevel(Logger.Level.INFO);
|
||||||
|
logger.setResult(recordList.stream().map(GaoRegistrationEventRecord::getId).collect(Collectors.joining(",")));
|
||||||
|
return recordList;
|
||||||
|
} 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("批量新增 GAO 登记记录失败", e);
|
||||||
|
throw new TimiException(TimiCode.ERROR, "批量新增 GAO 登记记录失败", e);
|
||||||
|
} finally {
|
||||||
|
loggerService.create(logger);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GaoRegistrationEventRecord record = new GaoRegistrationEventRecord();
|
private List<String> duplicateTempFileList(List<String> sourceIdList) {
|
||||||
record.setCustomerId(customerId);
|
if (sourceIdList == null) {
|
||||||
record.setRegistrationEventId(req.getRegistrationEventId());
|
return null;
|
||||||
record.setOperatorUserId(userLoginService.getRequireLoginUserId());
|
}
|
||||||
record.setRemark(req.getRemark());
|
List<String> targetIdList = new ArrayList<>();
|
||||||
record.setRegisteredAt(TimiJava.defaultIfNull(req.getRegisteredAt(), Time.now()));
|
for (String sourceId : sourceIdList) {
|
||||||
super.create(record);
|
if (sourceId == null || sourceId.isBlank()) {
|
||||||
saveAttachment(record.getId(), buildPhotoAttachmentList(req.getAttachmentIdList()));
|
continue;
|
||||||
return get(record.getId());
|
}
|
||||||
|
Attachment source = attachmentService.get(sourceId.trim());
|
||||||
|
TimiException.required(source, "not found attachment");
|
||||||
|
TimiException.required(source.getMongoId(), "not found attachment.mongoId");
|
||||||
|
Attachment target = new Attachment();
|
||||||
|
target.setBizType(Attachment.BizType.TEMP_FILE);
|
||||||
|
target.setName(source.getName());
|
||||||
|
target.setInputStream(new ByteArrayInputStream(attachmentService.readAllByMongoId(source.getMongoId())));
|
||||||
|
attachmentService.create(target);
|
||||||
|
targetIdList.add(target.getId());
|
||||||
|
}
|
||||||
|
return targetIdList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean canUseSourceTempFileList(List<String> sourceIdList) {
|
||||||
|
if (sourceIdList == null || sourceIdList.isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (String sourceId : sourceIdList) {
|
||||||
|
if (sourceId == null || sourceId.isBlank()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Attachment source = attachmentService.get(sourceId.trim());
|
||||||
|
if (source == null || source.getBizType() != Attachment.BizType.TEMP_FILE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private GaoRegistrationEventRecordCreateReq copyCreateReq(GaoRegistrationEventRecordCreateReq source) {
|
||||||
|
GaoRegistrationEventRecordCreateReq target = new GaoRegistrationEventRecordCreateReq();
|
||||||
|
target.setRegistrationEventId(source.getRegistrationEventId());
|
||||||
|
target.setRemark(source.getRemark());
|
||||||
|
target.setRegisteredAt(source.getRegisteredAt());
|
||||||
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||||
@Override
|
@Override
|
||||||
public GaoRegistrationEventRecord quickRegister(GaoQuickRegistrationEventRecordReq req) {
|
public GaoRegistrationEventRecord quickRegister(GaoQuickRegistrationEventRecordReq req) {
|
||||||
|
Logger logger = new Logger(Logger.Module.GAO, "GAO_REGISTRATION_EVENT_RECORD_QUICK_REGISTER");
|
||||||
|
try {
|
||||||
|
logger.setContent(jackson.writeValueAsString(req));
|
||||||
TimiException.required(req, "not found req");
|
TimiException.required(req, "not found req");
|
||||||
TimiException.required(req.getCustomerCode(), "not found req.customerCode");
|
TimiException.required(req.getCustomerCode(), "not found req.customerCode");
|
||||||
TimiException.required(req.getRegistrationEventId(), "not found req.registrationEventId");
|
TimiException.required(req.getRegistrationEventId(), "not found req.registrationEventId");
|
||||||
GaoCustomer customer = customerService.getOrQuickCreateByCode(req.getCustomerCode());
|
GaoCustomer customer = customerService.getOrQuickCreateByCode(req.getCustomerCode());
|
||||||
GaoRegistrationEventRecordCreateReq recordReq = new GaoRegistrationEventRecordCreateReq();
|
GaoRegistrationEventRecordCreateReq recordReq = new GaoRegistrationEventRecordCreateReq();
|
||||||
recordReq.setCustomerId(customer.getId());
|
recordReq.setCustomerIdList(List.of(customer.getId()));
|
||||||
recordReq.setRegistrationEventId(req.getRegistrationEventId());
|
recordReq.setRegistrationEventId(req.getRegistrationEventId());
|
||||||
recordReq.setRemark(req.getRemark());
|
recordReq.setRemark(req.getRemark());
|
||||||
recordReq.setAttachmentIdList(req.getAttachmentIdList());
|
recordReq.setAttachmentIdList(req.getAttachmentIdList());
|
||||||
return createRecord(recordReq);
|
GaoRegistrationEventRecord record = createRecords(recordReq).get(0);
|
||||||
|
logger.setLevel(Logger.Level.INFO);
|
||||||
|
logger.setResult(record.getId());
|
||||||
|
return record;
|
||||||
|
} 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("GAO 快速登记失败", e);
|
||||||
|
throw new TimiException(TimiCode.ERROR, "GAO 快速登记失败", e);
|
||||||
|
} finally {
|
||||||
|
loggerService.create(logger);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||||
@Override
|
@Override
|
||||||
public void update(GaoRegistrationEventRecord entity) {
|
public void update(GaoRegistrationEventRecord entity) {
|
||||||
|
Logger logger = new Logger(Logger.Module.GAO, "GAO_REGISTRATION_EVENT_RECORD_UPDATE");
|
||||||
|
try {
|
||||||
|
logger.setContent(jackson.writeValueAsString(entity));
|
||||||
TimiException.required(entity, "not found record");
|
TimiException.required(entity, "not found record");
|
||||||
TimiException.required(entity.getId(), "not found record.id");
|
TimiException.required(entity.getId(), "not found record.id");
|
||||||
TimiException.required(entity.getCustomerId(), "not found record.customerId");
|
TimiException.required(entity.getCustomerId(), "not found record.customerId");
|
||||||
@@ -142,6 +233,20 @@ public class GaoRegistrationEventRecordServiceImplement extends AbstractEntitySe
|
|||||||
entity.setRegisteredAt(TimiJava.defaultIfNull(entity.getRegisteredAt(), Time.now()));
|
entity.setRegisteredAt(TimiJava.defaultIfNull(entity.getRegisteredAt(), Time.now()));
|
||||||
super.update(entity);
|
super.update(entity);
|
||||||
saveAttachment(entity.getId(), resolveAttachmentList(entity));
|
saveAttachment(entity.getId(), resolveAttachmentList(entity));
|
||||||
|
logger.setLevel(Logger.Level.INFO);
|
||||||
|
logger.setResult(entity.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("修改 GAO 登记记录失败", e);
|
||||||
|
throw new TimiException(TimiCode.ERROR, "修改 GAO 登记记录失败", e);
|
||||||
|
} finally {
|
||||||
|
loggerService.create(logger);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -277,6 +382,29 @@ public class GaoRegistrationEventRecordServiceImplement extends AbstractEntitySe
|
|||||||
return mapper.statAllCustomerByRange(req.getBeginRegisteredAt(), req.getEndRegisteredAt());
|
return mapper.statAllCustomerByRange(req.getBeginRegisteredAt(), req.getEndRegisteredAt());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<GaoCustomerRegistrationRankView> listCustomerRegistrationRank(GaoRegistrationEventRecordRangeReq req) {
|
||||||
|
GaoRegistrationEventRecordRangeReq rangeReq = TimiJava.defaultIfNull(req, new GaoRegistrationEventRecordRangeReq());
|
||||||
|
if (rangeReq.getBeginRegisteredAt() != null || rangeReq.getEndRegisteredAt() != null) {
|
||||||
|
checkStatRange(rangeReq.getBeginRegisteredAt(), rangeReq.getEndRegisteredAt());
|
||||||
|
}
|
||||||
|
List<GaoCustomerRegistrationDayStatView> dayStatList = mapper.statCustomerRegistrationDay(rangeReq);
|
||||||
|
Map<String, List<GaoCustomerRegistrationDayStatView>> customerDayStatMap = dayStatList.stream()
|
||||||
|
.collect(Collectors.groupingBy(GaoCustomerRegistrationDayStatView::getCustomerId));
|
||||||
|
List<GaoCustomerRegistrationRankView> rankList = new ArrayList<>();
|
||||||
|
for (Map.Entry<String, List<GaoCustomerRegistrationDayStatView>> entry : customerDayStatMap.entrySet()) {
|
||||||
|
rankList.add(buildCustomerRegistrationRank(entry.getValue()));
|
||||||
|
}
|
||||||
|
rankList.sort(Comparator
|
||||||
|
.comparing(GaoCustomerRegistrationRankView::getTotalRegistrationDays, Comparator.nullsLast(Comparator.reverseOrder()))
|
||||||
|
.thenComparing(GaoCustomerRegistrationRankView::getTotalRegistrationCount, Comparator.nullsLast(Comparator.reverseOrder()))
|
||||||
|
.thenComparing(GaoCustomerRegistrationRankView::getLatestRegisteredAt, Comparator.nullsLast(Comparator.reverseOrder())));
|
||||||
|
for (int index = 0; index < rankList.size(); index++) {
|
||||||
|
rankList.get(index).setRank(index + 1);
|
||||||
|
}
|
||||||
|
return rankList;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<GaoRegistrationEventRecordDailyStatView> statDailyByCustomerAndRegistrationEvent(GaoRegistrationEventRecordTrendStatReq req) {
|
public List<GaoRegistrationEventRecordDailyStatView> statDailyByCustomerAndRegistrationEvent(GaoRegistrationEventRecordTrendStatReq req) {
|
||||||
TimiException.required(req, "not found req");
|
TimiException.required(req, "not found req");
|
||||||
@@ -299,21 +427,118 @@ public class GaoRegistrationEventRecordServiceImplement extends AbstractEntitySe
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String resolveCustomerId(GaoRegistrationEventRecordCreateReq req) {
|
private String resolveCustomerId(String customerId) {
|
||||||
if (TimiJava.isNotEmpty(req.getCustomerId())) {
|
TimiException.required(customerId, "not found customerId");
|
||||||
customerService.get(req.getCustomerId());
|
customerService.get(customerId);
|
||||||
return req.getCustomerId();
|
return customerId;
|
||||||
}
|
}
|
||||||
TimiException.required(req.getCustomerCode(), "not found req.customerCode");
|
|
||||||
GaoCustomer customer = customerService.getByCode(req.getCustomerCode());
|
private GaoRegistrationEventRecord doCreateRecord(GaoRegistrationEventRecordCreateReq req, String customerId) {
|
||||||
return customer.getId();
|
TimiException.required(req, "not found req");
|
||||||
|
TimiException.required(req.getRegistrationEventId(), "not found req.registrationEventId");
|
||||||
|
customerId = resolveCustomerId(customerId);
|
||||||
|
GaoRegistrationEvent registrationEvent = registrationEventService.get(req.getRegistrationEventId());
|
||||||
|
checkRegistrationEventPermission(registrationEvent);
|
||||||
|
long registeredAt = TimiJava.defaultIfNull(req.getRegisteredAt(), Time.now());
|
||||||
|
checkRegistrationEventCreatable(registrationEvent, customerId, registeredAt);
|
||||||
|
if (Boolean.TRUE.equals(registrationEvent.getRequirePhoto())) {
|
||||||
|
TimiException.requiredTrue(req.getAttachmentIdList() != null && !req.getAttachmentIdList().isEmpty(), "required record photo");
|
||||||
|
}
|
||||||
|
|
||||||
|
GaoRegistrationEventRecord record = new GaoRegistrationEventRecord();
|
||||||
|
record.setCustomerId(customerId);
|
||||||
|
record.setRegistrationEventId(req.getRegistrationEventId());
|
||||||
|
record.setOperatorUserId(userLoginService.getRequireLoginUserId());
|
||||||
|
record.setRemark(req.getRemark());
|
||||||
|
record.setRegisteredAt(registeredAt);
|
||||||
|
super.create(record);
|
||||||
|
saveAttachment(record.getId(), buildPhotoAttachmentList(req.getAttachmentIdList()));
|
||||||
|
return get(record.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkRegistrationEventPermission(GaoRegistrationEvent registrationEvent) {
|
private void checkRegistrationEventPermission(GaoRegistrationEvent registrationEvent) {
|
||||||
List<String> roleCodeList = registrationEventService.listRoleCode(registrationEvent.getId());
|
List<String> roleCodeList = registrationEventService.listRoleCode(registrationEvent.getId());
|
||||||
if (roleCodeList != null && !roleCodeList.isEmpty()) {
|
TimiException.requiredTrue(roleCodeList != null && !roleCodeList.isEmpty(), "登记事件未配置可登记角色");
|
||||||
roleChecker.checkAny(ModuleCode.GAO, roleCodeList.toArray(String[]::new));
|
roleChecker.checkAny(ModuleCode.GAO, roleCodeList.toArray(String[]::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkRegistrationEventCreatable(GaoRegistrationEvent registrationEvent, String customerId, long registeredAt) {
|
||||||
|
TimiException.requiredTrue(registrationEvent.getStatus() == null || registrationEvent.getStatus() == GaoRegistrationEvent.Status.ACTIVE, "登记事件不可登记");
|
||||||
|
TimiException.requiredTrue(registrationEvent.getBeginAt() == null || registrationEvent.getBeginAt() <= registeredAt, "登记事件未到可登记时间");
|
||||||
|
TimiException.requiredTrue(registrationEvent.getEndAt() == null || registeredAt <= registrationEvent.getEndAt(), "登记事件已过可登记时间");
|
||||||
|
GaoRegistrationEvent.LimitType limitType = TimiJava.defaultIfNull(registrationEvent.getLimitType(), GaoRegistrationEvent.LimitType.NONE);
|
||||||
|
switch (limitType) {
|
||||||
|
case DAILY_HALF_DAY -> checkRegistrationLimitRange(customerId, registrationEvent.getId(), getHalfDayBegin(registeredAt), getHalfDayEnd(registeredAt), "该客户当前半日已登记该事件");
|
||||||
|
case NATURAL_DAY -> checkRegistrationLimitRange(customerId, registrationEvent.getId(), getDayBegin(registeredAt), getDayEnd(registeredAt), "该客户当日已登记该事件");
|
||||||
|
case INTERVAL_HOUR -> checkIntervalHourRegistrationLimit(registrationEvent, customerId, registeredAt);
|
||||||
|
case NATURAL_MONTH -> checkRegistrationLimitRange(customerId, registrationEvent.getId(), getMonthBegin(registeredAt), getMonthEnd(registeredAt), "该客户当月已登记该事件");
|
||||||
|
case TOTAL_LIMIT -> checkTotalRegistrationLimit(registrationEvent);
|
||||||
|
case CUSTOMER_TOTAL_LIMIT -> checkCustomerTotalRegistrationLimit(registrationEvent, customerId);
|
||||||
|
default -> {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkRegistrationLimitRange(String customerId, String registrationEventId, long beginRegisteredAt, long endRegisteredAt, String message) {
|
||||||
|
Long count = mapper.countByCustomerIdAndRegistrationEventIdRange(customerId, registrationEventId, beginRegisteredAt, endRegisteredAt);
|
||||||
|
TimiException.requiredTrue(TimiJava.defaultIfNull(count, 0L) < 1, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkIntervalHourRegistrationLimit(GaoRegistrationEvent registrationEvent, String customerId, long registeredAt) {
|
||||||
|
Integer limitValue = registrationEvent.getLimitValue();
|
||||||
|
TimiException.requiredTrue(limitValue != null && 0 < limitValue, "登记事件间隔小时配置错误");
|
||||||
|
long beginRegisteredAt = registeredAt - limitValue * 60L * 60L * 1000L + 1;
|
||||||
|
checkRegistrationLimitRange(customerId, registrationEvent.getId(), beginRegisteredAt, registeredAt, "该客户登记该事件间隔不足");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkCustomerTotalRegistrationLimit(GaoRegistrationEvent registrationEvent, String customerId) {
|
||||||
|
Integer limitValue = registrationEvent.getLimitValue();
|
||||||
|
TimiException.requiredTrue(limitValue != null && 0 < limitValue, "登记事件单客户总次数配置错误");
|
||||||
|
Long count = mapper.countByCustomerIdAndRegistrationEventId(customerId, registrationEvent.getId());
|
||||||
|
TimiException.requiredTrue(TimiJava.defaultIfNull(count, 0L) < limitValue, "该客户登记该事件次数已达上限");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkTotalRegistrationLimit(GaoRegistrationEvent registrationEvent) {
|
||||||
|
Integer limitValue = registrationEvent.getLimitValue();
|
||||||
|
TimiException.requiredTrue(limitValue != null && 0 < limitValue, "登记事件总次数配置错误");
|
||||||
|
Long count = mapper.countByRegistrationEventId(registrationEvent.getId());
|
||||||
|
TimiException.requiredTrue(TimiJava.defaultIfNull(count, 0L) < limitValue, "登记事件总次数已达上限");
|
||||||
|
}
|
||||||
|
|
||||||
|
private long getDayBegin(long registeredAt) {
|
||||||
|
ZoneId zoneId = ZoneId.systemDefault();
|
||||||
|
return Instant.ofEpochMilli(registeredAt).atZone(zoneId).toLocalDate().atStartOfDay(zoneId).toInstant().toEpochMilli();
|
||||||
|
}
|
||||||
|
|
||||||
|
private long getDayEnd(long registeredAt) {
|
||||||
|
ZoneId zoneId = ZoneId.systemDefault();
|
||||||
|
return Instant.ofEpochMilli(registeredAt).atZone(zoneId).toLocalDate().plusDays(1).atStartOfDay(zoneId).toInstant().toEpochMilli() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long getHalfDayBegin(long registeredAt) {
|
||||||
|
ZoneId zoneId = ZoneId.systemDefault();
|
||||||
|
int hour = Instant.ofEpochMilli(registeredAt).atZone(zoneId).getHour();
|
||||||
|
long dayBegin = getDayBegin(registeredAt);
|
||||||
|
return hour < 12 ? dayBegin : dayBegin + 12L * 60L * 60L * 1000L;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long getHalfDayEnd(long registeredAt) {
|
||||||
|
ZoneId zoneId = ZoneId.systemDefault();
|
||||||
|
int hour = Instant.ofEpochMilli(registeredAt).atZone(zoneId).getHour();
|
||||||
|
long dayBegin = getDayBegin(registeredAt);
|
||||||
|
return hour < 12 ? dayBegin + 12L * 60L * 60L * 1000L - 1 : getDayEnd(registeredAt);
|
||||||
|
}
|
||||||
|
|
||||||
|
private long getMonthBegin(long registeredAt) {
|
||||||
|
ZoneId zoneId = ZoneId.systemDefault();
|
||||||
|
LocalDate date = Instant.ofEpochMilli(registeredAt).atZone(zoneId).toLocalDate();
|
||||||
|
return date.withDayOfMonth(1).atStartOfDay(zoneId).toInstant().toEpochMilli();
|
||||||
|
}
|
||||||
|
|
||||||
|
private long getMonthEnd(long registeredAt) {
|
||||||
|
ZoneId zoneId = ZoneId.systemDefault();
|
||||||
|
LocalDate date = Instant.ofEpochMilli(registeredAt).atZone(zoneId).toLocalDate();
|
||||||
|
return date.withDayOfMonth(1).plusMonths(1).atStartOfDay(zoneId).toInstant().toEpochMilli() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkStatRange(Long beginRegisteredAt, Long endRegisteredAt) {
|
private void checkStatRange(Long beginRegisteredAt, Long endRegisteredAt) {
|
||||||
@@ -356,6 +581,43 @@ public class GaoRegistrationEventRecordServiceImplement extends AbstractEntitySe
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private GaoCustomerRegistrationRankView buildCustomerRegistrationRank(List<GaoCustomerRegistrationDayStatView> dayStatList) {
|
||||||
|
List<GaoCustomerRegistrationDayStatView> sortedDayStatList = dayStatList.stream()
|
||||||
|
.sorted(Comparator.comparing(GaoCustomerRegistrationDayStatView::getDateValue, Comparator.nullsLast(Comparator.reverseOrder())))
|
||||||
|
.toList();
|
||||||
|
GaoCustomerRegistrationDayStatView first = sortedDayStatList.get(0);
|
||||||
|
GaoCustomerRegistrationRankView view = new GaoCustomerRegistrationRankView();
|
||||||
|
view.setCustomerId(first.getCustomerId());
|
||||||
|
view.setCustomerCode(first.getCustomerCode());
|
||||||
|
view.setCustomerName(first.getCustomerName());
|
||||||
|
view.setCustomerPhotoAttachmentId(first.getCustomerPhotoAttachmentId());
|
||||||
|
view.setTotalRegistrationDays((long) sortedDayStatList.size());
|
||||||
|
view.setTotalRegistrationCount(sortedDayStatList.stream().mapToLong(item -> TimiJava.defaultIfNull(item.getDailyCount(), 0L)).sum());
|
||||||
|
view.setLatestRegisteredAt(sortedDayStatList.stream().map(GaoCustomerRegistrationDayStatView::getLatestRegisteredAt).filter(Objects::nonNull).max(Long::compareTo).orElse(null));
|
||||||
|
view.setRecentContinuousRegistrationDays(countRecentContinuousRegistrationDays(sortedDayStatList));
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long countRecentContinuousRegistrationDays(List<GaoCustomerRegistrationDayStatView> sortedDayStatList) {
|
||||||
|
if (sortedDayStatList.isEmpty() || sortedDayStatList.get(0).getDateValue() == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
LocalDate expectedDate = LocalDate.parse(String.valueOf(sortedDayStatList.get(0).getDateValue()), DAY_FORMATTER);
|
||||||
|
long count = 0;
|
||||||
|
for (GaoCustomerRegistrationDayStatView item : sortedDayStatList) {
|
||||||
|
if (item.getDateValue() == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
LocalDate date = LocalDate.parse(String.valueOf(item.getDateValue()), DAY_FORMATTER);
|
||||||
|
if (!date.equals(expectedDate)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
expectedDate = expectedDate.minusDays(1);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
private void loadTransient(List<GaoRegistrationEventRecord> recordList) {
|
private void loadTransient(List<GaoRegistrationEventRecord> recordList) {
|
||||||
if (recordList == null || recordList.isEmpty()) {
|
if (recordList == null || recordList.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
+137
-23
@@ -1,17 +1,24 @@
|
|||||||
package com.imyeyu.api.modules.gao.service.implement;
|
package com.imyeyu.api.modules.gao.service.implement;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
|
import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
|
||||||
import com.imyeyu.api.modules.gao.entity.GaoRegistrationEventRoleRelation;
|
|
||||||
import com.imyeyu.api.modules.gao.entity.GaoRegistrationEvent;
|
import com.imyeyu.api.modules.gao.entity.GaoRegistrationEvent;
|
||||||
import com.imyeyu.api.modules.gao.mapper.GaoRegistrationEventRoleRelationMapper;
|
import com.imyeyu.api.modules.gao.entity.GaoRegistrationEventRoleRelation;
|
||||||
import com.imyeyu.api.modules.gao.mapper.GaoRegistrationEventMapper;
|
import com.imyeyu.api.modules.gao.mapper.GaoRegistrationEventMapper;
|
||||||
|
import com.imyeyu.api.modules.gao.mapper.GaoRegistrationEventRoleRelationMapper;
|
||||||
import com.imyeyu.api.modules.gao.service.GaoRegistrationEventService;
|
import com.imyeyu.api.modules.gao.service.GaoRegistrationEventService;
|
||||||
|
import com.imyeyu.api.modules.system.entity.Logger;
|
||||||
|
import com.imyeyu.api.modules.system.service.LoggerService;
|
||||||
|
import com.imyeyu.java.TimiJava;
|
||||||
|
import com.imyeyu.java.bean.timi.TimiCode;
|
||||||
import com.imyeyu.java.bean.timi.TimiException;
|
import com.imyeyu.java.bean.timi.TimiException;
|
||||||
import com.imyeyu.spring.bean.Page;
|
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;
|
||||||
|
|
||||||
@@ -25,12 +32,17 @@ import java.util.stream.Collectors;
|
|||||||
///
|
///
|
||||||
/// 登记事件服务实现
|
/// 登记事件服务实现
|
||||||
///
|
///
|
||||||
/// @author Codex
|
/// @author 夜雨
|
||||||
/// @since 2026-07-27
|
/// @since 2026-07-27 09:00
|
||||||
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class GaoRegistrationEventServiceImplement extends AbstractEntityService<GaoRegistrationEvent, String> implements GaoRegistrationEventService {
|
public class GaoRegistrationEventServiceImplement extends AbstractEntityService<GaoRegistrationEvent, String> implements GaoRegistrationEventService {
|
||||||
|
|
||||||
|
private final ObjectMapper jackson;
|
||||||
|
|
||||||
|
private final LoggerService loggerService;
|
||||||
|
|
||||||
private final GaoRegistrationEventMapper mapper;
|
private final GaoRegistrationEventMapper mapper;
|
||||||
private final GaoRegistrationEventRoleRelationMapper roleRelationMapper;
|
private final GaoRegistrationEventRoleRelationMapper roleRelationMapper;
|
||||||
|
|
||||||
@@ -42,6 +54,7 @@ public class GaoRegistrationEventServiceImplement extends AbstractEntityService<
|
|||||||
@Override
|
@Override
|
||||||
public PageResult<GaoRegistrationEvent> pageWithRegistrationEventLimit(Page<GaoRegistrationEvent> page) {
|
public PageResult<GaoRegistrationEvent> pageWithRegistrationEventLimit(Page<GaoRegistrationEvent> page) {
|
||||||
PageResult<GaoRegistrationEvent> result = page(page);
|
PageResult<GaoRegistrationEvent> result = page(page);
|
||||||
|
result.setList(result.getList().stream().filter(item -> item.getStatus() != GaoRegistrationEvent.Status.DELETED).toList());
|
||||||
loadRegistrationEventLimit(result.getList());
|
loadRegistrationEventLimit(result.getList());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -49,24 +62,90 @@ public class GaoRegistrationEventServiceImplement extends AbstractEntityService<
|
|||||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||||
@Override
|
@Override
|
||||||
public void create(GaoRegistrationEvent entity) {
|
public void create(GaoRegistrationEvent entity) {
|
||||||
|
Logger logger = new Logger(Logger.Module.GAO, "GAO_REGISTRATION_EVENT_CREATE");
|
||||||
|
try {
|
||||||
|
logger.setContent(jackson.writeValueAsString(entity));
|
||||||
checkEntity(entity, false);
|
checkEntity(entity, false);
|
||||||
super.create(entity);
|
super.create(entity);
|
||||||
saveRoleRelation(entity.getId(), entity.getRoleCodeList());
|
saveRoleRelation(entity.getId(), entity.getRoleCodeList());
|
||||||
|
logger.setLevel(Logger.Level.INFO);
|
||||||
|
logger.setResult(entity.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("新增 GAO 登记事件失败", e);
|
||||||
|
throw new TimiException(TimiCode.ERROR, "新增 GAO 登记事件失败", e);
|
||||||
|
} finally {
|
||||||
|
loggerService.create(logger);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||||
@Override
|
@Override
|
||||||
public void update(GaoRegistrationEvent entity) {
|
public void update(GaoRegistrationEvent entity) {
|
||||||
|
Logger logger = new Logger(Logger.Module.GAO, "GAO_REGISTRATION_EVENT_UPDATE");
|
||||||
|
try {
|
||||||
|
logger.setContent(jackson.writeValueAsString(entity));
|
||||||
|
Integer sort = entity.getSort();
|
||||||
checkEntity(entity, true);
|
checkEntity(entity, true);
|
||||||
super.update(entity);
|
GaoRegistrationEvent current = get(entity.getId());
|
||||||
|
current.setName(entity.getName());
|
||||||
|
current.setDescription(entity.getDescription());
|
||||||
|
current.setColor(entity.getColor());
|
||||||
|
current.setStatus(entity.getStatus());
|
||||||
|
current.setRequirePhoto(entity.getRequirePhoto());
|
||||||
|
current.setLimitType(entity.getLimitType());
|
||||||
|
current.setLimitValue(entity.getLimitValue());
|
||||||
|
current.setBeginAt(entity.getBeginAt());
|
||||||
|
current.setEndAt(entity.getEndAt());
|
||||||
|
if (sort != null) {
|
||||||
|
current.setSort(sort);
|
||||||
|
}
|
||||||
|
mapper.update(current);
|
||||||
saveRoleRelation(entity.getId(), entity.getRoleCodeList());
|
saveRoleRelation(entity.getId(), entity.getRoleCodeList());
|
||||||
|
logger.setLevel(Logger.Level.INFO);
|
||||||
|
logger.setResult(entity.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("修改 GAO 登记事件失败", e);
|
||||||
|
throw new TimiException(TimiCode.ERROR, "修改 GAO 登记事件失败", e);
|
||||||
|
} finally {
|
||||||
|
loggerService.create(logger);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||||
@Override
|
@Override
|
||||||
public void delete(String id) {
|
public void delete(String id) {
|
||||||
roleRelationMapper.deleteByRegistrationEventId(id);
|
Logger logger = new Logger(Logger.Module.GAO, "GAO_REGISTRATION_EVENT_DELETE");
|
||||||
super.delete(id);
|
try {
|
||||||
|
logger.setContent(id);
|
||||||
|
GaoRegistrationEvent entity = get(id);
|
||||||
|
entity.setStatus(GaoRegistrationEvent.Status.DELETED);
|
||||||
|
super.update(entity);
|
||||||
|
logger.setLevel(Logger.Level.INFO);
|
||||||
|
logger.setResult(id);
|
||||||
|
} 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("删除 GAO 登记事件失败", e);
|
||||||
|
throw new TimiException(TimiCode.ERROR, "删除 GAO 登记事件失败", e);
|
||||||
|
} finally {
|
||||||
|
loggerService.create(logger);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -78,8 +157,9 @@ public class GaoRegistrationEventServiceImplement extends AbstractEntityService<
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<GaoRegistrationEvent> listEnabled() {
|
public List<GaoRegistrationEvent> listEnabled() {
|
||||||
List<GaoRegistrationEvent> list = mapper.selectEnabledList();
|
List<GaoRegistrationEvent> list = mapper.selectEnabledList(Time.now());
|
||||||
loadRegistrationEventLimit(list);
|
loadRegistrationEventLimit(list);
|
||||||
|
list = list.stream().filter(item -> !TimiJava.isEmpty(item.getRoleCodeList())).toList();
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,23 +168,66 @@ public class GaoRegistrationEventServiceImplement extends AbstractEntityService<
|
|||||||
return roleRelationMapper.selectRoleCodeListByRegistrationEventId(registrationEventId);
|
return roleRelationMapper.selectRoleCodeListByRegistrationEventId(registrationEventId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||||
|
@Override
|
||||||
|
public void sort(List<String> idList) {
|
||||||
|
if (idList == null || idList.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<String> distinctIdList = new ArrayList<>(new LinkedHashSet<>(idList));
|
||||||
|
Map<String, GaoRegistrationEvent> eventMap = mapper.selectByIdList(distinctIdList).stream().collect(Collectors.toMap(GaoRegistrationEvent::getId, item -> item));
|
||||||
|
TimiException.requiredTrue(eventMap.size() == distinctIdList.size(), "not found registrationEvent");
|
||||||
|
for (int index = 0; index < distinctIdList.size(); index++) {
|
||||||
|
GaoRegistrationEvent registrationEvent = eventMap.get(distinctIdList.get(index));
|
||||||
|
registrationEvent.setSort(index);
|
||||||
|
mapper.update(registrationEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void checkEntity(GaoRegistrationEvent entity, boolean requireId) {
|
private void checkEntity(GaoRegistrationEvent entity, boolean requireId) {
|
||||||
TimiException.required(entity, "not found registrationEvent");
|
TimiException.required(entity, "not found registrationEvent");
|
||||||
if (requireId) {
|
if (requireId) {
|
||||||
TimiException.required(entity.getId(), "not found registrationEvent.id");
|
TimiException.required(entity.getId(), "not found registrationEvent.id");
|
||||||
}
|
}
|
||||||
TimiException.required(entity.getName(), "not found registrationEvent.name");
|
TimiException.required(entity.getName(), "not found registrationEvent.name");
|
||||||
if (entity.getEnabled() == null) {
|
if (entity.getStatus() == null) {
|
||||||
entity.setEnabled(true);
|
entity.setStatus(GaoRegistrationEvent.Status.ACTIVE);
|
||||||
}
|
}
|
||||||
if (entity.getRequirePhoto() == null) {
|
if (entity.getRequirePhoto() == null) {
|
||||||
entity.setRequirePhoto(false);
|
entity.setRequirePhoto(false);
|
||||||
}
|
}
|
||||||
|
if (entity.getLimitType() == null) {
|
||||||
|
entity.setLimitType(GaoRegistrationEvent.LimitType.NONE);
|
||||||
|
}
|
||||||
|
TimiException.requiredTrue(entity.getRoleCodeList() != null && entity.getRoleCodeList()
|
||||||
|
.stream()
|
||||||
|
.anyMatch(item -> item != null && !item.isBlank()), "not found registrationEvent.roleCodeList");
|
||||||
|
checkRegistrationLimit(entity);
|
||||||
|
checkRegisterablePeriod(entity);
|
||||||
|
if (entity.getColor() != null) {
|
||||||
|
entity.setColor(entity.getColor().trim());
|
||||||
|
}
|
||||||
if (entity.getSort() == null) {
|
if (entity.getSort() == null) {
|
||||||
entity.setSort(0);
|
entity.setSort(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkRegistrationLimit(GaoRegistrationEvent entity) {
|
||||||
|
if (entity.getLimitType() == GaoRegistrationEvent.LimitType.INTERVAL_HOUR || entity.getLimitType() == GaoRegistrationEvent.LimitType.TOTAL_LIMIT || entity.getLimitType() == GaoRegistrationEvent.LimitType.CUSTOMER_TOTAL_LIMIT) {
|
||||||
|
TimiException.required(entity.getLimitValue(), "not found registrationEvent.limitValue");
|
||||||
|
TimiException.requiredTrue(0 < entity.getLimitValue(), "registrationEvent.limitValue lte 0");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
entity.setLimitValue(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkRegisterablePeriod(GaoRegistrationEvent entity) {
|
||||||
|
if (entity.getBeginAt() == null && entity.getEndAt() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
TimiException.requiredTrue(entity.getBeginAt() == null || entity.getEndAt() == null || entity.getBeginAt() <= entity.getEndAt(), "registrationEvent.beginAt gt registrationEvent.endAt");
|
||||||
|
}
|
||||||
|
|
||||||
private void saveRoleRelation(String registrationEventId, List<String> roleCodeList) {
|
private void saveRoleRelation(String registrationEventId, List<String> roleCodeList) {
|
||||||
roleRelationMapper.deleteByRegistrationEventId(registrationEventId);
|
roleRelationMapper.deleteByRegistrationEventId(registrationEventId);
|
||||||
if (roleCodeList == null || roleCodeList.isEmpty()) {
|
if (roleCodeList == null || roleCodeList.isEmpty()) {
|
||||||
@@ -122,23 +245,14 @@ public class GaoRegistrationEventServiceImplement extends AbstractEntityService<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadRegistrationEventLimit(GaoRegistrationEvent registrationEvent) {
|
|
||||||
registrationEvent.setRoleCodeList(roleRelationMapper.selectRoleCodeListByRegistrationEventId(registrationEvent.getId()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadRegistrationEventLimit(List<GaoRegistrationEvent> registrationEventList) {
|
private void loadRegistrationEventLimit(List<GaoRegistrationEvent> registrationEventList) {
|
||||||
if (registrationEventList == null || registrationEventList.isEmpty()) {
|
if (registrationEventList == null || registrationEventList.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<String> registrationEventIdList = registrationEventList.stream()
|
List<String> registrationEventIdList = registrationEventList.stream().map(GaoRegistrationEvent::getId).distinct().toList();
|
||||||
.map(GaoRegistrationEvent::getId)
|
Map<String, List<String>> roleCodeMap = roleRelationMapper.selectByRegistrationEventIdList(new ArrayList<>(registrationEventIdList))
|
||||||
.distinct()
|
.stream()
|
||||||
.toList();
|
.collect(Collectors.groupingBy(GaoRegistrationEventRoleRelation::getRegistrationEventId, Collectors.mapping(GaoRegistrationEventRoleRelation::getRoleCode, Collectors.toList())));
|
||||||
Map<String, List<String>> roleCodeMap = roleRelationMapper.selectByRegistrationEventIdList(new ArrayList<>(registrationEventIdList)).stream()
|
|
||||||
.collect(Collectors.groupingBy(
|
|
||||||
GaoRegistrationEventRoleRelation::getRegistrationEventId,
|
|
||||||
Collectors.mapping(GaoRegistrationEventRoleRelation::getRoleCode, Collectors.toList())
|
|
||||||
));
|
|
||||||
for (GaoRegistrationEvent registrationEvent : registrationEventList) {
|
for (GaoRegistrationEvent registrationEvent : registrationEventList) {
|
||||||
registrationEvent.setRoleCodeList(roleCodeMap.getOrDefault(registrationEvent.getId(), List.of()));
|
registrationEvent.setRoleCodeList(roleCodeMap.getOrDefault(registrationEvent.getId(), List.of()));
|
||||||
}
|
}
|
||||||
|
|||||||
+42
@@ -1,10 +1,13 @@
|
|||||||
package com.imyeyu.api.modules.gao.service.implement;
|
package com.imyeyu.api.modules.gao.service.implement;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.imyeyu.api.bean.ModuleCode;
|
import com.imyeyu.api.bean.ModuleCode;
|
||||||
import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
|
import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
|
||||||
import com.imyeyu.api.modules.gao.entity.GaoUser;
|
import com.imyeyu.api.modules.gao.entity.GaoUser;
|
||||||
import com.imyeyu.api.modules.gao.mapper.GaoUserMapper;
|
import com.imyeyu.api.modules.gao.mapper.GaoUserMapper;
|
||||||
import com.imyeyu.api.modules.gao.service.GaoUserService;
|
import com.imyeyu.api.modules.gao.service.GaoUserService;
|
||||||
|
import com.imyeyu.api.modules.system.entity.Logger;
|
||||||
|
import com.imyeyu.api.modules.system.service.LoggerService;
|
||||||
import com.imyeyu.api.modules.user.entity.Role;
|
import com.imyeyu.api.modules.user.entity.Role;
|
||||||
import com.imyeyu.api.modules.user.entity.User;
|
import com.imyeyu.api.modules.user.entity.User;
|
||||||
import com.imyeyu.api.modules.user.mapper.UserMapper;
|
import com.imyeyu.api.modules.user.mapper.UserMapper;
|
||||||
@@ -14,12 +17,14 @@ import com.imyeyu.api.modules.user.vo.role.UserRoleAuthorizeReq;
|
|||||||
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;
|
||||||
|
import com.imyeyu.spring.TimiSpring;
|
||||||
import com.imyeyu.spring.bean.Page;
|
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 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;
|
||||||
|
|
||||||
@@ -34,11 +39,14 @@ import java.util.stream.Collectors;
|
|||||||
///
|
///
|
||||||
/// @author Codex
|
/// @author Codex
|
||||||
/// @since 2026-07-30
|
/// @since 2026-07-30
|
||||||
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class GaoUserServiceImplement extends AbstractEntityService<GaoUser, String> implements GaoUserService {
|
public class GaoUserServiceImplement extends AbstractEntityService<GaoUser, String> implements GaoUserService {
|
||||||
|
|
||||||
private final GaoUserMapper mapper;
|
private final GaoUserMapper mapper;
|
||||||
|
private final ObjectMapper jackson;
|
||||||
|
private final LoggerService loggerService;
|
||||||
private final UserMapper userMapper;
|
private final UserMapper userMapper;
|
||||||
private final UserService userService;
|
private final UserService userService;
|
||||||
private final RoleService roleService;
|
private final RoleService roleService;
|
||||||
@@ -51,20 +59,54 @@ public class GaoUserServiceImplement extends AbstractEntityService<GaoUser, Stri
|
|||||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||||
@Override
|
@Override
|
||||||
public void create(GaoUser entity) {
|
public void create(GaoUser entity) {
|
||||||
|
Logger logger = new Logger(Logger.Module.GAO, "GAO_USER_CREATE");
|
||||||
|
try {
|
||||||
|
logger.setContent(jackson.writeValueAsString(entity));
|
||||||
prepareUser(entity);
|
prepareUser(entity);
|
||||||
checkEntity(entity, false);
|
checkEntity(entity, false);
|
||||||
super.create(entity);
|
super.create(entity);
|
||||||
saveUserRole(entity);
|
saveUserRole(entity);
|
||||||
loadUser(entity);
|
loadUser(entity);
|
||||||
|
logger.setLevel(Logger.Level.INFO);
|
||||||
|
logger.setResult(entity.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("新增 GAO 用户失败", e);
|
||||||
|
throw new TimiException(TimiCode.ERROR, "新增 GAO 用户失败", e);
|
||||||
|
} finally {
|
||||||
|
loggerService.create(logger);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||||
@Override
|
@Override
|
||||||
public void update(GaoUser entity) {
|
public void update(GaoUser entity) {
|
||||||
|
Logger logger = new Logger(Logger.Module.GAO, "GAO_USER_UPDATE");
|
||||||
|
try {
|
||||||
|
logger.setContent(jackson.writeValueAsString(entity));
|
||||||
checkEntity(entity, true);
|
checkEntity(entity, true);
|
||||||
updateUser(entity);
|
updateUser(entity);
|
||||||
super.update(entity);
|
super.update(entity);
|
||||||
saveUserRole(entity);
|
saveUserRole(entity);
|
||||||
|
logger.setLevel(Logger.Level.INFO);
|
||||||
|
logger.setResult(entity.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("修改 GAO 用户失败", e);
|
||||||
|
throw new TimiException(TimiCode.ERROR, "修改 GAO 用户失败", e);
|
||||||
|
} finally {
|
||||||
|
loggerService.create(logger);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.imyeyu.api.modules.gao.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// 客户登记日期统计视图
|
||||||
|
///
|
||||||
|
/// @author Codex
|
||||||
|
/// @since 2026-08-03
|
||||||
|
@Data
|
||||||
|
public class GaoCustomerRegistrationDayStatView {
|
||||||
|
|
||||||
|
/// 客户 ID
|
||||||
|
private String customerId;
|
||||||
|
|
||||||
|
/// 客户编码
|
||||||
|
private String customerCode;
|
||||||
|
|
||||||
|
/// 客户姓名
|
||||||
|
private String customerName;
|
||||||
|
|
||||||
|
/// 客户头像附件 ID
|
||||||
|
private String customerPhotoAttachmentId;
|
||||||
|
|
||||||
|
/// 登记日期,格式 yyyyMMdd
|
||||||
|
private Integer dateValue;
|
||||||
|
|
||||||
|
/// 当日登记次数
|
||||||
|
private Long dailyCount;
|
||||||
|
|
||||||
|
/// 当日最后登记时间
|
||||||
|
private Long latestRegisteredAt;
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package com.imyeyu.api.modules.gao.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// 客户登记排行榜视图
|
||||||
|
///
|
||||||
|
/// @author Codex
|
||||||
|
/// @since 2026-08-03
|
||||||
|
@Data
|
||||||
|
public class GaoCustomerRegistrationRankView {
|
||||||
|
|
||||||
|
/// 排名
|
||||||
|
private Integer rank;
|
||||||
|
|
||||||
|
/// 客户 ID
|
||||||
|
private String customerId;
|
||||||
|
|
||||||
|
/// 客户编码
|
||||||
|
private String customerCode;
|
||||||
|
|
||||||
|
/// 客户姓名
|
||||||
|
private String customerName;
|
||||||
|
|
||||||
|
/// 客户头像附件 ID
|
||||||
|
private String customerPhotoAttachmentId;
|
||||||
|
|
||||||
|
/// 累计登记天数
|
||||||
|
private Long totalRegistrationDays;
|
||||||
|
|
||||||
|
/// 累计登记次数
|
||||||
|
private Long totalRegistrationCount;
|
||||||
|
|
||||||
|
/// 最近连续登记天数
|
||||||
|
private Long recentContinuousRegistrationDays;
|
||||||
|
|
||||||
|
/// 最后登记时间
|
||||||
|
private Long latestRegisteredAt;
|
||||||
|
}
|
||||||
+2
-5
@@ -13,11 +13,8 @@ import java.util.List;
|
|||||||
@Data
|
@Data
|
||||||
public class GaoRegistrationEventRecordCreateReq {
|
public class GaoRegistrationEventRecordCreateReq {
|
||||||
|
|
||||||
/// 客户 ID
|
/// 客户 ID 列表,批量登记时使用
|
||||||
private String customerId;
|
private List<String> customerIdList = new ArrayList<>();
|
||||||
|
|
||||||
/// 客户编码,扫码登记可直接传这个
|
|
||||||
private String customerCode;
|
|
||||||
|
|
||||||
/// 登记事件 ID
|
/// 登记事件 ID
|
||||||
private String registrationEventId;
|
private String registrationEventId;
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
package com.imyeyu.api.modules.gao.vo;
|
|
||||||
|
|
||||||
import com.imyeyu.api.modules.gao.entity.GaoRegistrationEvent;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// 登记事件保存请求
|
|
||||||
///
|
|
||||||
/// @author Codex
|
|
||||||
/// @since 2026-07-27
|
|
||||||
@Data
|
|
||||||
public class GaoRegistrationEventSaveReq {
|
|
||||||
|
|
||||||
/// 登记事件
|
|
||||||
private GaoRegistrationEvent registrationEvent;
|
|
||||||
|
|
||||||
/// 可登记角色代码列表
|
|
||||||
private List<String> roleCodeList = new ArrayList<>();
|
|
||||||
}
|
|
||||||
@@ -17,6 +17,21 @@ import lombok.NoArgsConstructor;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class Logger implements IDEntity<String>, Creatable {
|
public class Logger implements IDEntity<String>, Creatable {
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// @author 夜雨
|
||||||
|
/// @since 2026-08-03 11:43
|
||||||
|
public enum Module {
|
||||||
|
|
||||||
|
SYSTEM,
|
||||||
|
|
||||||
|
COMMON,
|
||||||
|
|
||||||
|
USER,
|
||||||
|
|
||||||
|
GAO,
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 日志级别
|
* 日志级别
|
||||||
*
|
*
|
||||||
@@ -43,7 +58,7 @@ public class Logger implements IDEntity<String>, Creatable {
|
|||||||
private Level level;
|
private Level level;
|
||||||
|
|
||||||
/** 模块名称 */
|
/** 模块名称 */
|
||||||
private String module;
|
private Module module;
|
||||||
|
|
||||||
/** 操作描述 */
|
/** 操作描述 */
|
||||||
private String operation;
|
private String operation;
|
||||||
@@ -69,7 +84,26 @@ public class Logger implements IDEntity<String>, Creatable {
|
|||||||
/** 创建时间 */
|
/** 创建时间 */
|
||||||
private Long createdAt;
|
private Long createdAt;
|
||||||
|
|
||||||
public Logger(Level level) {
|
public Logger(Module module, String operation) {
|
||||||
|
this.module = module;
|
||||||
|
this.operation = operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Logger(Module module, Level level, String operation) {
|
||||||
|
this.module = module;
|
||||||
this.level = level;
|
this.level = level;
|
||||||
|
this.operation = operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Logger info(Module module, String operation) {
|
||||||
|
return new Logger(module, Level.INFO, operation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Logger warning(Module module, String operation) {
|
||||||
|
return new Logger(module, Level.WARN, operation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Logger error(Module module, String operation) {
|
||||||
|
return new Logger(module, Level.ERROR, operation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,41 +16,29 @@ public interface LoggerService extends GettableService<Logger, String>, Pageable
|
|||||||
|
|
||||||
void createSync(Logger logger);
|
void createSync(Logger logger);
|
||||||
|
|
||||||
void create(Logger.Level level, String module, String operation, String userId, String content, String result);
|
void create(Logger.Module module, Logger.Level level, String operation, String content, String result);
|
||||||
|
|
||||||
default void info(String module, String operation, String userId) {
|
default void info(Logger.Module module, String operation) {
|
||||||
create(Logger.Level.INFO, module, operation, userId, null, null);
|
create(module, Logger.Level.INFO, operation, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
default void info(String module, String operation, String content, String result) {
|
default void info(Logger.Module module, String operation, String content, String result) {
|
||||||
create(Logger.Level.INFO, module, operation, null, content, result);
|
create(module, Logger.Level.INFO, operation, content, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
default void info(String module, String operation, String userId, String content, String result) {
|
default void warning(Logger.Module module, String operation) {
|
||||||
create(Logger.Level.INFO, module, operation, userId, content, result);
|
create(module, Logger.Level.WARN, operation, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
default void warning(String module, String operation, String userId) {
|
default void warning(Logger.Module module, String operation, String content, String result) {
|
||||||
create(Logger.Level.WARN, module, operation, userId, null, null);
|
create(module, Logger.Level.WARN, operation, content, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
default void warning(String module, String operation, String content, String result) {
|
default void error(Logger.Module module, String operation) {
|
||||||
create(Logger.Level.WARN, module, operation, null, content, result);
|
create(module, Logger.Level.ERROR, operation, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
default void warning(String module, String operation, String userId, String content, String result) {
|
default void error(Logger.Module module, String operation, String content, String result) {
|
||||||
create(Logger.Level.WARN, module, operation, userId, content, result);
|
create(module, Logger.Level.ERROR, operation, content, result);
|
||||||
}
|
|
||||||
|
|
||||||
default void error(String module, String operation, String userId) {
|
|
||||||
create(Logger.Level.ERROR, module, operation, userId, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
default void error(String module, String operation, String content, String result) {
|
|
||||||
create(Logger.Level.ERROR, module, operation, null, content, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
default void error(String module, String operation, String userId, String content, String result) {
|
|
||||||
create(Logger.Level.ERROR, module, operation, userId, content, result);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-6
@@ -3,6 +3,10 @@ package com.imyeyu.api.modules.system.service.implement;
|
|||||||
import com.imyeyu.api.modules.system.entity.Logger;
|
import com.imyeyu.api.modules.system.entity.Logger;
|
||||||
import com.imyeyu.api.modules.system.mapper.LoggerMapper;
|
import com.imyeyu.api.modules.system.mapper.LoggerMapper;
|
||||||
import com.imyeyu.api.modules.system.service.LoggerService;
|
import com.imyeyu.api.modules.system.service.LoggerService;
|
||||||
|
import com.imyeyu.api.modules.user.entity.User;
|
||||||
|
import com.imyeyu.api.modules.user.service.UserLoginService;
|
||||||
|
import com.imyeyu.java.TimiJava;
|
||||||
|
import com.imyeyu.spring.TimiSpring;
|
||||||
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
@@ -18,6 +22,8 @@ import org.springframework.stereotype.Service;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class LoggerServiceImplement extends AbstractEntityService<Logger, String> implements LoggerService {
|
public class LoggerServiceImplement extends AbstractEntityService<Logger, String> implements LoggerService {
|
||||||
|
|
||||||
|
private final UserLoginService userLoginService;
|
||||||
|
|
||||||
private final LoggerMapper mapper;
|
private final LoggerMapper mapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -28,19 +34,23 @@ public class LoggerServiceImplement extends AbstractEntityService<Logger, String
|
|||||||
@Override
|
@Override
|
||||||
public void create(Logger logger) {
|
public void create(Logger logger) {
|
||||||
// 默认异步
|
// 默认异步
|
||||||
Thread.startVirtualThread(() -> super.create(logger));
|
Thread.startVirtualThread(() -> createSync(logger));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createSync(Logger logger) {
|
public void createSync(Logger logger) {
|
||||||
|
if (TimiJava.isEmpty(logger.getUserId())) {
|
||||||
|
User loginUser = userLoginService.getLoginUser();
|
||||||
|
if (TimiJava.isNotEmpty(loginUser)) {
|
||||||
|
logger.setUserId(loginUser.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.setIp(TimiJava.defaultIfEmpty(logger.getIp(), TimiSpring.getRequestIP()));
|
||||||
super.create(logger);
|
super.create(logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void create(Logger.Level level, String module, String operation, String userId, String content, String result) {
|
public void create(Logger.Module module, Logger.Level level, String operation, String content, String result) {
|
||||||
Logger log = new Logger(level);
|
Logger log = new Logger(module, level, operation);
|
||||||
log.setModule(module);
|
|
||||||
log.setOperation(operation);
|
|
||||||
log.setUserId(userId);
|
|
||||||
log.setContent(content);
|
log.setContent(content);
|
||||||
log.setResult(result);
|
log.setResult(result);
|
||||||
create(log);
|
create(log);
|
||||||
|
|||||||
+4
-2
@@ -25,8 +25,8 @@ import org.springframework.context.annotation.Lazy;
|
|||||||
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.concurrent.ThreadLocalRandom;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
/// 用户登录服务实现
|
/// 用户登录服务实现
|
||||||
///
|
///
|
||||||
@@ -95,7 +95,9 @@ public class UserLoginServiceImplement implements UserLoginService, TimiJava {
|
|||||||
@Override
|
@Override
|
||||||
public User getLoginUser() {
|
public User getLoginUser() {
|
||||||
String token = TimiSpring.getToken();
|
String token = TimiSpring.getToken();
|
||||||
TimiException.required(token, "not found token");
|
if (TimiJava.isEmpty(token)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
String userId = redisUserToken.get(getUserTokenKey(token));
|
String userId = redisUserToken.get(getUserTokenKey(token));
|
||||||
if (TimiJava.isEmpty(userId)) {
|
if (TimiJava.isEmpty(userId)) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
package com.imyeyu.api.util;
|
package com.imyeyu.api.util;
|
||||||
|
|
||||||
import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
|
|
||||||
import com.imyeyu.api.bean.ModuleCode;
|
import com.imyeyu.api.bean.ModuleCode;
|
||||||
|
import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
|
||||||
import com.imyeyu.api.modules.common.bean.ImageType;
|
import com.imyeyu.api.modules.common.bean.ImageType;
|
||||||
import com.imyeyu.api.modules.gao.bean.GaoPermissionCode;
|
import com.imyeyu.api.modules.gao.bean.GaoPermissionCode;
|
||||||
import com.imyeyu.api.modules.gao.bean.GaoRoleCode;
|
import com.imyeyu.api.modules.gao.bean.GaoRoleCode;
|
||||||
|
import com.imyeyu.api.modules.system.entity.Logger;
|
||||||
import com.imyeyu.api.modules.system.service.LoggerService;
|
import com.imyeyu.api.modules.system.service.LoggerService;
|
||||||
import com.imyeyu.api.modules.user.bean.BootstrapData;
|
import com.imyeyu.api.modules.user.bean.BootstrapData;
|
||||||
import com.imyeyu.api.modules.user.bean.BuiltinAuthRegistry;
|
import com.imyeyu.api.modules.user.bean.BuiltinAuthRegistry;
|
||||||
@@ -92,7 +93,13 @@ public class InitBuiltinUser implements ApplicationRunner {
|
|||||||
userService.create(user);
|
userService.create(user);
|
||||||
|
|
||||||
String logContent = "初始化 %s 自举用户成功,请立即修改密码:%s".formatted(BootstrapData.SYS_USER_NAME, password);
|
String logContent = "初始化 %s 自举用户成功,请立即修改密码:%s".formatted(BootstrapData.SYS_USER_NAME, password);
|
||||||
loggerService.info("SYSTEM", "INITIALIZE_SYSTEM_USER", user.getId(), logContent, null);
|
|
||||||
|
Logger logger = new Logger();
|
||||||
|
logger.setModule(Logger.Module.SYSTEM);
|
||||||
|
logger.setOperation("INITIALIZE_SYSTEM_USER");
|
||||||
|
logger.setUserId(user.getId());
|
||||||
|
logger.setContent(logContent);
|
||||||
|
loggerService.create(logger);
|
||||||
}
|
}
|
||||||
// 授权系统用户角色
|
// 授权系统用户角色
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
ALTER TABLE `gao_registration_event`
|
||||||
|
ADD COLUMN `color` VARCHAR(32) NULL COMMENT '统计图表颜色' AFTER `id`,
|
||||||
|
ADD COLUMN `status` VARCHAR(32) NOT NULL DEFAULT 'ACTIVE' COMMENT '状态,ACTIVE 可登记,INACTIVE 无效,DELETED 已删除' AFTER `sort`,
|
||||||
|
ADD COLUMN `limit_type` VARCHAR(32) NOT NULL DEFAULT 'NONE' COMMENT '登记限制类型' AFTER `require_photo`,
|
||||||
|
ADD COLUMN `limit_value` INT NULL COMMENT '登记限制数值,按限制类型表示小时数或次数' AFTER `limit_type`,
|
||||||
|
ADD KEY `idx_gao_registration_event_status` (`status`, `enabled`, `deleted_at`, `sort`);
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
ALTER TABLE `gao_registration_event`
|
||||||
|
DROP KEY `idx_gao_registration_event_status`,
|
||||||
|
DROP COLUMN `enabled`,
|
||||||
|
MODIFY COLUMN `status` VARCHAR(32) NOT NULL DEFAULT 'ACTIVE' COMMENT '状态,DRAFT 草稿,ACTIVE 可登记,INACTIVE 不可登记,DELETED 已删除',
|
||||||
|
ADD COLUMN `begin_at` BIGINT NULL COMMENT '可登记起始时间戳,毫秒,空为不限制' AFTER `limit_value`,
|
||||||
|
ADD COLUMN `end_at` BIGINT NULL COMMENT '可登记终止时间戳,毫秒,空为不限制' AFTER `begin_at`,
|
||||||
|
ADD KEY `idx_gao_registration_event_status` (`status`, `deleted_at`, `sort`, `created_at`);
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
ALTER TABLE `gao_customer`
|
||||||
|
ADD COLUMN `birthdate` DATE NULL COMMENT '出生日期,统一保存为公历' AFTER `gender`,
|
||||||
|
ADD COLUMN `birthdate_calendar` VARCHAR(16) NOT NULL DEFAULT 'SOLAR' COMMENT '出生日期录入历法,SOLAR 公历,LUNAR 农历' AFTER `birthdate`;
|
||||||
@@ -18,4 +18,16 @@
|
|||||||
</if>
|
</if>
|
||||||
AND `deleted_at` IS NULL
|
AND `deleted_at` IS NULL
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="selectEnabledList" resultType="com.imyeyu.api.modules.gao.entity.GaoRegistrationEvent">
|
||||||
|
SELECT
|
||||||
|
*
|
||||||
|
FROM `gao_registration_event`
|
||||||
|
WHERE
|
||||||
|
(`status` IS NULL OR `status` = 'ACTIVE')
|
||||||
|
AND (`begin_at` IS NULL OR `begin_at` <= #{now})
|
||||||
|
AND (`end_at` IS NULL OR #{now} <= `end_at`)
|
||||||
|
AND `deleted_at` IS NULL
|
||||||
|
ORDER BY `sort` ASC, `created_at` ASC
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
@@ -20,6 +20,37 @@
|
|||||||
ORDER BY `registered_at` DESC
|
ORDER BY `registered_at` DESC
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="countByCustomerIdAndRegistrationEventIdRange" resultType="java.lang.Long">
|
||||||
|
SELECT
|
||||||
|
COUNT(1)
|
||||||
|
FROM `gao_registration_event_record`
|
||||||
|
WHERE
|
||||||
|
`customer_id` = #{customerId}
|
||||||
|
AND `registration_event_id` = #{registrationEventId}
|
||||||
|
AND `registered_at` >= #{beginRegisteredAt}
|
||||||
|
AND `registered_at` <= #{endRegisteredAt}
|
||||||
|
AND `deleted_at` IS NULL
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="countByCustomerIdAndRegistrationEventId" resultType="java.lang.Long">
|
||||||
|
SELECT
|
||||||
|
COUNT(1)
|
||||||
|
FROM `gao_registration_event_record`
|
||||||
|
WHERE
|
||||||
|
`customer_id` = #{customerId}
|
||||||
|
AND `registration_event_id` = #{registrationEventId}
|
||||||
|
AND `deleted_at` IS NULL
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="countByRegistrationEventId" resultType="java.lang.Long">
|
||||||
|
SELECT
|
||||||
|
COUNT(1)
|
||||||
|
FROM `gao_registration_event_record`
|
||||||
|
WHERE
|
||||||
|
`registration_event_id` = #{registrationEventId}
|
||||||
|
AND `deleted_at` IS NULL
|
||||||
|
</select>
|
||||||
|
|
||||||
<select id="statByRegistrationEventAndPeriodType" resultType="com.imyeyu.api.modules.gao.vo.GaoRegistrationEventPeriodStatView">
|
<select id="statByRegistrationEventAndPeriodType" resultType="com.imyeyu.api.modules.gao.vo.GaoRegistrationEventPeriodStatView">
|
||||||
SELECT
|
SELECT
|
||||||
`registration_event_id` AS `registrationEventId`,
|
`registration_event_id` AS `registrationEventId`,
|
||||||
@@ -112,6 +143,54 @@
|
|||||||
ORDER BY `latestRegisteredAt` DESC
|
ORDER BY `latestRegisteredAt` DESC
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="statCustomerRegistrationDay" resultType="com.imyeyu.api.modules.gao.vo.GaoCustomerRegistrationDayStatView">
|
||||||
|
SELECT
|
||||||
|
r.`customer_id` AS `customerId`,
|
||||||
|
c.`code` AS `customerCode`,
|
||||||
|
c.`name` AS `customerName`,
|
||||||
|
(
|
||||||
|
SELECT a.`id`
|
||||||
|
FROM `attachment` a
|
||||||
|
WHERE
|
||||||
|
a.`biz_type` = 'GAO_CUSTOMER'
|
||||||
|
AND a.`biz_id` = c.`id`
|
||||||
|
AND a.`attach_type` = 'PHOTO'
|
||||||
|
AND a.`deleted_at` IS NULL
|
||||||
|
AND (a.`destroy_at` IS NULL OR UNIX_TIMESTAMP() < a.`destroy_at`)
|
||||||
|
ORDER BY a.`created_at` ASC
|
||||||
|
LIMIT 1
|
||||||
|
) AS `customerPhotoAttachmentId`,
|
||||||
|
CAST(DATE_FORMAT(FROM_UNIXTIME(r.`registered_at` / 1000), '%Y%m%d') AS UNSIGNED) AS `dateValue`,
|
||||||
|
COUNT(1) AS `dailyCount`,
|
||||||
|
MAX(r.`registered_at`) AS `latestRegisteredAt`
|
||||||
|
FROM `gao_registration_event_record` r
|
||||||
|
LEFT JOIN `gao_customer` c ON r.`customer_id` = c.`id`
|
||||||
|
WHERE
|
||||||
|
r.`deleted_at` IS NULL
|
||||||
|
AND c.`deleted_at` IS NULL
|
||||||
|
<if test="req.beginRegisteredAt != null">
|
||||||
|
AND r.`registered_at` >= #{req.beginRegisteredAt}
|
||||||
|
</if>
|
||||||
|
<if test="req.endRegisteredAt != null">
|
||||||
|
AND r.`registered_at` <= #{req.endRegisteredAt}
|
||||||
|
</if>
|
||||||
|
<if test="req.registrationEventId != null and req.registrationEventId != ''">
|
||||||
|
AND r.`registration_event_id` = #{req.registrationEventId}
|
||||||
|
</if>
|
||||||
|
<if test="req.registrationEventIdList != null and req.registrationEventIdList.size() > 0">
|
||||||
|
AND r.`registration_event_id` IN
|
||||||
|
<foreach collection="req.registrationEventIdList" item="registrationEventId" open="(" separator="," close=")">
|
||||||
|
#{registrationEventId}
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
|
GROUP BY
|
||||||
|
r.`customer_id`,
|
||||||
|
c.`code`,
|
||||||
|
c.`name`,
|
||||||
|
DATE_FORMAT(FROM_UNIXTIME(r.`registered_at` / 1000), '%Y%m%d')
|
||||||
|
ORDER BY r.`customer_id` ASC, `dateValue` DESC
|
||||||
|
</select>
|
||||||
|
|
||||||
<select id="statDailyCountByCustomerIdAndRegistrationEventIdRange" resultType="com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordDailyStatView">
|
<select id="statDailyCountByCustomerIdAndRegistrationEventIdRange" resultType="com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordDailyStatView">
|
||||||
SELECT
|
SELECT
|
||||||
CAST(DATE_FORMAT(FROM_UNIXTIME(`registered_at` / 1000), '%Y%m%d') AS UNSIGNED) AS `dateValue`,
|
CAST(DATE_FORMAT(FROM_UNIXTIME(`registered_at` / 1000), '%Y%m%d') AS UNSIGNED) AS `dateValue`,
|
||||||
|
|||||||
Reference in New Issue
Block a user