✨ 新增客商档案同步金蝶功能(A902-1查询回填+A902-2审批推送)

This commit is contained in:
刘泉佳
2026-09-18 20:01:29 +08:00
parent 8ea0c70761
commit be44ed7a8c
10 changed files with 494 additions and 3 deletions
@@ -158,4 +158,13 @@ public class CustomerArchive extends TenantEntity {
@Schema(description = "审核通过时间")
private LocalDateTime approvedTime;
@Schema(description = "金蝶协同状态:none未推送/exist金蝶已有/synced已推送/failed推送失败")
private String kingdeeStatus;
@Schema(description = "金蝶推送失败原因")
private String kingdeeFailReason;
@Schema(description = "金蝶推送时间")
private LocalDateTime kingdeeSyncTime;
}
@@ -0,0 +1,69 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.transport.constant;
import java.util.Map;
/**
* 客商档案金蝶(星瀚)协同常量
*
* @author Chill
*/
public class CustomerBfiConstants {
/**
* 推送金蝶固定值:业务职能全选(1销售,2结算,3付款,4收货)
*/
public static final String BIZ_FUNCTION_ALL = "1,2,3,4";
/**
* 推送金蝶固定值:伙伴类型兜底编码(民营企业),客商性质未命中映射时使用
*/
public static final String DEFAULT_PARTNER_TYPE = "6";
/**
* 营业期限类型:长期(TMS 表单文本)
*/
public static final String BUSINESS_TERM_LONG = "长期";
/**
* 客商性质(nature_of_client 字典 dictKey)→ 金蝶伙伴类型编码
* 键名以数据库字典 nature_of_client 实际 dictKey 为准核对;未命中走 DEFAULT_PARTNER_TYPE
*/
public static final Map<String, String> NATURE_TYPE_MAPPING = Map.of(
"企业法人", "1",
"个人", "4",
"个体工商户", "5",
"民营企业", "6",
"国有企业", "8",
"政府事业单位", "9",
"其他", "12"
);
private CustomerBfiConstants() {
}
}
@@ -0,0 +1,75 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.transport.controller;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.thirdparty.bfi.pojo.dto.BfiCustomerQueryDTO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiCustomerVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiPageVO;
import org.springblade.thirdparty.bfi.service.IBfiService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 业财融合(BFI)客商查询控制器
*
* @author Chill
*/
@RestController
@AllArgsConstructor
@RequestMapping("/bfi")
@Tag(name = "BFI客商", description = "业财融合客商查询接口")
public class BfiCustomerController extends BladeController {
private final IBfiService bfiService;
@GetMapping("/customer/query-by-credit-code")
@Operation(summary = "按统一社会信用代码查询金蝶客商", description = "新增客商时查询金蝶是否已有该客商,已审核则回填工商信息")
public R<BfiCustomerVO> queryByCreditCode(
@Parameter(description = "统一社会信用代码", required = true) @RequestParam String creditCode) {
if (StringUtil.isBlank(creditCode)) {
return R.fail("统一社会信用代码不能为空");
}
BfiCustomerQueryDTO param = new BfiCustomerQueryDTO();
param.setPageNo(1);
param.setPageSize(1);
param.setSocietycreditcode(List.of(creditCode.trim().toUpperCase()));
BfiPageVO<BfiCustomerVO> page = bfiService.queryCustomer(param);
List<BfiCustomerVO> rows = page == null ? null : page.getRows();
return R.data(rows == null || rows.isEmpty() ? null : rows.get(0));
}
}
@@ -31,6 +31,7 @@ import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.excel.util.ExcelUtil;
import org.springblade.core.mp.support.Condition;
@@ -60,6 +61,7 @@ import java.util.List;
*
* @author Chill
*/
@Slf4j
@RestController
@AllArgsConstructor
@PreAuth(menu = "customer_archive")
@@ -133,13 +135,21 @@ public class CustomerArchiveController extends BladeController {
}
/**
* 审核通过
* 审核通过(通过后自动推送金蝶,推送失败不影响审批结果)
*/
@PostMapping("/approve")
@ApiOperationSupport(order = 6)
@Operation(summary = "审核通过", description = "传入id")
public R approve(@Parameter(description = "主键", required = true) @RequestParam Long id) {
return R.status(customerArchiveService.approve(id));
boolean result = customerArchiveService.approve(id);
if (result) {
try {
customerArchiveService.syncKingdee(id);
} catch (Exception exception) {
log.error("客商审批通过后推送金蝶异常,id={}", id, exception);
}
}
return R.status(result);
}
/**
@@ -173,6 +183,16 @@ public class CustomerArchiveController extends BladeController {
return R.status(customerArchiveService.removeDraft(ids));
}
/**
* 推送金蝶(审批通过后失败重推入口)
*/
@PostMapping("/sync-kingdee")
@ApiOperationSupport(order = 12)
@Operation(summary = "推送金蝶", description = "传入id,仅审批通过的客商可推送,已推送/金蝶已有自动幂等跳过")
public R<CustomerArchive> syncKingdee(@Parameter(description = "主键", required = true) @RequestParam Long id) {
return R.data(customerArchiveService.syncKingdee(id));
}
/**
* 评分明细模板
*/
@@ -105,4 +105,7 @@ public class CustomerArchiveExcel implements Serializable {
@ExcelProperty("审核通过时间")
private LocalDateTime approvedTime;
@ExcelProperty("金蝶同步状态")
private String kingdeeStatusName;
}
@@ -46,6 +46,9 @@
<result column="current_node" property="currentNode"/>
<result column="current_processor" property="currentProcessor"/>
<result column="approved_time" property="approvedTime"/>
<result column="kingdee_status" property="kingdeeStatus"/>
<result column="kingdee_fail_reason" property="kingdeeFailReason"/>
<result column="kingdee_sync_time" property="kingdeeSyncTime"/>
</resultMap>
<select id="selectCustomerArchivePage" resultMap="customerArchiveResultMap">
@@ -92,7 +95,10 @@
approval_status,
current_node,
current_processor,
approved_time
approved_time,
kingdee_status,
kingdee_fail_reason,
kingdee_sync_time
FROM blade_customer_archive
WHERE is_deleted = 0
<if test="userId != null">
@@ -124,6 +124,14 @@ public interface ICustomerArchiveService extends BaseService<CustomerArchive> {
*/
boolean removeDraft(String ids);
/**
* 推送金蝶(A902-1 复查 + A902-2 保存),幂等:已推送/金蝶已有直接返回
*
* @param id 主键
* @return 更新后的客商档案
*/
CustomerArchive syncKingdee(Long id);
/**
* 基于启用评分量化表生成评分记录
*
@@ -29,12 +29,22 @@ import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.jackson.JsonUtil;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.thirdparty.bfi.constant.BfiConstant;
import org.springblade.thirdparty.bfi.pojo.dto.BfiCustomerQueryDTO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiBillSaveResultErrorVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiBillSaveResultItemVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiBillSaveResultVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiCustomerVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiPageVO;
import org.springblade.thirdparty.bfi.service.IBfiService;
import org.springblade.transport.excel.CustomerArchiveExcel;
import org.springblade.transport.mapper.CreditRatingStandardMapper;
import org.springblade.transport.mapper.CreditScoreCategoryMapper;
@@ -101,6 +111,7 @@ import java.util.stream.Collectors;
* @author Chill
*/
@Service
@Slf4j
@RequiredArgsConstructor
public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveMapper, CustomerArchive> implements ICustomerArchiveService {
@@ -112,6 +123,10 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
private static final String APPROVAL_REVIEWING = "reviewing";
private static final String APPROVAL_APPROVED = "approved";
private static final String APPROVAL_REJECTED = "rejected";
private static final String KINGDEE_STATUS_NONE = "none";
private static final String KINGDEE_STATUS_EXIST = "exist";
private static final String KINGDEE_STATUS_SYNCED = "synced";
private static final String KINGDEE_STATUS_FAILED = "failed";
private static final String CUSTOMER_CODE_PREFIX = "KS";
/**
* 变更快照忽略字段:明细每次保存会重建主键/审计字段,不能作为“是否有修改”的依据
@@ -137,6 +152,8 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
private final CreditRatingStandardMapper standardMapper;
private final UserCustomerScopeMapper userCustomerScopeMapper;
private final PaymentApplicationMapper paymentApplicationMapper;
private final IBfiService bfiService;
private final CustomerBfiConverter customerBfiConverter;
@Override
public IPage<CustomerArchiveVO> selectCustomerArchivePage(IPage<CustomerArchiveVO> page, CustomerArchiveVO customer) {
@@ -268,6 +285,112 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
return updateById(after);
}
@Override
@Transactional(rollbackFor = Exception.class)
public CustomerArchive syncKingdee(Long id) {
CustomerArchive customer = ensureCustomerAccessible(id);
if (!Objects.equals(customer.getApprovalStatus(), APPROVAL_APPROVED)) {
throw new ServiceException("仅审批通过的客商允许推送金蝶");
}
if (List.of(KINGDEE_STATUS_SYNCED, KINGDEE_STATUS_EXIST).contains(customer.getKingdeeStatus())) {
// 幂等:已推送或金蝶已有档案,直接返回
return customer;
}
CustomerArchive after = copyCustomer(customer);
after.setKingdeeSyncTime(LocalDateTime.now());
BfiCustomerVO kingdeeCustomer = queryKingdeeCustomer(customer.getUnifiedCreditCode());
if (kingdeeCustomer != null && BfiConstant.BILL_STATUS_AUDITED.equals(kingdeeCustomer.getStatus())) {
// 金蝶已有已审核档案:跳过推送
after.setKingdeeStatus(KINGDEE_STATUS_EXIST);
after.setKingdeeFailReason(null);
addChangeRecord(id, "金蝶已存在该客商档案,跳过推送", customer, after);
updateById(after);
return after;
}
if (kingdeeCustomer != null) {
// 金蝶侧暂存/已提交:审核中,置失败待重推
after.setKingdeeStatus(KINGDEE_STATUS_FAILED);
after.setKingdeeFailReason("金蝶侧该客商审核中,请稍后重推");
addChangeRecord(id, "推送金蝶失败:金蝶侧客商审核中", customer, after);
updateById(after);
return after;
}
pushCustomerToKingdee(id, customer, after);
updateById(after);
return after;
}
/**
* 组装 A902-2 报文推送金蝶并回写协同状态
*/
private void pushCustomerToKingdee(Long id, CustomerArchive customer, CustomerArchive after) {
try {
BfiBillSaveResultVO result = bfiService.saveCustomer(customerBfiConverter.buildSaveDTO(detail(id)));
BfiBillSaveResultItemVO item = firstSaveItem(result);
if (item != null && Boolean.TRUE.equals(item.getBillStatus())) {
after.setKingdeeStatus(KINGDEE_STATUS_SYNCED);
after.setKingdeeFailReason(null);
addChangeRecord(id, "推送金蝶成功,金蝶客户编码与客商编号一致:" + customer.getCustomerCode(), customer, after);
} else {
after.setKingdeeStatus(KINGDEE_STATUS_FAILED);
after.setKingdeeFailReason(buildSaveFailReason(result, item));
addChangeRecord(id, "推送金蝶失败:" + after.getKingdeeFailReason(), customer, after);
}
} catch (Exception exception) {
log.error("客商推送金蝶失败,id={},unifiedCreditCode={}", id, customer.getUnifiedCreditCode(), exception);
after.setKingdeeStatus(KINGDEE_STATUS_FAILED);
after.setKingdeeFailReason(truncateText(exception.getMessage() == null ? "金蝶接口调用异常" : exception.getMessage()));
addChangeRecord(id, "推送金蝶失败:" + after.getKingdeeFailReason(), customer, after);
}
}
/**
* A902-1 按统一社会信用代码查询金蝶客商,无数据返回 null
*/
private BfiCustomerVO queryKingdeeCustomer(String unifiedCreditCode) {
BfiCustomerQueryDTO param = new BfiCustomerQueryDTO();
param.setPageNo(1);
param.setPageSize(1);
param.setSocietycreditcode(List.of(unifiedCreditCode));
BfiPageVO<BfiCustomerVO> page = bfiService.queryCustomer(param);
List<BfiCustomerVO> rows = page == null ? null : page.getRows();
return rows == null || rows.isEmpty() ? null : rows.get(0);
}
private BfiBillSaveResultItemVO firstSaveItem(BfiBillSaveResultVO result) {
if (result == null || result.getResult() == null || result.getResult().isEmpty()) {
return null;
}
return result.getResult().get(0);
}
private String buildSaveFailReason(BfiBillSaveResultVO result, BfiBillSaveResultItemVO item) {
if (item != null && Func.isNotEmpty(item.getErrors())) {
String messages = item.getErrors().stream()
.map(BfiBillSaveResultErrorVO::getRowMsg)
.filter(Func::isNotEmpty)
.flatMap(List::stream)
.collect(Collectors.joining(";"));
if (Func.isEmpty(messages)) {
messages = item.getErrors().stream()
.map(error -> String.valueOf(error.getEntityKey()))
.collect(Collectors.joining(";"));
}
return truncateText(messages);
}
if (result != null && Func.isNotEmpty(result.getFailCount())) {
return truncateText("金蝶返回失败数量:" + result.getFailCount());
}
return "金蝶返回结果为空";
}
private String truncateText(String text) {
if (text == null) {
return null;
}
return text.length() > 500 ? text.substring(0, 500) : text;
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean changeStatus(Long id, Integer status) {
@@ -343,6 +466,7 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
customer.setDeptName(trimToEmpty(customer.getDeptName()));
customer.setAccessType(Func.isEmpty(customer.getAccessType()) ? ACCESS_TEMPORARY : customer.getAccessType());
customer.setApprovalStatus(Func.isEmpty(customer.getApprovalStatus()) ? APPROVAL_DRAFT : customer.getApprovalStatus());
customer.setKingdeeStatus(Func.isEmpty(customer.getKingdeeStatus()) ? KINGDEE_STATUS_NONE : customer.getKingdeeStatus());
if (Func.isEmpty(customer.getStatus())) {
customer.setStatus(STATUS_ENABLED);
}
@@ -1266,6 +1390,7 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
excel.setContactPhone(customer.getContactPhone());
excel.setLegalPerson(customer.getLegalPerson());
excel.setCreateTime(customer.getCreateTime());
excel.setKingdeeStatusName(kingdeeStatusName(customer.getKingdeeStatus()));
return excel;
}
@@ -1286,6 +1411,19 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
return "草稿";
}
private String kingdeeStatusName(String kingdeeStatus) {
if (Objects.equals(kingdeeStatus, KINGDEE_STATUS_SYNCED)) {
return "已推送";
}
if (Objects.equals(kingdeeStatus, KINGDEE_STATUS_EXIST)) {
return "金蝶已有";
}
if (Objects.equals(kingdeeStatus, KINGDEE_STATUS_FAILED)) {
return "推送失败";
}
return "未推送";
}
private void validateLength(String value, int maxLength, String message) {
if (Func.isNotEmpty(value) && value.length() > maxLength) {
throw new ServiceException(message);
@@ -0,0 +1,147 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.transport.service.impl;
import lombok.RequiredArgsConstructor;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.system.cache.DictBizCache;
import org.springblade.system.pojo.entity.DictBiz;
import org.springblade.thirdparty.bfi.constant.BfiConstant;
import org.springblade.thirdparty.bfi.pojo.dto.BfiCustomerGroupEntryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiCustomerSaveDTO;
import org.springblade.transport.constant.CustomerBfiConstants;
import org.springblade.transport.pojo.vo.CustomerArchiveVO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 客商档案金蝶(星瀚)报文转换器
*
* @author Chill
*/
@Component
@RequiredArgsConstructor
public class CustomerBfiConverter {
/**
* 数据来源系统编码,默认 WLTMS(运输TMS)
*/
@Value("${thirdParty.bfi.customer.srcSys:WLTMS}")
private String srcSys;
/**
* 创建组织.编码,默认 WLTMS,需与财务确认
*/
@Value("${thirdParty.bfi.customer.createOrg:WLTMS}")
private String createOrg;
/**
* 组装 A902-2 客户保存参数
*
* @param customer 客商档案
* @return 客户保存参数
*/
public BfiCustomerSaveDTO buildSaveDTO(CustomerArchiveVO customer) {
BfiCustomerSaveDTO param = new BfiCustomerSaveDTO();
// 金蝶客户编码与 TMS 客商编号保持一致
param.setNumber(customer.getCustomerCode());
param.setStatus(BfiConstant.BILL_STATUS_SUBMITTED);
param.setName(customer.getFullName());
param.setSocietycreditcode(customer.getUnifiedCreditCode());
param.setTxRegisterNo(customer.getUnifiedCreditCode());
param.setArtificialperson(customer.getLegalPerson());
param.setType(resolvePartnerType(customer.getCustomerNature()));
param.setBizpartnerAddress(customer.getRegisteredAddress());
param.setBusinessscope(buildBusinessScopeText(customer.getBusinessScope()));
param.setBusinessterm(buildBusinessTerm(customer.getBusinessTermType(), customer.getBusinessEndDate()));
param.setBizpartnerPhone(customer.getContactPhone());
param.setFcusbeizhu(customer.getRemark());
param.setBizfunction(CustomerBfiConstants.BIZ_FUNCTION_ALL);
param.setAwrpDatasourcesys(srcSys);
param.setAwrpCusfortrade(BfiConstant.CUS_FOR_TRADE_YES);
param.setCreateorgNumber(createOrg);
BfiCustomerGroupEntryDTO groupEntry = new BfiCustomerGroupEntryDTO();
groupEntry.setStandardidNumber(BfiConstant.GROUP_STANDARD_BASIC);
groupEntry.setGroupidNumber(BfiConstant.CUSTOMER_GROUP_EXTERNAL);
param.setEntryGroupstandard(List.of(groupEntry));
return param;
}
/**
* 客商性质(字典 dictKey)→ 金蝶伙伴类型编码,未命中走兜底值
*
* @param customerNature 客商性质字典值
* @return 金蝶伙伴类型编码
*/
public String resolvePartnerType(String customerNature) {
if (Func.isNotEmpty(customerNature)) {
String partnerType = CustomerBfiConstants.NATURE_TYPE_MAPPING.get(customerNature.trim());
if (StringUtil.isNotBlank(partnerType)) {
return partnerType;
}
}
return CustomerBfiConstants.DEFAULT_PARTNER_TYPE;
}
/**
* 经营范围多选编码 → 字典文本「、」拼接,字典缺失时回退原编码
*
* @param businessScope 逗号拼接的经营范围编码
* @return 金蝶经营范围文本
*/
public String buildBusinessScopeText(String businessScope) {
if (Func.isEmpty(businessScope)) {
return "";
}
List<DictBiz> dictList = DictBizCache.getList("scope_of_business");
Map<String, String> scopeNames = dictList == null ? Map.of() : dictList.stream()
.collect(Collectors.toMap(DictBiz::getDictKey, DictBiz::getDictValue, (first, second) -> first));
return Func.toStrList(businessScope.replace(",", ",")).stream()
.map(code -> scopeNames.getOrDefault(code, code))
.collect(Collectors.joining("、"));
}
/**
* 营业期限:长期传「长期」;固定期限传「至 yyyy-MM-dd」(TMS 未采集起始日)
*
* @param businessTermType 营业期限类型
* @param businessEndDate 营业期限截止日
* @return 金蝶营业期限文本
*/
public String buildBusinessTerm(String businessTermType, LocalDate businessEndDate) {
if (CustomerBfiConstants.BUSINESS_TERM_LONG.equals(businessTermType)) {
return CustomerBfiConstants.BUSINESS_TERM_LONG;
}
return businessEndDate == null ? "" : "至 " + businessEndDate;
}
}
@@ -0,0 +1,16 @@
-- 客商档案:金蝶(星瀚)协同字段
-- kingdee_status:none未推送 / exist金蝶已有档案(A902-1查到已审核,跳过推送) / synced已推送成功 / failed推送失败或金蝶审核中
-- 金蝶客户编码与 TMS 客商编号(customer_code)一致(A902-2 number 传入客商编号),无需单独存储
ALTER TABLE `blade_customer_archive`
ADD COLUMN `kingdee_status` varchar(20) NOT NULL DEFAULT 'none' COMMENT '金蝶协同状态:none未推送/exist金蝶已有/synced已推送/failed推送失败' AFTER `approved_time`,
ADD COLUMN `kingdee_fail_reason` varchar(500) NULL DEFAULT NULL COMMENT '金蝶推送失败原因' AFTER `kingdee_status`,
ADD COLUMN `kingdee_sync_time` datetime NULL DEFAULT NULL COMMENT '金蝶推送时间' AFTER `kingdee_fail_reason`;
CREATE INDEX idx_kingdee_status ON blade_customer_archive (kingdee_status);
-- 列表「同步金蝶」按钮权限(审批通过后推送失败的重推入口;parent_id 通过菜单 code 关联,避免写死 id)
INSERT INTO blade_menu (id, parent_id, code, name, alias, path, source, sort, category, action, is_open, component, remark, is_deleted)
SELECT 2075431800000000001, m.id, 'customer_archive_sync', '同步金蝶', 'customer_archive_sync', '', '', 1, 2, 0, 1, '', '', 0
FROM blade_menu m
WHERE m.code = 'customer_archive' AND m.is_deleted = 0;