@@ -0,0 +1,536 @@
package com.rj.scheduler ;
import com.rj.entity.CustomerProfileAnalysis ;
import com.rj.service.biz.impl.CustomerProfileAnalysisServiceImpl ;
import lombok.extern.slf4j.Slf4j ;
import org.springframework.beans.factory.annotation.Autowired ;
import org.springframework.scheduling.annotation.Scheduled ;
import org.springframework.stereotype.Component ;
import java.time.LocalDateTime ;
import java.time.format.DateTimeFormatter ;
import java.util.concurrent.ThreadLocalRandom ;
/**
* 客户画像分析数据定时生成器
* 每天凌晨2:30插入模拟的客户画像分析数据
*
* Author: 李中华 wx: spllzh email(qq): 28668817@qq.com
* Date: 2025/1/3
*/
@Slf4j
@Component
public class CustomerProfileMockInsertDataScheduler {
// @Autowired
// private ICustomerProfileAnalysisService customerProfileAnalysisService;
@Autowired
CustomerProfileAnalysisServiceImpl customerProfileAnalysisService ; ;
// 项目数据 - 来自适配准真实.sql的project_management JSON
private static final String [ ] [ ] PROJECTS = {
{ " 1957424785875087363 " , " 奔驰C级销售项目 " } ,
{ " 1957424785875087364 " , " 奥迪A4L项目 " } ,
{ " 1957424785875087365 " , " 宝马3系项目 " } ,
{ " 1957424785875087366 " , " 雷克萨斯RX项目 " } ,
{ " 1957424785875087367 " , " 保时捷911项目 " } ,
{ " 1957424785875087368 " , " 威兹曼GT项目 " }
} ;
// 销售顾问数据 - 来自适配准真实.sql的sales_management JSON
private static final String [ ] [ ] SALES_PEOPLE = {
{ " 1957424800000000001 " , " 张明 " } ,
{ " 1957424800000000002 " , " 李华 " } ,
{ " 1957424800000000003 " , " 王强 " } ,
{ " 1957424800000000004 " , " 刘芳 " } ,
{ " 1957424800000000005 " , " 陈军 " } ,
{ " 1957424800000000006 " , " 赵敏 " } ,
{ " 1957424800000000007 " , " 孙丽 " } ,
{ " 1957424800000000008 " , " 周涛 " }
} ;
// 经销商门店数据 - 来自适配准真实.sql的经销商门店JSON
private static final String [ ] [ ] DEALERSHIPS = {
{ " 1957424710587330562 " , " 广州奔驰4S店 " } ,
{ " 1957424711560409089 " , " 北京奥迪4S店 " } ,
{ " 1957424714953601026 " , " 上海宝马4S店 " } ,
{ " 1957424739267981313 " , " 深圳雷克萨斯4S店 " } ,
{ " 1957424740000000001 " , " 成都保时捷4S店 " } ,
{ " 1957424740000000017 " , " 昆明威兹曼4S店 " }
} ;
// 大区数据 - 确保数据分布均衡
private static final String [ ] BIG_AREAS = {
" 华北区 " , " 华东区 " , " 华南区 " , " 华中区 " , " 西南区 " , " 西北区 " , " 东北区 "
} ;
// 单向开口率数据 - 来自适配准真实.sql的单向开口率JSON
private static final String [ ] [ ] OPENING_RATES = {
{ " 1957424800000000001 " , " 沃尔沃M90续航亮点 " } ,
{ " 1957424800000000002 " , " lexus RX350智能互联 " } ,
{ " 1957424800000000003 " , " 别克品牌主张 " } ,
{ " 1957424800000000004 " , " lexusRX470刹车问题 " }
} ;
// 客户姓名库
private static final String [ ] CUSTOMER_NAMES = {
" 王小明 " , " 李小红 " , " 张伟 " , " 刘敏 " , " 陈强 " , " 杨丽 " , " 赵刚 " , " 黄娟 " ,
" 周杰 " , " 吴芳 " , " 徐磊 " , " 孙静 " , " 马超 " , " 朱琳 " , " 胡军 " , " 郭娜 " ,
" 何涛 " , " 罗雪 " , " 高飞 " , " 梁梅 " , " 宋波 " , " 唐丽 " , " 韩强 " , " 冯敏 " ,
" 邓伟 " , " 曹静 " , " 彭军 " , " 蒋娜 " , " 薛涛 " , " 方丽 " , " 石强 " , " 顾敏 "
} ;
// 客户电话前缀
private static final String [ ] PHONE_PREFIXES = {
" 138 " , " 139 " , " 150 " , " 151 " , " 152 " , " 158 " , " 159 " , " 188 " , " 189 "
} ;
// 购买类型
private static final String [ ] PURCHASE_TYPES = { " 新购 " , " 置换 " , " 增购 " } ;
// 付款方式
private static final String [ ] PAYMENT_WAYS = { " 贷款 " , " 全款 " , " 分期 " } ;
// 竞品品牌
private static final String [ ] COMPETITOR_BRANDS = { " 奔驰 " , " 宝马 " , " 奥迪 " , " 雷克萨斯 " , " 保时捷 " , " 威兹曼 " } ;
// 购车用途
private static final String [ ] VEHICLE_USAGES = { " 家用 " , " 商用 " , " 代步 " } ;
// 实际驾驶人
private static final String [ ] PRIMARY_DRIVERS = { " 本人 " , " 家人 " , " 其他 " } ;
// 教育水平
private static final String [ ] EDUCATION_LEVELS = { " 高中 " , " 大专 " , " 本科 " , " 硕士 " , " 博士 " } ;
// 家庭结构
private static final String [ ] FAMILY_COMPOSITIONS = { " 单身 " , " 已婚无子女 " , " 已婚有子女 " , " 离异 " } ;
// 职业
private static final String [ ] JOB_TITLES = { " 教师 " , " 工程师 " , " 医生 " , " 律师 " , " 销售 " , " 经理 " , " 公务员 " , " 自由职业 " } ;
// 企业性质
private static final String [ ] COMPANY_TYPES = { " 民营企业 " , " 国企 " , " 外企 " , " 事业单位 " , " 政府机关 " } ;
// 所属行业
private static final String [ ] INDUSTRY_SECTORS = { " 教育 " , " 互联网 " , " 金融 " , " 制造业 " , " 医疗 " , " 房地产 " , " 零售 " , " 服务业 " } ;
// 兴趣点
private static final String [ ] INTEREST_FOCUSES = { " 智能驾驶 " , " 油耗 " , " 空间 " , " 外观 " , " 内饰 " , " 动力 " , " 安全 " , " 环保 " } ;
// 顾虑点
private static final String [ ] CONCERN_POINTS = { " 保养成本 " , " 保值率 " , " 维修费用 " , " 保险费用 " , " 充电便利性 " , " 续航里程 " } ;
// 情感倾向
private static final String [ ] EMOTION_TENDENCIES = { " 积极 " , " 中性 " , " 消极 " } ;
/**
* 每天凌晨2:30执行客户画像数据生成任务
*/
@Scheduled ( cron = " 0 30 2 * * ? " )
public void generateDailyCustomerProfileData ( ) {
try {
log . info ( " 开始执行客户画像数据生成任务... " ) ;
// 生成昨天的数据
LocalDateTime yesterday = LocalDateTime . now ( ) . minusDays ( 1 ) ;
int count = generateCustomerProfileDataForDate ( yesterday ) ;
log . info ( " 客户画像数据生成任务执行完成,生成日期:{},生成记录数:{} " ,
yesterday . format ( DateTimeFormatter . ofPattern ( " yyyy-MM-dd " ) ) , count ) ;
// 生成今天的数据
LocalDateTime today = LocalDateTime . now ( ) . minusDays ( 0 ) ;
int todayCount = generateCustomerProfileDataForDate ( today ) ;
log . info ( " 客户画像数据生成任务执行完成,生成日期:{},生成记录数:{} " ,
today . format ( DateTimeFormatter . ofPattern ( " yyyy-MM-dd " ) ) , todayCount ) ;
} catch ( Exception e ) {
log . error ( " 客户画像数据生成任务执行失败 " , e ) ;
}
}
/**
* 为指定日期生成客户画像数据
*
* @param date 要生成数据的日期
* @return 生成的记录数
*/
public int generateCustomerProfileDataForDate ( LocalDateTime date ) {
try {
log . info ( " 开始为日期 {} 生成客户画像数据 " , date . format ( DateTimeFormatter . ofPattern ( " yyyy-MM-dd " ) ) ) ;
// 每天生成20-50条记录, 确保数据分布均匀
int recordCount = ThreadLocalRandom . current ( ) . nextInt ( 30 , 50 ) ;
int successCount = 0 ;
for ( int i = 0 ; i < recordCount ; i + + ) {
try {
CustomerProfileAnalysis analysis = createRandomCustomerProfileAnalysis ( date ) ;
boolean result = customerProfileAnalysisService . save ( analysis ) ;
if ( result ) {
successCount + + ;
log . debug ( " 成功生成第{}条客户画像数据 - 客户:{},门店:{},项目:{} " ,
i + 1 , analysis . getClientName ( ) , analysis . getDealerName ( ) , analysis . getProjectName ( ) ) ;
} else {
log . warn ( " 保存第{}条客户画像数据失败 " , i + 1 ) ;
}
} catch ( Exception e ) {
log . error ( " 生成第{}条客户画像数据失败 " , i + 1 , e ) ;
}
}
log . info ( " 为日期 {} 生成客户画像数据完成,成功生成记录数:{} " ,
date . format ( DateTimeFormatter . ofPattern ( " yyyy-MM-dd " ) ) , successCount ) ;
return successCount ;
} catch ( Exception e ) {
log . error ( " 为日期 {} 生成客户画像数据失败 " , date . format ( DateTimeFormatter . ofPattern ( " yyyy-MM-dd " ) ) , e ) ;
throw e ;
}
}
/**
* 创建随机的客户画像分析数据
*
* @param baseDate 基础日期
* @return 客户画像分析对象
*/
private CustomerProfileAnalysis createRandomCustomerProfileAnalysis ( LocalDateTime baseDate ) {
CustomerProfileAnalysis analysis = new CustomerProfileAnalysis ( ) ;
ThreadLocalRandom random = ThreadLocalRandom . current ( ) ;
// 基础字段
analysis . setProfileAnalysisRecordId ( " AI_ " + System . currentTimeMillis ( ) + " _ " + random . nextInt ( 1000 , 9999 ) ) ;
analysis . setAnalysisSceneType ( random . nextInt ( 1 , 5 ) ) ; // 1-4随机
analysis . setRelatedBusinessId ( " BIZ_ " + System . currentTimeMillis ( ) + " _ " + random . nextInt ( 1000 , 9999 ) ) ;
// 随机选择经销商、项目、销售顾问、开口率,确保分布均匀
String [ ] dealership = DEALERSHIPS [ random . nextInt ( DEALERSHIPS . length ) ] ;
String [ ] project = PROJECTS [ random . nextInt ( PROJECTS . length ) ] ;
String [ ] salesPerson = SALES_PEOPLE [ random . nextInt ( SALES_PEOPLE . length ) ] ;
String [ ] openingRate = OPENING_RATES [ random . nextInt ( OPENING_RATES . length ) ] ;
// 设置经销商信息
analysis . setDealerCode ( dealership [ 0 ] ) ;
analysis . setDealerName ( dealership [ 1 ] ) ;
analysis . setBigArea ( BIG_AREAS [ random . nextInt ( BIG_AREAS . length ) ] ) ;
// 设置项目信息
analysis . setProjectId ( project [ 0 ] ) ;
analysis . setProjectName ( project [ 1 ] ) ;
// 设置销售顾问信息
analysis . setSalesPersonId ( salesPerson [ 0 ] ) ;
analysis . setSalesPersonName ( salesPerson [ 1 ] ) ;
// 生成唯一ID
long timestamp = System . currentTimeMillis ( ) ;
int randomSuffix = random . nextInt ( 1000 , 9999 ) ;
analysis . setOpportunityId ( " OPP_ " + timestamp + " _ " + randomSuffix ) ;
analysis . setClientId ( " CLIENT_ " + timestamp + " _ " + randomSuffix ) ;
// 客户信息
analysis . setClientName ( CUSTOMER_NAMES [ random . nextInt ( CUSTOMER_NAMES . length ) ] ) ;
analysis . setClientPhone ( generateRandomPhone ( ) ) ;
// 沟通时间 - 在基础日期的随机时间
LocalDateTime interactionTime = baseDate
. withHour ( random . nextInt ( 9 , 18 ) ) // 9-17点
. withMinute ( random . nextInt ( 0 , 60 ) )
. withSecond ( random . nextInt ( 0 , 60 ) ) ;
analysis . setInteractionDate ( interactionTime ) ;
// 客户画像信息字段
analysis . setPurchaseDate ( String . valueOf ( random . nextInt ( 1 , 91 ) ) ) ; // 1-90天
analysis . setPurchaseType ( PURCHASE_TYPES [ random . nextInt ( PURCHASE_TYPES . length ) ] ) ;
analysis . setPaymentWay ( PAYMENT_WAYS [ random . nextInt ( PAYMENT_WAYS . length ) ] ) ;
analysis . setCompetitorBrand ( COMPETITOR_BRANDS [ random . nextInt ( COMPETITOR_BRANDS . length ) ] ) ;
analysis . setVehicleUsage ( VEHICLE_USAGES [ random . nextInt ( VEHICLE_USAGES . length ) ] ) ;
analysis . setPrimaryDriver ( PRIMARY_DRIVERS [ random . nextInt ( PRIMARY_DRIVERS . length ) ] ) ;
// 预算范围
int budgetMin = random . nextInt ( 20 , 100 ) ;
int budgetMax = budgetMin + random . nextInt ( 10 , 50 ) ;
analysis . setBudgetRange ( budgetMin + " - " + budgetMax + " 万 " ) ;
// 教育水平
analysis . setEducationLevel ( EDUCATION_LEVELS [ random . nextInt ( EDUCATION_LEVELS . length ) ] ) ;
// 家庭结构
analysis . setFamilyComposition ( FAMILY_COMPOSITIONS [ random . nextInt ( FAMILY_COMPOSITIONS . length ) ] ) ;
// 月收入
int incomeMin = random . nextInt ( 5 , 30 ) ;
int incomeMax = incomeMin + random . nextInt ( 5 , 20 ) ;
analysis . setMonthlyIncome ( incomeMin + " - " + incomeMax + " 万 " ) ;
// 职业信息
analysis . setJobTitle ( JOB_TITLES [ random . nextInt ( JOB_TITLES . length ) ] ) ;
analysis . setCompanyType ( COMPANY_TYPES [ random . nextInt ( COMPANY_TYPES . length ) ] ) ;
analysis . setIndustrySector ( INDUSTRY_SECTORS [ random . nextInt ( INDUSTRY_SECTORS . length ) ] ) ;
// 兴趣和顾虑
analysis . setInterestFocus ( INTEREST_FOCUSES [ random . nextInt ( INTEREST_FOCUSES . length ) ] ) ;
analysis . setConcernPoint ( CONCERN_POINTS [ random . nextInt ( CONCERN_POINTS . length ) ] ) ;
analysis . setPurchaseQualification ( random . nextBoolean ( ) ? " 是 " : " 否 " ) ;
// 其他信息 - 利用新字段生成更详细的备注
analysis . setNotes ( String . format ( " 客户在%s门店咨询%s项目, 销售顾问%s接待, 关注点: %s, 购车意向明确 " ,
dealership [ 1 ] , project [ 1 ] , salesPerson [ 1 ] , openingRate [ 1 ] ) ) ;
analysis . setCurrentBrand ( COMPETITOR_BRANDS [ random . nextInt ( COMPETITOR_BRANDS . length ) ] ) ;
analysis . setHomeAddress ( generateRandomAddress ( ) ) ;
analysis . setFamilySize ( String . valueOf ( random . nextInt ( 1 , 6 ) ) ) ; // 1-5人
analysis . setHobby ( " 运动、旅游、音乐 " ) ;
// 实体情感分析字段 - 随机生成情感倾向
generateEntityEmotions ( analysis , random ) ;
// 系统字段
LocalDateTime now = LocalDateTime . now ( ) ;
analysis . setCreatedAt ( now ) ;
analysis . setUpdatedAt ( now ) ;
analysis . setRecordVersion ( 0 ) ;
analysis . setIsDeleted ( 0 ) ;
analysis . setCreateSqlby ( " sched " ) ; // 限制在8个字符以内
analysis . setUpdateSqlby ( " sched " ) ; // 限制在8个字符以内
// 数据验证
validateCustomerProfileAnalysis ( analysis ) ;
// 调试日志 - 输出生成的数据信息
log . debug ( " 生成客户画像数据完成 - ID: {}, 客户: {}, 门店: {}, 项目: {}, 销售顾问: {} " ,
analysis . getId ( ) , analysis . getClientName ( ) , analysis . getDealerName ( ) ,
analysis . getProjectName ( ) , analysis . getSalesPersonName ( ) ) ;
return analysis ;
}
/**
* 生成实体情感分析数据
*/
private void generateEntityEmotions ( CustomerProfileAnalysis analysis , ThreadLocalRandom random ) {
String [ ] emotions = EMOTION_TENDENCIES ;
String [ ] reasons = { " 客户对此方面表示满意 " , " 客户对此方面持中性态度 " , " 客户对此方面存在疑虑 " } ;
// 品牌情感
int brandEmotion = random . nextInt ( emotions . length ) ;
analysis . setEntityBrand ( emotions [ brandEmotion ] ) ;
analysis . setEntityBrandReason ( reasons [ brandEmotion ] ) ;
// 外观设计情感
int designEmotion = random . nextInt ( emotions . length ) ;
analysis . setEntityDesign ( emotions [ designEmotion ] ) ;
analysis . setEntityDesignReason ( reasons [ designEmotion ] ) ;
// 颜色情感
int colorEmotion = random . nextInt ( emotions . length ) ;
analysis . setEntityColor ( emotions [ colorEmotion ] ) ;
analysis . setEntityColorReason ( reasons [ colorEmotion ] ) ;
// 尺寸情感
int sizeEmotion = random . nextInt ( emotions . length ) ;
analysis . setEntitySize ( emotions [ sizeEmotion ] ) ;
analysis . setEntitySizeReason ( reasons [ sizeEmotion ] ) ;
// 空间情感
int spaceEmotion = random . nextInt ( emotions . length ) ;
analysis . setEntitySpace ( emotions [ spaceEmotion ] ) ;
analysis . setEntitySpaceReason ( reasons [ spaceEmotion ] ) ;
// 内饰情感
int interiorEmotion = random . nextInt ( emotions . length ) ;
analysis . setEntityInterior ( emotions [ interiorEmotion ] ) ;
analysis . setEntityInteriorReason ( reasons [ interiorEmotion ] ) ;
// 音响情感
int audioEmotion = random . nextInt ( emotions . length ) ;
analysis . setEntityAudio ( emotions [ audioEmotion ] ) ;
analysis . setEntityAudioReason ( reasons [ audioEmotion ] ) ;
// 车机情感
int ivinfoEmotion = random . nextInt ( emotions . length ) ;
analysis . setEntityIvinfo ( emotions [ ivinfoEmotion ] ) ;
analysis . setEntityIvinfoReason ( reasons [ ivinfoEmotion ] ) ;
// 智驾情感
int fsdEmotion = random . nextInt ( emotions . length ) ;
analysis . setEntityFsd ( emotions [ fsdEmotion ] ) ;
analysis . setEntityFsdReason ( reasons [ fsdEmotion ] ) ;
// 续航情感
int mileageEmotion = random . nextInt ( emotions . length ) ;
analysis . setEntityMileage ( emotions [ mileageEmotion ] ) ;
analysis . setEntityMileageReason ( reasons [ mileageEmotion ] ) ;
// 安全情感
int safetyEmotion = random . nextInt ( emotions . length ) ;
analysis . setEntitySafety ( emotions [ safetyEmotion ] ) ;
analysis . setEntitySafetyReason ( reasons [ safetyEmotion ] ) ;
// 环保情感
int ecoEmotion = random . nextInt ( emotions . length ) ;
analysis . setEntityEco ( emotions [ ecoEmotion ] ) ;
analysis . setEntityEcoReason ( reasons [ ecoEmotion ] ) ;
// 绿牌/路权情感
int liscenseEmotion = random . nextInt ( emotions . length ) ;
analysis . setEntityLiscense ( emotions [ liscenseEmotion ] ) ;
analysis . setEntityLiscenseReason ( reasons [ liscenseEmotion ] ) ;
// 价格情感
int priceEmotion = random . nextInt ( emotions . length ) ;
analysis . setEntityPrice ( emotions [ priceEmotion ] ) ;
analysis . setEntityPriceReason ( reasons [ priceEmotion ] ) ;
// 购车权益情感
int benefitEmotion = random . nextInt ( emotions . length ) ;
analysis . setEntityBenefit ( emotions [ benefitEmotion ] ) ;
analysis . setEntityBenefitReason ( reasons [ benefitEmotion ] ) ;
// 用车成本情感
int costEmotion = random . nextInt ( emotions . length ) ;
analysis . setEntityCost ( emotions [ costEmotion ] ) ;
analysis . setEntityCostReason ( reasons [ costEmotion ] ) ;
// 性价比情感
int valueEmotion = random . nextInt ( emotions . length ) ;
analysis . setEntityValue ( emotions [ valueEmotion ] ) ;
analysis . setEntityValueReason ( reasons [ valueEmotion ] ) ;
// 动力情感
int powerEmotion = random . nextInt ( emotions . length ) ;
analysis . setEntityPower ( emotions [ powerEmotion ] ) ;
analysis . setEntityPowerReason ( reasons [ powerEmotion ] ) ;
// 操控情感
int controlEmotion = random . nextInt ( emotions . length ) ;
analysis . setEntityControl ( emotions [ controlEmotion ] ) ;
analysis . setEntityControlReason ( reasons [ controlEmotion ] ) ;
// 置换政策情感
int tradeinEmotion = random . nextInt ( emotions . length ) ;
analysis . setEntityTradein ( emotions [ tradeinEmotion ] ) ;
analysis . setEntityTradeinReason ( reasons [ tradeinEmotion ] ) ;
// 金融方案情感
int financeEmotion = random . nextInt ( emotions . length ) ;
analysis . setEntityFinance ( emotions [ financeEmotion ] ) ;
analysis . setEntityFinanceReason ( reasons [ financeEmotion ] ) ;
// 质保情感
int warrantyEmotion = random . nextInt ( emotions . length ) ;
analysis . setEntityWarranty ( emotions [ warrantyEmotion ] ) ;
analysis . setEntityWarrantyReason ( reasons [ warrantyEmotion ] ) ;
// 交付时间情感
int deliveryEmotion = random . nextInt ( emotions . length ) ;
analysis . setEntityDelivery ( emotions [ deliveryEmotion ] ) ;
analysis . setEntityDeliveryReason ( reasons [ deliveryEmotion ] ) ;
}
/**
* 验证客户画像分析数据的完整性
*
* @param analysis 客户画像分析对象
*/
private void validateCustomerProfileAnalysis ( CustomerProfileAnalysis analysis ) {
if ( analysis = = null ) {
throw new IllegalArgumentException ( " 客户画像分析对象不能为空 " ) ;
}
// 验证必填字段
if ( analysis . getProfileAnalysisRecordId ( ) = = null | | analysis . getProfileAnalysisRecordId ( ) . trim ( ) . isEmpty ( ) ) {
throw new IllegalArgumentException ( " AI分析记录ID不能为空 " ) ;
}
if ( analysis . getDealerCode ( ) = = null | | analysis . getDealerCode ( ) . trim ( ) . isEmpty ( ) ) {
throw new IllegalArgumentException ( " 经销商编码不能为空 " ) ;
}
if ( analysis . getDealerName ( ) = = null | | analysis . getDealerName ( ) . trim ( ) . isEmpty ( ) ) {
throw new IllegalArgumentException ( " 经销商门店名称不能为空 " ) ;
}
if ( analysis . getProjectId ( ) = = null | | analysis . getProjectId ( ) . trim ( ) . isEmpty ( ) ) {
throw new IllegalArgumentException ( " 项目ID不能为空 " ) ;
}
if ( analysis . getProjectName ( ) = = null | | analysis . getProjectName ( ) . trim ( ) . isEmpty ( ) ) {
throw new IllegalArgumentException ( " 项目名称不能为空 " ) ;
}
if ( analysis . getSalesPersonId ( ) = = null | | analysis . getSalesPersonId ( ) . trim ( ) . isEmpty ( ) ) {
throw new IllegalArgumentException ( " 销售顾问ID不能为空 " ) ;
}
if ( analysis . getSalesPersonName ( ) = = null | | analysis . getSalesPersonName ( ) . trim ( ) . isEmpty ( ) ) {
throw new IllegalArgumentException ( " 销售顾问姓名不能为空 " ) ;
}
if ( analysis . getClientName ( ) = = null | | analysis . getClientName ( ) . trim ( ) . isEmpty ( ) ) {
throw new IllegalArgumentException ( " 客户姓名不能为空 " ) ;
}
if ( analysis . getClientPhone ( ) = = null | | analysis . getClientPhone ( ) . trim ( ) . isEmpty ( ) ) {
throw new IllegalArgumentException ( " 客户电话不能为空 " ) ;
}
if ( analysis . getInteractionDate ( ) = = null ) {
throw new IllegalArgumentException ( " 沟通时间不能为空 " ) ;
}
log . debug ( " 客户画像分析数据验证通过 - 客户:{},门店:{},项目:{},销售顾问:{} " ,
analysis . getClientName ( ) , analysis . getDealerName ( ) ,
analysis . getProjectName ( ) , analysis . getSalesPersonName ( ) ) ;
}
/**
* 生成随机手机号
*/
private String generateRandomPhone ( ) {
ThreadLocalRandom random = ThreadLocalRandom . current ( ) ;
String prefix = PHONE_PREFIXES [ random . nextInt ( PHONE_PREFIXES . length ) ] ;
StringBuilder phone = new StringBuilder ( prefix ) ;
for ( int i = 0 ; i < 8 ; i + + ) {
phone . append ( random . nextInt ( 0 , 10 ) ) ;
}
return phone . toString ( ) ;
}
/**
* 生成随机地址
*/
private String generateRandomAddress ( ) {
String [ ] cities = { " 北京市 " , " 上海市 " , " 广州市 " , " 深圳市 " , " 成都市 " , " 杭州市 " , " 南京市 " , " 武汉市 " } ;
String [ ] districts = { " 朝阳区 " , " 海淀区 " , " 西城区 " , " 东城区 " , " 丰台区 " , " 石景山区 " , " 通州区 " , " 昌平区 " } ;
ThreadLocalRandom random = ThreadLocalRandom . current ( ) ;
String city = cities [ random . nextInt ( cities . length ) ] ;
String district = districts [ random . nextInt ( districts . length ) ] ;
String street = " 某某街道 " + random . nextInt ( 1 , 100 ) + " 号 " ;
return city + district + street ;
}
/**
* 手动触发数据生成任务(用于测试或补录数据)
*
* @param date 要生成数据的日期
* @return 生成的记录数
*/
public int manualGenerateData ( LocalDateTime date ) {
try {
log . info ( " 手动执行客户画像数据生成任务,生成日期:{} " , date . format ( DateTimeFormatter . ofPattern ( " yyyy-MM-dd " ) ) ) ;
int count = generateCustomerProfileDataForDate ( date ) ;
log . info ( " 手动客户画像数据生成任务执行完成,生成日期:{},生成记录数:{} " ,
date . format ( DateTimeFormatter . ofPattern ( " yyyy-MM-dd " ) ) , count ) ;
return count ;
} catch ( Exception e ) {
log . error ( " 手动客户画像数据生成任务执行失败,生成日期:{} " , date . format ( DateTimeFormatter . ofPattern ( " yyyy-MM-dd " ) ) , e ) ;
throw e ;
}
}
}