Merge branch 'test' of http://git.lionquexpress.com/wuweihua/BMS into test
This commit is contained in:
+10
-6
@@ -7,9 +7,9 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import lombok.ToString;
|
||||
import com.bms.common.annotation.Excel;
|
||||
import com.bms.common.core.domain.BaseEntity;
|
||||
|
||||
@@ -52,16 +52,20 @@ public class BmsCustomer extends BaseEntity
|
||||
private String isEnable;
|
||||
|
||||
/** 业务员用户ID */
|
||||
@Excel(name = "业务员用户ID")
|
||||
private String salesUserId;
|
||||
|
||||
/** 业务员姓名 */
|
||||
@Excel(name = "业务员姓名")
|
||||
/** 业务员姓名(查询结果只回填已关联系统用户的姓名) */
|
||||
private String salesUser;
|
||||
|
||||
/** 业务员昵称(join sys_user.nick_name,sales_user_id 存工号=sys_user.user_name) */
|
||||
/** 业务员昵称(关联 sys_user.nick_name) */
|
||||
@Excel(name = "业务员")
|
||||
private String salesUserNickName;
|
||||
|
||||
/** 客户同步源中的原始业务员工号,仅供内部同步和迁移使用。 */
|
||||
@JsonIgnore
|
||||
@ToString.Exclude
|
||||
private String sourceSalesCode;
|
||||
|
||||
/** 资金额度(元) */
|
||||
@Excel(name = "资金额度", readConverterExp = "元=")
|
||||
private BigDecimal ed;
|
||||
|
||||
+3
@@ -34,6 +34,9 @@ public interface BmsCustomerMapper
|
||||
*/
|
||||
public List<BmsCustomer> selectBmsCustomerList(BmsCustomer bmsCustomer);
|
||||
|
||||
/** 校验业务员用户ID仍对应未删除的系统用户。 */
|
||||
public int countValidSalesUserId(@org.apache.ibatis.annotations.Param("salesUserId") String salesUserId);
|
||||
|
||||
/**
|
||||
* 新增客户主
|
||||
*
|
||||
|
||||
+5
-6
@@ -11,16 +11,15 @@ import com.bms.customer.customerinfo.domain.BmsCustomer;
|
||||
*/
|
||||
public interface CustomerSyncMapper
|
||||
{
|
||||
/**
|
||||
* 库中未删除的全部客户编码,用于判定新增/更新
|
||||
*/
|
||||
/** 库中未删除的全部客户编码,用于判定新增/更新。 */
|
||||
List<String> selectExistingCodes();
|
||||
|
||||
/**
|
||||
* 未删除用户的 工号(user_name)->用户ID(user_id) 映射,用于 TMS BELONG_SALER 工号转换
|
||||
*/
|
||||
/** 未删除用户映射,用于唯一工号匹配。 */
|
||||
List<SysUser> selectUserLoginMap();
|
||||
|
||||
/** 读取存量客户的人工业务员选择和上次同步的源工号。 */
|
||||
List<BmsCustomer> selectExistingSalesAssignments();
|
||||
|
||||
/**
|
||||
* 新增客户(同步专用,字段集与老系统导入脚本一致)
|
||||
*/
|
||||
|
||||
+1
-1
@@ -587,7 +587,7 @@ public class BmsCustomerLogServiceImpl implements IBmsCustomerLogService
|
||||
return s == null ? "" : s;
|
||||
}
|
||||
|
||||
/** 人员字段展示:姓名(工号),缺姓名时只显示工号 */
|
||||
/** 人员字段展示:姓名(系统用户ID),缺姓名时只显示系统用户ID。 */
|
||||
private static String userDisplay(String code, String name)
|
||||
{
|
||||
String c = trimToNull(code);
|
||||
|
||||
+20
-1
@@ -82,7 +82,7 @@ public class BmsCustomerServiceImpl implements IBmsCustomerService
|
||||
* @return 客户主
|
||||
*/
|
||||
@Override
|
||||
// sales_user_id 存的是员工工号(=sys_user.user_name),仅本人/本部门均通过 sys_user 别名 su 关联匹配
|
||||
// sales_user_id 只存系统 user_id;数据权限通过该用户的部门和用户范围判断。
|
||||
@DataScope(deptAlias = "su", deptField = "dept_id", userAlias = "su", userField = "user_id")
|
||||
public List<BmsCustomer> selectBmsCustomerList(BmsCustomer bmsCustomer)
|
||||
{
|
||||
@@ -275,6 +275,7 @@ public class BmsCustomerServiceImpl implements IBmsCustomerService
|
||||
public int insertBmsCustomer(BmsCustomer bmsCustomer)
|
||||
{
|
||||
checkContractDate(bmsCustomer.getContractStartDate(), bmsCustomer.getContractEndDate());
|
||||
normalizeAndValidateSalesUserId(bmsCustomer);
|
||||
SysUser user = SecurityUtils.getLoginUser().getUser();
|
||||
bmsCustomer.setCreateTime(DateUtils.getNowDate());
|
||||
bmsCustomer.setCreateBy(user.getUserName());
|
||||
@@ -303,6 +304,7 @@ public class BmsCustomerServiceImpl implements IBmsCustomerService
|
||||
public int updateBmsCustomer(BmsCustomer bmsCustomer)
|
||||
{
|
||||
checkContractDate(bmsCustomer.getContractStartDate(), bmsCustomer.getContractEndDate());
|
||||
normalizeAndValidateSalesUserId(bmsCustomer);
|
||||
SysUser user = SecurityUtils.getLoginUser().getUser();
|
||||
bmsCustomer.setUpdateTime(DateUtils.getNowDate());
|
||||
bmsCustomer.setUpdateBy(user.getUserName());
|
||||
@@ -518,4 +520,21 @@ public class BmsCustomerServiceImpl implements IBmsCustomerService
|
||||
throw new ServiceException("合同结束时间不能早于开始时间");
|
||||
}
|
||||
}
|
||||
|
||||
/** 客户编辑仅允许写入真实存在的系统用户ID,不接受工号作为兼容值。 */
|
||||
private void normalizeAndValidateSalesUserId(BmsCustomer customer)
|
||||
{
|
||||
String salesUserId = customer.getSalesUserId();
|
||||
if (salesUserId == null || salesUserId.trim().isEmpty())
|
||||
{
|
||||
customer.setSalesUserId(null);
|
||||
return;
|
||||
}
|
||||
salesUserId = salesUserId.trim();
|
||||
if (bmsCustomerMapper.countValidSalesUserId(salesUserId) == 0)
|
||||
{
|
||||
throw new ServiceException("业务员不存在或已删除,请从业务员选择器中重新选择");
|
||||
}
|
||||
customer.setSalesUserId(salesUserId);
|
||||
}
|
||||
}
|
||||
|
||||
+52
-24
@@ -9,6 +9,7 @@ import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -23,7 +24,7 @@ import com.bms.customer.customerinfo.mapper.CustomerSyncMapper;
|
||||
* 老系统 Oracle TAB_CUSTOMER -> ctr_customer 每日同步。
|
||||
*
|
||||
* 字段映射、字典转换与 D:\\生产客户数据\\scripts\\import_customers.py 完全一致:
|
||||
* 按 customer_code 判定新增/更新;源为空的字段不写(走默认值/保留原值)。
|
||||
* 按 customer_code 判定新增/更新;普通资料的源空字段不写,业务员归属则按匹配结果明确写入ID或NULL。
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@@ -59,7 +60,6 @@ public class CustomerSyncService
|
||||
private static final int LEN_CODE = 50;
|
||||
private static final int LEN_NAME = 100;
|
||||
private static final int LEN_CODE_DW = 50;
|
||||
private static final int LEN_USER_ID = 64;
|
||||
private static final int LEN_USER = 50;
|
||||
private static final int LEN_REMARK = 500;
|
||||
/** 告警明细最多打印条数 */
|
||||
@@ -86,8 +86,15 @@ public class CustomerSyncService
|
||||
|
||||
Set<String> existingCodes = new HashSet<>(customerSyncMapper.selectExistingCodes());
|
||||
|
||||
// 业务员归属转本系统用户ID:数据权限按 user_id 控制,工号后续修改不影响归属
|
||||
Map<String, String> userIdByLogin = loadUserIdByLogin();
|
||||
// 源工号只用于匹配;归属字段始终保存系统 user_id。
|
||||
Map<String, List<String>> userIdsByLogin = loadUserIdsByLogin();
|
||||
Set<String> validUserIds = new HashSet<>();
|
||||
userIdsByLogin.values().forEach(validUserIds::addAll);
|
||||
Map<String, BmsCustomer> existingSalesAssignments = new HashMap<>();
|
||||
for (BmsCustomer existing : customerSyncMapper.selectExistingSalesAssignments())
|
||||
{
|
||||
existingSalesAssignments.put(existing.getCustomerCode(), existing);
|
||||
}
|
||||
|
||||
List<BmsCustomer> inserts = new ArrayList<>();
|
||||
List<BmsCustomer> updates = new ArrayList<>();
|
||||
@@ -123,7 +130,8 @@ public class CustomerSyncService
|
||||
continue;
|
||||
}
|
||||
|
||||
BmsCustomer c = mapRow(row, code, name, userIdByLogin, warnings);
|
||||
BmsCustomer c = mapRow(row, code, name, userIdsByLogin,
|
||||
validUserIds, existingSalesAssignments.get(code), warnings);
|
||||
if (existingCodes.contains(code))
|
||||
{
|
||||
c.setUpdateBy(SYNC_MARKER);
|
||||
@@ -161,7 +169,8 @@ public class CustomerSyncService
|
||||
* 单行映射(逻辑对齐 import_customers.py 的 build_row)
|
||||
*/
|
||||
private BmsCustomer mapRow(Map<String, Object> row, String code, String name,
|
||||
Map<String, String> userIdByLogin, List<String> warnings)
|
||||
Map<String, List<String>> userIdsByLogin, Set<String> validUserIds,
|
||||
BmsCustomer existingAssignment, List<String> warnings)
|
||||
{
|
||||
BmsCustomer c = new BmsCustomer();
|
||||
c.setCustomerCode(truncate(code, LEN_CODE, code, "customer_code", warnings));
|
||||
@@ -169,7 +178,10 @@ public class CustomerSyncService
|
||||
c.setDelFlag("0");
|
||||
|
||||
c.setCustomerCodeDw(truncate(getStr(row, "CUSTOMER_OUTER_CODE"), LEN_CODE_DW, code, "customer_code_dw", warnings));
|
||||
c.setSalesUserId(resolveSalesUserId(clean(getStr(row, "BELONG_SALER")), userIdByLogin, code, warnings));
|
||||
String sourceSalesCode = clean(getStr(row, "BELONG_SALER"));
|
||||
c.setSourceSalesCode(sourceSalesCode);
|
||||
c.setSalesUserId(resolveSalesUserId(sourceSalesCode, userIdsByLogin,
|
||||
validUserIds, existingAssignment, code, warnings));
|
||||
c.setSalesUser(truncate(getStr(row, "BELONG_SALER_NAME"), LEN_USER, code, "sales_user", warnings));
|
||||
c.setSettlementUser(truncate(getStr(row, "SETTLEMENT_MAN"), LEN_USER, code, "settlement_user", warnings));
|
||||
c.setServiceUser(truncate(getStr(row, "SERVICE_MAN"), LEN_USER, code, "service_user", warnings));
|
||||
@@ -231,40 +243,56 @@ public class CustomerSyncService
|
||||
return ("1".equals(s) || "1.0".equals(s)) ? "0" : "1";
|
||||
}
|
||||
|
||||
/** 加载未删除用户的 工号(user_name)->用户ID(user_id) 映射 */
|
||||
private Map<String, String> loadUserIdByLogin()
|
||||
/** 加载未删除用户的工号映射;保留重复项以便将歧义匹配按未关联处理。 */
|
||||
private Map<String, List<String>> loadUserIdsByLogin()
|
||||
{
|
||||
Map<String, String> map = new HashMap<>();
|
||||
Map<String, List<String>> map = new HashMap<>();
|
||||
for (SysUser u : customerSyncMapper.selectUserLoginMap())
|
||||
{
|
||||
if (u != null && u.getUserName() != null && u.getUserId() != null
|
||||
&& !map.containsKey(u.getUserName()))
|
||||
if (u != null && clean(u.getUserName()) != null && u.getUserId() != null)
|
||||
{
|
||||
map.put(u.getUserName(), String.valueOf(u.getUserId()));
|
||||
map.computeIfAbsent(u.getUserName().trim(), key -> new ArrayList<>())
|
||||
.add(String.valueOf(u.getUserId()));
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 业务员工号 -> 本系统 sys_user.user_id 转换(数据权限按 user_id 控制,工号修改不影响归属)。
|
||||
* 工号在系统用户中不存在时保留原工号并告警(常见于该用户尚未同步),避免归属信息丢失。
|
||||
* 只在唯一匹配时关联系统用户。
|
||||
* 源工号不变时保留客户页面人工选择的有效业务员;工号为空时也保留有效业务员。
|
||||
*/
|
||||
private String resolveSalesUserId(String salerCode, Map<String, String> userIdByLogin,
|
||||
private String resolveSalesUserId(String salerCode, Map<String, List<String>> userIdsByLogin,
|
||||
Set<String> validUserIds, BmsCustomer existingAssignment,
|
||||
String code, List<String> warnings)
|
||||
{
|
||||
String s = truncate(salerCode, LEN_USER_ID, code, "sales_user_id", warnings);
|
||||
if (s == null)
|
||||
String existingUserId = existingAssignment == null ? null : clean(existingAssignment.getSalesUserId());
|
||||
boolean existingUserValid = existingUserId != null && validUserIds.contains(existingUserId);
|
||||
if (salerCode == null)
|
||||
{
|
||||
return null;
|
||||
return existingUserValid ? existingUserId : null;
|
||||
}
|
||||
String userId = userIdByLogin.get(s);
|
||||
if (userId != null)
|
||||
|
||||
boolean sourceCodeUnchanged = existingAssignment != null
|
||||
&& Objects.equals(salerCode, clean(existingAssignment.getSourceSalesCode()));
|
||||
boolean sourceCodeUnknown = existingAssignment != null
|
||||
&& clean(existingAssignment.getSourceSalesCode()) == null;
|
||||
if (existingUserValid && (sourceCodeUnchanged || sourceCodeUnknown))
|
||||
{
|
||||
return userId;
|
||||
// 历史有效用户ID可能尚无可恢复的源工号;首次同步建立源工号基线时不覆盖已有人工归属。
|
||||
return existingUserId;
|
||||
}
|
||||
warnings.add(code + ": 业务员工号 " + s + " 在系统用户中不存在,sales_user_id 保留原工号");
|
||||
return s;
|
||||
|
||||
List<String> matchedUserIds = userIdsByLogin.get(salerCode);
|
||||
if (matchedUserIds != null && matchedUserIds.size() == 1)
|
||||
{
|
||||
return matchedUserIds.get(0);
|
||||
}
|
||||
|
||||
warnings.add(code + (matchedUserIds == null || matchedUserIds.isEmpty()
|
||||
? ": 业务员工号未匹配到系统用户,客户保持未关联"
|
||||
: ": 业务员工号匹配到多个系统用户,客户保持未关联"));
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String clean(String v)
|
||||
|
||||
Reference in New Issue
Block a user