Browse Source
OpportunitySiteSurvey 实体 + Mapper 骨架(对齐票 03/09 粒度): - 一商机多条保留历史、无状态机、不绑阶段(自由记录) - 必填 surveyDate/engineerUserId/applyWay/surveySeq,选填 applyNo/surveyDesc - 主要工程师引用 crm-auth SysUser(可跨部门选人,≠操作人),联系方式反查不冗余存 - 附件复用统一附件表 biz_type=SITE_SURVEY(票 09) - 无唯一约束 → BaseEntity 逻辑删,不加 delete_key 测试:OpportunitySiteSurveyMapperTest,crm-opportunity 108→111 全绿。 接线待后续:勘察读写 Service/Controller、crm-dict 申请方式/勘察次数分组master
5 changed files with 147 additions and 1 deletions
@ -0,0 +1,68 @@ |
|||
package com.crm.opportunity.domain.entity; |
|||
|
|||
import com.baomidou.mybatisplus.annotation.TableName; |
|||
import com.crm.base.domain.entity.BaseEntity; |
|||
import jakarta.persistence.Column; |
|||
import jakarta.persistence.Entity; |
|||
import jakarta.persistence.Index; |
|||
import jakarta.persistence.Table; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import org.hibernate.annotations.Comment; |
|||
|
|||
import java.time.LocalDate; |
|||
|
|||
/** |
|||
* 现场勘察子表(票 08 §7.3 / 原型 A3-1-1-1-4 列表、A3-1-1-2-10 新增弹窗) |
|||
* |
|||
* <p>记录商机某次到客户现场勘察的**结果单据**(现场条件/客户需求/安装环境/工程师建议 + 附件)。 |
|||
* 一个商机可多条勘察记录(多次勘察保留历史不覆盖,新增多条区分);**无状态机**(填完即完整记录, |
|||
* 异于方案卡);**不绑阶段节点**(自由记录,不联动轴 2)。</p> |
|||
* |
|||
* <p>主要工程师从 {@code crm-auth} 组织架构选({@code engineer_user_id} 引用 SysUser,非自由文本, |
|||
* 可跨部门查询选人)——工程师是被选中的执行人,≠ 操作人(当前登录销售/管理员);列表「联系方式」 |
|||
* 由 engineer_user_id 反查 SysUser 电话脱敏展示,不冗余存。附件走统一附件表 |
|||
* {@code opportunity_attachment}({@code biz_type=SITE_SURVEY},{@code biz_id}=本记录 id,票 09)。</p> |
|||
* |
|||
* <p>删除留痕走 BaseEntity 逻辑删({@code deleted})——无唯一约束故不需 delete_key 复用键 |
|||
* (对齐子表族约定:delete_key 仅为唯一索引复用服务)。</p> |
|||
*/ |
|||
@Data |
|||
@EqualsAndHashCode(callSuper = true) |
|||
@TableName("opportunity_site_survey") |
|||
@Entity |
|||
@Table(name = "opportunity_site_survey", |
|||
indexes = { |
|||
@Index(name = "idx_oss_opp", columnList = "opp_id"), |
|||
@Index(name = "idx_oss_engineer", columnList = "engineer_user_id") |
|||
}) |
|||
public class OpportunitySiteSurvey extends BaseEntity { |
|||
|
|||
@Comment("所属商机ID(opportunity.id)") |
|||
@Column(columnDefinition = "bigint not null comment '所属商机ID'") |
|||
private Long oppId; |
|||
|
|||
@Comment("现场勘察日期(必填)") |
|||
@Column(columnDefinition = "date not null comment '现场勘察日期'") |
|||
private LocalDate surveyDate; |
|||
|
|||
@Comment("主要工程师用户ID(必填,引用 crm-auth SysUser,可跨部门选人;列表反查姓名/部门/脱敏电话)") |
|||
@Column(columnDefinition = "bigint not null comment '主要工程师用户ID'") |
|||
private Long engineerUserId; |
|||
|
|||
@Comment("申请方式字典 code(工单申请/线下申请…,crm-dict「申请方式」分组)") |
|||
@Column(columnDefinition = "varchar(32) not null comment '申请方式字典code'") |
|||
private String applyWay; |
|||
|
|||
@Comment("勘察次数字典 code(第一次/第二次/第三次/三次以上四档,crm-dict「勘察次数」分组,非自增,P1-2)") |
|||
@Column(columnDefinition = "varchar(32) not null comment '勘察次数字典code'") |
|||
private String surveySeq; |
|||
|
|||
@Comment("申请单号(选填,人工录入,外部勘察申请流程未对接、线下拿到后补录)") |
|||
@Column(columnDefinition = "varchar(64) comment '申请单号'") |
|||
private String applyNo; |
|||
|
|||
@Comment("勘察补充说明(选填,长文本:现场环境/客户需求/安装条件/设备数量/特殊要求/工程师建议)") |
|||
@Column(columnDefinition = "text comment '勘察补充说明'") |
|||
private String surveyDesc; |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
package com.crm.opportunity.mapper; |
|||
|
|||
import com.crm.base.mapper.CrmBaseMapper; |
|||
import com.crm.opportunity.domain.entity.OpportunitySiteSurvey; |
|||
import org.apache.ibatis.annotations.Mapper; |
|||
|
|||
@Mapper |
|||
public interface OpportunitySiteSurveyMapper extends CrmBaseMapper<OpportunitySiteSurvey> { |
|||
} |
|||
@ -0,0 +1,56 @@ |
|||
package com.crm.opportunity.mapper; |
|||
|
|||
import com.baomidou.mybatisplus.core.MybatisConfiguration; |
|||
import com.baomidou.mybatisplus.core.metadata.TableInfo; |
|||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; |
|||
import com.crm.base.mapper.CrmBaseMapper; |
|||
import com.crm.opportunity.domain.entity.OpportunitySiteSurvey; |
|||
import org.apache.ibatis.annotations.Mapper; |
|||
import org.apache.ibatis.builder.MapperBuilderAssistant; |
|||
import org.junit.jupiter.api.BeforeAll; |
|||
import org.junit.jupiter.api.DisplayName; |
|||
import org.junit.jupiter.api.Test; |
|||
|
|||
import static org.assertj.core.api.Assertions.assertThat; |
|||
|
|||
/** |
|||
* 现场勘察 Mapper 骨架单测(票 08 §7.3)。 |
|||
* <p>验证 MyBatis-Plus 表绑定 + 驼峰列映射;无唯一约束故走 BaseEntity 逻辑删(deleted), |
|||
* 无 delete_key 复用键。</p> |
|||
*/ |
|||
@DisplayName("现场勘察 Mapper 骨架 OpportunitySiteSurveyMapper(票 08)") |
|||
class OpportunitySiteSurveyMapperTest { |
|||
|
|||
@BeforeAll |
|||
static void initTableInfo() { |
|||
MapperBuilderAssistant assistant = |
|||
new MapperBuilderAssistant(new MybatisConfiguration(), ""); |
|||
TableInfoHelper.initTableInfo(assistant, OpportunitySiteSurvey.class); |
|||
} |
|||
|
|||
@Test |
|||
@DisplayName("继承 CrmBaseMapper + @Mapper 注解(可被扫描注册)") |
|||
void mapperWellFormed() { |
|||
assertThat(CrmBaseMapper.class).isAssignableFrom(OpportunitySiteSurveyMapper.class); |
|||
assertThat(OpportunitySiteSurveyMapper.class.getAnnotation(Mapper.class)).isNotNull(); |
|||
} |
|||
|
|||
@Test |
|||
@DisplayName("绑定 opportunity_site_survey,列映射 engineer_user_id↔engineerUserId / survey_seq↔surveySeq") |
|||
void tableInfo_resolvesSiteSurvey() { |
|||
TableInfo info = TableInfoHelper.getTableInfo(OpportunitySiteSurvey.class); |
|||
assertThat(info.getTableName()).isEqualTo("opportunity_site_survey"); |
|||
assertThat(info.getFieldList()).anyMatch(f -> |
|||
"engineer_user_id".equals(f.getColumn()) && "engineerUserId".equals(f.getProperty())); |
|||
assertThat(info.getFieldList()).anyMatch(f -> |
|||
"survey_seq".equals(f.getColumn()) && "surveySeq".equals(f.getProperty())); |
|||
} |
|||
|
|||
@Test |
|||
@DisplayName("逻辑删:BaseEntity deleted 生效,无 delete_key(无唯一约束不需复用键)") |
|||
void logicDelete_noDeleteKey() { |
|||
TableInfo info = TableInfoHelper.getTableInfo(OpportunitySiteSurvey.class); |
|||
assertThat(info.getLogicDeleteFieldInfo()).isNotNull(); |
|||
assertThat(info.getFieldList()).noneMatch(f -> "delete_key".equals(f.getColumn())); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue