补充客客户信息照片和性别年龄

This commit is contained in:
2026-05-02 18:09:07 +08:00
parent 557e12f631
commit 1799735b21
4 changed files with 113 additions and 9 deletions

View File

@@ -37,6 +37,14 @@ public class CustomerManagement implements Serializable {
@TableField("customer_name") @TableField("customer_name")
private String customerName; private String customerName;
@Schema(description = "性别")
@TableField("gender")
private String gender;
@Schema(description = "年龄")
@TableField("age")
private Integer age;
@Schema(description = "联系方式") @Schema(description = "联系方式")
@TableField("contact") @TableField("contact")
private String contact; private String contact;
@@ -93,6 +101,18 @@ public class CustomerManagement implements Serializable {
@TableField("contact_count") @TableField("contact_count")
private Integer contactCount; private Integer contactCount;
@Schema(description = "正面照片URL")
@TableField("front_photo_url")
private String frontPhotoUrl;
@Schema(description = "侧面照片URL")
@TableField("side_photo_url")
private String sidePhotoUrl;
@Schema(description = "生活照URL")
@TableField("life_photo_url")
private String lifePhotoUrl;
@Schema(description = "操作类型") @Schema(description = "操作类型")
@TableField("operation_type") @TableField("operation_type")
private String operationType; private String operationType;

View File

@@ -92,7 +92,7 @@ public class LbDailyUserTradeReportServiceImpl extends ServiceImpl<LbDailyUserTr
queryWrapper.eq(LbDailyUserTradeReport::getTenantId, tenantId) queryWrapper.eq(LbDailyUserTradeReport::getTenantId, tenantId)
.ge(LbDailyUserTradeReport::getReportDate, start) .ge(LbDailyUserTradeReport::getReportDate, start)
.lt(LbDailyUserTradeReport::getReportDate, end) .lt(LbDailyUserTradeReport::getReportDate, end)
.ne(LbDailyUserTradeReport::getDataType, DATA_TYPE_REPORT_SUM); .eq(LbDailyUserTradeReport::getDataType, DATA_TYPE_REPORT_DETAIL);
BigDecimal yestodayBuyAmt = BigDecimal.ZERO; BigDecimal yestodayBuyAmt = BigDecimal.ZERO;
BigDecimal dailySellAmt = BigDecimal.ZERO; BigDecimal dailySellAmt = BigDecimal.ZERO;
@@ -127,8 +127,19 @@ public class LbDailyUserTradeReportServiceImpl extends ServiceImpl<LbDailyUserTr
summary.setCreatedAt(LocalDateTime.now()); summary.setCreatedAt(LocalDateTime.now());
summary.setUpdatedAt(LocalDateTime.now()); summary.setUpdatedAt(LocalDateTime.now());
// 同日重复汇总时先清理历史汇总,避免 report_sum 产生多条导致读取口径不稳定。
LambdaQueryWrapper<LbDailyUserTradeReport> sumDeleteWrapper = new LambdaQueryWrapper<>();
sumDeleteWrapper.eq(LbDailyUserTradeReport::getTenantId, tenantId)
.ge(LbDailyUserTradeReport::getReportDate, start)
.lt(LbDailyUserTradeReport::getReportDate, end)
.eq(LbDailyUserTradeReport::getDataType, DATA_TYPE_REPORT_SUM);
remove(sumDeleteWrapper);
boolean success = save(summary); boolean success = save(summary);
Map<String, Object> checkInfo = buildCrossDayCheckInfo(reportDate, tenantId, start, end, yestodayBuyAmt); Map<String, Object> checkInfo = buildCrossDayCheckInfo(reportDate, tenantId, start, end, yestodayBuyAmt);
if (success && refreshSummaryFromDetail(summary, tenantId, start, end)) {
checkInfo.put("summaryRefreshed", true);
}
result.put("success", success); result.put("success", success);
if (success) { if (success) {
@@ -223,11 +234,64 @@ public class LbDailyUserTradeReportServiceImpl extends ServiceImpl<LbDailyUserTr
query.eq(LbDailyUserTradeReport::getTenantId, tenantId) query.eq(LbDailyUserTradeReport::getTenantId, tenantId)
.ge(LbDailyUserTradeReport::getReportDate, yesterdayStart) .ge(LbDailyUserTradeReport::getReportDate, yesterdayStart)
.lt(LbDailyUserTradeReport::getReportDate, yesterdayEnd) .lt(LbDailyUserTradeReport::getReportDate, yesterdayEnd)
.eq(LbDailyUserTradeReport::getDataType, DATA_TYPE_REPORT_SUM); .eq(LbDailyUserTradeReport::getDataType, DATA_TYPE_REPORT_SUM)
.orderByDesc(LbDailyUserTradeReport::getUpdatedAt)
.orderByDesc(LbDailyUserTradeReport::getCreatedAt)
.last("limit 1");
List<LbDailyUserTradeReport> rows = list(query); List<LbDailyUserTradeReport> rows = list(query);
return rows.isEmpty() ? null : rows.get(0); return rows.isEmpty() ? null : rows.get(0);
} }
private boolean refreshSummaryFromDetail(
LbDailyUserTradeReport summary,
String tenantId,
LocalDateTime start,
LocalDateTime end) {
TradeSummaryAmount latest = aggregateDetailAmounts(tenantId, start, end);
boolean changed = isSummaryChanged(summary, latest);
if (!changed) {
return false;
}
summary.setYestodayBuyAmt(latest.yestodayBuyAmt);
summary.setDailySellAmt(latest.dailySellAmt);
summary.setDailyBuyAmt(latest.dailyBuyAmt);
summary.setServiceAmt(latest.serviceAmt);
summary.setDiffAmt(latest.diffAmt);
summary.setDikouAmt(latest.dikouAmt);
summary.setActualReceiptsPayments(latest.diffAmt.subtract(latest.serviceAmt));
summary.setUpdatedAt(LocalDateTime.now());
updateById(summary);
return true;
}
private TradeSummaryAmount aggregateDetailAmounts(String tenantId, LocalDateTime start, LocalDateTime end) {
LambdaQueryWrapper<LbDailyUserTradeReport> detailQuery = new LambdaQueryWrapper<>();
detailQuery.eq(LbDailyUserTradeReport::getTenantId, tenantId)
.ge(LbDailyUserTradeReport::getReportDate, start)
.lt(LbDailyUserTradeReport::getReportDate, end)
.eq(LbDailyUserTradeReport::getDataType, DATA_TYPE_REPORT_DETAIL);
TradeSummaryAmount amount = new TradeSummaryAmount();
for (LbDailyUserTradeReport row : list(detailQuery)) {
amount.yestodayBuyAmt = amount.yestodayBuyAmt.add(defaultZero(row.getYestodayBuyAmt()));
amount.dailySellAmt = amount.dailySellAmt.add(defaultZero(row.getDailySellAmt()));
amount.dailyBuyAmt = amount.dailyBuyAmt.add(defaultZero(row.getDailyBuyAmt()));
amount.serviceAmt = amount.serviceAmt.add(defaultZero(row.getServiceAmt()));
amount.diffAmt = amount.diffAmt.add(defaultZero(row.getDiffAmt()));
amount.dikouAmt = amount.dikouAmt.add(defaultZero(row.getDikouAmt()));
}
return amount;
}
private boolean isSummaryChanged(LbDailyUserTradeReport summary, TradeSummaryAmount latest) {
return defaultZero(summary.getYestodayBuyAmt()).compareTo(latest.yestodayBuyAmt) != 0
|| defaultZero(summary.getDailySellAmt()).compareTo(latest.dailySellAmt) != 0
|| defaultZero(summary.getDailyBuyAmt()).compareTo(latest.dailyBuyAmt) != 0
|| defaultZero(summary.getServiceAmt()).compareTo(latest.serviceAmt) != 0
|| defaultZero(summary.getDiffAmt()).compareTo(latest.diffAmt) != 0
|| defaultZero(summary.getDikouAmt()).compareTo(latest.dikouAmt) != 0;
}
private List<LbDailyUserTradeReport> queryDetailRows(String tenantId, LocalDateTime start, LocalDateTime end) { private List<LbDailyUserTradeReport> queryDetailRows(String tenantId, LocalDateTime start, LocalDateTime end) {
LambdaQueryWrapper<LbDailyUserTradeReport> query = new LambdaQueryWrapper<>(); LambdaQueryWrapper<LbDailyUserTradeReport> query = new LambdaQueryWrapper<>();
query.eq(LbDailyUserTradeReport::getTenantId, tenantId) query.eq(LbDailyUserTradeReport::getTenantId, tenantId)
@@ -401,6 +465,15 @@ public class LbDailyUserTradeReportServiceImpl extends ServiceImpl<LbDailyUserTr
} }
} }
private static final class TradeSummaryAmount {
BigDecimal yestodayBuyAmt = BigDecimal.ZERO;
BigDecimal dailySellAmt = BigDecimal.ZERO;
BigDecimal dailyBuyAmt = BigDecimal.ZERO;
BigDecimal serviceAmt = BigDecimal.ZERO;
BigDecimal diffAmt = BigDecimal.ZERO;
BigDecimal dikouAmt = BigDecimal.ZERO;
}
private static BigDecimal defaultZero(BigDecimal value) { private static BigDecimal defaultZero(BigDecimal value) {
return value == null ? BigDecimal.ZERO : value; return value == null ? BigDecimal.ZERO : value;
} }

View File

@@ -100,14 +100,20 @@ public class LbDailyUserTradeServiceImpl extends ServiceImpl<LbDailyUserTradeMap
LambdaQueryWrapper<LbDailyUserTrade> yesterdayWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<LbDailyUserTrade> yesterdayWrapper = new LambdaQueryWrapper<>();
yesterdayWrapper.eq(LbDailyUserTrade::getTenantId, normalizedTenantId) yesterdayWrapper.eq(LbDailyUserTrade::getTenantId, normalizedTenantId)
.eq(LbDailyUserTrade::getReportDate, yesterday); .eq(LbDailyUserTrade::getReportDate, yesterday);
// .eq(LbDailyUserTrade::getUserId, trade.getUserId()); if (StringUtils.isNotBlank(trade.getUserId())) {
if (StringUtils.isNotBlank(trade.getNickname())) { // 以 userId 作为昨日数据关联主键,避免昵称重复/变更导致错配。
yesterdayWrapper.eq(LbDailyUserTrade::getUserId, trade.getUserId().trim());
} else if (StringUtils.isNotBlank(trade.getNickname())) {
// 历史脏数据兜底:仅当 userId 缺失时才按昵称匹配。
yesterdayWrapper.eq(LbDailyUserTrade::getNickname, trade.getNickname().trim()); yesterdayWrapper.eq(LbDailyUserTrade::getNickname, trade.getNickname().trim());
} }
LbDailyUserTrade lastDateRecord = null;
if (StringUtils.isNotBlank(trade.getUserId()) || StringUtils.isNotBlank(trade.getNickname())) {
yesterdayWrapper yesterdayWrapper
.orderByDesc(LbDailyUserTrade::getUpdatedAt) .orderByDesc(LbDailyUserTrade::getUpdatedAt)
.last("limit 1"); .last("limit 1");
LbDailyUserTrade lastDateRecord = this.getOne(yesterdayWrapper, false); lastDateRecord = this.getOne(yesterdayWrapper, false);
}
BigDecimal yestodayBuyAmt = lastDateRecord == null || lastDateRecord.getDailyBuyAmt() == null BigDecimal yestodayBuyAmt = lastDateRecord == null || lastDateRecord.getDailyBuyAmt() == null
? BigDecimal.ZERO ? BigDecimal.ZERO
: lastDateRecord.getDailyBuyAmt(); : lastDateRecord.getDailyBuyAmt();

View File

@@ -6,6 +6,8 @@
<resultMap id="BaseResultMap" type="com.rj.entity.CustomerManagement"> <resultMap id="BaseResultMap" type="com.rj.entity.CustomerManagement">
<id column="id" property="id" /> <id column="id" property="id" />
<result column="customer_name" property="customerName" /> <result column="customer_name" property="customerName" />
<result column="gender" property="gender" />
<result column="age" property="age" />
<result column="contact" property="contact" /> <result column="contact" property="contact" />
<result column="dealership_id" property="dealershipId" /> <result column="dealership_id" property="dealershipId" />
<result column="dealership_name" property="dealershipName" /> <result column="dealership_name" property="dealershipName" />
@@ -18,13 +20,16 @@
<result column="detailed_address" property="detailedAddress" /> <result column="detailed_address" property="detailedAddress" />
<result column="sales_phone" property="salesPhone" /> <result column="sales_phone" property="salesPhone" />
<result column="contact_count" property="contactCount" /> <result column="contact_count" property="contactCount" />
<result column="front_photo_url" property="frontPhotoUrl" />
<result column="side_photo_url" property="sidePhotoUrl" />
<result column="life_photo_url" property="lifePhotoUrl" />
<result column="create_time" property="createTime" /> <result column="create_time" property="createTime" />
<result column="update_time" property="updateTime" /> <result column="update_time" property="updateTime" />
</resultMap> </resultMap>
<!-- 通用查询结果列 --> <!-- 通用查询结果列 -->
<sql id="Base_Column_List"> <sql id="Base_Column_List">
id, customer_name, contact, dealership_id, dealership_name, sales_id, sales_name, recording_count, intended_model, info_card, remark, detailed_address, sales_phone, contact_count, create_time, update_time id, customer_name, gender, age, contact, dealership_id, dealership_name, sales_id, sales_name, recording_count, intended_model, info_card, remark, detailed_address, sales_phone, contact_count, front_photo_url, side_photo_url, life_photo_url, create_time, update_time
</sql> </sql>
</mapper> </mapper>