数据底座

This commit is contained in:
efren
2025-06-19 15:49:04 +08:00
parent e14e22bc14
commit 5bb8b18d83
15 changed files with 853 additions and 0 deletions

View File

@ -0,0 +1,106 @@
package com.chinaunicom.mall.ebtp.extend.dt.client;
import com.chinaunicom.mall.ebtp.extend.dt.entity.*;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import java.text.SimpleDateFormat;
@FeignClient(name = "dt-service", url = "${spring.dt.url}")
@RequestMapping("/DtStudio/datamasterservice")
public interface DtClient {
/**
* 获取Token接口
* POST /mdm/oauth/token
* @param appId 客户端Key
* @param appSecret 客户端Secret
* @return token信息
*/
@PostMapping("/mdm/oauth/token")
DtBaseResponseDTO<DtTokenResponseDTO> getToken(
@RequestHeader("app_id") String appId,
@RequestHeader("app_secret") String appSecret
);
/**
* 客户数据单条维护接口
* POST /mdm/maintain
参数:
{
"masterDataCode": "ods_custsup_customer_vendor_info",
"opType": "C",
"updateColumns": {
"sourceId": "20001DERJ291",
"sourceStatus": "1",
"sourceCompany": "9999100300",
"sourceSystem": "XT20210873086",
"code": "30911103027886014929",
"name": "联通数字科技有限公司",
"nameLanguage": "ZH",
"localName": "联通数字科技有限公司",
"nature": "20",
"country": "CN",
"certificateType": "10",
"certificateId": "911103027886014929",
"organizationType": "30",
"createdDate": "2025-06-18 16:47:21",
"lastModifiedUser": "IRIS4",
"lastModifiedDate": "2025-06-18 16:47:21"
}
}
返回:
{
"resultCode":"0",
"resultMsg":"操作成功",
"resultObject":{
"sourceID":"20001DERJ291",
"sapCode":"1000284811"
}
}
* @param token 认证token
* @param request 维护请求体
* @return 维护结果
*/
@PostMapping("/mdm/maintain")
DtMaintainResponeDTO maintain(
@RequestHeader("Authorization") String token,
@RequestBody DtMaintainRequestDTO request
);
/**
* 客商主数据批量新增接口
* POST /mdm/sync
* 适用于上游权威系统批量向主数据平台提交客商数据
* @param token 认证token
* @param syncRequestDTO 批量同步请求体
* @return 同步结果
*/
@PostMapping("/mdm/sync")
DtBaseResponseDTO sync(
@RequestHeader("Authorization") String token,
@RequestBody DtSyncRequestDTO syncRequestDTO
);
/**
* 客商主数据查询匹配接口
* POST /mdm/queryMdmAll
* @param token 认证token
* @param request 查询请求体
* @return 查询结果
*/
@PostMapping("/mdm/queryMdmAll")
DtBaseResponseDTO<DtQueryMdmAllResponseDTO> queryMdmAll(
@RequestHeader("Authorization") String token,
@RequestBody DtQueryMdmAllRequestDTO request
);
// public static void main(String[] args) {
// long millis = System.currentTimeMillis();
// System.out.println(millis);
// }
}

View File

@ -0,0 +1,51 @@
package com.chinaunicom.mall.ebtp.extend.dt.controller;
import com.chinaunicom.mall.ebtp.extend.dt.entity.DtBaseResponseDTO;
import com.chinaunicom.mall.ebtp.extend.dt.entity.DtSyncRequestDTO;
import com.chinaunicom.mall.ebtp.extend.dt.entity.DtTokenResponseDTO;
import com.chinaunicom.mall.ebtp.extend.dt.entity.DtMaintainRequestDTO;
import com.chinaunicom.mall.ebtp.extend.dt.entity.DtQueryMdmAllRequestDTO;
import com.chinaunicom.mall.ebtp.extend.dt.entity.DtQueryMdmAllResponseDTO;
import com.chinaunicom.mall.ebtp.extend.dt.service.DtService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@RestController
@Api(tags = "数据底座接口")
@RequestMapping("/dt/api")
@Slf4j
public class DtController {
@Resource
private DtService dtService;
@ApiOperation("获取token")
@PostMapping("/token")
public DtBaseResponseDTO<DtTokenResponseDTO> getToken() {
return dtService.getToken();
}
@ApiOperation("客商主数据单条维护")
@PostMapping("/maintain")
public Object maintain(@RequestBody DtMaintainRequestDTO request) {
return dtService.maintain(request);
}
@ApiOperation("客商主数据查询匹配")
@PostMapping("/queryMdmAll")
public DtBaseResponseDTO<DtQueryMdmAllResponseDTO> queryMdmAll(@RequestBody DtQueryMdmAllRequestDTO request) {
return dtService.queryMdmAll(request);
}
@ApiOperation("客商主数据批量同步")
@PostMapping("/sync")
public DtBaseResponseDTO sync(@RequestBody DtSyncRequestDTO syncRequestDTO) {
// token参数已在service内部自动获取
return dtService.sync(syncRequestDTO);
}
}

View File

@ -0,0 +1,20 @@
package com.chinaunicom.mall.ebtp.extend.dt.entity;
import lombok.Data;
/**
* {
* "resultCode":"0",
* "resultMsg":"",
* "resultObject":{
* "token": "a554cc92-6291-4d32-b7aa-08c97b4e3f09",
* "effectiveTime": 30
* }
* }
*/
@Data
public class DtBaseResponseDTO<T> {
private String resultCode;
private String resultMsg;
private T resultObject;
}

View File

@ -0,0 +1,24 @@
package com.chinaunicom.mall.ebtp.extend.dt.entity;
import lombok.Data;
@Data
public class DtMaintailResponseDTO {
/**
* 返回编码0成功-1失败
*/
private int resultCode;
/**
* 返回结果说明,成功返回"SUCCESS",失败返回失败或出错原因
*/
private String resultMsg;
/**
* 返回SAP编码
*/
private String sapCode;
/**
* 返回sourceID
*/
private String sourceID;
}

View File

@ -0,0 +1,49 @@
package com.chinaunicom.mall.ebtp.extend.dt.entity;
import com.chinaunicom.mall.ebtp.extend.dt.entity.maintain.PrimaryColumn;
import com.chinaunicom.mall.ebtp.extend.dt.entity.maintain.UpdateColumn;
import lombok.Data;
/**
* 若opType为C 或 S不传primaryColumns
* 参数说明:
* masterDataCode 主数据模型编码(ods_custsup_customer_vendor_info) 必填
* opType 操作类型C新增、U更新、D停用冻结、E启用解除冻结、S保存、K校验 必填
* updateColumns 该项为必须项请按主数据标准要求填写校验通过后返回集团SAPcode 必填
* 示例:
* {
* "masterDataCode": "ods_custsup_customer_vendor_info",
* "opType": "S",
* "updateColumns": {
* "name": "大连中远海运油品运输公司",
* "country": "CN"
* }
* }
*/
@Data
public class DtMaintainRequestDTO {
/**
* 主数据模型编码(ods_custsup_customer_vendor_info)
* 必填
*/
private String masterDataCode;
/**
* 操作类型
* 必填
* C 新增
* U 更新
* D 停用(冻结)
* E 启用(解除冻结)
* S 保存(用于不便区分操作类型的业务场景)
* K 校验(进行合规校验和标准校验,不正式写入)
*/
private String opType;
/**
* 更新字段
* 必填
* 该项为必须项请按主数据标准要求填写。校验通过后返回集团SAPcode。
*/
private UpdateColumn updateColumns;
private PrimaryColumn primaryColumns;
}

View File

@ -0,0 +1,29 @@
package com.chinaunicom.mall.ebtp.extend.dt.entity;
import lombok.Data;
/**
* resultCode
* int
* 返回编码
* 0成功
* -1 失败
* resultMsg
* String
* 返回结果说明
* 成功返回:"SUCCESS"
* 失败返回:失败或出错原因。
* sapCode
* String
* 返回编码
* sourceID
* String
* 返回编码
*/
@Data
public class DtMaintainResponeDTO {
private String resultCode;
private String resultMsg;
private String sapCode;
private String sourceID;
}

View File

@ -0,0 +1,90 @@
package com.chinaunicom.mall.ebtp.extend.dt.entity;
import java.util.List;
/**
* 客商主数据查询匹配接口请求体
*/
public class DtQueryMdmAllRequestDTO {
/**
* 主数据模型编码(customer_vendor_info)
*/
private String masterDataCode;
/**
* 查询条件(支持多条件组合)
*/
private List<QueryColumn> queryColumns;
/**
* 页码默认从1开始
*/
private Integer pageIndex;
/**
* 每页大小默认10条不得超过25条
*/
private Integer pageSize;
// ...getter/setter...
public static class QueryColumn {
/**
* 字段编码如name、localName、certificateType、certificateId、sapCode
*/
private String columnCode;
/**
* 字段值
*/
private String columnValue;
/**
* 匹配类型1:精确匹配 2模糊匹配
*/
private Integer matchingType;
// ...getter/setter...
public String getColumnCode() {
return columnCode;
}
public void setColumnCode(String columnCode) {
this.columnCode = columnCode;
}
public String getColumnValue() {
return columnValue;
}
public void setColumnValue(String columnValue) {
this.columnValue = columnValue;
}
public Integer getMatchingType() {
return matchingType;
}
public void setMatchingType(Integer matchingType) {
this.matchingType = matchingType;
}
}
public String getMasterDataCode() {
return masterDataCode;
}
public void setMasterDataCode(String masterDataCode) {
this.masterDataCode = masterDataCode;
}
public List<QueryColumn> getQueryColumns() {
return queryColumns;
}
public void setQueryColumns(List<QueryColumn> queryColumns) {
this.queryColumns = queryColumns;
}
public Integer getPageIndex() {
return pageIndex;
}
public void setPageIndex(Integer pageIndex) {
this.pageIndex = pageIndex;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
}

View File

@ -0,0 +1,101 @@
package com.chinaunicom.mall.ebtp.extend.dt.entity;
import java.util.List;
/**
* 客商主数据查询匹配接口响应体
*/
public class DtQueryMdmAllResponseDTO {
/**
* 总条数
*/
private Integer total;
/**
* 当前页码
*/
private Integer pageIndex;
/**
* 每页大小
*/
private Integer pageSize;
/**
* 数据列表
*/
private List<CustomerVendorInfo> data;
// ...getter/setter...
public static class CustomerVendorInfo {
// 只列举常用字段,实际可根据接口返回补充
private String code;
private String name;
private String localName;
private String certificateType;
private String certificateId;
private String sapCode;
// ...其他字段...
// ...getter/setter...
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLocalName() {
return localName;
}
public void setLocalName(String localName) {
this.localName = localName;
}
public String getCertificateType() {
return certificateType;
}
public void setCertificateType(String certificateType) {
this.certificateType = certificateType;
}
public String getCertificateId() {
return certificateId;
}
public void setCertificateId(String certificateId) {
this.certificateId = certificateId;
}
public String getSapCode() {
return sapCode;
}
public void setSapCode(String sapCode) {
this.sapCode = sapCode;
}
}
public Integer getTotal() {
return total;
}
public void setTotal(Integer total) {
this.total = total;
}
public Integer getPageIndex() {
return pageIndex;
}
public void setPageIndex(Integer pageIndex) {
this.pageIndex = pageIndex;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public List<CustomerVendorInfo> getData() {
return data;
}
public void setData(List<CustomerVendorInfo> data) {
this.data = data;
}
}

View File

@ -0,0 +1,21 @@
package com.chinaunicom.mall.ebtp.extend.dt.entity;
import com.chinaunicom.mall.ebtp.extend.dt.entity.sync.UpdateData;
import lombok.Data;
import java.util.List;
@Data
public class DtSyncRequestDTO {
/**
* 主数据模型编码(默认ods_custsup_customer_vendor_info)
*/
private String masterDataCode = "ods_custsup_customer_vendor_info";
/**
* updateDate 是 Array 必填项 数组记录数最大不得超过10000
*/
private List<UpdateData> updateData;
}

View File

@ -0,0 +1,13 @@
package com.chinaunicom.mall.ebtp.extend.dt.entity;
import lombok.Data;
/**
* "token": "a554cc92-6291-4d32-b7aa-08c97b4e3f09",
* "effectiveTime": 30
*/
@Data
public class DtTokenResponseDTO {
private String token;
private Integer effectiveTime;// token有效时常单位分钟
}

View File

@ -0,0 +1,8 @@
package com.chinaunicom.mall.ebtp.extend.dt.entity.maintain;
import lombok.Data;
@Data
public class PrimaryColumn {
private String sourceId;
private String sourceCompany;
}

View File

@ -0,0 +1,164 @@
package com.chinaunicom.mall.ebtp.extend.dt.entity.maintain;
import lombok.Data;
@Data
public class UpdateColumn {
/**
* 客商业务编码,客户唯一识别码
* 1. 境内:客商组织类型+统一社会信用编码
* 2. 境外:客商组织类型+国家编码+增值税号VAT/TIN
* 3. 境内个人:客商组织类型+身份证号码
* 4. 境外个人:客商组织类型+姓名+护照号码
* 5. 集团内部门客商:客商组织类型+组织编码
* 6. 集团个人供应商:客商组织类型+身份证号码
* 7. 其他客户:客商组织类型+二级单位编码+6位流水码
* 8. 临时/专用/功能性客商:客商组织类型+名称
* 该字段可等同为客商主数据主键真正主键为该值MD5加密形成
* 建议二级公司按该字段建立与客商主数据的映射关系。
* varchar(100) 必填
*/
private String code;
/**
* 来源系统客户标识id来源系统客商标识二级公司该数据的唯一标识可为客户/供应商编码或主键)
* 该字段可等同为租户客商管理系统的主键。
* 租户数据的更新、停用、启用根据该字段操作。
* varchar(50) 必填
*/
private String sourceId;
/**
* 客商名称
* 1. 境内企业:维护中文,全称须与工商注册或企业发文上的名称保持一致
* 2. 境外企业:需填英文名称,遵守首字母大写、单词间一个空格、无缩写、无特殊字符
* 3. 英文名称需在本地语言名称中维护中文信息
* varchar(255) 必填
*/
private String name;
/**
* 客商本国语言代码(多语言),境内企业为中文,境外企业默认为英文,非英文需按标准填写
* 参照维表字典值CUST001代码填写
* varchar(2) 能填尽填
*/
private String nameLanguage;
/**
* 客商本国语言名称,根据当地证件上的标准名称填写,官方注册名称
* 对于境内的客商,维护中文简体,全称须与工商注册或企业发文上的名称保持一致
* varchar(255) 能填尽填
*/
private String localName;
/**
* 客商属性,客户、供应商、客户+供应商、贷款人等
* 参照维表字典值CUST002代码填写
* varchar(2) 必填
*/
private String nature;
/**
* 客商归属国家或地区
* 参照维表字典值CUST003代码填写
* varchar(3) 必填
*/
private String country;
/**
* 证件类型营业执照、身份证、增值税号VAT、纳税人识别号、护照等
* 参照维表字典值CUST004代码填写
* varchar(2) 必填
*/
private String certificateType;
/**
* 证件号码
* 1. 境内企业:统一社会信用代码
* 2. 境内自然人:身份证号
* 3. 境外企业VAT/TIN号/UEN/商业登记证/企业注册码
* 4. 境外自然人:护照号码
* 5. 集团内部门客商:组织编码
* 6. 集团内个人客商:身份证号
* 7. 其他:按实际填写
* varchar(20) 境内必填
*/
private String certificateId;
/**
* 客商组织类型,集团内客商、集团联营客商、第三方客商等
* 参照维表字典值CUST005代码填写
* varchar(2) 必填
*/
private String organizationType;
/**
* 集团北京SAP系统编码SAP 客户编码,用于内部财务处理
* varchar(50) 能填尽填
*/
private String sapCode;
/**
* 数据来源二级公司填写数据来源二级公司编码9999200000
* 参照维表字典值CUST007代码填写
* varchar(255) 必填
*/
private String sourceCompany;
/**
* 数据来源系统填写来源系统的系统编码XT20210864425
* 参照维表字典值CUST008代码填写
* varchar(13) 必填
*/
private String sourceSystem;
/**
* 二级公司状态,正常、冻结、风险
* 参照维表字典值CUST006代码填写
* varchar(2) 必填
*/
private String sourceStatus;
/**
* 创建时间传输来源系统记录的数据创建时间格式为YYYY-MM-DD HH:MI:SS
* 必填
*/
private String createdDate;
/**
* 最后的更新人员,传输来源系统记录的最后的更新人员,若无,可传输主数据对接人
* varchar(30) 必填
*/
private String lastModifiedUser;
/**
* 最后的更新时间传输来源系统记录的最后的更新时间格式为YYYY-MM-DD HH:MI:SS
* 必填
*/
private String lastModifiedDate;
/**
* 数据来源二级公司SAP系统客商编码
* varchar(30) 能填尽填
*/
private String sourceCompanySapCode;
/**
* 客商生效时间主要用于客商组织类型发生变更时新客商的业务生效时间格式为YYYY-MM-DD
* 非必填
*/
private String effectiveDate;
/**
* 客商失效时间主要用于客商组织类型发生变更时旧客商的业务失效时间默认为30001231格式为YYYY-MM-DD
* 非必填
*/
private String endDate;
/**
* 操作符C 新增、U 更新、D 停用冻结、E 启用解除冻结、S 保存、K(校验)
* 参照维表字典值CUST009代码填写
* varchar(1) 必填
*/
private String opTypeMdm;
}

View File

@ -0,0 +1,82 @@
package com.chinaunicom.mall.ebtp.extend.dt.entity.sync;
import lombok.Data;
/**
* 客户主数据同步-单条数据结构
*/
@Data
public class UpdateData {
/**
* 客商业务编码,客户唯一识别码
*/
private String code;
/**
* 来源系统客户标识id
*/
private String sourceId;
/**
* 客商名称
*/
private String name;
/**
* 客商本国语言代码(多语言)
*/
private String nameLanguage;
/**
* 客商本国语言名称
*/
private String localName;
/**
* 客商属性
*/
private String nature;
/**
* 客商归属国家或地区
*/
private String country;
/**
* 证件类型
*/
private String certificateType;
/**
* 证件号码
*/
private String certificateId;
/**
* 客商组织类型
*/
private String organizationType;
/**
* 集团北京SAP系统编码
*/
private String sapCode;
/**
* 二级公司状态
*/
private String sourceStatus;
/**
* 数据来源二级公司
*/
private String sourceCompany;
/**
* 数据来源系统
*/
private String sourceSystem;
/**
* 创建时间
*/
private String createdDate;
/**
* 最后的更新人员
*/
private String lastModifiedUser;
/**
* 最后的更新时间
*/
private String lastModifiedDate;
/**
* 操作符
*/
private String opTypeMdm;
}

View File

@ -0,0 +1,32 @@
package com.chinaunicom.mall.ebtp.extend.dt.service;
import com.chinaunicom.mall.ebtp.extend.dt.entity.*;
public interface DtService {
/**
* 批量同步客商主数据
* @param syncRequestDTO 批量同步请求体
* @return 同步结果
*/
DtBaseResponseDTO sync(DtSyncRequestDTO syncRequestDTO);
/**
* 获取token
* @return token
*/
DtBaseResponseDTO<DtTokenResponseDTO> getToken();
/**
* 维护数据
* @param request 维护请求体
* @return 维护结果
*/
DtMaintainResponeDTO maintain(DtMaintainRequestDTO request);
/**
* 查询所有Mdm数据
* @param request 查询请求体
* @return Mdm数据
*/
DtBaseResponseDTO<DtQueryMdmAllResponseDTO> queryMdmAll(DtQueryMdmAllRequestDTO request);
}

View File

@ -0,0 +1,63 @@
package com.chinaunicom.mall.ebtp.extend.dt.service.impl;
import com.chinaunicom.mall.ebtp.extend.dt.client.DtClient;
import com.chinaunicom.mall.ebtp.extend.dt.entity.*;
import com.chinaunicom.mall.ebtp.extend.dt.service.DtService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service
public class DtServiceImpl implements DtService {
@Autowired
private DtClient dtClient;
@Value("${spring.dt.app_id}")
private String appId;
@Value("${spring.dt.app_secret}")
private String appSecret;
@Override
public DtBaseResponseDTO sync(DtSyncRequestDTO syncRequestDTO) {
// 忽略传入的token先获取token再调用sync
DtBaseResponseDTO<DtTokenResponseDTO> tokenResp = dtClient.getToken(appId, appSecret);
if (tokenResp == null || tokenResp.getResultObject() == null || tokenResp.getResultObject().getToken() == null) {
return tokenResp;
}
String realToken = tokenResp.getResultObject().getToken();
return dtClient.sync(realToken, syncRequestDTO);
}
@Override
public DtBaseResponseDTO<DtTokenResponseDTO> getToken() {
return dtClient.getToken(appId, appSecret);
}
@Override
public DtMaintainResponeDTO maintain(DtMaintainRequestDTO request) {
DtBaseResponseDTO<DtTokenResponseDTO> tokenResp = dtClient.getToken(appId, appSecret);
if (tokenResp == null || tokenResp.getResultObject() == null || tokenResp.getResultObject().getToken() == null) {
DtMaintainResponeDTO resp = new DtMaintainResponeDTO();
resp.setResultCode(tokenResp.getResultCode());
resp.setResultMsg(tokenResp.getResultMsg());
return resp;
}
String realToken = tokenResp.getResultObject().getToken();
return dtClient.maintain(realToken, request);
}
@Override
public DtBaseResponseDTO<DtQueryMdmAllResponseDTO> queryMdmAll(DtQueryMdmAllRequestDTO request) {
DtBaseResponseDTO<DtTokenResponseDTO> tokenResp = dtClient.getToken(appId, appSecret);
if (tokenResp == null || tokenResp.getResultObject() == null || tokenResp.getResultObject().getToken() == null) {
DtBaseResponseDTO<DtQueryMdmAllResponseDTO> resp = new DtBaseResponseDTO<>();
resp.setResultCode(tokenResp.getResultCode());
resp.setResultMsg(tokenResp.getResultMsg());
return resp;
}
String realToken = tokenResp.getResultObject().getToken();
return dtClient.queryMdmAll(realToken, request);
}
}