Merge branch 'master' into feature/mall_product
commit
af701360b7
|
@ -12,9 +12,11 @@ import io.swagger.v3.oas.annotations.Operation;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -83,4 +85,11 @@ public class DeptController {
|
||||||
return success(DeptConvert.INSTANCE.convert(deptService.getDept(id)));
|
return success(DeptConvert.INSTANCE.convert(deptService.getDept(id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "批量组织架构导入")
|
||||||
|
@PostMapping(value = "/batch/import", name = "批量组织架构导入")
|
||||||
|
public CommonResult<Boolean> batchImport(@RequestParam("file") MultipartFile file) throws IOException {
|
||||||
|
deptService.batchImport(file);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept;
|
||||||
|
|
||||||
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Title:BatchImportVO
|
||||||
|
* @Description: TODO
|
||||||
|
* @author: tangqian
|
||||||
|
* @date: 2023/5/30 11:11
|
||||||
|
* @version: V1.0.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class BatchImportVO implements Serializable {
|
||||||
|
private static final long serialVersionUID = -1235962811424997478L;
|
||||||
|
@ExcelProperty("名称")
|
||||||
|
private String depName;
|
||||||
|
@ExcelProperty("层级")
|
||||||
|
private String hierarchy;
|
||||||
|
@ExcelProperty("关系")
|
||||||
|
private String relation;
|
||||||
|
@ExcelProperty("标识(唯一)")
|
||||||
|
private String characteristic;
|
||||||
|
}
|
|
@ -71,4 +71,6 @@ public class DeptDO extends TenantBaseDO {
|
||||||
*/
|
*/
|
||||||
private String parentOrganizationName;
|
private String parentOrganizationName;
|
||||||
|
|
||||||
|
|
||||||
|
private String characteristic;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,9 @@ import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptCreateRe
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptUpdateReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptUpdateReqVO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -115,4 +117,5 @@ public interface DeptService {
|
||||||
*/
|
*/
|
||||||
void validateDeptList(Collection<Long> ids);
|
void validateDeptList(Collection<Long> ids);
|
||||||
|
|
||||||
|
void batchImport(MultipartFile file) throws IOException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,11 @@ package cn.iocoder.yudao.module.system.service.dept;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
|
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||||
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
||||||
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
||||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.BatchImportVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptCreateReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptUpdateReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptUpdateReqVO;
|
||||||
|
@ -13,6 +15,11 @@ import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||||
import cn.iocoder.yudao.module.system.dal.mysql.dept.DeptMapper;
|
import cn.iocoder.yudao.module.system.dal.mysql.dept.DeptMapper;
|
||||||
import cn.iocoder.yudao.module.system.enums.dept.DeptIdEnum;
|
import cn.iocoder.yudao.module.system.enums.dept.DeptIdEnum;
|
||||||
import cn.iocoder.yudao.module.system.mq.producer.dept.DeptProducer;
|
import cn.iocoder.yudao.module.system.mq.producer.dept.DeptProducer;
|
||||||
|
import cn.iocoder.yudao.module.system.util.TransactionalService;
|
||||||
|
import com.alibaba.excel.EasyExcel;
|
||||||
|
import com.alibaba.excel.context.AnalysisContext;
|
||||||
|
import com.alibaba.excel.event.AnalysisEventListener;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
@ -20,12 +27,18 @@ import com.google.common.collect.ImmutableMultimap;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||||
|
@ -43,7 +56,7 @@ public class DeptServiceImpl implements DeptService {
|
||||||
/**
|
/**
|
||||||
* 部门缓存
|
* 部门缓存
|
||||||
* key:部门编号 {@link DeptDO#getId()}
|
* key:部门编号 {@link DeptDO#getId()}
|
||||||
*
|
* <p>
|
||||||
* 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
|
* 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
|
@ -52,7 +65,7 @@ public class DeptServiceImpl implements DeptService {
|
||||||
* 父部门缓存
|
* 父部门缓存
|
||||||
* key:部门编号 {@link DeptDO#getParentId()}
|
* key:部门编号 {@link DeptDO#getParentId()}
|
||||||
* value: 直接子部门列表
|
* value: 直接子部门列表
|
||||||
*
|
* <p>
|
||||||
* 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
|
* 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
|
@ -63,6 +76,8 @@ public class DeptServiceImpl implements DeptService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private DeptProducer deptProducer;
|
private DeptProducer deptProducer;
|
||||||
|
@Resource
|
||||||
|
private TransactionalService transactionalService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化 {@link #parentDeptCache} 和 {@link #deptCache} 缓存
|
* 初始化 {@link #parentDeptCache} 和 {@link #deptCache} 缓存
|
||||||
|
@ -98,13 +113,13 @@ public class DeptServiceImpl implements DeptService {
|
||||||
// 插入部门
|
// 插入部门
|
||||||
DeptDO dept = DeptConvert.INSTANCE.convert(reqVO);
|
DeptDO dept = DeptConvert.INSTANCE.convert(reqVO);
|
||||||
dept.setId(IdWorker.getId());
|
dept.setId(IdWorker.getId());
|
||||||
if(DeptIdEnum.ROOT.getId().equals(dept.getParentId())){
|
if (DeptIdEnum.ROOT.getId().equals(dept.getParentId())) {
|
||||||
dept.setParentOrganizationIds(dept.getId()+"");
|
dept.setParentOrganizationIds(dept.getId() + "");
|
||||||
dept.setParentOrganizationName(dept.getName());
|
dept.setParentOrganizationName(dept.getName());
|
||||||
}else{
|
} else {
|
||||||
DeptDO parent = deptMapper.selectById(reqVO.getParentId());
|
DeptDO parent = deptMapper.selectById(reqVO.getParentId());
|
||||||
dept.setParentOrganizationIds(parent.getParentOrganizationIds()+","+dept.getId());
|
dept.setParentOrganizationIds(parent.getParentOrganizationIds() + "," + dept.getId());
|
||||||
dept.setParentOrganizationName(parent.getParentOrganizationName()+">"+dept.getName());
|
dept.setParentOrganizationName(parent.getParentOrganizationName() + ">" + dept.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
deptMapper.insert(dept);
|
deptMapper.insert(dept);
|
||||||
|
@ -122,13 +137,13 @@ public class DeptServiceImpl implements DeptService {
|
||||||
validateForCreateOrUpdate(reqVO.getId(), reqVO.getParentId(), reqVO.getName());
|
validateForCreateOrUpdate(reqVO.getId(), reqVO.getParentId(), reqVO.getName());
|
||||||
// 更新部门
|
// 更新部门
|
||||||
DeptDO updateObj = DeptConvert.INSTANCE.convert(reqVO);
|
DeptDO updateObj = DeptConvert.INSTANCE.convert(reqVO);
|
||||||
if(DeptIdEnum.ROOT.getId().equals(updateObj.getParentId())){
|
if (DeptIdEnum.ROOT.getId().equals(updateObj.getParentId())) {
|
||||||
updateObj.setParentOrganizationIds(updateObj.getId()+"");
|
updateObj.setParentOrganizationIds(updateObj.getId() + "");
|
||||||
updateObj.setParentOrganizationName(updateObj.getName());
|
updateObj.setParentOrganizationName(updateObj.getName());
|
||||||
}else{
|
} else {
|
||||||
DeptDO parent = deptMapper.selectById(reqVO.getParentId());
|
DeptDO parent = deptMapper.selectById(reqVO.getParentId());
|
||||||
updateObj.setParentOrganizationIds(parent.getParentOrganizationIds()+","+updateObj.getId());
|
updateObj.setParentOrganizationIds(parent.getParentOrganizationIds() + "," + updateObj.getId());
|
||||||
updateObj.setParentOrganizationName(parent.getParentOrganizationName()+">"+updateObj.getName());
|
updateObj.setParentOrganizationName(parent.getParentOrganizationName() + ">" + updateObj.getName());
|
||||||
}
|
}
|
||||||
deptMapper.updateById(updateObj);
|
deptMapper.updateById(updateObj);
|
||||||
// 发送刷新消息
|
// 发送刷新消息
|
||||||
|
@ -167,8 +182,8 @@ public class DeptServiceImpl implements DeptService {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public DeptDO findParentDept(Long tenantId) {
|
public DeptDO findParentDept(Long tenantId) {
|
||||||
List<DeptDO> deptDOs = deptMapper.selectList(Wrappers.lambdaQuery(DeptDO.class).eq(DeptDO::getParentId,DeptIdEnum.ROOT.getId()).eq(DeptDO::getTenantId,tenantId));
|
List<DeptDO> deptDOs = deptMapper.selectList(Wrappers.lambdaQuery(DeptDO.class).eq(DeptDO::getParentId, DeptIdEnum.ROOT.getId()).eq(DeptDO::getTenantId, tenantId));
|
||||||
if(deptDOs!=null && deptDOs.size() > 0){
|
if (deptDOs != null && deptDOs.size() > 0) {
|
||||||
return deptDOs.get(0);
|
return deptDOs.get(0);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -305,4 +320,99 @@ public class DeptServiceImpl implements DeptService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static List<DeptDO> deptDOS2 = new ArrayList<>();
|
||||||
|
private static List<DeptDO> deptDOS3 = new ArrayList<>();
|
||||||
|
private static List<DeptDO> deptDOS4 = new ArrayList<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void batchImport(MultipartFile file) throws IOException {
|
||||||
|
List<BatchImportVO> list = ExcelUtils.read(file, BatchImportVO.class);
|
||||||
|
try {
|
||||||
|
EasyExcel.read(file.getInputStream(), BatchImportVO.class, new AnalysisEventListener<BatchImportVO>() {
|
||||||
|
|
||||||
|
private final List<BatchImportVO> deptList = new ArrayList<>(10000);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invoke(BatchImportVO o, AnalysisContext analysisContext) {
|
||||||
|
deptList.add(o);
|
||||||
|
if (deptList.size() % 15 == 0) {
|
||||||
|
batchInsert();
|
||||||
|
deptList.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
|
||||||
|
if (CollectionUtils.isNotEmpty(deptList)) {
|
||||||
|
batchInsert();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void batchInsert() {
|
||||||
|
Map<String, List<BatchImportVO>> collect = deptList.stream().collect(Collectors.groupingBy(BatchImportVO::getHierarchy));
|
||||||
|
List<BatchImportVO> batchImportVOS1 = collect.get("1");
|
||||||
|
List<BatchImportVO> batchImportVOS2 = collect.get("2");
|
||||||
|
List<BatchImportVO> batchImportVOS3 = collect.get("3");
|
||||||
|
List<BatchImportVO> batchImportVOS4 = collect.get("4");
|
||||||
|
transactionalService.run(() -> {
|
||||||
|
// 装入层级1
|
||||||
|
BatchImportVO batchImportVO1 = batchImportVOS1.get(0);
|
||||||
|
DeptDO deptDO1 = new DeptDO();
|
||||||
|
deptDO1.setParentId(0L);
|
||||||
|
deptDO1.setName(batchImportVO1.getDepName());
|
||||||
|
deptDO1.setParentOrganizationName(batchImportVO1.getDepName());
|
||||||
|
deptDO1.setCharacteristic(batchImportVO1.getCharacteristic());
|
||||||
|
deptMapper.insert(deptDO1);
|
||||||
|
deptDO1.setParentOrganizationIds(deptDO1.getId().toString());
|
||||||
|
deptMapper.updateById(deptDO1);
|
||||||
|
// 装入层级2
|
||||||
|
for (BatchImportVO batchImportVO : batchImportVOS2) {
|
||||||
|
DeptDO deptDO2 = new DeptDO();
|
||||||
|
deptDO2.setName(batchImportVO.getDepName());
|
||||||
|
deptDO2.setParentId(deptDO1.getId());
|
||||||
|
deptDO2.setParentOrganizationName(deptDO1.getName() + "," + batchImportVO.getDepName());
|
||||||
|
deptDO2.setCharacteristic(batchImportVO.getCharacteristic());
|
||||||
|
deptMapper.insert(deptDO2);
|
||||||
|
deptDO2.setParentOrganizationIds(deptDO1.getId() + "," + deptDO2.getId());
|
||||||
|
deptMapper.updateById(deptDO2);
|
||||||
|
deptDOS2.add(deptDO2);
|
||||||
|
}
|
||||||
|
// 装入层级3
|
||||||
|
for (BatchImportVO batchImportVO : batchImportVOS3) {
|
||||||
|
DeptDO deptDO3 = new DeptDO();
|
||||||
|
deptDO3.setName(batchImportVO.getDepName());
|
||||||
|
List<DeptDO> collect1 = deptDOS2.stream().filter(e -> e.getCharacteristic().equals(batchImportVO.getCharacteristic())).collect(Collectors.toList());
|
||||||
|
DeptDO deptDO = collect1.get(0);
|
||||||
|
deptDO3.setParentId(deptDO.getId());
|
||||||
|
deptDO3.setParentOrganizationName(deptDO.getName() + "," + batchImportVO.getDepName());
|
||||||
|
deptMapper.insert(deptDO3);
|
||||||
|
deptDO3.setParentOrganizationIds(deptDO.getId() + "," + deptDO3.getId());
|
||||||
|
deptMapper.updateById(deptDO3);
|
||||||
|
deptDOS3.add(deptDO3);
|
||||||
|
}
|
||||||
|
// 装入层级4
|
||||||
|
for (BatchImportVO batchImportVO : batchImportVOS4) {
|
||||||
|
DeptDO deptDO4 = new DeptDO();
|
||||||
|
deptDO4.setName(batchImportVO.getDepName());
|
||||||
|
List<DeptDO> collect1 = deptDOS3.stream().filter(e -> e.getCharacteristic().equals(batchImportVO.getCharacteristic())).collect(Collectors.toList());
|
||||||
|
DeptDO deptDO = collect1.get(0);
|
||||||
|
deptDO4.setParentId(deptDO.getId());
|
||||||
|
deptDO4.setParentOrganizationName(deptDO.getName() + "," + batchImportVO.getDepName());
|
||||||
|
deptMapper.insert(deptDO4);
|
||||||
|
deptDO4.setParentOrganizationIds(deptDO.getId() + "," + deptDO4.getId());
|
||||||
|
deptMapper.updateById(deptDO4);
|
||||||
|
deptDOS3.add(deptDO4);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).sheet().headRowNumber(1).doRead();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("导入组织架构失败!", e);
|
||||||
|
} finally {
|
||||||
|
deptDOS2.removeAll(deptDOS2);
|
||||||
|
deptDOS3.removeAll(deptDOS3);
|
||||||
|
deptDOS4.removeAll(deptDOS4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
package cn.iocoder.yudao.module.system.util;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
import org.springframework.transaction.TransactionDefinition;
|
||||||
|
import org.springframework.transaction.TransactionStatus;
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Title: TransactionalService</p>
|
||||||
|
* <p>Description: 事务</p>
|
||||||
|
* <p>Package: com.cmx.activity.service</p>
|
||||||
|
* <p>Date: 2023年01月12日 21:10</p>
|
||||||
|
*
|
||||||
|
* @author wanglong [atva725@qq.com]
|
||||||
|
* @version V1.0.0
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class TransactionalService {
|
||||||
|
|
||||||
|
private final TransactionDefinition transactionDefinition;
|
||||||
|
private final PlatformTransactionManager platformTransactionManager;
|
||||||
|
|
||||||
|
public void run(Runnable runnable) {
|
||||||
|
final TransactionStatus transaction = platformTransactionManager.getTransaction(transactionDefinition);
|
||||||
|
try {
|
||||||
|
runnable.run();
|
||||||
|
platformTransactionManager.commit(transaction);
|
||||||
|
} catch (Exception e) {
|
||||||
|
platformTransactionManager.rollback(transaction);
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public <R> R run(Callable<R> callable) {
|
||||||
|
R rev;
|
||||||
|
final TransactionStatus transaction = platformTransactionManager.getTransaction(transactionDefinition);
|
||||||
|
try {
|
||||||
|
rev = callable.call();
|
||||||
|
platformTransactionManager.commit(transaction);
|
||||||
|
} catch (Exception e) {
|
||||||
|
platformTransactionManager.rollback(transaction);
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
return rev;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue