合同物料非定额导入导出功能1.0
This commit is contained in:
		
							parent
							
								
									9e5f04fe5f
								
							
						
					
					
						commit
						d724f240f0
					
				|  | @ -0,0 +1,254 @@ | |||
| package shkd.repc.recon.formplugin; | ||||
| 
 | ||||
| import kd.bos.context.RequestContext; | ||||
| import kd.bos.dataentity.entity.DynamicObject; | ||||
| import kd.bos.dataentity.entity.DynamicObjectCollection; | ||||
| import kd.bos.dataentity.utils.StringUtils; | ||||
| import kd.bos.fileservice.FileItem; | ||||
| import kd.bos.fileservice.FileService; | ||||
| import kd.bos.fileservice.FileServiceFactory; | ||||
| import kd.bos.form.control.events.ItemClickEvent; | ||||
| import kd.bos.form.plugin.AbstractFormPlugin; | ||||
| import kd.bos.orm.query.QCP; | ||||
| import kd.bos.orm.query.QFilter; | ||||
| import kd.bos.servicehelper.BusinessDataServiceHelper; | ||||
| import kd.sdk.plugin.Plugin; | ||||
| import org.apache.poi.ss.usermodel.FillPatternType; | ||||
| import org.apache.poi.ss.usermodel.HorizontalAlignment; | ||||
| import org.apache.poi.ss.usermodel.IndexedColors; | ||||
| import org.apache.poi.ss.usermodel.VerticalAlignment; | ||||
| import org.apache.poi.xssf.usermodel.*; | ||||
| 
 | ||||
| import java.awt.*; | ||||
| import java.io.ByteArrayInputStream; | ||||
| import java.io.ByteArrayOutputStream; | ||||
| import java.io.InputStream; | ||||
| import java.io.OutputStream; | ||||
| import java.text.SimpleDateFormat; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Date; | ||||
| import java.util.EventObject; | ||||
| import java.util.List; | ||||
| import java.util.stream.Collectors; | ||||
| 
 | ||||
| /** | ||||
|  * 合同物料导出插件 | ||||
|  */ | ||||
| public class ContractMaterialExportPlugin extends AbstractFormPlugin implements Plugin { | ||||
| 
 | ||||
|     @Override | ||||
|     public void registerListener(EventObject e) { | ||||
|         super.registerListener(e); | ||||
|         //工具栏控件 | ||||
|         this.addItemClickListeners("qeug_advcontoolbarap21"); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void itemClick(ItemClickEvent evt) { | ||||
|         super.itemClick(evt); | ||||
|         //工具栏控件里的工具栏项-导出 | ||||
|         if (StringUtils.equals("qeug_exportdata", evt.getItemKey())) { | ||||
|             Long value = (Long) this.getModel().getValue("id"); | ||||
|             if (value.compareTo(0L)==0){ | ||||
|                 this.getView().showMessage("请先保存单据"); | ||||
|                 return; | ||||
|             } | ||||
|             DynamicObject contract = BusinessDataServiceHelper.loadSingle(value, "recon_contractbill"); | ||||
|             if (null!=contract){ | ||||
|                 DynamicObjectCollection orderFormEntry = contract.getDynamicObjectCollection("qeug_orderformentry"); | ||||
|                 if (orderFormEntry==null||orderFormEntry.size()==0){ | ||||
|                     this.getView().showMessage("请填入数据保存后导出!"); | ||||
|                     return; | ||||
|                 } | ||||
|                 //根据导入模板配置导出数据 | ||||
|                 QFilter number = new QFilter("number", QCP.equals, "recon_contractbill_IMPT_ENTRY"); | ||||
|                 DynamicObject template = BusinessDataServiceHelper.loadSingle("bos_importentry_template", number.toArray()); | ||||
|                 if (null==template){ | ||||
|                     this.getView().showMessage("请先维护引入模板"); | ||||
|                     return; | ||||
|                 } | ||||
|                 //表头字段 | ||||
|                 List<DynamicObject> list =new ArrayList<>(); | ||||
|                 DynamicObjectCollection entry = template.getDynamicObjectCollection("treeentryentity"); | ||||
|                 if (null!=entry&&entry.size()!=0){ | ||||
|                     for (int i = 0; i < entry.size(); i++) { | ||||
|                         DynamicObject dynamicObject = entry.get(i); | ||||
|                         if (dynamicObject.getBoolean("isimport")){ | ||||
|                             list.add(dynamicObject); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 if (list.size()==0) return; | ||||
|                 //构建导出前四行数据 | ||||
| 
 | ||||
|                 // 创建Excel工作簿 | ||||
|                 XSSFWorkbook workbook = new XSSFWorkbook(); | ||||
|                 XSSFSheet sheet = workbook.createSheet("明细 # qeug_orderformentry"); | ||||
| 
 | ||||
|                 // 第一行:明细标题 | ||||
|                 XSSFRow row1 = sheet.createRow(0); | ||||
|                 XSSFCell cell1 = row1.createCell(0); | ||||
|                 cell1.setCellValue("明细 # qeug_orderformentry"); | ||||
|                 XSSFCellStyle style1 = workbook.createCellStyle(); | ||||
|                 XSSFFont font1 = workbook.createFont(); | ||||
|                 font1.setFontName("宋体"); | ||||
|                 font1.setFontHeightInPoints((short) 11); | ||||
|                 style1.setFont(font1); | ||||
|                 style1.setAlignment(HorizontalAlignment.CENTER); | ||||
|                 style1.setVerticalAlignment(VerticalAlignment.CENTER); | ||||
|                 sheet.setColumnWidth(0, 31 * 256); // 设置列宽 | ||||
|                 row1.setHeightInPoints(14.4f); | ||||
|                 cell1.setCellStyle(style1); | ||||
| 
 | ||||
|                 // 第二行:说明文本 | ||||
|                 XSSFRow row2 = sheet.createRow(1); | ||||
|                 XSSFCell cell2 = row2.createCell(0); | ||||
|                 cell2.setCellValue("1、请将鼠标移到灰色标题行查看字段录入要求。2、红色带星号(*)的字段为必录字段。"); | ||||
|                 XSSFCellStyle style2 = workbook.createCellStyle(); | ||||
|                 XSSFFont font2 = workbook.createFont(); | ||||
|                 font2.setFontName("Calibri"); | ||||
|                 font2.setFontHeightInPoints((short) 11); | ||||
|                 style2.setFont(font2); | ||||
|                 style2.setAlignment(HorizontalAlignment.LEFT); | ||||
|                 style2.setVerticalAlignment(VerticalAlignment.CENTER); | ||||
|                 style2.setWrapText(true); // 自动换行 | ||||
|                 row2.setHeightInPoints(60); | ||||
|                 sheet.setColumnWidth(0, 31 * 256); // 设置列宽 | ||||
|                 cell2.setCellStyle(style2); | ||||
| 
 | ||||
|                 // 第三行:list中的entitynumber | ||||
|                 XSSFRow row3 = sheet.createRow(2); | ||||
|                 for (int i = 0; i < list.size(); i++) { | ||||
|                     DynamicObject dynamicObject = list.get(i); | ||||
|                     String entityNumber=null; | ||||
|                     String importProp = dynamicObject.getString("importprop"); | ||||
|                     if (!("").equals(importProp)){ | ||||
|                         entityNumber = dynamicObject.getString("entitynumber")+"."+dynamicObject.getString("importprop"); | ||||
|                     }else { | ||||
|                         entityNumber = dynamicObject.getString("entitynumber"); | ||||
|                     } | ||||
| 
 | ||||
|                     XSSFCell cell = row3.createCell(i); | ||||
|                     cell.setCellValue(entityNumber); | ||||
|                     XSSFCellStyle style3 = workbook.createCellStyle(); | ||||
|                     XSSFFont font3 = workbook.createFont(); | ||||
|                     font3.setFontName("宋体"); | ||||
|                     font3.setFontHeightInPoints((short) 11); | ||||
|                     style3.setFont(font3); | ||||
|                     style3.setAlignment(HorizontalAlignment.CENTER); | ||||
|                     style3.setVerticalAlignment(VerticalAlignment.CENTER); | ||||
|                     sheet.setColumnWidth(i, 31 * 256); // 设置列宽 | ||||
|                     row3.setHeightInPoints(14.4f); | ||||
|                     cell.setCellStyle(style3); | ||||
|                 } | ||||
| 
 | ||||
|                 // 第四行:list中的entityname | ||||
|                 XSSFRow row4 = sheet.createRow(3); | ||||
|                 for (int i = 0; i < list.size(); i++) { | ||||
|                     DynamicObject dynamicObject = list.get(i); | ||||
|                     String entityName = dynamicObject.getString("entitydescription"); | ||||
|                     XSSFCell cell = row4.createCell(i); | ||||
|                     cell.setCellValue(entityName); | ||||
|                     XSSFCellStyle style4 = workbook.createCellStyle(); | ||||
|                     XSSFFont font4 = workbook.createFont(); | ||||
|                     font4.setFontName("Calibri"); | ||||
|                     font4.setFontHeightInPoints((short) 11); | ||||
|                     font4.setColor(IndexedColors.RED.getIndex()); | ||||
|                     style4.setFont(font4); | ||||
|                     style4.setAlignment(HorizontalAlignment.CENTER); | ||||
|                     style4.setVerticalAlignment(VerticalAlignment.CENTER); | ||||
|                     style4.setFillForegroundColor(new XSSFColor(new Color(192, 192, 192), new DefaultIndexedColorMap())); // 灰色背景 | ||||
|                     style4.setFillPattern(FillPatternType.SOLID_FOREGROUND); | ||||
|                     sheet.setColumnWidth(i, 31 * 256); // 设置列宽 | ||||
|                     row4.setHeightInPoints(14.4f); | ||||
|                     cell.setCellStyle(style4); | ||||
|                 } | ||||
| 
 | ||||
|                 // 填充数据行(根据entitynumber匹配) | ||||
|                 for (int i = 0; i < orderFormEntry.size(); i++) { | ||||
|                     DynamicObject orderEntry = orderFormEntry.get(i); | ||||
| 
 | ||||
|                     // 创建数据行 | ||||
|                     XSSFRow dataRow = sheet.createRow(i + 4); // 从第5行开始填充数据 | ||||
|                     int colIndex = 0; | ||||
| 
 | ||||
|                     for (int j = 0; j < list.size(); j++) { | ||||
|                         DynamicObject dynamicObject = list.get(j); | ||||
|                         String entityNumber=null; | ||||
|                         String importProp = dynamicObject.getString("importprop"); | ||||
|                         if (!("").equals(importProp)){ | ||||
|                             entityNumber = dynamicObject.getString("entitynumber")+"."+dynamicObject.getString("importprop"); | ||||
|                         }else { | ||||
|                             entityNumber = dynamicObject.getString("entitynumber"); | ||||
|                         } | ||||
|                         // 获取对应的数据 | ||||
|                         String data = orderEntry.getString(entityNumber); | ||||
|                         if (data==null||"".equals(data)){ | ||||
|                             switch (entityNumber){ | ||||
|                                 case "qeug_material.number": | ||||
|                                     continue; | ||||
|                                 case "qeug_importmaterialtype": | ||||
|                                     data=orderEntry.getString("qeug_material.group.name"); | ||||
|                                     break; | ||||
|                                 case "qeug_importmodel": | ||||
|                                     data=orderEntry.getString("qeug_material.modelnum"); | ||||
|                                     break; | ||||
|                                 case "qeug_importunit": | ||||
|                                     data=orderEntry.getString("qeug_material.baseunit.name"); | ||||
|                                     break; | ||||
|                                 default: | ||||
|                                     break; | ||||
|                             } | ||||
|                         } | ||||
| 
 | ||||
|                         // 填充单元格 | ||||
|                         XSSFCell cell = dataRow.createCell(colIndex++); | ||||
|                         cell.setCellValue(data != null ? data : ""); | ||||
|                         XSSFCellStyle dataStyle = workbook.createCellStyle(); | ||||
|                         XSSFFont dataFont = workbook.createFont(); | ||||
|                         dataFont.setFontName("宋体"); | ||||
|                         dataFont.setFontHeightInPoints((short) 11); | ||||
|                         dataStyle.setFont(dataFont); | ||||
|                         dataStyle.setAlignment(HorizontalAlignment.CENTER); | ||||
|                         dataStyle.setVerticalAlignment(VerticalAlignment.CENTER); | ||||
|                         dataRow.setHeightInPoints(14.4f); | ||||
|                         cell.setCellStyle(dataStyle); | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 // 上传Excel文件并获取下载路径 | ||||
|                 String uploadedFilePath = uploadExcel(workbook); | ||||
|                 String downloadUrl = RequestContext.get().getClientFullContextPath() + "/attachment/download.do?path=" + uploadedFilePath; | ||||
|                 this.getView().openUrl(downloadUrl); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     /** | ||||
|      * 上传Excel文件并返回路径 | ||||
|      */ | ||||
|     private String uploadExcel(XSSFWorkbook workbook) { | ||||
|         SimpleDateFormat sdf = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss"); | ||||
|         String fileName = "导出数据_" + sdf.format(new Date()) + ".xlsx"; | ||||
|         String pathName = "/offices/" + fileName; | ||||
|         try { | ||||
|             OutputStream outputStream = new ByteArrayOutputStream(); | ||||
|             workbook.write(outputStream); | ||||
|             InputStream inputStream = parse(outputStream); | ||||
| 
 | ||||
|             FileService fs = FileServiceFactory.getAttachmentFileService(); | ||||
|             return fs.upload(new FileItem(fileName, pathName, inputStream)); | ||||
|         } catch (Exception e) { | ||||
|             //logger.error("上传Excel失败", e); | ||||
|             throw new RuntimeException("上传Excel失败", e); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 解析输出流为输入流 | ||||
|      */ | ||||
|     public ByteArrayInputStream parse(final OutputStream out) throws Exception { | ||||
|         ByteArrayOutputStream outputStream = (ByteArrayOutputStream) out; | ||||
|         return new ByteArrayInputStream(outputStream.toByteArray()); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | @ -1,16 +1,23 @@ | |||
| package shkd.repc.recon.formplugin; | ||||
| 
 | ||||
| import com.alibaba.fastjson.JSONObject; | ||||
| import kd.bos.dataentity.entity.DynamicObject; | ||||
| import kd.bos.dataentity.entity.DynamicObjectCollection; | ||||
| import kd.bos.entity.datamodel.BasedataItem; | ||||
| import kd.bos.entity.datamodel.events.BeforeImportEntryEventArgs; | ||||
| import kd.bos.entity.datamodel.events.QueryImportBasedataEventArgs; | ||||
| import kd.bos.form.plugin.AbstractFormPlugin; | ||||
| import kd.bos.form.plugin.importentry.resolving.ImportEntryData; | ||||
| import kd.bos.form.plugin.impt.BatchImportPlugin; | ||||
| import kd.bos.orm.query.QCP; | ||||
| import kd.bos.orm.query.QFilter; | ||||
| import kd.bos.servicehelper.BusinessDataServiceHelper; | ||||
| import kd.bos.servicehelper.operation.SaveServiceHelper; | ||||
| import kd.bos.servicehelper.org.OrgUnitServiceHelper; | ||||
| import shkd.repc.recon.formplugin.dynamic.ImportMaterial; | ||||
| 
 | ||||
| import java.util.Iterator; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.*; | ||||
| import java.util.stream.Collectors; | ||||
| 
 | ||||
| /** | ||||
|  * 合同表单插件 | ||||
|  | @ -20,6 +27,8 @@ public class ContractMaterialImportPlugin  extends AbstractFormPlugin { | |||
|     private static final String BOS_ORG = "bos_org";//组织实体 | ||||
| 
 | ||||
|     private static final String BD_MATERIAL = "bd_material";//物料实体 | ||||
| 
 | ||||
|     private static final Set<ImportMaterial> materialList=new HashSet<>(); | ||||
|     //TODO: 生成物料逻辑迁移到导入过程中,获取excel行 | ||||
|     @Override | ||||
|     public void queryImportBasedata(QueryImportBasedataEventArgs e) { | ||||
|  | @ -28,7 +37,10 @@ public class ContractMaterialImportPlugin  extends AbstractFormPlugin { | |||
|         for (Map.Entry<BasedataItem, List<Object>> entry : searchResult.entrySet()) { | ||||
|             List<Object> basedata = entry.getValue(); | ||||
|             if (basedata.isEmpty()) { // 查不到基础资料数据 | ||||
|                 Long materialId = newMaterial(entry.getKey().getSearchValue()); | ||||
|                 //数据去重 | ||||
|                 //List<ImportMaterial> list = getDistinctMaterialsByNumber(); | ||||
| 
 | ||||
|                 Long materialId = newMaterial(entry.getKey().getSearchValue(),materialList); | ||||
|                 basedata.add(materialId); | ||||
|                 //algo.storage.redis.ip_port | ||||
| //                System.getProperty("algo.storage.redis.ip_port"); | ||||
|  | @ -43,15 +55,44 @@ public class ContractMaterialImportPlugin  extends AbstractFormPlugin { | |||
|             } | ||||
|         } | ||||
|     } | ||||
|     private Long newMaterial(String number){ | ||||
|     private Long newMaterial(String number,Set<ImportMaterial> set){ | ||||
|         ImportMaterial materialByNumber = getMaterialByNumber(number, set); | ||||
| 
 | ||||
|         DynamicObject bd_material = BusinessDataServiceHelper.newDynamicObject(BD_MATERIAL); | ||||
|         //物料编码 | ||||
|         bd_material.set("number",number); | ||||
|         //物料名称 | ||||
|         bd_material.set("name",materialByNumber.getMaterialName()); | ||||
|         //所属组织 | ||||
|         long rootOrgId = OrgUnitServiceHelper.getRootOrgId(); | ||||
|         DynamicObject org = BusinessDataServiceHelper.loadSingle(rootOrgId, BOS_ORG); | ||||
|         DynamicObject bd_material = BusinessDataServiceHelper.newDynamicObject(BD_MATERIAL); | ||||
|         bd_material.set("number",number); | ||||
|         bd_material.set("name",number); | ||||
|         if (null != org) { | ||||
|             bd_material.set("createorg",org); | ||||
|         } | ||||
|         //物料分类 | ||||
|         QFilter type = new QFilter("name", QCP.equals, materialByNumber.getMaterialType()); | ||||
|         DynamicObject materialGroup = BusinessDataServiceHelper.loadSingle("bd_materialgroup",type.toArray()); | ||||
|         if (null!=materialGroup){ | ||||
|             //物料分组 | ||||
|             bd_material.set("group",materialGroup); | ||||
|             //分类标准 | ||||
|             DynamicObjectCollection groupStandard = bd_material.getDynamicObjectCollection("entry_groupstandard"); | ||||
|             DynamicObject newEntry = groupStandard.addNew(); | ||||
|             QFilter qFilter = new QFilter("name", QCP.equals, "物料基本分类标准"); | ||||
|             DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle("bd_materialgroupstandard", qFilter.toArray()); | ||||
|             if (null!=dynamicObject){ | ||||
|                 newEntry.set("standardid",dynamicObject); | ||||
|             } | ||||
|             //分类 | ||||
|             newEntry.set("groupid",materialGroup); | ||||
|         } | ||||
|         //物料单位 | ||||
|         QFilter unit = new QFilter("name", QCP.equals, materialByNumber.getMaterialUnit()); | ||||
|         DynamicObject measureUnits = BusinessDataServiceHelper.loadSingle("bd_measureunits",unit.toArray()); | ||||
|         if (null!=measureUnits){ | ||||
|             bd_material.set("baseunit",measureUnits); | ||||
|         } | ||||
|         bd_material.set("modelnum",materialByNumber.getMaterialModel());//规格 | ||||
|         bd_material.set("materialtype","1");//物料类型:物资 | ||||
|         bd_material.set("enable", "1");//使用状态:可用 | ||||
|         bd_material.set("status", "C");//数据状态:审核 | ||||
|  | @ -62,4 +103,59 @@ public class ContractMaterialImportPlugin  extends AbstractFormPlugin { | |||
|         SaveServiceHelper.save(new DynamicObject[]{bd_material}); | ||||
|         return bd_material.getLong("id"); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void beforeImportEntry(BeforeImportEntryEventArgs e) { | ||||
|         super.beforeImportEntry(e); | ||||
|         materialList.clear(); | ||||
|         HashMap itemEntry = (HashMap) e.getSource(); | ||||
|         ArrayList list = (ArrayList) itemEntry.get("qeug_orderformentry"); | ||||
|         for (int i = 0; i < list.size(); i++) { | ||||
|             ImportEntryData importData = (ImportEntryData) list.get(i); | ||||
|             JSONObject data = importData.getData(); | ||||
|             ImportMaterial importMaterial = new ImportMaterial(); | ||||
|             Map<String, Object> map = data.toJavaObject(Map.class); | ||||
|             JSONObject material = (JSONObject) map.get("qeug_material"); | ||||
|             //物料编码 | ||||
|             importMaterial.setMaterialNumber(material.getString("number")); | ||||
|             //物料名称 | ||||
|             importMaterial.setMaterialName((String) map.get("qeug_materialnames")); | ||||
|             //物料类型 | ||||
|             importMaterial.setMaterialType((String) map.get("qeug_importmaterialtype")); | ||||
|             //物料规格 | ||||
|             importMaterial.setMaterialModel((String) map.get("qeug_importmodel")); | ||||
|             //物料单位 | ||||
|             importMaterial.setMaterialUnit((String) map.get("qeug_importunit")); | ||||
|             materialList.add(importMaterial); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public List<ImportMaterial> getDistinctMaterialsByNumber() { | ||||
| 
 | ||||
| 
 | ||||
|         return new ArrayList<>(materialList.stream() | ||||
|                 .collect(Collectors.toMap( | ||||
|                         ImportMaterial::getMaterialNumber, // 根据 materialNumber 去重 | ||||
|                         material -> material, // 保留第一个匹配的元素 | ||||
|                         (existing, replacement) -> existing // 如果有重复的 materialNumber,保留第一个 | ||||
|                 )) | ||||
|                 .values()); // 收集成 List | ||||
|     } | ||||
| 
 | ||||
|     public ImportMaterial getMaterialByNumber(String number, Set<ImportMaterial> set) { | ||||
|         ImportMaterial result = null; | ||||
|         if (set != null && !set.isEmpty()) { | ||||
|             // 使用for-each循环遍历set | ||||
|             for (ImportMaterial importMaterial : set) { | ||||
|                 String materialNumber = importMaterial.getMaterialNumber(); | ||||
|                 if (number.equals(materialNumber)) { | ||||
|                     result = importMaterial; | ||||
|                     break; // 找到后立刻跳出循环 | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,189 @@ | |||
| package shkd.repc.recon.formplugin; | ||||
| 
 | ||||
| import kd.bos.context.RequestContext; | ||||
| import kd.bos.dataentity.entity.DynamicObject; | ||||
| import kd.bos.dataentity.entity.DynamicObjectCollection; | ||||
| import kd.bos.dataentity.utils.StringUtils; | ||||
| import kd.bos.fileservice.FileItem; | ||||
| import kd.bos.fileservice.FileService; | ||||
| import kd.bos.fileservice.FileServiceFactory; | ||||
| import kd.bos.form.control.events.ItemClickEvent; | ||||
| import kd.bos.form.events.AfterDoOperationEventArgs; | ||||
| import kd.bos.form.plugin.AbstractFormPlugin; | ||||
| import kd.bos.orm.query.QCP; | ||||
| import kd.bos.orm.query.QFilter; | ||||
| import kd.bos.servicehelper.BusinessDataServiceHelper; | ||||
| import kd.sdk.plugin.Plugin; | ||||
| import org.apache.poi.ss.usermodel.FillPatternType; | ||||
| import org.apache.poi.ss.usermodel.HorizontalAlignment; | ||||
| import org.apache.poi.ss.usermodel.IndexedColors; | ||||
| import org.apache.poi.ss.usermodel.VerticalAlignment; | ||||
| import org.apache.poi.xssf.usermodel.*; | ||||
| 
 | ||||
| import java.awt.*; | ||||
| import java.io.ByteArrayInputStream; | ||||
| import java.io.ByteArrayOutputStream; | ||||
| import java.io.InputStream; | ||||
| import java.io.OutputStream; | ||||
| import java.text.SimpleDateFormat; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Date; | ||||
| import java.util.EventObject; | ||||
| import java.util.List; | ||||
| 
 | ||||
| /** | ||||
|  * 二开导入模板 | ||||
|  */ | ||||
| public class ContractMaterialTemplatePlugin extends AbstractFormPlugin implements Plugin { | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public void registerListener(EventObject e) { | ||||
|         super.registerListener(e); | ||||
|         //工具栏控件 | ||||
|         this.addItemClickListeners("qeug_advcontoolbarap21"); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void afterDoOperation(AfterDoOperationEventArgs evt) { | ||||
|         String operateKey = evt.getOperateKey(); | ||||
|         if (StringUtils.equals("exporttemplate",operateKey)){ | ||||
|             //根据导入模板配置导出数据 | ||||
|             QFilter number = new QFilter("number", QCP.equals, "recon_contractbill_IMPT_ENTRY"); | ||||
|             DynamicObject template = BusinessDataServiceHelper.loadSingle("bos_importentry_template", number.toArray()); | ||||
|             if (null == template) { | ||||
|                 this.getView().showMessage("请先维护引入模板"); | ||||
|                 return; | ||||
|             } | ||||
|             //表头字段 | ||||
|             List<DynamicObject> list = new ArrayList<>(); | ||||
|             DynamicObjectCollection entry = template.getDynamicObjectCollection("treeentryentity"); | ||||
|             if (null != entry && entry.size() != 0) { | ||||
|                 for (int i = 0; i < entry.size(); i++) { | ||||
|                     DynamicObject dynamicObject = entry.get(i); | ||||
|                     if (dynamicObject.getBoolean("isimport")) { | ||||
|                         list.add(dynamicObject); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             if (list.size() == 0) return; | ||||
|             //构建导出前四行数据 | ||||
| 
 | ||||
|             // 创建Excel工作簿 | ||||
|             XSSFWorkbook workbook = new XSSFWorkbook(); | ||||
|             XSSFSheet sheet = workbook.createSheet("明细 # qeug_orderformentry"); | ||||
| 
 | ||||
|             // 第一行:明细标题 | ||||
|             XSSFRow row1 = sheet.createRow(0); | ||||
|             XSSFCell cell1 = row1.createCell(0); | ||||
|             cell1.setCellValue("明细 # qeug_orderformentry"); | ||||
|             XSSFCellStyle style1 = workbook.createCellStyle(); | ||||
|             XSSFFont font1 = workbook.createFont(); | ||||
|             font1.setFontName("宋体"); | ||||
|             font1.setFontHeightInPoints((short) 11); | ||||
|             style1.setFont(font1); | ||||
|             style1.setAlignment(HorizontalAlignment.CENTER); | ||||
|             style1.setVerticalAlignment(VerticalAlignment.CENTER); | ||||
|             sheet.setColumnWidth(0, 31 * 256); // 设置列宽 | ||||
|             row1.setHeightInPoints(14.4f); | ||||
|             cell1.setCellStyle(style1); | ||||
| 
 | ||||
|             // 第二行:说明文本 | ||||
|             XSSFRow row2 = sheet.createRow(1); | ||||
|             XSSFCell cell2 = row2.createCell(0); | ||||
|             cell2.setCellValue("1、请将鼠标移到灰色标题行查看字段录入要求。2、红色带星号(*)的字段为必录字段。"); | ||||
|             XSSFCellStyle style2 = workbook.createCellStyle(); | ||||
|             XSSFFont font2 = workbook.createFont(); | ||||
|             font2.setFontName("Calibri"); | ||||
|             font2.setFontHeightInPoints((short) 11); | ||||
|             style2.setFont(font2); | ||||
|             style2.setAlignment(HorizontalAlignment.LEFT); | ||||
|             style2.setVerticalAlignment(VerticalAlignment.CENTER); | ||||
|             style2.setWrapText(true); // 自动换行 | ||||
|             row2.setHeightInPoints(60); | ||||
|             sheet.setColumnWidth(0, 31 * 256); // 设置列宽 | ||||
|             cell2.setCellStyle(style2); | ||||
| 
 | ||||
|             // 第三行:list中的entitynumber | ||||
|             XSSFRow row3 = sheet.createRow(2); | ||||
|             for (int i = 0; i < list.size(); i++) { | ||||
|                 DynamicObject dynamicObject = list.get(i); | ||||
|                 String entityNumber = null; | ||||
|                 String importProp = dynamicObject.getString("importprop"); | ||||
|                 if (!("").equals(importProp)) { | ||||
|                     entityNumber = dynamicObject.getString("entitynumber") + "." + dynamicObject.getString("importprop"); | ||||
|                 } else { | ||||
|                     entityNumber = dynamicObject.getString("entitynumber"); | ||||
|                 } | ||||
| 
 | ||||
|                 XSSFCell cell = row3.createCell(i); | ||||
|                 cell.setCellValue(entityNumber); | ||||
|                 XSSFCellStyle style3 = workbook.createCellStyle(); | ||||
|                 XSSFFont font3 = workbook.createFont(); | ||||
|                 font3.setFontName("宋体"); | ||||
|                 font3.setFontHeightInPoints((short) 11); | ||||
|                 style3.setFont(font3); | ||||
|                 style3.setAlignment(HorizontalAlignment.CENTER); | ||||
|                 style3.setVerticalAlignment(VerticalAlignment.CENTER); | ||||
|                 sheet.setColumnWidth(i, 31 * 256); // 设置列宽 | ||||
|                 row3.setHeightInPoints(14.4f); | ||||
|                 cell.setCellStyle(style3); | ||||
|             } | ||||
| 
 | ||||
|             // 第四行:list中的entityname | ||||
|             XSSFRow row4 = sheet.createRow(3); | ||||
|             for (int i = 0; i < list.size(); i++) { | ||||
|                 DynamicObject dynamicObject = list.get(i); | ||||
|                 String entityName = dynamicObject.getString("entitydescription"); | ||||
|                 XSSFCell cell = row4.createCell(i); | ||||
|                 cell.setCellValue(entityName); | ||||
|                 XSSFCellStyle style4 = workbook.createCellStyle(); | ||||
|                 XSSFFont font4 = workbook.createFont(); | ||||
|                 font4.setFontName("Calibri"); | ||||
|                 font4.setFontHeightInPoints((short) 11); | ||||
|                 font4.setColor(IndexedColors.RED.getIndex()); | ||||
|                 style4.setFont(font4); | ||||
|                 style4.setAlignment(HorizontalAlignment.CENTER); | ||||
|                 style4.setVerticalAlignment(VerticalAlignment.CENTER); | ||||
|                 style4.setFillForegroundColor(new XSSFColor(new Color(192, 192, 192), new DefaultIndexedColorMap())); // 灰色背景 | ||||
|                 style4.setFillPattern(FillPatternType.SOLID_FOREGROUND); | ||||
|                 sheet.setColumnWidth(i, 31 * 256); // 设置列宽 | ||||
|                 row4.setHeightInPoints(14.4f); | ||||
|                 cell.setCellStyle(style4); | ||||
|             } | ||||
|             // 上传Excel文件并获取下载路径 | ||||
|             String uploadedFilePath = uploadExcel(workbook); | ||||
|             String downloadUrl = RequestContext.get().getClientFullContextPath() + "/attachment/download.do?path=" + uploadedFilePath; | ||||
|             this.getView().openUrl(downloadUrl); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * 上传Excel文件并返回路径 | ||||
|      */ | ||||
|     private String uploadExcel(XSSFWorkbook workbook) { | ||||
|         SimpleDateFormat sdf = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss"); | ||||
|         String fileName = "导入模板_" + sdf.format(new Date()) + ".xlsx"; | ||||
|         String pathName = "/offices/" + fileName; | ||||
|         try { | ||||
|             OutputStream outputStream = new ByteArrayOutputStream(); | ||||
|             workbook.write(outputStream); | ||||
|             InputStream inputStream = parse(outputStream); | ||||
| 
 | ||||
|             FileService fs = FileServiceFactory.getAttachmentFileService(); | ||||
|             return fs.upload(new FileItem(fileName, pathName, inputStream)); | ||||
|         } catch (Exception e) { | ||||
|             //logger.error("上传Excel失败", e); | ||||
|             throw new RuntimeException("上传Excel失败", e); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 解析输出流为输入流 | ||||
|      */ | ||||
|     public ByteArrayInputStream parse(final OutputStream out) throws Exception { | ||||
|         ByteArrayOutputStream outputStream = (ByteArrayOutputStream) out; | ||||
|         return new ByteArrayInputStream(outputStream.toByteArray()); | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,65 @@ | |||
| package shkd.repc.recon.formplugin.dynamic; | ||||
| 
 | ||||
| public class ImportMaterial { | ||||
| 
 | ||||
|     public String materialNumber; | ||||
| 
 | ||||
|     public String materialName; | ||||
| 
 | ||||
|     public String materialType; | ||||
| 
 | ||||
|     public String materialModel; | ||||
| 
 | ||||
|     public String materialUnit; | ||||
| 
 | ||||
|     public String getMaterialNumber() { | ||||
|         return materialNumber; | ||||
|     } | ||||
| 
 | ||||
|     public void setMaterialNumber(String materialNumber) { | ||||
|         this.materialNumber = materialNumber; | ||||
|     } | ||||
| 
 | ||||
|     public String getMaterialName() { | ||||
|         return materialName; | ||||
|     } | ||||
| 
 | ||||
|     public void setMaterialName(String materialName) { | ||||
|         this.materialName = materialName; | ||||
|     } | ||||
| 
 | ||||
|     public String getMaterialType() { | ||||
|         return materialType; | ||||
|     } | ||||
| 
 | ||||
|     public void setMaterialType(String materialType) { | ||||
|         this.materialType = materialType; | ||||
|     } | ||||
| 
 | ||||
|     public String getMaterialModel() { | ||||
|         return materialModel; | ||||
|     } | ||||
| 
 | ||||
|     public void setMaterialModel(String materialModel) { | ||||
|         this.materialModel = materialModel; | ||||
|     } | ||||
| 
 | ||||
|     public String getMaterialUnit() { | ||||
|         return materialUnit; | ||||
|     } | ||||
| 
 | ||||
|     public void setMaterialUnit(String materialUnit) { | ||||
|         this.materialUnit = materialUnit; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public String toString() { | ||||
|         return "ImportMaterial{" + | ||||
|                 "materialId='" + materialNumber + '\'' + | ||||
|                 ", materialName='" + materialName + '\'' + | ||||
|                 ", materialType='" + materialType + '\'' + | ||||
|                 ", materialModel='" + materialModel + '\'' + | ||||
|                 ", materialUnit='" + materialUnit + '\'' + | ||||
|                 '}'; | ||||
|     } | ||||
| } | ||||
|  | @ -1,219 +0,0 @@ | |||
| package shkd.repc.resm.formplugin; | ||||
| 
 | ||||
| import kd.bos.bill.AbstractBillPlugIn; | ||||
| import kd.bos.dataentity.OperateOption; | ||||
| import kd.bos.dataentity.entity.DynamicObject; | ||||
| import kd.bos.dataentity.entity.DynamicObjectCollection; | ||||
| import kd.bos.dataentity.utils.StringUtils; | ||||
| import kd.bos.form.control.Control; | ||||
| import kd.bos.logging.Log; | ||||
| import kd.bos.logging.LogFactory; | ||||
| import kd.bos.orm.query.QCP; | ||||
| import kd.bos.orm.query.QFilter; | ||||
| import kd.bos.servicehelper.BusinessDataServiceHelper; | ||||
| import kd.bos.servicehelper.botp.BFTrackerServiceHelper; | ||||
| import kd.bos.servicehelper.operation.SaveServiceHelper; | ||||
| import kd.bos.servicehelper.org.OrgUnitServiceHelper; | ||||
| import kd.bos.servicehelper.org.OrgViewType; | ||||
| import kd.scm.bid.common.constant.entity.BidTemplateMangeEntity; | ||||
| import kd.sdk.plugin.Plugin; | ||||
| 
 | ||||
| import java.math.BigDecimal; | ||||
| import java.math.RoundingMode; | ||||
| import java.util.ArrayList; | ||||
| import java.util.EventObject; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.stream.Collectors; | ||||
| 
 | ||||
| /** | ||||
|  * 自动设置考察任务考察对象 | ||||
|  */ | ||||
| public class AutomaticallySetObjectPlugin extends AbstractBillPlugIn implements Plugin { | ||||
| 
 | ||||
|     private static final Log logger = LogFactory.getLog(AutomaticallySetObjectPlugin.class); | ||||
| 
 | ||||
|     @Override | ||||
|     public void afterBindData(EventObject e) { | ||||
|         super.afterBindData(e); | ||||
| 
 | ||||
|         DynamicObject dataEntity = this.getModel().getDataEntity(); | ||||
|         DynamicObjectCollection entry = dataEntity.getDynamicObjectCollection("entry_evaldetail"); | ||||
| 
 | ||||
|         if (entry == null || entry.isEmpty()) return; | ||||
| 
 | ||||
|         String object = entry.get(0).getString("entryevaluatorstr"); | ||||
| 
 | ||||
|         // 状态暂存且分录考察人为空 | ||||
|         if ("A".equals(this.getModel().getValue("billstatus")) && "".equals(object)) { | ||||
| 
 | ||||
|             // 获取取值逻辑 | ||||
|             DynamicObject dataModel = BusinessDataServiceHelper.loadSingle("qeug_datamodel", | ||||
|                     (new QFilter("qeug_projectsource", QCP.equals, "考察计划")).toArray()); | ||||
| 
 | ||||
|             if (dataModel == null) return; | ||||
| 
 | ||||
|             String projectSource = dataModel.getString("qeug_projectsource"); | ||||
|             Long orgId; | ||||
|             if ("考察计划".equals(projectSource)) { | ||||
| 
 | ||||
|                 // 获取考察详情 | ||||
|                 QFilter qFilter = new QFilter("plandetails.evaltask", QCP.equals, dataEntity.getPkValue()); | ||||
|                 DynamicObject plane = BusinessDataServiceHelper.loadSingle("resm_investigationplan", qFilter.toArray()); | ||||
| 
 | ||||
|                 if (plane == null) return; | ||||
| 
 | ||||
|                 DynamicObject project = plane.getDynamicObject("qeug_project"); | ||||
|                 if (project == null) return; | ||||
| 
 | ||||
|                 // 获取项目-所属组织 | ||||
|                 QFilter qFilter1 = new QFilter("id", QCP.equals, project.get("id")); | ||||
|                 DynamicObject dynamicObject1 = BusinessDataServiceHelper.loadSingle("repmd_projectbill", qFilter1.toArray()); | ||||
|                 if (dynamicObject1 == null) return; | ||||
| 
 | ||||
|                 DynamicObject org = dynamicObject1.getDynamicObject("org"); | ||||
|                 if (org == null) return; | ||||
| 
 | ||||
|                 orgId = org.getLong("id"); | ||||
|                 DynamicObjectCollection dataModelEntry = dataModel.getDynamicObjectCollection("entryentity"); | ||||
| 
 | ||||
|                 // 使用 Stream API 获取所有匹配的 role 对象 | ||||
|                 List<DynamicObject> matchingRoles = dataModelEntry.stream() | ||||
|                         .map(modelEntry -> modelEntry.getString("qeug_rolenumber")) | ||||
|                         .filter(roleNumber -> roleNumber != null) | ||||
|                         .map(roleNumber -> BusinessDataServiceHelper.loadSingle("wf_role", new QFilter("number", QCP.equals, roleNumber).toArray())) | ||||
|                         .filter(roleDynamic -> roleDynamic != null) | ||||
|                         .filter(roleDynamic -> roleDynamic.getDynamicObjectCollection("roleentry") != null && !roleDynamic.getDynamicObjectCollection("roleentry").isEmpty()) // 跳过 roleentry 为空的情况 | ||||
|                         .flatMap(roleDynamic -> roleDynamic.getDynamicObjectCollection("roleentry").stream()) | ||||
|                         .filter(role -> { | ||||
|                             Long roleOrgId = role.getLong("org.id"); | ||||
|                             return roleOrgId != null && roleOrgId.compareTo(orgId) == 0; // 筛选符合条件的 role | ||||
|                         }) | ||||
|                         .collect(Collectors.toList()); | ||||
|                 // 如果有匹配项 | ||||
|                 if (!((List<?>) matchingRoles).isEmpty()) { | ||||
|                     creatExamData(matchingRoles, entry); | ||||
|                 } else { | ||||
|                     findParentOrgMatch(entry, orgId, dataModelEntry); | ||||
|                 } | ||||
|                 SaveServiceHelper.saveOperate("resm_exam_task", new DynamicObject[]{dataEntity}, OperateOption.create()); | ||||
|             } | ||||
|         } | ||||
|         this.getView().updateView("entry_evaldetail"); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * 递归查找上级组织 | ||||
|      * | ||||
|      * @param entry          考察任务分录 | ||||
|      * @param orgId          当前工作流角色组织 | ||||
|      * @param dataModelEntry 取数模板 | ||||
|      */ | ||||
|     private void findParentOrgMatch(DynamicObjectCollection entry, Long orgId, DynamicObjectCollection dataModelEntry) { | ||||
|         if (orgId == null) return; | ||||
|         //取上级组织. | ||||
|         List<Long> dptIds = new ArrayList<>(); | ||||
|         dptIds.add(orgId); | ||||
|         Map<Long, Long> orgParentMap = OrgUnitServiceHelper.getDirectSuperiorOrg(OrgViewType.Admin, dptIds); | ||||
|         if (orgParentMap != null) { | ||||
|             Long parentId = orgParentMap.get(orgId); | ||||
|             DynamicObject parentOrg = BusinessDataServiceHelper.loadSingle(parentId, "bos_adminorg"); | ||||
|             if (parentOrg != null) { | ||||
|                 orgId = parentOrg.getLong("id"); | ||||
|                 // 使用 Stream API 获取所有匹配的 role 对象 | ||||
|                 Long finalOrgId = orgId; | ||||
|                 List<DynamicObject> matchingRoles = dataModelEntry.stream() | ||||
|                         .map(modelEntry -> modelEntry.getString("qeug_rolenumber")) | ||||
|                         .filter(roleNumber -> roleNumber != null) | ||||
|                         .map(roleNumber -> BusinessDataServiceHelper.loadSingle("wf_role", new QFilter("number", QCP.equals, roleNumber).toArray())) | ||||
|                         .filter(roleDynamic -> roleDynamic != null) | ||||
|                         .filter(roleDynamic -> roleDynamic.getDynamicObjectCollection("roleentry") != null && !roleDynamic.getDynamicObjectCollection("roleentry").isEmpty()) // 跳过 roleentry 为空的情况 | ||||
|                         .flatMap(roleDynamic -> roleDynamic.getDynamicObjectCollection("roleentry").stream()) | ||||
|                         .filter(role -> { | ||||
|                             Long roleOrgId = role.getLong("org.id"); | ||||
|                             return roleOrgId != null && roleOrgId.compareTo(finalOrgId) == 0; // 筛选符合条件的 role | ||||
|                         }) | ||||
|                         .collect(Collectors.toList()); | ||||
|                 // 如果有匹配项,则返回;否则递归查找上级组织 | ||||
|                 if (!matchingRoles.isEmpty()) { | ||||
|                     creatExamData(matchingRoles, entry); | ||||
|                 } else { | ||||
|                     findParentOrgMatch(entry, orgId, dataModelEntry); // 没有匹配项,递归调用上级组织 | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 生成考察人 | ||||
|      * @param matchingRoles 收集符合条件的人员 | ||||
|      * @param entry         考察任务分录 | ||||
|      */ | ||||
|     private void creatExamData(List<DynamicObject> matchingRoles, DynamicObjectCollection entry) { | ||||
|         for (DynamicObject dynamicObject : entry) { | ||||
|             StringBuilder objectText = new StringBuilder(); | ||||
|             DynamicObject examuator = BusinessDataServiceHelper.newDynamicObject("resm_examuator"); | ||||
|             String pkValue = dynamicObject.getString("id"); | ||||
|             examuator.set("evalentryid", pkValue); | ||||
| 
 | ||||
|             DynamicObjectCollection entryCollection = examuator.getDynamicObjectCollection("entry_evaluator"); | ||||
| 
 | ||||
|             boolean isSingleRole = matchingRoles.size() == 1; | ||||
| 
 | ||||
|             for (int i = 0; i < matchingRoles.size(); i++) { | ||||
|                 DynamicObject matchingRole = matchingRoles.get(i); | ||||
|                 DynamicObject evaluator = entryCollection.addNew(); | ||||
|                 evaluator.set("user", matchingRole.getLong("user.id")); | ||||
|                 evaluator.set("userposition", matchingRole.getLong("userposition.id")); | ||||
| 
 | ||||
|                 String name = matchingRole.getString("user.name"); | ||||
|                 BigDecimal weight = calculateWeight(matchingRoles.size(), i); | ||||
|                 String weightPercentage = formatWeight(weight); | ||||
| 
 | ||||
|                 if (isSingleRole) { | ||||
|                     objectText.append(name).append("(").append(weightPercentage).append(")"); | ||||
|                 } else { | ||||
|                     if (i > 0) objectText.append(";"); | ||||
|                     objectText.append(name).append("(").append(weightPercentage).append(")"); | ||||
|                 } | ||||
| 
 | ||||
|                 evaluator.set("weight", weight); | ||||
|                 evaluator.set("seq", i + 1); | ||||
|             } | ||||
|             dynamicObject.set("entryevaluatorstr", objectText); | ||||
|             try { | ||||
|                 SaveServiceHelper.saveOperate("resm_examuator", new DynamicObject[]{examuator}, OperateOption.create()); | ||||
|             } catch (Exception ex) { | ||||
|                 logger.error("保存考察人数据失败", ex); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * 权重计算 | ||||
|      * @param totalRoles 人员列表 | ||||
|      * @param currentIndex 行数 | ||||
|      * @return 权重 | ||||
|      */ | ||||
|     private BigDecimal calculateWeight(int totalRoles, int currentIndex) { | ||||
|         BigDecimal weight = new BigDecimal(1.0 / totalRoles).setScale(2, RoundingMode.HALF_UP); | ||||
|         if (totalRoles % 2 == 1 && currentIndex == totalRoles - 1 && totalRoles != 1) { | ||||
|             weight = weight.add(new BigDecimal(0.01)); | ||||
|         } | ||||
|         return weight; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 权重转百分比 | ||||
|      * @param weight 权重 | ||||
|      * @return 百分比字符串 | ||||
|      */ | ||||
|     private String formatWeight(BigDecimal weight) { | ||||
|         return weight.multiply(new BigDecimal(100)).setScale(0, RoundingMode.HALF_UP) + "%"; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
		Loading…
	
		Reference in New Issue