refactor all
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
package com.imyeyu.api.modules.gao.annotation;
|
||||
|
||||
import com.imyeyu.api.bean.PermissionMatchMode;
|
||||
import com.imyeyu.api.modules.gao.bean.GaoPermissionCode;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
///
|
||||
/// 要求 GAO 模块权限
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-26
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface RequireGaoPermission {
|
||||
|
||||
/// 所需权限
|
||||
///
|
||||
/// @return 权限列表
|
||||
GaoPermissionCode[] value();
|
||||
|
||||
/// 匹配模式
|
||||
///
|
||||
/// @return 匹配模式
|
||||
PermissionMatchMode mode() default PermissionMatchMode.ALL;
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package com.imyeyu.api.modules.gao.annotation;
|
||||
|
||||
import com.imyeyu.api.bean.ModuleCode;
|
||||
import com.imyeyu.api.bean.PermissionMatchMode;
|
||||
import com.imyeyu.api.modules.gao.bean.GaoPermissionCode;
|
||||
import com.imyeyu.api.modules.user.service.PermissionChecker;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
///
|
||||
/// GAO 权限注解处理器
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
@Component
|
||||
public class RequireGaoPermissionInterceptor implements HandlerInterceptor {
|
||||
|
||||
private final PermissionChecker permissionChecker;
|
||||
|
||||
public RequireGaoPermissionInterceptor(PermissionChecker permissionChecker) {
|
||||
this.permissionChecker = permissionChecker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean preHandle(@NonNull HttpServletRequest req, @NonNull HttpServletResponse resp, @NonNull Object handler) {
|
||||
if (!(handler instanceof HandlerMethod handlerMethod)) {
|
||||
return true;
|
||||
}
|
||||
RequireGaoPermission annotation = handlerMethod.getMethodAnnotation(RequireGaoPermission.class);
|
||||
if (annotation == null || TimiJava.isEmpty(annotation.value())) {
|
||||
return true;
|
||||
}
|
||||
String[] permissionCodeList = java.util.Arrays.stream(annotation.value()).map(GaoPermissionCode::getValue).toArray(String[]::new);
|
||||
if (annotation.mode() == PermissionMatchMode.ANY) {
|
||||
permissionChecker.checkAny(ModuleCode.GAO, permissionCodeList);
|
||||
} else {
|
||||
permissionChecker.checkAll(ModuleCode.GAO, permissionCodeList);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.imyeyu.api.modules.gao.annotation;
|
||||
|
||||
import com.imyeyu.api.bean.RoleMatchMode;
|
||||
import com.imyeyu.api.modules.gao.bean.GaoRoleCode;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
///
|
||||
/// 要求 GAO 模块角色
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-26
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface RequireGaoRole {
|
||||
|
||||
/// 所需角色
|
||||
///
|
||||
/// @return 角色列表
|
||||
GaoRoleCode[] value();
|
||||
|
||||
/// 匹配模式
|
||||
///
|
||||
/// @return 匹配模式
|
||||
RoleMatchMode mode() default RoleMatchMode.ALL;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.imyeyu.api.modules.gao.annotation;
|
||||
|
||||
import com.imyeyu.api.bean.ModuleCode;
|
||||
import com.imyeyu.api.bean.RoleMatchMode;
|
||||
import com.imyeyu.api.modules.gao.bean.GaoRoleCode;
|
||||
import com.imyeyu.api.modules.user.service.RoleChecker;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
///
|
||||
/// GAO 角色注解处理器
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
@Component
|
||||
public class RequireGaoRoleInterceptor implements HandlerInterceptor {
|
||||
|
||||
private final RoleChecker roleChecker;
|
||||
|
||||
public RequireGaoRoleInterceptor(RoleChecker roleChecker) {
|
||||
this.roleChecker = roleChecker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean preHandle(@NonNull HttpServletRequest req, @NonNull HttpServletResponse resp, @NonNull Object handler) {
|
||||
if (!(handler instanceof HandlerMethod handlerMethod)) {
|
||||
return true;
|
||||
}
|
||||
RequireGaoRole annotation = handlerMethod.getMethodAnnotation(RequireGaoRole.class);
|
||||
if (annotation == null || TimiJava.isEmpty(annotation.value())) {
|
||||
return true;
|
||||
}
|
||||
String[] roleCodeList = java.util.Arrays.stream(annotation.value()).map(GaoRoleCode::name).toArray(String[]::new);
|
||||
if (annotation.mode() == RoleMatchMode.ANY) {
|
||||
roleChecker.checkAny(ModuleCode.GAO, roleCodeList);
|
||||
} else {
|
||||
roleChecker.checkAll(ModuleCode.GAO, roleCodeList);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.imyeyu.api.modules.gao.bean;
|
||||
|
||||
import com.imyeyu.api.bean.ModuleCode;
|
||||
import com.imyeyu.api.modules.user.bean.BuiltinPermissionCode;
|
||||
|
||||
///
|
||||
/// GAO 模块权限枚举
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-26
|
||||
public enum GaoPermissionCode implements BuiltinPermissionCode {
|
||||
|
||||
CUSTOMER_CREATE("CUSTOMER:CREATE", "客户创建"),
|
||||
|
||||
CUSTOMER_READ("CUSTOMER:READ", "客户读取"),
|
||||
|
||||
CUSTOMER_UPDATE("CUSTOMER:UPDATE", "客户修改"),
|
||||
|
||||
CUSTOMER_DELETE("CUSTOMER:DELETE", "客户删除"),
|
||||
|
||||
REGISTRATION_EVENT_CREATE("REGISTRATION_EVENT:CREATE", "登记事件创建"),
|
||||
|
||||
REGISTRATION_EVENT_READ("REGISTRATION_EVENT:READ", "登记事件读取"),
|
||||
|
||||
REGISTRATION_EVENT_UPDATE("REGISTRATION_EVENT:UPDATE", "登记事件修改"),
|
||||
|
||||
REGISTRATION_EVENT_DELETE("REGISTRATION_EVENT:DELETE", "登记事件删除"),
|
||||
|
||||
REGISTRATION_EVENT_RECORD_CREATE("REGISTRATION_EVENT_RECORD:CREATE", "登记事件记录创建"),
|
||||
|
||||
REGISTRATION_EVENT_RECORD_READ("REGISTRATION_EVENT_RECORD:READ", "登记事件记录读取"),
|
||||
|
||||
REGISTRATION_EVENT_RECORD_UPDATE("REGISTRATION_EVENT_RECORD:UPDATE", "登记事件记录修改"),
|
||||
|
||||
REGISTRATION_EVENT_RECORD_DELETE("REGISTRATION_EVENT_RECORD:DELETE", "登记事件记录删除"),
|
||||
|
||||
STAT_READ("STAT:READ", "统计读取"),
|
||||
|
||||
QR_CODE_CREATE("QR_CODE:CREATE", "二维码创建"),
|
||||
|
||||
USER_CREATE("USER:CREATE", "用户创建", true),
|
||||
|
||||
USER_READ("USER:READ", "用户读取", true),
|
||||
|
||||
USER_UPDATE("USER:UPDATE", "用户修改", true),
|
||||
|
||||
USER_DELETE("USER:DELETE", "用户删除", true);
|
||||
|
||||
final String value;
|
||||
final String defaultName;
|
||||
final boolean grantToStoreManager;
|
||||
|
||||
GaoPermissionCode(String value, String defaultName) {
|
||||
this(value, defaultName, false);
|
||||
}
|
||||
|
||||
GaoPermissionCode(String value, String defaultName, boolean grantToStoreManager) {
|
||||
this.value = value;
|
||||
this.defaultName = defaultName;
|
||||
this.grantToStoreManager = grantToStoreManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModuleCode getModuleCode() {
|
||||
return ModuleCode.GAO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultName() {
|
||||
return defaultName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGrantToSystem() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGrantToAdmin() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// true 为初始化时授权给店长角色
|
||||
///
|
||||
/// @return 是否授权给店长角色
|
||||
public boolean isGrantToStoreManager() {
|
||||
return grantToStoreManager;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.imyeyu.api.modules.gao.bean;
|
||||
|
||||
import com.imyeyu.api.bean.ModuleCode;
|
||||
import com.imyeyu.api.modules.user.bean.BuiltinRoleCode;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
///
|
||||
/// GAO 模块角色枚举
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-26
|
||||
@AllArgsConstructor
|
||||
public enum GaoRoleCode implements BuiltinRoleCode {
|
||||
|
||||
/// 店长
|
||||
STORE_MANAGER("店长"),
|
||||
|
||||
EMPLOYEE("员工");
|
||||
|
||||
final String defaultName;
|
||||
|
||||
@Override
|
||||
public ModuleCode getModuleCode() {
|
||||
return ModuleCode.GAO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultName() {
|
||||
return defaultName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProtected() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParentCode() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
package com.imyeyu.api.modules.gao.controller;
|
||||
|
||||
import com.imyeyu.api.modules.gao.bean.GaoPermissionCode;
|
||||
import com.imyeyu.api.modules.gao.bean.GaoRoleCode;
|
||||
import com.imyeyu.api.bean.RoleMatchMode;
|
||||
import com.imyeyu.api.modules.gao.annotation.RequireGaoPermission;
|
||||
import com.imyeyu.api.modules.gao.annotation.RequireGaoRole;
|
||||
import com.imyeyu.api.modules.gao.entity.GaoCustomer;
|
||||
import com.imyeyu.api.modules.gao.entity.GaoRegistrationEvent;
|
||||
import com.imyeyu.api.modules.gao.entity.GaoRegistrationEventRecord;
|
||||
import com.imyeyu.api.modules.gao.service.GaoRegistrationEventService;
|
||||
import com.imyeyu.api.modules.gao.service.GaoCustomerService;
|
||||
import com.imyeyu.api.modules.gao.service.GaoRegistrationEventRecordService;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerDailyStatView;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerInviteUpdateReq;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerSearchReq;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerTrendStatReq;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoQuickRegistrationEventRecordReq;
|
||||
import com.imyeyu.spring.annotation.AOPLog;
|
||||
import com.imyeyu.spring.annotation.RequestRateLimit;
|
||||
import com.imyeyu.spring.bean.Page;
|
||||
import com.imyeyu.spring.bean.PageResult;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
///
|
||||
/// GAO 客户接口
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/gao/customer")
|
||||
@RequireGaoRole(value = {GaoRoleCode.STORE_MANAGER, GaoRoleCode.EMPLOYEE}, mode = RoleMatchMode.ANY)
|
||||
public class GaoCustomerController {
|
||||
|
||||
private static final String SIGN_IN_REGISTRATION_EVENT_NAME = "签到";
|
||||
|
||||
private final GaoCustomerService service;
|
||||
private final GaoRegistrationEventRecordService registrationEventRecordService;
|
||||
private final GaoRegistrationEventService registrationEventService;
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.CUSTOMER_READ)
|
||||
@PostMapping("/list")
|
||||
public PageResult<GaoCustomer> list(@RequestBody Page<GaoCustomer> page) {
|
||||
PageResult<GaoCustomer> result = service.page(page);
|
||||
fillLastSignInAt(result.getList());
|
||||
return result;
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.CUSTOMER_READ)
|
||||
@PostMapping("/search")
|
||||
public List<GaoCustomer> search(@RequestBody GaoCustomerSearchReq req) {
|
||||
return service.search(req);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.CUSTOMER_READ)
|
||||
@PostMapping("/detail")
|
||||
public GaoCustomer detail(@RequestParam String id) {
|
||||
return service.get(id);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.CUSTOMER_READ)
|
||||
@PostMapping("/detail/code")
|
||||
public GaoCustomer detailByCode(@RequestParam String code) {
|
||||
return service.getByCode(code);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.CUSTOMER_READ)
|
||||
@PostMapping("/invited/list")
|
||||
public List<GaoCustomer> invitedList(@RequestParam String introducerCustomerId) {
|
||||
return service.listInvited(introducerCustomerId);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.CUSTOMER_CREATE)
|
||||
@PostMapping("/create")
|
||||
public void create(@RequestBody GaoCustomer customer) {
|
||||
service.create(customer);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@PostMapping("/quick/register")
|
||||
public GaoRegistrationEventRecord quickRegister(@RequestBody GaoQuickRegistrationEventRecordReq req) {
|
||||
return registrationEventRecordService.quickRegister(req);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.CUSTOMER_UPDATE)
|
||||
@PostMapping("/update")
|
||||
public void update(@RequestBody GaoCustomer customer) {
|
||||
service.update(customer);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.CUSTOMER_DELETE)
|
||||
@PostMapping("/delete")
|
||||
public void delete(@RequestParam String id) {
|
||||
service.delete(id);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.CUSTOMER_UPDATE)
|
||||
@PostMapping("/invite/create")
|
||||
public void createInvite(@RequestBody GaoCustomerInviteUpdateReq req) {
|
||||
service.saveInviteRelation(req);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.CUSTOMER_READ)
|
||||
@PostMapping("/invite/detail")
|
||||
public GaoCustomer inviteDetail(@RequestParam String customerId) {
|
||||
return service.get(customerId);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.CUSTOMER_UPDATE)
|
||||
@PostMapping("/invite/update")
|
||||
public void updateInvite(@RequestBody GaoCustomerInviteUpdateReq req) {
|
||||
service.saveInviteRelation(req);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.CUSTOMER_UPDATE)
|
||||
@PostMapping("/invite/delete")
|
||||
public void deleteInvite(@RequestParam String customerId) {
|
||||
service.deleteInviteRelation(customerId);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.CUSTOMER_READ)
|
||||
@PostMapping("/stat/daily")
|
||||
/// 按天统计客户新增数和累计总数
|
||||
public List<GaoCustomerDailyStatView> dailyStat(@RequestBody GaoCustomerTrendStatReq req) {
|
||||
return service.statDailyTrend(req);
|
||||
}
|
||||
|
||||
private void fillLastSignInAt(List<GaoCustomer> customerList) {
|
||||
if (customerList == null || customerList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
String signInRegistrationEventId = null;
|
||||
for (GaoRegistrationEvent registrationEvent : registrationEventService.listEnabled()) {
|
||||
if (SIGN_IN_REGISTRATION_EVENT_NAME.equals(registrationEvent.getName())) {
|
||||
signInRegistrationEventId = registrationEvent.getId();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (signInRegistrationEventId == null) {
|
||||
return;
|
||||
}
|
||||
List<String> customerIdList = customerList.stream().map(GaoCustomer::getId).toList();
|
||||
Map<String, GaoRegistrationEventRecord> recordMap = registrationEventRecordService.listLatestByCustomerIdListAndRegistrationEventId(customerIdList, signInRegistrationEventId).stream()
|
||||
.collect(Collectors.toMap(GaoRegistrationEventRecord::getCustomerId, Function.identity(), (left, right) -> left));
|
||||
for (GaoCustomer customer : customerList) {
|
||||
GaoRegistrationEventRecord record = recordMap.get(customer.getId());
|
||||
if (record != null) {
|
||||
customer.setLastSignInAt(record.getRegisteredAt());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
package com.imyeyu.api.modules.gao.controller;
|
||||
|
||||
import com.imyeyu.api.modules.gao.annotation.RequireGaoPermission;
|
||||
import com.imyeyu.api.modules.gao.annotation.RequireGaoRole;
|
||||
import com.imyeyu.api.bean.RoleMatchMode;
|
||||
import com.imyeyu.api.modules.gao.bean.GaoPermissionCode;
|
||||
import com.imyeyu.api.modules.gao.bean.GaoRoleCode;
|
||||
import com.imyeyu.api.modules.gao.entity.GaoRegistrationEvent;
|
||||
import com.imyeyu.api.modules.gao.service.GaoRegistrationEventService;
|
||||
import com.imyeyu.spring.annotation.AOPLog;
|
||||
import com.imyeyu.spring.annotation.RequestRateLimit;
|
||||
import com.imyeyu.spring.bean.Page;
|
||||
import com.imyeyu.spring.bean.PageResult;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
///
|
||||
/// GAO 登记事件接口
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/gao/registration-event")
|
||||
@RequireGaoRole(value = {GaoRoleCode.STORE_MANAGER, GaoRoleCode.EMPLOYEE}, mode = RoleMatchMode.ANY)
|
||||
public class GaoRegistrationEventController {
|
||||
|
||||
private final GaoRegistrationEventService service;
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.REGISTRATION_EVENT_READ)
|
||||
@PostMapping("/list")
|
||||
public PageResult<GaoRegistrationEvent> list(@RequestBody Page<GaoRegistrationEvent> page) {
|
||||
return service.pageWithRegistrationEventLimit(page);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@PostMapping("/enabled/list")
|
||||
public List<GaoRegistrationEvent> enabledList() {
|
||||
return service.listEnabled();
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.REGISTRATION_EVENT_READ)
|
||||
@PostMapping("/detail")
|
||||
public GaoRegistrationEvent detail(@RequestParam String id) {
|
||||
return service.get(id);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.REGISTRATION_EVENT_CREATE)
|
||||
@PostMapping("/create")
|
||||
public void create(@RequestBody GaoRegistrationEvent registrationEvent) {
|
||||
service.create(registrationEvent);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.REGISTRATION_EVENT_UPDATE)
|
||||
@PostMapping("/update")
|
||||
public void update(@RequestBody GaoRegistrationEvent registrationEvent) {
|
||||
service.update(registrationEvent);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.REGISTRATION_EVENT_DELETE)
|
||||
@PostMapping("/delete")
|
||||
public void delete(@RequestParam String id) {
|
||||
service.delete(id);
|
||||
}
|
||||
}
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
package com.imyeyu.api.modules.gao.controller;
|
||||
|
||||
import com.imyeyu.api.modules.gao.bean.GaoPermissionCode;
|
||||
import com.imyeyu.api.modules.gao.bean.GaoRoleCode;
|
||||
import com.imyeyu.api.bean.RoleMatchMode;
|
||||
import com.imyeyu.api.modules.gao.annotation.RequireGaoPermission;
|
||||
import com.imyeyu.api.modules.gao.annotation.RequireGaoRole;
|
||||
import com.imyeyu.api.modules.gao.entity.GaoRegistrationEventRecord;
|
||||
import com.imyeyu.api.modules.gao.service.GaoRegistrationEventRecordService;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventPeriodStatView;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerRegisterStatView;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordCreateReq;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordDailyStatView;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordPeriodReq;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordRangeReq;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordStatReq;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordTrendStatReq;
|
||||
import com.imyeyu.spring.annotation.AOPLog;
|
||||
import com.imyeyu.spring.annotation.IgnoreGlobalReturn;
|
||||
import com.imyeyu.spring.annotation.RequestRateLimit;
|
||||
import com.imyeyu.spring.bean.Page;
|
||||
import com.imyeyu.spring.bean.PageResult;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
///
|
||||
/// GAO 登记事件记录接口
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/gao/registration-event-record")
|
||||
@RequireGaoRole(value = {GaoRoleCode.STORE_MANAGER, GaoRoleCode.EMPLOYEE}, mode = RoleMatchMode.ANY)
|
||||
public class GaoRegistrationEventRecordController {
|
||||
|
||||
private final GaoRegistrationEventRecordService service;
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.REGISTRATION_EVENT_RECORD_READ)
|
||||
@PostMapping("/list")
|
||||
public PageResult<GaoRegistrationEventRecord> list(@RequestBody Page<GaoRegistrationEventRecord> page) {
|
||||
return service.page(page);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.REGISTRATION_EVENT_RECORD_READ)
|
||||
@PostMapping("/detail")
|
||||
public GaoRegistrationEventRecord detail(@RequestParam String id) {
|
||||
return service.get(id);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@PostMapping("/create")
|
||||
public GaoRegistrationEventRecord create(@RequestBody GaoRegistrationEventRecordCreateReq req) {
|
||||
return service.createRecord(req);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.REGISTRATION_EVENT_RECORD_UPDATE)
|
||||
@PostMapping("/update")
|
||||
public void update(@RequestBody GaoRegistrationEventRecord record) {
|
||||
service.update(record);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.REGISTRATION_EVENT_RECORD_DELETE)
|
||||
@PostMapping("/delete")
|
||||
public void delete(@RequestParam String id) {
|
||||
service.delete(id);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.REGISTRATION_EVENT_RECORD_READ)
|
||||
@PostMapping("/period/list")
|
||||
public List<GaoRegistrationEventRecord> periodList(@RequestBody GaoRegistrationEventRecordPeriodReq req) {
|
||||
return service.listByRegistrationEventAndPeriod(req);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.REGISTRATION_EVENT_RECORD_READ)
|
||||
@PostMapping("/range/list")
|
||||
public List<GaoRegistrationEventRecord> rangeList(@RequestBody GaoRegistrationEventRecordRangeReq req) {
|
||||
return service.listByRange(req);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@IgnoreGlobalReturn
|
||||
@RequireGaoPermission(GaoPermissionCode.REGISTRATION_EVENT_RECORD_READ)
|
||||
@PostMapping("/range/export")
|
||||
public void rangeExport(@RequestBody GaoRegistrationEventRecordRangeReq req, HttpServletResponse resp) throws IOException {
|
||||
List<GaoRegistrationEventRecord> list = service.listByRange(req);
|
||||
resp.setContentType("application/vnd.ms-excel;charset=UTF-8");
|
||||
resp.setHeader("Content-Disposition", "attachment; filename=\"gao-registration-event-record.csv\"");
|
||||
resp.getOutputStream().write(buildCsv(list).getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
|
||||
@PostMapping("/period/stat")
|
||||
public List<GaoRegistrationEventPeriodStatView> periodStat(@RequestBody GaoRegistrationEventRecordPeriodReq req) {
|
||||
return service.statByRegistrationEventAndPeriodType(req.getRegistrationEventId(), req.getPeriodType());
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
|
||||
@PostMapping("/customer/stat")
|
||||
public List<GaoCustomerRegisterStatView> customerStat(@RequestParam String customerId) {
|
||||
return service.statByCustomerId(customerId);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
|
||||
@PostMapping("/customer/range/stat")
|
||||
/// 按时间段统计单个客户各登记事件记录数
|
||||
public List<GaoCustomerRegisterStatView> customerRangeStat(@RequestBody GaoRegistrationEventRecordStatReq req) {
|
||||
return service.statByCustomerAndRange(req);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
|
||||
@PostMapping("/all-customer/range/stat")
|
||||
/// 按时间段统计全部客户各登记事件记录数
|
||||
public List<GaoCustomerRegisterStatView> allCustomerRangeStat(@RequestBody GaoRegistrationEventRecordStatReq req) {
|
||||
return service.statAllCustomerByRange(req);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
|
||||
@PostMapping("/customer/registration-event/daily/stat")
|
||||
/// 按天统计单个客户单个登记事件记录趋势
|
||||
public List<GaoRegistrationEventRecordDailyStatView> customerRegistrationEventDailyStat(@RequestBody GaoRegistrationEventRecordTrendStatReq req) {
|
||||
return service.statDailyByCustomerAndRegistrationEvent(req);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
|
||||
@PostMapping("/all-customer/registration-event/daily/stat")
|
||||
/// 按天统计全部客户单个登记事件记录趋势
|
||||
public List<GaoRegistrationEventRecordDailyStatView> allCustomerRegistrationEventDailyStat(@RequestBody GaoRegistrationEventRecordTrendStatReq req) {
|
||||
return service.statDailyByRegistrationEvent(req);
|
||||
}
|
||||
|
||||
private String buildCsv(List<GaoRegistrationEventRecord> list) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append((char) 65279);
|
||||
builder.append("客户编码,客户姓名,登记事件,登记时间,登记人用户 ID,备注\n");
|
||||
for (GaoRegistrationEventRecord record : list) {
|
||||
builder.append(csv(record.getCustomer() == null ? null : record.getCustomer().getCode())).append(',');
|
||||
builder.append(csv(record.getCustomer() == null ? null : record.getCustomer().getName())).append(',');
|
||||
builder.append(csv(record.getRegistrationEvent() == null ? null : record.getRegistrationEvent().getName())).append(',');
|
||||
builder.append(csv(record.getRegisteredAt())).append(',');
|
||||
builder.append(csv(record.getOperatorUserId())).append(',');
|
||||
builder.append(csv(record.getRemark())).append('\n');
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private String csv(Object value) {
|
||||
if (value == null) {
|
||||
return "";
|
||||
}
|
||||
String text = value.toString();
|
||||
if (!text.contains(",") && !text.contains("\"") && !text.contains("\n") && !text.contains("\r")) {
|
||||
return text;
|
||||
}
|
||||
return "\"%s\"".formatted(text.replace("\"", "\"\""));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.imyeyu.api.modules.gao.controller;
|
||||
|
||||
import com.imyeyu.api.bean.ModuleCode;
|
||||
import com.imyeyu.api.modules.gao.annotation.RequireGaoRole;
|
||||
import com.imyeyu.api.modules.gao.bean.GaoRoleCode;
|
||||
import com.imyeyu.api.modules.user.entity.Role;
|
||||
import com.imyeyu.api.modules.user.service.RoleService;
|
||||
import com.imyeyu.spring.annotation.AOPLog;
|
||||
import com.imyeyu.spring.annotation.RequestRateLimit;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
///
|
||||
/// GAO 角色接口
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-28
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/gao/role")
|
||||
@RequireGaoRole(GaoRoleCode.STORE_MANAGER)
|
||||
public class GaoRoleController {
|
||||
|
||||
private final RoleService roleService;
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@PostMapping("/available/list")
|
||||
public List<Role> availableList() {
|
||||
return roleService.listByModuleCode(ModuleCode.GAO);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.imyeyu.api.modules.gao.controller;
|
||||
|
||||
import com.imyeyu.api.bean.ModuleCode;
|
||||
import com.imyeyu.api.modules.gao.annotation.RequireGaoPermission;
|
||||
import com.imyeyu.api.modules.gao.annotation.RequireGaoRole;
|
||||
import com.imyeyu.api.modules.gao.bean.GaoPermissionCode;
|
||||
import com.imyeyu.api.modules.gao.bean.GaoRoleCode;
|
||||
import com.imyeyu.api.modules.gao.entity.GaoUser;
|
||||
import com.imyeyu.api.modules.gao.service.GaoUserService;
|
||||
import com.imyeyu.api.modules.user.entity.Role;
|
||||
import com.imyeyu.api.modules.user.service.RoleService;
|
||||
import com.imyeyu.spring.annotation.AOPLog;
|
||||
import com.imyeyu.spring.annotation.RequestRateLimit;
|
||||
import com.imyeyu.spring.bean.Page;
|
||||
import com.imyeyu.spring.bean.PageResult;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
///
|
||||
/// GAO 用户接口
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-30
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/gao/user")
|
||||
@RequireGaoRole(GaoRoleCode.STORE_MANAGER)
|
||||
public class GaoUserController {
|
||||
|
||||
private final GaoUserService service;
|
||||
private final RoleService roleService;
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.USER_READ)
|
||||
@PostMapping("/list")
|
||||
public PageResult<GaoUser> list(@RequestBody Page<GaoUser> page) {
|
||||
return service.pageWithUser(page);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.USER_READ)
|
||||
@PostMapping("/detail")
|
||||
public GaoUser detail(@RequestParam String id) {
|
||||
return service.get(id);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.USER_READ)
|
||||
@PostMapping("/detail/user")
|
||||
public GaoUser detailByUserId(@RequestParam String userId) {
|
||||
return service.getByUserId(userId);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.USER_CREATE)
|
||||
@PostMapping("/create")
|
||||
public GaoUser create(@RequestBody GaoUser gaoUser) {
|
||||
service.create(gaoUser);
|
||||
return service.get(gaoUser.getId());
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.USER_UPDATE)
|
||||
@PostMapping("/update")
|
||||
public GaoUser update(@RequestBody GaoUser gaoUser) {
|
||||
service.update(gaoUser);
|
||||
return service.get(gaoUser.getId());
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.USER_DELETE)
|
||||
@PostMapping("/delete")
|
||||
public void delete(@RequestParam String id) {
|
||||
service.delete(id);
|
||||
}
|
||||
|
||||
@AOPLog
|
||||
@RequestRateLimit
|
||||
@RequireGaoPermission(GaoPermissionCode.USER_READ)
|
||||
@PostMapping("/role/list")
|
||||
public List<Role> roleList() {
|
||||
return roleService.listByModuleCode(ModuleCode.GAO);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.imyeyu.api.modules.gao.entity;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.imyeyu.api.modules.common.entity.Attachment;
|
||||
import com.imyeyu.api.modules.user.bean.Gender;
|
||||
import com.imyeyu.spring.annotation.table.Transient;
|
||||
import com.imyeyu.spring.entity.UUIDEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
///
|
||||
/// 医疗护理客户
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class GaoCustomer extends UUIDEntity {
|
||||
|
||||
///
|
||||
/// 客户附件类型
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
public enum AttachType {
|
||||
|
||||
PHOTO
|
||||
}
|
||||
|
||||
/// 客户编码
|
||||
private String code;
|
||||
|
||||
/// 姓名
|
||||
private String name;
|
||||
|
||||
/// 性别
|
||||
private Gender gender;
|
||||
|
||||
/// 年龄
|
||||
private Integer age;
|
||||
|
||||
/// 电话
|
||||
private String telephone;
|
||||
|
||||
/// 住址
|
||||
private String address;
|
||||
|
||||
/// 备注
|
||||
private String remark;
|
||||
|
||||
/// 病症
|
||||
private String disease;
|
||||
|
||||
/// 调理部位,结构由前端决定
|
||||
private JsonNode conditioningPart;
|
||||
|
||||
/// 介绍人客户 ID
|
||||
private String introducerCustomerId;
|
||||
|
||||
@Transient
|
||||
private Long lastSignInAt;
|
||||
|
||||
@Transient
|
||||
private GaoCustomer introducerCustomer;
|
||||
|
||||
@Transient
|
||||
private Long invitedCount;
|
||||
|
||||
@Transient
|
||||
private List<Attachment> attachmentList;
|
||||
|
||||
/// 临时照片附件 ID 列表
|
||||
@Transient
|
||||
private List<String> attachmentIdList;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.imyeyu.api.modules.gao.entity;
|
||||
|
||||
import com.imyeyu.spring.annotation.table.Transient;
|
||||
import com.imyeyu.spring.entity.UUIDEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
///
|
||||
/// 登记事件
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class GaoRegistrationEvent extends UUIDEntity {
|
||||
|
||||
/// 登记事件名称
|
||||
private String name;
|
||||
|
||||
/// 说明
|
||||
private String description;
|
||||
|
||||
/// true 为启用
|
||||
private Boolean enabled;
|
||||
|
||||
/// true 为登记时要求拍照
|
||||
private Boolean requirePhoto;
|
||||
|
||||
/// 排序值
|
||||
private Integer sort;
|
||||
|
||||
/// 可登记角色代码列表
|
||||
@Transient
|
||||
private List<String> roleCodeList;
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.imyeyu.api.modules.gao.entity;
|
||||
|
||||
import com.imyeyu.api.modules.common.entity.Attachment;
|
||||
import com.imyeyu.api.modules.user.entity.User;
|
||||
import com.imyeyu.spring.annotation.table.Transient;
|
||||
import com.imyeyu.spring.entity.UUIDEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
///
|
||||
/// 登记事件记录
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class GaoRegistrationEventRecord extends UUIDEntity {
|
||||
|
||||
///
|
||||
/// 登记事件记录附件类型
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
public enum AttachType {
|
||||
|
||||
PHOTO
|
||||
}
|
||||
|
||||
/// 客户 ID
|
||||
private String customerId;
|
||||
|
||||
/// 登记登记事件 ID
|
||||
private String registrationEventId;
|
||||
|
||||
/// 操作管理员用户 ID
|
||||
private String operatorUserId;
|
||||
|
||||
/// 备注
|
||||
private String remark;
|
||||
|
||||
/// 登记时间
|
||||
private Long registeredAt;
|
||||
|
||||
@Transient
|
||||
private GaoCustomer customer;
|
||||
|
||||
@Transient
|
||||
private GaoRegistrationEvent registrationEvent;
|
||||
|
||||
@Transient
|
||||
private User operator;
|
||||
|
||||
@Transient
|
||||
private List<Attachment> attachmentList;
|
||||
|
||||
/// 临时照片附件 ID 列表
|
||||
@Transient
|
||||
private List<String> attachmentIdList;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.imyeyu.api.modules.gao.entity;
|
||||
|
||||
import com.imyeyu.spring.entity.UUIDEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
///
|
||||
/// 登记事件角色关联
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-28
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class GaoRegistrationEventRoleRelation extends UUIDEntity {
|
||||
|
||||
/// 登记事件 ID
|
||||
private String registrationEventId;
|
||||
|
||||
/// 角色代码
|
||||
private String roleCode;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.imyeyu.api.modules.gao.entity;
|
||||
|
||||
import com.imyeyu.api.modules.user.entity.User;
|
||||
import com.imyeyu.api.modules.user.entity.Role;
|
||||
import com.imyeyu.spring.annotation.table.Transient;
|
||||
import com.imyeyu.spring.entity.UUIDEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
///
|
||||
/// GAO 用户
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-30
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class GaoUser extends UUIDEntity {
|
||||
|
||||
/// 用户 ID
|
||||
private String userId;
|
||||
|
||||
/// true 为启用
|
||||
private Boolean enabled;
|
||||
|
||||
/// 备注
|
||||
private String remark;
|
||||
|
||||
@Transient
|
||||
private User user;
|
||||
|
||||
@Transient
|
||||
private List<Role> roleList;
|
||||
|
||||
@Transient
|
||||
private List<String> roleIdList;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.imyeyu.api.modules.gao.mapper;
|
||||
|
||||
import com.imyeyu.api.modules.gao.entity.GaoCustomer;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerDailyStatView;
|
||||
import com.imyeyu.spring.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
///
|
||||
/// 客户 Mapper
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
public interface GaoCustomerMapper extends BaseMapper<GaoCustomer, String> {
|
||||
|
||||
@Select("SELECT * FROM `gao_customer` WHERE `code` = #{code} AND `deleted_at` IS NULL LIMIT 1")
|
||||
GaoCustomer selectByCode(@Param("code") String code);
|
||||
|
||||
List<GaoCustomer> search(@Param("keyword") String keyword, @Param("introducerCustomerId") String introducerCustomerId);
|
||||
|
||||
List<GaoCustomer> selectInvitedList(@Param("introducerCustomerId") String introducerCustomerId);
|
||||
|
||||
Long countInvited(@Param("introducerCustomerId") String introducerCustomerId);
|
||||
|
||||
/// 统计每日新增客户数
|
||||
///
|
||||
/// @param beginCreatedAt 开始创建时间
|
||||
/// @param endCreatedAt 结束创建时间
|
||||
/// @return 每日新增客户数
|
||||
List<GaoCustomerDailyStatView> statDailyNewCustomer(@Param("beginCreatedAt") Long beginCreatedAt, @Param("endCreatedAt") Long endCreatedAt);
|
||||
|
||||
/// 统计开始时间前客户总数
|
||||
///
|
||||
/// @param beginCreatedAt 开始创建时间
|
||||
/// @return 客户总数
|
||||
Long countCreatedBefore(@Param("beginCreatedAt") Long beginCreatedAt);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.imyeyu.api.modules.gao.mapper;
|
||||
|
||||
import com.imyeyu.api.modules.gao.entity.GaoRegistrationEvent;
|
||||
import com.imyeyu.spring.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
///
|
||||
/// 登记事件 Mapper
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
public interface GaoRegistrationEventMapper extends BaseMapper<GaoRegistrationEvent, String> {
|
||||
|
||||
@Select("SELECT * FROM `gao_registration_event` WHERE `enabled` = TRUE AND `deleted_at` IS NULL ORDER BY `sort` ASC, `created_at` ASC")
|
||||
List<GaoRegistrationEvent> selectEnabledList();
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
package com.imyeyu.api.modules.gao.mapper;
|
||||
|
||||
import com.imyeyu.api.modules.gao.entity.GaoRegistrationEventRecord;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventPeriodStatView;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerRegisterStatView;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordDailyStatView;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordPeriodReq;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordRangeReq;
|
||||
import com.imyeyu.spring.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
///
|
||||
/// 登记事件记录 Mapper
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
public interface GaoRegistrationEventRecordMapper extends BaseMapper<GaoRegistrationEventRecord, String> {
|
||||
|
||||
/// 按登记事件查询客户最后登记事件记录
|
||||
///
|
||||
/// @param customerIdList 客户 ID 列表
|
||||
/// @param registrationEventId 登记事件 ID
|
||||
/// @return 最后登记事件记录列表
|
||||
List<GaoRegistrationEventRecord> selectByRegistrationEventAndPeriod(@Param("registrationEventId") String registrationEventId, @Param("periodType") GaoRegistrationEventRecordPeriodReq.PeriodType periodType, @Param("periodValue") Integer periodValue);
|
||||
|
||||
/// 按周期统计登记事件记录
|
||||
///
|
||||
/// @param registrationEventId 登记事件 ID
|
||||
/// @param periodType 周期类型
|
||||
/// @return 统计结果
|
||||
List<GaoRegistrationEventPeriodStatView> statByRegistrationEventAndPeriodType(@Param("registrationEventId") String registrationEventId, @Param("periodType") GaoRegistrationEventRecordPeriodReq.PeriodType periodType);
|
||||
|
||||
/// 统计客户所有登记
|
||||
///
|
||||
/// @param customerId 客户 ID
|
||||
/// @return 统计结果
|
||||
List<GaoCustomerRegisterStatView> statByCustomerId(@Param("customerId") String customerId);
|
||||
|
||||
/// 按时间段统计单个客户登记
|
||||
///
|
||||
/// @param customerId 客户 ID
|
||||
/// @param beginRegisteredAt 开始登记时间
|
||||
/// @param endRegisteredAt 结束登记时间
|
||||
/// @return 统计结果
|
||||
List<GaoCustomerRegisterStatView> statByCustomerIdAndRange(@Param("customerId") String customerId, @Param("beginRegisteredAt") Long beginRegisteredAt, @Param("endRegisteredAt") Long endRegisteredAt);
|
||||
|
||||
/// 按时间段统计全部客户登记
|
||||
///
|
||||
/// @param beginRegisteredAt 开始登记时间
|
||||
/// @param endRegisteredAt 结束登记时间
|
||||
/// @return 统计结果
|
||||
List<GaoCustomerRegisterStatView> statAllCustomerByRange(@Param("beginRegisteredAt") Long beginRegisteredAt, @Param("endRegisteredAt") Long endRegisteredAt);
|
||||
|
||||
/// 统计单个客户单个登记事件的每日登记事件记录数
|
||||
///
|
||||
/// @param customerId 客户 ID
|
||||
/// @param registrationEventId 登记事件 ID
|
||||
/// @param beginRegisteredAt 开始登记时间
|
||||
/// @param endRegisteredAt 结束登记时间
|
||||
/// @return 每日统计
|
||||
List<GaoRegistrationEventRecordDailyStatView> statDailyCountByCustomerIdAndRegistrationEventIdRange(@Param("customerId") String customerId, @Param("registrationEventId") String registrationEventId, @Param("beginRegisteredAt") Long beginRegisteredAt, @Param("endRegisteredAt") Long endRegisteredAt);
|
||||
|
||||
/// 统计全部客户单个登记事件的每日登记事件记录数
|
||||
///
|
||||
/// @param registrationEventId 登记事件 ID
|
||||
/// @param beginRegisteredAt 开始登记时间
|
||||
/// @param endRegisteredAt 结束登记时间
|
||||
/// @return 每日统计
|
||||
List<GaoRegistrationEventRecordDailyStatView> statDailyCountByRegistrationEventIdRange(@Param("registrationEventId") String registrationEventId, @Param("beginRegisteredAt") Long beginRegisteredAt, @Param("endRegisteredAt") Long endRegisteredAt);
|
||||
|
||||
/// 统计时间段前单个客户单个登记事件累计登记事件记录数
|
||||
///
|
||||
/// @param customerId 客户 ID
|
||||
/// @param registrationEventId 登记事件 ID
|
||||
/// @param beginRegisteredAt 开始登记时间
|
||||
/// @return 累计登记数
|
||||
Long countBeforeByCustomerIdAndRegistrationEventId(@Param("customerId") String customerId, @Param("registrationEventId") String registrationEventId, @Param("beginRegisteredAt") Long beginRegisteredAt);
|
||||
|
||||
/// 统计时间段前全部客户单个登记事件累计登记事件记录数
|
||||
///
|
||||
/// @param registrationEventId 登记事件 ID
|
||||
/// @param beginRegisteredAt 开始登记时间
|
||||
/// @return 累计登记数
|
||||
Long countBeforeByRegistrationEventId(@Param("registrationEventId") String registrationEventId, @Param("beginRegisteredAt") Long beginRegisteredAt);
|
||||
|
||||
/// 查询客户指定登记事件的最后登记事件记录
|
||||
///
|
||||
/// @param customerIdList 客户 ID 列表
|
||||
/// @param registrationEventId 登记事件 ID
|
||||
/// @return 最后登记事件记录列表
|
||||
List<GaoRegistrationEventRecord> selectLatestByCustomerIdListAndRegistrationEventId(@Param("customerIdList") List<String> customerIdList, @Param("registrationEventId") String registrationEventId);
|
||||
|
||||
/// 查询客户全部登记事件的最后登记事件记录
|
||||
///
|
||||
/// @param customerId 客户 ID
|
||||
/// @return 最后登记事件记录列表
|
||||
List<GaoRegistrationEventRecord> selectLatestByCustomerId(@Param("customerId") String customerId);
|
||||
|
||||
/// 按任意时间范围查询登记事件记录
|
||||
///
|
||||
/// @param req 范围查询请求
|
||||
/// @return 登记事件记录列表
|
||||
List<GaoRegistrationEventRecord> selectByRange(@Param("req") GaoRegistrationEventRecordRangeReq req);
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.imyeyu.api.modules.gao.mapper;
|
||||
|
||||
import com.imyeyu.api.modules.gao.entity.GaoRegistrationEventRoleRelation;
|
||||
import com.imyeyu.spring.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
///
|
||||
/// 登记事件角色关联 Mapper
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-28
|
||||
public interface GaoRegistrationEventRoleRelationMapper extends BaseMapper<GaoRegistrationEventRoleRelation, String> {
|
||||
|
||||
@Select("SELECT `role_code` FROM `gao_registration_event_role_relation` WHERE `registration_event_id` = #{registrationEventId} AND `deleted_at` IS NULL ORDER BY `created_at` ASC")
|
||||
List<String> selectRoleCodeListByRegistrationEventId(@Param("registrationEventId") String registrationEventId);
|
||||
|
||||
@Update("UPDATE `gao_registration_event_role_relation` SET `deleted_at` = UNIX_TIMESTAMP() WHERE `registration_event_id` = #{registrationEventId} AND `deleted_at` IS NULL")
|
||||
void deleteByRegistrationEventId(@Param("registrationEventId") String registrationEventId);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.imyeyu.api.modules.gao.mapper;
|
||||
|
||||
import com.imyeyu.api.modules.gao.entity.GaoUser;
|
||||
import com.imyeyu.spring.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
///
|
||||
/// GAO 用户 Mapper
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-30
|
||||
public interface GaoUserMapper extends BaseMapper<GaoUser, String> {
|
||||
|
||||
@Select("SELECT * FROM `gao_user` WHERE `user_id` = #{userId} AND `deleted_at` IS NULL LIMIT 1")
|
||||
GaoUser selectByUserId(@Param("userId") String userId);
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.imyeyu.api.modules.gao.service;
|
||||
|
||||
import com.imyeyu.api.modules.gao.entity.GaoCustomer;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerDailyStatView;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerInviteUpdateReq;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerSearchReq;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerTrendStatReq;
|
||||
import com.imyeyu.spring.service.BaseService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
///
|
||||
/// 客户服务
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
public interface GaoCustomerService extends BaseService<GaoCustomer, String> {
|
||||
|
||||
/// 按编码查询客户
|
||||
///
|
||||
/// @param code 客户编码
|
||||
/// @return 客户
|
||||
GaoCustomer getByCode(String code);
|
||||
|
||||
/// 按编码查询客户,不存在时返回 null
|
||||
///
|
||||
/// @param code 客户编码
|
||||
/// @return 客户
|
||||
GaoCustomer getNullableByCode(String code);
|
||||
|
||||
/// 按编码获取或快速创建客户
|
||||
///
|
||||
/// @param code 客户编码
|
||||
/// @return 客户
|
||||
GaoCustomer getOrQuickCreateByCode(String code);
|
||||
|
||||
/// 搜索客户
|
||||
///
|
||||
/// @param req 搜索请求
|
||||
/// @return 客户列表
|
||||
List<GaoCustomer> search(GaoCustomerSearchReq req);
|
||||
|
||||
/// 查询邀请的客户
|
||||
///
|
||||
/// @param introducerCustomerId 介绍人客户 ID
|
||||
/// @return 被邀请客户列表
|
||||
List<GaoCustomer> listInvited(String introducerCustomerId);
|
||||
|
||||
/// 保存邀请关系
|
||||
///
|
||||
/// @param req 邀请关系请求
|
||||
void saveInviteRelation(GaoCustomerInviteUpdateReq req);
|
||||
|
||||
/// 删除邀请关系
|
||||
///
|
||||
/// @param customerId 客户 ID
|
||||
void deleteInviteRelation(String customerId);
|
||||
|
||||
/// 统计客户每日趋势
|
||||
///
|
||||
/// @param req 趋势统计请求
|
||||
/// @return 每日趋势列表
|
||||
List<GaoCustomerDailyStatView> statDailyTrend(GaoCustomerTrendStatReq req);
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
package com.imyeyu.api.modules.gao.service;
|
||||
|
||||
import com.imyeyu.api.modules.gao.entity.GaoRegistrationEventRecord;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventPeriodStatView;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerRegisterStatView;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoQuickRegistrationEventRecordReq;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordCreateReq;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordDailyStatView;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordPeriodReq;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordRangeReq;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordStatReq;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordTrendStatReq;
|
||||
import com.imyeyu.spring.service.BaseService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
///
|
||||
/// 登记事件记录服务
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
public interface GaoRegistrationEventRecordService extends BaseService<GaoRegistrationEventRecord, String> {
|
||||
|
||||
/// 创建登记事件记录
|
||||
///
|
||||
/// @param req 创建请求
|
||||
/// @return 创建后的登记事件记录
|
||||
GaoRegistrationEventRecord createRecord(GaoRegistrationEventRecordCreateReq req);
|
||||
|
||||
/// 快速录入客户并创建登记事件记录
|
||||
///
|
||||
/// @param req 快速录入请求
|
||||
/// @return 创建后的登记事件记录
|
||||
GaoRegistrationEventRecord quickRegister(GaoQuickRegistrationEventRecordReq req);
|
||||
|
||||
/// 按任意时间范围查询登记事件记录
|
||||
///
|
||||
/// @param req 范围查询请求
|
||||
/// @return 登记事件记录列表
|
||||
List<GaoRegistrationEventRecord> listByRange(GaoRegistrationEventRecordRangeReq req);
|
||||
|
||||
/// 按周期查询登记事件记录
|
||||
///
|
||||
/// @param req 周期请求
|
||||
/// @return 登记事件记录列表
|
||||
List<GaoRegistrationEventRecord> listByRegistrationEventAndPeriod(GaoRegistrationEventRecordPeriodReq req);
|
||||
|
||||
/// 按周期统计登记事件记录
|
||||
///
|
||||
/// @param registrationEventId 登记事件 ID
|
||||
/// @param periodType 周期类型
|
||||
/// @return 统计列表
|
||||
List<GaoRegistrationEventPeriodStatView> statByRegistrationEventAndPeriodType(String registrationEventId, GaoRegistrationEventRecordPeriodReq.PeriodType periodType);
|
||||
|
||||
/// 查询客户指定登记事件的最后登记事件记录
|
||||
///
|
||||
/// @param customerIdList 客户 ID 列表
|
||||
/// @param registrationEventId 登记事件 ID
|
||||
/// @return 每个客户的最后登记事件记录
|
||||
List<GaoRegistrationEventRecord> listLatestByCustomerIdListAndRegistrationEventId(List<String> customerIdList, String registrationEventId);
|
||||
|
||||
/// 统计客户所有登记
|
||||
///
|
||||
/// @param customerId 客户 ID
|
||||
/// @return 统计结果
|
||||
List<GaoCustomerRegisterStatView> statByCustomerId(String customerId);
|
||||
|
||||
/// 按时间段统计单个客户登记
|
||||
///
|
||||
/// @param req 统计请求
|
||||
/// @return 统计结果
|
||||
List<GaoCustomerRegisterStatView> statByCustomerAndRange(GaoRegistrationEventRecordStatReq req);
|
||||
|
||||
/// 按时间段统计全部客户登记
|
||||
///
|
||||
/// @param req 统计请求
|
||||
/// @return 统计结果
|
||||
List<GaoCustomerRegisterStatView> statAllCustomerByRange(GaoRegistrationEventRecordStatReq req);
|
||||
|
||||
/// 按时间段统计单个客户单个登记事件每日趋势
|
||||
///
|
||||
/// @param req 趋势统计请求
|
||||
/// @return 每日趋势列表
|
||||
List<GaoRegistrationEventRecordDailyStatView> statDailyByCustomerAndRegistrationEvent(GaoRegistrationEventRecordTrendStatReq req);
|
||||
|
||||
/// 按时间段统计全部客户单个登记事件每日趋势
|
||||
///
|
||||
/// @param req 趋势统计请求
|
||||
/// @return 每日趋势列表
|
||||
List<GaoRegistrationEventRecordDailyStatView> statDailyByRegistrationEvent(GaoRegistrationEventRecordTrendStatReq req);
|
||||
|
||||
/// 查询客户全部登记事件的最后登记事件记录
|
||||
///
|
||||
/// @param customerId 客户 ID
|
||||
/// @return 每个登记事件的最后登记事件记录
|
||||
List<GaoRegistrationEventRecord> listLatestByCustomerId(String customerId);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.imyeyu.api.modules.gao.service;
|
||||
|
||||
import com.imyeyu.api.modules.gao.entity.GaoRegistrationEvent;
|
||||
import com.imyeyu.spring.bean.Page;
|
||||
import com.imyeyu.spring.bean.PageResult;
|
||||
import com.imyeyu.spring.service.BaseService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
///
|
||||
/// 登记事件服务
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
public interface GaoRegistrationEventService extends BaseService<GaoRegistrationEvent, String> {
|
||||
|
||||
/// 分页查询登记事件并填充可登记角色
|
||||
///
|
||||
/// @param page 分页参数
|
||||
/// @return 登记事件分页
|
||||
PageResult<GaoRegistrationEvent> pageWithRegistrationEventLimit(Page<GaoRegistrationEvent> page);
|
||||
|
||||
/// 查询启用的登记事件
|
||||
///
|
||||
/// @return 登记事件列表
|
||||
List<GaoRegistrationEvent> listEnabled();
|
||||
|
||||
/// 查询登记事件要求的角色
|
||||
///
|
||||
/// @param registrationEventId 登记事件 ID
|
||||
/// @return 角色代码列表
|
||||
List<String> listRoleCode(String registrationEventId);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.imyeyu.api.modules.gao.service;
|
||||
|
||||
import com.imyeyu.api.modules.gao.entity.GaoUser;
|
||||
import com.imyeyu.spring.bean.Page;
|
||||
import com.imyeyu.spring.bean.PageResult;
|
||||
import com.imyeyu.spring.service.BaseService;
|
||||
|
||||
///
|
||||
/// GAO 用户服务
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-30
|
||||
public interface GaoUserService extends BaseService<GaoUser, String> {
|
||||
|
||||
/// 按用户 ID 查询 GAO 用户
|
||||
///
|
||||
/// @param userId 用户 ID
|
||||
/// @return GAO 用户
|
||||
GaoUser getByUserId(String userId);
|
||||
|
||||
/// 分页查询并填充用户详情
|
||||
///
|
||||
/// @param page 分页请求
|
||||
/// @return GAO 用户分页
|
||||
PageResult<GaoUser> pageWithUser(Page<GaoUser> page);
|
||||
}
|
||||
+243
@@ -0,0 +1,243 @@
|
||||
package com.imyeyu.api.modules.gao.service.implement;
|
||||
|
||||
import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
|
||||
import com.imyeyu.api.modules.common.entity.Attachment;
|
||||
import com.imyeyu.api.modules.common.service.AttachmentService;
|
||||
import com.imyeyu.api.modules.common.vo.attach.BizUpdateReq;
|
||||
import com.imyeyu.api.modules.gao.entity.GaoCustomer;
|
||||
import com.imyeyu.api.modules.gao.mapper.GaoCustomerMapper;
|
||||
import com.imyeyu.api.modules.gao.service.GaoCustomerService;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerDailyStatView;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerInviteUpdateReq;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerSearchReq;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerTrendStatReq;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import com.imyeyu.java.bean.timi.TimiCode;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.spring.mapper.BaseMapper;
|
||||
import com.imyeyu.spring.service.AbstractEntityService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
///
|
||||
/// 客户服务实现
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class GaoCustomerServiceImplement extends AbstractEntityService<GaoCustomer, String> implements GaoCustomerService {
|
||||
|
||||
private static final DateTimeFormatter DAY_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
|
||||
|
||||
private final GaoCustomerMapper mapper;
|
||||
private final AttachmentService attachmentService;
|
||||
|
||||
@Override
|
||||
protected BaseMapper<GaoCustomer, String> mapper() {
|
||||
return mapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create(GaoCustomer entity) {
|
||||
checkEntity(entity, false);
|
||||
super.create(entity);
|
||||
saveAttachment(entity.getId(), resolveAttachmentList(entity));
|
||||
loadTransient(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(GaoCustomer entity) {
|
||||
checkEntity(entity, true);
|
||||
super.update(entity);
|
||||
saveAttachment(entity.getId(), resolveAttachmentList(entity));
|
||||
}
|
||||
|
||||
@Override
|
||||
public GaoCustomer get(String id) {
|
||||
GaoCustomer customer = super.get(id);
|
||||
loadTransient(customer);
|
||||
return customer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GaoCustomer getByCode(String code) {
|
||||
TimiException.required(code, "not found customer.code");
|
||||
GaoCustomer customer = mapper.selectByCode(code);
|
||||
TimiException.required(customer, "not found customer");
|
||||
loadTransient(customer);
|
||||
return customer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GaoCustomer getNullableByCode(String code) {
|
||||
TimiException.required(code, "not found customer.code");
|
||||
GaoCustomer customer = mapper.selectByCode(code);
|
||||
loadTransient(customer);
|
||||
return customer;
|
||||
}
|
||||
|
||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||
@Override
|
||||
public GaoCustomer getOrQuickCreateByCode(String code) {
|
||||
GaoCustomer customer = getNullableByCode(code);
|
||||
if (customer != null) {
|
||||
return customer;
|
||||
}
|
||||
customer = new GaoCustomer();
|
||||
customer.setCode(code);
|
||||
customer.setName(code);
|
||||
create(customer);
|
||||
return customer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GaoCustomer> search(GaoCustomerSearchReq req) {
|
||||
if (req == null) {
|
||||
req = new GaoCustomerSearchReq();
|
||||
}
|
||||
List<GaoCustomer> list = mapper.search(req.getKeyword(), req.getIntroducerCustomerId());
|
||||
list.forEach(this::loadTransient);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GaoCustomer> listInvited(String introducerCustomerId) {
|
||||
TimiException.required(introducerCustomerId, "not found introducerCustomerId");
|
||||
List<GaoCustomer> list = mapper.selectInvitedList(introducerCustomerId);
|
||||
list.forEach(this::loadTransient);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||
@Override
|
||||
public void saveInviteRelation(GaoCustomerInviteUpdateReq req) {
|
||||
TimiException.required(req, "not found invite req");
|
||||
TimiException.required(req.getCustomerId(), "not found invite req.customerId");
|
||||
GaoCustomer customer = super.get(req.getCustomerId());
|
||||
customer.setIntroducerCustomerId(req.getIntroducerCustomerId());
|
||||
checkEntity(customer, true);
|
||||
super.update(customer);
|
||||
}
|
||||
|
||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||
@Override
|
||||
public void deleteInviteRelation(String customerId) {
|
||||
TimiException.required(customerId, "not found customerId");
|
||||
GaoCustomer customer = super.get(customerId);
|
||||
customer.setIntroducerCustomerId(null);
|
||||
super.update(customer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GaoCustomerDailyStatView> statDailyTrend(GaoCustomerTrendStatReq req) {
|
||||
TimiException.required(req, "not found req");
|
||||
TimiException.required(req.getBeginCreatedAt(), "not found req.beginCreatedAt");
|
||||
TimiException.required(req.getEndCreatedAt(), "not found req.endCreatedAt");
|
||||
TimiException.requiredTrue(req.getEndCreatedAt() >= req.getBeginCreatedAt(), "req.endCreatedAt lt req.beginCreatedAt");
|
||||
ZoneId zoneId = ZoneId.systemDefault();
|
||||
LocalDate beginDate = Instant.ofEpochMilli(req.getBeginCreatedAt()).atZone(zoneId).toLocalDate();
|
||||
LocalDate endDate = Instant.ofEpochMilli(req.getEndCreatedAt()).atZone(zoneId).toLocalDate();
|
||||
checkDailyStatRange(beginDate, endDate);
|
||||
long beginCreatedAt = beginDate.atStartOfDay(zoneId).toInstant().toEpochMilli();
|
||||
long endCreatedAt = endDate.plusDays(1).atStartOfDay(zoneId).toInstant().toEpochMilli() - 1;
|
||||
Map<Integer, Long> newCustomerCountMap = new HashMap<>();
|
||||
for (GaoCustomerDailyStatView view : mapper.statDailyNewCustomer(beginCreatedAt, endCreatedAt)) {
|
||||
newCustomerCountMap.put(view.getDateValue(), TimiJava.defaultIfNull(view.getNewCustomerCount(), 0L));
|
||||
}
|
||||
long totalCustomerCount = TimiJava.defaultIfNull(mapper.countCreatedBefore(beginCreatedAt), 0L);
|
||||
List<GaoCustomerDailyStatView> list = new ArrayList<>();
|
||||
for (LocalDate date = beginDate; !date.isAfter(endDate); date = date.plusDays(1)) {
|
||||
int dateValue = Integer.parseInt(DAY_FORMATTER.format(date));
|
||||
long newCustomerCount = TimiJava.defaultIfNull(newCustomerCountMap.get(dateValue), 0L);
|
||||
totalCustomerCount += newCustomerCount;
|
||||
GaoCustomerDailyStatView view = new GaoCustomerDailyStatView();
|
||||
view.setDateValue(dateValue);
|
||||
view.setNewCustomerCount(newCustomerCount);
|
||||
view.setTotalCustomerCount(totalCustomerCount);
|
||||
list.add(view);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private void checkDailyStatRange(LocalDate beginDate, LocalDate endDate) {
|
||||
long days = ChronoUnit.DAYS.between(beginDate, endDate) + 1;
|
||||
TimiException.requiredTrue(days <= 366, "daily stat range too large");
|
||||
}
|
||||
|
||||
private void checkEntity(GaoCustomer entity, boolean requireId) {
|
||||
TimiException.required(entity, "not found customer");
|
||||
if (requireId) {
|
||||
TimiException.required(entity.getId(), "not found customer.id");
|
||||
}
|
||||
TimiException.required(entity.getCode(), "not found customer.code");
|
||||
TimiException.required(entity.getName(), "not found customer.name");
|
||||
GaoCustomer dbCustomer = mapper.selectByCode(entity.getCode());
|
||||
if (dbCustomer != null && !dbCustomer.getId().equals(entity.getId())) {
|
||||
throw new TimiException(TimiCode.ARG_BAD).msgKey("客户编码已存在");
|
||||
}
|
||||
if (TimiJava.isNotEmpty(entity.getIntroducerCustomerId())) {
|
||||
TimiException.requiredTrue(!entity.getIntroducerCustomerId().equals(entity.getId()), "customer.introducerCustomerId invalid");
|
||||
TimiException.required(super.get(entity.getIntroducerCustomerId()), "not found introducer customer");
|
||||
}
|
||||
}
|
||||
|
||||
private void loadTransient(GaoCustomer customer) {
|
||||
if (customer == null) {
|
||||
return;
|
||||
}
|
||||
if (TimiJava.isNotEmpty(customer.getIntroducerCustomerId())) {
|
||||
customer.setIntroducerCustomer(super.get(customer.getIntroducerCustomerId()));
|
||||
}
|
||||
customer.setInvitedCount(mapper.countInvited(customer.getId()));
|
||||
customer.setAttachmentList(attachmentService.listByBizId(Attachment.BizType.GAO_CUSTOMER, customer.getId(), GaoCustomer.AttachType.PHOTO.name()));
|
||||
}
|
||||
|
||||
private void saveAttachment(String customerId, List<Attachment> attachmentList) {
|
||||
if (attachmentList == null) {
|
||||
return;
|
||||
}
|
||||
for (Attachment attachment : attachmentList) {
|
||||
attachment.setBizType(Attachment.BizType.GAO_CUSTOMER);
|
||||
attachment.setBizId(customerId);
|
||||
attachment.setAttachType(GaoCustomer.AttachType.PHOTO.name());
|
||||
}
|
||||
BizUpdateReq req = new BizUpdateReq();
|
||||
req.setBizType(Attachment.BizType.GAO_CUSTOMER);
|
||||
req.setBizId(customerId);
|
||||
req.setItems(attachmentList);
|
||||
attachmentService.updateByBiz(req);
|
||||
}
|
||||
|
||||
private List<Attachment> resolveAttachmentList(GaoCustomer customer) {
|
||||
if (customer.getAttachmentIdList() != null) {
|
||||
return buildPhotoAttachmentList(customer.getAttachmentIdList());
|
||||
}
|
||||
return customer.getAttachmentList();
|
||||
}
|
||||
|
||||
private List<Attachment> buildPhotoAttachmentList(List<String> attachmentIdList) {
|
||||
List<Attachment> list = new ArrayList<>();
|
||||
for (String attachmentId : attachmentIdList) {
|
||||
if (attachmentId == null || attachmentId.isBlank()) {
|
||||
continue;
|
||||
}
|
||||
Attachment attachment = new Attachment();
|
||||
attachment.setTempFileId(attachmentId.trim());
|
||||
attachment.setAttachType(GaoCustomer.AttachType.PHOTO.name());
|
||||
list.add(attachment);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
+325
@@ -0,0 +1,325 @@
|
||||
package com.imyeyu.api.modules.gao.service.implement;
|
||||
|
||||
import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
|
||||
import com.imyeyu.api.bean.ModuleCode;
|
||||
import com.imyeyu.api.modules.common.entity.Attachment;
|
||||
import com.imyeyu.api.modules.common.service.AttachmentService;
|
||||
import com.imyeyu.api.modules.common.vo.attach.BizUpdateReq;
|
||||
import com.imyeyu.api.modules.gao.entity.GaoCustomer;
|
||||
import com.imyeyu.api.modules.gao.entity.GaoRegistrationEvent;
|
||||
import com.imyeyu.api.modules.gao.entity.GaoRegistrationEventRecord;
|
||||
import com.imyeyu.api.modules.gao.mapper.GaoRegistrationEventRecordMapper;
|
||||
import com.imyeyu.api.modules.gao.service.GaoCustomerService;
|
||||
import com.imyeyu.api.modules.gao.service.GaoRegistrationEventService;
|
||||
import com.imyeyu.api.modules.gao.service.GaoRegistrationEventRecordService;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventPeriodStatView;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoCustomerRegisterStatView;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoQuickRegistrationEventRecordReq;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordCreateReq;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordDailyStatView;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordPeriodReq;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordRangeReq;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordStatReq;
|
||||
import com.imyeyu.api.modules.gao.vo.GaoRegistrationEventRecordTrendStatReq;
|
||||
import com.imyeyu.api.modules.user.service.RoleChecker;
|
||||
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.bean.timi.TimiException;
|
||||
import com.imyeyu.spring.mapper.BaseMapper;
|
||||
import com.imyeyu.spring.service.AbstractEntityService;
|
||||
import com.imyeyu.utils.Time;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
///
|
||||
/// 登记事件记录服务实现
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class GaoRegistrationEventRecordServiceImplement extends AbstractEntityService<GaoRegistrationEventRecord, String> implements GaoRegistrationEventRecordService {
|
||||
|
||||
private static final DateTimeFormatter DAY_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
|
||||
|
||||
private final GaoRegistrationEventRecordMapper mapper;
|
||||
private final AttachmentService attachmentService;
|
||||
private final RoleChecker roleChecker;
|
||||
private final UserLoginService userLoginService;
|
||||
private final UserService userService;
|
||||
private final GaoCustomerService customerService;
|
||||
private final GaoRegistrationEventService registrationEventService;
|
||||
|
||||
@Override
|
||||
protected BaseMapper<GaoRegistrationEventRecord, String> mapper() {
|
||||
return mapper;
|
||||
}
|
||||
|
||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||
@Override
|
||||
public GaoRegistrationEventRecord createRecord(GaoRegistrationEventRecordCreateReq req) {
|
||||
TimiException.required(req, "not found req");
|
||||
TimiException.required(req.getRegistrationEventId(), "not found req.registrationEventId");
|
||||
String customerId = resolveCustomerId(req);
|
||||
GaoRegistrationEvent registrationEvent = registrationEventService.get(req.getRegistrationEventId());
|
||||
checkRegistrationEventPermission(registrationEvent);
|
||||
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(TimiJava.defaultIfNull(req.getRegisteredAt(), Time.now()));
|
||||
super.create(record);
|
||||
saveAttachment(record.getId(), buildPhotoAttachmentList(req.getAttachmentIdList()));
|
||||
return get(record.getId());
|
||||
}
|
||||
|
||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||
@Override
|
||||
public GaoRegistrationEventRecord quickRegister(GaoQuickRegistrationEventRecordReq req) {
|
||||
TimiException.required(req, "not found req");
|
||||
TimiException.required(req.getCustomerCode(), "not found req.customerCode");
|
||||
TimiException.required(req.getRegistrationEventId(), "not found req.registrationEventId");
|
||||
GaoCustomer customer = customerService.getOrQuickCreateByCode(req.getCustomerCode());
|
||||
GaoRegistrationEventRecordCreateReq recordReq = new GaoRegistrationEventRecordCreateReq();
|
||||
recordReq.setCustomerId(customer.getId());
|
||||
recordReq.setRegistrationEventId(req.getRegistrationEventId());
|
||||
recordReq.setRemark(req.getRemark());
|
||||
recordReq.setAttachmentIdList(req.getAttachmentIdList());
|
||||
return createRecord(recordReq);
|
||||
}
|
||||
|
||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||
@Override
|
||||
public void update(GaoRegistrationEventRecord entity) {
|
||||
TimiException.required(entity, "not found record");
|
||||
TimiException.required(entity.getId(), "not found record.id");
|
||||
TimiException.required(entity.getCustomerId(), "not found record.customerId");
|
||||
TimiException.required(entity.getRegistrationEventId(), "not found record.registrationEventId");
|
||||
customerService.get(entity.getCustomerId());
|
||||
GaoRegistrationEvent registrationEvent = registrationEventService.get(entity.getRegistrationEventId());
|
||||
checkRegistrationEventPermission(registrationEvent);
|
||||
entity.setRegisteredAt(TimiJava.defaultIfNull(entity.getRegisteredAt(), Time.now()));
|
||||
super.update(entity);
|
||||
saveAttachment(entity.getId(), resolveAttachmentList(entity));
|
||||
}
|
||||
|
||||
@Override
|
||||
public GaoRegistrationEventRecord get(String id) {
|
||||
GaoRegistrationEventRecord record = super.get(id);
|
||||
loadTransient(record);
|
||||
return record;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GaoRegistrationEventRecord> listByRegistrationEventAndPeriod(GaoRegistrationEventRecordPeriodReq req) {
|
||||
TimiException.required(req, "not found req");
|
||||
TimiException.required(req.getRegistrationEventId(), "not found req.registrationEventId");
|
||||
TimiException.required(req.getPeriodType(), "not found req.periodType");
|
||||
TimiException.required(req.getPeriodValue(), "not found req.periodValue");
|
||||
List<GaoRegistrationEventRecord> list = mapper.selectByRegistrationEventAndPeriod(req.getRegistrationEventId(), req.getPeriodType(), req.getPeriodValue());
|
||||
list.forEach(this::loadTransient);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GaoRegistrationEventRecord> listByRange(GaoRegistrationEventRecordRangeReq req) {
|
||||
TimiException.required(req, "not found req");
|
||||
checkStatRange(req.getBeginRegisteredAt(), req.getEndRegisteredAt());
|
||||
List<GaoRegistrationEventRecord> list = mapper.selectByRange(req);
|
||||
list.forEach(this::loadTransient);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GaoRegistrationEventPeriodStatView> statByRegistrationEventAndPeriodType(String registrationEventId, GaoRegistrationEventRecordPeriodReq.PeriodType periodType) {
|
||||
TimiException.required(registrationEventId, "not found registrationEventId");
|
||||
TimiException.required(periodType, "not found periodType");
|
||||
return mapper.statByRegistrationEventAndPeriodType(registrationEventId, periodType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GaoRegistrationEventRecord> listLatestByCustomerIdListAndRegistrationEventId(List<String> customerIdList, String registrationEventId) {
|
||||
TimiException.required(registrationEventId, "not found registrationEventId");
|
||||
if (TimiJava.isEmpty(customerIdList)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<GaoRegistrationEventRecord> list = mapper.selectLatestByCustomerIdListAndRegistrationEventId(customerIdList, registrationEventId);
|
||||
list.forEach(this::loadTransient);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GaoCustomerRegisterStatView> statByCustomerId(String customerId) {
|
||||
TimiException.required(customerId, "not found customerId");
|
||||
return mapper.statByCustomerId(customerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GaoCustomerRegisterStatView> statByCustomerAndRange(GaoRegistrationEventRecordStatReq req) {
|
||||
TimiException.required(req, "not found req");
|
||||
TimiException.required(req.getCustomerId(), "not found req.customerId");
|
||||
checkStatRange(req.getBeginRegisteredAt(), req.getEndRegisteredAt());
|
||||
return mapper.statByCustomerIdAndRange(req.getCustomerId(), req.getBeginRegisteredAt(), req.getEndRegisteredAt());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GaoCustomerRegisterStatView> statAllCustomerByRange(GaoRegistrationEventRecordStatReq req) {
|
||||
TimiException.required(req, "not found req");
|
||||
checkStatRange(req.getBeginRegisteredAt(), req.getEndRegisteredAt());
|
||||
return mapper.statAllCustomerByRange(req.getBeginRegisteredAt(), req.getEndRegisteredAt());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GaoRegistrationEventRecordDailyStatView> statDailyByCustomerAndRegistrationEvent(GaoRegistrationEventRecordTrendStatReq req) {
|
||||
TimiException.required(req, "not found req");
|
||||
TimiException.required(req.getCustomerId(), "not found req.customerId");
|
||||
customerService.get(req.getCustomerId());
|
||||
return buildDailyTrend(req, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GaoRegistrationEventRecordDailyStatView> statDailyByRegistrationEvent(GaoRegistrationEventRecordTrendStatReq req) {
|
||||
TimiException.required(req, "not found req");
|
||||
return buildDailyTrend(req, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GaoRegistrationEventRecord> listLatestByCustomerId(String customerId) {
|
||||
TimiException.required(customerId, "not found customerId");
|
||||
List<GaoRegistrationEventRecord> list = mapper.selectLatestByCustomerId(customerId);
|
||||
list.forEach(this::loadTransient);
|
||||
return list;
|
||||
}
|
||||
|
||||
private String resolveCustomerId(GaoRegistrationEventRecordCreateReq req) {
|
||||
if (TimiJava.isNotEmpty(req.getCustomerId())) {
|
||||
customerService.get(req.getCustomerId());
|
||||
return req.getCustomerId();
|
||||
}
|
||||
TimiException.required(req.getCustomerCode(), "not found req.customerCode");
|
||||
GaoCustomer customer = customerService.getByCode(req.getCustomerCode());
|
||||
return customer.getId();
|
||||
}
|
||||
|
||||
private void checkRegistrationEventPermission(GaoRegistrationEvent registrationEvent) {
|
||||
List<String> roleCodeList = registrationEventService.listRoleCode(registrationEvent.getId());
|
||||
if (roleCodeList != null && !roleCodeList.isEmpty()) {
|
||||
roleChecker.checkAny(ModuleCode.GAO, roleCodeList.toArray(String[]::new));
|
||||
}
|
||||
}
|
||||
|
||||
private void checkStatRange(Long beginRegisteredAt, Long endRegisteredAt) {
|
||||
TimiException.required(beginRegisteredAt, "not found beginRegisteredAt");
|
||||
TimiException.required(endRegisteredAt, "not found endRegisteredAt");
|
||||
TimiException.requiredTrue(endRegisteredAt >= beginRegisteredAt, "endRegisteredAt lt beginRegisteredAt");
|
||||
}
|
||||
|
||||
private List<GaoRegistrationEventRecordDailyStatView> buildDailyTrend(GaoRegistrationEventRecordTrendStatReq req, boolean byCustomer) {
|
||||
TimiException.required(req.getRegistrationEventId(), "not found req.registrationEventId");
|
||||
registrationEventService.get(req.getRegistrationEventId());
|
||||
checkStatRange(req.getBeginRegisteredAt(), req.getEndRegisteredAt());
|
||||
ZoneId zoneId = ZoneId.systemDefault();
|
||||
LocalDate beginDate = Instant.ofEpochMilli(req.getBeginRegisteredAt()).atZone(zoneId).toLocalDate();
|
||||
LocalDate endDate = Instant.ofEpochMilli(req.getEndRegisteredAt()).atZone(zoneId).toLocalDate();
|
||||
checkDailyStatRange(beginDate, endDate);
|
||||
long beginRegisteredAt = beginDate.atStartOfDay(zoneId).toInstant().toEpochMilli();
|
||||
long endRegisteredAt = endDate.plusDays(1).atStartOfDay(zoneId).toInstant().toEpochMilli() - 1;
|
||||
Map<Integer, Long> dailyCountMap = new HashMap<>();
|
||||
List<GaoRegistrationEventRecordDailyStatView> dbList = byCustomer
|
||||
? mapper.statDailyCountByCustomerIdAndRegistrationEventIdRange(req.getCustomerId(), req.getRegistrationEventId(), beginRegisteredAt, endRegisteredAt)
|
||||
: mapper.statDailyCountByRegistrationEventIdRange(req.getRegistrationEventId(), beginRegisteredAt, endRegisteredAt);
|
||||
for (GaoRegistrationEventRecordDailyStatView view : dbList) {
|
||||
dailyCountMap.put(view.getDateValue(), TimiJava.defaultIfNull(view.getDailyCount(), 0L));
|
||||
}
|
||||
long totalCount = byCustomer
|
||||
? TimiJava.defaultIfNull(mapper.countBeforeByCustomerIdAndRegistrationEventId(req.getCustomerId(), req.getRegistrationEventId(), beginRegisteredAt), 0L)
|
||||
: TimiJava.defaultIfNull(mapper.countBeforeByRegistrationEventId(req.getRegistrationEventId(), beginRegisteredAt), 0L);
|
||||
List<GaoRegistrationEventRecordDailyStatView> list = new ArrayList<>();
|
||||
for (LocalDate date = beginDate; !date.isAfter(endDate); date = date.plusDays(1)) {
|
||||
int dateValue = Integer.parseInt(DAY_FORMATTER.format(date));
|
||||
long dailyCount = TimiJava.defaultIfNull(dailyCountMap.get(dateValue), 0L);
|
||||
totalCount += dailyCount;
|
||||
GaoRegistrationEventRecordDailyStatView view = new GaoRegistrationEventRecordDailyStatView();
|
||||
view.setDateValue(dateValue);
|
||||
view.setDailyCount(dailyCount);
|
||||
view.setTotalCount(totalCount);
|
||||
list.add(view);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private void loadTransient(GaoRegistrationEventRecord record) {
|
||||
if (record == null) {
|
||||
return;
|
||||
}
|
||||
record.setCustomer(customerService.get(record.getCustomerId()));
|
||||
record.setRegistrationEvent(registrationEventService.get(record.getRegistrationEventId()));
|
||||
if (TimiJava.isNotEmpty(record.getOperatorUserId())) {
|
||||
record.setOperator(userService.get(record.getOperatorUserId()));
|
||||
}
|
||||
record.setAttachmentList(attachmentService.listByBizId(Attachment.BizType.GAO_REGISTRATION_EVENT_RECORD, record.getId(), GaoRegistrationEventRecord.AttachType.PHOTO.name()));
|
||||
}
|
||||
|
||||
private void checkDailyStatRange(LocalDate beginDate, LocalDate endDate) {
|
||||
long days = ChronoUnit.DAYS.between(beginDate, endDate) + 1;
|
||||
TimiException.requiredTrue(days <= 366, "daily stat range too large");
|
||||
}
|
||||
|
||||
private void saveAttachment(String recordId, List<Attachment> attachmentList) {
|
||||
if (attachmentList == null) {
|
||||
return;
|
||||
}
|
||||
for (Attachment attachment : attachmentList) {
|
||||
attachment.setBizType(Attachment.BizType.GAO_REGISTRATION_EVENT_RECORD);
|
||||
attachment.setBizId(recordId);
|
||||
attachment.setAttachType(GaoRegistrationEventRecord.AttachType.PHOTO.name());
|
||||
}
|
||||
BizUpdateReq req = new BizUpdateReq();
|
||||
req.setBizType(Attachment.BizType.GAO_REGISTRATION_EVENT_RECORD);
|
||||
req.setBizId(recordId);
|
||||
req.setItems(attachmentList);
|
||||
attachmentService.updateByBiz(req);
|
||||
}
|
||||
|
||||
private List<Attachment> resolveAttachmentList(GaoRegistrationEventRecord record) {
|
||||
if (record.getAttachmentIdList() != null) {
|
||||
return buildPhotoAttachmentList(record.getAttachmentIdList());
|
||||
}
|
||||
return record.getAttachmentList();
|
||||
}
|
||||
|
||||
private List<Attachment> buildPhotoAttachmentList(List<String> attachmentIdList) {
|
||||
if (attachmentIdList == null) {
|
||||
return null;
|
||||
}
|
||||
List<Attachment> list = new ArrayList<>();
|
||||
for (String attachmentId : attachmentIdList) {
|
||||
if (attachmentId == null || attachmentId.isBlank()) {
|
||||
continue;
|
||||
}
|
||||
Attachment attachment = new Attachment();
|
||||
attachment.setTempFileId(attachmentId.trim());
|
||||
attachment.setAttachType(GaoRegistrationEventRecord.AttachType.PHOTO.name());
|
||||
list.add(attachment);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
package com.imyeyu.api.modules.gao.service.implement;
|
||||
|
||||
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.mapper.GaoRegistrationEventRoleRelationMapper;
|
||||
import com.imyeyu.api.modules.gao.mapper.GaoRegistrationEventMapper;
|
||||
import com.imyeyu.api.modules.gao.service.GaoRegistrationEventService;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.spring.bean.Page;
|
||||
import com.imyeyu.spring.bean.PageResult;
|
||||
import com.imyeyu.spring.mapper.BaseMapper;
|
||||
import com.imyeyu.spring.service.AbstractEntityService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
///
|
||||
/// 登记事件服务实现
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class GaoRegistrationEventServiceImplement extends AbstractEntityService<GaoRegistrationEvent, String> implements GaoRegistrationEventService {
|
||||
|
||||
private final GaoRegistrationEventMapper mapper;
|
||||
private final GaoRegistrationEventRoleRelationMapper roleRelationMapper;
|
||||
|
||||
@Override
|
||||
protected BaseMapper<GaoRegistrationEvent, String> mapper() {
|
||||
return mapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<GaoRegistrationEvent> pageWithRegistrationEventLimit(Page<GaoRegistrationEvent> page) {
|
||||
PageResult<GaoRegistrationEvent> result = page(page);
|
||||
if (result.getList() != null) {
|
||||
result.getList().forEach(this::loadRegistrationEventLimit);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||
@Override
|
||||
public void create(GaoRegistrationEvent entity) {
|
||||
checkEntity(entity, false);
|
||||
super.create(entity);
|
||||
saveRoleRelation(entity.getId(), entity.getRoleCodeList());
|
||||
}
|
||||
|
||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||
@Override
|
||||
public void update(GaoRegistrationEvent entity) {
|
||||
checkEntity(entity, true);
|
||||
super.update(entity);
|
||||
saveRoleRelation(entity.getId(), entity.getRoleCodeList());
|
||||
}
|
||||
|
||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||
@Override
|
||||
public void delete(String id) {
|
||||
roleRelationMapper.deleteByRegistrationEventId(id);
|
||||
super.delete(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GaoRegistrationEvent get(String id) {
|
||||
GaoRegistrationEvent registrationEvent = super.get(id);
|
||||
registrationEvent.setRoleCodeList(roleRelationMapper.selectRoleCodeListByRegistrationEventId(id));
|
||||
return registrationEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GaoRegistrationEvent> listEnabled() {
|
||||
List<GaoRegistrationEvent> list = mapper.selectEnabledList();
|
||||
list.forEach(this::loadRegistrationEventLimit);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> listRoleCode(String registrationEventId) {
|
||||
return roleRelationMapper.selectRoleCodeListByRegistrationEventId(registrationEventId);
|
||||
}
|
||||
|
||||
private void checkEntity(GaoRegistrationEvent entity, boolean requireId) {
|
||||
TimiException.required(entity, "not found registrationEvent");
|
||||
if (requireId) {
|
||||
TimiException.required(entity.getId(), "not found registrationEvent.id");
|
||||
}
|
||||
TimiException.required(entity.getName(), "not found registrationEvent.name");
|
||||
if (entity.getEnabled() == null) {
|
||||
entity.setEnabled(true);
|
||||
}
|
||||
if (entity.getRequirePhoto() == null) {
|
||||
entity.setRequirePhoto(false);
|
||||
}
|
||||
if (entity.getSort() == null) {
|
||||
entity.setSort(0);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveRoleRelation(String registrationEventId, List<String> roleCodeList) {
|
||||
roleRelationMapper.deleteByRegistrationEventId(registrationEventId);
|
||||
if (roleCodeList == null || roleCodeList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Set<String> distinctCodeSet = new LinkedHashSet<>(roleCodeList);
|
||||
for (String roleCode : distinctCodeSet) {
|
||||
if (roleCode == null || roleCode.isBlank()) {
|
||||
continue;
|
||||
}
|
||||
GaoRegistrationEventRoleRelation relation = new GaoRegistrationEventRoleRelation();
|
||||
relation.setRegistrationEventId(registrationEventId);
|
||||
relation.setRoleCode(roleCode.trim());
|
||||
roleRelationMapper.insert(relation);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadRegistrationEventLimit(GaoRegistrationEvent registrationEvent) {
|
||||
registrationEvent.setRoleCodeList(roleRelationMapper.selectRoleCodeListByRegistrationEventId(registrationEvent.getId()));
|
||||
}
|
||||
}
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
package com.imyeyu.api.modules.gao.service.implement;
|
||||
|
||||
import com.imyeyu.api.bean.ModuleCode;
|
||||
import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
|
||||
import com.imyeyu.api.modules.gao.entity.GaoUser;
|
||||
import com.imyeyu.api.modules.gao.mapper.GaoUserMapper;
|
||||
import com.imyeyu.api.modules.gao.service.GaoUserService;
|
||||
import com.imyeyu.api.modules.user.entity.Role;
|
||||
import com.imyeyu.api.modules.user.entity.User;
|
||||
import com.imyeyu.api.modules.user.mapper.UserMapper;
|
||||
import com.imyeyu.api.modules.user.service.RoleService;
|
||||
import com.imyeyu.api.modules.user.service.UserService;
|
||||
import com.imyeyu.api.modules.user.vo.role.UserRoleAuthorizeReq;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import com.imyeyu.java.bean.timi.TimiCode;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.spring.bean.Page;
|
||||
import com.imyeyu.spring.bean.PageResult;
|
||||
import com.imyeyu.spring.mapper.BaseMapper;
|
||||
import com.imyeyu.spring.service.AbstractEntityService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
///
|
||||
/// GAO 用户服务实现
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-30
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class GaoUserServiceImplement extends AbstractEntityService<GaoUser, String> implements GaoUserService {
|
||||
|
||||
private final GaoUserMapper mapper;
|
||||
private final UserMapper userMapper;
|
||||
private final UserService userService;
|
||||
private final RoleService roleService;
|
||||
|
||||
@Override
|
||||
protected BaseMapper<GaoUser, String> mapper() {
|
||||
return mapper;
|
||||
}
|
||||
|
||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||
@Override
|
||||
public void create(GaoUser entity) {
|
||||
prepareUser(entity);
|
||||
checkEntity(entity, false);
|
||||
super.create(entity);
|
||||
saveUserRole(entity);
|
||||
loadUser(entity);
|
||||
}
|
||||
|
||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||
@Override
|
||||
public void update(GaoUser entity) {
|
||||
checkEntity(entity, true);
|
||||
updateUser(entity);
|
||||
super.update(entity);
|
||||
saveUserRole(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GaoUser get(String id) {
|
||||
GaoUser gaoUser = super.get(id);
|
||||
loadUser(gaoUser);
|
||||
return gaoUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GaoUser getByUserId(String userId) {
|
||||
TimiException.required(userId, "not found userId");
|
||||
GaoUser gaoUser = mapper.selectByUserId(userId);
|
||||
TimiException.required(gaoUser, "not found gao user");
|
||||
loadUser(gaoUser);
|
||||
return gaoUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<GaoUser> pageWithUser(Page<GaoUser> page) {
|
||||
PageResult<GaoUser> result = page(page);
|
||||
loadUser(result.getList());
|
||||
return result;
|
||||
}
|
||||
|
||||
private void checkEntity(GaoUser entity, boolean requireId) {
|
||||
TimiException.required(entity, "not found gao user");
|
||||
if (requireId) {
|
||||
TimiException.required(entity.getId(), "not found gao user.id");
|
||||
}
|
||||
TimiException.required(entity.getUserId(), "not found gao user.userId");
|
||||
TimiException.required(userMapper.select(entity.getUserId()), "not found user");
|
||||
GaoUser dbGaoUser = mapper.selectByUserId(entity.getUserId());
|
||||
if (dbGaoUser != null && !dbGaoUser.getId().equals(entity.getId())) {
|
||||
throw new TimiException(TimiCode.ARG_BAD).msgKey("GAO 用户已存在");
|
||||
}
|
||||
if (entity.getEnabled() == null) {
|
||||
entity.setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void prepareUser(GaoUser entity) {
|
||||
TimiException.required(entity, "not found gao user");
|
||||
if (TimiJava.isNotEmpty(entity.getUserId())) {
|
||||
return;
|
||||
}
|
||||
User user = entity.getUser();
|
||||
TimiException.required(user, "not found gao user.user");
|
||||
userService.create(user);
|
||||
entity.setUserId(user.getId());
|
||||
}
|
||||
|
||||
private void updateUser(GaoUser entity) {
|
||||
User reqUser = entity.getUser();
|
||||
if (reqUser == null) {
|
||||
return;
|
||||
}
|
||||
User user = userService.get(entity.getUserId());
|
||||
if (reqUser.getName() != null) {
|
||||
user.setName(reqUser.getName());
|
||||
}
|
||||
if (reqUser.getNick() != null) {
|
||||
user.setNick(reqUser.getNick());
|
||||
}
|
||||
if (reqUser.getPhoneNo() != null) {
|
||||
user.setPhoneNo(reqUser.getPhoneNo());
|
||||
}
|
||||
if (reqUser.getEmail() != null) {
|
||||
user.setEmail(reqUser.getEmail());
|
||||
}
|
||||
userService.update(user);
|
||||
}
|
||||
|
||||
private void saveUserRole(GaoUser entity) {
|
||||
if (entity.getRoleIdList() == null) {
|
||||
return;
|
||||
}
|
||||
UserRoleAuthorizeReq req = new UserRoleAuthorizeReq();
|
||||
req.setUserId(entity.getUserId());
|
||||
req.setModuleCode(ModuleCode.GAO);
|
||||
req.setRoleIdList(entity.getRoleIdList());
|
||||
roleService.authorizeUserRole(req);
|
||||
}
|
||||
|
||||
private void loadUser(GaoUser gaoUser) {
|
||||
if (gaoUser == null) {
|
||||
return;
|
||||
}
|
||||
gaoUser.setUser(userMapper.select(gaoUser.getUserId()));
|
||||
gaoUser.setRoleList(roleService.listByUserId(gaoUser.getUserId(), ModuleCode.GAO));
|
||||
}
|
||||
|
||||
private void loadUser(List<GaoUser> gaoUserList) {
|
||||
if (gaoUserList == null || gaoUserList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<String> userIdList = gaoUserList.stream().map(GaoUser::getUserId).distinct().toList();
|
||||
Map<String, User> userMap = userMapper.listByIdList(new ArrayList<>(userIdList)).stream()
|
||||
.collect(Collectors.toMap(User::getId, Function.identity(), (left, right) -> left));
|
||||
for (GaoUser gaoUser : gaoUserList) {
|
||||
gaoUser.setUser(userMap.get(gaoUser.getUserId()));
|
||||
List<Role> roleList = roleService.listByUserId(gaoUser.getUserId(), ModuleCode.GAO);
|
||||
gaoUser.setRoleList(roleList);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.imyeyu.api.modules.gao.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
///
|
||||
/// 客户每日统计视图
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-28
|
||||
@Data
|
||||
public class GaoCustomerDailyStatView {
|
||||
|
||||
/// 日期值,格式为 yyyyMMdd
|
||||
private Integer dateValue;
|
||||
|
||||
/// 当日新增客户数
|
||||
private Long newCustomerCount;
|
||||
|
||||
/// 截止当日客户总数
|
||||
private Long totalCustomerCount;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.imyeyu.api.modules.gao.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
///
|
||||
/// 客户邀请关系更新请求
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
@Data
|
||||
public class GaoCustomerInviteUpdateReq {
|
||||
|
||||
/// 客户 ID
|
||||
private String customerId;
|
||||
|
||||
/// 介绍人客户 ID
|
||||
private String introducerCustomerId;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.imyeyu.api.modules.gao.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
///
|
||||
/// 客户登记统计视图
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
@Data
|
||||
public class GaoCustomerRegisterStatView {
|
||||
|
||||
/// 客户 ID
|
||||
private String customerId;
|
||||
|
||||
/// 客户姓名
|
||||
private String customerName;
|
||||
|
||||
/// 登记事件 ID
|
||||
private String registrationEventId;
|
||||
|
||||
/// 登记事件名称
|
||||
private String registrationEventName;
|
||||
|
||||
/// 数量
|
||||
private Long count;
|
||||
|
||||
/// 最后登记时间
|
||||
private Long latestRegisteredAt;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.imyeyu.api.modules.gao.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
///
|
||||
/// 客户搜索请求
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
@Data
|
||||
public class GaoCustomerSearchReq {
|
||||
|
||||
/// 关键字,匹配编码、姓名、手机号、电话、住址、病症、条例部位
|
||||
private String keyword;
|
||||
|
||||
/// 介绍人客户 ID
|
||||
private String introducerCustomerId;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.imyeyu.api.modules.gao.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
///
|
||||
/// 客户趋势统计请求
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-28
|
||||
@Data
|
||||
public class GaoCustomerTrendStatReq {
|
||||
|
||||
/// 开始创建时间
|
||||
private Long beginCreatedAt;
|
||||
|
||||
/// 结束创建时间
|
||||
private Long endCreatedAt;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.imyeyu.api.modules.gao.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
///
|
||||
/// 快速录入并登记请求
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-28
|
||||
@Data
|
||||
public class GaoQuickRegistrationEventRecordReq {
|
||||
|
||||
/// 客户编码
|
||||
private String customerCode;
|
||||
|
||||
/// 登记登记事件 ID
|
||||
private String registrationEventId;
|
||||
|
||||
/// 备注
|
||||
private String remark;
|
||||
|
||||
/// 临时照片附件 ID 列表
|
||||
private List<String> attachmentIdList = new ArrayList<>();
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.imyeyu.api.modules.gao.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
///
|
||||
/// 登记事件周期统计视图
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
@Data
|
||||
public class GaoRegistrationEventPeriodStatView {
|
||||
|
||||
/// 登记事件 ID
|
||||
private String registrationEventId;
|
||||
|
||||
/// 周期值
|
||||
private Integer periodValue;
|
||||
|
||||
/// 数量
|
||||
private Long count;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.imyeyu.api.modules.gao.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
///
|
||||
/// 登记登记事件记录创建请求
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
@Data
|
||||
public class GaoRegistrationEventRecordCreateReq {
|
||||
|
||||
/// 客户 ID
|
||||
private String customerId;
|
||||
|
||||
/// 客户编码,扫码登记可直接传这个
|
||||
private String customerCode;
|
||||
|
||||
/// 登记事件 ID
|
||||
private String registrationEventId;
|
||||
|
||||
/// 备注
|
||||
private String remark;
|
||||
|
||||
/// 登记时间
|
||||
private Long registeredAt;
|
||||
|
||||
/// 临时照片附件 ID 列表
|
||||
private List<String> attachmentIdList = new ArrayList<>();
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.imyeyu.api.modules.gao.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
///
|
||||
/// 登记事件记录每日统计视图
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-28
|
||||
@Data
|
||||
public class GaoRegistrationEventRecordDailyStatView {
|
||||
|
||||
/// 日期值,格式为 yyyyMMdd
|
||||
private Integer dateValue;
|
||||
|
||||
/// 当日登记数
|
||||
private Long dailyCount;
|
||||
|
||||
/// 截止当日累计登记数
|
||||
private Long totalCount;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.imyeyu.api.modules.gao.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
///
|
||||
/// 登记事件记录按周期查询请求
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
@Data
|
||||
public class GaoRegistrationEventRecordPeriodReq {
|
||||
|
||||
///
|
||||
/// 周期类型
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-27
|
||||
public enum PeriodType {
|
||||
|
||||
DAY,
|
||||
|
||||
MONTH,
|
||||
|
||||
YEAR
|
||||
}
|
||||
|
||||
/// 登记事件 ID
|
||||
private String registrationEventId;
|
||||
|
||||
/// 周期类型
|
||||
private PeriodType periodType;
|
||||
|
||||
/// 周期值,日为 yyyyMMdd,月为 yyyyMM,年为 yyyy
|
||||
private Integer periodValue;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.imyeyu.api.modules.gao.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
///
|
||||
/// 登记事件记录范围查询请求
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-28
|
||||
@Data
|
||||
public class GaoRegistrationEventRecordRangeReq {
|
||||
|
||||
/// 客户 ID,为空查询全部客户
|
||||
private String customerId;
|
||||
|
||||
/// 登记事件 ID,为空查询全部登记事件
|
||||
private String registrationEventId;
|
||||
|
||||
/// 开始登记时间
|
||||
private Long beginRegisteredAt;
|
||||
|
||||
/// 结束登记时间
|
||||
private Long endRegisteredAt;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.imyeyu.api.modules.gao.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
///
|
||||
/// 登记事件记录统计请求
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-28
|
||||
@Data
|
||||
public class GaoRegistrationEventRecordStatReq {
|
||||
|
||||
/// 客户 ID,全部客户统计时不传
|
||||
private String customerId;
|
||||
|
||||
/// 开始登记时间
|
||||
private Long beginRegisteredAt;
|
||||
|
||||
/// 结束登记时间
|
||||
private Long endRegisteredAt;
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package com.imyeyu.api.modules.gao.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
///
|
||||
/// 登记事件记录趋势统计请求
|
||||
///
|
||||
/// @author Codex
|
||||
/// @since 2026-07-28
|
||||
@Data
|
||||
public class GaoRegistrationEventRecordTrendStatReq {
|
||||
|
||||
/// 客户 ID,全部客户趋势时不传
|
||||
private String customerId;
|
||||
|
||||
/// 登记事件 ID
|
||||
private String registrationEventId;
|
||||
|
||||
/// 开始登记时间
|
||||
private Long beginRegisteredAt;
|
||||
|
||||
/// 结束登记时间
|
||||
private Long endRegisteredAt;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
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<>();
|
||||
}
|
||||
Reference in New Issue
Block a user