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