初始化艾志OA仓库

master
钱涛 3 weeks ago
commit dfcb8f95f7

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="GB2312"?>
<config name="CBS字段映射配置">
<table name="境内账户明细" key="uf_jnzhmx" modeId="10">
<field name="交易流水号" key="jylsh" ebsKey="transactionSerialNumber" unique="true"/>
<field name="收款日期" key="skrq" ebsKey="bankTransactionDate"/>
<field name="汇款人" key="hkr" ebsKey="unitName"/>
<field name="对应客户" key="dykh" ebsKey="unitName"/>
<field name="金额" key="je" ebsKey="incurredAmount"/>
</table>
<table name="票据收款明细" key="uf_pjskmx" modeId="11">
<field name="收款日期" key="skrq" ebsKey="acceptorDate"/>
<field name="汇款人" key="hkr" ebsKey="drawerName"/>
<field name="对应客户" key="dykh" ebsKey="drawerName"/>
<field name="金额" key="je" ebsKey="billAmount"/>
<field name="票据编号" key="pjbh" ebsKey="billNbr" unique="true"/>
<field name="出票日期" key="cprq" ebsKey="issueDate"/>
<field name="到期日期" key="dqrq" ebsKey="dueDate"/>
<field name="承兑银行" key="cdyx" ebsKey="acceptorName"/>
</table>
<table name="票据池" key="uf_pjc" modeId="13">
<field name="收到日期/开具日期" key="sdrqkjrq" ebsKey="acceptorDate"/>
<field name="回款人/收款人" key="hkrskr" ebsKey="drawerName"/>
<field name="票面金额" key="pmje" ebsKey="billAmount"/>
<field name="票据编号" key="pjbh" ebsKey="billNbr" unique="true"/>
<field name="出票日期" key="cprq" ebsKey="issueDate"/>
<field name="到期日期" key="dqrq" ebsKey="dueDate"/>
<field name="承兑银行/付款银行" key="cdyhfkyh" ebsKey="acceptorName/"/>
</table>
</config>

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"></setting>
<setting name="jdbcTypeForNull" value="NULL"/>
</settings>
<plugins>
<plugin interceptor="weaver.conn.mybatis.MyBatisCachePlugin"></plugin>
</plugins>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="weaver.conn.mybatis.MyBatisDataSourceFactory">
</dataSource>
</environment>
</environments>
<databaseIdProvider type="weaver.conn.mybatis.DatabaseIdProvider">
</databaseIdProvider>
<mappers>
<!--mapper resource="MyBatis/mapper/WorkflowBaseMapper.xml"/-->
<!--package name="*.mapper"></package 不可行Mybatis不支持通配符这是spring的ant匹配模式提供的-->
<package name="weaver.conn.mybatis.mapper"></package><!-- 示例Mapper -->
<!-- 项目Mapper -->
<package name="com.weaver.mapper"></package>
<package name="weaver.general.mapper"></package>
<package name="weaver.hrm.mapper"></package>
<package name="weaver.workflow.mapper"></package>
<package name="weaver.interfaces.mapper"></package>
<package name="weaver.portal.mapper"></package>
<package name="com.api.formmode.mybatis.mapper"></package>
<package name="com.cloudstore.dev.api.mapper"></package>
<package name="com.engine.integration.mapper"></package>
<package name="com.engine.salary.mapper"></package>
<package name="com.engine.organization.mapper"></package>
<!-- 需要把现在的配置文件都调整到WEB-INF/config/mapper目录下 -->
<!-- 在WEB-INF/config/mapper目录下配置的xml文件也不必加入这里的package -->
</mappers>
</configuration>

@ -0,0 +1,12 @@
# ??ID
app_id=Yg8fWSvs
# ????
app_secret=1f23768c02219d7864b0009c30a1b6a59fe84606
# ????
bodyEncryptionKey=0467E11F7CA86D884C990D4F3F5C2A1EFEEBB02B9878F4FDDCB7899DFABADCC8F38FC23F007A8AF9B2EB8A1D313959647CD8A1542F0414116AE6CFCA792346A802
# ????????
signEncryptionPrivateKey=135d6d61d5e820a979e58f4939abbd528c82528c8c276852445854377e1df247
# ????????
bodyDecryptionKey=135d6d61d5e820a979e58f4939abbd528c82528c8c276852445854377e1df247
# ????
host=https://cbs8-openapi-reprd.csuat.cmburl.cn

@ -0,0 +1,15 @@
package com.engine.salary.exception;
public class CBS8RunTimeException extends RuntimeException {
public CBS8RunTimeException(String message) {
super(message);
}
public CBS8RunTimeException(Throwable cause) {
super(cause);
}
public CBS8RunTimeException(String message, Throwable cause) {
super(message, cause);
}
}

@ -0,0 +1,22 @@
package com.engine.salary.mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* SQLMapper
* <p>Copyright: Copyright (c) 2024</p>
* <p>Company: </p>
*
* @author qiantao
* @version 1.0
**/
public interface SQLMapper {
List<Map> runSQL(@Param("sql") String sql);
List<Long> listLong(@Param("sql") String sql);
List<String> listString(@Param("sql") String sql);
}

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.engine.salary.mapper.SQLMapper">
<select id="runSQL" resultType="java.util.Map">
${sql}
</select>
<select id="listLong" resultType="long">
${sql}
</select>
<select id="listString" resultType="string">
${sql}
</select>
</mapper>

@ -0,0 +1,57 @@
package com.engine.salary.mapper.cbs;
import com.engine.salary.remote.cbs8.po.UfHkrdzbPO;
import java.util.List;
public interface UfHkrdzbMapper {
/**
*
*
* @return List
*/
List<UfHkrdzbPO> listAll();
/**
*
*
* @return List
*/
List<UfHkrdzbPO> listSome(UfHkrdzbPO ufHkrdzb);
/**
*
*
* @param id
* @return null
*/
UfHkrdzbPO getById(Integer id);
/**
* null
*
* @param ufHkrdzb
* @return
*/
int insertIgnoreNull(UfHkrdzbPO ufHkrdzb);
/**
*
*
* @param ufHkrdzb
* @return
*/
int update(UfHkrdzbPO ufHkrdzb);
/**
* null
*
* @param ufHkrdzb
* @return
*/
int updateIgnoreNull(UfHkrdzbPO ufHkrdzb);
}

@ -0,0 +1,322 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.engine.salary.mapper.cbs.UfHkrdzbMapper">
<resultMap id="BaseResultMap" type="com.engine.salary.remote.cbs8.po.UfHkrdzbPO">
<result column="id" property="id"/>
<result column="requestId" property="requestId"/>
<result column="formmodeid" property="formmodeid"/>
<result column="modedatacreater" property="modedatacreater"/>
<result column="modedatacreatertype" property="modedatacreatertype"/>
<result column="modedatacreatedate" property="modedatacreatedate"/>
<result column="modedatacreatetime" property="modedatacreatetime"/>
<result column="MODEUUID" property="modeuuid"/>
<result column="form_biz_id" property="formBizId"/>
<result column="gsbm" property="gsbm"/>
<result column="khbm" property="khbm"/>
<result column="khmc" property="khmc"/>
<result column="bmbm" property="bmbm"/>
<result column="bmd" property="bmd"/>
<result column="bm" property="bm"/>
<result column="modedatamodifier" property="modedatamodifier"/>
<result column="modedatamodifydatetime" property="modedatamodifydatetime"/>
<result column="departmentId" property="departmentId"/>
</resultMap>
<!-- 表字段 -->
<sql id="baseColumns">
t
.
id
, t.requestId
, t.formmodeid
, t.modedatacreater
, t.modedatacreatertype
, t.modedatacreatedate
, t.modedatacreatetime
, t.MODEUUID
, t.form_biz_id
, t.gsbm
, t.khbm
, t.khmc
, t.bmbm
, t.bmd
, t.bm
, t.modedatamodifier
, t.modedatamodifydatetime
</sql>
<!-- 查询全部 -->
<select id="listAll" resultMap="BaseResultMap">
SELECT
<include refid="baseColumns"/>
,d.id as departmentId
FROM uf_hkrdzb t
left join hrmdepartment d on t.bmbm = d.departmentcode
</select>
<!-- 根据主键获取单条记录 -->
<select id="getById" resultMap="BaseResultMap" parameterType="Integer">
SELECT
<include refid="baseColumns"/>
FROM uf_hkrdzb t
WHERE id = #{id}
</select>
<!-- 条件查询 -->
<select id="listSome" resultMap="BaseResultMap" parameterType="com.engine.salary.remote.cbs8.po.UfHkrdzbPO">
SELECT
<include refid="baseColumns"/>
FROM uf_hkrdzb t
WHERE 1=1
<if test="requestId != null">
AND requestId = #{requestId}
</if>
<if test="formmodeid != null">
AND formmodeid = #{formmodeid}
</if>
<if test="modedatacreater != null">
AND modedatacreater = #{modedatacreater}
</if>
<if test="modedatacreatertype != null">
AND modedatacreatertype = #{modedatacreatertype}
</if>
<if test="modedatacreatedate != null">
AND modedatacreatedate = #{modedatacreatedate}
</if>
<if test="modedatacreatetime != null">
AND modedatacreatetime = #{modedatacreatetime}
</if>
<if test="modeuuid != null">
AND MODEUUID = #{modeuuid}
</if>
<if test="formBizId != null">
AND form_biz_id = #{formBizId}
</if>
<if test="gsbm != null">
AND gsbm = #{gsbm}
</if>
<if test="khbm != null">
AND khbm = #{khbm}
</if>
<if test="khmc != null">
AND khmc = #{khmc}
</if>
<if test="bmbm != null">
AND bmbm = #{bmbm}
</if>
<if test="bmd != null">
AND bmd = #{bmd}
</if>
<if test="bm != null">
AND bm = #{bm}
</if>
<if test="modedatamodifier != null">
AND modedatamodifier = #{modedatamodifier}
</if>
<if test="modedatamodifydatetime != null">
AND modedatamodifydatetime = #{modedatamodifydatetime}
</if>
<if test="ids != null and ids.size()>0">
AND id IN
<foreach collection="ids" open="(" item="id" separator="," close=")">
#{id}
</foreach>
</if>
ORDER BY id DESC
</select>
<!-- 插入不为NULL的字段 -->
<insert id="insertIgnoreNull" parameterType="com.engine.salary.remote.cbs8.po.UfHkrdzbPO">
INSERT INTO uf_hkrdzb
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="requestId != null">
requestId,
</if>
<if test="formmodeid != null">
formmodeid,
</if>
<if test="modedatacreater != null">
modedatacreater,
</if>
<if test="modedatacreatertype != null">
modedatacreatertype,
</if>
<if test="modedatacreatedate != null">
modedatacreatedate,
</if>
<if test="modedatacreatetime != null">
modedatacreatetime,
</if>
<if test="modeuuid != null">
MODEUUID,
</if>
<if test="formBizId != null">
form_biz_id,
</if>
<if test="gsbm != null">
gsbm,
</if>
<if test="khbm != null">
khbm,
</if>
<if test="khmc != null">
khmc,
</if>
<if test="bmbm != null">
bmbm,
</if>
<if test="bmd != null">
bmd,
</if>
<if test="bm != null">
bm,
</if>
<if test="modedatamodifier != null">
modedatamodifier,
</if>
<if test="modedatamodifydatetime != null">
modedatamodifydatetime,
</if>
</trim>
<trim prefix="VALUES (" suffix=")" suffixOverrides=",">
<if test="requestId != null">
#{requestId},
</if>
<if test="formmodeid != null">
#{formmodeid},
</if>
<if test="modedatacreater != null">
#{modedatacreater},
</if>
<if test="modedatacreatertype != null">
#{modedatacreatertype},
</if>
<if test="modedatacreatedate != null">
#{modedatacreatedate},
</if>
<if test="modedatacreatetime != null">
#{modedatacreatetime},
</if>
<if test="modeuuid != null">
#{modeuuid},
</if>
<if test="formBizId != null">
#{formBizId},
</if>
<if test="gsbm != null">
#{gsbm},
</if>
<if test="khbm != null">
#{khbm},
</if>
<if test="khmc != null">
#{khmc},
</if>
<if test="bmbm != null">
#{bmbm},
</if>
<if test="bmd != null">
#{bmd},
</if>
<if test="bm != null">
#{bm},
</if>
<if test="modedatamodifier != null">
#{modedatamodifier},
</if>
<if test="modedatamodifydatetime != null">
#{modedatamodifydatetime},
</if>
</trim>
</insert>
<!-- 更新,更新全部字段 -->
<update id="update" parameterType="com.engine.salary.remote.cbs8.po.UfHkrdzbPO">
UPDATE uf_hkrdzb
<set>
requestId=#{requestId},
formmodeid=#{formmodeid},
modedatacreater=#{modedatacreater},
modedatacreatertype=#{modedatacreatertype},
modedatacreatedate=#{modedatacreatedate},
modedatacreatetime=#{modedatacreatetime},
MODEUUID=#{modeuuid},
form_biz_id=#{formBizId},
gsbm=#{gsbm},
khbm=#{khbm},
khmc=#{khmc},
bmbm=#{bmbm},
bmd=#{bmd},
bm=#{bm},
modedatamodifier=#{modedatamodifier},
modedatamodifydatetime=#{modedatamodifydatetime},
</set>
WHERE id = #{id}
</update>
<!-- 更新不为NULL的字段 -->
<update id="updateIgnoreNull" parameterType="com.engine.salary.remote.cbs8.po.UfHkrdzbPO">
UPDATE uf_hkrdzb
<set>
<if test="requestId != null">
requestId=#{requestId},
</if>
<if test="formmodeid != null">
formmodeid=#{formmodeid},
</if>
<if test="modedatacreater != null">
modedatacreater=#{modedatacreater},
</if>
<if test="modedatacreatertype != null">
modedatacreatertype=#{modedatacreatertype},
</if>
<if test="modedatacreatedate != null">
modedatacreatedate=#{modedatacreatedate},
</if>
<if test="modedatacreatetime != null">
modedatacreatetime=#{modedatacreatetime},
</if>
<if test="modeuuid != null">
MODEUUID=#{modeuuid},
</if>
<if test="formBizId != null">
form_biz_id=#{formBizId},
</if>
<if test="gsbm != null">
gsbm=#{gsbm},
</if>
<if test="khbm != null">
khbm=#{khbm},
</if>
<if test="khmc != null">
khmc=#{khmc},
</if>
<if test="bmbm != null">
bmbm=#{bmbm},
</if>
<if test="bmd != null">
bmd=#{bmd},
</if>
<if test="bm != null">
bm=#{bm},
</if>
<if test="modedatamodifier != null">
modedatamodifier=#{modedatamodifier},
</if>
<if test="modedatamodifydatetime != null">
modedatamodifydatetime=#{modedatamodifydatetime},
</if>
</set>
WHERE id = #{id}
</update>
</mapper>

@ -0,0 +1,233 @@
package com.engine.salary.remote.cbs8;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
/**
* Http
*
* @author Terry
*/
@Slf4j
public class HttpUtil {
public static final String TEXT_TYPE = "text/plain";
public static final String JSON_TYPE = "application/json";
public static final String XML_TYPE = "text/xml";
public static final String HTML_TYPE = "text/html";
public static final String EXCEL_TYPE = "application/vnd.ms-excel";
public static final String STREAM_TYPE = "application/octet-stream";
public static final int SLEEP_TIME = 1000;
public static final int IAS_SUCCESS = 400;
public static HttpClient httpsTrustClient() {
try {
// 在调用SSL之前需要重写验证方法取消检测SSL
X509TrustManager trustManager = new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] xcs, String str) {
}
@Override
public void checkServerTrusted(X509Certificate[] xcs, String str) {
}
};
SSLContext ctx = SSLContext.getInstance(SSLConnectionSocketFactory.TLS);
ctx.init(null, new TrustManager[]{trustManager}, null);
SSLConnectionSocketFactory socketFactory =
new SSLConnectionSocketFactory(ctx, NoopHostnameVerifier.INSTANCE);
// 创建Registry
RequestConfig requestConfig =
RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD_STRICT).setExpectContinueEnabled(Boolean.TRUE)
.setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST))
.setProxyPreferredAuthSchemes(Collections.singletonList(AuthSchemes.BASIC)).build();
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE).register("https", socketFactory).build();
// 创建ConnectionManager添加Connection配置信息
PoolingHttpClientConnectionManager connectionManager =
new PoolingHttpClientConnectionManager(socketFactoryRegistry);
return HttpClients.custom().setConnectionManager(connectionManager)
.setDefaultRequestConfig(requestConfig).build();
} catch (KeyManagementException | NoSuchAlgorithmException ex) {
throw new RuntimeException(ex);
}
}
/**
* HttpClient
*
* @param path
* @return
*/
public static HttpClient wrapClient(String path) {
HttpClient httpClient = HttpClientBuilder.create().build();
if (path != null && path.startsWith("https://")) {
return httpsTrustClient();
}
return httpClient;
}
/**
* http
*
* @param requestConfig
* @return
*/
private static RequestConfig setTimeOutConfig(RequestConfig requestConfig) {
if (requestConfig == null) {
requestConfig = RequestConfig.DEFAULT;
}
return RequestConfig.copy(requestConfig).setConnectionRequestTimeout(900000).setConnectTimeout(900000)
.setSocketTimeout(900000).build();
}
/**
* get
*
* @param url
* @param header
* @param params
* @return
*/
public static String getRequest(String url, Map<String, String> header, Map<String, String> params) {
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
String result = "";
StringBuilder urlStr = new StringBuilder();
urlStr.append(url).append("?");
int i = params.size();
for (Map.Entry<String, String> map : params.entrySet()) {
urlStr.append(map.getKey()).append("=").append(map.getValue());
if ((--i) == 0) {
continue;
}
urlStr.append("&");
}
try {
httpClient = (CloseableHttpClient) wrapClient(url);
HttpGet httpGet = new HttpGet(urlStr.toString());
if (null != header && !header.isEmpty()) {
for (String key : header.keySet()) {
httpGet.setHeader(key, header.get(key));
}
}
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(20000)
.setConnectionRequestTimeout(20000).setSocketTimeout(40000).build();
httpGet.setConfig(requestConfig);
response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();
result = EntityUtils.toString(entity);
httpGet.abort();
EntityUtils.consume(entity);
} catch (IOException e) {
log.error("发起GET请求失败", e);
result = "发起GET请求失败";
} finally {
if (null != response) {
try {
httpClient.close();
response.close();
} catch (IOException e) {
log.error("发起GET请求失败", e);
}
}
if (null != httpClient) {
try {
httpClient.close();
} catch (IOException e) {
log.error("发起GET请求失败", e);
}
}
}
return result;
}
/**
* HTTP Post
*
* @param url url ?
* @param params
* @param header
* @return
*/
public static String doPost(String url, Map<String, String> header, String params, String contentType) {
String result = null;
try {
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("Connection", "close");
httpPost.setConfig(setTimeOutConfig(httpPost.getConfig()));
httpPost.setHeader("Content-Type", contentType);
if (null != header && !header.isEmpty()) {
for (String key : header.keySet()) {
httpPost.setHeader(key, header.get(key));
}
}
if (null != params) {
httpPost.setEntity(new StringEntity(params, Consts.UTF_8));
}
HttpClient httpClient = wrapClient(url);
HttpResponse response = httpClient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != 200) {
httpPost.abort();
throw new RuntimeException("HttpClient,error status code :" + statusCode);
}
HttpEntity entity = response.getEntity();
if (entity != null) {
result = EntityUtils.toString(entity, Consts.UTF_8);
}
EntityUtils.consume(entity);
httpPost.abort();
return result;
} catch (Exception e) {
log.error("发起POST请求失败", e);
result = "发起POST请求失败";
}
return result;
}
}

@ -0,0 +1,97 @@
package com.engine.salary.remote.cbs8;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.util.TypeUtils;
import java.lang.reflect.Type;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class JsonUtil {
private static final SerializerFeature[] DEFAULT_S_FEATURES;
private static final SerializerFeature[] PRETTY_S_FEATURES;
private static final Feature[] DEFAULT_P_FEATURES;
public JsonUtil() {
}
public static String toJsonString(Object obj) {
return JSON.toJSONString(obj, DEFAULT_S_FEATURES);
}
public static String toJsonString(Object obj, SerializerFeature... features) {
return JSON.toJSONString(obj, features);
}
public static String toPrettyJson(Object object) {
return JSON.toJSONString(object, PRETTY_S_FEATURES);
}
public static JSONObject parseJsonObject(String jsonStr) {
return JSON.parseObject(jsonStr, DEFAULT_P_FEATURES);
}
public static <T> T parseValue(JSONObject jsonObject, String key, Class<T> clazz) {
if (jsonObject != null) {
T value = jsonObject.getObject(key, (Type) clazz);
return value;
} else {
return null;
}
}
public static <T> T parseObject(String jsonStr, Class<T> clazz) {
return JSON.parseObject(jsonStr, (Type) clazz, DEFAULT_P_FEATURES);
}
public static <T> List<T> parseList(String jsonStr, Class<T> clazz) {
return JSON.parseArray(jsonStr, clazz);
}
public static <T> List<T> parseList(Object jsonObject, Class<T> clazz) {
String jsonStr = toJsonString(jsonObject);
return parseList(jsonStr, clazz);
}
public static <V> Map<String, V> parseMap(String jsonStr, Class<V> valueCls) {
Map<String, V> result = new LinkedHashMap();
Map<String, Object> map = JSON.parseObject(jsonStr, DEFAULT_P_FEATURES);
if (map != null && map.size() > 0) {
Iterator var4 = map.entrySet().iterator();
while (var4.hasNext()) {
Entry<String, Object> entry = (Entry) var4.next();
Object obj = entry.getValue();
V value = JSON.parseObject(JSON.toJSONString(obj), valueCls);
result.put(entry.getKey(), value);
}
}
return result;
}
public static <V> Map<String, V> parseMap(Object jsonObject, Class<V> valueCls) {
String jsonStr = toJsonString(jsonObject);
return parseMap(jsonStr, valueCls);
}
public static <T> T parseBean(String jsonString, Class<T> beanClazz) {
return parseBean(parseJsonObject(jsonString), beanClazz);
}
public static <T> T parseBean(JSONObject jsonObject, Class<T> beanClazz) {
return TypeUtils.castToJavaBean(jsonObject, beanClazz);
}
static {
DEFAULT_S_FEATURES = new SerializerFeature[]{SerializerFeature.WriteDateUseDateFormat, SerializerFeature.SortField};
PRETTY_S_FEATURES = new SerializerFeature[]{SerializerFeature.WriteDateUseDateFormat, SerializerFeature.SortField, SerializerFeature.PrettyFormat};
DEFAULT_P_FEATURES = new Feature[]{Feature.OrderedField};
}
}

@ -0,0 +1,417 @@
package com.engine.salary.remote.cbs8;
import com.alibaba.fastjson.JSON;
import com.engine.salary.exception.CBS8RunTimeException;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collector;
import java.util.stream.Collectors;
/**
*
* <p>Copyright: Copyright (c) 2022</p>
* <p>Company: </p>
*
* @author qiantao
* @version 1.0
**/
public class SalaryEntityUtil {
private static final DecimalFormat decimalFormat = new DecimalFormat("#,##0.00");
/**
*
* 00.00000
*/
public static final String NUMBER_REGEX = "(-?[1-9]\\d*\\.?\\d+)|(-?0\\.\\d*[0-9])|(\\d+)";
/**
*
*
* @param originMap map
* @param targetMap map
*/
public static void thousandthConvert(Map<String, Object> originMap, Map<String, Object> targetMap) {
if (MapUtils.isNotEmpty(originMap)) {
originMap.forEach((k, v) -> {
if (StringUtils.isNotBlank(String.valueOf(v))) {
targetMap.put(k, decimalFormat.format(Double.valueOf(String.valueOf(v))));
}
});
}
}
/**
*
*
* @param originString
* @return
*/
public static String thousandthConvert(String originString) {
if (StringUtils.isNotBlank(originString)) {
return decimalFormat.format(Double.valueOf(originString));
}
return "0.00";
}
/**
* : null0Mapempty
*
* @param obj
* @return
*/
public static boolean isNullOrEmpty(Object obj) {
if (obj == null) {
return true;
}
if (obj instanceof CharSequence) {
return ((CharSequence) obj).length() == 0;
}
if (obj instanceof Collection) {
return ((Collection) obj).isEmpty();
}
if (obj instanceof Map) {
return ((Map) obj).isEmpty();
}
if (obj instanceof Object[]) {
Object[] object = (Object[]) obj;
if (object.length == 0) {
return true;
}
boolean empty = true;
for (int i = 0; i < object.length; i++) {
if (!isNullOrEmpty(object[i])) {
empty = false;
break;
}
}
return empty;
}
return false;
}
public static boolean isNotNullOrEmpty(Object obj) {
return !isNullOrEmpty(obj);
}
public static <R, T, A> A properties(Collection<T> objs, Function<T, R> function, Collector<R, ?, A> collectors) {
return objs.stream().map(function).collect(collectors);
}
public static <R, T> Set<R> properties(Collection<T> objs, Function<T, R> function) {
if (CollectionUtils.isEmpty(objs)) {
return Sets.newHashSet();
}
return properties(objs, function, Collectors.toSet());
}
public static <R, T> Map<R, T> convert2Map(Collection<T> objs, Function<T, R> function) {
if (CollectionUtils.isEmpty(objs)) {
return Maps.newHashMap();
}
return objs.stream().collect(Collectors.toMap(function, Function.identity(), (a, b) -> a));
}
public static <T, K, V> Map<K, V> convert2Map(Collection<T> objs, Function<T, K> keyMapper, Function<T, V> valueMapper) {
if (CollectionUtils.isEmpty(objs)) {
return Maps.newHashMap();
}
return objs.stream()
.filter(e -> valueMapper.apply(e) != null && keyMapper.apply(e) != null)
.collect(Collectors.toMap(keyMapper, valueMapper, (a, b) -> a));
}
public static <R, T> Map<R, List<T>> group2Map(Collection<T> objs, Function<T, R> function) {
if (CollectionUtils.isEmpty(objs)) {
return Maps.newHashMap();
}
return objs.stream().collect(Collectors.groupingBy(function));
}
public static <T, K, V> Map<K, Set<V>> group2Map(Collection<T> objs, Function<T, K> keyMapper, Function<T, V> valueMapper) {
if (CollectionUtils.isEmpty(objs)) {
return Maps.newHashMap();
}
return objs.stream()
.filter(e -> keyMapper.apply(e) != null && valueMapper.apply(e) != null)
.collect(Collectors.groupingBy(keyMapper,
Collectors.collectingAndThen(Collectors.toList(), e -> e.stream().map(valueMapper).collect(Collectors.toSet()))));
}
public static <T, K, V> Map<K, List<V>> group2ListMap(Collection<T> objs, Function<T, K> keyMapper, Function<T, V> valueMapper) {
if (CollectionUtils.isEmpty(objs)) {
return Maps.newHashMap();
}
return objs.stream()
.filter(e -> keyMapper.apply(e) != null && valueMapper.apply(e) != null)
.collect(Collectors.groupingBy(keyMapper,
Collectors.collectingAndThen(Collectors.toList(), e -> e.stream().map(valueMapper).collect(Collectors.toList()))));
}
public static <R, T, K, V> Map<R, Map<K, V>> list2Map(Collection<T> objs, Function<T, R> function1, Function<T, K> function2, Function<T, V> function3) {
if (CollectionUtils.isEmpty(objs)) {
return Maps.newHashMap();
}
Map<R, List<T>> collect = objs.stream().collect(Collectors.groupingBy(function1));
Map<R, Map<K, V>> map = new HashMap<>();
for (Map.Entry<R, List<T>> entry: collect.entrySet()) {
Map<K, V> values = map.getOrDefault(entry.getKey(), new HashMap<>());
entry.getValue().forEach(e -> values.put(function2.apply(e), function3.apply(e)));
map.put(entry.getKey(), values);
}
return map;
}
public static <R, T, K> Map<R, Map<K, T>> list2Map(Collection<T> objs, Function<T, R> function1, Function<T, K> function2) {
if (CollectionUtils.isEmpty(objs)) {
return Maps.newHashMap();
}
Map<R, List<T>> collect = objs.stream().collect(Collectors.groupingBy(function1));
Map<R, Map<K, T>> map = new HashMap<>();
for (Map.Entry<R, List<T>> entry: collect.entrySet()) {
Map<K, T> values = map.getOrDefault(entry.getKey(), new HashMap<>());
entry.getValue().forEach(e -> values.put(function2.apply(e), e));
map.put(entry.getKey(), values);
}
return map;
}
/**
* LinkedHashMap
*
* @param keyExtractor
* @param <T>
* @return
*/
public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
LinkedHashMap<Object, Boolean> map = new LinkedHashMap<>();
return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
/**
* ConcurrentHashMap
*
* @param keyExtractor
* @param <T>
* @return
*/
public static <T> Predicate<T> distinctByKeyMap(Function<? super T, Object> keyExtractor) {
ConcurrentHashMap<Object, Boolean> map = new ConcurrentHashMap<>();
return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
public static <T> BigDecimal reduce(Collection<T> objs, Function<T, BigDecimal> function) {
if (CollectionUtils.isEmpty(objs)) {
return BigDecimal.ZERO;
}
return objs.stream()
.filter(e -> function.apply(e) != null)
.map(function)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
public static BigDecimal empty2Zero(String value) {
if (StringUtils.isEmpty(value)) {
return BigDecimal.ZERO;
}
try {
return new BigDecimal(value);
} catch (Exception e) {
return BigDecimal.ZERO;
}
}
/**
*
*
* @param list1
* @param list2
* @param <T>
* @return
*/
public static <T> boolean judgeIntersection(List<T> list1, List<T> list2) {
boolean flag = false;
List<T> origin = new ArrayList<>();
origin.addAll(list1);
origin.retainAll(list2);
if (origin.size() > 0) {
flag = true;
}
return flag;
}
/**
* StringLong
*
* @param obj
* @return
*/
public static Long string2Long(String obj) {
if (NumberUtils.isCreatable(obj)) {
return Long.valueOf(obj);
}
return null;
}
/**
* StringInteger
*
* @param obj
* @return
*/
public static Integer string2Integer(String obj) {
if (NumberUtils.isCreatable(obj)) {
return Integer.valueOf(obj);
}
return null;
}
/**
* StringBigDecimal
*
* @param obj
* @return
*/
public static BigDecimal string2BigDecimal(String obj) {
if (NumberUtils.isCreatable(obj)) {
return new BigDecimal(obj);
}
return null;
}
/**
* StringBigDecimal
*
* @param obj
* @return
*/
public static BigDecimal string2BigDecimalDefault0(String obj) {
if (NumberUtils.isCreatable(obj)) {
return new BigDecimal(obj);
}
return BigDecimal.ZERO;
}
/**
* 0
*
* @param obj
* @return
*/
public static boolean StringEqZERO(String obj) {
if (NumberUtils.isCreatable(obj)) {
return BigDecimal.ZERO.compareTo(new BigDecimal(obj)) == 0;
}
return false;
}
public static Double string2DoubleDefault0(String obj) {
if (NumberUtils.isCreatable(obj)) {
return new Double(obj);
}
return new Double("0.0");
}
/**
* forEasy
*
* @param arr1
* @param arr2
* @return
*/
public static <T> Collection<T> intersectionForList(Collection<T> arr1, Collection<T> arr2) {
Collection<T> resultList = new ArrayList<>();
if (CollectionUtils.isEmpty(arr1) || CollectionUtils.isEmpty(arr1)) {
return resultList;
}
arr1.forEach(a1 -> {
if (arr2.contains(a1)) {
resultList.add(a1);
}
});
return resultList;
}
public static String toJSONString(Object obj) {
if (obj != null) {
return JSON.toJSONString(obj);
}
return "";
}
public static String null2String(Object obj) {
if (Objects.isNull(obj)) {
return "";
}
return obj.toString();
}
public static String null2String(Object obj, String def) {
if (Objects.isNull(obj)) {
return def;
}
return obj.toString();
}
public static Integer getIntValue(Object obj, Integer def) {
if (Objects.isNull(obj)) {
return def;
}
try {
return StringUtils.isEmpty(String.valueOf(obj)) ? def : Integer.valueOf(String.valueOf(obj));
} catch (NumberFormatException e) {
return def;
}
}
public static BigDecimal getBigDecimal(Object value, int scale) {
String valueStr = null2String(value);
if (StringUtils.isEmpty(valueStr)) {
return BigDecimal.ZERO;
}
try {
return new BigDecimal(valueStr).setScale(scale, RoundingMode.HALF_UP);
} catch (NumberFormatException e) {
return null;
}
}
public static BigDecimal getBigDecimal(Object value, int scale, BigDecimal defValue) {
try {
return new BigDecimal(null2String(value)).setScale(scale, RoundingMode.HALF_UP);
} catch (NumberFormatException e) {
return defValue;
}
}
public static <T> T findFirst(Collection<T> objs) {
if (CollectionUtils.isEmpty(objs)) {
throw new CBS8RunTimeException("the collection can not be empty");
}
return objs.stream().findFirst().orElse(null);
}
}

@ -0,0 +1,59 @@
package com.engine.salary.remote.cbs8.client;
import com.engine.salary.exception.CBS8RunTimeException;
import com.engine.salary.remote.cbs8.request.GetTransactionDetailRequest;
import com.engine.salary.remote.cbs8.response.GetTransactionDetailResponse;
import com.engine.salary.remote.cbs8.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
@Slf4j
public class AccountManagementClient extends CBS8BaseClient {
public GetTransactionDetailResponse transactionDetailQuery(GetTransactionDetailRequest requestParam) throws IOException {
String url = host + "/openapi/account/openapi/v1/transaction-detail/query";
CloseableHttpClient client = HttpClients.custom()
// 禁止HttpClient自动解压缩
.disableContentCompression()
.build();
String requestData = JsonUtil.toJsonString(requestParam);
log.info("获取cbs交易参数" + url + "\n" + requestData);
HttpPost httpPost = setupRequest(url, requestData);
try (CloseableHttpResponse response = client.execute(httpPost)) {
byte[] finalResponseData = handleResponse(response);
String req = new String(finalResponseData, StandardCharsets.UTF_8);
GetTransactionDetailResponse getTransactionDetailResponse = JsonUtil.parseBean(req, GetTransactionDetailResponse.class);
log.info("获取cbs交易结果" + "\n" + JsonUtil.toJsonString(getTransactionDetailResponse));
if (Objects.isNull(getTransactionDetailResponse)) {
throw new CBS8RunTimeException("服务异常");
}
if (!"0".equals(getTransactionDetailResponse.getCode())) {
throw new CBS8RunTimeException(getTransactionDetailResponse.getMsg());
}
if (getTransactionDetailResponse.getData() == null) {
throw new CBS8RunTimeException("未获取数据");
}
return getTransactionDetailResponse;
} catch (IOException ignored) {
log.error("网络连接失败或超时!",ignored);
throw new CBS8RunTimeException("网络连接失败或超时!");
} finally {
client.close();
}
}
}

@ -0,0 +1,56 @@
package com.engine.salary.remote.cbs8.client;
import com.engine.salary.exception.CBS8RunTimeException;
import com.engine.salary.remote.cbs8.request.GetDtaRequest;
import com.engine.salary.remote.cbs8.response.GetDtaResponse;
import com.engine.salary.remote.cbs8.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
@Slf4j
public class BillManagementClient extends CBS8BaseClient {
public GetDtaResponse dtaQuery(GetDtaRequest requestParam) throws IOException {
String url = host + "/openapi/draft/openapi/v1/dta/query";
CloseableHttpClient client = HttpClients.custom()
// 禁止HttpClient自动解压缩
.disableContentCompression()
.build();
String requestData = JsonUtil.toJsonString(requestParam);
log.info("获取cbs票据参数" + url + "\n" + requestData);
HttpPost httpPost = setupRequest(url, requestData);
try (CloseableHttpResponse response = client.execute(httpPost)) {
byte[] finalResponseData = handleResponse(response);
String req = new String(finalResponseData, StandardCharsets.UTF_8);
GetDtaResponse getDtaResponse = JsonUtil.parseBean(req, GetDtaResponse.class);
log.info("获取cbs票据结果" + "\n" + JsonUtil.toJsonString(getDtaResponse));
if (Objects.isNull(getDtaResponse)) {
throw new CBS8RunTimeException("服务异常");
}
if (!"0".equals(getDtaResponse.getCode())) {
throw new CBS8RunTimeException(getDtaResponse.getMsg());
}
if (getDtaResponse.getData() == null) {
throw new CBS8RunTimeException("未获取数据");
}
return getDtaResponse;
} catch (IOException ignored) {
throw new CBS8RunTimeException("网络连接失败或超时!");
} finally {
client.close();
}
}
}

@ -0,0 +1,166 @@
package com.engine.salary.remote.cbs8.client;
import cn.hutool.core.util.StrUtil;
import com.engine.salary.exception.CBS8RunTimeException;
import com.engine.salary.remote.cbs8.common.Constants;
import com.engine.salary.remote.cbs8.response.GetTokenResponse;
import com.engine.salary.remote.cbs8.util.SM2Util;
import com.engine.salary.remote.cbs8.HttpUtil;
import com.engine.salary.remote.cbs8.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.apache.http.Header;
import org.apache.http.HttpMessage;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.protocol.HTTP;
import weaver.general.BaseBean;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.zip.GZIPInputStream;
@Slf4j
public class CBS8BaseClient {
static final String appId = new BaseBean().getPropValue("hrmSalaryCBS8", "app_id");
static final String appSecret = new BaseBean().getPropValue("hrmSalaryCBS8", "app_secret");
/**
* ()
*/
static final String bodyEncryptionKey = new BaseBean().getPropValue("hrmSalaryCBS8", "bodyEncryptionKey");
/**
*
*/
static final String signEncryptionPrivateKey = new BaseBean().getPropValue("hrmSalaryCBS8", "signEncryptionPrivateKey");
/**
*
*/
static final String bodyDecryptionKey = new BaseBean().getPropValue("hrmSalaryCBS8", "bodyDecryptionKey");
/**
*
*/
static final String host = new BaseBean().getPropValue("hrmSalaryCBS8", "host");
/**
* token
*
* @return
*/
public static String getToken() {
Map<String, String> params = new HashMap<>();
params.put("app_id", appId);
params.put("app_secret", appSecret);
params.put("grant_type", "client_credentials");
// 开始请求
String paramBody = JsonUtil.toJsonString(params);
String res = HttpUtil.doPost(host + "/openapi/app/v1/app/token", new HashMap<>(), paramBody, HttpUtil.JSON_TYPE);
GetTokenResponse getTokenResponse = JsonUtil.parseBean(res, GetTokenResponse.class);
log.info("获取token params:{} res: {}", paramBody, res);
if (Objects.isNull(getTokenResponse)) {
throw new CBS8RunTimeException("服务异常");
}
if (!"0".equals(getTokenResponse.getCode())) {
throw new CBS8RunTimeException(getTokenResponse.getMsg());
}
if (getTokenResponse.getData() == null) {
throw new CBS8RunTimeException("未获取数据");
}
if (StrUtil.isBlank(getTokenResponse.getData().getToken())) {
throw new CBS8RunTimeException("未获取token");
}
String token = getTokenResponse.getData().getToken();
return token;
}
/**
*
*/
public static HttpPost setupRequest(String url, String requestData) {
long timestamp = System.currentTimeMillis();
// 请求数据拼接: 报文体+时间戳
byte[] requestDataBytes = requestData.getBytes(StandardCharsets.UTF_8);
byte[] timestampBytes = ("&timestamp=" + timestamp).getBytes(StandardCharsets.UTF_8);
byte[] newBytes = new byte[requestDataBytes.length + timestampBytes.length];
System.arraycopy(requestDataBytes, 0, newBytes, 0, requestDataBytes.length);
System.arraycopy(timestampBytes, 0, newBytes, requestDataBytes.length, timestampBytes.length);
// 生成签名
byte[] signature = SM2Util.sign(signEncryptionPrivateKey, newBytes);
String sign = Base64.encodeBase64String(SM2Util.encodeDERSignature(signature));
// 设置请求URL
HttpPost httpPost = new HttpPost(url);
// 请求头设置签名
httpPost.setHeader(Constants.SIGN_HEADER_NAME, sign);
// 请求头设置时间戳
httpPost.setHeader(Constants.TIMESTAMP_HEADER, Long.toString(timestamp));
// 请求头设置请求参数格式,请根据实际情况改写
httpPost.setHeader(HTTP.CONTENT_TYPE, Constants.TARGET_CONTENT_TYPE);
// 请求头设置TOKEN
String token = getToken();
httpPost.setHeader(Constants.AUTHORIZATION, Constants.BEARER + token);
// 报文体加密
byte[] encryptedData = SM2Util.encrypt(bodyEncryptionKey, requestDataBytes);
// 设置请求体
httpPost.setEntity(new ByteArrayEntity(encryptedData));
return httpPost;
}
/**
*
*/
public byte[] handleResponse(HttpResponse response) throws IOException {
InputStream content = response.getEntity().getContent();
byte[] responseData = IOUtils.toByteArray(content);
if (responseData == null || responseData.length == 0) {
return responseData == null ? new byte[0] : responseData;
}
// 步骤1 原始响应报文解密 如果服务网关获取加解密密钥失败,则无法解密请求报文,且无法加密响应报文。 这时候,网关会直接返回错误信息,响应报文是未加密状态。
Boolean encryptionEnable = getHeader(response, Constants.ENCRYPTION_ENABLED_HEADER_NAME);
if (Boolean.TRUE.equals(encryptionEnable)) {
responseData = SM2Util.decrypt(bodyDecryptionKey, responseData);
}
Boolean xMbcloudCompress = getHeader(response, Constants.X_MBCLOUD_COMPRESS);
if (Boolean.TRUE.equals(xMbcloudCompress)) {
responseData = decompress(responseData);
}
return responseData;
}
private static Boolean getHeader(HttpMessage message, String name) {
Header header = message.getFirstHeader(name);
return header != null;
}
public static byte[] decompress(byte[] data) throws IOException {
ByteArrayInputStream input = new ByteArrayInputStream(data);
GZIPInputStream gzipInput = new GZIPInputStream(input);
return IOUtils.toByteArray(gzipInput);
}
}

@ -0,0 +1,23 @@
package com.engine.salary.remote.cbs8.common;
/**
* @author: KeXue
* @time: 2022/8/25
* @description:
*/
public interface Constants {
String TARGET_CONTENT_TYPE = "application/json";
String SIGN_HEADER_NAME = "X-MBCLOUD-API-SIGN";
String TIMESTAMP_HEADER = "X-MBCLOUD-TIMESTAMP";
String ENCRYPTION_ENABLED_HEADER_NAME = "X-MBCLOUD-ENCRYPTION-ENABLED";
String X_MBCLOUD_COMPRESS = "X-Mbcloud-Compress";
String AUTHORIZATION = "Authorization";
String BEARER = "Bearer ";
}

@ -0,0 +1,63 @@
package com.engine.salary.remote.cbs8.config;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@XStreamAlias("config")
public class EBS2ECConfig {
@XStreamAlias("name")
@XStreamAsAttribute
private String name;
@XStreamImplicit(itemFieldName = "table")
private List<Table> tables;
@Data
public static class Table {
@XStreamAlias("name")
@XStreamAsAttribute
private String name;
@XStreamAlias("key")
@XStreamAsAttribute
private String key;
@XStreamAlias("modeId")
@XStreamAsAttribute
private Integer modeId;
@XStreamImplicit(itemFieldName = "field")
private List<Field> fields;
@Data
public static class Field {
@XStreamAlias("name")
@XStreamAsAttribute
private String name;
@XStreamAlias("key")
@XStreamAsAttribute
private String key;
@XStreamAlias("ebsKey")
@XStreamAsAttribute
private String ebsKey;
@XStreamAlias("unique")
@XStreamAsAttribute
private boolean unique;
}
}
}

@ -0,0 +1,155 @@
package com.engine.salary.remote.cbs8.example;
import com.engine.salary.remote.cbs8.common.Constants;
import com.engine.salary.remote.cbs8.util.SM2Util;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.apache.http.Header;
import org.apache.http.HttpMessage;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HTTP;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.zip.GZIPInputStream;
/**
* @author: KeXue
* @time: 2022/8/25
* @description: SM2
*/
@Slf4j
public class SM2Example {
/**
* ()
*/
static final String bodyEncryptionKey = "0467E11F7CA86D884C990D4F3F5C2A1EFEEBB02B9878F4FDDCB7899DFABADCC8F38FC23F007A8AF9B2EB8A1D313959647CD8A1542F0414116AE6CFCA792346A802";
/**
*
*/
static final String signEncryptionPrivateKey = "135d6d61d5e820a979e58f4939abbd528c82528c8c276852445854377e1df247";
/**
*
*/
static final String bodyDecryptionKey = "135d6d61d5e820a979e58f4939abbd528c82528c8c276852445854377e1df247";
/**
* appidappsecerttoken
*/
static final String token = "e4cdf00f-3fc9-4845-ac57-6baaee620895";
/**
*
*/
static final String TARGET_URL = "https://cbs8-openapi-reprd.csuat.cmburl.cn/openapi/account/accounts-current-balance/erp/query";
/**
*
*/
static final String requestData = "\n" + "{\"accountNo\":\"\"}";
public static void main(String[] args) throws Exception {
CloseableHttpClient client = HttpClients.custom()
// 禁止HttpClient自动解压缩
.disableContentCompression()
.build();
HttpPost httpPost = setupRequest();
try (CloseableHttpResponse response = client.execute(httpPost)) {
byte[] finalResponseData = handleResponse(response);
log.info("\n返回结果{}", new String(finalResponseData));
}catch (IOException ignored){
throw new IOException("网络连接失败或超时!");
}finally {
client.close();
}
}
/**
*
*/
private static HttpPost setupRequest() {
long timestamp = System.currentTimeMillis();
// 请求数据拼接: 报文体+时间戳
byte[] requestDataBytes = requestData.getBytes(StandardCharsets.UTF_8);
byte[] timestampBytes = ("&timestamp=" + timestamp).getBytes(StandardCharsets.UTF_8);
byte[] newBytes = new byte[requestDataBytes.length + timestampBytes.length];
System.arraycopy(requestDataBytes, 0, newBytes, 0, requestDataBytes.length);
System.arraycopy(timestampBytes, 0, newBytes, requestDataBytes.length, timestampBytes.length);
// 生成签名
byte[] signature = SM2Util.sign(signEncryptionPrivateKey, newBytes);
String sign = Base64.encodeBase64String(SM2Util.encodeDERSignature(signature));
log.info("签名:{}", sign);
// 设置请求URL
HttpPost httpPost = new HttpPost(TARGET_URL);
// 请求头设置签名
httpPost.setHeader(Constants.SIGN_HEADER_NAME, sign);
// 请求头设置时间戳
httpPost.setHeader(Constants.TIMESTAMP_HEADER, Long.toString(timestamp));
// 请求头设置请求参数格式,请根据实际情况改写
httpPost.setHeader(HTTP.CONTENT_TYPE, Constants.TARGET_CONTENT_TYPE);
// 请求头设置TOKEN
httpPost.setHeader(Constants.AUTHORIZATION, Constants.BEARER + token);
// 报文体加密
byte[] encryptedData = SM2Util.encrypt(bodyEncryptionKey, requestDataBytes);
// 设置请求体
httpPost.setEntity(new ByteArrayEntity(encryptedData));
return httpPost;
}
/**
*
*/
private static byte[] handleResponse(HttpResponse response) throws Exception {
InputStream content = response.getEntity().getContent();
byte[] responseData = IOUtils.toByteArray(content);
if (responseData == null || responseData.length == 0) {
return responseData == null ? new byte[0] : responseData;
}
// 步骤1 原始响应报文解密 如果服务网关获取加解密密钥失败,则无法解密请求报文,且无法加密响应报文。 这时候,网关会直接返回错误信息,响应报文是未加密状态。
Boolean encryptionEnable = getHeader(response, Constants.ENCRYPTION_ENABLED_HEADER_NAME);
if (Boolean.TRUE.equals(encryptionEnable)) {
responseData = SM2Util.decrypt(bodyDecryptionKey, responseData);
}
Boolean xMbcloudCompress = getHeader(response, Constants.X_MBCLOUD_COMPRESS);
if (Boolean.TRUE.equals(xMbcloudCompress)) {
responseData = decompress(responseData);
}
return responseData;
}
private static Boolean getHeader(HttpMessage message, String name) {
Header header = message.getFirstHeader(name);
return header != null;
}
public static byte[] decompress(byte[] data) throws IOException {
ByteArrayInputStream input = new ByteArrayInputStream(data);
GZIPInputStream gzipInput = new GZIPInputStream(input);
return IOUtils.toByteArray(gzipInput);
}
}

@ -0,0 +1,55 @@
package com.engine.salary.remote.cbs8.po;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Collection;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UfHkrdzbPO {
private Integer id;
private Integer requestId;
private Integer formmodeid;
private Integer modedatacreater;
private Integer modedatacreatertype;
private String modedatacreatedate;
private String modedatacreatetime;
private String modeuuid;
private String formBizId;
private String gsbm;
private String khbm;
private String khmc;
private String bmbm;
private Integer bmd;
private Integer bm;
private Integer modedatamodifier;
private String modedatamodifydatetime;
private Collection<Long> ids;
private Integer departmentId;
}

@ -0,0 +1,10 @@
package com.engine.salary.remote.cbs8.request;
import lombok.Data;
@Data
public class CBS8BaseRequest {
private int currentPage;
private int pageSize;
}

@ -0,0 +1,108 @@
package com.engine.salary.remote.cbs8.request;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.util.List;
@Data
@EqualsAndHashCode(callSuper = true)
public class GetDtaRequest extends CBS8BaseRequest {
/**
* yyyy-mm-dd
*/
private String issueDateStart;
/**
* yyyy-mm-dd
*/
private String issueDateEnd;
/**
* yyyy-mm-dd
*/
private String dueDateStart;
/**
* yyyy-mm-dd
*/
private String dueDateEnd;
/**
* AC01-AC02-
*/
private String billType;
/**
* 1-2-3-4-5-
*/
private List<String> draftSourceList;
/**
* 4.1.1.
*/
private List<String> holdBankTypeList;
/**
* cbs>>
*/
private List<String> displayHoldOrganizationCodeList;
/**
*
*/
private List<String> holdAccountList;
/**
* yyyy-mm-dd
*/
private String holdSignDateStart;
/**
* yyyy-mm-dd
*/
private String holdSignDateEnd;
/**
*
*/
private String draftNbr;
/**
* ()
*/
private String billNbr;
/**
* 0,13
*/
private BigDecimal billAmountStart;
/**
* 0,13
*/
private BigDecimal billAmountEnd;
/**
* 12
*/
private String subBillIntervalStart;
/**
* ,12
*/
private String subBillIntervalEnd;
/**
* 4.1.3--4.1.34.1.44.1.5
*/
private List<String> billVarietyList;
/**
*
*/
private List<String> billStsList;
/**
*
*/
private List<String> billTrsStsList;
/**
* 1-2-
*/
private String stockFlag;
/**
* 0-2-3-4-5-6-7-, 8-
*/
private String outInvType;
/**
* NOR-USE-DEL- SUC-
*/
private String lockFlag;
}

@ -0,0 +1,75 @@
package com.engine.salary.remote.cbs8.request;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
@Data
@EqualsAndHashCode(callSuper = true)
public class GetTransactionDetailRequest extends CBS8BaseRequest {
/**
* yyyy-mm-dd
*/
private String startDate;
/**
* yyyy-mm-dd
*/
private String endDate;
/**
* 0-
*/
private String dateType;
/**
*
*/
private List<String> accountNoList;
/**
* CMB4.1.5
*/
private List<String> bankTypeList;
/**
* 4.1.1
*/
private List<String> currencyList;
/**
*
* B
* U/ERP
*
*/
private String detailedSources;
/**
* 1- 2-
*/
private String currentFlag;
/**
* 1-2-
*/
private String loanType;
/**
* >>AA-AA
*/
private List<String> accountNatureList;
/**
*
*/
private String bankSerialNumber;
/**
* CBS8
*/
private Long transactionSerialNumber;
/**
* >>0001-XX0001
*/
private List<String> unitCodeList;
/**
* ERP erpSerialNumber
*/
private String erpSerialNumber;
/**
*
*/
private List<String> paymentNatureList;
}

@ -0,0 +1,10 @@
package com.engine.salary.remote.cbs8.response;
import lombok.Data;
@Data
public class CBS8BaseResponse {
private String code;
private String msg;
}

@ -0,0 +1,77 @@
package com.engine.salary.remote.cbs8.response;
import lombok.Data;
@Data
public class CBS8PageInfo {
/**
*
*/
private int pageNum;
/**
*
*/
private int pageSize;
/**
*
*/
private int size;
/**
*
*/
private int pages;
/**
*
*/
private int prePage;
/**
*
*/
private int nextPage;
/**
*
*/
private long total;
/**
*
*/
private int startRow;
/**
*
*/
private int endRow;
/**
*
*/
private boolean isFirstPage;
/**
*
*/
private boolean isLastPage;
/**
*
*/
private boolean hasPreviousPage;
/**
*
*/
private boolean hasNextPage;
/**
*
*/
private int navigatePages;
/**
*
*/
private int[] navigatepageNums;
/**
*
*/
private int navigateFirstPage;
/**
*
*/
private int navigateLastPage;
}

@ -0,0 +1,440 @@
package com.engine.salary.remote.cbs8.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
@Data
@EqualsAndHashCode(callSuper = true)
public class GetDtaResponse extends CBS8BaseResponse {
/**
*
*/
private Body data;
@Data
public static class Body extends CBS8PageInfo{
/**
*
*/
private List<Detail> list;
}
@Data
public static class Detail {
/**
*
*/
private String draftNbr;
/**
*
*/
private String fatDraftNbr;
/**
* 4.1.3
*/
private String billVariety;
/**
* ()
*/
private String billNbr;
/**
* 0- 1-
*/
private String splitFlag;
/**
*
*/
private String subBillIntervalStart;
/**
*
*/
private String subBillIntervalEnd;
/**
*
*/
private String subBillInterval;
/**
* 0,13
*/
private BigDecimal billAmount;
/**
* AC01-AC02-
*/
private String billType;
/**
* yyyy-mm-dd
*/
private Date issueDate;
/**
* yyyy-mm-dd
*/
private Date dueDate;
/**
* yyyy-mm-dd
*/
private Date receiptDate;
/**
* yyyy-mm-dd
*/
private Date holdSignDate;
/**
* EM00-EM01-
*/
private String trfFlag;
/**
* EM00-EM01-
*/
private String endorsementTransferFlg;
/**
* 4.1.4
*/
private String billSts;
/**
* 4.1.5
*/
private String billTrsSts;
/**
* 0-1-2-
*/
private String stockFlag;
/**
* 0-2-3-4-5-6-7-, 8-
*/
private String outInvType;
/**
* RS00- RS01- RS02- RS03- RS05- RS06-
*/
private String riskFlag;
/**
* NOR-USE-DEL- SUC-
*/
private String lockFlag;
/**
*
* 1-
* 2-
* 3-
* 4-
* 5-
*/
private String draftSource;
/**
* RC00-(02), RC01-(00) ,RC02- (01),RC03 -(A1),RC04-(A2), RC05-(03), RC06-(03) ,RC07-(03)
*/
private String acceptorType;
/**
* 1-0-
*/
private String drawerEnsureFlag;
/**
* 1-0-
*/
private String acceptorEnsureFlag;
/**
* 1-0-
*/
private String backEnsureFlag;
/**
*
*/
private String drawerName;
/**
* 1-0-
*/
private String drawerInternalFlag;
/**
*
*/
private String drawerOrganizationName;
/**
*
*/
private String displayDrawerOrganizationCode;
/**
* 1-0-
*/
private String drawerCustomerFlg;
/**
*
*/
private String drawerCustomerName;
/**
* cbs>>>
*/
private String drawerCustomerNbr;
/**
*
*/
private String drawerAccountName;
/**
*
*/
private String drawerAccount;
/**
*
*/
private String drawerBrnName;
/**
*
*/
private String drawerInterbankNbr;
/**
*
*/
private String payeeName;
/**
* 1-0-
*/
private String payeeInternalFlag;
/**
*
*/
private String payeeOrganizationName;
/**
*
*/
private String displayPayeeOrganizationCode;
/**
* 1-0-
*/
private String payeeCustomerFlag;
/**
*
*/
private String payeeCustomerName;
/**
* cbs>>>
*/
private String payeeCustomerNbr;
/**
*
*/
private String payeeAccountName;
/**
*
*/
private String payeeAccount;
/**
*
*/
private String payeeInterbankNbr;
/**
*
*/
private String payeeBrnName;
/**
*
*/
private String acceptorName;
/**
* 1-0-
*/
private String acceptorInternalFlag;
/**
*
*/
private String acceptorOrganizationName;
/**
*
*/
private String displayAcceptorOrganizationCode;
/**
* 1-0-
*/
private String acceptorCustomerFlg;
/**
*
*/
private String acceptorCustomerName;
/**
* cbs>>>
*/
private String acceptorCustomerNbr;
/**
*
*/
private String acceptorAccountName;
/**
*
*/
private String acceptorAccount;
/**
*
*/
private String acceptorBrnName;
/**
*
*/
private String acceptorInterbankNbr;
/**
* /
*/
private String expireUnconditionalPay;
/**
* yyyy-mm-dd
*/
private Date acceptorDate;
/**
*
*/
private String drawerRateSubject;
/**
* 4.1.7
*/
private String drawerCreditRating;
/**
* yyyy-mm-dd
*/
private Date drawerRateDueDate;
/**
*
*/
private String acceptorRateSubject;
/**
* 4.1.7
*/
private String acceptorCreditRating;
/**
* yyyy-mm-dd
*/
private Date acceptorRateDueDate;
/**
*
*/
private String holdName;
/**
*
*/
private String holdOrganizationName;
/**
*
*/
private String displayHoldOrganizationCode;
/**
*
*/
private String holdAccountName;
/**
* 4.1.1.
*/
private String holdBankType;
/**
*
*/
private String holdAccount;
/**
*
*/
private String holdBrnName;
/**
*
*/
private String holdInterbankNbr;
/**
*
*/
private String preName;
/**
* 1-0-
*/
private String preInternalFlag;
/**
*
*/
private String preOrganizationName;
/**
*
*/
private String displayPreOrganizationCode;
/**
* 1-0-
*/
private String preCustomerFlag;
/**
*
*/
private String preCustomerName;
/**
* cbs>>>
*/
private String preCustomerNbr;
/**
*
*/
private String preAccountName;
/**
*
*/
private String preAccount;
/**
*
*/
private String preBrnName;
/**
*
*/
private String preInterbankNbr;
/**
*
*/
private String nextName;
/**
* 1-0-
*/
private String nextInternalFlag;
/**
*
*/
private String nextOrganizationName;
/**
*
*/
private String displayNextOrganizationCode;
/**
* 1-0-
*/
private String nextCustomerFlag;
/**
*
*/
private String nextCustomerName;
/**
* cbs>>>
*/
private String nextCustomerNbr;
/**
*
*/
private String nextAccountName;
/**
*
*/
private String nextAccount;
/**
*
*/
private String nextBrnName;
/**
*
*/
private String nextInterbankNbr;
/**
* 1-2-
*/
private String signMethod;
/**
*
* INIT-
* ING-
* SUC-
* FAL-
*/
private String asyncStatus;
}
}

@ -0,0 +1,20 @@
package com.engine.salary.remote.cbs8.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
public class GetTokenResponse extends CBS8BaseResponse {
/**
*
*/
private Body data;
@Data
public static class Body {
private Integer expires;
private String token;
private String token_type;
}
}

@ -0,0 +1,268 @@
package com.engine.salary.remote.cbs8.response;
import com.alibaba.fastjson.JSON;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
@Data
@EqualsAndHashCode(callSuper = true)
public class GetTransactionDetailResponse extends CBS8BaseResponse {
/**
*
*/
private Body data;
@Data
@EqualsAndHashCode(callSuper = true)
public static class Body extends CBS8PageInfo{
/**
*
*/
private List<Detail> list;
}
@Data
public static class Detail {
/**
*
*/
private String accountNo;
/**
*
*/
private String accountName;
/**
* 4.1.5
*/
private String bankType;
/**
*
*/
private String openBank;
/**
*
*/
private Date bankTransactionDate;
/**
*
*/
private String bankSerialNumber;
/**
*
*/
private Long transactionSerialNumber;
/**
* 4.1.1
*/
private String currency;
/**
* 1-2-
*/
private String loanType;
/**
*
*/
private BigDecimal incurredAmount;
/**
*
*/
private BigDecimal accountBalance;
/**
*
*/
private String purpose;
/**
*
*/
private String digest;
/**
*
*/
private String oppositeAccount;
/**
*
*/
private String oppositeName;
/**
*
*/
private String oppositeOpeningBank;
/**
*
*/
private String associatedCustomerNumber;
/**
* >>C002-XXC002
*/
private String merchantNumber;
/**
* >>C002-XXXX
*/
private String merchantName;
/**
*
*/
private Date valueDate;
/**
* 4.1.8
*/
private String transactionCode;
/**
* 1-2-3-4-
*/
private String paymentNatureFlag;
/**
* >>A001-A001
*/
private String paymentNature;
/**
* B U/ERP
*/
private String detailSource;
/**
* 1- 2-
*/
private String detailType;
/**
* 0-1-
*/
private String accountStatus;
/**
* >>AA-AA
*/
private String accountNature;
/**
* CBS8
*/
private String checkCode;
/**
* >>0001-XX0001
*/
private String unitCode;
/**
*
*/
private String unitName;
/**
*
*/
private String remark;
/**
* ERP referenceNum
*/
private String erpSerialNumber;
/**
* 1
*/
private String PayApplyRemark1;
/**
* 2
*/
private String PayApplyRemark2;
/**
* 3
*/
private String PayApplyRemark3;
/**
*
*/
private String corporateIdentityCode;
/**
* 1
*/
private String reserveField1;
/**
* 2
*/
private String reserveField2;
/**
* 3
*/
private String reserveField3;
/**
* 4
*/
private String reserveField4;
/**
* fieldKeyKEY title : content :
*/
private List<JSON> extensionMsg;
/**
*
*/
private String postscript;
/**
*
*/
private String voucherCode;
/**
*
*/
private Date bookingDate;
/**
* 1 4.1.20
*/
private String personalizeField1;
/**
* 2 4.1.20
*/
private String personalizeField2;
/**
* 3 4.1.20
*/
private String personalizeField3;
/**
* 4 4.1.20
*/
private String personalizeField4;
/**
* 5 4.1.20
*/
private String personalizeField5;
/**
*
*/
private String virtualAccount;
/**
*
*/
private String virtualAccountName;
/**
*
*/
private String protocolType;
/**
*
*/
private String protocolTypeName;
/**
* /
*/
private String parentSubCompanyAccount;
/**
* //
*/
private String parentSubCompanyName;
/**
* 9091->->->
* ->->erp_trans_detail_mark_return_flag(ERP)null
* id:id
* bizCode:(4.1.22)
* bizFlag:
* (0-
* 1-
* 2-
* 3-ERP)
* moduleCode:
* menuName:
* bizOrderNo:
*/
private List<JSON> markingList;
}
}

@ -0,0 +1,215 @@
package com.engine.salary.remote.cbs8.util;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.asn1.*;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.params.*;
import org.bouncycastle.crypto.signers.SM2Signer;
import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.encoders.Hex;
import java.io.ByteArrayInputStream;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.Enumeration;
/**
* @author: KeXue
* @time: 2022/8/25
* @description: SM2
*/
@Slf4j
public class SM2Util {
private SM2Util() {
throw new IllegalStateException("Utility class");
}
private static final String STD_NAME = "sm2p256v1";
/**
* SM2
*
* @param publicKey
* @param data
* @return
*/
public static byte[] encrypt(String publicKey, byte[] data) {
ECPublicKeyParameters ecPublicKeyParameters = encodePublicKey(Hex.decode(publicKey));
SM2Engine engine = new SM2Engine();
engine.init(true, new ParametersWithRandom(ecPublicKeyParameters, new SecureRandom()));
byte[] bytes = null;
try {
byte[] cipherText = engine.processBlock(data, 0, data.length);
bytes = C1C2C3ToC1C3C2(cipherText);
} catch (Exception e) {
log.warn("SM2加密时出现异常:" + e.getMessage());
}
return bytes;
}
/**
* SM2
*
* @param privateKey
* @param cipherData
* @return
*/
public static byte[] decrypt(String privateKey, byte[] cipherData) {
ECPrivateKeyParameters ecPrivateKeyParameters = encodePrivateKey(Hex.decode(privateKey));
SM2Engine engine = new SM2Engine();
engine.init(false, ecPrivateKeyParameters);
byte[] bytes = null;
try {
cipherData = C1C3C2ToC1C2C3(cipherData);
bytes = engine.processBlock(cipherData, 0, cipherData.length);
} catch (Exception e) {
log.warn("SM2解密时出现异常:" + e.getMessage());
}
return bytes;
}
/**
*
*
* @param privateKey
* @param data
* @return
*/
public static byte[] sign(String privateKey, byte[] data) {
ECPrivateKeyParameters ecPrivateKeyParameters = encodePrivateKey(hexToByte(privateKey));
SM2Signer signer = new SM2Signer();
ParametersWithID parameters = new ParametersWithID(ecPrivateKeyParameters, "1234567812345678".getBytes());
signer.init(true, parameters);
signer.update(data, 0, data.length);
byte[] signature = null;
try {
signature = decodeDERSignature(signer.generateSignature());
} catch (Exception e) {
log.warn("SM2签名时出现异常:" + e.getMessage());
}
return signature;
}
private static byte[] hexToByte(String hex)
throws IllegalArgumentException {
if (hex.length() % 2 != 0) {
throw new IllegalArgumentException();
}
char[] arr = hex.toCharArray();
byte[] b = new byte[hex.length() / 2];
for (int i = 0, j = 0, l = hex.length(); i < l; i++, j++) {
String swap = "" + arr[i++] + arr[i];
int byteInt = Integer.parseInt(swap, 16) & 0xFF;
b[j] = BigInteger.valueOf(byteInt).byteValue();
}
return b;
}
private static byte[] C1C2C3ToC1C3C2(byte[] cipherText) throws Exception {
if (cipherText != null && cipherText.length >= 97) {
byte[] bytes = new byte[cipherText.length];
System.arraycopy(cipherText, 0, bytes, 0, 65);
System.arraycopy(cipherText, cipherText.length - 32, bytes, 65, 32);
System.arraycopy(cipherText, 65, bytes, 97, cipherText.length - 97);
return bytes;
} else {
throw new Exception("SM2 cipher text error, must be more than 96 bytes and in the format C1||C3||C2.");
}
}
private static byte[] C1C3C2ToC1C2C3(byte[] cipherText) throws Exception {
if (cipherText != null && cipherText.length >= 97) {
byte[] bytes = new byte[cipherText.length];
System.arraycopy(cipherText, 0, bytes, 0, 65);
System.arraycopy(cipherText, 97, bytes, 65, cipherText.length - 97);
System.arraycopy(cipherText, 65, bytes, cipherText.length - 32, 32);
return bytes;
} else {
throw new Exception("SM2 cipher text error, must be more than 96 bytes and in the format C1||C3||C2.");
}
}
private static ECPublicKeyParameters encodePublicKey(byte[] value) {
byte[] x = new byte[32];
byte[] y = new byte[32];
System.arraycopy(value, 1, x, 0, 32);
System.arraycopy(value, 33, y, 0, 32);
BigInteger X = new BigInteger(1, x);
BigInteger Y = new BigInteger(1, y);
ECPoint Q = getSM2Curve().createPoint(X, Y);
return new ECPublicKeyParameters(Q, getECDomainParameters());
}
private static ECCurve getSM2Curve() {
ECParameterSpec spec = ECNamedCurveTable.getParameterSpec(STD_NAME);
return spec.getCurve();
}
private static ECPrivateKeyParameters encodePrivateKey(byte[] value) {
BigInteger d = new BigInteger(1, value);
return new ECPrivateKeyParameters(d, getECDomainParameters());
}
private static ECDomainParameters getECDomainParameters() {
ECParameterSpec spec = ECNamedCurveTable.getParameterSpec(STD_NAME);
return new ECDomainParameters(spec.getCurve(), spec.getG(), spec.getN(), spec.getH(), spec.getSeed());
}
private static byte[] decodeDERSignature(byte[] signature) {
ASN1InputStream stream = new ASN1InputStream(new ByteArrayInputStream(signature));
byte[] bytes = new byte[64];
try {
ASN1Sequence primitive = (ASN1Sequence) stream.readObject();
Enumeration enumeration = primitive.getObjects();
BigInteger R = ((ASN1Integer) enumeration.nextElement()).getValue();
BigInteger S = ((ASN1Integer) enumeration.nextElement()).getValue();
byte[] r = format(R.toByteArray());
byte[] s = format(S.toByteArray());
System.arraycopy(r, 0, bytes, 0, 32);
System.arraycopy(s, 0, bytes, 32, 32);
} catch (Exception e) {
log.warn("decodeDERSignature时出现异常:" + e.getMessage());
}
return bytes;
}
public static byte[] encodeDERSignature(byte[] signature) {
byte[] r = new byte[32];
byte[] s = new byte[32];
System.arraycopy(signature, 0, r, 0, 32);
System.arraycopy(signature, 32, s, 0, 32);
ASN1EncodableVector vector = new ASN1EncodableVector();
vector.add(new ASN1Integer(new BigInteger(1, r)));
vector.add(new ASN1Integer(new BigInteger(1, s)));
byte[] encoded = null;
try {
encoded = (new DERSequence(vector)).getEncoded();
} catch (Exception e) {
log.warn("encodeDERSignature时出现异常:" + e.getMessage());
}
return encoded;
}
private static byte[] format(byte[] value) {
if (value.length == 32) {
return value;
} else {
byte[] bytes = new byte[32];
if (value.length > 32) {
System.arraycopy(value, value.length - 32, bytes, 0, 32);
} else {
System.arraycopy(value, 0, bytes, 32 - value.length, value.length);
}
return bytes;
}
}
}

@ -0,0 +1,51 @@
package com.engine.salary.remote.cbs8.util.db;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
public class IdGenerator {
private static AtomicLong next = new AtomicLong(1L);
public static final int ID_LENGTH_36 = 36;
public IdGenerator() {
}
public static long generate() {
return System.currentTimeMillis() + next.getAndIncrement();
}
public static String generateId() {
return System.currentTimeMillis() + String.valueOf(next.getAndIncrement());
}
public static String generateStrId() {
return System.currentTimeMillis() + generateStrId(36);
}
public static String generateStrId(int idLength) {
if (idLength >= 1 && idLength <= 36) {
char[] srcChars = new char[]{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'g', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
char[] chars = new char[idLength];
for(int i = 0; i < idLength; ++i) {
if (i != 8 && i != 13 && i != 18 && i != 23) {
if (i == 0) {
chars[i] = srcChars[(int)(Math.random() * 26.0D) % 26];
} else {
chars[i] = srcChars[(int)(Math.random() * 36.0D) % 36];
}
} else {
chars[i] = '_';
}
}
return new String(chars);
} else {
return "";
}
}
public static String getUUID() {
return UUID.randomUUID().toString().replaceAll("-", "");
}
}

@ -0,0 +1,79 @@
/**
*
*/
package com.engine.salary.remote.cbs8.util.db;
import org.apache.ibatis.session.SqlSession;
import weaver.conn.mybatis.MyBatisFactory;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* mapper
* <p>Copyright: Copyright (c) 2022</p>
* <p>Company: </p>
*
* @author qiantao
* @version 1.0
**/
public class MapperProxyFactory implements InvocationHandler {
private Class clazz;
private boolean enableTransactions = false;
private SqlSession session;
public MapperProxyFactory(Class clazz) {
this.clazz = clazz;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Exception {
this.session = MyBatisFactory.sqlSessionFactory.openSession();
try {
Object target = session.getMapper(clazz);
return method.invoke(target, args);
} finally {
if (!enableTransactions) {
session.commit();
session.close();
}
}
}
public Object getProxy() {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class<?>[] interfaces = new Class<?>[1];
interfaces[0] = this.clazz;
return Proxy.newProxyInstance(loader, interfaces, this);
}
public Object getProxy(boolean enableTransactions) {
this.enableTransactions = enableTransactions;
return this.getProxy();
}
public void commit() {
if (this.session != null) {
this.session.commit();
this.session.close();
}
}
public void rollback() {
if (this.session != null) {
this.session.rollback();
this.session.close();
}
}
public static <T> T getProxy(Class<T> clazz) {
MapperProxyFactory handle = new MapperProxyFactory(clazz);
return (T) handle.getProxy();
}
public static <T> T getProxy(Class<T> clazz, boolean enableTransactions) {
MapperProxyFactory handle = new MapperProxyFactory(clazz);
return (T) handle.getProxy(enableTransactions);
}
}

@ -0,0 +1,68 @@
package com.engine.salary.remote.cbs8.xml;
import cn.hutool.core.util.StrUtil;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.HierarchicalStreamDriver;
import com.thoughtworks.xstream.io.naming.NoNameCoder;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.security.AnyTypePermission;
import java.util.Objects;
public class XStreamUtil {
//new NoNameCoder() 解决 _ 被序列化成 __ 的问题
private static final NoNameCoder noNameCoder = new NoNameCoder();
private static XStream xStream = new XStream(new DomDriver("UTF-8", noNameCoder));
private static XStream getxStream(HierarchicalStreamDriver driver){
if(Objects.isNull(driver)){
return xStream;
}
return new XStream(driver);
}
public static <T> T unmarshal(String pkgName, Class<T> cla, String xmlStr, HierarchicalStreamDriver driver) {
xStream = getxStream(driver);
if (StrUtil.isEmpty(pkgName)) {
//高版本为了解决安全漏洞,增加了白名单机制, 如果不设置这个权限可能会报错
xStream.addPermission(AnyTypePermission.ANY);
} else {
//设置允许解析的包,如果不想设置可以用 addPermission(AnyTypePermission.ANY) 代替
xStream.allowTypesByWildcard(new String[]{pkgName});
}
//支持注解不然使用的XStream注解不会生效且不报错
xStream.autodetectAnnotations(true);
xStream.processAnnotations(cla);
//忽略未知属性, 如果不添加这个当Xml报文中出现实体中没有的属性时会报错 No such field
xStream.ignoreUnknownElements();
return (T) xStream.fromXML(xmlStr);
}
public static <T> T unmarshal(String pkgName, Class<T> cla, String xmlStr) {
return unmarshal(pkgName, cla, xmlStr, null);
}
public static <T> T unmarshal(Class<T> cla, String xmlStr) {
return unmarshal(null, cla, xmlStr, null);
}
public static String marshal(Object o, DomDriver driver) {
xStream = getxStream(driver);
//支持注解,不然使用的 @XStreamAlias() 注解不会生效而且不会报错
xStream.autodetectAnnotations(true);
//注册自定义时间转换器使得XStream全局支持LocalDateTime 或者不在这里注册,使用@XStreamConverter(LocalDateTimeConverter.class)注解在单一字段上
// xStream.registerConverter(new LocalDateTimeConverter());
return xStream.toXML(o);
}
public static String marshal(Object o){
return marshal(o, null);
}
}

@ -0,0 +1,285 @@
package com.engine.salary.timer;
import cn.hutool.core.util.StrUtil;
import com.engine.salary.exception.CBS8RunTimeException;
import com.engine.salary.mapper.SQLMapper;
import com.engine.salary.mapper.cbs.UfHkrdzbMapper;
import com.engine.salary.remote.cbs8.client.AccountManagementClient;
import com.engine.salary.remote.cbs8.config.EBS2ECConfig;
import com.engine.salary.remote.cbs8.po.UfHkrdzbPO;
import com.engine.salary.remote.cbs8.request.GetTransactionDetailRequest;
import com.engine.salary.remote.cbs8.response.GetTransactionDetailResponse;
import com.engine.salary.remote.cbs8.JsonUtil;
import com.engine.salary.remote.cbs8.SalaryEntityUtil;
import com.engine.salary.remote.cbs8.util.db.MapperProxyFactory;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.security.AnyTypePermission;
import lombok.extern.slf4j.Slf4j;
import weaver.conn.RecordSet;
import weaver.formmode.setup.ModeRightInfo;
import weaver.general.GCONST;
import weaver.general.TimeUtil;
import weaver.hrm.User;
import weaver.interfaces.schedule.BaseCronJob;
import java.io.File;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
/**
*
* <p>Copyright: Copyright (c) 2024</p>
* <p>Company: </p>
*
* @author qiantao
* @version 1.0
**/
@Slf4j
public class SyncCBSAccountDetailsJob extends BaseCronJob {
/**
* yyyy-mm-dd
*/
private String startDate;
/**
* yyyy-mm-dd
*/
private String endDate;
/**
* 1-2-
*/
private String loanType;
/**
*
*/
private String paymentNatureList;
/**
* 0-
*/
private String dateType;
/**
*
*/
private String accountNoList;
/**
* CMB4.1.5
*/
private String bankTypeList;
/**
* 4.1.1
*/
private String currencyList;
/**
*
* B
* U/ERP
*
*/
private String detailedSources;
/**
* 1- 2-
*/
private String currentFlag;
/**
* >>AA-AA
*/
private String accountNatureList;
/**
*
*/
private String bankSerialNumber;
/**
* CBS8
*/
private Long transactionSerialNumber;
/**
* >>0001-XX0001
*/
private String unitCodeList;
/**
* ERP erpSerialNumber
*/
private String erpSerialNumber;
private SQLMapper getSQLMapper() {
return MapperProxyFactory.getProxy(SQLMapper.class);
}
private UfHkrdzbMapper getUfHkrdzbMapper() {
return MapperProxyFactory.getProxy(UfHkrdzbMapper.class);
}
@Override
public void execute() {
User user = new User();
user.setUid(1);
user.setLoginid("sysadmin");
try {
GetTransactionDetailRequest requestParam = new GetTransactionDetailRequest();
requestParam.setCurrentPage(1);
requestParam.setPageSize(1000);
if (StrUtil.isNotBlank(startDate) && StrUtil.isNotBlank(endDate)) {
requestParam.setStartDate(startDate);
requestParam.setEndDate(endDate);
} else {
String nowDate = LocalDate.now().toString();
requestParam.setStartDate(nowDate);
requestParam.setEndDate(nowDate);
}
requestParam.setLoanType(loanType);
requestParam.setPaymentNatureList(paymentNatureList == null ? null :Arrays.stream(paymentNatureList.split(",")).collect(Collectors.toList()));
requestParam.setDateType(dateType);
requestParam.setAccountNoList(accountNoList== null ? null :Arrays.stream(accountNoList.split(",")).collect(Collectors.toList()));
requestParam.setBankTypeList(bankTypeList== null ? null :Arrays.stream(bankTypeList.split(",")).collect(Collectors.toList()));
requestParam.setCurrencyList(currencyList== null ? null :Arrays.stream(currencyList.split(",")).collect(Collectors.toList()));
requestParam.setDetailedSources(detailedSources);
requestParam.setCurrentFlag(currentFlag);
requestParam.setAccountNatureList(accountNatureList== null ? null :Arrays.stream(accountNatureList.split(",")).collect(Collectors.toList()));
requestParam.setBankSerialNumber(bankSerialNumber);
requestParam.setTransactionSerialNumber(transactionSerialNumber);
requestParam.setUnitCodeList(unitCodeList== null ? null :Arrays.stream(unitCodeList.split(",")).collect(Collectors.toList()));
requestParam.setErpSerialNumber(erpSerialNumber);
//查询前1000条数据
AccountManagementClient accountManagementClient = new AccountManagementClient();
GetTransactionDetailResponse response = accountManagementClient.transactionDetailQuery(requestParam);
List<GetTransactionDetailResponse.Detail> list = response.getData().getList();
//判断是否还存在数据,递归查询
boolean hasNextPage = response.getData().isHasNextPage();
int nextPage = response.getData().getNextPage();
while (hasNextPage) {
requestParam.setCurrentPage(nextPage);
GetTransactionDetailResponse nextPageResponse = accountManagementClient.transactionDetailQuery(requestParam);
List<GetTransactionDetailResponse.Detail> pageData = nextPageResponse.getData().getList();
list.addAll(pageData);
hasNextPage = nextPageResponse.getData().isHasNextPage();
nextPage = nextPageResponse.getData().getNextPage();
}
//加载cbs配置
XStream xStream = new XStream();
String resource = GCONST.getRootPath() + "WEB-INF" + File.separatorChar + "CBS2ECConfig.xml";
File file = new File(resource);
xStream.addPermission(AnyTypePermission.ANY);
xStream.processAnnotations(EBS2ECConfig.class);
EBS2ECConfig dto = (EBS2ECConfig) xStream.fromXML(file);
EBS2ECConfig.Table table = dto.getTables().get(0);
Integer modeId = table.getModeId();
String tableName = table.getKey();
//获取已存在的数据
EBS2ECConfig.Table.Field uniqueField = table.getFields().stream().filter(EBS2ECConfig.Table.Field::isUnique).findFirst().orElse(null);
if (uniqueField == null) {
throw new CBS8RunTimeException("未设置唯一标识字段");
}
String uniqueKey = uniqueField.getKey();
String uniqueEbsKey = uniqueField.getEbsKey();
List<String> uniqueDataKeys = getSQLMapper().listString(String.format("select %s from %s", uniqueKey, tableName));
//获取汇款人与办事处的对照数据
List<UfHkrdzbPO> ufHkrdzbPOS = getUfHkrdzbMapper().listAll();
Map<String, Integer> customerDepartmentMap = SalaryEntityUtil.convert2Map(ufHkrdzbPOS, UfHkrdzbPO::getKhmc, UfHkrdzbPO::getDepartmentId);
for (GetTransactionDetailResponse.Detail detail : list) {
Map<String, String> detailMap = JsonUtil.parseMap(detail, String.class);
String uniqueData = detailMap.get(uniqueEbsKey);
if (StrUtil.isBlank(uniqueData)) {
log.warn("跳过cbs交易数据唯一标识返回空,uniqueKey:{},uniqueEbsKey:{}", uniqueKey, uniqueEbsKey);
continue;
}
if (uniqueDataKeys.contains(uniqueData)) {
log.warn("跳过cbs交易数据数据已存在,uniqueKey:{},uniqueEbsKey:{},值{}", uniqueKey, uniqueEbsKey, uniqueData);
continue;
}
List<String> fields = new ArrayList<String>() {{
//建模默认字段
add("formmodeid");
add("modedatacreater");
add("modedatacreatertype");
add("modedatacreatedate");
add("modedatacreatetime");
}};
String currDate = TimeUtil.getCurrentDateString();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
String currTime = sdf.format(new Date());
List<Object> values = new ArrayList<Object>() {{
add(modeId);
add(1);
add(0);
add(String.format("'%s'", currDate));
add(String.format("'%s'", currTime));
}};
String hkr = "";
for (EBS2ECConfig.Table.Field field : table.getFields()) {
//数据库字段
String fieldName = field.getKey();
fields.add(fieldName);
// 接口值
String value = detailMap.getOrDefault(field.getEbsKey(), "");
values.add(String.format("'%s'", detailMap.getOrDefault(field.getEbsKey(), "")));
//汇款人
if ("hkr".equals(fieldName)) {
hkr = value;
}
}
//业务逻辑字段,收款类型,默认是银行存款
fields.add("sklx");
values.add(0);
/*
*
*
*
*
*/
Integer departmentId = customerDepartmentMap.get(hkr);
if(departmentId!=null){
//认领
fields.add("zt");
values.add(1);
//是否系统认领
fields.add("sfxtzdrl");
values.add(1);
//办事处
fields.add("szbm");
values.add(departmentId);
}else {
//未认领
fields.add("zt");
values.add(0);
}
String sql = String.format("insert into %s (%s) values (%s)", tableName, String.join(",", fields), values.stream().map(Object::toString).collect(Collectors.joining(",")));
RecordSet rs = new RecordSet();
rs.execute(sql);
if (modeId != null) {
rs.executeQuery("select max(id) from " + tableName);
int mainId = 0;
if (rs.next()) {
mainId = rs.getInt(1);
}
ModeRightInfo ModeRightInfo = new ModeRightInfo();
ModeRightInfo.setNewRight(true);
ModeRightInfo.editModeDataShare(1, modeId, mainId);
}
}
} catch (Exception e) {
log.error("获取CBS交易信息失败", e);
throw new CBS8RunTimeException("获取CBS交易信息失败," + e.getMessage(), e);
}
}
}

@ -0,0 +1,311 @@
package com.engine.salary.timer;
import cn.hutool.core.util.StrUtil;
import com.engine.salary.exception.CBS8RunTimeException;
import com.engine.salary.mapper.SQLMapper;
import com.engine.salary.remote.cbs8.client.BillManagementClient;
import com.engine.salary.remote.cbs8.config.EBS2ECConfig;
import com.engine.salary.remote.cbs8.request.GetDtaRequest;
import com.engine.salary.remote.cbs8.response.GetDtaResponse;
import com.engine.salary.remote.cbs8.JsonUtil;
import com.engine.salary.remote.cbs8.util.db.MapperProxyFactory;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.security.AnyTypePermission;
import lombok.extern.slf4j.Slf4j;
import weaver.conn.RecordSet;
import weaver.formmode.setup.ModeRightInfo;
import weaver.general.GCONST;
import weaver.general.TimeUtil;
import weaver.general.Util;
import weaver.hrm.User;
import weaver.interfaces.schedule.BaseCronJob;
import java.io.File;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
/**
*
* <p>Copyright: Copyright (c) 2024</p>
* <p>Company: </p>
*
* @author qiantao
* @version 1.0
**/
@Slf4j
public class SyncCBSBillPoolJob extends BaseCronJob {
/**
* cbs>>
*/
private String displayHoldOrganizationCodeList;
/**
*
*/
private String holdAccountList;
/**
* 4.1.3--4.1.34.1.44.1.5
*/
private String billVarietyList;
/**
* yyyy-mm-dd
*/
private String issueDateStart;
/**
* yyyy-mm-dd
*/
private String issueDateEnd;
/**
* yyyy-mm-dd
*/
private String dueDateStart;
/**
* yyyy-mm-dd
*/
private String dueDateEnd;
/**
* AC01-AC02-
*/
private String billType;
/**
* 1-2-3-4-5-
*/
private String draftSourceList;
/**
* 4.1.1.
*/
private String holdBankTypeList;
/**
* yyyy-mm-dd
*/
private String holdSignDateStart;
/**
* yyyy-mm-dd
*/
private String holdSignDateEnd;
/**
*
*/
private String draftNbr;
/**
* ()
*/
private String billNbr;
/**
* 0,13
*/
private BigDecimal billAmountStart;
/**
* 0,13
*/
private BigDecimal billAmountEnd;
/**
* 12
*/
private String subBillIntervalStart;
/**
* ,12
*/
private String subBillIntervalEnd;
/**
*
*/
private String billStsList;
/**
*
*/
private String billTrsStsList;
/**
* 1-2-
*/
private String stockFlag;
/**
* 0-2-3-4-5-6-7-, 8-
*/
private String outInvType;
/**
* NOR-USE-DEL- SUC-
*/
private String lockFlag;
private SQLMapper getSQLMapper() {
return MapperProxyFactory.getProxy(SQLMapper.class);
}
@Override
public void execute() {
User user = new User();
user.setUid(1);
user.setLoginid("sysadmin");
try {
GetDtaRequest requestParam = new GetDtaRequest();
requestParam.setCurrentPage(1);
requestParam.setPageSize(1000);
if (StrUtil.isBlank(displayHoldOrganizationCodeList)) {
throw new CBS8RunTimeException("持票人单位编码为空,请在计划任务配置此项!");
}
requestParam.setDisplayHoldOrganizationCodeList(Arrays.stream(displayHoldOrganizationCodeList.split(",")).collect(Collectors.toList()));
if (StrUtil.isBlank(holdAccountList)) {
throw new CBS8RunTimeException("持票人账号为空,请在计划任务配置此项!");
}
requestParam.setHoldAccountList(Arrays.stream(holdAccountList.split(",")).collect(Collectors.toList()));
if (StrUtil.isNotBlank(issueDateStart) && StrUtil.isNotBlank(issueDateEnd)) {
requestParam.setIssueDateStart(issueDateStart);
requestParam.setIssueDateEnd(issueDateEnd);
} else {
String nowDate = LocalDate.now().toString();
requestParam.setIssueDateStart(nowDate);
requestParam.setIssueDateEnd(nowDate);
}
//系统票据类型
requestParam.setBillVarietyList(Arrays.stream(Util.null2String(billVarietyList).split(",")).collect(Collectors.toList()));
requestParam.setDueDateStart(dueDateStart);
requestParam.setDueDateEnd(dueDateEnd);
requestParam.setBillType(billType);
requestParam.setDraftSourceList(draftSourceList==null ? null :Arrays.stream(draftSourceList.split(",")).collect(Collectors.toList()));
requestParam.setHoldBankTypeList(holdBankTypeList==null ? null :Arrays.stream(holdBankTypeList.split(",")).collect(Collectors.toList()));
requestParam.setHoldSignDateStart(holdSignDateStart);
requestParam.setHoldSignDateEnd(holdSignDateEnd);
requestParam.setDraftNbr(draftNbr);
requestParam.setBillNbr(billNbr);
requestParam.setBillAmountStart(billAmountStart);
requestParam.setBillAmountEnd(billAmountEnd);
requestParam.setSubBillIntervalStart(subBillIntervalStart);
requestParam.setSubBillIntervalEnd(subBillIntervalEnd);
requestParam.setBillStsList(billStsList==null ? null :Arrays.stream(billStsList.split(",")).collect(Collectors.toList()));
requestParam.setBillTrsStsList(billTrsStsList==null ? null :Arrays.stream(billTrsStsList.split(",")).collect(Collectors.toList()));
requestParam.setStockFlag(stockFlag);
requestParam.setOutInvType(outInvType);
requestParam.setLockFlag(lockFlag);
//查询前1000条数据
BillManagementClient bailManagementClient = new BillManagementClient();
GetDtaResponse response = bailManagementClient.dtaQuery(requestParam);
List<GetDtaResponse.Detail> list = response.getData().getList();
//判断是否还存在数据,递归查询
boolean hasNextPage = response.getData().isHasNextPage();
int nextPage = response.getData().getNextPage();
while (hasNextPage) {
requestParam.setCurrentPage(nextPage);
GetDtaResponse nextPageResponse = bailManagementClient.dtaQuery(requestParam);
List<GetDtaResponse.Detail> pageData = nextPageResponse.getData().getList();
list.addAll(pageData);
hasNextPage = nextPageResponse.getData().isHasNextPage();
nextPage = nextPageResponse.getData().getNextPage();
}
//加载cbs配置
XStream xStream = new XStream();
String resource = GCONST.getRootPath() + "WEB-INF" + File.separatorChar + "CBS2ECConfig.xml";
File file = new File(resource);
xStream.addPermission(AnyTypePermission.ANY);
xStream.processAnnotations(EBS2ECConfig.class);
EBS2ECConfig dto = (EBS2ECConfig) xStream.fromXML(file);
EBS2ECConfig.Table table = dto.getTables().get(2);
Integer modeId = table.getModeId();
String tableName = table.getKey();
//获取已存在的数据
EBS2ECConfig.Table.Field uniqueField = table.getFields().stream().filter(EBS2ECConfig.Table.Field::isUnique).findFirst().orElse(null);
if (uniqueField == null) {
throw new CBS8RunTimeException("未设置唯一标识字段");
}
String uniqueKey = uniqueField.getKey();
String uniqueEbsKey = uniqueField.getEbsKey();
List<String> uniqueDataKeys = getSQLMapper().listString(String.format("select %s from %s", uniqueKey, tableName));
for (GetDtaResponse.Detail detail : list) {
Map<String, String> detailMap = JsonUtil.parseMap(detail, String.class);
String uniqueData = detailMap.get(uniqueEbsKey);
if (StrUtil.isBlank(uniqueData)) {
log.warn("跳过cbs票据池数据唯一标识返回空,uniqueKey:{},uniqueEbsKey:{}", uniqueKey, uniqueEbsKey);
continue;
}
if (uniqueDataKeys.contains(uniqueData)) {
log.warn("跳过cbs票据池数据数据已存在,uniqueKey:{},uniqueEbsKey:{},值{}", uniqueKey, uniqueEbsKey, uniqueData);
continue;
}
List<String> fields = new ArrayList<String>() {{
add("formmodeid");
add("modedatacreater");
add("modedatacreatertype");
add("modedatacreatedate");
add("modedatacreatetime");
}};
String currDate = TimeUtil.getCurrentDateString();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
String currTime = sdf.format(new Date());
List<Object> values = new ArrayList<Object>() {{
add(modeId);
add(1);
add(0);
add(String.format("'%s'", currDate));
add(String.format("'%s'", currTime));
}};
for (EBS2ECConfig.Table.Field field : table.getFields()) {
//数据库字段
String fieldName = field.getKey();
fields.add(fieldName);
// 接口值
String value = detailMap.getOrDefault(field.getEbsKey(), "");
values.add(String.format("'%s'", value));
}
//业务逻辑字段,收款类型
fields.add("pjlx");
//应付票据
Integer pjlx;
if ("ISS".equals(detail.getBillVariety())) {
pjlx = 2;
} else {
//应收票据 0银承 1商承
pjlx = "AC01".equals(detail.getBillType()) ? 0 : 1;
}
values.add(pjlx);
String sql = String.format("insert into %s (%s) values (%s)", tableName, String.join(",", fields), values.stream().map(Object::toString).collect(Collectors.joining(",")));
RecordSet rs = new RecordSet();
rs.execute(sql);
if (modeId != null) {
rs.executeQuery("select max(id) from " + tableName);
int mainId = 0;
if (rs.next()) {
mainId = rs.getInt(1);
}
ModeRightInfo ModeRightInfo = new ModeRightInfo();
ModeRightInfo.setNewRight(true);
ModeRightInfo.editModeDataShare(1, modeId, mainId);
}
}
} catch (Exception e) {
log.error("获取CBS票据池数据失败", e);
throw new CBS8RunTimeException("获取CBS票据池数据失败," + e.getMessage(), e);
}
}
}

@ -0,0 +1,344 @@
package com.engine.salary.timer;
import cn.hutool.core.util.StrUtil;
import com.engine.salary.exception.CBS8RunTimeException;
import com.engine.salary.mapper.SQLMapper;
import com.engine.salary.mapper.cbs.UfHkrdzbMapper;
import com.engine.salary.remote.cbs8.client.BillManagementClient;
import com.engine.salary.remote.cbs8.config.EBS2ECConfig;
import com.engine.salary.remote.cbs8.po.UfHkrdzbPO;
import com.engine.salary.remote.cbs8.request.GetDtaRequest;
import com.engine.salary.remote.cbs8.response.GetDtaResponse;
import com.engine.salary.remote.cbs8.JsonUtil;
import com.engine.salary.remote.cbs8.SalaryEntityUtil;
import com.engine.salary.remote.cbs8.util.db.MapperProxyFactory;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.security.AnyTypePermission;
import lombok.extern.slf4j.Slf4j;
import weaver.conn.RecordSet;
import weaver.formmode.setup.ModeRightInfo;
import weaver.general.GCONST;
import weaver.general.TimeUtil;
import weaver.hrm.User;
import weaver.interfaces.schedule.BaseCronJob;
import java.io.File;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
/**
*
* <p>Copyright: Copyright (c) 2024</p>
* <p>Company: </p>
*
* @author qiantao
* @version 1.0
**/
@Slf4j
public class SyncCBSPayDetailsJob extends BaseCronJob {
/**
* cbs>>
*/
private String displayHoldOrganizationCodeList;
/**
*
*/
private String holdAccountList;
/**
* 4.1.3--4.1.34.1.44.1.5
*/
private String billVarietyList;
/**
* yyyy-mm-dd
*/
private String issueDateStart;
/**
* yyyy-mm-dd
*/
private String issueDateEnd;
/**
* yyyy-mm-dd
*/
private String dueDateStart;
/**
* yyyy-mm-dd
*/
private String dueDateEnd;
/**
* AC01-AC02-
*/
private String billType;
/**
* 1-2-3-4-5-
*/
private String draftSourceList;
/**
* 4.1.1.
*/
private String holdBankTypeList;
/**
* yyyy-mm-dd
*/
private String holdSignDateStart;
/**
* yyyy-mm-dd
*/
private String holdSignDateEnd;
/**
*
*/
private String draftNbr;
/**
* ()
*/
private String billNbr;
/**
* 0,13
*/
private BigDecimal billAmountStart;
/**
* 0,13
*/
private BigDecimal billAmountEnd;
/**
* 12
*/
private String subBillIntervalStart;
/**
* ,12
*/
private String subBillIntervalEnd;
/**
*
*/
private String billStsList;
/**
*
*/
private String billTrsStsList;
/**
* 1-2-
*/
private String stockFlag;
/**
* 0-2-3-4-5-6-7-, 8-
*/
private String outInvType;
/**
* NOR-USE-DEL- SUC-
*/
private String lockFlag;
private SQLMapper getSQLMapper() {
return MapperProxyFactory.getProxy(SQLMapper.class);
}
private UfHkrdzbMapper getUfHkrdzbMapper() {
return MapperProxyFactory.getProxy(UfHkrdzbMapper.class);
}
@Override
public void execute() {
User user = new User();
user.setUid(1);
user.setLoginid("sysadmin");
try {
GetDtaRequest requestParam = new GetDtaRequest();
requestParam.setCurrentPage(1);
requestParam.setPageSize(1000);
if (StrUtil.isBlank(displayHoldOrganizationCodeList)) {
throw new CBS8RunTimeException("持票人单位编码为空,请在计划任务配置此项!");
}
requestParam.setDisplayHoldOrganizationCodeList(Arrays.stream(displayHoldOrganizationCodeList.split(",")).collect(Collectors.toList()));
if (StrUtil.isBlank(holdAccountList)) {
throw new CBS8RunTimeException("持票人账号为空,请在计划任务配置此项!");
}
requestParam.setHoldAccountList(Arrays.stream(holdAccountList.split(",")).collect(Collectors.toList()));
if (StrUtil.isNotBlank(issueDateStart) && StrUtil.isNotBlank(issueDateEnd)) {
requestParam.setIssueDateStart(issueDateStart);
requestParam.setIssueDateEnd(issueDateEnd);
} else {
String nowDate = LocalDate.now().toString();
requestParam.setIssueDateStart(nowDate);
requestParam.setIssueDateEnd(nowDate);
}
//系统票据类型
requestParam.setBillVarietyList(Arrays.stream(billVarietyList.split(",")).collect(Collectors.toList()));
requestParam.setDueDateStart(dueDateStart);
requestParam.setDueDateEnd(dueDateEnd);
requestParam.setBillType(billType);
requestParam.setDraftSourceList(draftSourceList==null ? null :Arrays.stream(draftSourceList.split(",")).collect(Collectors.toList()));
requestParam.setHoldBankTypeList(holdBankTypeList==null ? null :Arrays.stream(holdBankTypeList.split(",")).collect(Collectors.toList()));
requestParam.setHoldSignDateStart(holdSignDateStart);
requestParam.setHoldSignDateEnd(holdSignDateEnd);
requestParam.setDraftNbr(draftNbr);
requestParam.setBillNbr(billNbr);
requestParam.setBillAmountStart(billAmountStart);
requestParam.setBillAmountEnd(billAmountEnd);
requestParam.setSubBillIntervalStart(subBillIntervalStart);
requestParam.setSubBillIntervalEnd(subBillIntervalEnd);
requestParam.setBillStsList(billStsList==null ? null :Arrays.stream(billStsList.split(",")).collect(Collectors.toList()));
requestParam.setBillTrsStsList(billTrsStsList==null ? null :Arrays.stream(billTrsStsList.split(",")).collect(Collectors.toList()));
requestParam.setStockFlag(stockFlag);
requestParam.setOutInvType(outInvType);
requestParam.setLockFlag(lockFlag);
//查询前1000条数据
BillManagementClient bailManagementClient = new BillManagementClient();
GetDtaResponse response = bailManagementClient.dtaQuery(requestParam);
List<GetDtaResponse.Detail> list = response.getData().getList();
//判断是否还存在数据,递归查询
boolean hasNextPage = response.getData().isHasNextPage();
int nextPage = response.getData().getNextPage();
while (hasNextPage) {
requestParam.setCurrentPage(nextPage);
GetDtaResponse nextPageResponse = bailManagementClient.dtaQuery(requestParam);
List<GetDtaResponse.Detail> pageData = nextPageResponse.getData().getList();
list.addAll(pageData);
hasNextPage = nextPageResponse.getData().isHasNextPage();
nextPage = nextPageResponse.getData().getNextPage();
}
//加载cbs配置
XStream xStream = new XStream();
String resource = GCONST.getRootPath() + "WEB-INF" + File.separatorChar + "CBS2ECConfig.xml";
File file = new File(resource);
xStream.addPermission(AnyTypePermission.ANY);
xStream.processAnnotations(EBS2ECConfig.class);
EBS2ECConfig dto = (EBS2ECConfig) xStream.fromXML(file);
EBS2ECConfig.Table table = dto.getTables().get(1);
Integer modeId = table.getModeId();
String tableName = table.getKey();
//获取已存在的数据
EBS2ECConfig.Table.Field uniqueField = table.getFields().stream().filter(EBS2ECConfig.Table.Field::isUnique).findFirst().orElse(null);
if (uniqueField == null) {
throw new CBS8RunTimeException("未设置唯一标识字段");
}
String uniqueKey = uniqueField.getKey();
String uniqueEbsKey = uniqueField.getEbsKey();
List<String> uniqueDataKeys = getSQLMapper().listString(String.format("select %s from %s", uniqueKey, tableName));
//获取汇款人与办事处的对照数据
List<UfHkrdzbPO> ufHkrdzbPOS = getUfHkrdzbMapper().listAll();
Map<String, Integer> customerDepartmentMap = SalaryEntityUtil.convert2Map(ufHkrdzbPOS, UfHkrdzbPO::getKhmc, UfHkrdzbPO::getDepartmentId);
for (GetDtaResponse.Detail detail : list) {
Map<String, String> detailMap = JsonUtil.parseMap(detail, String.class);
String uniqueData = detailMap.get(uniqueEbsKey);
if (StrUtil.isBlank(uniqueData)) {
log.warn("跳过cbs票据收款数据唯一标识返回空,uniqueKey:{},uniqueEbsKey:{}", uniqueKey, uniqueEbsKey);
continue;
}
if (uniqueDataKeys.contains(uniqueData)) {
log.warn("跳过cbs票据收款数据数据已存在,uniqueKey:{},uniqueEbsKey:{},值{}", uniqueKey, uniqueEbsKey, uniqueData);
continue;
}
List<String> fields = new ArrayList<String>() {{
add("formmodeid");
add("modedatacreater");
add("modedatacreatertype");
add("modedatacreatedate");
add("modedatacreatetime");
}};
String currDate = TimeUtil.getCurrentDateString();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
String currTime = sdf.format(new Date());
List<Object> values = new ArrayList<Object>() {{
add(modeId);
add(1);
add(0);
add(String.format("'%s'", currDate));
add(String.format("'%s'", currTime));
}};
String hkr = "";
for (EBS2ECConfig.Table.Field field : table.getFields()) {
//数据库字段
String fieldName = field.getKey();
fields.add(fieldName);
// 接口值
String value = detailMap.getOrDefault(field.getEbsKey(), "");
values.add(String.format("'%s'", value));
//汇款人
if ("hkr".equals(fieldName)) {
hkr = value;
}
}
//业务逻辑字段,收款类型
fields.add("sklx");
//应收票据 0银承 1商承
values. add("AC01".equals(detail.getBillType()) ? 0 : 1);
/*
*
*
*
*
*/
Integer departmentId = customerDepartmentMap.get(hkr);
if(departmentId!=null){
//认领
fields.add("zt");
values.add(1);
//是否系统认领
fields.add("sfxtzdrl");
values.add(1);
//办事处
fields.add("szbm");
values.add(departmentId);
}else {
//未认领
fields.add("zt");
values.add(0);
}
String sql = String.format("insert into %s (%s) values (%s)", tableName, String.join(",", fields), values.stream().map(Object::toString).collect(Collectors.joining(",")));
RecordSet rs = new RecordSet();
rs.execute(sql);
if (modeId != null) {
rs.executeQuery("select max(id) from " + tableName);
int mainId = 0;
if (rs.next()) {
mainId = rs.getInt(1);
}
ModeRightInfo ModeRightInfo = new ModeRightInfo();
ModeRightInfo.setNewRight(true);
ModeRightInfo.editModeDataShare(1, modeId, mainId);
}
}
} catch (Exception e) {
log.error("获取CBS票据收款数据失败", e);
throw new CBS8RunTimeException("获取CBS票据收款数据信息失败," + e.getMessage(), e);
}
}
}
Loading…
Cancel
Save