按需求调整

This commit is contained in:
andy committed 2026-02-03 15:37:25 +08:00
1 parent 8aa3af986f
commit daacd7d742
17 files changed
+602 -165

No files matched your search

@@ -55,6 +55,11 @@ public class Constants {
*/
public static final int REPORT_STATUS_EXPIRED = 3;
/**
* 报备状态 - 已作废
*/
public static final int REPORT_STATUS_CANCELED = 4;
/**
* 用户角色 - 管理员
*/
@@ -5,6 +5,7 @@ import com.bycrm.common.Result;
import com.bycrm.dto.PageQuery;
import com.bycrm.dto.ReportAuditDTO;
import com.bycrm.dto.ReportDTO;
import com.bycrm.dto.ReportUpdateDTO;
import com.bycrm.service.ReportService;
import com.bycrm.vo.ReportVO;
import io.swagger.annotations.Api;
@@ -72,6 +73,20 @@ public class ReportController {
return Result.success();
}
/**
* 更新报备
*/
@ApiOperation("更新报备")
@PutMapping("/{id}")
public Result<Void> updateReport(
@ApiParam("报备ID") @PathVariable Long id,
@RequestBody ReportUpdateDTO updateDTO,
HttpServletRequest request) {
Long currentUserId = (Long) request.getAttribute("currentUserId");
reportService.updateReport(id, updateDTO, currentUserId);
return Result.success();
}
/**
* 审核报备
*/
@@ -2,7 +2,7 @@ package com.bycrm.dto;
import lombok.Data;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
/**
@@ -14,10 +14,27 @@ public class ReportDTO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 客户ID
* 学校ID(可选,从数据源中选择时提供)
*/
@NotNull(message = "客户ID不能为空")
private Long customerId;
private Long schoolId;
/**
* 学校名称(必填)
*/
@NotBlank(message = "学校名称不能为空")
private String schoolName;
/**
* 所属产品
*/
@NotBlank(message = "所属产品不能为空")
private String product;
/**
* 项目类型
*/
@NotBlank(message = "项目类型不能为空")
private String projectType;
/**
* 报备说明
@@ -0,0 +1,44 @@
package com.bycrm.dto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* 报备更新 DTO
*/
@Data
public class ReportUpdateDTO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 所属产品
*/
@NotBlank(message = "所属产品不能为空")
private String product;
/**
* 项目类型
*/
@NotBlank(message = "项目类型不能为空")
private String projectType;
/**
* 报备说明
*/
private String description;
/**
* 状态
*/
@NotNull(message = "状态不能为空")
private Integer status;
/**
* 作废原因(当状态为作废时必填)
*/
private String cancelReason;
}
@@ -26,9 +26,24 @@ public class Report implements Serializable {
private Long dealerId;
/**
* 客户ID
* 学校ID(从 crm_school 选择)
*/
private Long customerId;
private Long schoolId;
/**
* 学校名称(冗余存储,方便查询)
*/
private String schoolName;
/**
* 所属产品
*/
private String product;
/**
* 项目类型
*/
private String projectType;
/**
* 报备说明
@@ -36,7 +51,7 @@ public class Report implements Serializable {
private String description;
/**
* 状态:0-待审核 1-已通过 2-已驳回 3-已失效
* 状态:0-待审核 1-已通过 2-已驳回 3-已失效 4-已作废
*/
private Integer status;
@@ -45,6 +60,11 @@ public class Report implements Serializable {
*/
private String rejectReason;
/**
* 作废原因
*/
private String cancelReason;
/**
* 保护期开始日期
*/
@@ -73,14 +93,4 @@ public class Report implements Serializable {
* 关联查询字段 - 经销商名称
*/
private String dealerName;
/**
* 关联查询字段 - 客户名称
*/
private String customerName;
/**
* 关联查询字段 - 客户电话
*/
private String customerPhone;
}
@@ -19,9 +19,18 @@ public interface ReportMapper {
Report selectById(@Param("id") Long id);
/**
* 查询客户的有效报备
* 查询学校+产品+项目类型的有效报备(根据学校ID)
*/
Report selectValidByCustomerId(@Param("customerId") Long customerId);
Report selectValidBySchoolAndProduct(@Param("schoolId") Long schoolId,
@Param("product") String product,
@Param("projectType") String projectType);
/**
* 查询学校名称+产品+项目类型的有效报备(根据学校名称)
*/
Report selectValidBySchoolNameAndProduct(@Param("schoolName") String schoolName,
@Param("product") String product,
@Param("projectType") String projectType);
/**
* 分页查询报备
@@ -12,6 +12,11 @@ import java.util.List;
@Mapper
public interface SchoolMapper {
/**
* 根据ID查询学校
*/
School selectById(@Param("id") Long id);
/**
* 插入学校
*/
@@ -4,6 +4,7 @@ import com.bycrm.common.PageResult;
import com.bycrm.dto.PageQuery;
import com.bycrm.dto.ReportAuditDTO;
import com.bycrm.dto.ReportDTO;
import com.bycrm.dto.ReportUpdateDTO;
import com.bycrm.vo.ReportVO;
/**
@@ -27,6 +28,11 @@ public interface ReportService {
*/
void createReport(ReportDTO reportDTO, Long currentUserId);
/**
* 更新报备
*/
void updateReport(Long id, ReportUpdateDTO updateDTO, Long currentUserId);
/**
* 审核报备
*/
@@ -5,12 +5,13 @@ import com.bycrm.common.PageResult;
import com.bycrm.dto.PageQuery;
import com.bycrm.dto.ReportAuditDTO;
import com.bycrm.dto.ReportDTO;
import com.bycrm.dto.ReportUpdateDTO;
import com.bycrm.entity.Report;
import com.bycrm.entity.Customer;
import com.bycrm.entity.School;
import com.bycrm.entity.User;
import com.bycrm.exception.BusinessException;
import com.bycrm.mapper.CustomerMapper;
import com.bycrm.mapper.ReportMapper;
import com.bycrm.mapper.SchoolMapper;
import com.bycrm.mapper.UserMapper;
import com.bycrm.service.ReportService;
import com.bycrm.service.SystemConfigService;
@@ -32,16 +33,16 @@ import java.util.stream.Collectors;
public class ReportServiceImpl implements ReportService {
private final ReportMapper reportMapper;
private final CustomerMapper customerMapper;
private final SchoolMapper schoolMapper;
private final UserMapper userMapper;
private final SystemConfigService systemConfigService;
public ReportServiceImpl(ReportMapper reportMapper,
CustomerMapper customerMapper,
SchoolMapper schoolMapper,
UserMapper userMapper,
SystemConfigService systemConfigService) {
this.reportMapper = reportMapper;
this.customerMapper = customerMapper;
this.schoolMapper = schoolMapper;
this.userMapper = userMapper;
this.systemConfigService = systemConfigService;
}
@@ -86,23 +87,47 @@ public class ReportServiceImpl implements ReportService {
throw new BusinessException("您未关联经销商,无法提交报备");
}
// 检查客户是否存在
Customer customer = customerMapper.selectById(reportDTO.getCustomerId());
if (customer == null) {
throw new BusinessException("客户不存在");
// 防撞单校验:根据是否有 schoolId 选择不同的校验方式
Report existingReport = null;
if (reportDTO.getSchoolId() != null) {
// 有学校ID,按学校ID+产品+项目类型校验
existingReport = reportMapper.selectValidBySchoolAndProduct(
reportDTO.getSchoolId(),
reportDTO.getProduct(),
reportDTO.getProjectType()
);
} else {
// 没有学校ID,按学校名称+产品+项目类型校验
existingReport = reportMapper.selectValidBySchoolNameAndProduct(
reportDTO.getSchoolName(),
reportDTO.getProduct(),
reportDTO.getProjectType()
);
}
// 防撞单校验:检查该客户是否已存在有效报备
Report existingReport = reportMapper.selectValidByCustomerId(reportDTO.getCustomerId());
Boolean allowOverlap = systemConfigService.getBooleanConfigValue("report.allow.overlap", false);
if (existingReport != null && !allowOverlap) {
throw new BusinessException("该客户已被其他经销商报备,无法重复报备");
throw new BusinessException("该项目已报备");
}
// 如果有学校ID,查询学校信息
String schoolName = reportDTO.getSchoolName();
Long schoolId = reportDTO.getSchoolId();
if (schoolId != null) {
School school = schoolMapper.selectById(schoolId);
if (school != null) {
schoolName = school.getSchoolName();
}
}
// 创建报备
Report report = new Report();
report.setDealerId(currentUser.getDealerId());
report.setCustomerId(reportDTO.getCustomerId());
report.setSchoolId(schoolId); // 可以为 NULL
report.setSchoolName(schoolName);
report.setProduct(reportDTO.getProduct());
report.setProjectType(reportDTO.getProjectType());
report.setDescription(reportDTO.getDescription());
report.setStatus(Constants.REPORT_STATUS_PENDING);
report.setCreatedAt(LocalDateTime.now());
@@ -138,11 +163,6 @@ public class ReportServiceImpl implements ReportService {
report.setProtectStartDate(today);
Integer protectDays = systemConfigService.getIntegerConfigValue("report.protect.days", Constants.DEFAULT_PROTECT_DAYS);
report.setProtectEndDate(today.plusDays(protectDays));
// 更新客户状态为保护中
Customer customer = customerMapper.selectById(report.getCustomerId());
customer.setStatus(Constants.CUSTOMER_STATUS_PROTECTED);
customerMapper.update(customer);
} else {
// 审核驳回
report.setStatus(Constants.REPORT_STATUS_REJECTED);
@@ -153,6 +173,43 @@ public class ReportServiceImpl implements ReportService {
reportMapper.update(report);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateReport(Long id, ReportUpdateDTO updateDTO, Long currentUserId) {
// 获取当前用户
User currentUser = userMapper.selectById(currentUserId);
if (currentUser.getRole() != Constants.USER_ROLE_ADMIN) {
throw new BusinessException("只有管理员才能编辑报备");
}
Report report = reportMapper.selectById(id);
if (report == null) {
throw new BusinessException("报备不存在");
}
// 只有已通过的报备才能编辑
if (report.getStatus() != Constants.REPORT_STATUS_APPROVED) {
throw new BusinessException("只能编辑已通过的报备");
}
// 如果状态改为作废,必须填写作废原因
if (updateDTO.getStatus() == Constants.REPORT_STATUS_CANCELED) {
if (updateDTO.getCancelReason() == null || updateDTO.getCancelReason().trim().isEmpty()) {
throw new BusinessException("作废时必须填写作废原因");
}
}
// 更新报备信息
report.setProduct(updateDTO.getProduct());
report.setProjectType(updateDTO.getProjectType());
report.setDescription(updateDTO.getDescription());
report.setStatus(updateDTO.getStatus());
report.setCancelReason(updateDTO.getCancelReason());
report.setUpdatedAt(LocalDateTime.now());
reportMapper.update(report);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void withdrawReport(Long id, Long currentUserId) {
@@ -189,15 +246,6 @@ public class ReportServiceImpl implements ReportService {
// 批量更新报备状态
List<Long> ids = expiringReports.stream().map(Report::getId).collect(Collectors.toList());
reportMapper.batchUpdateExpired(ids);
// 批量更新客户状态为可报备
expiringReports.forEach(report -> {
Customer customer = customerMapper.selectById(report.getCustomerId());
if (customer != null && customer.getStatus() == Constants.CUSTOMER_STATUS_PROTECTED) {
customer.setStatus(Constants.CUSTOMER_STATUS_AVAILABLE);
customerMapper.update(customer);
}
});
}
@Override
@@ -236,6 +284,9 @@ public class ReportServiceImpl implements ReportService {
case Constants.REPORT_STATUS_EXPIRED:
vo.setStatusDesc("已失效");
break;
case Constants.REPORT_STATUS_CANCELED:
vo.setStatusDesc("已作废");
break;
default:
vo.setStatusDesc("未知");
}
@@ -31,19 +31,24 @@ public class ReportVO implements Serializable {
private String dealerName;
/**
* 客户ID
* 学校ID
*/
private Long customerId;
private Long schoolId;
/**
* 客户名称
* 学校名称
*/
private String customerName;
private String schoolName;
/**
* 客户电话
* 所属产品
*/
private String customerPhone;
private String product;
/**
* 项目类型
*/
private String projectType;
/**
* 报备说明
@@ -51,7 +56,7 @@ public class ReportVO implements Serializable {
private String description;
/**
* 状态:0-待审核 1-已通过 2-已驳回 3-已失效
* 状态:0-待审核 1-已通过 2-已驳回 3-已失效 4-已作废
*/
private Integer status;
@@ -65,6 +70,11 @@ public class ReportVO implements Serializable {
*/
private String rejectReason;
/**
* 作废原因
*/
private String cancelReason;
/**
* 保护期开始日期
*/