|
|
|
|
@ -0,0 +1,403 @@
|
|
|
|
|
package org.dromara.oa.base.service.impl;
|
|
|
|
|
|
|
|
|
|
import org.dromara.common.core.exception.ServiceException;
|
|
|
|
|
import org.dromara.common.core.utils.StringUtils;
|
|
|
|
|
import org.dromara.oa.base.domain.bo.BaseTemplateVariableBo;
|
|
|
|
|
import org.dromara.oa.base.domain.bo.TemplateVariableAssignRequest;
|
|
|
|
|
import org.dromara.oa.base.domain.vo.BaseTemplateVariableVo;
|
|
|
|
|
import org.dromara.oa.base.domain.vo.TemplateVariableAssignVo;
|
|
|
|
|
import org.dromara.oa.base.service.IBaseTemplateVariableService;
|
|
|
|
|
import org.dromara.oa.base.service.ITemplateVariableAssignService;
|
|
|
|
|
import org.dromara.oa.erp.domain.bo.ErpContractInfoBo;
|
|
|
|
|
import org.dromara.oa.erp.domain.bo.ErpContractMaterialBo;
|
|
|
|
|
import org.dromara.oa.erp.domain.vo.ErpContractInfoVo;
|
|
|
|
|
import org.dromara.oa.erp.domain.vo.ErpContractMaterialVo;
|
|
|
|
|
import org.dromara.oa.erp.service.IErpContractInfoService;
|
|
|
|
|
import org.dromara.oa.erp.service.IErpContractMaterialService;
|
|
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
|
|
import java.lang.reflect.Field;
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Collection;
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 模板变量赋值Service业务层处理
|
|
|
|
|
*
|
|
|
|
|
* @author Yinq
|
|
|
|
|
* @date 2025-01-XX
|
|
|
|
|
*/
|
|
|
|
|
@RequiredArgsConstructor
|
|
|
|
|
@Service
|
|
|
|
|
public class TemplateVariableAssignServiceImpl implements ITemplateVariableAssignService {
|
|
|
|
|
|
|
|
|
|
private final IBaseTemplateVariableService baseTemplateVariableService;
|
|
|
|
|
private final IErpContractInfoService erpContractInfoService;
|
|
|
|
|
private final IErpContractMaterialService erpContractMaterialService;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 根据模板类型为模板变量赋值
|
|
|
|
|
* 模板类型:1=合同,2=发货单
|
|
|
|
|
*
|
|
|
|
|
* @param request 赋值请求(包含变量名称数组、模板类型、业务ID等)
|
|
|
|
|
* @return 赋值后的模板变量列表
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public List<TemplateVariableAssignVo> assignTemplateVariables(TemplateVariableAssignRequest request) {
|
|
|
|
|
// 根据模板类型选择不同的处理逻辑
|
|
|
|
|
String templateType = request.getTemplateType();
|
|
|
|
|
if ("1".equals(templateType)) {
|
|
|
|
|
// 合同类型
|
|
|
|
|
return assignContractTemplateVariables(request);
|
|
|
|
|
} else if ("2".equals(templateType)) {
|
|
|
|
|
// 发货单类型
|
|
|
|
|
return assignDeliveryTemplateVariables(request);
|
|
|
|
|
} else {
|
|
|
|
|
throw new ServiceException("不支持的模板类型:" + templateType);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 为合同模板变量赋值
|
|
|
|
|
*
|
|
|
|
|
* @param request 赋值请求
|
|
|
|
|
* @return 赋值后的模板变量列表
|
|
|
|
|
*/
|
|
|
|
|
private List<TemplateVariableAssignVo> assignContractTemplateVariables(TemplateVariableAssignRequest request) {
|
|
|
|
|
// 1. 根据模板类型查询所有模板变量配置
|
|
|
|
|
BaseTemplateVariableBo queryBo = new BaseTemplateVariableBo();
|
|
|
|
|
queryBo.setTemplateType(request.getTemplateType());
|
|
|
|
|
List<BaseTemplateVariableVo> allTemplateVariables = baseTemplateVariableService.queryList(queryBo);
|
|
|
|
|
|
|
|
|
|
// 构建变量名到配置的映射
|
|
|
|
|
Map<String, BaseTemplateVariableVo> variableMap = buildVariableMap(allTemplateVariables);
|
|
|
|
|
|
|
|
|
|
// 2. 查询合同信息
|
|
|
|
|
ErpContractInfoBo bo = new ErpContractInfoBo();
|
|
|
|
|
bo.setContractId(request.getContractId());
|
|
|
|
|
List<ErpContractInfoVo> contractInfoVoList = erpContractInfoService.queryList(bo);
|
|
|
|
|
if (contractInfoVoList.isEmpty()) {
|
|
|
|
|
throw new ServiceException("合同信息不存在,合同ID:" + request.getContractId());
|
|
|
|
|
}
|
|
|
|
|
ErpContractInfoVo contractInfo = contractInfoVoList.get(0);
|
|
|
|
|
|
|
|
|
|
// 3. 查询合同物料列表(如果存在需要物料数据的变量)
|
|
|
|
|
List<ErpContractMaterialVo> contractMaterials = null;
|
|
|
|
|
boolean needMaterialData = allTemplateVariables.stream()
|
|
|
|
|
.anyMatch(var -> "erp_contract_material".equalsIgnoreCase(var.getDataSource()));
|
|
|
|
|
if (needMaterialData) {
|
|
|
|
|
ErpContractMaterialBo materialBo = new ErpContractMaterialBo();
|
|
|
|
|
materialBo.setContractId(request.getContractId());
|
|
|
|
|
contractMaterials = erpContractMaterialService.queryList(materialBo);
|
|
|
|
|
for (int i = 0; i < contractMaterials.size(); i++) {
|
|
|
|
|
contractMaterials.get(i).setSeq(i + 1L);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 4. 为所有模板变量赋值
|
|
|
|
|
return buildAssignResultList(allTemplateVariables, variableMap, contractInfo, contractMaterials);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 为发货单模板变量赋值
|
|
|
|
|
*
|
|
|
|
|
* @param request 赋值请求
|
|
|
|
|
* @return 赋值后的模板变量列表
|
|
|
|
|
*/
|
|
|
|
|
private List<TemplateVariableAssignVo> assignDeliveryTemplateVariables(TemplateVariableAssignRequest request) {
|
|
|
|
|
// TODO: 实现发货单模板变量赋值逻辑
|
|
|
|
|
throw new ServiceException("发货单模板变量赋值功能暂未实现");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 构建赋值结果列表
|
|
|
|
|
*
|
|
|
|
|
* @param allTemplateVariables 所有模板变量配置
|
|
|
|
|
* @param variableMap 变量配置映射
|
|
|
|
|
* @param contractInfo 合同信息
|
|
|
|
|
* @param contractMaterials 合同物料列表
|
|
|
|
|
* @return 赋值结果列表
|
|
|
|
|
*/
|
|
|
|
|
private List<TemplateVariableAssignVo> buildAssignResultList(
|
|
|
|
|
List<BaseTemplateVariableVo> allTemplateVariables,
|
|
|
|
|
Map<String, BaseTemplateVariableVo> variableMap,
|
|
|
|
|
ErpContractInfoVo contractInfo,
|
|
|
|
|
List<ErpContractMaterialVo> contractMaterials) {
|
|
|
|
|
|
|
|
|
|
List<TemplateVariableAssignVo> resultList = new ArrayList<>();
|
|
|
|
|
for (BaseTemplateVariableVo variable : allTemplateVariables) {
|
|
|
|
|
if (variable == null || StringUtils.isBlank(variable.getVarName())) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据 dataSource 决定数据源
|
|
|
|
|
Object value = getValueFromDataSource(variable, contractInfo, contractMaterials);
|
|
|
|
|
|
|
|
|
|
// 如果获取不到值,使用默认值
|
|
|
|
|
if (value == null && StringUtils.isNotBlank(variable.getDefaultValue())) {
|
|
|
|
|
value = variable.getDefaultValue();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据变量类型决定返回类型(4表示数组类型)
|
|
|
|
|
boolean shouldReturnArray = "4".equals(variable.getVarType());
|
|
|
|
|
Object finalValue = convertValueToTargetType(value, shouldReturnArray);
|
|
|
|
|
|
|
|
|
|
// 构建返回对象
|
|
|
|
|
TemplateVariableAssignVo assignVo = new TemplateVariableAssignVo();
|
|
|
|
|
assignVo.setVarName(variable.getVarName());
|
|
|
|
|
assignVo.setVarLabel(variable.getVarLabel());
|
|
|
|
|
assignVo.setVarValue(finalValue);
|
|
|
|
|
assignVo.setVarType(variable.getVarType());
|
|
|
|
|
resultList.add(assignVo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return resultList;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 解析变量名称格式
|
|
|
|
|
* #{变量名} 表示字符串类型
|
|
|
|
|
* ^{变量名} 表示数组类型
|
|
|
|
|
*
|
|
|
|
|
* @param varNameWithFormat 带格式的变量名,如 #{客户名称} 或 ^{产品名称}
|
|
|
|
|
* @return 变量名信息
|
|
|
|
|
*/
|
|
|
|
|
private VariableNameInfo parseVariableName(String varNameWithFormat) {
|
|
|
|
|
if (StringUtils.isBlank(varNameWithFormat)) {
|
|
|
|
|
return new VariableNameInfo(varNameWithFormat, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查是否是 #{变量名} 格式(字符串)
|
|
|
|
|
if (varNameWithFormat.startsWith("#{") && varNameWithFormat.endsWith("}")) {
|
|
|
|
|
String actualName = varNameWithFormat.substring(2, varNameWithFormat.length() - 1);
|
|
|
|
|
return new VariableNameInfo(actualName, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查是否是 ^{变量名} 格式(数组)
|
|
|
|
|
if (varNameWithFormat.startsWith("^{") && varNameWithFormat.endsWith("}")) {
|
|
|
|
|
String actualName = varNameWithFormat.substring(2, varNameWithFormat.length() - 1);
|
|
|
|
|
return new VariableNameInfo(actualName, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 默认格式,返回原值
|
|
|
|
|
return new VariableNameInfo(varNameWithFormat, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 变量名信息内部类
|
|
|
|
|
*/
|
|
|
|
|
private static class VariableNameInfo {
|
|
|
|
|
private final String actualName;
|
|
|
|
|
private final boolean arrayType;
|
|
|
|
|
|
|
|
|
|
public VariableNameInfo(String actualName, boolean arrayType) {
|
|
|
|
|
this.actualName = actualName;
|
|
|
|
|
this.arrayType = arrayType;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getActualName() {
|
|
|
|
|
return actualName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean isArrayType() {
|
|
|
|
|
return arrayType;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 构建变量名到配置的映射
|
|
|
|
|
* 支持带占位符(#{变量名}或^{变量名})和不带占位符的匹配
|
|
|
|
|
*
|
|
|
|
|
* @param templateVariables 所有模板变量配置
|
|
|
|
|
* @return 变量名到配置的映射
|
|
|
|
|
*/
|
|
|
|
|
private Map<String, BaseTemplateVariableVo> buildVariableMap(
|
|
|
|
|
List<BaseTemplateVariableVo> templateVariables) {
|
|
|
|
|
Map<String, BaseTemplateVariableVo> variableMap = new HashMap<>();
|
|
|
|
|
|
|
|
|
|
for (BaseTemplateVariableVo variable : templateVariables) {
|
|
|
|
|
String varName = variable.getVarName();
|
|
|
|
|
if (StringUtils.isBlank(varName)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 提取变量名(去除占位符)
|
|
|
|
|
String normalizedName = normalizeVariableName(varName);
|
|
|
|
|
|
|
|
|
|
// 添加到映射中(使用规范化后的变量名作为key)
|
|
|
|
|
variableMap.put(normalizedName, variable);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return variableMap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 规范化变量名(去除占位符格式)
|
|
|
|
|
*
|
|
|
|
|
* @param varName 变量名(可能包含#{或^{})
|
|
|
|
|
* @return 规范化后的变量名
|
|
|
|
|
*/
|
|
|
|
|
private String normalizeVariableName(String varName) {
|
|
|
|
|
if (StringUtils.isBlank(varName)) {
|
|
|
|
|
return varName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 去除 #{变量名} 或 ^{变量名} 格式
|
|
|
|
|
if ((varName.startsWith("#{") || varName.startsWith("^{")) && varName.endsWith("}")) {
|
|
|
|
|
return varName.substring(2, varName.length() - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return varName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 根据数据源获取字段值
|
|
|
|
|
*
|
|
|
|
|
* @param variable 变量配置
|
|
|
|
|
* @param contractInfo 合同信息
|
|
|
|
|
* @param contractMaterials 合同物料列表(可能为null)
|
|
|
|
|
* @return 字段值
|
|
|
|
|
*/
|
|
|
|
|
private Object getValueFromDataSource(BaseTemplateVariableVo variable,
|
|
|
|
|
ErpContractInfoVo contractInfo,
|
|
|
|
|
List<ErpContractMaterialVo> contractMaterials) {
|
|
|
|
|
if (StringUtils.isBlank(variable.getDataField())) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String dataSource = variable.getDataSource();
|
|
|
|
|
|
|
|
|
|
// 根据数据源类型获取值
|
|
|
|
|
if ("erp_contract_material".equalsIgnoreCase(dataSource)) {
|
|
|
|
|
// 从合同物料列表中提取字段值
|
|
|
|
|
return getFieldValueFromMaterialList(contractMaterials, variable.getDataField());
|
|
|
|
|
} else {
|
|
|
|
|
// 默认从合同信息中获取
|
|
|
|
|
return getFieldValueFromContract(contractInfo, variable.getDataField());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 从合同物料列表中提取指定字段的值列表
|
|
|
|
|
*
|
|
|
|
|
* @param contractMaterials 合同物料列表
|
|
|
|
|
* @param fieldName 字段名
|
|
|
|
|
* @return 字段值列表
|
|
|
|
|
*/
|
|
|
|
|
private List<Object> getFieldValueFromMaterialList(List<ErpContractMaterialVo> contractMaterials, String fieldName) {
|
|
|
|
|
if (contractMaterials == null || contractMaterials.isEmpty() || StringUtils.isBlank(fieldName)) {
|
|
|
|
|
return new ArrayList<>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<Object> values = new ArrayList<>();
|
|
|
|
|
for (ErpContractMaterialVo material : contractMaterials) {
|
|
|
|
|
Object value = getFieldValueFromObject(material, fieldName);
|
|
|
|
|
// 如果值为null,用空字符串代替
|
|
|
|
|
values.add(value != null ? value : "");
|
|
|
|
|
}
|
|
|
|
|
return values;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 使用反射从对象中根据字段名获取值
|
|
|
|
|
*
|
|
|
|
|
* @param obj 对象
|
|
|
|
|
* @param fieldName 字段名
|
|
|
|
|
* @return 字段值
|
|
|
|
|
*/
|
|
|
|
|
private Object getFieldValueFromObject(Object obj, String fieldName) {
|
|
|
|
|
if (obj == null || StringUtils.isBlank(fieldName)) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 先尝试使用反射获取字段值
|
|
|
|
|
Field field = obj.getClass().getDeclaredField(fieldName);
|
|
|
|
|
field.setAccessible(true);
|
|
|
|
|
return field.get(obj);
|
|
|
|
|
} catch (NoSuchFieldException e) {
|
|
|
|
|
// 如果字段不存在,尝试使用 getter 方法
|
|
|
|
|
try {
|
|
|
|
|
String methodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
|
|
|
|
|
return obj.getClass().getMethod(methodName).invoke(obj);
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
// 如果都获取不到,返回 null
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 使用反射从合同信息中根据字段名获取值
|
|
|
|
|
*
|
|
|
|
|
* @param contractInfo 合同信息
|
|
|
|
|
* @param fieldName 字段名
|
|
|
|
|
* @return 字段值
|
|
|
|
|
*/
|
|
|
|
|
private Object getFieldValueFromContract(ErpContractInfoVo contractInfo, String fieldName) {
|
|
|
|
|
return getFieldValueFromObject(contractInfo, fieldName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 将值转换为目标类型
|
|
|
|
|
*
|
|
|
|
|
* @param value 原始值
|
|
|
|
|
* @param shouldReturnArray 是否应该返回数组类型
|
|
|
|
|
* @return 转换后的值
|
|
|
|
|
*/
|
|
|
|
|
private Object convertValueToTargetType(Object value, boolean shouldReturnArray) {
|
|
|
|
|
if (shouldReturnArray) {
|
|
|
|
|
// 转换为数组类型
|
|
|
|
|
if (value instanceof List) {
|
|
|
|
|
return value;
|
|
|
|
|
} else if (value instanceof Collection) {
|
|
|
|
|
return new ArrayList<>((Collection<?>) value);
|
|
|
|
|
} else if (value != null) {
|
|
|
|
|
// 单个值,转换为列表
|
|
|
|
|
List<Object> arrayValue = new ArrayList<>();
|
|
|
|
|
arrayValue.add(value);
|
|
|
|
|
return arrayValue;
|
|
|
|
|
} else {
|
|
|
|
|
return new ArrayList<>();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 转换为字符串类型
|
|
|
|
|
if (value instanceof List) {
|
|
|
|
|
List<?> list = (List<?>) value;
|
|
|
|
|
if (!list.isEmpty()) {
|
|
|
|
|
return list.get(0).toString();
|
|
|
|
|
} else {
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
} else if (value instanceof Collection) {
|
|
|
|
|
Collection<?> collection = (Collection<?>) value;
|
|
|
|
|
if (!collection.isEmpty()) {
|
|
|
|
|
return collection.iterator().next().toString();
|
|
|
|
|
} else {
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
} else if (value != null) {
|
|
|
|
|
return value.toString();
|
|
|
|
|
} else {
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 根据类型获取默认值
|
|
|
|
|
*
|
|
|
|
|
* @param isArrayType 是否为数组类型
|
|
|
|
|
* @return 默认值
|
|
|
|
|
*/
|
|
|
|
|
private Object getDefaultValueByType(boolean isArrayType) {
|
|
|
|
|
return isArrayType ? new ArrayList<>() : "";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|