fix: 移植长辉已验证的四类接口 500/体验问题(不含物料颜色字段)
1. BPM 发起流程 500:新增 BpmProcessDefinitionIdUtils 对流程定义编号做幂等 URL 解码(前端双重编码时会查到不存在的编号),并对流程定义缺失做 null 容错;BpmProcessDefinitionInfoMapper 兼容同一 processDefinitionId 多条记录导致的 TooManyResultsException;BpmProcessInstanceConvert 容错流程定义已删除场景
2. HRM 到期提醒 NPE:HrmExpiryRemindServiceImpl.buildEmployeeMap 空集合返回 Map.of(),调用方 get(employeeId) 在 employeeId 为空时触发 NPE,改为 new HashMap<>()
3. Excel 导入模板日期显示为序列号:新增 DateAsTextCellWriteHandler + LocalDate/LocalDateTime 字符串转换器,ExcelUtils 增加 writeTemplate;53 个含日期列的导入模板改用 writeTemplate(导出逻辑不受影响)
4. 用户导入部门改为按名称填写:UserImportExcelVO.deptId(Long) -> deptName(String),模板示例取当前真实部门,导入按名称精确匹配并给出明确提示;空文件/非法文件不再报「系统异常」
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.framework.excel.core.convert; |
| | | |
| | | import cn.idev.excel.converters.Converter; |
| | | import cn.idev.excel.enums.CellDataTypeEnum; |
| | | import cn.idev.excel.metadata.GlobalConfiguration; |
| | | import cn.idev.excel.metadata.data.WriteCellData; |
| | | import cn.idev.excel.metadata.property.ExcelContentProperty; |
| | | |
| | | import java.time.LocalDate; |
| | | import java.time.format.DateTimeFormatter; |
| | | |
| | | /** |
| | | * LocalDate ååºä¸ºçº¯ææ¬ï¼yyyy-MM-ddï¼ç转æ¢å¨ |
| | | * |
| | | * <p>é»è®¤ FastExcel ææ¥æåæãæ¥æåå
æ ¼ãï¼å¨ Excel éæ¾ç¤ºä¸º 46023.0 è¿ç±»åºåå·ï¼ |
| | | * 使ç¨è
çä¸æè¯¥å¡«ä»ä¹æ ¼å¼ã导å
¥æ¨¡æ¿ç±»åºæ¯æ³¨åæ¬è½¬æ¢å¨åï¼æ¥æä»¥ææ¬è¾åºï¼ç´è§å¯è¯»ã</p> |
| | | * |
| | | * <p>注æï¼ä»
ç¨äºãååºæ¨¡æ¿ãï¼ä¸è¦ç¨äºå¯¼å
¥è§£æã</p> |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | public class LocalDateStringConverter implements Converter<LocalDate> { |
| | | |
| | | private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); |
| | | |
| | | @Override |
| | | public Class<LocalDate> supportJavaTypeKey() { |
| | | return LocalDate.class; |
| | | } |
| | | |
| | | @Override |
| | | public CellDataTypeEnum supportExcelTypeKey() { |
| | | return CellDataTypeEnum.STRING; |
| | | } |
| | | |
| | | @Override |
| | | public WriteCellData<?> convertToExcelData(LocalDate value, ExcelContentProperty contentProperty, |
| | | GlobalConfiguration globalConfiguration) { |
| | | return new WriteCellData<>(value.format(FORMATTER)); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.framework.excel.core.convert; |
| | | |
| | | import cn.idev.excel.converters.Converter; |
| | | import cn.idev.excel.enums.CellDataTypeEnum; |
| | | import cn.idev.excel.metadata.GlobalConfiguration; |
| | | import cn.idev.excel.metadata.data.WriteCellData; |
| | | import cn.idev.excel.metadata.property.ExcelContentProperty; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.time.format.DateTimeFormatter; |
| | | |
| | | /** |
| | | * LocalDateTime ååºä¸ºçº¯ææ¬ï¼yyyy-MM-dd HH:mm:ssï¼ç转æ¢å¨ |
| | | * |
| | | * <p>ç¨éå {@link LocalDateStringConverter}ï¼é¿å
æ¶é´æ¾ç¤ºä¸º Excel åºåå·ã</p> |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | public class LocalDateTimeStringConverter implements Converter<LocalDateTime> { |
| | | |
| | | private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); |
| | | |
| | | @Override |
| | | public Class<LocalDateTime> supportJavaTypeKey() { |
| | | return LocalDateTime.class; |
| | | } |
| | | |
| | | @Override |
| | | public CellDataTypeEnum supportExcelTypeKey() { |
| | | return CellDataTypeEnum.STRING; |
| | | } |
| | | |
| | | @Override |
| | | public WriteCellData<?> convertToExcelData(LocalDateTime value, ExcelContentProperty contentProperty, |
| | | GlobalConfiguration globalConfiguration) { |
| | | return new WriteCellData<>(value.format(FORMATTER)); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.framework.excel.core.handler; |
| | | |
| | | import cn.idev.excel.write.handler.CellWriteHandler; |
| | | import cn.idev.excel.write.handler.context.CellWriteHandlerContext; |
| | | import org.apache.poi.ss.usermodel.Cell; |
| | | import org.apache.poi.ss.usermodel.CellType; |
| | | |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.time.format.DateTimeFormatter; |
| | | |
| | | /** |
| | | * ææ¥æåå
æ ¼å¼ºå¶åæçº¯ææ¬çå¤çå¨ |
| | | * |
| | | * <p>èæ¯ï¼FastExcel å¨ååºæ¶ï¼å³ä½¿æ³¨åäºå符串转æ¢å¨ï¼æ¥æå段ä»å¯è½è¢«å
ç½®ç |
| | | * Number 转æ¢å¨æ¥ç®¡ï¼æç»å¨ Excel éæ¾ç¤ºä¸º 46023.0 è¿ç±»åºåå·ï¼ä½¿ç¨è
ç䏿ã</p> |
| | | * |
| | | * <p>æ¬å¤çå¨å¨åå
æ ¼åå®åä»å
¥ï¼æ LocalDate / LocalDateTime ç±»åçåå§å¼ |
| | | * æ ¼å¼å为 yyyy-MM-dd / yyyy-MM-dd HH:mm:ss å¹¶ä»¥ææ¬åå
¥ã</p> |
| | | * |
| | | * <p>ä»
ç¨äºãä¸è½½å¯¼å
¥æ¨¡æ¿ãï¼ä¸å½±å导å
¥è§£æã</p> |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | public class DateAsTextCellWriteHandler implements CellWriteHandler { |
| | | |
| | | private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); |
| | | private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); |
| | | |
| | | @Override |
| | | public void afterCellDispose(CellWriteHandlerContext context) { |
| | | // åªå¤çæ°æ®è¡ï¼è·³è¿è¡¨å¤´ |
| | | if (Boolean.TRUE.equals(context.getHead())) { |
| | | return; |
| | | } |
| | | Object value = context.getOriginalValue(); |
| | | if (value == null) { |
| | | return; |
| | | } |
| | | String text = null; |
| | | if (value instanceof LocalDate localDate) { |
| | | text = localDate.format(DATE_FORMATTER); |
| | | } else if (value instanceof LocalDateTime localDateTime) { |
| | | text = localDateTime.format(DATETIME_FORMATTER); |
| | | } else if (value instanceof java.util.Date date) { |
| | | text = date.toInstant().atZone(java.time.ZoneId.systemDefault()) |
| | | .toLocalDate().format(DATE_FORMATTER); |
| | | } |
| | | if (text == null) { |
| | | return; |
| | | } |
| | | Cell cell = context.getCell(); |
| | | if (cell == null) { |
| | | return; |
| | | } |
| | | cell.setCellType(CellType.STRING); |
| | | cell.setCellValue(text); |
| | | } |
| | | |
| | | } |
| | |
| | | import cn.idev.excel.converters.longconverter.LongStringConverter; |
| | | import cn.iocoder.yudao.framework.common.util.http.HttpUtils; |
| | | import cn.iocoder.yudao.framework.excel.core.handler.ColumnWidthMatchStyleStrategy; |
| | | import cn.iocoder.yudao.framework.excel.core.handler.DateAsTextCellWriteHandler; |
| | | import cn.iocoder.yudao.framework.excel.core.handler.SelectSheetWriteHandler; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | |
| | | response.setContentType("application/vnd.ms-excel;charset=UTF-8"); |
| | | } |
| | | |
| | | /** |
| | | * è¾åº Excel 模æ¿ï¼æ¥ææææ¬æ¸²æï¼ |
| | | * |
| | | * <p>ä¸ {@link #write} çåºå«ï¼é¢å¤æ³¨åäº {@link DateAsTextCellWriteHandler}ï¼ |
| | | * æ LocalDate / LocalDateTime åæ yyyy-MM-dd ææ¬ï¼è䏿¯ Excel æ¥æåºåå·ã |
| | | * ä»
ç¨äºãä¸è½½å¯¼å
¥æ¨¡æ¿ãï¼å¯¼å
¥è§£æä»èµ° {@link #read}ï¼ä¸åå½±åã</p> |
| | | */ |
| | | public static <T> void writeTemplate(HttpServletResponse response, String filename, String sheetName, |
| | | Class<T> head, List<T> data) throws IOException { |
| | | ExcelWriter excelWriter = FastExcelFactory.write(response.getOutputStream(), head) |
| | | .autoCloseStream(false) |
| | | .registerWriteHandler(new ColumnWidthMatchStyleStrategy()) |
| | | .registerWriteHandler(new SelectSheetWriteHandler(head)) |
| | | .registerWriteHandler(new DateAsTextCellWriteHandler()) |
| | | .registerConverter(new LongStringConverter()) |
| | | .build(); |
| | | try { |
| | | excelWriter.write(data, FastExcelFactory.writerSheet(sheetName).build()); |
| | | } finally { |
| | | excelWriter.finish(); |
| | | excelWriter.close(); |
| | | } |
| | | response.addHeader("Content-Disposition", "attachment;filename=" + HttpUtils.encodeUtf8(filename)); |
| | | response.setContentType("application/vnd.ms-excel;charset=UTF-8"); |
| | | } |
| | | |
| | | public static <T> List<T> read(MultipartFile file, Class<T> head) throws IOException { |
| | | // åè https://t.zsxq.com/zM77F å¸åï¼å¢å try å¤çï¼å
¼å®¹ windows åºæ¯ |
| | | try (InputStream inputStream = file.getInputStream()) { |
| | |
| | | BpmProcessInstanceRespVO respVO = BeanUtils.toBean(processInstance, BpmProcessInstanceRespVO.class); |
| | | respVO.setStatus(FlowableUtils.getProcessInstanceStatus(processInstance)) |
| | | .setFormVariables(FlowableUtils.getProcessInstanceFormVariable(processInstance)); |
| | | // definition |
| | | respVO.setProcessDefinition(BeanUtils.toBean(processDefinition, BpmProcessDefinitionRespVO.class)); |
| | | copyTo(processDefinitionInfo, respVO.getProcessDefinition()); |
| | | // definitionï¼æµç¨å®ä¹å¯è½å·²è¢«å é¤ï¼éè¦å®¹éï¼å¦åå端æ¿å° 500ï¼ |
| | | if (processDefinition != null) { |
| | | respVO.setProcessDefinition(BeanUtils.toBean(processDefinition, BpmProcessDefinitionRespVO.class)); |
| | | if (respVO.getProcessDefinition() != null && processDefinitionInfo != null) { |
| | | copyTo(processDefinitionInfo, respVO.getProcessDefinition()); |
| | | } |
| | | } |
| | | // user |
| | | if (startUser != null) { |
| | | respVO.setStartUser(BeanUtils.toBean(startUser, UserSimpleBaseVO.class)); |
| | |
| | | return selectList(BpmProcessDefinitionInfoDO::getProcessDefinitionId, processDefinitionIds); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨å®ä¹çæ©å±ä¿¡æ¯ |
| | | * |
| | | * <p>åå²åå åä¸ processDefinitionId å¯è½åå¨å¤æ¡è®°å½ï¼éå¤é¨ç½² / éå¤ä¿å模åï¼ï¼ |
| | | * ç´æ¥ç¨ selectOne 伿 TooManyResultsException å¯¼è´æ¥å£ 500ï¼ |
| | | * è¿éæ¹ä¸ºåææ°ä¸æ¡ï¼ä¿è¯æ¥å£å¯ç¨ã</p> |
| | | */ |
| | | default BpmProcessDefinitionInfoDO selectByProcessDefinitionId(String processDefinitionId) { |
| | | return selectOne(BpmProcessDefinitionInfoDO::getProcessDefinitionId, processDefinitionId); |
| | | List<BpmProcessDefinitionInfoDO> list = selectList( |
| | | new LambdaQueryWrapperX<BpmProcessDefinitionInfoDO>() |
| | | .eq(BpmProcessDefinitionInfoDO::getProcessDefinitionId, processDefinitionId) |
| | | .orderByDesc(BpmProcessDefinitionInfoDO::getId)); |
| | | return list.isEmpty() ? null : list.get(0); |
| | | } |
| | | |
| | | default void updateByModelId(String modelId, BpmProcessDefinitionInfoDO updateObj) { |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.bpm.framework.flowable.core.util; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | |
| | | import java.net.URLDecoder; |
| | | import java.nio.charset.StandardCharsets; |
| | | |
| | | /** |
| | | * Flowable æµç¨å®ä¹ç¼å·å·¥å
· |
| | | * |
| | | * <p>æµç¨å®ä¹ç¼å·å½¢å¦ {@code qingjia:2:553a7ac9-...}ï¼å
å«åå·ã |
| | | * åç«¯å¦æå¯¹è¯¥å¼åäº URL ç¼ç ååä½ä¸ºæ¥è¯¢åæ°ä¼ éï¼åéç¼ç ï¼ï¼ |
| | | * Spring åªè§£ç ä¸å±ï¼æç»æ¿å°ç仿¯ {@code qingjia%3A2%3A...}ï¼ |
| | | * Flowable æè¯¥ç¼å·æ¥ä¸å°æµç¨å®ä¹ï¼ç´æ¥æ FlowableObjectNotFoundException å¯¼è´ 500ã</p> |
| | | * |
| | | * <p>è¿éå¨å
¥å£å¤å䏿¬¡å¹ççå½ä¸åï¼åªå¨ç¡®å®æ®ç % è½¬ä¹æ¶æè§£ç ï¼ |
| | | * åæ³çæµç¨å®ä¹ç¼å·ä¸å¯è½å
å« %ï¼å æ¤ä¸ä¼è¯¯ä¼¤ã</p> |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | public class BpmProcessDefinitionIdUtils { |
| | | |
| | | /** æå¤è§£ç 屿°ï¼é²æ¢å¼å¸¸è¾å
¥æ éå¾ªç¯ */ |
| | | private static final int MAX_DECODE_TIMES = 5; |
| | | |
| | | private BpmProcessDefinitionIdUtils() { |
| | | } |
| | | |
| | | /** |
| | | * å½ä¸åæµç¨å®ä¹ç¼å·ï¼éå±è§£ç æ®çç URL è½¬ä¹ |
| | | * |
| | | * @param id æµç¨å®ä¹ç¼å· |
| | | * @return å½ä¸ååçç¼å·ï¼å
¥å为空æ¶åæ ·è¿å |
| | | */ |
| | | public static String normalize(String id) { |
| | | if (StrUtil.isBlank(id) || id.indexOf('%') < 0) { |
| | | return id; |
| | | } |
| | | String current = id; |
| | | for (int i = 0; i < MAX_DECODE_TIMES && current.indexOf('%') >= 0; i++) { |
| | | String decoded; |
| | | try { |
| | | decoded = URLDecoder.decode(current, StandardCharsets.UTF_8); |
| | | } catch (Exception ignored) { |
| | | // è§£ç 失败说æä¸æ¯ URL 转ä¹ï¼ä¿æåå¼ |
| | | break; |
| | | } |
| | | if (decoded.equals(current)) { |
| | | break; |
| | | } |
| | | current = decoded; |
| | | } |
| | | return current; |
| | | } |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO; |
| | | import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmProcessDefinitionInfoMapper; |
| | | import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants; |
| | | import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmProcessDefinitionIdUtils; |
| | | import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; |
| | | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| | | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.flowable.bpmn.model.BpmnModel; |
| | | import org.flowable.common.engine.api.FlowableObjectNotFoundException; |
| | | import org.flowable.common.engine.impl.db.SuspensionState; |
| | | import org.flowable.engine.RepositoryService; |
| | | import org.flowable.engine.repository.Deployment; |
| | |
| | | |
| | | @Override |
| | | public ProcessDefinition getProcessDefinition(String id) { |
| | | return repositoryService.getProcessDefinition(id); |
| | | String definitionId = BpmProcessDefinitionIdUtils.normalize(id); |
| | | if (StrUtil.isBlank(definitionId)) { |
| | | return null; |
| | | } |
| | | // ç¼å·ä¸å卿¶ Flowable 伿 FlowableObjectNotFoundExceptionï¼ |
| | | // è¿éç»ä¸è½¬æ null ç±è°ç¨æ¹å¤çï¼é¿å
å端æ¿å° 500ãç³»ç»å¼å¸¸ã |
| | | try { |
| | | return repositoryService.getProcessDefinition(definitionId); |
| | | } catch (FlowableObjectNotFoundException ex) { |
| | | log.warn("[getProcessDefinition][æµç¨å®ä¹({}) ä¸åå¨]", definitionId); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | @Override |
| | |
| | | if (CollUtil.isEmpty(ids)) { |
| | | return emptyList(); |
| | | } |
| | | return repositoryService.createProcessDefinitionQuery().processDefinitionIds(ids).list(); |
| | | return repositoryService.createProcessDefinitionQuery() |
| | | .processDefinitionIds(ids.stream().map(BpmProcessDefinitionIdUtils::normalize) |
| | | .collect(java.util.stream.Collectors.toSet())).list(); |
| | | } |
| | | |
| | | @Override |
| | |
| | | public ProcessDefinition getActiveProcessDefinition(String key) { |
| | | return repositoryService.createProcessDefinitionQuery() |
| | | .processDefinitionTenantId(FlowableUtils.getTenantId()) |
| | | .processDefinitionKey(key).active().singleResult(); |
| | | .processDefinitionKey(BpmProcessDefinitionIdUtils.normalize(key)).active().singleResult(); |
| | | } |
| | | |
| | | @Override |
| | |
| | | |
| | | @Override |
| | | public BpmnModel getProcessDefinitionBpmnModel(String id) { |
| | | return repositoryService.getBpmnModel(id); |
| | | String definitionId = BpmProcessDefinitionIdUtils.normalize(id); |
| | | if (StrUtil.isBlank(definitionId)) { |
| | | return null; |
| | | } |
| | | try { |
| | | return repositoryService.getBpmnModel(definitionId); |
| | | } catch (FlowableObjectNotFoundException ex) { |
| | | log.warn("[getProcessDefinitionBpmnModel][æµç¨å®ä¹({}) ä¸åå¨]", definitionId); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public BpmProcessDefinitionInfoDO getProcessDefinitionInfo(String id) { |
| | | return processDefinitionMapper.selectByProcessDefinitionId(id); |
| | | return processDefinitionMapper.selectByProcessDefinitionId(BpmProcessDefinitionIdUtils.normalize(id)); |
| | | } |
| | | |
| | | @Override |
| | | public List<BpmProcessDefinitionInfoDO> getProcessDefinitionInfoList(Collection<String> ids) { |
| | | return processDefinitionMapper.selectListByProcessDefinitionIds(ids); |
| | | if (CollUtil.isEmpty(ids)) { |
| | | return emptyList(); |
| | | } |
| | | return processDefinitionMapper.selectListByProcessDefinitionIds(ids.stream() |
| | | .map(BpmProcessDefinitionIdUtils::normalize).collect(java.util.stream.Collectors.toSet())); |
| | | } |
| | | |
| | | @Override |
| | |
| | | processVariables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID, loginUserId); |
| | | } |
| | | // 1.3 读åå
¶å®ç¸å
³æ°æ® |
| | | ProcessDefinition processDefinition = processDefinitionService.getProcessDefinition( |
| | | historicProcessInstance != null ? historicProcessInstance.getProcessDefinitionId() |
| | | : reqVO.getProcessDefinitionId()); |
| | | String processDefinitionId = historicProcessInstance != null |
| | | ? historicProcessInstance.getProcessDefinitionId() : reqVO.getProcessDefinitionId(); |
| | | ProcessDefinition processDefinition = processDefinitionService.getProcessDefinition(processDefinitionId); |
| | | if (processDefinition == null) { |
| | | // æµç¨å®ä¹ä¸å卿¶è¿åæç¡®çä¸å¡é误ï¼é¿å
NPE / Flowable å¼å¸¸åæ 500ãç³»ç»å¼å¸¸ã |
| | | throw exception(ErrorCodeConstants.PROCESS_DEFINITION_NOT_EXISTS); |
| | | } |
| | | BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService |
| | | .getProcessDefinitionInfo(processDefinition.getId()); |
| | | BpmnModel bpmnModel = processDefinitionService.getProcessDefinitionBpmnModel(processDefinition.getId()); |
| | |
| | | // è·å¾æµç¨å®ä¹ |
| | | ProcessDefinition definition = processDefinitionService |
| | | .getProcessDefinition(createReqVO.getProcessDefinitionId()); |
| | | if (definition == null) { |
| | | throw exception(ErrorCodeConstants.PROCESS_DEFINITION_NOT_EXISTS); |
| | | } |
| | | // åèµ·æµç¨ |
| | | return createProcessInstance0(userId, definition, createReqVO.getVariables(), null, |
| | | createReqVO.getStartUserSelectAssignees()); |
| | |
| | | .dealTime(null).totalProductPrice(null).discountPercent(null).totalPrice(null).remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "åæºå¯¼å
¥æ¨¡æ¿.xls", "åæºå表", CrmBusinessImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "åæºå¯¼å
¥æ¨¡æ¿.xls", "åæºå表", CrmBusinessImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .payCycle(null).remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "åå导å
¥æ¨¡æ¿.xls", "ååå表", CrmContractImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "åå导å
¥æ¨¡æ¿.xls", "ååå表", CrmContractImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .score(null).evalType("").evalReason("").operatorName("") |
| | | .operateTime(null).validUntil(null).remark("").build() |
| | | ); |
| | | ExcelUtils.write(response, "客æ·ä¿¡ç¨è¯çº§å¯¼å
¥æ¨¡æ¿.xls", "客æ·ä¿¡ç¨è¯çº§å表", CrmCreditRatingImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "客æ·ä¿¡ç¨è¯çº§å¯¼å
¥æ¨¡æ¿.xls", "客æ·ä¿¡ç¨è¯çº§å表", CrmCreditRatingImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | @Operation(summary = "ä¸è½½é宿¥ä»·å¯¼å
¥æ¨¡æ¿") |
| | | @PreAuthorize("@ss.hasPermission('crm:sale-quotation:create')") |
| | | public void importTemplate(HttpServletResponse response) throws IOException { |
| | | ExcelUtils.write(response, "é宿¥ä»·å¯¼å
¥æ¨¡æ¿.xls", "æ¥ä»·æç»", CrmSaleQuotationImportExcelVO.class, java.util.Collections.emptyList()); |
| | | ExcelUtils.writeTemplate(response, "é宿¥ä»·å¯¼å
¥æ¨¡æ¿.xls", "æ¥ä»·æç»", CrmSaleQuotationImportExcelVO.class, java.util.Collections.emptyList()); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .invoiceTime(null).remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "æ¥ç¥¨å¯¼å
¥æ¨¡æ¿.xls", "æ¥ç¥¨å表", ErpPurchaseInvoiceImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "æ¥ç¥¨å¯¼å
¥æ¨¡æ¿.xls", "æ¥ç¥¨å表", ErpPurchaseInvoiceImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .count(null).taxPercent(null).qcCheckFlag(false).itemRemark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "éè´è®¢å导å
¥æ¨¡æ¿.xls", "éè´è®¢åå表", ErpPurchaseOrderImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "éè´è®¢å导å
¥æ¨¡æ¿.xls", "éè´è®¢åå表", ErpPurchaseOrderImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .demandTime(null).itemRemark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "éè´è®¡å导å
¥æ¨¡æ¿.xls", "éè´è®¡åå表", ErpPurchasePlanImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "éè´è®¡å导å
¥æ¨¡æ¿.xls", "éè´è®¡åå表", ErpPurchasePlanImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .itemRemark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "éè´ç³è¯·å¯¼å
¥æ¨¡æ¿.xls", "éè´ç³è¯·å表", ErpPurchaseRequestImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "éè´ç³è¯·å¯¼å
¥æ¨¡æ¿.xls", "éè´ç³è¯·å表", ErpPurchaseRequestImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .productPrice(null).count(null).taxPercent(null).needProduction(0).itemRemark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "éå®è®¢å导å
¥æ¨¡æ¿.xls", "éå®è®¢åå表", ErpSaleOrderImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "éå®è®¢å导å
¥æ¨¡æ¿.xls", "éå®è®¢åå表", ErpSaleOrderImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .type(1).isLegal(1).remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "è忥é
置导å
¥æ¨¡æ¿.xls", "è忥é
ç½®å表", HrmAttendanceHolidayImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "è忥é
置导å
¥æ¨¡æ¿.xls", "è忥é
ç½®å表", HrmAttendanceHolidayImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .remark("ç¤ºä¾æ°æ®") |
| | | .build() |
| | | ); |
| | | ExcelUtils.write(response, "èå¤å¯¼å
¥æ¨¡æ¿.xls", "èå¤è®°å½", HrmAttendanceRecordImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "èå¤å¯¼å
¥æ¨¡æ¿.xls", "èå¤è®°å½", HrmAttendanceRecordImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .expireDate(LocalDate.of(2029, 1, 1)).remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "è¯ä¹¦èµè´¨å¯¼å
¥æ¨¡æ¿.xls", "è¯ä¹¦èµè´¨å表", HrmCertificateImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "è¯ä¹¦èµè´¨å¯¼å
¥æ¨¡æ¿.xls", "è¯ä¹¦èµè´¨å表", HrmCertificateImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .effectiveDate(LocalDate.of(2026, 1, 1)).status(0).remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "å工社ä¿å
¬ç§¯éæ¡£æ¡å¯¼å
¥æ¨¡æ¿.xls", "å工社ä¿å
¬ç§¯éæ¡£æ¡å表", |
| | | ExcelUtils.writeTemplate(response, "å工社ä¿å
¬ç§¯éæ¡£æ¡å¯¼å
¥æ¨¡æ¿.xls", "å工社ä¿å
¬ç§¯éæ¡£æ¡å表", |
| | | HrmEmployeeSocialSecurityImportExcelVO.class, list); |
| | | } |
| | | |
| | |
| | | .status(0).remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "社ä¿å
¬ç§¯éæ¹æ¡å¯¼å
¥æ¨¡æ¿.xls", "社ä¿å
¬ç§¯éæ¹æ¡å表", |
| | | ExcelUtils.writeTemplate(response, "社ä¿å
¬ç§¯éæ¹æ¡å¯¼å
¥æ¨¡æ¿.xls", "社ä¿å
¬ç§¯éæ¹æ¡å表", |
| | | HrmSocialSecuritySchemeImportExcelVO.class, list); |
| | | } |
| | | |
| | |
| | | .taxRate(new BigDecimal("3")).quickDeduction(new BigDecimal("0")).status(0).remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "个ç¨ç¨çé
置导å
¥æ¨¡æ¿.xls", "个ç¨ç¨çé
ç½®å表", |
| | | ExcelUtils.writeTemplate(response, "个ç¨ç¨çé
置导å
¥æ¨¡æ¿.xls", "个ç¨ç¨çé
ç½®å表", |
| | | HrmTaxRateConfigImportExcelVO.class, list); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | private Map<Long, HrmEmployeeDO> buildEmployeeMap(java.util.Collection<Long> employeeIds) { |
| | | // å¿
é¡»è¿å坿¥å null key ç空 Mapï¼è°ç¨æ¹ä¼ employeeMap.get(certificate.getEmployeeId())ï¼ |
| | | // è employeeId å
许为空ï¼è¯ä»¶/ååæªç»å®åå·¥ï¼ï¼Map.of() ç get(null) 伿 NPE 导è´å表æ¥å£ 500 |
| | | if (CollUtil.isEmpty(employeeIds)) { |
| | | return Map.of(); |
| | | return new HashMap<>(); |
| | | } |
| | | return employeeService.getEmployeeList(employeeIds).stream() |
| | | .collect(java.util.stream.Collectors.toMap(HrmEmployeeDO::getId, e -> e, (a, b) -> a)); |
| | |
| | | .remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "æç计å导å
¥æ¨¡æ¿.xls", "æç计åå表", MesCalPlanImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "æç计å导å
¥æ¨¡æ¿.xls", "æç计åå表", MesCalPlanImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "ç¹æ£ä¿å
»æ¹æ¡å¯¼å
¥æ¨¡æ¿.xls", "ç¹æ£ä¿å
»æ¹æ¡å表", MesDvCheckPlanImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "ç¹æ£ä¿å
»æ¹æ¡å¯¼å
¥æ¨¡æ¿.xls", "ç¹æ£ä¿å
»æ¹æ¡å表", MesDvCheckPlanImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "设å¤ç¹æ£è®°å½å¯¼å
¥æ¨¡æ¿.xls", "设å¤ç¹æ£è®°å½å表", MesDvCheckRecordImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "设å¤ç¹æ£è®°å½å¯¼å
¥æ¨¡æ¿.xls", "设å¤ç¹æ£è®°å½å表", MesDvCheckRecordImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "设å¤ä¿å
»è®°å½å¯¼å
¥æ¨¡æ¿.xls", "设å¤ä¿å
»è®°å½å表", MesDvMaintenRecordImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "设å¤ä¿å
»è®°å½å¯¼å
¥æ¨¡æ¿.xls", "设å¤ä¿å
»è®°å½å表", MesDvMaintenRecordImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "计éå¨å
·å¯¼å
¥æ¨¡æ¿.xls", "计éå¨å
·å表", MesDvMeteringImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "计éå¨å
·å¯¼å
¥æ¨¡æ¿.xls", "计éå¨å
·å表", MesDvMeteringImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "è®¡éæ£æµè®°å½å¯¼å
¥æ¨¡æ¿.xls", "è®¡éæ£æµè®°å½å表", MesDvMeteringCheckImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "è®¡éæ£æµè®°å½å¯¼å
¥æ¨¡æ¿.xls", "è®¡éæ£æµè®°å½å表", MesDvMeteringCheckImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "维修工å导å
¥æ¨¡æ¿.xls", "维修工åå表", MesDvRepairImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "维修工å导å
¥æ¨¡æ¿.xls", "维修工åå表", MesDvRepairImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "设计项ç®å¯¼å
¥æ¨¡æ¿.xls", "设计项ç®å表", MesPdProjectImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "设计项ç®å¯¼å
¥æ¨¡æ¿.xls", "设计项ç®å表", MesPdProjectImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "ç产æ¥å·¥å¯¼å
¥æ¨¡æ¿.xls", "ç产æ¥å·¥å表", MesProFeedbackImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "ç产æ¥å·¥å¯¼å
¥æ¨¡æ¿.xls", "ç产æ¥å·¥å表", MesProFeedbackImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .name("8æåçµè¿ç»´æç").workDate(java.time.LocalDate.of(2026, 8, 20)).shift(1).workType(1) |
| | | .region("110kV ååºçº¿").teamName("åçµè¿ç»´ä¸ç").personnel("å¼ ä¸,æå").remark("").build() |
| | | ); |
| | | ExcelUtils.write(response, "çµåè¿ç»´æ¥å导å
¥æ¨¡æ¿.xls", "çµåè¿ç»´æ¥åå表", MesProMaintenanceCalendarImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "çµåè¿ç»´æ¥å导å
¥æ¨¡æ¿.xls", "çµåè¿ç»´æ¥åå表", MesProMaintenanceCalendarImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .teamName("è¿ç»´ä¸ç").planDate(java.time.LocalDateTime.of(2026, 8, 1, 9, 0, 0)) |
| | | .remark("").itemCode("").itemQuantity(new java.math.BigDecimal("10")).itemRemark("").build() |
| | | ); |
| | | ExcelUtils.write(response, "çµåä½ä¸è®¡å导å
¥æ¨¡æ¿.xls", "çµåä½ä¸è®¡åå表", MesProMaintenancePlanImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "çµåä½ä¸è®¡å导å
¥æ¨¡æ¿.xls", "çµåä½ä¸è®¡åå表", MesProMaintenancePlanImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .clientName("").requestDate(java.time.LocalDateTime.of(2026, 10, 16, 9, 0, 0)) |
| | | .remark("").build() |
| | | ); |
| | | ExcelUtils.write(response, "ç产主计å导å
¥æ¨¡æ¿.xls", "ç产主计åå表", MesProMpsImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "ç产主计å导å
¥æ¨¡æ¿.xls", "ç产主计åå表", MesProMpsImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "ç产工å导å
¥æ¨¡æ¿.xls", "ç产工åå表", MesProWorkOrderImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "ç产工å导å
¥æ¨¡æ¿.xls", "ç产工åå表", MesProWorkOrderImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "è¿ç¨æ£éªå导å
¥æ¨¡æ¿.xls", "è¿ç¨æ£éªåå表", MesQcIpqcImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "è¿ç¨æ£éªå导å
¥æ¨¡æ¿.xls", "è¿ç¨æ£éªåå表", MesQcIpqcImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "æ¥ææ£éªå导å
¥æ¨¡æ¿.xls", "æ¥ææ£éªåå表", MesQcIqcImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "æ¥ææ£éªå导å
¥æ¨¡æ¿.xls", "æ¥ææ£éªåå表", MesQcIqcImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "åºè´§æ£éªå导å
¥æ¨¡æ¿.xls", "åºè´§æ£éªåå表", MesQcOqcImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "åºè´§æ£éªå导å
¥æ¨¡æ¿.xls", "åºè´§æ£éªåå表", MesQcOqcImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "å§å¤æ£æµè¯éªå导å
¥æ¨¡æ¿.xls", "å§å¤æ£æµè¯éªåå表", MesQcOutsourceTestImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "å§å¤æ£æµè¯éªå导å
¥æ¨¡æ¿.xls", "å§å¤æ£æµè¯éªåå表", MesQcOutsourceTestImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "éè´§æ£éªå导å
¥æ¨¡æ¿.xls", "éè´§æ£éªåå表", MesQcRqcImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "éè´§æ£éªå导å
¥æ¨¡æ¿.xls", "éè´§æ£éªåå表", MesQcRqcImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .status(1).remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "å·¥å
·å¯¼å
¥æ¨¡æ¿.xls", "å·¥å
·å表", MesTmToolImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "å·¥å
·å¯¼å
¥æ¨¡æ¿.xls", "å·¥å
·å表", MesTmToolImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "å°è´§éç¥å导å
¥æ¨¡æ¿.xls", "å°è´§éç¥åå表", MesWmArrivalNoticeImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "å°è´§éç¥å导å
¥æ¨¡æ¿.xls", "å°è´§éç¥åå表", MesWmArrivalNoticeImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "设å¤å
¥åºå导å
¥æ¨¡æ¿.xls", "设å¤å
¥åºåå表", MesWmEquipmentReceiptImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "设å¤å
¥åºå导å
¥æ¨¡æ¿.xls", "设å¤å
¥åºåå表", MesWmEquipmentReceiptImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "éè´å
¥åºå导å
¥æ¨¡æ¿.xls", "éè´å
¥åºåå表", MesWmItemReceiptImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "éè´å
¥åºå导å
¥æ¨¡æ¿.xls", "éè´å
¥åºåå表", MesWmItemReceiptImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | @Operation(summary = "ä¸è½½åºå导å
¥æ¨¡æ¿") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm-material-stock:adjust')") |
| | | public void importTemplate(HttpServletResponse response) throws IOException { |
| | | ExcelUtils.write(response, "åºå导å
¥æ¨¡æ¿.xls", "åºåæç»", MesWmStockImportExcelVO.class, Collections.emptyList()); |
| | | ExcelUtils.writeTemplate(response, "åºå导å
¥æ¨¡æ¿.xls", "åºåæç»", MesWmStockImportExcelVO.class, Collections.emptyList()); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .sourceDocType("").sourceDocCode("").remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "æé¡¹åºåºå导å
¥æ¨¡æ¿.xls", "æé¡¹åºåºåå表", MesWmMiscIssueImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "æé¡¹åºåºå导å
¥æ¨¡æ¿.xls", "æé¡¹åºåºåå表", MesWmMiscIssueImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .sourceDocType("").sourceDocCode("").remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "æé¡¹å
¥åºå导å
¥æ¨¡æ¿.xls", "æé¡¹å
¥åºåå表", MesWmMiscReceiptImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "æé¡¹å
¥åºå导å
¥æ¨¡æ¿.xls", "æé¡¹å
¥åºåå表", MesWmMiscReceiptImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "å¤ååæå导å
¥æ¨¡æ¿.xls", "å¤ååæåå表", MesWmOutsourceIssueImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "å¤ååæå导å
¥æ¨¡æ¿.xls", "å¤ååæåå表", MesWmOutsourceIssueImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "å¤åå
¥åºå导å
¥æ¨¡æ¿.xls", "å¤åå
¥åºåå表", MesWmOutsourceReceiptImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "å¤åå
¥åºå导å
¥æ¨¡æ¿.xls", "å¤åå
¥åºåå表", MesWmOutsourceReceiptImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .width(new java.math.BigDecimal("40.00")).remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "è£
ç®±å导å
¥æ¨¡æ¿.xls", "è£
ç®±åå表", MesWmPackageImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "è£
ç®±å导å
¥æ¨¡æ¿.xls", "è£
ç®±åå表", MesWmPackageImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "çäº§é¢æåºåºå导å
¥æ¨¡æ¿.xls", "çäº§é¢æåºåºåå表", MesWmProductIssueImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "çäº§é¢æåºåºå导å
¥æ¨¡æ¿.xls", "çäº§é¢æåºåºåå表", MesWmProductIssueImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "äº§åæ¶è´§å导å
¥æ¨¡æ¿.xls", "äº§åæ¶è´§åå表", MesWmProductReceiptImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "äº§åæ¶è´§å导å
¥æ¨¡æ¿.xls", "äº§åæ¶è´§åå表", MesWmProductReceiptImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .contactName("å¼ ä¸").remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "éå®åºåºå导å
¥æ¨¡æ¿.xls", "éå®åºåºåå表", MesWmProductSalesImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "éå®åºåºå导å
¥æ¨¡æ¿.xls", "éå®åºåºåå表", MesWmProductSalesImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "ç产éæå导å
¥æ¨¡æ¿.xls", "ç产éæåå表", MesWmReturnIssueImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "ç产éæå导å
¥æ¨¡æ¿.xls", "ç产éæåå表", MesWmReturnIssueImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .returnReason("è´¨éé®é¢").remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "éå®éè´§å导å
¥æ¨¡æ¿.xls", "éå®éè´§åå表", MesWmReturnSalesImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "éå®éè´§å导å
¥æ¨¡æ¿.xls", "éå®éè´§åå表", MesWmReturnSalesImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .returnReason("è´¨éä¸åæ ¼").remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "ä¾åºåéè´§å导å
¥æ¨¡æ¿.xls", "ä¾åºåéè´§åå表", MesWmReturnVendorImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "ä¾åºåéè´§å导å
¥æ¨¡æ¿.xls", "ä¾åºåéè´§åå表", MesWmReturnVendorImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "åè´§éç¥å导å
¥æ¨¡æ¿.xls", "åè´§éç¥åå表", MesWmSalesNoticeImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "åè´§éç¥å导å
¥æ¨¡æ¿.xls", "åè´§éç¥åå表", MesWmSalesNoticeImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .recipientName("å¼ ä¸").remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "转移å导å
¥æ¨¡æ¿.xls", "转移åå表", MesWmTransferImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "转移å导å
¥æ¨¡æ¿.xls", "转移åå表", MesWmTransferImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .remark("").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "èµè´¨è¯ä¹¦å¯¼å
¥æ¨¡æ¿.xls", "èµè´¨è¯ä¹¦å表", SrmSupplierCertificateImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "èµè´¨è¯ä¹¦å¯¼å
¥æ¨¡æ¿.xls", "èµè´¨è¯ä¹¦å表", SrmSupplierCertificateImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO; |
| | | import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; |
| | | import cn.iocoder.yudao.module.system.enums.common.SexEnum; |
| | | import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO; |
| | | import cn.iocoder.yudao.module.system.service.dept.DeptService; |
| | | import cn.iocoder.yudao.module.system.service.permission.PermissionService; |
| | | import cn.iocoder.yudao.module.system.service.permission.RoleService; |
| | |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_IMPORT_FILE_EMPTY; |
| | | import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_IMPORT_FILE_INVALID; |
| | | |
| | | @Tag(name = "管çåå° - ç¨æ·") |
| | | @RestController |
| | |
| | | } |
| | | |
| | | @GetMapping("/get-import-template") |
| | | @Operation(summary = "è·å¾å¯¼å
¥ç¨æ·æ¨¡æ¿") |
| | | @Operation(summary = "è·å¾å¯¼å
¥ç¨æ·æ¨¡æ¿", description = "é¨é¨æé¨é¨åç§°å¡«åï¼ç¤ºä¾åèªå½åç³»ç»çå®é¨é¨") |
| | | public void importTemplate(HttpServletResponse response) throws IOException { |
| | | // æå¨åå»ºå¯¼åº demo |
| | | // 示ä¾åå½åçå®é¨é¨åç§°ï¼é¿å
使ç¨è
ç
§æå®æ¹ demo 导è´ãé¨é¨ä¸åå¨ã |
| | | List<DeptDO> depts = deptService.getDeptList(new DeptListReqVO()); |
| | | String sampleDept1 = CollUtil.isNotEmpty(depts) ? depts.get(0).getName() : "请填åé¨é¨åç§°"; |
| | | String sampleDept2 = depts.size() > 1 ? depts.get(1).getName() : sampleDept1; |
| | | |
| | | List<UserImportExcelVO> list = Arrays.asList( |
| | | UserImportExcelVO.builder().username("yunai").deptId(1L).email("yunai@iocoder.cn").mobile("15601691300") |
| | | .nickname("è¶
级管çå").status(CommonStatusEnum.ENABLE.getStatus()).sex(SexEnum.MALE.getSex()).build(), |
| | | UserImportExcelVO.builder().username("yuanma").deptId(2L).email("yuanma@iocoder.cn").mobile("15601701300") |
| | | .nickname("æºç ").status(CommonStatusEnum.DISABLE.getStatus()).sex(SexEnum.FEMALE.getSex()).build() |
| | | UserImportExcelVO.builder().username("zhangsan").deptName(sampleDept1).email("zhangsan@example.com") |
| | | .mobile("13800000001").nickname("å¼ ä¸") |
| | | .status(CommonStatusEnum.ENABLE.getStatus()).sex(SexEnum.MALE.getSex()).build(), |
| | | UserImportExcelVO.builder().username("lisi").deptName(sampleDept2).email("lisi@example.com") |
| | | .mobile("13800000002").nickname("æå") |
| | | .status(CommonStatusEnum.ENABLE.getStatus()).sex(SexEnum.FEMALE.getSex()).build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "ç¨æ·å¯¼å
¥æ¨¡æ¿.xls", "ç¨æ·å表", UserImportExcelVO.class, list); |
| | | // æ¥æåæææ¬è¾åºï¼é¿å
æ¾ç¤ºæ Excel åºåå· |
| | | ExcelUtils.writeTemplate(response, "ç¨æ·å¯¼å
¥æ¨¡æ¿.xls", "ç¨æ·å表", UserImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | @PreAuthorize("@ss.hasPermission('system:user:import')") |
| | | public CommonResult<UserImportRespVO> importExcel(@RequestParam("file") MultipartFile file, |
| | | @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception { |
| | | List<UserImportExcelVO> list = ExcelUtils.read(file, UserImportExcelVO.class); |
| | | // 空æä»¶ / éæ³æä»¶ç»åºæç¡®æç¤ºï¼é¿å
åºå±å¼å¸¸åæãç³»ç»å¼å¸¸ã |
| | | if (file == null || file.isEmpty()) { |
| | | throw exception(USER_IMPORT_FILE_EMPTY); |
| | | } |
| | | List<UserImportExcelVO> list; |
| | | try { |
| | | list = ExcelUtils.read(file, UserImportExcelVO.class); |
| | | } catch (Exception ex) { |
| | | throw exception(USER_IMPORT_FILE_INVALID); |
| | | } |
| | | return success(userService.importUserList(list, updateSupport)); |
| | | } |
| | | |
| | |
| | | @ExcelProperty("ç¨æ·åç§°") |
| | | private String nickname; |
| | | |
| | | @ExcelProperty("é¨é¨ç¼å·") |
| | | private Long deptId; |
| | | @ExcelProperty("é¨é¨åç§°") |
| | | private String deptName; |
| | | |
| | | @ExcelProperty("ç¨æ·é®ç®±") |
| | | private String email; |
| | |
| | | ErrorCode USER_IS_DISABLE = new ErrorCode(1_002_003_006, "åå为ã{}ãçç¨æ·å·²è¢«ç¦ç¨"); |
| | | ErrorCode USER_COUNT_MAX = new ErrorCode(1_002_003_008, "åå»ºç¨æ·å¤±è´¥ï¼åå ï¼è¶
è¿ç§æ·æå¤§ç§æ·é
é¢({})ï¼"); |
| | | ErrorCode USER_IMPORT_INIT_PASSWORD = new ErrorCode(1_002_003_009, "åå§å¯ç ä¸è½ä¸ºç©º"); |
| | | ErrorCode USER_IMPORT_FILE_EMPTY = new ErrorCode(1_002_003_010, "è¯·éæ©è¦å¯¼å
¥ç Excel æä»¶"); |
| | | ErrorCode USER_IMPORT_FILE_INVALID = new ErrorCode(1_002_003_011, "Excel æä»¶æ ¼å¼ä¸æ£ç¡®ï¼è¯·ä¸è½½ææ°æ¨¡æ¿éæ°å¡«å"); |
| | | ErrorCode USER_MOBILE_NOT_EXISTS = new ErrorCode(1_002_003_010, "è¯¥ææºå·å°æªæ³¨å"); |
| | | ErrorCode USER_REGISTER_DISABLED = new ErrorCode(1_002_003_011, "注ååè½å·²å
³é"); |
| | | |
| | |
| | | import cn.iocoder.yudao.framework.datapermission.core.util.DataPermissionUtils; |
| | | import cn.iocoder.yudao.module.infra.api.config.ConfigApi; |
| | | import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthRegisterReqVO; |
| | | import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO; |
| | | import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdatePasswordReqVO; |
| | | import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdateReqVO; |
| | | import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserImportExcelVO; |
| | |
| | | } |
| | | // 1.2 ç³»ç»åæ°ä¸çåå§å¯ç ï¼ä½ä¸º Excel æªå¡«åå¯ç æ¶çå
åº |
| | | String initPassword = configApi.getConfigValueByKey(USER_INIT_PASSWORD_KEY); |
| | | // 1.3 é¢å è½½é¨é¨ï¼åç§° -> é¨é¨ï¼ç¨äºæåç§°è§£æï¼æ¨¡æ¿è¦æ±å¡«é¨é¨åç§°ï¼èéæ°æ®åºä¸»é® IDï¼ |
| | | List<DeptDO> allDepts = deptService.getDeptList(new DeptListReqVO()); |
| | | Map<String, DeptDO> deptByName = new HashMap<>(Math.max(allDepts.size(), 1)); |
| | | for (DeptDO dept : allDepts) { |
| | | deptByName.put(dept.getName().trim(), dept); |
| | | } |
| | | |
| | | // 2. éåï¼é个å建 or æ´æ° |
| | | UserImportRespVO respVO = UserImportRespVO.builder().createUsernames(new ArrayList<>()) |
| | |
| | | importUsers.forEach(importUser -> { |
| | | int currentIndex = index.getAndIncrement(); |
| | | String key = StrUtil.blankToDefault(importUser.getUsername(), "第 " + currentIndex + " è¡"); |
| | | // 2.0 è§£æé¨é¨ï¼æé¨é¨å称精确å¹é
ï¼å¹é
ä¸å°ç»åºæç¡®æç¤ºï¼ä¸åè¦æ±å¡«æ°æ®åºä¸»é® IDï¼ |
| | | DeptDO importDept = resolveImportDept(importUser.getDeptName(), deptByName); |
| | | if (importDept == null && StrUtil.isNotBlank(importUser.getDeptName())) { |
| | | respVO.getFailureUsernames().put(key, |
| | | "é¨é¨ã" + importUser.getDeptName().trim() + "ãä¸åå¨ï¼è¯·å¡«åé¨é¨ç®¡çä¸ç宿´é¨é¨åç§°"); |
| | | return; |
| | | } |
| | | Long importDeptId = importDept != null ? importDept.getId() : null; |
| | | // 2.1.0 è§£æè¯¥è¡åå§å¯ç ï¼Excel å¡«åäºå°±ç¨å¡«åçï¼å¦å读åç³»ç»åæ° |
| | | String effectivePassword = StrUtil.isNotBlank(importUser.getPassword()) |
| | | ? importUser.getPassword() : initPassword; |
| | |
| | | } |
| | | // 2.1.1 æ ¡éªå段æ¯å¦ç¬¦åè¦æ± |
| | | try { |
| | | ValidationUtils.validate(BeanUtils.toBean(importUser, UserSaveReqVO.class).setPassword(effectivePassword)); |
| | | ValidationUtils.validate(BeanUtils.toBean(importUser, UserSaveReqVO.class) |
| | | .setPassword(effectivePassword).setDeptId(importDeptId)); |
| | | } catch (ConstraintViolationException ex) { |
| | | respVO.getFailureUsernames().put(key, ex.getMessage()); |
| | | return; |
| | |
| | | // 2.1.2 æ ¡éªï¼å¤ææ¯å¦æä¸ç¬¦åçåå |
| | | try { |
| | | validateUserForCreateOrUpdate(null, null, importUser.getMobile(), importUser.getEmail(), |
| | | importUser.getDeptId(), null); |
| | | importDeptId, null); |
| | | } catch (ServiceException ex) { |
| | | respVO.getFailureUsernames().put(importUser.getUsername(), ex.getMessage()); |
| | | return; |
| | |
| | | AdminUserDO existUser = userMapper.selectByUsername(importUser.getUsername()); |
| | | if (existUser == null) { |
| | | userMapper.insert(BeanUtils.toBean(importUser, AdminUserDO.class) |
| | | .setDeptId(importDeptId) // é¨é¨å·²æåç§°è§£æï¼éæ¾å¼åå¡« ID |
| | | .setPassword(encodePassword(effectivePassword)).setPostIds(new HashSet<>())); // 设置åå§å¯ç å空å²ä½ç¼å·æ°ç» |
| | | respVO.getCreateUsernames().add(importUser.getUsername()); |
| | | return; |
| | |
| | | } |
| | | AdminUserDO updateUser = BeanUtils.toBean(importUser, AdminUserDO.class); |
| | | updateUser.setId(existUser.getId()); |
| | | updateUser.setDeptId(importDeptId); // é¨é¨å·²æåç§°è§£æï¼éæ¾å¼åå¡« ID |
| | | // å¯ç åç¬å¤çï¼Excel å¡«åäºææ´æ°ï¼æªå¡«åå置空ï¼ä¿æåå¯ç ä¸åï¼é¿å
æææåè¿åºï¼ |
| | | updateUser.setPassword(StrUtil.isNotBlank(importUser.getPassword()) |
| | | ? encodePassword(importUser.getPassword()) : null); |
| | |
| | | return respVO; |
| | | } |
| | | |
| | | /** |
| | | * è§£æå¯¼å
¥è¡éçé¨é¨åç§° |
| | | * |
| | | * <p>åªæé¨é¨å称精确å¹é
ï¼ä¸åè¦æ±å¡«åæ°æ®åºä¸»é® IDï¼ï¼ |
| | | * é¿å
使ç¨è
æ ä»å¾ç¥é¨é¨ ID 导è´å¯¼å
¥å¿
ç¶å¤±è´¥ã</p> |
| | | * |
| | | * @param raw 导å
¥å¡«åçé¨é¨åç§° |
| | | * @param byName é¨é¨åç§° -> é¨é¨ |
| | | * @return å¹é
å°çé¨é¨ï¼æªå¡«åæå¹é
ä¸å°è¿å null |
| | | */ |
| | | private DeptDO resolveImportDept(String raw, Map<String, DeptDO> byName) { |
| | | if (StrUtil.isBlank(raw)) { |
| | | return null; |
| | | } |
| | | return byName.get(raw.trim()); |
| | | } |
| | | |
| | | @Override |
| | | public List<AdminUserDO> getUserListByStatus(Integer status) { |
| | | return userMapper.selectListByStatus(status); |