From 0a7bdc4334b2ba2281d0701d352b220dbe81ff69 Mon Sep 17 00:00:00 2001 From: mzr Date: Mon, 25 Aug 2025 09:33:49 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E5=85=B6=E5=AE=83=E4=BB=93?= =?UTF-8?q?=E5=BA=93=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/uapbd/wms/utils/IWmsSyncUtils.java | 42 +++ .../api/uapbd/wms/utils/WmsSyncUtils.java | 337 ++++++++++++++++++ 2 files changed, 379 insertions(+) create mode 100644 uapbd/src/public/nccloud/api/uapbd/wms/utils/IWmsSyncUtils.java create mode 100644 uapbd/src/public/nccloud/api/uapbd/wms/utils/WmsSyncUtils.java diff --git a/uapbd/src/public/nccloud/api/uapbd/wms/utils/IWmsSyncUtils.java b/uapbd/src/public/nccloud/api/uapbd/wms/utils/IWmsSyncUtils.java new file mode 100644 index 0000000..fc31a2e --- /dev/null +++ b/uapbd/src/public/nccloud/api/uapbd/wms/utils/IWmsSyncUtils.java @@ -0,0 +1,42 @@ +package nccloud.api.uapbd.wms.utils; + +import com.alibaba.fastjson.JSONObject; +import nc.vo.pub.BusinessException; + +import java.util.Map; + +public interface IWmsSyncUtils { + /** + * @param method WMS方法名 如:putASN、cancelASN等 + * @param json 入参 + */ + public String callWMS(String method, JSONObject json) throws BusinessException; + + /** + * 发送数据到外部系统 + */ + public void sendToExternalSystem(String method, Map requestData) throws BusinessException; + + public boolean checkIfExcludeUser(); + + public boolean checkIfIncludeOrg(String code) throws BusinessException; + + public String transferCodeByPk(String tableName, String selectField, String pkField, String pk) throws BusinessException; + + /** + * 根据主键查询字段值(允许为空) + * + * @param tableName 表名 + * @param selectField 查询字段 + * @param pkField 主键字段 + * @param pk 主键值 + * @return 查询结果,如果未查询到或字段值为空则返回null + */ + public String transferFieldByPkAllowNull(String tableName, String selectField, String pkField, String pk); + + /* + * 是否是WMS系统在同步 + * @return true:是 + */ + boolean isWMS(); +} \ No newline at end of file diff --git a/uapbd/src/public/nccloud/api/uapbd/wms/utils/WmsSyncUtils.java b/uapbd/src/public/nccloud/api/uapbd/wms/utils/WmsSyncUtils.java new file mode 100644 index 0000000..46f3d55 --- /dev/null +++ b/uapbd/src/public/nccloud/api/uapbd/wms/utils/WmsSyncUtils.java @@ -0,0 +1,337 @@ +package nccloud.api.uapbd.wms.utils; + +import com.alibaba.fastjson.JSONObject; +import nc.bs.dao.BaseDAO; +import nc.bs.framework.common.InvocationInfoProxy; +import nc.bs.framework.common.RuntimeEnv; +import nc.bs.logging.Log; +import nc.itf.arap.goldentax.SysParaInitQuery; +import nc.jdbc.framework.processor.ColumnProcessor; +import nc.uap.lfw.core.log.LfwLogger; +import nc.vo.am.common.util.StringUtils; +import nc.vo.pub.BusinessException; +import nc.vo.pubapp.pattern.pub.SqlBuilder; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.apache.tomcat.util.http.fileupload.IOUtils; +import uap.mw.trans.TransactionFactory; +import uap.mw.trans.UAPTransactionManagerProxy; +import uap.mw.trans.itf.IUAPTransactionManager; +import uap.mw.trans.util.TransactionContextType; + +import java.io.*; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +public class WmsSyncUtils implements IWmsSyncUtils { + + public static final BaseDAO dao = new BaseDAO(); + private static final Log log = Log.getInstance("wmslog"); + + public static Properties loadPropertie(String fileName) throws BusinessException { + Properties nodeProps = null; + InputStream input = null; + InputStreamReader inputReader = null; + try { + String homepath = RuntimeEnv.getInstance().getNCHome() + File.separator; + String filepath = "resources" + File.separator + fileName.replace(".", File.separator) + ".properties"; + File file = new File(homepath + filepath); + if (!file.exists()) + throw new BusinessException(filepath + "文件不存在,请检查"); + input = new FileInputStream(homepath + filepath); + nodeProps = new Properties(); + inputReader = new InputStreamReader(input, StandardCharsets.UTF_8); + nodeProps.load(inputReader); + } catch (IOException e) { + LfwLogger.error(e.getMessage(), e); + } finally { + IOUtils.closeQuietly(inputReader); + IOUtils.closeQuietly(input); + } + return nodeProps; + } + + /** + * 获取WMS配置信息 + * + * @return WMS配置信息 + */ + private Map getWmsConfig() throws BusinessException { + Map config = new HashMap<>(); + try { + // 从配置文件读取WMS配置 + Properties props = loadPropertie("wms.FlusWmsConfig"); + if (props != null) { + config.put("wmsIp", props.getProperty("wms.ip", "http://172.168.16.212:18080")); + config.put("baseUrl", props.getProperty("wms.baseUrl", "/datahubjson/FluxWmsJsonApi/")); + config.put("format", props.getProperty("wms.format", "json")); + config.put("apptoken", props.getProperty("wms.apptoken", "97EE89DA3DC642C22EAD5C33597DC903")); + config.put("sign", props.getProperty("wms.sign", "1")); + config.put("baseUrlQc", props.getProperty("wms.baseUrlQc", "/datahubjson/TK_BIP/")); + } else { + throw new BusinessException("未找到wms.FlusWmsConfig.properties文件"); + } + } catch (Exception e) { + log.error("读取WMS配置文件失败:" + e.getMessage(), e); + throw new BusinessException("读取WMS配置文件失败:" + e.getMessage()); + } + return config; + } + + @Override + public String callWMS(String method, JSONObject json) throws BusinessException { + String wmsUrl = buildUrl(method); + Map headers = new HashMap<>(); + headers.put("Content-Type", "application/json;charset=UTF-8"); + return doPost(wmsUrl, headers, json); + } + + /** + * 构造WMS请求URL + * + * @param method WMS方法名 + * @return 完整的请求URL + */ + private String buildUrl(String method) throws BusinessException { + Map config = getWmsConfig(); + String wmsIp = config.get("wmsIp"); + String baseUrl = config.get("baseUrl"); + String format = config.get("format"); + String apptoken = config.get("apptoken"); + String sign = config.get("sign"); + String baseUrlQc = config.get("baseUrlQc"); + + if (wmsIp == null || wmsIp.isEmpty()) { + throw new RuntimeException("未配置WMS服务器地址"); + } + + // 报检单单独一个地址 + if ("TK_BIP_QC_ORDER".equals(method)) { + return wmsIp + "/" + baseUrlQc + "?method=" + method; + } + + // 生成时间戳 + String timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); + + try { + // 构造URL参数 + StringBuilder urlBuilder = new StringBuilder(wmsIp); + if (!wmsIp.endsWith("/")) { + urlBuilder.append("/"); + } + urlBuilder.append(baseUrl.substring(1)); + urlBuilder.append("?method=").append(URLEncoder.encode(method, StandardCharsets.UTF_8)); + urlBuilder.append("&format=").append(URLEncoder.encode(format, StandardCharsets.UTF_8)); + urlBuilder.append("&apptoken=").append(URLEncoder.encode(apptoken, StandardCharsets.UTF_8)); + urlBuilder.append("×tamp=").append(URLEncoder.encode(timestamp, StandardCharsets.UTF_8)); + urlBuilder.append("&sign=").append(URLEncoder.encode(sign, StandardCharsets.UTF_8)); + + return urlBuilder.toString(); + } catch (Exception e) { + throw new RuntimeException("构造WMS请求URL失败: " + e.getMessage(), e); + } + } + + @Override + public void sendToExternalSystem(String method, Map requestData) throws BusinessException { + try { + log.debug("WMS请求方法:" + method + ",请求数据:" + JSONObject.toJSONString(requestData)); + JSONObject jsonRequest = new JSONObject(requestData); + + String response = callWMS(method, jsonRequest); + JSONObject jsonResponse = JSONObject.parseObject(response); + log.debug("WMS接口返回:" + jsonResponse.toJSONString()); + + // 解析新的WMS响应格式 + parseWmsResponse(jsonResponse); + + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException("调用WMS接口失败:" + e.getMessage(), e); + } + } + + /** + * 解析WMS响应 + * + * @param jsonResponse WMS返回的JSON响应 + * @throws BusinessException 业务异常 + */ + private void parseWmsResponse(JSONObject jsonResponse) throws BusinessException { + if (!jsonResponse.containsKey("Response")) { + throw new BusinessException("WMS响应格式错误:缺少Response节点"); + } + + JSONObject response = jsonResponse.getJSONObject("Response"); + if (!response.containsKey("return")) { + throw new BusinessException("WMS响应格式错误:缺少return节点"); + } + + JSONObject returnObj = response.getJSONObject("return"); + String returnFlag = returnObj.getString("returnFlag"); + String returnCode = returnObj.getString("returnCode"); + String returnDesc = returnObj.getString("returnDesc"); + + // returnFlag: 1-成功, 2-失败 + if (!"1".equals(returnFlag)) { + StringBuilder errorMsg = new StringBuilder("向WMS发起同步失败:"); + errorMsg.append("返回码:").append(returnCode); + errorMsg.append(",描述:").append(returnDesc); + + // 检查是否有详细错误信息 + if (returnObj.containsKey("resultInfo")) { + com.alibaba.fastjson.JSONArray resultInfo = returnObj.getJSONArray("resultInfo"); + if (resultInfo != null && !resultInfo.isEmpty()) { + errorMsg.append(",详细错误:"); + for (int i = 0; i < resultInfo.size(); i++) { + JSONObject errorItem = resultInfo.getJSONObject(i); + errorMsg.append("[doc:").append(errorItem.getString("docNo")) + .append(",错误码:").append(errorItem.getString("errorcode")) + .append(",错误描述:").append(errorItem.getString("errordescr")).append("]"); + if (i < resultInfo.size() - 1) { + errorMsg.append(";"); + } + } + } + } + + throw new BusinessException(errorMsg.toString()); + } + } + + /** + * 检查当前用户是否需要跳过同步 + */ + @Override + public boolean checkIfExcludeUser() { + return false; + } + + @Override + public boolean checkIfIncludeOrg(String code) throws BusinessException { + String targetCode = SysParaInitQuery.getParaString("GLOBLE00000000000000", "WMSORG"); + if (targetCode == null || StringUtils.isEmpty(targetCode)) { + throw new BusinessException("未配置组织参数,请前往 [业务参数设置-全局] 配置WMSORG 参数"); + } + String[] orgItem = targetCode.split(";"); + for (String orgCode : orgItem) { + if (!orgCode.isEmpty() && orgCode.equals(code)) { + log.debug("当前处理组织校验为WMS可同步:" + code); + return true; + } + } + return false; + } + + + /** + * 业务请求post方法 + */ + private String doPost(String url, Map headers, JSONObject jsonPayload) { + try (CloseableHttpClient httpClient = HttpClients.createDefault()) { + HttpPost httpPost = new HttpPost(url); + + // 设置标准请求头 + httpPost.setHeader("Content-Type", "application/json;charset=UTF-8"); + + // 设置自定义请求头 + if (headers != null) { + for (Map.Entry entry : headers.entrySet()) { + httpPost.setHeader(entry.getKey(), entry.getValue()); + } + } + + if (jsonPayload != null) { + StringEntity stringEntity = new StringEntity(jsonPayload.toJSONString(), "UTF-8"); + httpPost.setEntity(stringEntity); + } + + try (CloseableHttpResponse response = httpClient.execute(httpPost)) { + HttpEntity entity = response.getEntity(); + String responseString = EntityUtils.toString(entity, "UTF-8"); + return responseString; + } + } catch (IOException e) { + throw new RuntimeException("HTTP POST 请求到 " + url + " 失败: " + e.getMessage(), e); + } + } + + /** + * 根据主键查询编码 + */ + public String transferCodeByPk(String tableName, String selectField, String pkField, String pk) throws BusinessException { + if (pk == null || pk.trim().isEmpty()) { + log.warn("未传入主键信息,无法查询编码:" + pkField + ":" + tableName + ":" + selectField); + return null; + } + SqlBuilder sqlBuilder = new SqlBuilder(); + sqlBuilder.append(" select " + selectField); + sqlBuilder.append(" from " + tableName); + sqlBuilder.append(" where "); + sqlBuilder.append(pkField, pk); + Object o = dao.executeQuery(sqlBuilder.toString(), new ColumnProcessor()); + if (o == null) { + throw new BusinessException("未查询到编码信息,sql【" + sqlBuilder + "】"); + } + return o.toString(); + } + + /** + * 根据主键查询字段值(允许为空) + * + * @param tableName 表名 + * @param selectField 查询字段 + * @param pkField 主键字段 + * @param pk 主键值 + * @return 查询结果,如果未查询到或字段值为空则返回null + */ + public String transferFieldByPkAllowNull(String tableName, String selectField, String pkField, String pk) { + if (pk == null || pk.trim().isEmpty()) { + log.debug("未传入主键信息,无法查询字段值:" + pkField + ":" + tableName + ":" + selectField); + return null; + } + try { + SqlBuilder sqlBuilder = new SqlBuilder(); + sqlBuilder.append(" select " + selectField); + sqlBuilder.append(" from " + tableName); + sqlBuilder.append(" where "); + sqlBuilder.append(pkField, pk); + Object o = dao.executeQuery(sqlBuilder.toString(), new ColumnProcessor()); + if (o == null) { + log.debug("未查询到字段值或字段值为空,sql【" + sqlBuilder + "】"); + return null; + } + String result = o.toString(); + // 如果字段值为空字符串,也返回null + if (result.trim().isEmpty()) { + log.debug("查询到的字段值为空字符串,表:" + tableName + ",字段:" + selectField + ",主键:" + pk); + return null; + } + return result; + } catch (Exception e) { + log.warn("查询字段值失败:" + e.getMessage() + ",表:" + tableName + ",字段:" + selectField + ",主键:" + pk); + return null; + } + } + + @Override + public boolean isWMS() { + String code = InvocationInfoProxy.getInstance().getUserCode(); + return code != null && code.equals("WMS"); + } + + public static void fillOutBillsInfo() { + return; + } +}