fix(mcp): 修正物业所属销售富化永远为空(Map key 被驼峰化)

根因:SQL 别名用 property_id/user_id/user_name,而 MyBatis 的
mapUnderscoreToCamelCase=true 会把结果 Map 的 key 转成 propertyId/userId/userName,
代码按 "property_id" 取值永远 null → 富化静默跳过,sale_user_id 恒为空。

修复:
- 别名改为无下划线的 pid/uid/uname,绕开驼峰转换
- 单测补两条并锁住:取到 userId → sale_user_id;缺失时回落 create_id
  (此前构造器新增 AgentMapper 参数,测试未同步,已一并修正)

验证:SyncEntitiesTest 26 例全过。
This commit is contained in:
xiaoqu-ai
2026-10-20 18:40:44 +08:00
parent 99adb3dfc1
commit 10982f24a3
3 changed files with 49 additions and 6 deletions
@@ -24,7 +24,9 @@ public interface ProperytMapper extends BaseMapper<Properyt> {
* <p>来源是物业表的 userId / userName 两列(实体未映射,故用显式 SQL)。
* 独立查询 + 调用方容错:列名或数据异常只丢归属,不影响 properties 变更流。</p>
*/
@Select("<script>SELECT id AS property_id, userId AS user_id, userName AS user_name"
// 别名刻意用无下划线的名字:MyBatis 的 mapUnderscoreToCamelCase 会把
// property_id → propertyId,导致按 "property_id" 取值永远为 null。
@Select("<script>SELECT id AS pid, userId AS uid, userName AS uname"
+ " FROM properyt WHERE id IN"
+ " <foreach collection='ids' item='id' open='(' separator=',' close=')'>#{id}</foreach>"
+ "</script>")
@@ -76,13 +76,13 @@ public class PropertiesSyncEntity extends AbstractSyncEntity implements SyncEnti
}
if (!ids.isEmpty()) {
for (Map<String, Object> owner : properytMapper.selectPropertyOwners(ids)) {
Object pid = owner.get("property_id");
Object pid = owner.get("pid");
if (pid == null) {
continue;
}
Long propertyId = Long.valueOf(String.valueOf(pid));
Object uid = owner.get("user_id");
Object uname = owner.get("user_name");
Object uid = owner.get("uid");
Object uname = owner.get("uname");
if (uid != null) {
ownerIds.put(propertyId, String.valueOf(uid));
}
@@ -18,6 +18,7 @@ import me.iiv.agent.entity.m2.WithdrawOrder;
import me.iiv.agent.mapper.m0.BatteryFaultLogMapper;
import me.iiv.agent.mapper.m0.DeviceLifeCycleMapper;
import me.iiv.agent.mapper.m0.HardwareViewMapper;
import me.iiv.agent.mapper.m0.AgentMapper;
import me.iiv.agent.mapper.m0.ProperytMapper;
import me.iiv.agent.mapper.m0.UserMapper;
import me.iiv.agent.mapper.m1.MallGoodsOrderMapper;
@@ -67,6 +68,8 @@ class SyncEntitiesTest {
@Mock
ProperytMapper properytMapper;
@Mock
AgentMapper agentMapper;
@Mock
ContractNewMapper contractNewMapper;
@Mock
SalerRepaymentMapper salerRepaymentMapper;
@@ -166,7 +169,7 @@ class SyncEntitiesTest {
@Test
void propertiesAppliesRowFilterForUserAndMapsFields() {
PropertiesSyncEntity entity = new PropertiesSyncEntity(properytMapper, permissionService);
PropertiesSyncEntity entity = new PropertiesSyncEntity(properytMapper, permissionService, agentMapper);
Properyt property = new Properyt();
property.setId(9L);
property.setName("望京SOHO");
@@ -192,9 +195,47 @@ class SyncEntitiesTest {
assertEquals("ACTIVE", rows.get(0).item().get("status"));
}
@Test
void propertiesExportsSaleOwnerFromUserIdColumns() {
PropertiesSyncEntity entity = new PropertiesSyncEntity(properytMapper, permissionService, agentMapper);
Properyt property = new Properyt();
property.setId(9L);
property.setName("望京SOHO");
property.setAgentId(33L);
property.setCreateId(11L);
property.setSoftDelete(0);
property.setModifyTime(Timestamp.valueOf("2026-09-01 10:00:00"));
when(properytMapper.selectList(any())).thenReturn(List.of(property));
// 别名刻意无下划线:MyBatis 会把 property_id 转成 propertyId
when(properytMapper.selectPropertyOwners(any()))
.thenReturn(List.of(Map.of("pid", 9L, "uid", 77L, "uname", "张三")));
List<SyncRow> rows = entity.fetchPage(null, 2000L, null, null, 3, null);
assertEquals("77", rows.get(0).item().get("sale_user_id"), "物业所属销售取 userId 列");
assertEquals("张三", rows.get(0).item().get("sale_user_name"));
}
@Test
void propertiesFallsBackToCreateIdWhenOwnerMissing() {
PropertiesSyncEntity entity = new PropertiesSyncEntity(properytMapper, permissionService, agentMapper);
Properyt property = new Properyt();
property.setId(9L);
property.setName("望京SOHO");
property.setCreateId(11L);
property.setSoftDelete(0);
property.setModifyTime(Timestamp.valueOf("2026-09-01 10:00:00"));
when(properytMapper.selectList(any())).thenReturn(List.of(property));
when(properytMapper.selectPropertyOwners(any())).thenReturn(List.of());
List<SyncRow> rows = entity.fetchPage(null, 2000L, null, null, 3, null);
assertEquals("11", rows.get(0).item().get("sale_user_id"), "缺 userId 时回落到创建人");
}
@Test
void propertiesSkipsRowFilterForServiceToken() {
PropertiesSyncEntity entity = new PropertiesSyncEntity(properytMapper, permissionService);
PropertiesSyncEntity entity = new PropertiesSyncEntity(properytMapper, permissionService, agentMapper);
when(properytMapper.selectList(any())).thenReturn(List.of());
entity.fetchPage(null, 2000L, null, null, 3, null);