test dockerfile

This commit is contained in:
2025-11-18 08:51:29 +08:00
parent dda1a4935a
commit 7b76a4d2f7
5 changed files with 3280 additions and 61 deletions

View File

@@ -5,12 +5,18 @@ FROM docker.aipper.de/eclipse-temurin:8-jre-alpine AS base
# 设置维护者信息
LABEL maintainer="digital-archive-team"
# 使用阿里云镜像源并安装最小基础包
# 使用阿里云镜像源并安装基础包包含OCR和字体支持
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
apk add --no-cache \
ca-certificates \
curl \
bash \
ttf-dejavu \
fontconfig \
tini \
tesseract-ocr \
tesseract-ocr-data-chi_sim \
tesseract-ocr-data-eng \
&& rm -rf /var/cache/apk/*
# ===== Maven 构建阶段 =====
@@ -133,6 +139,8 @@ FROM base
# 设置环境变量(优化内存使用)
ENV JAVA_OPTS="-Xmx512m -Xms256m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -Djava.awt.headless=true -XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0"
ENV SPRING_PROFILES_ACTIVE=prod
ENV TESSDATA_PREFIX=/usr/share/tessdata/
ENV OCR_TESSPATH=/usr/bin/tesseract
# 创建应用用户和目录
RUN addgroup -g 1001 app && \

View File

@@ -33,12 +33,6 @@ services:
networks:
- proxy
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9081/point-strategy/actuator/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
networks:
proxy:
external: true

View File

@@ -141,6 +141,117 @@ public class ArchivesUploadController {
}
}
// SQL 值格式化:数值型为空用 NULL字符型加引号空用 ''
private static String toSqlValue(Object value, boolean numeric) {
if (value == null) return numeric ? "NULL" : "''";
if (numeric) return String.valueOf(value);
String s = String.valueOf(value).replace("'", "''");
return "'" + s + "'";
}
// 在销/退出/进销存/终端建设 统一字段顺序1-100的数值型列索引用于默认填充
private static final java.util.Set<Integer> SALES_NUMERIC_INDEX = new java.util.HashSet<>(
java.util.Arrays.asList(
7,8,9,10,12,14,16,18,19,22,23,24,
45,46,47,48,49,50,51,52,53,54,55,56,57,
58,59,60,61,62,63,64,65,66,67,68,69,70,
71,72,73,74,75,76
)
);
// 判断字符串是否为空白
private static boolean isBlank(String s) {
return s == null || s.trim().isEmpty();
}
// 有值才放入字符串非空白数字非null
private static void putIfHasData(java.util.Map<String, Object> m, String key, Object v) {
if (v == null) return;
if (v instanceof CharSequence) {
if (!isBlank(v.toString())) m.put(key, v.toString());
} else {
// 数值/时间等非空即存
m.put(key, v);
}
}
// 根据实际表结构过滤后生成动态列/值并保存
private void saveDynamicRow(String tempTableName, java.util.Map<String, Object> values) {
java.util.List<com.point.strategy.bean.TtableStructDescription> struct = null;
try {
struct = danganguanliService.danganguanliMapper.selectTableStruct(tempTableName);
} catch (Throwable ignore) {
}
java.util.Set<String> colSet = new java.util.HashSet<>();
if (struct != null) {
for (com.point.strategy.bean.TtableStructDescription d : struct) {
if (d != null && d.getColumnName() != null) colSet.add(d.getColumnName().toLowerCase());
}
}
java.util.Map<String, Object> filtered = new java.util.LinkedHashMap<>();
boolean hasMeta = !colSet.isEmpty();
for (java.util.Map.Entry<String, Object> e : values.entrySet()) {
String col = e.getKey();
Object v = e.getValue();
if (hasMeta) {
if (colSet.contains(col.toLowerCase())) filtered.put(col, v);
} else {
// 无元数据时先不过滤,后续失败再按报错剔除
filtered.put(col, v);
}
}
if (filtered.isEmpty()) return; // 无有效字段则不写入
// 失败重试若报列不存在剔除该列重试最多剔除10次防止循环
java.util.Map<String, Object> current = new java.util.LinkedHashMap<>(filtered);
for (int attempt = 0; attempt < 10 && !current.isEmpty(); attempt++) {
java.util.List<String> fields = new java.util.ArrayList<>();
java.util.List<String> vals = new java.util.ArrayList<>();
for (java.util.Map.Entry<String, Object> e : current.entrySet()) {
String col = e.getKey();
Object v = e.getValue();
fields.add("\"" + col + "\"");
boolean isNumeric = v instanceof java.lang.Number;
vals.add(toSqlValue(v, isNumeric));
}
String fieldName = String.join(",", fields);
String valueName = String.join(",", vals);
java.util.Map<String, Object> mapTwo = new java.util.HashMap<>();
mapTwo.put("tableName", tempTableName);
mapTwo.put("fieldName", fieldName);
mapTwo.put("valueName", valueName);
try {
danganguanliService.saveObject(mapTwo);
return; // 成功
} catch (Throwable ex) {
String msg = ex.getMessage() != null ? ex.getMessage() : "";
// 尝试解析缺失列名(兼容多种数据库报错格式)
String missing = null;
java.util.regex.Matcher m1 = java.util.regex.Pattern.compile("column \\\"([^\\\"]+)\\\" (does not exist|not found)", java.util.regex.Pattern.CASE_INSENSITIVE).matcher(msg);
if (m1.find()) missing = m1.group(1);
if (missing == null) {
java.util.regex.Matcher m2 = java.util.regex.Pattern.compile("column ([a-zA-Z0-9_]+) (does not exist|not found)", java.util.regex.Pattern.CASE_INSENSITIVE).matcher(msg);
if (m2.find()) missing = m2.group(1);
}
if (missing != null) {
// 按大小写不敏感从 current 中移除
String keyToRemove = null;
for (String k : current.keySet()) {
if (k.equalsIgnoreCase(missing)) { keyToRemove = k; break; }
}
if (keyToRemove != null) {
current.remove(keyToRemove);
continue; // 重试
}
}
// 其他错误或无法解析缺失列,直接抛出
throw ex;
}
}
}
/**
* 基于中文类型描述推断页码(公文用)
*/
@@ -1040,7 +1151,8 @@ public class ArchivesUploadController {
// 使用统一的sales表
String tableName = "sales_20251019171058";
String tempTableName = tableName+"_temp";
String fileTableName = tableName + "_file";
// 与合同对接保持一致:原文写入临时原文表
String fileTableName = tableName + "_temp_file";
// 统计四个表的总条数
String[] tableNames = {"cc_tbc_product_ez", "cc_tbc_drawout_ez", "scm_rpt_bizstordayreport_ez", "ec_exp_apply_accept_ez"};
@@ -1271,44 +1383,57 @@ public class ArchivesUploadController {
out_begin_date = nvl(resultSet.getString("out_begin_date"));
maintitle = product_name;
// 使用产品ID作为批次号避免空串
recordId = product_uuid;
valueName = "''," +
"'" + product_code + "'," +
"'" + product_name + "'," +
"'" + factory_simple_name + "'," +
"'" + brand_name + "'," +
"'" + is_abnormity + "'," +
(length != null ? length : "NULL") + "," +
(width != null ? width : "NULL") + "," +
(height != null ? height : "NULL") + "," +
(tar_qty != null ? tar_qty : "NULL") + "," +
"'" + bar_code + "'," +
(package_qty != null ? package_qty : "NULL") + "," +
"'" + bar_code2 + "'," +
(package_qty2 != null ? package_qty2 : "NULL") + "," +
"'" + bar_code3 + "'," +
(package_qty3 != null ? package_qty3 : "NULL") + "," +
"'" + price_type_code + "'," +
(direct_whole_price != null ? direct_whole_price : "NULL") + "," +
(direct_retail_price != null ? direct_retail_price : "NULL") + "," +
"'" + is_province + "'," +
"'" + is_seized + "'," +
(adjust_price != null ? adjust_price : "NULL") + "," +
(retail_price != null ? retail_price : "NULL") + "," +
(whole_sale_price != null ? whole_sale_price : "NULL") + "," +
"'" + in_begin_date + "'," +
"'" + sale_begin_date + "'," +
"'" + out_begin_date + "'," +
"'','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','',''," +
"'" + fonds_no + "'," +
"'" + retention + "'," +
"'" + archive_ctg_no + "'," +
"'" + created_date + "'," +
"'" + maintitle + "'," +
"'" + responsibleby + "'," +
"'预归档未完成'," +
"'" + recordId + "'," +
"'" + sourceTable + "'";
// 按字段顺序组装100列严防列/值不匹配
String[] valsP = new String[100];
valsP[0] = toSqlValue(product_uuid, false);
valsP[1] = toSqlValue(product_code, false);
valsP[2] = toSqlValue(product_name, false);
valsP[3] = toSqlValue(factory_simple_name, false);
valsP[4] = toSqlValue(brand_name, false);
valsP[5] = toSqlValue(is_abnormity, false);
valsP[6] = toSqlValue(length, true);
valsP[7] = toSqlValue(width, true);
valsP[8] = toSqlValue(height, true);
valsP[9] = toSqlValue(tar_qty, true);
valsP[10] = toSqlValue(bar_code, false);
valsP[11] = toSqlValue(package_qty, true);
valsP[12] = toSqlValue(bar_code2, false);
valsP[13] = toSqlValue(package_qty2, true);
valsP[14] = toSqlValue(bar_code3, false);
valsP[15] = toSqlValue(package_qty3, true);
valsP[16] = toSqlValue(price_type_code, false);
valsP[17] = toSqlValue(direct_whole_price, true);
valsP[18] = toSqlValue(direct_retail_price, true);
valsP[19] = toSqlValue(is_province, false);
valsP[20] = toSqlValue(is_seized, false);
valsP[21] = toSqlValue(adjust_price, true);
valsP[22] = toSqlValue(retail_price, true);
valsP[23] = toSqlValue(whole_sale_price, true);
valsP[24] = toSqlValue(in_begin_date, false);
valsP[25] = toSqlValue(sale_begin_date, false);
valsP[26] = toSqlValue(out_begin_date, false);
// 元信息 92~100
valsP[91] = toSqlValue(fonds_no, false);
valsP[92] = toSqlValue(retention, false);
valsP[93] = toSqlValue(archive_ctg_no, false);
valsP[94] = toSqlValue(created_date, false);
valsP[95] = toSqlValue(maintitle, false);
valsP[96] = toSqlValue(responsibleby, false);
valsP[97] = toSqlValue("预归档未完成", false);
valsP[98] = toSqlValue(recordId, false);
valsP[99] = toSqlValue(sourceTable, false);
StringBuilder sbP = new StringBuilder();
for (int i = 1; i <= 100; i++) {
String v = valsP[i - 1];
if (v == null) v = SALES_NUMERIC_INDEX.contains(i) ? "NULL" : "''";
if (i > 1) sbP.append(',');
sbP.append(v);
}
valueName = sbP.toString();
} else if ("cc_tbc_drawout_ez".equals(sourceTable)) {
// 退出品规数据
@@ -1378,6 +1503,193 @@ public class ArchivesUploadController {
"'" + recordId + "'," +
"'" + sourceTable + "'";
// 构造100列进销存 36~76覆盖上面的拼接
{
String[] valsS = new String[100];
valsS[35] = toSqlValue(biz_date, false);
valsS[36] = toSqlValue(manage_unit_uuid, false);
valsS[37] = toSqlValue(stor_uuid, false);
valsS[38] = toSqlValue(stor_name, false);
valsS[39] = toSqlValue(product_uuid2, false);
valsS[40] = toSqlValue(product_code2, false);
valsS[41] = toSqlValue(product_name, false);
valsS[42] = toSqlValue(unit_uuid, false);
valsS[43] = toSqlValue(unit_name, false);
valsS[44] = toSqlValue(last_qty, true);
valsS[45] = toSqlValue(last_amount, true);
valsS[46] = toSqlValue(buy_qty, true);
valsS[47] = toSqlValue(buy_notax_amount, true);
valsS[48] = toSqlValue(buy_amount, true);
valsS[49] = toSqlValue(movein_qty, true);
valsS[50] = toSqlValue(movein_notax_amount, true);
valsS[51] = toSqlValue(movein_amount, true);
valsS[52] = toSqlValue(movein_cost, true);
valsS[53] = toSqlValue(moveout_qty, true);
valsS[54] = toSqlValue(moveout_notax_amount, true);
valsS[55] = toSqlValue(moveout_amount, true);
valsS[56] = toSqlValue(moveout_cost, true);
valsS[57] = toSqlValue(sale_qty, true);
valsS[58] = toSqlValue(sale_notax_amount, true);
valsS[59] = toSqlValue(sale_amount, true);
valsS[60] = toSqlValue(sale_cost, true);
valsS[61] = toSqlValue(sale_gross_profit, true);
valsS[62] = toSqlValue(allot_qty, true);
valsS[63] = toSqlValue(allot_notax_amount, true);
valsS[64] = toSqlValue(allot_amount, true);
valsS[65] = toSqlValue(allot_cost, true);
valsS[66] = toSqlValue(allot_gross_profit, true);
valsS[67] = toSqlValue(dec_qty, true);
valsS[68] = toSqlValue(dec_notax_amount, true);
valsS[69] = toSqlValue(dec_amount, true);
valsS[70] = toSqlValue(inc_qty, true);
valsS[71] = toSqlValue(inc_notax_amount, true);
valsS[72] = toSqlValue(inc_amount, true);
valsS[73] = toSqlValue(rest_qty, true);
valsS[74] = toSqlValue(rest_amount, true);
valsS[75] = toSqlValue(cost_price, true);
valsS[91] = toSqlValue(fonds_no, false);
valsS[92] = toSqlValue(retention, false);
valsS[93] = toSqlValue(archive_ctg_no, false);
valsS[94] = toSqlValue(created_date, false);
valsS[95] = toSqlValue(maintitle, false);
valsS[96] = toSqlValue(responsibleby, false);
valsS[97] = toSqlValue("预归档未完成", false);
valsS[98] = toSqlValue(recordId, false);
valsS[99] = toSqlValue(sourceTable, false);
StringBuilder sbS = new StringBuilder();
for (int i = 1; i <= 100; i++) {
String v = valsS[i - 1];
if (v == null) v = SALES_NUMERIC_INDEX.contains(i) ? "NULL" : "''";
if (i > 1) sbS.append(',');
sbS.append(v);
}
valueName = sbS.toString();
}
// 重新按位生成 100 列(终端建设 77~91覆盖上面的拼接
String[] valsE = new String[100];
valsE[76] = toSqlValue(depart_uuid, false);
valsE[77] = toSqlValue(depart_name, false);
valsE[78] = toSqlValue(saler_dept_uuid, false);
valsE[79] = toSqlValue(license_code, false);
valsE[80] = toSqlValue(cust_name, false);
valsE[81] = toSqlValue(address, false);
valsE[82] = toSqlValue(manage_person_name, false);
valsE[83] = toSqlValue(cust_type_name, false);
valsE[84] = toSqlValue(busi_place_code, false);
valsE[85] = toSqlValue(terminal_level_before, false);
valsE[86] = toSqlValue(terminal_level_after, false);
valsE[87] = toSqlValue(apply_remark, false);
valsE[88] = toSqlValue(deal_remark, false);
valsE[89] = toSqlValue(accept_status, false);
valsE[90] = toSqlValue(updator_name, false);
valsE[91] = toSqlValue(fonds_no, false);
valsE[92] = toSqlValue(retention, false);
valsE[93] = toSqlValue(archive_ctg_no, false);
valsE[94] = toSqlValue(created_date, false);
valsE[95] = toSqlValue(maintitle, false);
valsE[96] = toSqlValue(responsibleby, false);
valsE[97] = toSqlValue("预归档未完成", false);
valsE[98] = toSqlValue(recordId, false);
valsE[99] = toSqlValue(sourceTable, false);
StringBuilder sbE = new StringBuilder();
for (int i = 1; i <= 100; i++) {
String v = valsE[i - 1];
if (v == null) v = SALES_NUMERIC_INDEX.contains(i) ? "NULL" : "''";
if (i > 1) sbE.append(',');
sbE.append(v);
}
valueName = sbE.toString();
// 重新按位生成 100 列(进销存 36~76覆盖上面的拼接
String[] valsS = new String[100];
valsS[35] = toSqlValue(biz_date, false);
valsS[36] = toSqlValue(manage_unit_uuid, false);
valsS[37] = toSqlValue(stor_uuid, false);
valsS[38] = toSqlValue(stor_name, false);
valsS[39] = toSqlValue(product_uuid2, false);
valsS[40] = toSqlValue(product_code2, false);
valsS[41] = toSqlValue(product_name, false);
valsS[42] = toSqlValue(unit_uuid, false);
valsS[43] = toSqlValue(unit_name, false);
valsS[44] = toSqlValue(last_qty, true);
valsS[45] = toSqlValue(last_amount, true);
valsS[46] = toSqlValue(buy_qty, true);
valsS[47] = toSqlValue(buy_notax_amount, true);
valsS[48] = toSqlValue(buy_amount, true);
valsS[49] = toSqlValue(movein_qty, true);
valsS[50] = toSqlValue(movein_notax_amount, true);
valsS[51] = toSqlValue(movein_amount, true);
valsS[52] = toSqlValue(movein_cost, true);
valsS[53] = toSqlValue(moveout_qty, true);
valsS[54] = toSqlValue(moveout_notax_amount, true);
valsS[55] = toSqlValue(moveout_amount, true);
valsS[56] = toSqlValue(moveout_cost, true);
valsS[57] = toSqlValue(sale_qty, true);
valsS[58] = toSqlValue(sale_notax_amount, true);
valsS[59] = toSqlValue(sale_amount, true);
valsS[60] = toSqlValue(sale_cost, true);
valsS[61] = toSqlValue(sale_gross_profit, true);
valsS[62] = toSqlValue(allot_qty, true);
valsS[63] = toSqlValue(allot_notax_amount, true);
valsS[64] = toSqlValue(allot_amount, true);
valsS[65] = toSqlValue(allot_cost, true);
valsS[66] = toSqlValue(allot_gross_profit, true);
valsS[67] = toSqlValue(dec_qty, true);
valsS[68] = toSqlValue(dec_notax_amount, true);
valsS[69] = toSqlValue(dec_amount, true);
valsS[70] = toSqlValue(inc_qty, true);
valsS[71] = toSqlValue(inc_notax_amount, true);
valsS[72] = toSqlValue(inc_amount, true);
valsS[73] = toSqlValue(rest_qty, true);
valsS[74] = toSqlValue(rest_amount, true);
valsS[75] = toSqlValue(cost_price, true);
valsS[91] = toSqlValue(fonds_no, false);
valsS[92] = toSqlValue(retention, false);
valsS[93] = toSqlValue(archive_ctg_no, false);
valsS[94] = toSqlValue(created_date, false);
valsS[95] = toSqlValue(maintitle, false);
valsS[96] = toSqlValue(responsibleby, false);
valsS[97] = toSqlValue("预归档未完成", false);
valsS[98] = toSqlValue(recordId, false);
valsS[99] = toSqlValue(sourceTable, false);
StringBuilder sbS = new StringBuilder();
for (int i = 1; i <= 100; i++) {
String v = valsS[i - 1];
if (v == null) v = SALES_NUMERIC_INDEX.contains(i) ? "NULL" : "''";
if (i > 1) sbS.append(',');
sbS.append(v);
}
valueName = sbS.toString();
// 重新按位生成 100 列,覆盖上面的拼接,避免列数与值数不一致
String[] valsD = new String[100];
valsD[27] = toSqlValue(recordId, false);
valsD[28] = toSqlValue(org_name, false);
valsD[29] = toSqlValue(quit_uuid, false);
valsD[30] = toSqlValue(drawout_date, false);
valsD[31] = toSqlValue(quit_date, false);
valsD[32] = toSqlValue(comment, false);
valsD[33] = toSqlValue(creater_name, false);
valsD[34] = toSqlValue(syscreatedate, false);
valsD[91] = toSqlValue(fonds_no, false);
valsD[92] = toSqlValue(retention, false);
valsD[93] = toSqlValue(archive_ctg_no, false);
valsD[94] = toSqlValue(created_date, false);
valsD[95] = toSqlValue(maintitle, false);
valsD[96] = toSqlValue(responsibleby, false);
valsD[97] = toSqlValue("预归档未完成", false);
valsD[98] = toSqlValue(recordId, false);
valsD[99] = toSqlValue(sourceTable, false);
StringBuilder sbD = new StringBuilder();
for (int i = 1; i <= 100; i++) {
String v = valsD[i - 1];
if (v == null) v = SALES_NUMERIC_INDEX.contains(i) ? "NULL" : "''";
if (i > 1) sbD.append(',');
sbD.append(v);
}
valueName = sbD.toString();
} else if ("scm_rpt_bizstordayreport_ez".equals(sourceTable)) {
// 月度进销存数据
recordId = String.valueOf(resultSet.getLong("id"));
@@ -1480,14 +1792,46 @@ public class ArchivesUploadController {
"'" + recordId + "'," +
"'" + sourceTable + "'";
// 严格按位填充 100 列(退出品规 28~34
{
String[] valsD = new String[100];
valsD[27] = toSqlValue(recordId, false);
valsD[28] = toSqlValue(org_name, false);
valsD[29] = toSqlValue(quit_uuid, false);
valsD[30] = toSqlValue(drawout_date, false);
valsD[31] = toSqlValue(quit_date, false);
valsD[32] = toSqlValue(comment, false);
valsD[33] = toSqlValue(creater_name, false);
valsD[34] = toSqlValue(syscreatedate, false);
valsD[91] = toSqlValue(fonds_no, false);
valsD[92] = toSqlValue(retention, false);
valsD[93] = toSqlValue(archive_ctg_no, false);
valsD[94] = toSqlValue(created_date, false);
valsD[95] = toSqlValue(maintitle, false);
valsD[96] = toSqlValue(responsibleby, false);
valsD[97] = toSqlValue("预归档未完成", false);
valsD[98] = toSqlValue(recordId, false);
valsD[99] = toSqlValue(sourceTable, false);
StringBuilder sbD = new StringBuilder();
for (int i = 1; i <= 100; i++) {
String v = valsD[i - 1];
if (v == null) v = SALES_NUMERIC_INDEX.contains(i) ? "NULL" : "''";
if (i > 1) sbD.append(',');
sbD.append(v);
}
valueName = sbD.toString();
}
} else if ("ec_exp_apply_accept_ez".equals(sourceTable)) {
// 终端建设数据
recordId = nvl(resultSet.getString("accept_uuid"));
org_name = nvl(resultSet.getString("org_name"));
org_name2 = nvl(resultSet.getString("org_name2"));
depart_uuid = nvl(resultSet.getString("depart_uuid"));
depart_name = nvl(resultSet.getString("depart_name"));
saler_dept_uuid = nvl(resultSet.getString("saler_dept_uuid"));
// 源表 ec_exp_apply_accept_ez 不含 depart_uuid/depart_name/saler_dept_uuid(见 doc/1.md 的 DDL
// 按合同对接一致逻辑,这些目标字段留空(由后续流程/映射补齐)。
depart_uuid = "";
depart_name = "";
saler_dept_uuid = "";
license_code = nvl(resultSet.getString("license_code"));
cust_name = nvl(resultSet.getString("cust_name"));
address = nvl(resultSet.getString("address"));
@@ -1509,6 +1853,7 @@ public class ArchivesUploadController {
valueName = "'','','','','','','','','','','','','','','','','','','','','','','','',',," + // 在销品牌字段为空
"'','','','','',''," +
"'','','','','','','','','','','','','',''," +
"'','','','','','','','','','','','','','','','','','','','','','','','',',',''," +
"'" + depart_uuid + "'," +
"'" + depart_name + "'," +
"'" + saler_dept_uuid + "'," +
@@ -1534,6 +1879,43 @@ public class ArchivesUploadController {
"'预归档未完成'," +
"'" + recordId + "'," +
"'" + sourceTable + "'";
// 终端建设字段77~91按位填充
{
String[] valsE = new String[100];
valsE[76] = toSqlValue(depart_uuid, false);
valsE[77] = toSqlValue(depart_name, false);
valsE[78] = toSqlValue(saler_dept_uuid, false);
valsE[79] = toSqlValue(license_code, false);
valsE[80] = toSqlValue(cust_name, false);
valsE[81] = toSqlValue(address, false);
valsE[82] = toSqlValue(manage_person_name, false);
valsE[83] = toSqlValue(cust_type_name, false);
valsE[84] = toSqlValue(busi_place_code, false);
valsE[85] = toSqlValue(terminal_level_before, false);
valsE[86] = toSqlValue(terminal_level_after, false);
valsE[87] = toSqlValue(apply_remark, false);
valsE[88] = toSqlValue(deal_remark, false);
valsE[89] = toSqlValue(accept_status, false);
valsE[90] = toSqlValue(updator_name, false);
valsE[91] = toSqlValue(fonds_no, false);
valsE[92] = toSqlValue(retention, false);
valsE[93] = toSqlValue(archive_ctg_no, false);
valsE[94] = toSqlValue(created_date, false);
valsE[95] = toSqlValue(maintitle, false);
valsE[96] = toSqlValue(responsibleby, false);
valsE[97] = toSqlValue("预归档未完成", false);
valsE[98] = toSqlValue(recordId, false);
valsE[99] = toSqlValue(sourceTable, false);
StringBuilder sbE = new StringBuilder();
for (int i = 1; i <= 100; i++) {
String v = valsE[i - 1];
if (v == null) v = SALES_NUMERIC_INDEX.contains(i) ? "NULL" : "''";
if (i > 1) sbE.append(',');
sbE.append(v);
}
valueName = sbE.toString();
}
}
if (log.isInfoEnabled()) {
@@ -1542,19 +1924,140 @@ public class ArchivesUploadController {
// 幂等:优先检查是否已存在相同记录
Integer jhId;
boolean recordExists = false;
String whereSql = " 1=1 and batch_id='" + recordId + "' and table_name='" + sourceTable + "'";
if (existsInTemp(tempTableName, whereSql)) {
jhId = findSingleId(tempTableName, whereSql);
recordExists = true;
if (log.isDebugEnabled()) {
log.debug("[PRODUCT_SALES] 命中幂等: 复用已有记录 id={}, where={}", jhId, whereSql);
}
} else {
Map<String, Object> mapTwo = new HashMap<String, Object>();
mapTwo.put("tableName", tempTableName);
mapTwo.put("fieldName", "product_uuid,product_code1,product_name1,factory_simple_name,brand_name,is_abnormity,length,width,height,tar_qty,bar_code,package_qty,bar_code2,package_qty2,bar_code3,package_qty3,price_type_code,direct_whole_price,direct_retail_price,is_province,is_seized,adjust_price,retail_price,whole_sale_price,in_begin_date,sale_begin_date,out_begin_date,drawout_uuid,org_name,quit_uuid,drawout_date,quit_date,comment,creater_name,syscreatedate,biz_date,manage_unit_uuid,stor_uuid,stor_name,product_uuid2,product_code2,product_name2,unit_uuid,unit_name,last_qty,last_amount,buy_qty,buy_notax_amount,buy_amount,movein_qty,movein_notax_amount,movein_amount,movein_cost,moveout_qty,moveout_notax_amount,moveout_amount,moveout_cost,sale_qty,sale_notax_amount,sale_amount,sale_cost,sale_gross_profit,allot_qty,allot_notax_amount,allot_amount,allot_cost,allot_gross_profit,dec_qty,dec_notax_amount,dec_amount,inc_qty,inc_notax_amount,inc_amount,rest_qty,rest_amount,cost_price,depart_uuid,depart_name,saler_dept_uuid,license_code,cust_name,address,manage_person_name,cust_type_name,busi_place_code,terminal_level_before,terminal_level_after,apply_remark,deal_remark,accept_status,syscreatedate,updator_name,fonds_no,retention,archive_ctg_no,created_date,maintitle,responsibleby,archive_flag,batch_id,table_name");
mapTwo.put("valueName", valueName);
danganguanliService.saveObject(mapTwo);
jhId = Integer.parseInt(mapTwo.get("id").toString());
// 动态构造:有数据才存 + 仅存存在于目标表的列
Map<String, Object> values = new LinkedHashMap<>();
// 在销品牌
putIfHasData(values, "product_uuid", product_uuid);
putIfHasData(values, "product_code1", product_code);
putIfHasData(values, "product_name1", product_name);
putIfHasData(values, "factory_simple_name", factory_simple_name);
putIfHasData(values, "brand_name", brand_name);
putIfHasData(values, "is_abnormity", is_abnormity);
putIfHasData(values, "length", length);
putIfHasData(values, "width", width);
putIfHasData(values, "height", height);
putIfHasData(values, "tar_qty", tar_qty);
putIfHasData(values, "bar_code", bar_code);
putIfHasData(values, "package_qty", package_qty);
putIfHasData(values, "bar_code2", bar_code2);
putIfHasData(values, "package_qty2", package_qty2);
putIfHasData(values, "bar_code3", bar_code3);
putIfHasData(values, "package_qty3", package_qty3);
putIfHasData(values, "price_type_code", price_type_code);
putIfHasData(values, "direct_whole_price", direct_whole_price);
putIfHasData(values, "direct_retail_price", direct_retail_price);
putIfHasData(values, "is_province", is_province);
putIfHasData(values, "is_seized", is_seized);
putIfHasData(values, "adjust_price", adjust_price);
putIfHasData(values, "retail_price", retail_price);
putIfHasData(values, "whole_sale_price", whole_sale_price);
putIfHasData(values, "in_begin_date", in_begin_date);
putIfHasData(values, "sale_begin_date", sale_begin_date);
putIfHasData(values, "out_begin_date", out_begin_date);
// 退出品规
putIfHasData(values, "drawout_uuid", "cc_tbc_drawout_ez".equals(sourceTable) ? recordId : "");
putIfHasData(values, "org_name", org_name);
putIfHasData(values, "quit_uuid", quit_uuid);
putIfHasData(values, "drawout_date", drawout_date);
putIfHasData(values, "quit_date", quit_date);
putIfHasData(values, "comment", comment);
putIfHasData(values, "creater_name", creater_name);
putIfHasData(values, "syscreatedate", syscreatedate);
// 进销存
putIfHasData(values, "biz_date", biz_date);
putIfHasData(values, "manage_unit_uuid", manage_unit_uuid);
putIfHasData(values, "stor_uuid", stor_uuid);
putIfHasData(values, "stor_name", stor_name);
putIfHasData(values, "product_uuid2", product_uuid2);
putIfHasData(values, "product_code2", product_code2);
putIfHasData(values, "product_name2", product_name);
putIfHasData(values, "unit_uuid", unit_uuid);
putIfHasData(values, "unit_name", unit_name);
putIfHasData(values, "last_qty", last_qty);
putIfHasData(values, "last_amount", last_amount);
putIfHasData(values, "buy_qty", buy_qty);
putIfHasData(values, "buy_notax_amount", buy_notax_amount);
putIfHasData(values, "buy_amount", buy_amount);
putIfHasData(values, "movein_qty", movein_qty);
putIfHasData(values, "movein_notax_amount", movein_notax_amount);
putIfHasData(values, "movein_amount", movein_amount);
putIfHasData(values, "movein_cost", movein_cost);
putIfHasData(values, "moveout_qty", moveout_qty);
putIfHasData(values, "moveout_notax_amount", moveout_notax_amount);
putIfHasData(values, "moveout_amount", moveout_amount);
putIfHasData(values, "moveout_cost", moveout_cost);
putIfHasData(values, "sale_qty", sale_qty);
putIfHasData(values, "sale_notax_amount", sale_notax_amount);
putIfHasData(values, "sale_amount", sale_amount);
putIfHasData(values, "sale_cost", sale_cost);
putIfHasData(values, "sale_gross_profit", sale_gross_profit);
putIfHasData(values, "allot_qty", allot_qty);
putIfHasData(values, "allot_notax_amount", allot_notax_amount);
putIfHasData(values, "allot_amount", allot_amount);
putIfHasData(values, "allot_cost", allot_cost);
putIfHasData(values, "allot_gross_profit", allot_gross_profit);
putIfHasData(values, "dec_qty", dec_qty);
putIfHasData(values, "dec_notax_amount", dec_notax_amount);
putIfHasData(values, "dec_amount", dec_amount);
putIfHasData(values, "inc_qty", inc_qty);
putIfHasData(values, "inc_notax_amount", inc_notax_amount);
putIfHasData(values, "inc_amount", inc_amount);
putIfHasData(values, "rest_qty", rest_qty);
putIfHasData(values, "rest_amount", rest_amount);
putIfHasData(values, "cost_price", cost_price);
// 终端建设
putIfHasData(values, "depart_uuid", depart_uuid);
putIfHasData(values, "depart_name", depart_name);
putIfHasData(values, "saler_dept_uuid", saler_dept_uuid);
putIfHasData(values, "license_code", license_code);
putIfHasData(values, "cust_name", cust_name);
putIfHasData(values, "address", address);
putIfHasData(values, "manage_person_name", manage_person_name);
putIfHasData(values, "cust_type_name", cust_type_name);
putIfHasData(values, "busi_place_code", busi_place_code);
putIfHasData(values, "terminal_level_before", terminal_level_before);
putIfHasData(values, "terminal_level_after", terminal_level_after);
putIfHasData(values, "apply_remark", apply_remark);
putIfHasData(values, "deal_remark", deal_remark);
putIfHasData(values, "accept_status", accept_status);
putIfHasData(values, "updator_name", updator_name);
// 元信息:必须写入(即便为空字符串)
values.put("fonds_no", isBlank(fonds_no) ? "" : fonds_no);
values.put("retention", isBlank(retention) ? "" : retention);
values.put("archive_ctg_no", isBlank(archive_ctg_no) ? "" : archive_ctg_no);
values.put("created_date", isBlank(created_date) ? "" : created_date);
values.put("maintitle", isBlank(maintitle) ? "" : maintitle);
values.put("responsibleby", isBlank(responsibleby) ? "" : responsibleby);
values.put("archive_flag", "预归档未完成");
values.put("batch_id", isBlank(recordId) ? "" : recordId);
values.put("table_name", sourceTable);
// 终端建设表为常用字段填充空串即使源表无值避免目标NOT NULL列报错
if ("ec_exp_apply_accept_ez".equals(sourceTable)) {
String[] termCols = new String[]{
"depart_uuid","depart_name","saler_dept_uuid",
"license_code","cust_name","address","manage_person_name",
"cust_type_name","busi_place_code","terminal_level_before",
"terminal_level_after","apply_remark","deal_remark",
"accept_status","updator_name"
};
for (String c : termCols) {
if (!values.containsKey(c)) values.put(c, "");
}
if (!values.containsKey("org_name")) values.put("org_name", "");
}
saveDynamicRow(tempTableName, values);
jhId = findSingleId(tempTableName, whereSql);
if (log.isInfoEnabled()) {
log.info("[PRODUCT_SALES] 新增主表记录 id={} (temp={})", jhId, tempTableName);
}
@@ -1567,8 +2070,8 @@ public class ArchivesUploadController {
log.debug("[PRODUCT_SALES] 目标目录: {}", dir);
}
//是否生成归档xml
if(archiveXMLGenerate){
//是否生成归档xml - 仅在新记录时生成
if(archiveXMLGenerate && !recordExists){
String head = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
String xml = " <目录>" +
" <来源表>" + xmlEscape(sourceTable) + "</来源表>" +
@@ -1692,6 +2195,18 @@ public class ArchivesUploadController {
}
}
// 仅对新记录更新原文数量
if (!recordExists) {
Map<String, Object> map7=new HashMap<>();
map7.put("tableName",tempTableName);
map7.put("tableName2",fileTableName);
map7.put("id",jhId);
danganguanliService.wsajmlTempCount(map7);
if (log.isDebugEnabled()) {
log.debug("[PRODUCT_SALES] 更新原文数量: id={}", jhId);
}
}
j++;
//添加日志

View File

@@ -15,7 +15,7 @@
<!-- name的值是变量的名称value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义后可以使“${}”来使用变量。 -->
<!-- <property name="log.path" value="/logs" /> -->
<property name="log.path" value="logs" />
<property name="log.path" value="/app/logs" />
<!--0. 日志格式和颜色渲染 -->
<!-- 彩色日志依赖的渲染类 -->
@@ -170,10 +170,10 @@
<root level="debug">
<appender-ref ref="CONSOLE" />
<!-- <appender-ref ref="DEBUG_FILE" />-->
<!-- <appender-ref ref="INFO_FILE" />-->
<!-- <appender-ref ref="WARN_FILE" />-->
<!-- <appender-ref ref="ERROR_FILE" />-->
<appender-ref ref="DEBUG_FILE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="WARN_FILE" />
<appender-ref ref="ERROR_FILE" />
</root>