diff --git a/javascript/xuanran.wang/bme/js/Common.js b/javascript/xuanran.wang/bme/js/Common.js index 583099e..5208873 100644 --- a/javascript/xuanran.wang/bme/js/Common.js +++ b/javascript/xuanran.wang/bme/js/Common.js @@ -57,7 +57,7 @@ function submitCallback(detailTable, detail2PayProportionId){ let rowIndex = rowArr[i]; if(rowIndex !== ""){ let field = `${detail2PayProportionId}_${rowIndex}`; - sum += parseFloat(WfForm.getFieldValue(field));//遍历明细行字段 + sum = addFloat(sum, parseFloat(WfForm.getFieldValue(field)));//遍历明细行字段 } } console.log('sum => ', sum) @@ -65,6 +65,11 @@ function submitCallback(detailTable, detail2PayProportionId){ }); } +function addFloat(a, b) { + let precision = Math.pow(10, 10); // 设置精度,根据需要调整 + return (Math.round(a * precision) + Math.round(b * precision)) / precision; +} + /** * 明细表字段发生变化进行日期计算 * @param bindField diff --git a/javascript/xuanran.wang/longgong/NewProductTest.js b/javascript/xuanran.wang/longgong/NewProductTest.js index ca63af7..fe457d8 100644 --- a/javascript/xuanran.wang/longgong/NewProductTest.js +++ b/javascript/xuanran.wang/longgong/NewProductTest.js @@ -1,27 +1,27 @@ // 首台销售日期 -const firstSaleDateField = WfForm.convertFieldNameToId("stxsrq"); +var firstSaleDateField = WfForm.convertFieldNameToId("stxsrq"); // 跟踪时间 -const trackTimeField = WfForm.convertFieldNameToId("gzsj"); +var trackTimeField = WfForm.convertFieldNameToId("gzsj"); // 跟踪时间为三个月以内 -const threeMonthIndex = 1; +var threeMonthIndex = 1; // 是否提交等待节点 -const submitWaitNode = WfForm.convertFieldNameToId("sftjddjd"); +var submitWaitNode = WfForm.convertFieldNameToId("sftjddjd"); // 下次超时提醒日期 -const timeoutRemindDateFiled = WfForm.convertFieldNameToId("cstxrq"); +var timeoutRemindDateFiled = WfForm.convertFieldNameToId("cstxrq"); // 跟踪天数 <= 1 ? 15 : 30; -const trackingDaysField = WfForm.convertFieldNameToId("gzts") +var trackingDaysField = WfForm.convertFieldNameToId("gzts") // 跟踪触发行数 -const trackingLineField = WfForm.convertFieldNameToId("gzcfxs"); -$(() => { - let detail2LineNum = WfForm.getDetailRowCount("detail_2"); +var trackingLineField = WfForm.convertFieldNameToId("gzcfxs"); +jQuery(document).ready(function (){ + var detail2LineNum = WfForm.getDetailRowCount("detail_2"); // let firstTrack = Boolean(true); // if (new Date(firstSaleDate) < new Date(currentDate) && dayDiff > 0) { // firstTrack = false; // } // console.log('firstTrack ', firstTrack) // 到达节点次数 - const nodeNum = getNodeNum(); - let trackingLine = parseInt(WfForm.getFieldValue(trackingLineField)); + var nodeNum = getNodeNum(); + var trackingLine = parseInt(WfForm.getFieldValue(trackingLineField)); // 如果不是则自动添加一行明细让他自己填写 if (detail2LineNum < trackingLine && detail2LineNum < nodeNum) { console.log('添加一行明细!'); @@ -33,32 +33,32 @@ $(() => { return; } initTimeoutDate(); - WfForm.bindFieldChangeEvent(`${firstSaleDateField},${trackTimeField}`,()=>{ + WfForm.bindFieldChangeEvent(firstSaleDateField + "," + trackTimeField,function (){ initTimeoutDate(); }); }); function getNodeNum(){ - let firstSaleDate = WfForm.getFieldValue(firstSaleDateField); + var firstSaleDate = WfForm.getFieldValue(firstSaleDateField); console.log('首台销售日期 ', firstSaleDate); - let currentDate = getCurrentDate(); - let dayDiff = getDaysDiff(firstSaleDate, currentDate); + var currentDate = getCurrentDate(); + var dayDiff = getDaysDiff(firstSaleDate, currentDate); console.log('当前天数与首台销售日期相差天数 : ', dayDiff) - let trackingDays = WfForm.getFieldValue(trackingDaysField); + var trackingDays = WfForm.getFieldValue(trackingDaysField); return Math.floor(dayDiff / trackingDays) + 1; } function initTimeoutDate(){ console.log('==== initTimeoutDate begin ====') - let firstSaleDate = WfForm.getFieldValue(firstSaleDateField); - const nodeNum = getNodeNum(); + var firstSaleDate = WfForm.getFieldValue(firstSaleDateField); + var nodeNum = getNodeNum(); console.log('到达节点次数 ', nodeNum); - let trackingDays = WfForm.getFieldValue(trackingDaysField); + var trackingDays = WfForm.getFieldValue(trackingDaysField); console.log('跟踪天数 ', trackingDays); - let computeTimeoutDate = addDays(firstSaleDate, nodeNum * trackingDays); + var computeTimeoutDate = addDays(firstSaleDate, nodeNum * trackingDays); console.log('计算下次超时日期 ', computeTimeoutDate); - let trackingLine = parseInt(WfForm.getFieldValue(trackingLineField)); - let detail2LineNum = WfForm.getDetailRowCount("detail_2"); + var trackingLine = parseInt(WfForm.getFieldValue(trackingLineField)); + var detail2LineNum = WfForm.getDetailRowCount("detail_2"); setTimeout(()=>{ WfForm.changeFieldValue(timeoutRemindDateFiled, {value: computeTimeoutDate}); // 判断流程提交走向 @@ -72,7 +72,7 @@ function initTimeoutDate(){ if (detail2LineNum < trackingLine) { WfForm.showMessage('请填写明细表信息!'); detail2LineNum = WfForm.getDetailRowCount("detail_2"); - for (let i = 0; i < trackingLine - parseInt(detail2LineNum); i++) { + for (var i = 0; i < trackingLine - parseInt(detail2LineNum); i++) { WfForm.addDetailRow("detail_2", {}); } return; @@ -89,8 +89,8 @@ function initTimeoutDate(){ function getDaysDiff(date1, date2) { date1 = new Date(date1); date2 = new Date(date2); - const oneDay = 24 * 60 * 60 * 1000; // 一天的毫秒数 - const timeDiff = Math.abs(date1.getTime() - date2.getTime()); // 两个日期对象的毫秒数差值 + var oneDay = 24 * 60 * 60 * 1000; // 一天的毫秒数 + var timeDiff = Math.abs(date1.getTime() - date2.getTime()); // 两个日期对象的毫秒数差值 // 将毫秒数差值转换为天数差值并四舍五入 return Math.round(timeDiff / oneDay); } @@ -100,14 +100,14 @@ function getCurrentDate() { } function parseDate(date) { - const currentYear = date.getFullYear(); - const currentMonth = date.getMonth() + 1; // getMonth()返回0~11,需要加1 - const currentDay = date.getDate(); + var currentYear = date.getFullYear(); + var currentMonth = date.getMonth() + 1; // getMonth()返回0~11,需要加1 + var currentDay = date.getDate(); return currentYear + '-' + currentMonth + '-' + currentDay; } function addDays(date, days) { - const newDate = new Date(date); + var newDate = new Date(date); newDate.setDate(newDate.getDate() + days); console.log('newDate ', newDate) return parseDate(newDate); diff --git a/src/main/java/aiyh/utils/ecologyutil/timeutil/TimeUtil.java b/src/main/java/aiyh/utils/ecologyutil/timeutil/TimeUtil.java new file mode 100644 index 0000000..267fb50 --- /dev/null +++ b/src/main/java/aiyh/utils/ecologyutil/timeutil/TimeUtil.java @@ -0,0 +1,70 @@ +package aiyh.utils.ecologyutil.timeutil; + +import aiyh.utils.Util; +import aiyh.utils.httpUtil.cushttpclasses.CusHttpServletRequest; +import aiyh.utils.httpUtil.cushttpclasses.CusHttpSession; +import com.alibaba.fastjson.JSONObject; +import com.engine.hrm.cmd.permissiontoadjust.ProcessDataCmd; +import org.apache.log4j.Logger; +import weaver.hrm.User; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import java.util.HashMap; +import java.util.Map; + + +/** + * ecology权限相关方法 + */ +public class TimeUtil { + + private static final Logger logger = Util.getLogger(); + + /** + * 触发标准权限转移 转移待办已办等信息 + * + * @param param 入参按需填写如下等参数 + * fromid + * toid + * T133All + * T133AllNum + * @return + */ + public static JSONObject moveRight(JSONObject param) { + JSONObject result = new JSONObject(); + try { + logger.info("RightMoveUtil moveRight begin;param:" + param.toJSONString()); + Map params = new HashMap<>(); + for (Object key : param.keySet()) { + params.put(key.toString(), param.get(key)); + } + HttpServletRequest request = new CusHttpServletRequest() { + @Override + public String getParameter(String s) { + return param.getString(s); + } + + @Override + public HttpSession getSession(boolean b) { + HttpSession session = new CusHttpSession() { + @Override + public Object getAttribute(String s) { + return new User(1); + } + }; + return session; + } + }; + ProcessDataCmd cmd = new ProcessDataCmd(params, request, new User(1)); + Map execute = cmd.execute(null); + result = new JSONObject(execute); + logger.info("RightMoveUtil moveRight end;result:" + execute); + return result; + } catch (Throwable e) { + logger.error("RightMoveUtil moveRight error;message:" + e.getMessage()); + return result; + } + } + +} \ No newline at end of file diff --git a/src/main/java/com/api/xuanran/wang/eny/export_excel/controller/ExportExcelController.java b/src/main/java/com/api/xuanran/wang/eny/export_excel/controller/ExportExcelController.java index cc02515..eca4517 100644 --- a/src/main/java/com/api/xuanran/wang/eny/export_excel/controller/ExportExcelController.java +++ b/src/main/java/com/api/xuanran/wang/eny/export_excel/controller/ExportExcelController.java @@ -1,14 +1,23 @@ package com.api.xuanran.wang.eny.export_excel.controller; +import aiyh.utils.Util; +import com.api.xuanran.wang.eny.export_excel.entity.CusExportExcelConfigMain; +import com.api.xuanran.wang.eny.export_excel.service.ExportExcelServiceImpl; +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; +import weaver.general.TimeUtil; + import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.POST; +import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import java.nio.charset.StandardCharsets; +import javax.ws.rs.core.StreamingOutput; +import java.net.URLEncoder; +import java.util.Objects; /** *

安永 建模自定义导出excel

@@ -19,14 +28,42 @@ import java.nio.charset.StandardCharsets; @Path("/wxr/eny/excel") public class ExportExcelController { - @POST + private final ExportExcelServiceImpl exportExcelService = new ExportExcelServiceImpl(); + private final Logger logger = Util.getLogger(); + + @GET @Path("/cus_port") - @Produces(MediaType.TEXT_PLAIN) + @Produces(MediaType.APPLICATION_OCTET_STREAM) public Response exportExcel(@Context HttpServletRequest request, @Context HttpServletResponse response){ - return null; -// return Response.ok(streamingOutput, MediaType.APPLICATION_OCTET_STREAM).type("application/zip") -// .header("Content-Disposition", "attachment;filename=" + -// new String(packageName.toString().getBytes("GBK"), StandardCharsets.ISO_8859_1) + ".zip").build(); + String onlyMark = request.getParameter("onlyMark"); + String dataId = request.getParameter("dataId"); + if(StringUtils.isBlank(onlyMark) || StringUtils.isBlank(dataId)){ + logger.error("配置唯一标识或dataId为空!"); + return null; + } + CusExportExcelConfigMain config = exportExcelService.getConfig(onlyMark); + if(Objects.isNull(config)){ + logger.error("该唯一标识在配置表中没有找到配置数据!"); + return null; + } + try { + String suffix = config.getTemplate_path().substring(config.getTemplate_path().lastIndexOf(".")); + StreamingOutput os = exportExcelService.exportExcel(config, dataId, suffix); +// String mimeType = ".xls".equals(suffix) ? "application/vnd.ms-excel":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; + String fileName = request.getParameter("fileName"); + if(StringUtils.isBlank(fileName)){ + fileName = TimeUtil.getCurrentDateString() + config.getFile_name(); + } + fileName += suffix; + fileName = URLEncoder.encode(fileName, "UTF-8"); + logger.info("文件名称 : " + fileName); + return Response.ok(os, MediaType.APPLICATION_OCTET_STREAM) + .header("Content-Disposition", "attachment; filename*=UTF-8''" + fileName).build(); + }catch (Exception e){ + logger.error("生成excel文件异常 : "); + logger.error(Util.getErrString(e)); + return null; + } } } diff --git a/src/main/java/com/api/xuanran/wang/eny/export_excel/entity/CusExportExcelConfigDetail.java b/src/main/java/com/api/xuanran/wang/eny/export_excel/entity/CusExportExcelConfigDetail.java index 59a203d..b41eeea 100644 --- a/src/main/java/com/api/xuanran/wang/eny/export_excel/entity/CusExportExcelConfigDetail.java +++ b/src/main/java/com/api/xuanran/wang/eny/export_excel/entity/CusExportExcelConfigDetail.java @@ -12,6 +12,6 @@ import lombok.Data; public class CusExportExcelConfigDetail { private String excel_row; private String model_field; - private String get_value_type; + private int get_value_type; private String value_context; } diff --git a/src/main/java/com/api/xuanran/wang/eny/export_excel/entity/CusExportExcelConfigMain.java b/src/main/java/com/api/xuanran/wang/eny/export_excel/entity/CusExportExcelConfigMain.java index 84890b9..398aa8c 100644 --- a/src/main/java/com/api/xuanran/wang/eny/export_excel/entity/CusExportExcelConfigMain.java +++ b/src/main/java/com/api/xuanran/wang/eny/export_excel/entity/CusExportExcelConfigMain.java @@ -15,5 +15,6 @@ public class CusExportExcelConfigMain { private String model_table; private String template_path; private String file_name; + private String table_name; private List configDetailList; } diff --git a/src/main/java/com/api/xuanran/wang/eny/export_excel/mapper/ExportExcelMapper.java b/src/main/java/com/api/xuanran/wang/eny/export_excel/mapper/ExportExcelMapper.java index aa0d63b..3a96430 100644 --- a/src/main/java/com/api/xuanran/wang/eny/export_excel/mapper/ExportExcelMapper.java +++ b/src/main/java/com/api/xuanran/wang/eny/export_excel/mapper/ExportExcelMapper.java @@ -3,8 +3,6 @@ package com.api.xuanran.wang.eny.export_excel.mapper; import aiyh.utils.annotation.recordset.*; import com.api.xuanran.wang.eny.export_excel.entity.CusExportExcelConfigDetail; import com.api.xuanran.wang.eny.export_excel.entity.CusExportExcelConfigMain; -import com.api.xuanran.wang.traffic_bank.email.entity.EmailOutConfigDetail; -import com.api.xuanran.wang.traffic_bank.email.entity.EmailOutConfigMain; import java.util.List; import java.util.Map; @@ -17,13 +15,17 @@ import java.util.Map; */ @SqlMapper public interface ExportExcelMapper { - @Select("select * from uf_mod_export_excel where model_table = #{modelTable}") + @Select("SELECT a.*,b.tablename as table_name " + + "FROM uf_mod_export_excel a " + + "left join workflow_mode_table_view b " + + "on a.model_table = b.id " + + "where only_mark = #{onlyMark}") @CollectionMappings({ @CollectionMapping(property = "configDetailList", column = "id", id = @Id(value = Integer.class, methodId = 1)) }) - CusExportExcelConfigMain selectConfigByModelId(@ParamMapper("modelTable") int modelTable); + CusExportExcelConfigMain selectConfigByOnlyMark(@ParamMapper("onlyMark") String onlyMark); /** *

查询配置表明细表信息

@@ -39,6 +41,9 @@ public interface ExportExcelMapper { @CollectionMethod(1) List selectConfigDetail(@ParamMapper("mainId") int mainId); + @Select(custom = true) + Map selectCustomerSqlMap(@SqlString String sql, Map map); + @Select(custom = true) String selectCustomerSql(@SqlString String sql, Map map); } diff --git a/src/main/java/com/api/xuanran/wang/eny/export_excel/service/ExportExcelServiceImpl.java b/src/main/java/com/api/xuanran/wang/eny/export_excel/service/ExportExcelServiceImpl.java index a975574..b7f17b6 100644 --- a/src/main/java/com/api/xuanran/wang/eny/export_excel/service/ExportExcelServiceImpl.java +++ b/src/main/java/com/api/xuanran/wang/eny/export_excel/service/ExportExcelServiceImpl.java @@ -1,8 +1,27 @@ package com.api.xuanran.wang.eny.export_excel.service; import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import com.api.xuanran.wang.eny.export_excel.entity.CusExportExcelConfigDetail; import com.api.xuanran.wang.eny.export_excel.entity.CusExportExcelConfigMain; import com.api.xuanran.wang.eny.export_excel.mapper.ExportExcelMapper; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; +import org.apache.log4j.Logger; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import weaver.general.GCONST; + +import javax.ws.rs.core.StreamingOutput; +import java.io.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; /** *

自定义导出excel

@@ -12,16 +31,143 @@ import com.api.xuanran.wang.eny.export_excel.mapper.ExportExcelMapper; */ public class ExportExcelServiceImpl { private final ExportExcelMapper exportExcelMapper = Util.getMapper(ExportExcelMapper.class); - + private final Logger log = Util.getLogger(); /** *

根据模块id查询配置

+ * + * @param onlyMark 唯一标识 + * @return 配置对象 * @author xuanran.wang * @dateTime 2023/6/7 11:28 - * @param modelId 模块id - * @return 配置对象 **/ - public CusExportExcelConfigMain getConfig(int modelId){ - return exportExcelMapper.selectConfigByModelId(modelId); + public CusExportExcelConfigMain getConfig(String onlyMark) { + return exportExcelMapper.selectConfigByOnlyMark(onlyMark); + } + + /** + *

导出excel

+ * @author xuanran.wang + * @dateTime 2023/6/7 16:26 + * @param config 配置对象 + * @param dataId 数据ID + * @param suffix 文件后缀 + * @return 输出流 + **/ + public StreamingOutput exportExcel(CusExportExcelConfigMain config, + String dataId, + String suffix) throws IOException { + return outputStream -> { + String filePath = config.getTemplate_path(); + filePath = parseConfigPath(filePath); + if(!new File(filePath).exists()){ + throw new IOException("在服务器中未找到模版文件!"); + } + String sql = "select * from " + config.getTable_name() + " where id in ( " + dataId + " )"; + Map map = exportExcelMapper.selectCustomerSqlMap(sql, new HashMap<>()); + if(MapUtils.isEmpty(map)){ + throw new CustomerException("模块数据查询为空!"); + } + List configDetailList = config.getConfigDetailList(); + List specialRow = new ArrayList<>(); + if(CollectionUtils.isNotEmpty(configDetailList)){ + specialRow = configDetailList.stream().map(CusExportExcelConfigDetail::getExcel_row).collect(Collectors.toList()); + } + FileInputStream fis = new FileInputStream(filePath); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + Workbook workbook; + if (".xls".equals(suffix)) { + workbook = new HSSFWorkbook(fis); + }else { + workbook = new XSSFWorkbook(fis); + } + try { + Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表 + for (Row row : sheet) { + for (Cell cell : row) { + String cellValue = cell.getStringCellValue(); + String replacedValue = replacePlaceholder(cellValue, map, specialRow, config); + cell.setCellValue(replacedValue); + } + } + workbook.write(bos); + bos.writeTo(outputStream); + outputStream.flush(); + }catch (Exception e){ + throw new CustomerException("replacePlaceholder error ", e); + }finally { + try { + outputStream.close(); + bos.close(); + workbook.close(); + fis.close(); + }catch (Exception e){ + log.error("关流异常 : " + e.getMessage()); + } + } + }; + } + + /** + *

将excel模版中的参数进行替换

+ * @author xuanran.wang + * @dateTime 2023/6/7 14:32 + * @param cellValue 单元格数据 + * @param modelMap 建模数据集合 + * @param specialRow 明细1配置的数据 + * @param config 配置对象 + * @return 替换后的值 + **/ + public String replacePlaceholder(String cellValue, Map modelMap, List specialRow, CusExportExcelConfigMain config){ + Pattern pattern = Pattern.compile("\\{(.*?)}"); // 匹配以{}包裹的内容 + Matcher matcher = pattern.matcher(cellValue); + StringBuffer replacedValue = new StringBuffer(); + while (matcher.find()) { + String placeholder = matcher.group(1); // 获取{}中的内容 + Object replacement = Util.null2DefaultStr(modelMap.get(placeholder),""); + // sql特殊处理 + if(CollectionUtils.isNotEmpty(specialRow) && specialRow.contains(placeholder)){ + List collect = config.getConfigDetailList().stream().filter(item -> item.getExcel_row().equals(placeholder)).collect(Collectors.toList()); + if(CollectionUtils.isNotEmpty(collect)){ + CusExportExcelConfigDetail configDetail = collect.get(0); + if(configDetail.getGet_value_type() == 2){ + String cusSql = configDetail.getValue_context(); + cusSql = Util.sbc2dbcCase(cusSql); + replacement = exportExcelMapper.selectCustomerSql(cusSql, modelMap); + } + } + } + // 根据需要进行替换的逻辑 + matcher.appendReplacement(replacedValue, replacement.toString()); + } + matcher.appendTail(replacedValue); + return replacedValue.toString(); + } + + /** + *

解析请求xls模板位置

+ * @param configFilePath 模板文件路径 + * @return 解析后的文件路径 + */ + public String parseConfigPath(String configFilePath){ + StringBuilder filePath = new StringBuilder(GCONST.getSysFilePath()); + int beginIndex = configFilePath.indexOf("."); + int endIndex = configFilePath.lastIndexOf("."); + if(beginIndex == endIndex){ + filePath.append(configFilePath); + }else { + String[] pathArr = configFilePath.split("\\."); + for (int i = 0; i < pathArr.length - 2; i++) { + if(i != 0){ + filePath.append(File.separator); + } + filePath.append(pathArr[i]); + } + filePath.append(File.separator) + .append(pathArr[pathArr.length - 2]) + .append(".") + .append(pathArr[pathArr.length - 1]); + } + return filePath.toString(); } diff --git a/src/main/java/com/api/xuanran/wang/sh_bigdata/sso/service/impl/OtherSystemToOAServiceImpl.java b/src/main/java/com/api/xuanran/wang/sh_bigdata/sso/service/impl/OtherSystemToOAServiceImpl.java index c07bd3c..460558b 100644 --- a/src/main/java/com/api/xuanran/wang/sh_bigdata/sso/service/impl/OtherSystemToOAServiceImpl.java +++ b/src/main/java/com/api/xuanran/wang/sh_bigdata/sso/service/impl/OtherSystemToOAServiceImpl.java @@ -69,7 +69,7 @@ public class OtherSystemToOAServiceImpl implements OtherSystemToOAService { String sql = "select id from hrmresource where " + Util.null2DefaultStr(ShBigDataUtil.getPropertiesValByKey("ssoOaCompareField"),"outkey") + " = #{outKey}"; int id = otherSystemToOAMapper.selectUserIdByOutKey(sql, oaOutKey); if(id < 0){ - throw new CustomerException(Util.logStr("code : {} not found in OA!", id)); + throw new CustomerException(Util.logStr("code : {} not found in OA!", oaOutKey)); } return id; } diff --git a/src/main/java/weaver/xuanran/wang/common/entity/CusSuccess.java b/src/main/java/weaver/xuanran/wang/common/entity/CusSuccess.java new file mode 100644 index 0000000..3bb23ba --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/common/entity/CusSuccess.java @@ -0,0 +1,27 @@ +package weaver.xuanran.wang.common.entity; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import weaver.xuanran.wang.common.service.CusDataDecipher; + + +/** + *

自定义请求条件

+ * + * @author xuanran.wang + * @date 2023/4/6 19:34 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class CusSuccess { + private String successField; + private Object successValue; + private String errorMsg; + private String dataKey; + private Object response; + private CusDataDecipher cusDataDecipher; +} diff --git a/src/main/java/weaver/xuanran/wang/common/mapper/CommonMapper.java b/src/main/java/weaver/xuanran/wang/common/mapper/CommonMapper.java index 1a13798..d51b2b6 100644 --- a/src/main/java/weaver/xuanran/wang/common/mapper/CommonMapper.java +++ b/src/main/java/weaver/xuanran/wang/common/mapper/CommonMapper.java @@ -121,4 +121,7 @@ public interface CommonMapper { @BatchUpdate(custom = true) boolean updateModelInfoList(@SqlString String sql, @BatchSqlArgs List> params); + + @BatchInsert(custom = true) + boolean batchInsertModel(@SqlString String sql,@BatchSqlArgs List> collect); } diff --git a/src/main/java/weaver/xuanran/wang/common/service/CusDataDecipher.java b/src/main/java/weaver/xuanran/wang/common/service/CusDataDecipher.java new file mode 100644 index 0000000..973850f --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/common/service/CusDataDecipher.java @@ -0,0 +1,15 @@ +package weaver.xuanran.wang.common.service; + +import aiyh.utils.httpUtil.ResponeVo; + +import java.util.Map; + +/** + *

自定义解密类

+ * + * @author xuanran.wang + * @date 2023/4/10 13:20 + */ +public interface CusDataDecipher { + Map decoder(ResponeVo responeVo); +} diff --git a/src/main/java/weaver/xuanran/wang/common/util/CommonUtil.java b/src/main/java/weaver/xuanran/wang/common/util/CommonUtil.java index 6d2b236..e52a8a8 100644 --- a/src/main/java/weaver/xuanran/wang/common/util/CommonUtil.java +++ b/src/main/java/weaver/xuanran/wang/common/util/CommonUtil.java @@ -708,5 +708,20 @@ public class CommonUtil { return tableName; } + /** + *

构建get url

+ * @author xuanran.wang + * @dateTime 2023/6/8 16:51 + * @param url 接口地址 + * @param query 请求参数 + * @return url + **/ + public static String buildGetUrl(String url, Map query){ + StringBuilder sb = new StringBuilder(url + "?"); + for (Map.Entry entry : query.entrySet()) { + sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&"); + } + return sb.substring(0, sb.lastIndexOf("&")); + } } diff --git a/src/main/java/weaver/xuanran/wang/common/util/CusData2OA.java b/src/main/java/weaver/xuanran/wang/common/util/CusData2OA.java index 28f1680..a35cf3e 100644 --- a/src/main/java/weaver/xuanran/wang/common/util/CusData2OA.java +++ b/src/main/java/weaver/xuanran/wang/common/util/CusData2OA.java @@ -1,19 +1,26 @@ package weaver.xuanran.wang.common.util; +import aiyh.utils.ThreadPoolConfig; import aiyh.utils.Util; import aiyh.utils.annotation.recordset.BatchUpdate; import aiyh.utils.excention.CustomerException; +import com.alibaba.fastjson.JSONObject; +import com.weaver.general.TimeUtil; import org.apache.axis2.databinding.types.xsd._float; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import weaver.formmode.data.ModeDataIdUpdate; import weaver.formmode.setup.ModeRightInfo; import weaver.xuanran.wang.common.mapper.CommonMapper; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; /** *

自定义数据写入oa

@@ -26,24 +33,25 @@ public class CusData2OA { private static final Logger log = Util.getLogger(); private static final String TABLE_NAME_PLACEHOLDER = "#\\{tableName}"; + private static final ExecutorService threadPoolInstance = ThreadPoolConfig.createThreadPoolInstance(); + public static String writeToModel(String modelId, String uniqueSql, Map params){ - return baseExecute(modelId, uniqueSql, Collections.singletonList(params)).get(0); + return baseExecute(modelId, uniqueSql, Collections.singletonList(params), null).get(0); } public static String writeToModel(String modelId, Map params){ - return baseExecute(modelId, "", Collections.singletonList(params)).get(0); + return baseExecute(modelId, "", Collections.singletonList(params), null).get(0); } - public static List batchWriteToModel(String modelId, List> params){ - return baseExecute(modelId, "", params); + public static List batchWriteToModel(String modelId, List> params, CountDownLatch latch){ + return baseExecute(modelId, "", params, latch); } public static List batchWriteToModel(String modelId, String uniqueSql, List> params){ - return baseExecute(modelId, uniqueSql, params); + return baseExecute(modelId, uniqueSql, params, null); } - @BatchUpdate - public static List baseExecute(String modelId, String uniqueSql, List> params){ + public static List baseExecute(String modelId, String uniqueSql, List> params, CountDownLatch latch){ int modelIdInt = Util.getIntValue(modelId, -1); String tableName = CommonUtil.checkModelId(modelIdInt); if(modelIdInt < 0 || StringUtils.isBlank(tableName)){ @@ -51,39 +59,99 @@ public class CusData2OA { } uniqueSql = Util.sbc2dbcCase(uniqueSql); uniqueSql = uniqueSql.replaceAll(TABLE_NAME_PLACEHOLDER, tableName); - String modelDataId = ""; List delList = new ArrayList<>(); List modelDataList = new ArrayList<>(); String updateSql = ""; - for (Map param : params) { - log.info("写入日志参数 : " + com.alibaba.fastjson.JSONObject.toJSONString(param)); + String modelDataId = Util.null2DefaultStr(param.get("id"),""); if(StringUtils.isNotBlank(uniqueSql)){ modelDataId = commonMapper.selectCustomerSql(uniqueSql, param); } if(StringUtils.isBlank(modelDataId)){ modelDataId = Util.null2DefaultStr(Util.getModeDataId(tableName, modelIdInt, 1),""); delList.add(modelDataId); - Util.rebuildModeDataShare(1, tableName, Util.getIntValue(modelDataId, -1)); + param.put("id",modelDataId); } if(StringUtils.isBlank(updateSql)){ updateSql = buildUpdateSql(tableName, param); } - param.put("id",modelDataId); modelDataList.add(modelDataId); } try { - log.info("updateSql => " + updateSql); if (!commonMapper.updateModelInfoList(updateSql, params)) { throw new CustomerException("update model data sql execute error!"); } + threadPoolInstance.submit(()->{ + log.info("需要重构的数据 : " + JSONObject.toJSONString(modelDataList)); + for (String id : modelDataList) { + if(StringUtils.isBlank(id)){ + continue; + } + Util.rebuildModeDataShare(1, tableName, Util.getIntValue(id, -1)); + } + }); }catch (Exception e){ CommonUtil.deleteDataByIds(delList, tableName); throw new CustomerException(e); } + if(latch != null){ + for (int i = 0; i < modelDataList.size(); i++) { + latch.countDown(); + } + } return modelDataList; } + public static void baseInsertAndUpdate(String modelId, List> params, CountDownLatch latch){ + int modelIdInt = Util.getIntValue(modelId, -1); + String tableName = CommonUtil.checkModelId(modelIdInt); + if(modelIdInt < 0 || StringUtils.isBlank(tableName)){ + throw new CustomerException("modelId can not < 0 or modelTableName can not empty!"); + } + String updateSql = ""; + String insertSql = ""; + List> updateParams = new ArrayList<>(); + List> insertParams = new ArrayList<>(); + for (Map param : params) { + String modelDataId = Util.null2DefaultStr(param.get("id"),""); + if(StringUtils.isBlank(modelDataId)){ + insertParams.add(param); + param.put("modedatacreater","1"); + param.put("formmodeid", modelId); + param.put("modedatacreatedate", TimeUtil.getCurrentDateString()); + param.put("modedatacreatetime", TimeUtil.getOnlyCurrentTimeString()); + }else { + updateParams.add(param); + } + if(StringUtils.isBlank(updateSql)){ + updateSql = buildUpdateSql(tableName, param); + } + if(StringUtils.isBlank(insertSql)){ + insertSql = buildInsertSql(tableName, modelId, param); + } + } + try { + if(CollectionUtils.isNotEmpty(updateParams)){ + if (!commonMapper.updateModelInfoList(updateSql, params)) { + throw new CustomerException("update model data sql execute error!"); + } + } + if(CollectionUtils.isNotEmpty(insertParams)){ + if (!commonMapper.batchInsertModel(insertSql, params)) { + throw new CustomerException("insert model data sql execute error!"); + } + } + }catch (Exception e){ + throw new CustomerException(e); + }finally { + if(latch != null){ + for (int i = 0; i < params.size(); i++) { + latch.countDown(); + } + } + } + } + public static String buildUpdateSql(String tableName, Map params) { StringBuilder sqlSb = new StringBuilder("update ") .append(tableName) @@ -98,4 +166,23 @@ public class CusData2OA { sqlSb.append(" where id = #{item.id}"); return sqlSb.toString(); } + + public static String buildInsertSql(String tableName, String modelId,Map params) { + StringBuilder sqlSb = new StringBuilder("insert into ") + .append(tableName) + .append(" ("); + StringBuilder fields = new StringBuilder(); + StringBuilder values = new StringBuilder(); + for (Map.Entry entry : params.entrySet()) { + fields.append(entry.getKey()).append(","); + values.append("#{item.") + .append(entry.getKey()) + .append("}") + .append(","); + } + fields.deleteCharAt(fields.length() - 1); + values.deleteCharAt(values.length() - 1); + sqlSb.append(fields).append(" ) ").append(" values ( ").append(values).append(" )"); + return sqlSb.toString(); + } } diff --git a/src/main/java/weaver/xuanran/wang/common/util/RequestMasterPlate.java b/src/main/java/weaver/xuanran/wang/common/util/RequestMasterPlate.java new file mode 100644 index 0000000..1288eef --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/common/util/RequestMasterPlate.java @@ -0,0 +1,78 @@ +package weaver.xuanran.wang.common.util; + +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import aiyh.utils.httpUtil.ResponeVo; +import aiyh.utils.httpUtil.util.HttpUtils; +import com.alibaba.fastjson.JSON; +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; +import weaver.xuanran.wang.common.entity.CusSuccess; + +import java.io.IOException; +import java.util.Map; + +/** + *

请求模版方法

+ * + * @author xuanran.wang + * @date 2023/4/4 11:51 + */ +public class RequestMasterPlate { + private final Logger log = Util.getLogger(); + private final HttpUtils httpUtils = new HttpUtils(); + private static final int HTTP_SUCCESS_CODE = 200; + + public T apiGet(String url, Map params, Map headers, CusSuccess cusSuccess){ + ResponeVo responeVo; + try { + responeVo = httpUtils.apiGet(url, params, headers); + } catch (IOException e) { + throw new CustomerException(Util.logStr("发送请求发生异常! : {}", e.getMessage())); // 自定义异常类 create 2022/3/9 2:20 PM 构建日志字符串 + } + return parseResponse(url, responeVo, params, cusSuccess); + } + + public T apiPost(String url, Object o, Map headers, CusSuccess cusSuccess){ + ResponeVo responeVo; + try { + responeVo = httpUtils.apiPostObject(url, o, headers); + } catch (IOException e) { + throw new CustomerException(Util.logStr("发送请求发生异常! : {}", e.getMessage())); // 自定义异常类 create 2022/3/9 2:20 PM 构建日志字符串 + } + return parseResponse(url, responeVo, o, cusSuccess); + } + + public T parseResponse(String url, ResponeVo responseVo, Object o, CusSuccess cusSuccess){ + if (responseVo.getCode() != HTTP_SUCCESS_CODE) { // 相应状态码 + log.error(Util.logStr("can not fetch [{}],this request params is [{}]," + // 构建日志字符串 + "this request heard is [{}],but response status code is [{}]," + + "this response is [{}]", url, JSON.toJSON(o), JSON.toJSONString(httpUtils.getGlobalCache().header), responseVo.getCode(), // 相应状态码 + responseVo.getEntityString())); // 相应内容 + throw new CustomerException(Util.logStr("can not fetch [{}]", url)); // 自定义异常类 create 2022/3/9 2:20 PM 构建日志字符串 + } + Map response; + if(cusSuccess.getCusDataDecipher() != null){ + response = cusSuccess.getCusDataDecipher().decoder(responseVo); + }else { + response = responseVo.getResponseMap(); // 根据相应结果转化为map集合 + } + cusSuccess.setResponse(response); + String responseValue = Util.null2DefaultStr(response.get(cusSuccess.getSuccessField()), ""); + if (!responseValue.equals(Util.null2DefaultStr(cusSuccess.getSuccessValue(),""))) { + throw new CustomerException(Util.logStr("接口地址:[{}], 接口响应码不为: [{}], 接口响应信息: {}", url, cusSuccess.getSuccessValue(), Util.null2DefaultStr(response.get(cusSuccess.getErrorMsg()), ""))); // 自定义异常类 create 2022/3/9 2:20 PM 构建日志字符串 + } + String[] split = Util.null2DefaultStr(cusSuccess.getDataKey(),"").split("\\."); + int len = split.length; + if(len == 0 || StringUtils.isBlank(cusSuccess.getDataKey())){ + return (T)response; + } + for (int i = 0; i < len - 1; i++) { + response = (Map) response.get(split[i]); + } + return (T) response.get(split[len - 1]); + } + + + +} diff --git a/src/main/java/weaver/xuanran/wang/eny/data_async/entity/DataAsyncConfigDetail.java b/src/main/java/weaver/xuanran/wang/eny/data_async/entity/DataAsyncConfigDetail.java new file mode 100644 index 0000000..f9ec85f --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/eny/data_async/entity/DataAsyncConfigDetail.java @@ -0,0 +1,19 @@ +package weaver.xuanran.wang.eny.data_async.entity; + +import lombok.Data; + +/** + *

安永 - 建模数据同步配置明细表对象

+ * + * @author xuanran.wang + * @date 2023/6/8 15:21 + */ +@Data +public class DataAsyncConfigDetail { + private String interface_field; + private String model_field; + private int get_value_type; + private String value_context; + private int primary_key; + private String model_field_name; +} diff --git a/src/main/java/weaver/xuanran/wang/eny/data_async/entity/DataAsyncConfigMain.java b/src/main/java/weaver/xuanran/wang/eny/data_async/entity/DataAsyncConfigMain.java new file mode 100644 index 0000000..38cb2dc --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/eny/data_async/entity/DataAsyncConfigMain.java @@ -0,0 +1,23 @@ +package weaver.xuanran.wang.eny.data_async.entity; + +import lombok.Data; + +import java.util.List; + +/** + *

安永 - 建模数据同步配置主表对象

+ * + * @author xuanran.wang + * @date 2023/6/8 15:21 + */ +@Data +public class DataAsyncConfigMain { + private String model_id; + private String model_table; + private String async_url; + private String only_mark; + private String unique_sql; + private String remark; + private String table_name; + private List configDetailList; +} diff --git a/src/main/java/weaver/xuanran/wang/eny/data_async/entity/EyDataAsyncCusToken.java b/src/main/java/weaver/xuanran/wang/eny/data_async/entity/EyDataAsyncCusToken.java new file mode 100644 index 0000000..8a87e1f --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/eny/data_async/entity/EyDataAsyncCusToken.java @@ -0,0 +1,21 @@ +package weaver.xuanran.wang.eny.data_async.entity; + +import lombok.Data; + +/** + *

token实体类

+ * + * @author xuanran.wang + * @date 2023/4/7 23:29 + */ +@Data +public class EyDataAsyncCusToken { + /** + *

token

+ **/ + private String accessToken; + /** + *

过期时间戳

+ **/ + private long expiresTime; +} diff --git a/src/main/java/weaver/xuanran/wang/eny/data_async/job/ModelDataAsyncJob.java b/src/main/java/weaver/xuanran/wang/eny/data_async/job/ModelDataAsyncJob.java new file mode 100644 index 0000000..28dc251 --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/eny/data_async/job/ModelDataAsyncJob.java @@ -0,0 +1,75 @@ +package weaver.xuanran.wang.eny.data_async.job; + +import aiyh.utils.Util; +import aiyh.utils.annotation.PrintParamMark; +import aiyh.utils.annotation.RequiredMark; +import lombok.Setter; +import org.apache.log4j.Logger; +import weaver.interfaces.schedule.BaseCronJob; +import weaver.xuanran.wang.eny.data_async.entity.DataAsyncConfigMain; +import weaver.xuanran.wang.eny.data_async.service.DataAsyncServiceImpl; + +import java.util.HashMap; + +/** + *

安永 接口数据同步到建模

+ * + * @author xuanran.wang + * @date 2023/6/8 15:17 + */ +@Setter +public class ModelDataAsyncJob extends BaseCronJob { + + @RequiredMark(desc = "配置唯一标识") + @PrintParamMark + private String onlyMark; + + @PrintParamMark + @RequiredMark(desc = "token地址") + private String tokenUrl; + + @PrintParamMark + @RequiredMark(desc = "clientId") + private String clientId; + + @PrintParamMark + @RequiredMark(desc = "appId") + private String appId; + + @PrintParamMark + @RequiredMark(desc = "appSecret") + private String appSecret; + + @PrintParamMark + private String pageSize; + + @PrintParamMark + private String pageNo; + + @PrintParamMark + private String debug; + + private final DataAsyncServiceImpl dataAsyncService = new DataAsyncServiceImpl(); + + private final Logger log = Util.getLogger(); + + @Override + public void execute() { + try { + Util.verifyRequiredField(this); + dataAsyncService.setPageSize(Util.getIntValue(pageSize, 500)); + dataAsyncService.setPageNo(Util.getIntValue(pageNo, 1)); + dataAsyncService.setClientId(clientId); + dataAsyncService.setDebug(debug); + DataAsyncConfigMain config = dataAsyncService.getConfig(onlyMark); + HashMap params = new HashMap<>(); + params.put("clientId", clientId); + params.put("appId", appId); + params.put("appSecret", appSecret); + dataAsyncService.asyncData(config, tokenUrl, params); + }catch (Exception e){ + log.error("同步接口数据异常 : " + e.getMessage()); + log.error(Util.getErrString(e)); + } + } +} diff --git a/src/main/java/weaver/xuanran/wang/eny/data_async/mapper/DataAsyncMapper.java b/src/main/java/weaver/xuanran/wang/eny/data_async/mapper/DataAsyncMapper.java new file mode 100644 index 0000000..3716c54 --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/eny/data_async/mapper/DataAsyncMapper.java @@ -0,0 +1,58 @@ +package weaver.xuanran.wang.eny.data_async.mapper; + +import aiyh.utils.annotation.recordset.*; +import weaver.xuanran.wang.eny.data_async.entity.DataAsyncConfigDetail; +import weaver.xuanran.wang.eny.data_async.entity.DataAsyncConfigMain; + +import java.util.List; +import java.util.Map; + +/** + *

安永 - 建模数据同步 mapper

+ * + * @author xuanran.wang + * @date 2023/6/8 15:25 + */ +@SqlMapper +public interface DataAsyncMapper { + @Select("SELECT a.*,b.tablename as table_name, c.id as model_id " + + "FROM uf_ey_data_async a " + + "left join workflow_mode_table_view b " + + "on a.model_table = b.id " + + "left join modeinfo c " + + "on a.model_table = c.formid " + + "where only_mark = #{onlyMark}") + @CollectionMappings({ + @CollectionMapping(property = "configDetailList", + column = "id", + id = @Id(value = Integer.class, methodId = 1)) + }) + DataAsyncConfigMain selectConfigByOnlyMark(@ParamMapper("onlyMark") String onlyMark); + + /** + *

查询配置表明细表信息

+ * @author xuanran.wang + * @dateTime 2023/3/1 16:39 + * @param mainId 主表数据id + * @return 配置集合 + **/ + @Select("select a.*,b.fieldname model_field_name from uf_ey_data_async_dt1 a " + + "left join workflow_field_table_view b " + + "on a.model_field = b.id " + + "where mainid = #{mainId} and enable = 0") + @CollectionMethod(1) + List selectConfigDetail(@ParamMapper("mainId") int mainId); + + @Select(custom = true) + Map selectCustomerSqlMap(@SqlString String sql, Map map); + + @Select("select $t{foreignKey},id from $t{tableName} where $t{foreignKey} between #{min} and #{max}") + @CaseConversion(value = false) + List> selectDataIds(@ParamMapper("foreignKey") String foreignKey, + @ParamMapper("tableName") String tableName, + @ParamMapper("min") Integer min, + @ParamMapper("max") Integer max); + + @Select(custom = true) + String selectCustomerSql(@SqlString String sql, Map map); +} diff --git a/src/main/java/weaver/xuanran/wang/eny/data_async/service/DataAsyncServiceImpl.java b/src/main/java/weaver/xuanran/wang/eny/data_async/service/DataAsyncServiceImpl.java new file mode 100644 index 0000000..920dfe1 --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/eny/data_async/service/DataAsyncServiceImpl.java @@ -0,0 +1,385 @@ +package weaver.xuanran.wang.eny.data_async.service; + +import aiyh.utils.ThreadPoolConfig; +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import com.alibaba.fastjson.JSONObject; +import com.engine.common.util.ServiceUtil; +import com.engine.cube.service.ModeAppService; +import com.engine.cube.service.impl.ModeAppServiceImpl; +import lombok.Setter; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; +import weaver.formmode.setup.ModeRightInfoThread; +import weaver.general.TimeUtil; +import weaver.hrm.User; +import weaver.xuanran.wang.common.entity.CusSuccess; +import weaver.xuanran.wang.common.util.CommonUtil; +import weaver.xuanran.wang.common.util.CusData2OA; +import weaver.xuanran.wang.common.util.RequestMasterPlate; +import weaver.xuanran.wang.eny.data_async.entity.DataAsyncConfigDetail; +import weaver.xuanran.wang.eny.data_async.entity.DataAsyncConfigMain; +import weaver.xuanran.wang.eny.data_async.mapper.DataAsyncMapper; +import weaver.xuanran.wang.eny.data_async.util.EyDataAsyncTokenUtil; +import weaver.xuanran.wang.eny.data_async.util.ValueRuleMethod; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpSession; +import javax.servlet.http.HttpSessionContext; +import java.util.*; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + *

安永 - 建模数据同步

+ * + * @author xuanran.wang + * @date 2023/6/8 15:19 + */ +@Setter +public class DataAsyncServiceImpl { + + private final DataAsyncMapper asyncMapper = Util.getMapper(DataAsyncMapper.class); + + private final Logger log = Util.getLogger(); + + private final RequestMasterPlate requestMasterPlate = new RequestMasterPlate(); + + private final CusSuccess dataSuccess = CusSuccess.builder() + .successField("code") + .successValue(0) + .dataKey("data") + .errorMsg("msg") + .build(); + + private int pageSize = 100; + + private int pageNo = 1; + + private String clientId = ""; + + private String debug = "0"; + + private final ExecutorService threadPoolInstance = ThreadPoolConfig.createThreadPoolInstance(); + + /** + *

根据模块id查询配置

+ * + * @param onlyMark 唯一标识 + * @return 配置对象 + * @author xuanran.wang + * @dateTime 2023/6/7 11:28 + **/ + public DataAsyncConfigMain getConfig(String onlyMark) { + DataAsyncConfigMain config = asyncMapper.selectConfigByOnlyMark(onlyMark); + if(Objects.isNull(config) || CollectionUtils.isEmpty(config.getConfigDetailList())){ + throw new CustomerException("该唯一标识在配置表中未找到对应的配置!或存在该配置但是明细数据为空!"); + } + return config; + } + + /** + *

数据同步 有一个点 就是如果接口请求过程中报错了 怎么重新处理

+ * @author xuanran.wang + * @dateTime 2023/6/9 13:28 + * @param config 配置对象 + * @param tokenUrl token地址 + * @param params token 参数 + **/ + public void asyncData(DataAsyncConfigMain config, String tokenUrl, Map params){ + long startTime = System.currentTimeMillis(); + log.info("数据开始同步时间 : " + TimeUtil.getCurrentTimeString()); + String asyncUrl = config.getAsync_url(); + int total = Integer.MAX_VALUE; + int pageNo = this.pageNo; + int count = 0; + // 请求头 + HashMap header = new HashMap<>(); + header.put("client-id", clientId); + // url地址参数 + HashMap query = new HashMap<>(); + query.put("pageSize", pageSize); + CountDownLatch latch = null; + int preNum = 0; + // 如果不是第一页就先定位到指定位置 + if(pageNo > 1){ + count += (pageNo - 1) * pageSize; + preNum = count; + } + boolean show = true; + while (count < total){ + // 从缓存中获取token + String token = EyDataAsyncTokenUtil.getToken(tokenUrl, params); + header.put("Authorization", "Bearer " + token); + query.put("pageNo", pageNo); + // 构建请求url 拼接上分分页参数 + String url = CommonUtil.buildGetUrl(asyncUrl, query); + Map data; + List> maps; + try { + // 获取接口数据 + data = requestMasterPlate.apiPost(url, new HashMap<>(), header, dataSuccess); + total = Util.getIntValue(Util.null2DefaultStr(data.get("total"),""), -1); + if(show){ + log.info("接口数据条数total : " + total); + } + if(latch == null){ + // 应该传入 total / pageSize + latch = new CountDownLatch(total); + } + pageNo++; + count += pageSize; + List> list = (List>) data.get("list"); + // 进行数据处理 + maps = dealData(config, list); + show = false; + }catch (Exception e){ + for (int i = 0; i < pageSize; i++) { + if(latch != null){ + latch.countDown(); + } + } + log.error("请求异常 : " + e.getMessage() + " 当前页数 : " + pageNo); + if(latch != null){ + log.info("当前latch信号数量 : " + latch.getCount()); + } + continue; + } + CountDownLatch finalLatch = latch; + if(finalLatch.getCount() > 0 && maps.size() > 0){ + // 异步提交数据库处理 + threadPoolInstance.execute(()->{ + log.info("======================================================================================="); + log.info(Thread.currentThread().getName() + " 入库之前信号数量 : " + finalLatch.getCount()); + CusData2OA.baseInsertAndUpdate(config.getModel_id(), maps, finalLatch); + log.info(Thread.currentThread().getName() + " 入库之后信号数量 : " + finalLatch.getCount()); + log.info("======================================================================================="); + }); + } + } + try { + if(latch != null){ + log.info("preNum : " + preNum); + while (preNum-- > 0){ + latch.countDown(); + } + boolean await = latch.await(30, TimeUnit.MINUTES); + if(!await){ + throw new CustomerException("线程等待时间超过最大时间限制!"); + } + long endTime = System.currentTimeMillis(); + log.info("数据结束同步时间 : " + TimeUtil.getCurrentTimeString()); + rebuildRight(Util.getIntValue(config.getModel_id())); + log.info("同步耗时时间 " + (endTime - startTime) / 1000 + " s");// 等待所有转换操作完成 + } + } catch (Exception e) { + throw new CustomerException(e); + } + } + + /** + *

同步处理数据

+ * @author xuanran.wang + * @dateTime 2023/6/8 16:50 + * @param config 配置对象 + * @param data 接口数据 + **/ + public List> dealData(DataAsyncConfigMain config, List> data) { + List configDetailList = config.getConfigDetailList(); + List primaryKey = configDetailList.stream().filter(item -> item.getPrimary_key() == 0).collect(Collectors.toList()); + List> maps = new ArrayList<>(); + if(CollectionUtils.isNotEmpty(primaryKey)){ + // 模版-接口外键 + String modelFieldName = primaryKey.get(0).getModel_field_name(); + maps = data.stream().map(item -> convert(item, primaryKey.get(0).getInterface_field(), configDetailList)).filter(MapUtils::isNotEmpty).collect(Collectors.toList()); + // 进行排序 + Optional minClassId = maps.stream() + .map(map -> Util.getIntValue(Util.null2DefaultStr(map.get(modelFieldName),""),-1)) + .min(Comparator.naturalOrder()); + Optional maxClassId = maps.stream() + .map(map -> Util.getIntValue(Util.null2DefaultStr(map.get(modelFieldName),""),-1)) + .max(Comparator.naturalOrder()); + Integer min = minClassId.orElse(0); + Integer max = maxClassId.orElse(0); + // 按照外键排序并且在oa中范围查询出外键与oa数据的对应关系 + List> dataIdList = asyncMapper.selectDataIds(modelFieldName, config.getTable_name(), min, max); + if("1".equals(debug)){ + log.info("dataIdList : " + JSONObject.toJSONString(dataIdList)); + } + if(CollectionUtils.isNotEmpty(dataIdList)){ + HashMap idMap = parseListMap2Map(modelFieldName, "id", dataIdList); + if("1".equals(debug)){ + log.info("idMap : " + JSONObject.toJSONString(idMap)); + } + maps.forEach(item->{ + if("1".equals(debug)){ + log.info("item : " + JSONObject.toJSONString(item)); + } + String id = Util.null2DefaultStr(item.get(modelFieldName),""); + if("1".equals(debug)){ + log.info("id : " + id); + } + if(idMap.containsKey(id)){ + String oaId = idMap.get(id); + item.put("id",oaId); + } + }); + } + } + return maps; + } + + /** + *

将数据进行转换

+ * @author xuanran.wang + * @dateTime 2023/6/9 13:27 + * @param data 原始数据 + * @param foreignKey 外键 + * @param configDetailList 配置集合 + * @return 转换后的数据 + **/ + public Map convert(Map data, + String foreignKey, + List configDetailList){ + String foreignVal = Util.null2DefaultStr(data.get(foreignKey), ""); + if(StringUtils.isBlank(foreignVal)){ + return new HashMap<>(); + } + HashMap map = new HashMap<>(); + for (DataAsyncConfigDetail detail : configDetailList) { + map.put(detail.getModel_field_name(), ValueRuleMethod.VALUE_RULE_FUNCTION.get(detail.getGet_value_type()).apply(detail, data)); + } + return map; + } + + /** + *

将集合数据放到缓存中

+ * @author xuanran.wang + * @dateTime 2023/4/10 18:33 + * @param listMap 集合数据 + **/ + public static HashMap parseListMap2Map(String key, String value, List> listMap){ + if(CollectionUtils.isEmpty(listMap)){ + return new HashMap<>(); + } + HashMap res = new HashMap<>(); + listMap.forEach(map -> { + String outKey = Util.null2DefaultStr(map.get(key),""); + if(StringUtils.isNotBlank(outKey)){ + String id = Util.null2DefaultStr(map.get(value),""); + res.put(outKey, id); + } + }); + return res; + } + + public static ModeAppService modeAppService = ServiceUtil.getService(ModeAppServiceImpl.class, new User(1)); + + /** + *

模块数据全量权限重构

+ * @author xuanran.wang + * @dateTime 2023/6/9 13:28 + * @param modeId 模块id + **/ + public static void rebuildRight(int modeId){ + ModeRightInfoThread var5 = new ModeRightInfoThread(); + var5.setModeId(modeId); + var5.setRebulidFlag("1"); + var5.setSession(new HttpSession() { + @Override + public String getId() { + return null; + } + + @Override + public boolean isNew() { + return false; + } + + @Override + public long getCreationTime() { + return 0; + } + + @Override + public long getLastAccessedTime() { + return 0; + } + + @Override + public void setMaxInactiveInterval(int i) { + + } + + @Override + public int getMaxInactiveInterval() { + return 0; + } + + @Override + public Object getAttribute(String s) { + return null; + } + + @Override + public Enumeration getAttributeNames() { + return null; + } + + @Override + public void setAttribute(String s, Object o) { + + } + + @Override + public void removeAttribute(String s) { + + } + + @Override + public void invalidate() { + + } + + @Override + public HttpSessionContext getSessionContext() { + return null; + } + + @Override + public ServletContext getServletContext() { + return null; + } + + @Override + public Object getValue(String s) { + return null; + } + + @Override + public String[] getValueNames() { + return new String[0]; + } + + @Override + public void putValue(String s, Object o) { + + } + + @Override + public void removeValue(String s) { + + } + }); + var5.setUser(new User(1)); + var5.resetModeRight(); + } + + + + +} diff --git a/src/main/java/weaver/xuanran/wang/eny/data_async/service/convert/CusAsyncConvert.java b/src/main/java/weaver/xuanran/wang/eny/data_async/service/convert/CusAsyncConvert.java new file mode 100644 index 0000000..cd07430 --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/eny/data_async/service/convert/CusAsyncConvert.java @@ -0,0 +1,20 @@ +package weaver.xuanran.wang.eny.data_async.service.convert; + +import aiyh.utils.Util; +import org.apache.log4j.Logger; +import weaver.xuanran.wang.eny.data_async.entity.DataAsyncConfigDetail; +import weaver.xuanran.wang.sh_bigdata.org_hrm_async.entity.OrgHrmAsyncCache; +import weaver.xuanran.wang.sh_bigdata.org_hrm_async.entity.OrgHrmAsyncConfigDetail; + +import java.util.Map; + +/** + *

自定义转换接口

+ * + * @author xuanran.wang + * @date 2023/4/11 16:49 + */ +public interface CusAsyncConvert { + Logger log = Util.getLogger(); + Object cusConvert(DataAsyncConfigDetail configDetail, Map maps, Map pathParam); +} diff --git a/src/main/java/weaver/xuanran/wang/eny/data_async/service/convert/CusSubStringConvert.java b/src/main/java/weaver/xuanran/wang/eny/data_async/service/convert/CusSubStringConvert.java new file mode 100644 index 0000000..754d61c --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/eny/data_async/service/convert/CusSubStringConvert.java @@ -0,0 +1,37 @@ +package weaver.xuanran.wang.eny.data_async.service.convert; + +import aiyh.utils.Util; +import org.apache.commons.lang3.StringUtils; +import weaver.xuanran.wang.eny.data_async.entity.DataAsyncConfigDetail; + +import java.util.Map; + +/** + *

自定义转换

+ * + * @author xuanran.wang + * @date 2023/6/9 10:00 + */ +public class CusSubStringConvert implements CusAsyncConvert{ + @Override + public Object cusConvert(DataAsyncConfigDetail configDetail, Map maps, Map pathParam) { + try { + String interfaceField = configDetail.getInterface_field(); + if(StringUtils.isBlank(interfaceField)){ + return ""; + } + String value = Util.null2DefaultStr(maps.get(interfaceField),""); + if(StringUtils.isBlank(value)){ + return ""; + } + if (value.equals("00")) { + return "0"; + } else { + return value.replace("0", ""); + } + }catch (Exception e){ + log.error("CusSubStringConvert error : ",e); + } + return null; + } +} diff --git a/src/main/java/weaver/xuanran/wang/eny/data_async/service/convert/CusTimeConvert.java b/src/main/java/weaver/xuanran/wang/eny/data_async/service/convert/CusTimeConvert.java new file mode 100644 index 0000000..9188723 --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/eny/data_async/service/convert/CusTimeConvert.java @@ -0,0 +1,40 @@ +package weaver.xuanran.wang.eny.data_async.service.convert; + +import aiyh.utils.Util; +import org.apache.commons.lang3.StringUtils; +import weaver.xuanran.wang.eny.data_async.entity.DataAsyncConfigDetail; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; + +/** + *

时间戳转自定义时间格式字符串

+ * + * @author xuanran.wang + * @date 2023/6/9 09:53 + */ +public class CusTimeConvert implements CusAsyncConvert { + @Override + public Object cusConvert(DataAsyncConfigDetail configDetail, Map maps, Map pathParam) { + try { + String interfaceField = configDetail.getInterface_field(); + String format = Util.null2DefaultStr(pathParam.get("format"),"yyyy-MM-dd"); + String time; + if(StringUtils.isBlank(interfaceField)){ + time = String.valueOf(System.currentTimeMillis()); + }else { + time = Util.null2DefaultStr(maps.get(interfaceField),""); + if(StringUtils.isBlank(time)){ + return ""; + } + } + Date date = new Date(Long.parseLong(time)); + SimpleDateFormat sdf = new SimpleDateFormat(format); // 定义日期格式 + return Util.null2DefaultStr( sdf.format(date),""); // 将Date对象格式化为字 + }catch (Exception e){ + log.error("CusTimeConvert error : ",e); + } + return null; + } +} diff --git a/src/main/java/weaver/xuanran/wang/eny/data_async/util/EyDataAsyncTokenUtil.java b/src/main/java/weaver/xuanran/wang/eny/data_async/util/EyDataAsyncTokenUtil.java new file mode 100644 index 0000000..9ca81e4 --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/eny/data_async/util/EyDataAsyncTokenUtil.java @@ -0,0 +1,72 @@ +package weaver.xuanran.wang.eny.data_async.util; + +import aiyh.utils.Util; +import com.alibaba.fastjson.JSONObject; +import org.apache.log4j.Logger; +import weaver.xuanran.wang.common.entity.CusSuccess; +import weaver.xuanran.wang.common.util.RequestMasterPlate; +import weaver.xuanran.wang.eny.data_async.entity.EyDataAsyncCusToken; + +import java.util.HashMap; +import java.util.Map; + +/** + *

+ * + * @author xuanran.wang + * @date 2023/6/8 15:55 + */ +public class EyDataAsyncTokenUtil { + private static volatile EyDataAsyncCusToken token; + private static final CusSuccess tokenSuccess = CusSuccess.builder() + .successField("code") + .successValue(0) + .dataKey("data") + .build(); + private static final RequestMasterPlate requestMasterPlate = new RequestMasterPlate(); + private static final Logger log = Util.getLogger(); + /** + *

获取token

+ * @author xuanran.wang + * @dateTime 2023/4/6 19:59 + * @return token + **/ + public static String getToken(String url, Map params) { + if(token == null){ + synchronized (EyDataAsyncTokenUtil.class){ + if(token == null){ + return getTokenByHTTP(url, params); + } + } + } + long expiryTime = token.getExpiresTime(); + if(System.currentTimeMillis() >= expiryTime){ + synchronized (EyDataAsyncTokenUtil.class){ + expiryTime = token.getExpiresTime(); + if(System.currentTimeMillis() >= expiryTime){ + return getTokenByHTTP(url, params); + } + } + } + return token.getAccessToken(); + } + + /** + *

从接口获取token

+ * @author xuanran.wang + * @dateTime 2023/4/7 23:49 + * @return token + **/ + private static String getTokenByHTTP(String url, Map params){ + HashMap header = new HashMap<>(); + header.put("Content-Type", "application/json"); + Map response = requestMasterPlate.apiPost(url, params, header, tokenSuccess); + token = JSONObject.parseObject(JSONObject.toJSONString(response), EyDataAsyncCusToken.class); + String accessToken = Util.null2DefaultStr(response.get("accessToken"), ""); + long expiresTime = Long.parseLong(Util.null2DefaultStr(response.get("expiresTime"), "")); + // 默认少5分钟过期 + token.setExpiresTime(expiresTime - (60 * 5 * 1000)); + log.info("token : " + JSONObject.toJSONString(token)); + return accessToken; + } +} diff --git a/src/main/java/weaver/xuanran/wang/eny/data_async/util/ValueRuleMethod.java b/src/main/java/weaver/xuanran/wang/eny/data_async/util/ValueRuleMethod.java new file mode 100644 index 0000000..9c0e610 --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/eny/data_async/util/ValueRuleMethod.java @@ -0,0 +1,104 @@ +package weaver.xuanran.wang.eny.data_async.util; + +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import com.google.common.base.Strings; +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; +import weaver.xuanran.wang.eny.data_async.entity.DataAsyncConfigDetail; +import weaver.xuanran.wang.eny.data_async.mapper.DataAsyncMapper; +import weaver.xuanran.wang.eny.data_async.service.convert.CusAsyncConvert; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.*; +import java.util.function.BiFunction; + +/** + *

值处理方法

+ * + *

create: 2023-02-02 15:15

+ * + * @author youHong.ai + */ + +public class ValueRuleMethod { + + + public static final Map, Object>> VALUE_RULE_FUNCTION = new HashMap<>(); + + private final DataAsyncMapper mapper = Util.getMapper(DataAsyncMapper.class); + + private final Logger log = Util.getLogger(); + + static { + Class valueRuleMethodClass = ValueRuleMethod.class; + Method[] methods = valueRuleMethodClass.getMethods(); + for (Method method : methods) { + if (method.isAnnotationPresent(ValueRuleMethodNo.class)) { + ValueRuleMethodNo annotation = method.getAnnotation(ValueRuleMethodNo.class); + int value = annotation.value(); + VALUE_RULE_FUNCTION.put(value, (detail, map) -> { + try { + ValueRuleMethod valueRuleMethod = new ValueRuleMethod(); + return method.invoke(valueRuleMethod, detail, map); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + }); + } + } + } + + @ValueRuleMethodNo(value = 0, desc = "不转换") + public Object getFixValue(DataAsyncConfigDetail configDetail,Map map) { + return Util.null2DefaultStr(map.get(configDetail.getInterface_field()),""); + } + + + @ValueRuleMethodNo(value = 1, desc = "默认值") + public Object getCusText(DataAsyncConfigDetail configDetail, Map map) { + return Util.null2DefaultStr(configDetail.getValue_context(),""); + } + + + @ValueRuleMethodNo(value = 2, desc = "自定义sql") + public Object getCustomerSqlValue(DataAsyncConfigDetail configDetail, Map map) { + String cusText = configDetail.getValue_context(); + cusText = Util.sbc2dbcCase(cusText); + if (Strings.isNullOrEmpty(cusText)) { + return null; + } + if (!cusText.startsWith("select")) { + return null; + } + // 接口字段值判断 + String interfaceField = configDetail.getInterface_field(); + String interfaceFieldVal = Util.null2DefaultStr(map.get(interfaceField),""); + if(StringUtils.isBlank(interfaceFieldVal)){ + return ""; + } + return Util.null2DefaultStr(mapper.selectCustomerSql(cusText, map),""); + } + + @ValueRuleMethodNo(value = 3, desc = "自定义接口") + public Object getCusConvertInterface(DataAsyncConfigDetail configDetail, Map map) { + String cusText = configDetail.getValue_context(); + if(Strings.isNullOrEmpty(cusText)){ + return null; + } + try { + Class clazz = Class.forName(cusText); + if(!CusAsyncConvert.class.isAssignableFrom(clazz)){ + throw new CustomerException(cusText + " not implements weaver.xuanran.wang.sh_bigdata.org_hrm_async.annotations.CusOrgHrmAsyncConvert"); + } + CusAsyncConvert o = (CusAsyncConvert) clazz.newInstance(); + Map pathParam = Util.parseCusInterfacePathParam(cusText); + return o.cusConvert(configDetail, map, pathParam); + }catch (Exception e){ + log.error("getCusConvertInterface error! " + e.getMessage()); + return null; + } + } + +} diff --git a/src/main/java/weaver/xuanran/wang/eny/data_async/util/ValueRuleMethodNo.java b/src/main/java/weaver/xuanran/wang/eny/data_async/util/ValueRuleMethodNo.java new file mode 100644 index 0000000..e795072 --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/eny/data_async/util/ValueRuleMethodNo.java @@ -0,0 +1,19 @@ +package weaver.xuanran.wang.eny.data_async.util; + +import java.lang.annotation.*; + +/** + *

值处理方法编号注解

+ * + *

create: 2023-02-02 15:18

+ * + * @author youHong.ai + */ + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface ValueRuleMethodNo { + int value(); + String desc(); +} diff --git a/src/main/java/weaver/xuanran/wang/immc/cusfieldvalue/CusListValue.java b/src/main/java/weaver/xuanran/wang/immc/cusfieldvalue/CusListValue.java index 44faeeb..4694a75 100644 --- a/src/main/java/weaver/xuanran/wang/immc/cusfieldvalue/CusListValue.java +++ b/src/main/java/weaver/xuanran/wang/immc/cusfieldvalue/CusListValue.java @@ -2,8 +2,10 @@ package weaver.xuanran.wang.immc.cusfieldvalue; import aiyh.utils.Util; import com.alibaba.fastjson.JSONObject; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; +import weaver.general.TimeUtil; import weaver.xiao.commons.config.interfacies.CusInterfaceGetValue; import weaver.xiao.commons.config.interfacies.CusInterfaceListValue; import weaver.xuanran.wang.immc.mapper.ImMcMapper; @@ -27,23 +29,30 @@ public class CusListValue implements CusInterfaceGetValue { log.info("pathParam : \n" + JSONObject.toJSONString(pathParam)); String attachmentField = Util.null2DefaultStr(pathParam.get("attachmentField"), ""); String cusSql = Util.null2DefaultStr(pathParam.get("cusSql"), ""); + // 如果fileName不为空则对集合中每个map添加"fileName":value value则是附件字段名称 + String fileName = Util.null2DefaultStr(pathParam.get("fileName"), ""); if(StringUtils.isNotBlank(cusSql)){ - String docIds = ""; if (StringUtils.isNotBlank(attachmentField)) { - List attachment = new ArrayList<>(); for (String item : attachmentField.split(",")) { String filedValue = Util.null2DefaultStr(mainMap.get(item),""); - if(StringUtils.isNotBlank(Util.null2DefaultStr(mainMap.get(item),""))){ - attachment.add(filedValue); + if(StringUtils.isNotBlank(Util.null2DefaultStr(mainMap.get(filedValue),""))){ + cusSql = cusSql + .replace("{?docIds}", "( " + filedValue + " )") + .replace("{?requestid}",Util.null2DefaultStr(mainMap.get("requestid"),"")); + List> attachmentInfo = mapper.getAttachmentInfo(cusSql); + if(CollectionUtils.isEmpty(attachmentInfo)){ + continue; + } + // 往map中put附件字段名 + if(StringUtils.isBlank(fileName)){ + attachmentInfo.forEach(file ->{ + file.put(fileName, item); + }); + } + list.addAll(attachmentInfo); } } - docIds = StringUtils.join(attachment, ","); } - cusSql = cusSql - .replace("{?docIds}", "( " + docIds + " )") - .replace("{?requestid}",Util.null2DefaultStr(mainMap.get("requestid"),"")); - List> attachmentInfo = mapper.getAttachmentInfo(cusSql); - list.addAll(attachmentInfo); } return list; } diff --git a/src/main/java/weaver/xuanran/wang/immc/service/WorkFlowToVmsAndMQService.java b/src/main/java/weaver/xuanran/wang/immc/service/WorkFlowToVmsAndMQService.java index 6de58fa..efcbf85 100644 --- a/src/main/java/weaver/xuanran/wang/immc/service/WorkFlowToVmsAndMQService.java +++ b/src/main/java/weaver/xuanran/wang/immc/service/WorkFlowToVmsAndMQService.java @@ -42,6 +42,7 @@ public class WorkFlowToVmsAndMQService { // 表单字段 private static final String VMS_SUCCESS = "vms_success"; private static final String SUCCESS = "0"; + { httpUtils.getGlobalCache().header.put("Content-Type", MediaType.APPLICATION_JSON); // 全局请求头 } @@ -50,11 +51,11 @@ public class WorkFlowToVmsAndMQService { /** *

推送数据

* - * @param onlyMark 唯一编码 - * @param billTable 表名 - * @param requestId 请求id + * @param onlyMark 唯一编码 + * @param billTable 表名 + * @param requestId 请求id * @param vmsResponseVoField vms成功标识 - * @param config kafka配置文件名称 + * @param config kafka配置文件名称 * @author xuanran.wang * @dateTime 2022/12/5 17:05 **/ @@ -68,9 +69,9 @@ public class WorkFlowToVmsAndMQService { String url = requestMappingConfig.getRequestUrl(); dealWithMapping.setMainTable(billTable); Map param = dealWithMapping.getRequestParam(recordSet, requestMappingConfig); - String vmsSuccess = Util.null2DefaultStr(recordSet.getString(VMS_SUCCESS),""); - String mqSuccess = Util.null2DefaultStr(recordSet.getString(MQ_SUCCESS),""); - if(!SUCCESS.equals(vmsSuccess)){ + String vmsSuccess = Util.null2DefaultStr(recordSet.getString(VMS_SUCCESS), ""); + String mqSuccess = Util.null2DefaultStr(recordSet.getString(MQ_SUCCESS), ""); + if (!SUCCESS.equals(vmsSuccess)) { ResponeVo responeVo; try { responeVo = httpUtils.apiPost(url, param); @@ -80,7 +81,7 @@ public class WorkFlowToVmsAndMQService { parseResponseVo(responeVo, url, param, vmsResponseVoField); updateWorkFlow(VMS_SUCCESS, billTable, requestId); } - if(!SUCCESS.equals(mqSuccess) && StringUtils.isNotBlank(config)){ + if (!SUCCESS.equals(mqSuccess) && StringUtils.isNotBlank(config)) { sendToMQ(config, param); updateWorkFlow(MQ_SUCCESS, billTable, requestId); } @@ -88,13 +89,14 @@ public class WorkFlowToVmsAndMQService { /** *

解析响应对象

+ * + * @param responseVo 响应对象 + * @param url 地址 + * @param requestParam 请求 * @author xuanran.wang * @dateTime 2022/12/23 11:25 - * @param responseVo 响应对象 - * @param url 地址 - * @param requestParam 请求 **/ - private void parseResponseVo(ResponeVo responseVo, String url, Map requestParam, VmsResponseVoField vmsResponseVoField){ + private void parseResponseVo(ResponeVo responseVo, String url, Map requestParam, VmsResponseVoField vmsResponseVoField) { if (responseVo.getCode() != SUCCESS_CODE) { // 相应状态码 log.error(Util.logStr("can not fetch [{}],this request params is [{}]," + // 构建日志字符串 "this request heard is [{}],but response status code is [{}]," + @@ -112,63 +114,65 @@ public class WorkFlowToVmsAndMQService { /** *

将流程信息发送到kafka

+ * + * @param kafkaConfig kafka配置文件名称 + * @param message 消息对象 * @author xuanran.wang * @dateTime 2023/3/30 14:56 - * @param kafkaConfig kafka配置文件名称 - * @param message 消息对象 **/ - public void sendToMQ(String kafkaConfig, Map message){ + public void sendToMQ(String kafkaConfig, Map message) { KafkaProducer producer = null; InputStream inputStream = null; - try { - String path = GCONST.getPropertyPath() + "prop2map" + File.separator + kafkaConfig + ".properties"; - File configFile = new File(path); - if(!configFile.exists()){ - throw new CustomerException("please check /web-inf/prop2map has " + kafkaConfig + ".properties"); - } - Properties prop = new Properties(); - inputStream= new BufferedInputStream(Files.newInputStream(configFile.toPath())); - prop.load(inputStream); - log.info("prop => " + JSONObject.toJSONString(prop)); - log.info("msg => " + JSONObject.toJSONString(message)); - String topic = Util.null2DefaultStr(prop.getProperty("topic"),""); - if(StringUtils.isBlank(topic)){ - throw new CustomerException("kafka properties topic can not null!"); - } - producer = new KafkaProducer<>(prop); - // 发送消息到指定主题 - ProducerRecord record = new ProducerRecord<>(topic, JSONObject.toJSONString(message)); - producer.send(record).get(); - }catch (Exception e){ - log.error(Util.getErrString(e)); - throw new CustomerException(Util.logStr("send to kafka error!: [{}]", e.getMessage())); - }finally { - // 关闭Kafka生产者实例 - if(producer != null){ - producer.close(); - } - if(inputStream != null){ - try { - inputStream.close(); - }catch (Exception e){ - log.error("inputStream close error! " + e.getMessage()); - } - } - } + try { + String path = GCONST.getPropertyPath() + "prop2map" + File.separator + kafkaConfig + ".properties"; + File configFile = new File(path); + if (!configFile.exists()) { + throw new CustomerException("please check /web-inf/prop2map has " + kafkaConfig + ".properties"); + } + Properties prop = new Properties(); + inputStream = new BufferedInputStream(Files.newInputStream(configFile.toPath())); + prop.load(inputStream); + log.info("prop => " + JSONObject.toJSONString(prop)); + log.info("msg => " + JSONObject.toJSONString(message)); + String topic = Util.null2DefaultStr(prop.getProperty("topic"), ""); + if (StringUtils.isBlank(topic)) { + throw new CustomerException("kafka properties topic can not null!"); + } + producer = new KafkaProducer<>(prop); + // 发送消息到指定主题 + ProducerRecord record = new ProducerRecord<>(topic, JSONObject.toJSONString(message)); + producer.send(record).get(); + } catch (Exception e) { + log.error(Util.getErrString(e)); + throw new CustomerException(Util.logStr("send to kafka error!: [{}]", e.getMessage())); + } finally { + // 关闭Kafka生产者实例 + if (producer != null) { + producer.close(); + } + if (inputStream != null) { + try { + inputStream.close(); + } catch (Exception e) { + log.error("inputStream close error! " + e.getMessage()); + } + } + } } /** *

更新流程sql

- * @author xuanran.wang - * @dateTime 2023/3/30 19:18 - * @param field 主表字段 + * + * @param field 主表字段 * @param tableName 表名 * @param requestId 请求id + * @author xuanran.wang + * @dateTime 2023/3/30 19:18 **/ - public void updateWorkFlow(String field, String tableName, String requestId){ + public void updateWorkFlow(String field, String tableName, String requestId) { String updateSQL = "update " + tableName + " set " + field + " = " + SUCCESS + " where requestid = ?"; RecordSet recordSet = new RecordSet(); - if(!recordSet.executeUpdate(updateSQL, requestId)){ + if (!recordSet.executeUpdate(updateSQL, requestId)) { log.error(Util.logStr("update field error! sql: {}, requestId: {}", updateSQL, requestId)); throw new CustomerException("更新表单字段失败!"); } diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/common/util/SendTodoTaskUtil.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/common/util/SendTodoTaskUtil.java index 62a118f..4a9e12d 100644 --- a/src/main/java/weaver/xuanran/wang/sh_bigdata/common/util/SendTodoTaskUtil.java +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/common/util/SendTodoTaskUtil.java @@ -74,6 +74,11 @@ public class SendTodoTaskUtil { todoTask.setAgentid(agentId); todoTask.setTaskName(obj.getRequestnamenew()); todoTask.setTaskDesc(obj.getRequestnamenew()); + String pcAgentId = ShBigDataUtil.getPropertiesValByKey("pcAgentId"); + if(StringUtils.isBlank(pcAgentId)){ + pcAgentId = agentId; + } + todoTask.setPcAgentId(pcAgentId); String todoSSOCallBackUrl = ShBigDataUtil.getPropertiesValByKey("todoSSOCallBackUrl"); StringBuilder sb = new StringBuilder(todoSSOCallBackUrl); sb.append("?user=") diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/common/util/ShBigDataUtil.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/common/util/ShBigDataUtil.java index 13de9f8..022066b 100644 --- a/src/main/java/weaver/xuanran/wang/sh_bigdata/common/util/ShBigDataUtil.java +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/common/util/ShBigDataUtil.java @@ -37,6 +37,7 @@ public class ShBigDataUtil { WHILTE_LIST.add("getUserIdDebugOutKey"); WHILTE_LIST.add("ssoInterfaceCompareField"); WHILTE_LIST.add("ssoOaCompareField"); + WHILTE_LIST.add("pcAgentId"); } /** diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/entity/CusTodoTask.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/entity/CusTodoTask.java index 1337e35..9ac3046 100644 --- a/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/entity/CusTodoTask.java +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/entity/CusTodoTask.java @@ -26,4 +26,5 @@ public class CusTodoTask { protected String mobileLinkUrl; protected String receiver; protected String sender; + protected String pcAgentId; } diff --git a/src/test/java/xuanran/wang/big_data/BigDataTest.java b/src/test/java/xuanran/wang/big_data/BigDataTest.java index 1639bc9..f828e71 100644 --- a/src/test/java/xuanran/wang/big_data/BigDataTest.java +++ b/src/test/java/xuanran/wang/big_data/BigDataTest.java @@ -391,8 +391,8 @@ public class BigDataTest extends BaseTest { @Test public void testG(){ - String oaOutKey = "111"; - String sql = "select id from hrmresource where " + Util.null2DefaultStr(ShBigDataUtil.getPropertiesValByKey("ssoOaCompareField"),"outkey") + " = #{outKey}"; + String oaOutKey = "wld"; + String sql = "select id from hrmresource where loginid = #{outKey}"; int id = otherSystemToOAMapper.selectUserIdByOutKey(sql, oaOutKey); log.info("id => " + id); } diff --git a/src/test/java/xuanran/wang/eny/DataAsyncTest.java b/src/test/java/xuanran/wang/eny/DataAsyncTest.java new file mode 100644 index 0000000..b3330e2 --- /dev/null +++ b/src/test/java/xuanran/wang/eny/DataAsyncTest.java @@ -0,0 +1,70 @@ +package xuanran.wang.eny; + +import aiyh.utils.Util; +import basetest.BaseTest; +import com.alibaba.fastjson.JSONObject; +import com.engine.common.util.ServiceUtil; +import com.engine.cube.service.ModeAppService; +import com.engine.cube.service.impl.ModeAppServiceImpl; +import org.junit.Test; +import weaver.formmode.setup.ModeRightInfoThread; +import weaver.hrm.User; +import weaver.xuanran.wang.eny.data_async.entity.DataAsyncConfigMain; +import weaver.xuanran.wang.eny.data_async.mapper.DataAsyncMapper; +import weaver.xuanran.wang.eny.data_async.service.DataAsyncServiceImpl; + +import javax.jms.Session; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpSession; +import javax.servlet.http.HttpSessionContext; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + *

+ * + * @author xuanran.wang + * @date 2023/6/8 16:20 + */ +public class DataAsyncTest extends BaseTest { + private DataAsyncServiceImpl dataAsyncService = new DataAsyncServiceImpl(); + @Test + public void testA(){ + String onlyMark = "test"; + String tokenUrl = "http://47.94.138.180:48070/rpc-api/system/oauth2/token/client/create"; + String clientId = "6d067ac6c14211ed8fd700163e1331c6"; + String appId = "WEAVER"; + String appSecret = "7b09e5f7c14211ed8fd700163e1331c6"; + int pageSize = 500; + int pageNo = 25; + dataAsyncService.setPageSize(25); + dataAsyncService.setPageSize(pageSize); + dataAsyncService.setClientId(clientId); + + HashMap params = new HashMap<>(); + params.put("clientId", clientId); + params.put("appId", appId); + params.put("appSecret", appSecret); + DataAsyncConfigMain config = dataAsyncService.getConfig(onlyMark); + dataAsyncService.asyncData(config, tokenUrl, params); + } + + private final DataAsyncMapper asyncMapper = Util.getMapper(DataAsyncMapper.class); + + @Test + public void testb(){ + String json = "[{\"interfaceForeignKey\":\"12001\",\"id\":386455},{\"interfaceForeignKey\":\"12002\",\"id\":386457},{\"interfaceForeignKey\":\"12003\",\"id\":386459},{\"interfaceForeignKey\":\"12004\",\"id\":386460},{\"interfaceForeignKey\":\"12005\",\"id\":386462},{\"interfaceForeignKey\":\"12006\",\"id\":386464},{\"interfaceForeignKey\":\"12007\",\"id\":386466},{\"interfaceForeignKey\":\"12008\",\"id\":386468},{\"interfaceForeignKey\":\"12009\",\"id\":386469},{\"interfaceForeignKey\":\"12010\",\"id\":386471}]"; +// List> maps = asyncMapper.selectDataIds("classId", "uf_class", 1, 10); + List> list = JSONObject.parseObject(json, List.class); + System.out.println("maps : " + JSONObject.toJSONString(list)); + HashMap stringStringHashMap = dataAsyncService.parseListMap2Map("interfaceForeignKey", "id", list); + System.out.println("stringStringHashMap : " + JSONObject.toJSONString(stringStringHashMap)); + } + + public static ModeAppService modeAppService = ServiceUtil.getService(ModeAppServiceImpl.class, new User(1)); + + + +} diff --git a/src/test/java/xuanran/wang/eny/ExcelExportTest.java b/src/test/java/xuanran/wang/eny/ExcelExportTest.java index e436e2a..62d5528 100644 --- a/src/test/java/xuanran/wang/eny/ExcelExportTest.java +++ b/src/test/java/xuanran/wang/eny/ExcelExportTest.java @@ -1,10 +1,27 @@ package xuanran.wang.eny; +import aiyh.utils.Util; import basetest.BaseTest; import com.alibaba.fastjson.JSONObject; import com.api.xuanran.wang.eny.export_excel.entity.CusExportExcelConfigMain; +import com.api.xuanran.wang.eny.export_excel.mapper.ExportExcelMapper; import com.api.xuanran.wang.eny.export_excel.service.ExportExcelServiceImpl; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.junit.Test; +import weaver.general.GCONST; + +import javax.ws.rs.core.StreamingOutput; +import java.io.*; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** *

@@ -15,10 +32,84 @@ import org.junit.Test; public class ExcelExportTest extends BaseTest { private final ExportExcelServiceImpl exportExcelService = new ExportExcelServiceImpl(); - + private final ExportExcelMapper exportExcelMapper = Util.getMapper(ExportExcelMapper.class); @Test public void testA(){ - CusExportExcelConfigMain config = exportExcelService.getConfig(126); + CusExportExcelConfigMain config = exportExcelService.getConfig("class"); System.out.println("config : " + JSONObject.toJSONString(config)); + try { + String suffix = config.getTemplate_path().substring(config.getTemplate_path().lastIndexOf(".")); + StreamingOutput streamingOutput = exportExcelService.exportExcel(config, "1", suffix); + FileOutputStream fos = new FileOutputStream("/Users/wangxuanran/company/project/ebu_ecology_dev1/file/eny/" + System.currentTimeMillis() + ".xls"); + streamingOutput.write(fos); + }catch (Exception e){ + System.out.println("e : " + e.getMessage()); + System.out.println(Util.getErrString(e)); + } + } + + public void service1(CusExportExcelConfigMain config, String dataId) throws IOException { + String sql = "select * from " + config.getTable_name() + " where id in ( " + dataId + " )"; + Map map = exportExcelMapper.selectCustomerSqlMap(sql, new HashMap<>()); + String filePath = config.getTemplate_path(); + String suffix = filePath.substring(filePath.lastIndexOf(".")); + FileInputStream fis = new FileInputStream(parseConfigPath(filePath)); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + Workbook workbook; + if (".xls".equals(suffix)) { + workbook = new HSSFWorkbook(fis); + }else { + workbook = new XSSFWorkbook(fis); + } + Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表 + for (Row row : sheet) { + for (Cell cell : row) { + String cellValue = cell.getStringCellValue(); + if(StringUtils.isNotBlank(cellValue)){ + String replacedValue = replacePlaceholder(cellValue, map); + cell.setCellValue(replacedValue); + } + } + } + } + + public String replacePlaceholder(String cellValue, Map modelMap){ + Pattern pattern = Pattern.compile("\\{(.*?)}"); + Matcher matcher = pattern.matcher(cellValue); + StringBuffer replacedValue = new StringBuffer(); + while (matcher.find()) { + String placeholder = matcher.group(1); // 获取{}中的内容 + Object replacement = Util.null2DefaultStr(modelMap.get(placeholder),""); // 根据需要进行替换的逻辑 + matcher.appendReplacement(replacedValue, replacement.toString()); + } + matcher.appendTail(replacedValue); + return replacedValue.toString(); + } + + /** + *

解析请求xls模板位置

+ * @param configFilePath 模板文件路径 + * @return 解析后的文件路径 + */ + public String parseConfigPath(String configFilePath){ + StringBuilder filePath = new StringBuilder(GCONST.getSysFilePath()); + int beginIndex = configFilePath.indexOf("."); + int endIndex = configFilePath.lastIndexOf("."); + if(beginIndex == endIndex){ + filePath.append(configFilePath); + }else { + String[] pathArr = configFilePath.split("\\."); + for (int i = 0; i < pathArr.length - 2; i++) { + if(i != 0){ + filePath.append(File.separator); + } + filePath.append(pathArr[i]); + } + filePath.append(File.separator) + .append(pathArr[pathArr.length - 2]) + .append(".") + .append(pathArr[pathArr.length - 1]); + } + return filePath.toString(); } }