|
@@ -22,26 +22,32 @@ import java.util.Map;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 员工履历 Word 导出 — 服务层二开扩展。
|
|
* 员工履历 Word 导出 — 服务层二开扩展。
|
|
|
- * <p>
|
|
|
|
|
- * 按 familyRelation.number(与本人关系基础资料编码 FNumber)升序排序。
|
|
|
|
|
- * personFamily.relation.number 在 SQL 中会映射为 FRelationID(内码),不能用于按编码排序。
|
|
|
|
|
- * </p>
|
|
|
|
|
|
|
+ * coyle
|
|
|
|
|
+ * 202605
|
|
|
|
|
+ * PersonFamily:按 familyRelation.number(基础资料编码 FNumber)升序排序
|
|
|
|
|
+ * ygzzk(年度考核结果):按 kaoheshij 降序取最新 3 条,升序合并为单行;考核时间展示为 yyyy年
|
|
|
*/
|
|
*/
|
|
|
public class ResumeWordTemplateServiceImplEx extends ResumeWordTemplateServiceImpl {
|
|
public class ResumeWordTemplateServiceImplEx extends ResumeWordTemplateServiceImpl {
|
|
|
|
|
|
|
|
private static final Logger LOGGER = LoggerFactory.getLogger(ResumeWordTemplateServiceImplEx.class);
|
|
private static final Logger LOGGER = LoggerFactory.getLogger(ResumeWordTemplateServiceImplEx.class);
|
|
|
|
|
|
|
|
- /** Word / 结构配置中 PersonFamily 实体别名(匹配时忽略大小写) */
|
|
|
|
|
private static final String PERSON_FAMILY_ENTITY = "PERSONFAMILY";
|
|
private static final String PERSON_FAMILY_ENTITY = "PERSONFAMILY";
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 与本人关系编码排序字段。
|
|
|
|
|
- * SQL 中 personFamily.relation.number → PERSONFAMILY.FRelationID(UUID),不是编码;
|
|
|
|
|
- * familyRelation.number → T_HR_BDRelation.FNumber(01/02/07777),与 Word 中 familyRelation.name 同源。
|
|
|
|
|
- */
|
|
|
|
|
private static final String PERSON_FAMILY_SORT_FIELD = "familyRelation.number";
|
|
private static final String PERSON_FAMILY_SORT_FIELD = "familyRelation.number";
|
|
|
|
|
|
|
|
- /** multiNotOne 内存排序临时键,不写入 Word */
|
|
|
|
|
|
|
+ /** 年度考核结果表体(结构配置 clientNumber) */
|
|
|
|
|
+ private static final String YGZZK_ENTITY = "YGZZK";
|
|
|
|
|
+ private static final String YGZZK_SORT_FIELD = "kaoheshij";
|
|
|
|
|
+ private static final int YGZZK_ROW_LIMIT = 3;
|
|
|
|
|
+ private static final String YGZZK_SEGMENT_SEPARATOR = ",";
|
|
|
|
|
+ private static final String YGZZK_YEAR_SUFFIX = "年";
|
|
|
|
|
+
|
|
|
|
|
+ /** 记录内字段拼接顺序(模板未出现的字段自动跳过) */
|
|
|
|
|
+ private static final String[] YGZZK_FIELD_ORDER = {
|
|
|
|
|
+ "kaoheshij",
|
|
|
|
|
+ "kaohe2.name",
|
|
|
|
|
+ "kaohezzwenb"
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
private static final String ROW_SORT_VALUE = "__sortValue";
|
|
private static final String ROW_SORT_VALUE = "__sortValue";
|
|
|
|
|
|
|
|
private static final int PERSON_FAMILY_ROW_LIMIT = 0;
|
|
private static final int PERSON_FAMILY_ROW_LIMIT = 0;
|
|
@@ -67,7 +73,9 @@ public class ResumeWordTemplateServiceImplEx extends ResumeWordTemplateServiceIm
|
|
|
Map<String, Object> resultMap,
|
|
Map<String, Object> resultMap,
|
|
|
Map<String, StructureConfigColumnsInfo> columnsInfoMap
|
|
Map<String, StructureConfigColumnsInfo> columnsInfoMap
|
|
|
) throws EASBizException, BOSException, ShrWebBizException, SQLException {
|
|
) throws EASBizException, BOSException, ShrWebBizException, SQLException {
|
|
|
- if (containsPersonFamilyEntity(sqlParam)) {
|
|
|
|
|
|
|
+ if (containsYgzzkEntity(sqlParam)) {
|
|
|
|
|
+ prepareYgzzkSortBeforeQuery(sqlParam);
|
|
|
|
|
+ } else if (containsPersonFamilyEntity(sqlParam)) {
|
|
|
LOGGER.info("ResumeWordTemplateServiceImplEx.rowHandle: apply PersonFamily sort before query, field="
|
|
LOGGER.info("ResumeWordTemplateServiceImplEx.rowHandle: apply PersonFamily sort before query, field="
|
|
|
+ PERSON_FAMILY_SORT_FIELD);
|
|
+ PERSON_FAMILY_SORT_FIELD);
|
|
|
preparePersonFamilySortBeforeQuery(sqlParam);
|
|
preparePersonFamilySortBeforeQuery(sqlParam);
|
|
@@ -78,11 +86,11 @@ public class ResumeWordTemplateServiceImplEx extends ResumeWordTemplateServiceIm
|
|
|
@Override
|
|
@Override
|
|
|
protected void sorterHandler(Context ctx, SqlParam param) {
|
|
protected void sorterHandler(Context ctx, SqlParam param) {
|
|
|
super.sorterHandler(ctx, param);
|
|
super.sorterHandler(ctx, param);
|
|
|
- applyPersonFamilySorter(param);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private void preparePersonFamilySortBeforeQuery(SqlParam param) {
|
|
|
|
|
- applyPersonFamilySorter(param);
|
|
|
|
|
|
|
+ if (containsYgzzkEntity(param)) {
|
|
|
|
|
+ applyYgzzkSorter(param);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ applyPersonFamilySorter(param);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -93,12 +101,90 @@ public class ResumeWordTemplateServiceImplEx extends ResumeWordTemplateServiceIm
|
|
|
Map<String, String> selectKeyToWordKeyMap,
|
|
Map<String, String> selectKeyToWordKeyMap,
|
|
|
Map<String, Object> resultMap,
|
|
Map<String, Object> resultMap,
|
|
|
Map<String, StructureConfigColumnsInfo> columnsInfoMap
|
|
Map<String, StructureConfigColumnsInfo> columnsInfoMap
|
|
|
|
|
+ ) throws SQLException {
|
|
|
|
|
+ if (containsYgzzkEntity(sqlParam)) {
|
|
|
|
|
+ handleYgzzkMultiNotOne(rowSet, ctx, sqlParam, selectKeyToWordKeyMap, resultMap, columnsInfoMap);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (containsPersonFamilyEntity(sqlParam)) {
|
|
|
|
|
+ handlePersonFamilyMultiNotOne(rowSet, ctx, sqlParam, selectKeyToWordKeyMap, resultMap, columnsInfoMap);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ super.multiNotOne(rowSet, ctx, sqlParam, selectKeyToWordKeyMap, resultMap, columnsInfoMap);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void handleYgzzkMultiNotOne(
|
|
|
|
|
+ IRowSet rowSet,
|
|
|
|
|
+ Context ctx,
|
|
|
|
|
+ SqlParam sqlParam,
|
|
|
|
|
+ Map<String, String> selectKeyToWordKeyMap,
|
|
|
|
|
+ Map<String, Object> resultMap,
|
|
|
|
|
+ Map<String, StructureConfigColumnsInfo> columnsInfoMap
|
|
|
|
|
+ ) throws SQLException {
|
|
|
|
|
+ String sortSelectKey = resolveSelectKeyByFieldSuffix(selectKeyToWordKeyMap, YGZZK_SORT_FIELD);
|
|
|
|
|
+ List<String> orderedWordKeys = buildYgzzkOrderedWordKeys(selectKeyToWordKeyMap);
|
|
|
|
|
+ List<Map<String, String>> rowList = new ArrayList<Map<String, String>>();
|
|
|
|
|
+
|
|
|
|
|
+ while (rowSet.next()) {
|
|
|
|
|
+ Map<String, String> rowData = new HashMap<String, String>();
|
|
|
|
|
+ for (Map.Entry<String, String> entry : selectKeyToWordKeyMap.entrySet()) {
|
|
|
|
|
+ if (!isYgzzkSelectKey(entry.getKey())) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ String wordKey = entry.getValue();
|
|
|
|
|
+ Object dbValue = rowSet.getObject(entry.getKey());
|
|
|
|
|
+ String displayValue = dataTypeHandle(ctx, dbValue, columnsInfoMap.get(wordKey));
|
|
|
|
|
+ if (matchesYgzzkField(entry.getKey(), YGZZK_SORT_FIELD)) {
|
|
|
|
|
+ displayValue = formatYgzzkKaoheshij(displayValue);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!StringUtils.isEmpty(displayValue)) {
|
|
|
|
|
+ rowData.put(wordKey, displayValue);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (sortSelectKey != null) {
|
|
|
|
|
+ rowData.put(ROW_SORT_VALUE, resolveRowSortValue(rowSet, sortSelectKey));
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!rowData.isEmpty()) {
|
|
|
|
|
+ rowList.add(rowData);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (sortSelectKey != null) {
|
|
|
|
|
+ sortRowListDesc(rowList);
|
|
|
|
|
+ limitRowList(rowList, YGZZK_ROW_LIMIT);
|
|
|
|
|
+ sortRowListAsc(rowList);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ LOGGER.warn("ResumeWordTemplateServiceImplEx.handleYgzzkMultiNotOne: sortSelectKey missing for "
|
|
|
|
|
+ + YGZZK_SORT_FIELD);
|
|
|
|
|
+ limitRowList(rowList, YGZZK_ROW_LIMIT);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ String merged = mergeYgzzkSegments(rowList, orderedWordKeys);
|
|
|
|
|
+ if (StringUtils.isEmpty(merged) || orderedWordKeys.isEmpty()) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Map<String, String> singleRow = new HashMap<String, String>();
|
|
|
|
|
+ String primaryWordKey = orderedWordKeys.get(0);
|
|
|
|
|
+ singleRow.put(primaryWordKey, merged);
|
|
|
|
|
+ resultMap.putAll(singleRow);
|
|
|
|
|
+
|
|
|
|
|
+ LOGGER.info("ResumeWordTemplateServiceImplEx.handleYgzzkMultiNotOne: merged into wordKey="
|
|
|
|
|
+ + primaryWordKey + ", value=[" + merged + "], sourceRows=" + rowList.size());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void handlePersonFamilyMultiNotOne(
|
|
|
|
|
+ IRowSet rowSet,
|
|
|
|
|
+ Context ctx,
|
|
|
|
|
+ SqlParam sqlParam,
|
|
|
|
|
+ Map<String, String> selectKeyToWordKeyMap,
|
|
|
|
|
+ Map<String, Object> resultMap,
|
|
|
|
|
+ Map<String, StructureConfigColumnsInfo> columnsInfoMap
|
|
|
) throws SQLException {
|
|
) throws SQLException {
|
|
|
List<Map<String, String>> rowList = new ArrayList<Map<String, String>>();
|
|
List<Map<String, String>> rowList = new ArrayList<Map<String, String>>();
|
|
|
String entityKey = null;
|
|
String entityKey = null;
|
|
|
String sortSelectKey = resolveSortSelectKey(selectKeyToWordKeyMap, PERSON_FAMILY_SORT_FIELD);
|
|
String sortSelectKey = resolveSortSelectKey(selectKeyToWordKeyMap, PERSON_FAMILY_SORT_FIELD);
|
|
|
- boolean personFamilyQuery = containsPersonFamilyEntity(sqlParam);
|
|
|
|
|
- boolean sortInMemory = personFamilyQuery && sortSelectKey != null;
|
|
|
|
|
|
|
+ boolean sortInMemory = sortSelectKey != null;
|
|
|
|
|
|
|
|
while (rowSet.next()) {
|
|
while (rowSet.next()) {
|
|
|
Map<String, String> rowData = new HashMap<String, String>();
|
|
Map<String, String> rowData = new HashMap<String, String>();
|
|
@@ -128,13 +214,13 @@ public class ResumeWordTemplateServiceImplEx extends ResumeWordTemplateServiceIm
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (containsPersonFamilyEntity(sqlParam) && sortInMemory) {
|
|
|
|
|
- sortRowList(rowList);
|
|
|
|
|
|
|
+ if (sortInMemory) {
|
|
|
|
|
+ sortRowListAsc(rowList);
|
|
|
logSortPreview(rowList);
|
|
logSortPreview(rowList);
|
|
|
for (Map<String, String> rowData : rowList) {
|
|
for (Map<String, String> rowData : rowList) {
|
|
|
rowData.remove(ROW_SORT_VALUE);
|
|
rowData.remove(ROW_SORT_VALUE);
|
|
|
}
|
|
}
|
|
|
- } else if (personFamilyQuery) {
|
|
|
|
|
|
|
+ } else {
|
|
|
LOGGER.warn("ResumeWordTemplateServiceImplEx.multiNotOne: PersonFamily detected but sortSelectKey missing, "
|
|
LOGGER.warn("ResumeWordTemplateServiceImplEx.multiNotOne: PersonFamily detected but sortSelectKey missing, "
|
|
|
+ "entityKey=" + entityKey);
|
|
+ "entityKey=" + entityKey);
|
|
|
}
|
|
}
|
|
@@ -148,6 +234,24 @@ public class ResumeWordTemplateServiceImplEx extends ResumeWordTemplateServiceIm
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ private void preparePersonFamilySortBeforeQuery(SqlParam param) {
|
|
|
|
|
+ applyPersonFamilySorter(param);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void prepareYgzzkSortBeforeQuery(SqlParam param) {
|
|
|
|
|
+ applyYgzzkSorter(param);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void applyYgzzkSorter(SqlParam param) {
|
|
|
|
|
+ if (!containsYgzzkEntity(param)) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ String sortField = YGZZK_ENTITY.toLowerCase() + "." + YGZZK_SORT_FIELD;
|
|
|
|
|
+ param.setSortStr(sortField + " desc");
|
|
|
|
|
+ addSortFieldToSelectMapping(param.getSelectMapping(), sortField);
|
|
|
|
|
+ LOGGER.info("ResumeWordTemplateServiceImplEx: ygzzk sortStr=" + param.getSortStr());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private void applyPersonFamilySorter(SqlParam param) {
|
|
private void applyPersonFamilySorter(SqlParam param) {
|
|
|
if (!containsPersonFamilyEntity(param)) {
|
|
if (!containsPersonFamilyEntity(param)) {
|
|
|
return;
|
|
return;
|
|
@@ -157,6 +261,159 @@ public class ResumeWordTemplateServiceImplEx extends ResumeWordTemplateServiceIm
|
|
|
LOGGER.info("ResumeWordTemplateServiceImplEx: sortStr=" + param.getSortStr());
|
|
LOGGER.info("ResumeWordTemplateServiceImplEx: sortStr=" + param.getSortStr());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ private boolean containsYgzzkEntity(SqlParam param) {
|
|
|
|
|
+ if (containsEntity(param.getInfoCtr(), YGZZK_ENTITY)) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ Map<String, String> selectMapping = param.getSelectMapping();
|
|
|
|
|
+ if (selectMapping == null) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ for (String key : selectMapping.keySet()) {
|
|
|
|
|
+ if (isYgzzkSelectKey(key)) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private boolean isYgzzkSelectKey(String selectKey) {
|
|
|
|
|
+ if (selectKey == null) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ return selectKey.toUpperCase().startsWith(YGZZK_ENTITY + ".");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private boolean matchesYgzzkField(String selectKey, String fieldSuffix) {
|
|
|
|
|
+ if (selectKey == null || fieldSuffix == null) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!isYgzzkSelectKey(selectKey)) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ String upperKey = selectKey.toUpperCase();
|
|
|
|
|
+ String upperSuffix = fieldSuffix.toUpperCase();
|
|
|
|
|
+ return upperKey.equals(YGZZK_ENTITY + "." + upperSuffix)
|
|
|
|
|
+ || upperKey.endsWith("." + upperSuffix);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private List<String> buildYgzzkOrderedWordKeys(Map<String, String> selectKeyToWordKeyMap) {
|
|
|
|
|
+ List<String> orderedSelectKeys = new ArrayList<String>();
|
|
|
|
|
+ for (int i = 0; i < YGZZK_FIELD_ORDER.length; i++) {
|
|
|
|
|
+ appendMatchingSelectKeys(orderedSelectKeys, selectKeyToWordKeyMap, YGZZK_FIELD_ORDER[i]);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (selectKeyToWordKeyMap != null) {
|
|
|
|
|
+ for (String selectKey : selectKeyToWordKeyMap.keySet()) {
|
|
|
|
|
+ if (isYgzzkSelectKey(selectKey) && !orderedSelectKeys.contains(selectKey)) {
|
|
|
|
|
+ orderedSelectKeys.add(selectKey);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ List<String> orderedWordKeys = new ArrayList<String>();
|
|
|
|
|
+ for (int i = 0; i < orderedSelectKeys.size(); i++) {
|
|
|
|
|
+ String wordKey = selectKeyToWordKeyMap.get(orderedSelectKeys.get(i));
|
|
|
|
|
+ if (wordKey != null && !orderedWordKeys.contains(wordKey)) {
|
|
|
|
|
+ orderedWordKeys.add(wordKey);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return orderedWordKeys;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void appendMatchingSelectKeys(
|
|
|
|
|
+ List<String> orderedSelectKeys,
|
|
|
|
|
+ Map<String, String> selectKeyToWordKeyMap,
|
|
|
|
|
+ String fieldSuffix
|
|
|
|
|
+ ) {
|
|
|
|
|
+ if (selectKeyToWordKeyMap == null) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ for (String selectKey : selectKeyToWordKeyMap.keySet()) {
|
|
|
|
|
+ if (matchesYgzzkField(selectKey, fieldSuffix) && !orderedSelectKeys.contains(selectKey)) {
|
|
|
|
|
+ orderedSelectKeys.add(selectKey);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private String mergeYgzzkSegments(List<Map<String, String>> rowList, List<String> orderedWordKeys) {
|
|
|
|
|
+ if (rowList == null || rowList.isEmpty() || orderedWordKeys == null || orderedWordKeys.isEmpty()) {
|
|
|
|
|
+ return "";
|
|
|
|
|
+ }
|
|
|
|
|
+ StringBuilder merged = new StringBuilder();
|
|
|
|
|
+ for (int i = 0; i < rowList.size(); i++) {
|
|
|
|
|
+ String segment = buildYgzzkRecordSegment(rowList.get(i), orderedWordKeys);
|
|
|
|
|
+ if (StringUtils.isEmpty(segment)) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (merged.length() > 0) {
|
|
|
|
|
+ merged.append(YGZZK_SEGMENT_SEPARATOR);
|
|
|
|
|
+ }
|
|
|
|
|
+ merged.append(segment);
|
|
|
|
|
+ }
|
|
|
|
|
+ return merged.toString();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private String buildYgzzkRecordSegment(Map<String, String> rowData, List<String> orderedWordKeys) {
|
|
|
|
|
+ if (rowData == null || orderedWordKeys == null) {
|
|
|
|
|
+ return "";
|
|
|
|
|
+ }
|
|
|
|
|
+ StringBuilder segment = new StringBuilder();
|
|
|
|
|
+ for (int i = 0; i < orderedWordKeys.size(); i++) {
|
|
|
|
|
+ String value = rowData.get(orderedWordKeys.get(i));
|
|
|
|
|
+ if (!StringUtils.isEmpty(value)) {
|
|
|
|
|
+ segment.append(value);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return segment.toString();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /** 考核时间合并展示:仅保留 yyyy,并追加「年」,如 2026年 */
|
|
|
|
|
+ private String formatYgzzkKaoheshij(String displayValue) {
|
|
|
|
|
+ if (StringUtils.isEmpty(displayValue)) {
|
|
|
|
|
+ return displayValue;
|
|
|
|
|
+ }
|
|
|
|
|
+ String trimmed = displayValue.trim();
|
|
|
|
|
+ if (trimmed.endsWith(YGZZK_YEAR_SUFFIX) && trimmed.length() >= 5) {
|
|
|
|
|
+ String yearPart = trimmed.substring(0, trimmed.length() - YGZZK_YEAR_SUFFIX.length());
|
|
|
|
|
+ if (yearPart.length() == 4 && isFourDigitYear(yearPart)) {
|
|
|
|
|
+ return trimmed;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ String year = extractFourDigitYear(trimmed);
|
|
|
|
|
+ if (year != null) {
|
|
|
|
|
+ return year + YGZZK_YEAR_SUFFIX;
|
|
|
|
|
+ }
|
|
|
|
|
+ return trimmed;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private String extractFourDigitYear(String text) {
|
|
|
|
|
+ StringBuilder year = new StringBuilder();
|
|
|
|
|
+ for (int i = 0; i < text.length(); i++) {
|
|
|
|
|
+ char ch = text.charAt(i);
|
|
|
|
|
+ if (ch >= '0' && ch <= '9') {
|
|
|
|
|
+ year.append(ch);
|
|
|
|
|
+ if (year.length() == 4) {
|
|
|
|
|
+ return year.toString();
|
|
|
|
|
+ }
|
|
|
|
|
+ } else if (year.length() > 0) {
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return year.length() == 4 ? year.toString() : null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private boolean isFourDigitYear(String year) {
|
|
|
|
|
+ if (year == null || year.length() != 4) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ for (int i = 0; i < 4; i++) {
|
|
|
|
|
+ char ch = year.charAt(i);
|
|
|
|
|
+ if (ch < '0' || ch > '9') {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private boolean containsPersonFamilyEntity(SqlParam param) {
|
|
private boolean containsPersonFamilyEntity(SqlParam param) {
|
|
|
if (containsEntity(param.getInfoCtr(), PERSON_FAMILY_ENTITY)) {
|
|
if (containsEntity(param.getInfoCtr(), PERSON_FAMILY_ENTITY)) {
|
|
|
return true;
|
|
return true;
|
|
@@ -209,21 +466,25 @@ public class ResumeWordTemplateServiceImplEx extends ResumeWordTemplateServiceIm
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private String resolveSortSelectKey(Map<String, String> selectKeyToWordKeyMap, String sortField) {
|
|
private String resolveSortSelectKey(Map<String, String> selectKeyToWordKeyMap, String sortField) {
|
|
|
- if (selectKeyToWordKeyMap == null || StringUtils.isEmpty(sortField)) {
|
|
|
|
|
|
|
+ return resolveSelectKeyByFieldSuffix(selectKeyToWordKeyMap, sortField);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private String resolveSelectKeyByFieldSuffix(Map<String, String> selectKeyToWordKeyMap, String fieldSuffix) {
|
|
|
|
|
+ if (selectKeyToWordKeyMap == null || StringUtils.isEmpty(fieldSuffix)) {
|
|
|
return null;
|
|
return null;
|
|
|
}
|
|
}
|
|
|
for (String key : selectKeyToWordKeyMap.keySet()) {
|
|
for (String key : selectKeyToWordKeyMap.keySet()) {
|
|
|
- if (key != null && key.equalsIgnoreCase(sortField)) {
|
|
|
|
|
|
|
+ if (key != null && key.equalsIgnoreCase(fieldSuffix)) {
|
|
|
return key;
|
|
return key;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- String suffix = ".relation.number";
|
|
|
|
|
|
|
+ String dottedSuffix = "." + fieldSuffix;
|
|
|
for (String key : selectKeyToWordKeyMap.keySet()) {
|
|
for (String key : selectKeyToWordKeyMap.keySet()) {
|
|
|
- if (key != null && key.toUpperCase().endsWith(suffix.toUpperCase())) {
|
|
|
|
|
|
|
+ if (key != null && key.toUpperCase().endsWith(dottedSuffix.toUpperCase())) {
|
|
|
return key;
|
|
return key;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- if (sortField != null && sortField.toUpperCase().endsWith(".NUMBER")) {
|
|
|
|
|
|
|
+ if (fieldSuffix.toUpperCase().endsWith(".NUMBER")) {
|
|
|
for (String key : selectKeyToWordKeyMap.keySet()) {
|
|
for (String key : selectKeyToWordKeyMap.keySet()) {
|
|
|
if (key != null && key.toUpperCase().endsWith(".NUMBER")) {
|
|
if (key != null && key.toUpperCase().endsWith(".NUMBER")) {
|
|
|
return key;
|
|
return key;
|
|
@@ -258,7 +519,15 @@ public class ResumeWordTemplateServiceImplEx extends ResumeWordTemplateServiceIm
|
|
|
+ ", sortValues=[" + preview + "], count=" + rowList.size());
|
|
+ ", sortValues=[" + preview + "], count=" + rowList.size());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private void sortRowList(List<Map<String, String>> rowList) {
|
|
|
|
|
|
|
+ private void sortRowListAsc(List<Map<String, String>> rowList) {
|
|
|
|
|
+ sortRowList(rowList, false);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void sortRowListDesc(List<Map<String, String>> rowList) {
|
|
|
|
|
+ sortRowList(rowList, true);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void sortRowList(List<Map<String, String>> rowList, boolean descending) {
|
|
|
if (rowList == null || rowList.size() <= 1) {
|
|
if (rowList == null || rowList.size() <= 1) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
@@ -273,11 +542,19 @@ public class ResumeWordTemplateServiceImplEx extends ResumeWordTemplateServiceIm
|
|
|
if (rightValue == null) {
|
|
if (rightValue == null) {
|
|
|
rightValue = "";
|
|
rightValue = "";
|
|
|
}
|
|
}
|
|
|
- return leftValue.compareTo(rightValue);
|
|
|
|
|
|
|
+ int result = leftValue.compareTo(rightValue);
|
|
|
|
|
+ return descending ? -result : result;
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ private void limitRowList(List<Map<String, String>> rowList, int limit) {
|
|
|
|
|
+ if (limit <= 0 || rowList == null || rowList.size() <= limit) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ rowList.subList(limit, rowList.size()).clear();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private void applyPersonFamilyRowLimit(String entityKey, List<Map<String, String>> rowList) {
|
|
private void applyPersonFamilyRowLimit(String entityKey, List<Map<String, String>> rowList) {
|
|
|
if (PERSON_FAMILY_ROW_LIMIT <= 0 || rowList == null || rowList.isEmpty()) {
|
|
if (PERSON_FAMILY_ROW_LIMIT <= 0 || rowList == null || rowList.isEmpty()) {
|
|
|
return;
|
|
return;
|
|
@@ -285,8 +562,6 @@ public class ResumeWordTemplateServiceImplEx extends ResumeWordTemplateServiceIm
|
|
|
if (!isPersonFamilyEntityKey(entityKey)) {
|
|
if (!isPersonFamilyEntityKey(entityKey)) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
- if (rowList.size() > PERSON_FAMILY_ROW_LIMIT) {
|
|
|
|
|
- rowList.subList(PERSON_FAMILY_ROW_LIMIT, rowList.size()).clear();
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ limitRowList(rowList, PERSON_FAMILY_ROW_LIMIT);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|