mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-22 07:11:52 +08:00
feat: crm 线索表完善 review 提到的问题
This commit is contained in:
parent
435d7dcfca
commit
e4eeaa1d69
@ -41,23 +41,23 @@ CREATE TABLE `crm_contract`
|
||||
|
||||
DROP TABLE IF EXISTS `crm_clue`;
|
||||
CREATE TABLE `crm_clue` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,主键自增',
|
||||
`transform_status` tinyint NOT NULL COMMENT '转化状态',
|
||||
`follow_up_status` tinyint NOT NULL COMMENT '跟进状态',
|
||||
`name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '线索名称',
|
||||
`customer_id` bigint NOT NULL COMMENT '客户id',
|
||||
`contact_next_time` datetime NULL DEFAULT NULL COMMENT '下次联系时间',
|
||||
`telephone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '电话',
|
||||
`mobile` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '手机号',
|
||||
`address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '地址',
|
||||
`owner_user_id` bigint NULL DEFAULT NULL COMMENT '负责人的用户编号',
|
||||
`contact_last_time` datetime NULL DEFAULT NULL COMMENT '最后跟进时间',
|
||||
`remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '备注',
|
||||
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '线索表' ROW_FORMAT = Dynamic;
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,主键自增',
|
||||
`transform_status` tinyint DEFAULT NULL COMMENT '转化状态',
|
||||
`follow_up_status` tinyint DEFAULT NULL COMMENT '跟进状态',
|
||||
`name` varchar(128) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '线索名称',
|
||||
`customer_id` bigint NOT NULL COMMENT '客户id',
|
||||
`contact_next_time` datetime DEFAULT NULL COMMENT '下次联系时间',
|
||||
`telephone` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '电话',
|
||||
`mobile` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '手机号',
|
||||
`address` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '地址',
|
||||
`owner_user_id` bigint NOT NULL COMMENT '负责人的用户编号',
|
||||
`contact_last_time` datetime DEFAULT NULL COMMENT '最后跟进时间',
|
||||
`remark` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '备注',
|
||||
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '更新者',
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB COMMENT = '线索表' ;
|
@ -0,0 +1,28 @@
|
||||
package cn.iocoder.yudao.framework.common.validation;
|
||||
|
||||
import javax.validation.Constraint;
|
||||
import javax.validation.Payload;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target({
|
||||
ElementType.METHOD,
|
||||
ElementType.FIELD,
|
||||
ElementType.ANNOTATION_TYPE,
|
||||
ElementType.CONSTRUCTOR,
|
||||
ElementType.PARAMETER,
|
||||
ElementType.TYPE_USE
|
||||
})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Constraint(
|
||||
validatedBy = TelephoneValidator.class
|
||||
)
|
||||
public @interface Telephone {
|
||||
|
||||
String message() default "电话格式不正确";
|
||||
|
||||
Class<?>[] groups() default {};
|
||||
|
||||
Class<? extends Payload>[] payload() default {};
|
||||
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package cn.iocoder.yudao.framework.common.validation;
|
||||
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.core.util.PhoneUtil;
|
||||
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
|
||||
public class TelephoneValidator implements ConstraintValidator<Telephone, String> {
|
||||
|
||||
@Override
|
||||
public void initialize(Telephone annotation) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(String value, ConstraintValidatorContext context) {
|
||||
// 如果手机号为空,默认不校验,即校验通过
|
||||
if (CharSequenceUtil.isEmpty(value)) {
|
||||
return true;
|
||||
}
|
||||
// 校验手机
|
||||
return PhoneUtil.isTel(value) || PhoneUtil.isPhone(value);
|
||||
}
|
||||
|
||||
}
|
@ -12,7 +12,7 @@ public interface ErrorCodeConstants {
|
||||
// ========== 合同管理 1-020-000-000 ==========
|
||||
ErrorCode CONTRACT_NOT_EXISTS = new ErrorCode(1_020_000_000, "合同不存在");
|
||||
|
||||
// TODO @wanwan:要单独一个分段噢
|
||||
ErrorCode CLUE_NOT_EXISTS = new ErrorCode(1_020_000_001, "线索不存在");
|
||||
// ========== 线索管理 1-020-001-000 ==========
|
||||
ErrorCode CLUE_NOT_EXISTS = new ErrorCode(1_020_001_000, "线索不存在");
|
||||
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.clue.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.validation.Mobile;
|
||||
import cn.iocoder.yudao.framework.common.validation.Telephone;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@ -17,44 +19,31 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
|
||||
@Data
|
||||
public class CrmClueBaseVO {
|
||||
|
||||
// TODO @wanwan:转化状态,新增和修改的时候,应该不传递的哈;而是在未来的时候,才会更新到
|
||||
@Schema(description = "转化状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
@NotNull(message = "转化状态不能为空")
|
||||
private Boolean transformStatus;
|
||||
|
||||
// TODO @wanwan:同 transformStatus
|
||||
@Schema(description = "跟进状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
@NotNull(message = "跟进状态不能为空")
|
||||
private Boolean followUpStatus;
|
||||
|
||||
@Schema(description = "线索名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "线索xxx")
|
||||
@NotNull(message = "线索名称不能为空") // TODO @wanwan:应该是 NotEmpty 噢。空串都无法接受
|
||||
@NotEmpty(message = "线索名称不能为空")
|
||||
private String name;
|
||||
|
||||
// TODO @wanwan:中英文之间,要有个空格;例如说,客户 id 不能为空
|
||||
@Schema(description = "客户id", requiredMode = Schema.RequiredMode.REQUIRED, example = "520")
|
||||
@NotNull(message = "客户id不能为空")
|
||||
@Schema(description = "客户 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "520")
|
||||
@NotNull(message = "客户不能为空")
|
||||
private Long customerId;
|
||||
|
||||
@Schema(description = "下次联系时间", example = "2023-10-18 01:00:00")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime contactNextTime;
|
||||
|
||||
// TODO @wanwan:@Schema 在 @Mobile 之前,要保持统一的顺序;2)可以加个 @Telephone 的校验格式;应该不是手机的格式哈
|
||||
@Mobile(message = "电话格式不正确")
|
||||
@Schema(description = "电话", example = "18000000000")
|
||||
@Telephone
|
||||
private String telephone;
|
||||
|
||||
// TODO @wanwan:@Schema 在 @Mobile 之前,要保持统一的顺序;2)类似 @Mobile 这个提示如果是默认的,就可以不写 message
|
||||
@Mobile(message = "手机号格式不正确")
|
||||
@Schema(description = "手机号", example = "18000000000")
|
||||
@Mobile
|
||||
private String mobile;
|
||||
|
||||
@Schema(description = "地址", example = "北京市海淀区")
|
||||
private String address;
|
||||
|
||||
@Schema(description = "负责人的用户编号", example = "27199")
|
||||
// TODO @wanwan:这个是必填字段哈;
|
||||
@NotNull(message = "负责人不能为空")
|
||||
private Long ownerUserId;
|
||||
|
||||
@Schema(description = "最后跟进时间")
|
||||
|
@ -1,5 +1,6 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.clue.vo;
|
||||
|
||||
import cn.iocoder.yudao.module.infra.enums.DictTypeConstants;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
@ -12,7 +13,6 @@ import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
|
||||
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
|
||||
|
||||
|
||||
/**
|
||||
* 线索 Excel VO
|
||||
*
|
||||
@ -21,20 +21,21 @@ import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
|
||||
@Data
|
||||
public class CrmClueExcelVO {
|
||||
|
||||
@ExcelProperty("编号,主键自增")
|
||||
@ExcelProperty("编号")
|
||||
private Long id;
|
||||
|
||||
@ExcelProperty(value = "转化状态", converter = DictConvert.class)
|
||||
@DictFormat("infra_boolean_string") // TODO 代码优化:建议设置到对应的 XXXDictTypeConstants 枚举类中
|
||||
@DictFormat(DictTypeConstants.BOOLEAN_STRING)
|
||||
private Boolean transformStatus;
|
||||
|
||||
@ExcelProperty(value = "跟进状态", converter = DictConvert.class)
|
||||
@DictFormat("infra_boolean_string") // TODO 代码优化:建议设置到对应的 XXXDictTypeConstants 枚举类中
|
||||
@DictFormat(DictTypeConstants.BOOLEAN_STRING)
|
||||
private Boolean followUpStatus;
|
||||
|
||||
@ExcelProperty("线索名称")
|
||||
private String name;
|
||||
|
||||
// TODO 这里需要导出成客户名称
|
||||
@ExcelProperty("客户id")
|
||||
private Long customerId;
|
||||
|
||||
|
@ -5,54 +5,18 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 线索分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CrmCluePageReqVO extends PageParam {
|
||||
|
||||
// TODO @wanwan:目前只要支持 name、mobile、telephone 的搜索即可;其它字段应该暂时不需要哈;
|
||||
|
||||
@Schema(description = "转化状态", example = "true")
|
||||
private Boolean transformStatus;
|
||||
|
||||
@Schema(description = "跟进状态", example = "true")
|
||||
private Boolean followUpStatus;
|
||||
|
||||
@Schema(description = "线索名称", example = "线索xxx")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "客户id", example = "520")
|
||||
private Long customerId;
|
||||
|
||||
@Schema(description = "下次联系时间", example = "2023-10-18 01:00:00")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] contactNextTime;
|
||||
|
||||
@Schema(description = "电话", example = "18000000000")
|
||||
private String telephone;
|
||||
|
||||
@Schema(description = "手机号", example = "18000000000")
|
||||
private String mobile;
|
||||
|
||||
@Schema(description = "地址", example = "北京市海淀区")
|
||||
private String address;
|
||||
|
||||
@Schema(description = "负责人的用户编号", example = "27199")
|
||||
private Long ownerUserId;
|
||||
|
||||
@Schema(description = "最后跟进时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] contactLastTime;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.crm.controller.admin.clue.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 线索 Response VO")
|
||||
@ -16,4 +18,10 @@ public class CrmClueRespVO extends CrmClueBaseVO {
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "转化状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
private Boolean transformStatus;
|
||||
|
||||
@Schema(description = "跟进状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
private Boolean followUpStatus;
|
||||
|
||||
}
|
||||
|
@ -19,17 +19,9 @@ public interface CrmClueMapper extends BaseMapperX<CrmClueDO> {
|
||||
|
||||
default PageResult<CrmClueDO> selectPage(CrmCluePageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<CrmClueDO>()
|
||||
.eqIfPresent(CrmClueDO::getTransformStatus, reqVO.getTransformStatus())
|
||||
.eqIfPresent(CrmClueDO::getFollowUpStatus, reqVO.getFollowUpStatus())
|
||||
.likeIfPresent(CrmClueDO::getName, reqVO.getName())
|
||||
.eqIfPresent(CrmClueDO::getCustomerId, reqVO.getCustomerId())
|
||||
.betweenIfPresent(CrmClueDO::getContactNextTime, reqVO.getContactNextTime())
|
||||
.likeIfPresent(CrmClueDO::getTelephone, reqVO.getTelephone())
|
||||
.likeIfPresent(CrmClueDO::getMobile, reqVO.getMobile())
|
||||
.likeIfPresent(CrmClueDO::getAddress, reqVO.getAddress())
|
||||
.eqIfPresent(CrmClueDO::getOwnerUserId, reqVO.getOwnerUserId())
|
||||
.betweenIfPresent(CrmClueDO::getContactLastTime, reqVO.getContactLastTime())
|
||||
.betweenIfPresent(CrmClueDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(CrmClueDO::getId));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user