no message
parent
8a2337e458
commit
e6b8b18a3f
|
|
@ -40,7 +40,7 @@ import java.util.List;
|
|||
* 收货地址 Controller
|
||||
*
|
||||
* @author hj
|
||||
* @since 2024-12-26 15:35:23
|
||||
* @since 2024-12-26 15:35:23
|
||||
* copyright 友仓
|
||||
*/
|
||||
|
||||
|
|
@ -115,7 +115,7 @@ public class AddressController {
|
|||
@SaCheckPermission("address:exportAddress")
|
||||
@OperateLog
|
||||
public void exportAddress(HttpServletResponse response) throws IOException {
|
||||
List<AddressExcelVO> addressList = addressQueryService.getAddressExcelVOList();
|
||||
List<AddressExcelVO> addressList = addressQueryService.queryAddressExcelVO();
|
||||
SmartExcelUtil.exportExcel(response, "收货地址信息.xlsx", "收货地址", AddressExcelVO.class, addressList);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,17 +6,16 @@ import net.lab1024.sa.admin.constant.AdminCacheConst;
|
|||
import net.lab1024.sa.admin.module.business.wms.base.address.domain.entity.AddressEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.address.dao.AddressDao;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import net.lab1024.sa.admin.util.TransactionCommitUtil;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 收货单位 Manager
|
||||
|
|
@ -27,6 +26,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
@CacheConfig(cacheNames = AdminCacheConst.Base.ADDRESS_ENTITY)
|
||||
public class AddressManager extends ServiceImpl<AddressDao, AddressEntity> {
|
||||
|
||||
@Resource
|
||||
|
|
@ -35,153 +35,61 @@ public class AddressManager extends ServiceImpl<AddressDao, AddressEntity> {
|
|||
@Resource
|
||||
private CacheManager cacheManager;
|
||||
|
||||
// 使用读写锁保证高并发下的缓存操作安全
|
||||
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
|
||||
private final Lock readLock = rwLock.readLock();
|
||||
private final Lock writeLock = rwLock.writeLock();
|
||||
|
||||
/**
|
||||
* 查询收货单位(带缓存)
|
||||
* 使用Spring Cache自动缓存查询结果
|
||||
* 使用Spring Cache进行缓存管理
|
||||
*/
|
||||
@Cacheable(value = AdminCacheConst.Base.ADDRESS_ENTITY, key = "#addressId", unless = "#result == null")
|
||||
@Cacheable(key = "#addressId", unless = "#result == null")
|
||||
public AddressEntity queryAddress(Long addressId) {
|
||||
try {
|
||||
readLock.lock();
|
||||
return addressDao.selectById(addressId);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
return addressDao.selectById(addressId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建收货单位(带缓存)
|
||||
* 事务提交后执行缓存刷新,保证数据一致性
|
||||
* 更新收货单位(清除缓存)
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public AddressEntity insert(AddressEntity entity) {
|
||||
super.save(entity);
|
||||
// 在事务提交后刷新缓存,确保数据库操作成功后再更新缓存
|
||||
executeAfterCommit("刷新收货单位缓存", () -> refreshCache(entity.getAddressId()));
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新收货单位(带缓存)
|
||||
* 事务提交后执行缓存刷新,保证数据一致性
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public AddressEntity update(AddressEntity entity) {
|
||||
@CacheEvict(key = "#entity.addressId")
|
||||
public void update(AddressEntity entity) {
|
||||
super.updateById(entity);
|
||||
// 在事务提交后刷新缓存,确保数据库操作成功后再更新缓存
|
||||
executeAfterCommit("刷新收货单位缓存", () -> refreshCache(entity.getAddressId()));
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除收货单位(清理缓存)
|
||||
* 事务提交后清除缓存
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@CacheEvict(key = "#addressId")
|
||||
public void deleteById(Long addressId) {
|
||||
super.removeById(addressId);
|
||||
// 在事务提交后清除缓存,确保数据库操作成功后再更新缓存
|
||||
executeAfterCommit("清除收货单位缓存", () -> evictCache(addressId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量创建收货单位(带缓存)
|
||||
* 事务提交后执行缓存刷新,保证数据一致性
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchInsert(List<AddressEntity> entities) {
|
||||
super.saveBatch(entities);
|
||||
// 在事务提交后批量刷新缓存
|
||||
executeAfterCommit("批量刷新收货单位缓存", () -> batchRefreshCache(entities));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新收货单位(带缓存)
|
||||
* 事务提交后执行缓存刷新,保证数据一致性
|
||||
* 批量更新收货单位(清理相关缓存)
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchUpdate(List<AddressEntity> entities) {
|
||||
super.updateBatchById(entities);
|
||||
// 在事务提交后批量刷新缓存
|
||||
executeAfterCommit("批量刷新收货单位缓存", () -> batchRefreshCache(entities));
|
||||
List<Long> addressIds = entities.stream().map(AddressEntity::getAddressId).filter(Objects::nonNull).distinct().toList();
|
||||
addressIds.forEach(this::clearCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除收货单位(清理缓存)
|
||||
* 事务提交后清除缓存
|
||||
* 批量删除收货单位(清理相关缓存)
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchDelete(List<Long> addressIds) {
|
||||
super.removeByIds(addressIds);
|
||||
// 在事务提交后批量清除缓存
|
||||
executeAfterCommit("批量清除收货单位缓存", () -> addressIds.forEach(this::evictCache));
|
||||
addressIds.forEach(this::clearCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用方法:事务提交后执行操作
|
||||
*
|
||||
* @param operationDesc 操作描述(用于日志)
|
||||
* @param operation 要执行的操作
|
||||
* 手工清理缓存
|
||||
*/
|
||||
private void executeAfterCommit(String operationDesc, Runnable operation) {
|
||||
TransactionCommitUtil.executeAfterCommit(operationDesc, operation);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新单个缓存
|
||||
* 使用写锁确保并发安全
|
||||
*/
|
||||
public void refreshCache(Long addressId) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
// 先清除可能存在的旧缓存
|
||||
evictCache(addressId);
|
||||
// 重新查询并缓存最新数据
|
||||
AddressEntity entity = addressDao.selectById(addressId);
|
||||
|
||||
// 手动更新缓存,避免使用@CachePut注解可能导致的问题
|
||||
if (entity != null) {
|
||||
Cache cache = cacheManager.getCache(AdminCacheConst.Base.ADDRESS_ENTITY);
|
||||
if (cache != null) {
|
||||
cache.put(addressId, entity);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量刷新缓存
|
||||
* 先收集所有ID,再逐一刷新,减少锁争用
|
||||
*/
|
||||
private void batchRefreshCache(Collection<AddressEntity> entities) {
|
||||
List<Long> addressIds = entities.stream()
|
||||
.map(AddressEntity::getAddressId)
|
||||
.distinct()
|
||||
.toList();
|
||||
addressIds.forEach(this::refreshCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动清除缓存
|
||||
* 使用写锁确保并发安全
|
||||
*/
|
||||
private void evictCache(Long addressId) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
public void clearCache(Long addressId) {
|
||||
if (addressId != null) {
|
||||
Cache cache = cacheManager.getCache(AdminCacheConst.Base.ADDRESS_ENTITY);
|
||||
if (cache != null) {
|
||||
cache.evict(addressId);
|
||||
}
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,12 @@ import net.lab1024.sa.admin.module.business.wms.base.address.domain.form.Address
|
|||
import net.lab1024.sa.admin.module.business.wms.base.address.domain.vo.AddressExcelVO;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.address.domain.vo.AddressVO;
|
||||
import net.lab1024.sa.base.common.domain.PageResult;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public interface AddressQueryService {
|
||||
/**
|
||||
|
|
@ -33,7 +36,15 @@ public interface AddressQueryService {
|
|||
* @param addressIdList 地址id集合
|
||||
* @return Map<Long, AreaEntity>
|
||||
*/
|
||||
Map<Long, AddressEntity> queryAddressList(List<Long> addressIdList);
|
||||
Map<Long, AddressEntity> queryByAddressIdsToMap(List<Long> addressIdList);
|
||||
|
||||
/**
|
||||
* 根据地址name集合查询地址信息
|
||||
*
|
||||
* @param addressNameList 地址name集合
|
||||
* @return List<AddressEntity>
|
||||
*/
|
||||
List<AddressEntity> queryByNames(List<String> addressNameList);
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -42,13 +53,13 @@ public interface AddressQueryService {
|
|||
* @param addressNameList 地址name集合
|
||||
* @return Map<Long, AddressEntity>
|
||||
*/
|
||||
Map<String, AddressEntity> queryAddressByNameList(List<String> addressNameList);
|
||||
Map<String, AddressEntity> queryByNamesToMap(List<String> addressNameList);
|
||||
|
||||
/**
|
||||
* 地址导出
|
||||
*
|
||||
* @return List<AddressExcelVO>
|
||||
*/
|
||||
List<AddressExcelVO> getAddressExcelVOList();
|
||||
List<AddressExcelVO> queryAddressExcelVO();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import org.springframework.stereotype.Service;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
|
|
@ -50,7 +51,7 @@ public class AddressQueryServiceImpl implements AddressQueryService {
|
|||
* @return List<AddressEntity>
|
||||
*/
|
||||
public List<AddressEntity> queryAddress(AddressSelect addressSelect) {
|
||||
return addressDao.selectList(null);
|
||||
return addressManager.list();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -59,11 +60,13 @@ public class AddressQueryServiceImpl implements AddressQueryService {
|
|||
* @param addressIdList 地址id集合
|
||||
* @return Map<Long, AreaEntity>
|
||||
*/
|
||||
public Map<Long, AddressEntity> queryAddressList(List<Long> addressIdList) {
|
||||
public Map<Long, AddressEntity> queryByAddressIdsToMap(List<Long> addressIdList) {
|
||||
if (CollectionUtils.isEmpty(addressIdList)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
addressIdList = addressIdList.stream().distinct().collect(Collectors.toList());
|
||||
// 去重
|
||||
addressIdList = addressIdList.stream().filter(Objects::nonNull).distinct().toList();
|
||||
//封装map
|
||||
Map<Long, AddressEntity> addressMap = Maps.newHashMap();
|
||||
for (Long addressId : addressIdList) {
|
||||
AddressEntity address = addressManager.queryAddress(addressId);
|
||||
|
|
@ -74,25 +77,43 @@ public class AddressQueryServiceImpl implements AddressQueryService {
|
|||
return addressMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据地址name集合查询地址信息
|
||||
*
|
||||
* @param addressNameList 地址name集合
|
||||
* @return List<AddressEntity>
|
||||
*/
|
||||
public List<AddressEntity> queryByNames(List<String> addressNameList) {
|
||||
if (CollectionUtils.isEmpty(addressNameList)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
//去重
|
||||
addressNameList = addressNameList.stream().filter(Objects::nonNull).distinct().toList();
|
||||
//查询收获单位
|
||||
LambdaQueryWrapper<AddressEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.in(AddressEntity::getName, addressNameList);
|
||||
return addressManager.list(queryWrapper);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据地址name集合查询地址信息
|
||||
*
|
||||
* @param addressNameList 地址name集合
|
||||
* @return Map<Long, AddressEntity>
|
||||
*/
|
||||
public Map<String, AddressEntity> queryAddressByNameList(List<String> addressNameList) {
|
||||
public Map<String, AddressEntity> queryByNamesToMap(List<String> addressNameList) {
|
||||
if (CollectionUtils.isEmpty(addressNameList)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
LambdaQueryWrapper<AddressEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.in(AddressEntity::getName, addressNameList);
|
||||
|
||||
List<AddressEntity> addressList = addressDao.selectList(queryWrapper);
|
||||
if (CollectionUtils.isEmpty(addressList)) {
|
||||
return Collections.emptyMap();
|
||||
//查询收获单位
|
||||
List<AddressEntity> addressList = queryByNames(addressNameList);
|
||||
//封装map
|
||||
Map<String, AddressEntity> addressMap = Maps.newHashMap();
|
||||
for (AddressEntity address : addressList) {
|
||||
addressMap.put(address.getName(), address);
|
||||
}
|
||||
return addressList.stream()
|
||||
.collect(Collectors.toMap(AddressEntity::getName, address -> address, (existing, replacement) -> existing));
|
||||
return addressMap;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -100,8 +121,8 @@ public class AddressQueryServiceImpl implements AddressQueryService {
|
|||
*
|
||||
* @return List<AddressExcelVO>
|
||||
*/
|
||||
public List<AddressExcelVO> getAddressExcelVOList() {
|
||||
List<AddressEntity> addressList = addressDao.selectList(null);
|
||||
public List<AddressExcelVO> queryAddressExcelVO() {
|
||||
List<AddressEntity> addressList = addressManager.list();
|
||||
return addressList.stream()
|
||||
.map(address ->
|
||||
AddressExcelVO.builder()
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class AddressServiceImpl implements AddressService {
|
||||
|
|
@ -44,8 +43,7 @@ public class AddressServiceImpl implements AddressService {
|
|||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<String> add(AddressAddForm addForm) {
|
||||
AddressEntity addressEntity = SmartBeanUtil.copy(addForm, AddressEntity.class);
|
||||
//新增并更新缓存
|
||||
addressManager.insert(addressEntity);
|
||||
addressManager.save(addressEntity);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
|
|
@ -118,21 +116,19 @@ public class AddressServiceImpl implements AddressService {
|
|||
return ResponseDTO.userErrorParam("数据为空");
|
||||
}
|
||||
|
||||
//获取所有去重后的收货单位
|
||||
List<String> addressName = dataList.stream().map(AddressImportForm::getName).distinct().collect(Collectors.toList());
|
||||
//获取所以收货单位
|
||||
List<String> addressName = dataList.stream().map(AddressImportForm::getName).toList();
|
||||
|
||||
//查询数据库存在的物料
|
||||
Map<String, AddressEntity> exitAddressMap = addressQueryService.queryAddressByNameList(addressName);
|
||||
//查询数据库存在的收获单位
|
||||
Map<String, AddressEntity> exitAddressMap = addressQueryService.queryByNamesToMap(addressName);
|
||||
|
||||
List<AddressEntity> insertToAddress = new ArrayList<>();
|
||||
List<AddressEntity> updateToAddress = new ArrayList<>();
|
||||
for (AddressImportForm addressImportForm : dataList) {
|
||||
|
||||
|
||||
//物料
|
||||
//收获单位
|
||||
AddressEntity address = exitAddressMap.get(addressImportForm.getName());
|
||||
|
||||
//物料为空则新增,否则更新
|
||||
//收获单位为空则新增,否则更新
|
||||
if (address == null) {
|
||||
insertToAddress.add(createAddress(addressImportForm.getName(), addressImportForm.getPerson(), addressImportForm.getTelephone(), addressImportForm.getAddress()));
|
||||
} else {
|
||||
|
|
@ -141,7 +137,7 @@ public class AddressServiceImpl implements AddressService {
|
|||
}
|
||||
|
||||
JoinerResult resultMsg = JoinerResult.createJoiner();
|
||||
return ResponseDTOUtil.buildResponseDTO(insertToAddress,updateToAddress,addressManager::batchInsert,addressManager::batchUpdate,resultMsg);
|
||||
return ResponseDTOUtil.buildResponseDTO(insertToAddress, updateToAddress, addressManager::saveBatch, addressManager::batchUpdate, resultMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -7,18 +7,16 @@ import net.lab1024.sa.admin.module.business.wms.base.area.domain.entity.AreaEnti
|
|||
import net.lab1024.sa.admin.module.business.wms.base.area.dao.AreaDao;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import net.lab1024.sa.admin.util.TransactionCommitUtil;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 库区信息 Manager
|
||||
|
|
@ -29,6 +27,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
@CacheConfig(cacheNames = AdminCacheConst.Base.AREA_ENTITY)
|
||||
public class AreaManager extends ServiceImpl<AreaDao, AreaEntity> {
|
||||
|
||||
@Resource
|
||||
|
|
@ -37,118 +36,61 @@ public class AreaManager extends ServiceImpl<AreaDao, AreaEntity> {
|
|||
@Resource
|
||||
private CacheManager cacheManager;
|
||||
|
||||
// 使用读写锁保证高并发下的缓存操作安全
|
||||
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
|
||||
private final Lock readLock = rwLock.readLock();
|
||||
private final Lock writeLock = rwLock.writeLock();
|
||||
|
||||
/**
|
||||
* 查询库区(带缓存)
|
||||
* 使用Spring Cache自动缓存查询结果
|
||||
* 使用Spring Cache进行缓存管理
|
||||
*/
|
||||
@Cacheable(value = AdminCacheConst.Base.AREA_ENTITY, key = "#areaId", unless = "#result == null")
|
||||
@Cacheable(key = "#areaId", unless = "#result == null")
|
||||
public AreaEntity queryArea(Long areaId) {
|
||||
try {
|
||||
readLock.lock();
|
||||
return areaDao.selectById(areaId);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
return areaDao.selectById(areaId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建库区(带缓存)
|
||||
* 事务提交后执行缓存刷新,保证数据一致性
|
||||
* 更新库区(清除缓存)
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public AreaEntity insert(AreaEntity entity) {
|
||||
super.save(entity);
|
||||
// 在事务提交后刷新缓存,确保数据库操作成功后再更新缓存
|
||||
executeAfterCommit("刷新库区缓存", () -> refreshCache(entity.getAreaId()));
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新库区(带缓存)
|
||||
* 事务提交后执行缓存刷新,保证数据一致性
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public AreaEntity update(AreaEntity entity) {
|
||||
@CacheEvict(key = "#entity.areaId")
|
||||
public void update(AreaEntity entity) {
|
||||
super.updateById(entity);
|
||||
// 在事务提交后刷新缓存,确保数据库操作成功后再更新缓存
|
||||
executeAfterCommit("刷新库区缓存", () -> refreshCache(entity.getAreaId()));
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除库区(清理缓存)
|
||||
* 事务提交后清除缓存
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@CacheEvict(key = "#areaId")
|
||||
public void deleteById(Long areaId) {
|
||||
super.removeById(areaId);
|
||||
// 在事务提交后清除缓存,确保数据库操作成功后再更新缓存
|
||||
executeAfterCommit("清除库区缓存", () -> evictCache(areaId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除库区(清理缓存)
|
||||
* 事务提交后清除缓存
|
||||
* 批量更新库区(清理相关缓存)
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchUpdate(List<AreaEntity> entities) {
|
||||
super.updateBatchById(entities);
|
||||
List<Long> areaIds = entities.stream().map(AreaEntity::getAreaId).filter(Objects::nonNull).distinct().toList();
|
||||
areaIds.forEach(this::clearCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除库区(清理相关缓存)
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchDelete(List<Long> areaIds) {
|
||||
super.removeByIds(areaIds);
|
||||
// 在事务提交后批量清除缓存
|
||||
executeAfterCommit("批量清除库区缓存", () -> areaIds.forEach(this::evictCache));
|
||||
areaIds.forEach(this::clearCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用方法:事务提交后执行操作
|
||||
*
|
||||
* @param operationDesc 操作描述(用于日志)
|
||||
* @param operation 要执行的操作
|
||||
* 手工清理缓存
|
||||
*/
|
||||
private void executeAfterCommit(String operationDesc, Runnable operation) {
|
||||
TransactionCommitUtil.executeAfterCommit(operationDesc, operation);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新单个缓存
|
||||
* 使用写锁确保并发安全
|
||||
*/
|
||||
public void refreshCache(Long areaId) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
// 先清除可能存在的旧缓存
|
||||
evictCache(areaId);
|
||||
// 重新查询并缓存最新数据
|
||||
AreaEntity entity = areaDao.selectById(areaId);
|
||||
|
||||
// 手动更新缓存,避免使用@CachePut注解可能导致的问题
|
||||
if (entity != null) {
|
||||
Cache cache = cacheManager.getCache(AdminCacheConst.Base.AREA_ENTITY);
|
||||
if (cache != null) {
|
||||
cache.put(areaId, entity);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动清除缓存
|
||||
* 使用写锁确保并发安全
|
||||
*/
|
||||
private void evictCache(Long areaId) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
public void clearCache(Long areaId) {
|
||||
if (areaId != null) {
|
||||
Cache cache = cacheManager.getCache(AdminCacheConst.Base.AREA_ENTITY);
|
||||
if (cache != null) {
|
||||
cache.evict(areaId);
|
||||
}
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ public interface AreaQueryService {
|
|||
* @param areaIdList 库区id集合
|
||||
* @return Map<Long, AreaEntity>
|
||||
*/
|
||||
Map<Long, AreaEntity> queryAreaList(List<Long> areaIdList);
|
||||
Map<Long, AreaEntity> queryByAreaIds(List<Long> areaIdList);
|
||||
|
||||
/**
|
||||
* 根据库区name集合查询库区信息
|
||||
|
|
@ -44,7 +44,15 @@ public interface AreaQueryService {
|
|||
* @param areaNameList 库区name集合
|
||||
* @return Map<Long, AreaEntity>
|
||||
*/
|
||||
Map<String, AreaEntity> queryAreaByNameList(List<String> areaNameList);
|
||||
List<AreaEntity> queryByAreaNames(List<String> areaNameList);
|
||||
|
||||
/**
|
||||
* 根据库区name集合查询库区信息
|
||||
*
|
||||
* @param areaNameList 库区name集合
|
||||
* @return Map<Long, AreaEntity>
|
||||
*/
|
||||
Map<String, AreaEntity> queryByAreaNamesToMap(List<String> areaNameList);
|
||||
|
||||
/**
|
||||
* 根据库区名称查询库区信息
|
||||
|
|
|
|||
|
|
@ -14,12 +14,13 @@ import net.lab1024.sa.admin.module.business.wms.base.area.service.AreaQueryServi
|
|||
import net.lab1024.sa.base.common.domain.PageResult;
|
||||
import net.lab1024.sa.base.common.util.SmartPageUtil;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.Objects;
|
||||
|
||||
@Service
|
||||
public class AreaQueryServiceImpl implements AreaQueryService {
|
||||
|
|
@ -58,7 +59,7 @@ public class AreaQueryServiceImpl implements AreaQueryService {
|
|||
if (CollectionUtils.isNotEmpty(areaSelect.getAreaNames())) {
|
||||
queryWrapper.in(AreaEntity::getAreaName, areaSelect.getAreaNames());
|
||||
}
|
||||
return areaDao.selectList(queryWrapper);
|
||||
return areaManager.list(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -67,11 +68,13 @@ public class AreaQueryServiceImpl implements AreaQueryService {
|
|||
* @param areaIdList 库区id集合
|
||||
* @return Map<Long, AreaEntity>
|
||||
*/
|
||||
public Map<Long, AreaEntity> queryAreaList(List<Long> areaIdList) {
|
||||
public Map<Long, AreaEntity> queryByAreaIds(List<Long> areaIdList) {
|
||||
if (CollectionUtils.isEmpty(areaIdList)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
areaIdList = areaIdList.stream().distinct().collect(Collectors.toList());
|
||||
//去重
|
||||
areaIdList = areaIdList.stream().filter(Objects::nonNull).distinct().toList();
|
||||
//封装map
|
||||
Map<Long, AreaEntity> areaMap = Maps.newHashMap();
|
||||
for (Long areaId : areaIdList) {
|
||||
AreaEntity area = areaManager.queryArea(areaId);
|
||||
|
|
@ -82,25 +85,42 @@ public class AreaQueryServiceImpl implements AreaQueryService {
|
|||
return areaMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据库区name集合查询库区信息
|
||||
*
|
||||
* @param areaNameList 库区name集合
|
||||
* @return List<AreaEntity>
|
||||
*/
|
||||
public List<AreaEntity> queryByAreaNames(List<String> areaNameList) {
|
||||
if (CollectionUtils.isEmpty(areaNameList)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
//去重
|
||||
areaNameList = areaNameList.stream().filter(Objects::nonNull).distinct().toList();
|
||||
//查询库区信息
|
||||
LambdaQueryWrapper<AreaEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.in(AreaEntity::getAreaName, areaNameList);
|
||||
return areaManager.list(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据库区name集合查询库区信息
|
||||
*
|
||||
* @param areaNameList 库区name集合
|
||||
* @return Map<Long, AreaEntity>
|
||||
*/
|
||||
public Map<String, AreaEntity> queryAreaByNameList(List<String> areaNameList) {
|
||||
public Map<String, AreaEntity> queryByAreaNamesToMap(List<String> areaNameList) {
|
||||
if (CollectionUtils.isEmpty(areaNameList)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
LambdaQueryWrapper<AreaEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.in(AreaEntity::getAreaName, areaNameList);
|
||||
|
||||
List<AreaEntity> areaList = areaDao.selectList(queryWrapper);
|
||||
if (CollectionUtils.isEmpty(areaList)) {
|
||||
return Collections.emptyMap();
|
||||
//查询库区信息
|
||||
List<AreaEntity> areaList = queryByAreaNames(areaNameList);
|
||||
//封装map
|
||||
Map<String, AreaEntity> areaMap = Maps.newHashMap();
|
||||
for (AreaEntity area : areaList) {
|
||||
areaMap.put(area.getAreaName(), area);
|
||||
}
|
||||
return areaList.stream()
|
||||
.collect(Collectors.toMap(AreaEntity::getAreaName, area -> area, (existing, replacement) -> existing));
|
||||
return areaMap;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -110,9 +130,12 @@ public class AreaQueryServiceImpl implements AreaQueryService {
|
|||
* @return AreaEntity
|
||||
*/
|
||||
public AreaEntity queryByAreaName(String areaName) {
|
||||
if (StringUtils.isBlank(areaName)) {
|
||||
return null;
|
||||
}
|
||||
LambdaQueryWrapper<AreaEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(AreaEntity::getAreaName, areaName);
|
||||
return areaDao.selectOne(queryWrapper);
|
||||
return areaManager.getOne(queryWrapper);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,8 +46,7 @@ public class AreaServiceImpl implements AreaService {
|
|||
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
|
||||
}
|
||||
AreaEntity areaEntity = SmartBeanUtil.copy(addForm, AreaEntity.class);
|
||||
//新增并新增缓存
|
||||
areaManager.insert(areaEntity);
|
||||
areaManager.save(areaEntity);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
|
|
@ -93,7 +92,6 @@ public class AreaServiceImpl implements AreaService {
|
|||
}
|
||||
}
|
||||
|
||||
//删除库区
|
||||
if (CollectionUtils.isNotEmpty(idsToDelete)) {
|
||||
//删除并删除缓存
|
||||
areaManager.batchDelete(idsToDelete);
|
||||
|
|
|
|||
|
|
@ -7,18 +7,16 @@ import net.lab1024.sa.admin.module.business.wms.base.customer.domain.entity.Cust
|
|||
import net.lab1024.sa.admin.module.business.wms.base.customer.dao.CustomerDao;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import net.lab1024.sa.admin.util.TransactionCommitUtil;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 客户管理 Manager
|
||||
|
|
@ -29,6 +27,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
@CacheConfig(cacheNames = AdminCacheConst.Base.CUSTOMER_ENTITY)
|
||||
public class CustomerManager extends ServiceImpl<CustomerDao, CustomerEntity> {
|
||||
|
||||
@Resource
|
||||
|
|
@ -37,118 +36,61 @@ public class CustomerManager extends ServiceImpl<CustomerDao, CustomerEntity> {
|
|||
@Resource
|
||||
private CacheManager cacheManager;
|
||||
|
||||
// 使用读写锁保证高并发下的缓存操作安全
|
||||
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
|
||||
private final Lock readLock = rwLock.readLock();
|
||||
private final Lock writeLock = rwLock.writeLock();
|
||||
|
||||
/**
|
||||
* 查询客户(带缓存)
|
||||
* 使用Spring Cache自动缓存查询结果
|
||||
* 使用Spring Cache进行缓存管理
|
||||
*/
|
||||
@Cacheable(value = AdminCacheConst.Base.CUSTOMER_ENTITY, key = "#customerId", unless = "#result == null")
|
||||
@Cacheable(key = "#customerId", unless = "#result == null")
|
||||
public CustomerEntity queryCustomer(Long customerId) {
|
||||
try {
|
||||
readLock.lock();
|
||||
return customerDao.selectById(customerId);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
return customerDao.selectById(customerId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建客户(带缓存)
|
||||
* 事务提交后执行缓存刷新,保证数据一致性
|
||||
* 更新客户(清除缓存)
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public CustomerEntity insert(CustomerEntity entity) {
|
||||
super.save(entity);
|
||||
// 在事务提交后刷新缓存,确保数据库操作成功后再更新缓存
|
||||
executeAfterCommit("刷新客户缓存", () -> refreshCache(entity.getCustomerId()));
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新客户(带缓存)
|
||||
* 事务提交后执行缓存刷新,保证数据一致性
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public CustomerEntity update(CustomerEntity entity) {
|
||||
@CacheEvict(key = "#entity.customerId")
|
||||
public void update(CustomerEntity entity) {
|
||||
super.updateById(entity);
|
||||
// 在事务提交后刷新缓存,确保数据库操作成功后再更新缓存
|
||||
executeAfterCommit("刷新客户缓存", () -> refreshCache(entity.getCustomerId()));
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除客户(清理缓存)
|
||||
* 事务提交后清除缓存
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@CacheEvict(key = "#customerId")
|
||||
public void deleteById(Long customerId) {
|
||||
super.removeById(customerId);
|
||||
// 在事务提交后清除缓存,确保数据库操作成功后再更新缓存
|
||||
executeAfterCommit("清除客户缓存", () -> evictCache(customerId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除客户(清理缓存)
|
||||
* 事务提交后清除缓存
|
||||
* 批量更新客户(清理相关缓存)
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchUpdate(List<CustomerEntity> entities) {
|
||||
super.updateBatchById(entities);
|
||||
List<Long> customerIds = entities.stream().map(CustomerEntity::getCustomerId).filter(Objects::nonNull).distinct().toList();
|
||||
customerIds.forEach(this::clearCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除客户(清理相关缓存)
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchDelete(List<Long> customerIds) {
|
||||
super.removeByIds(customerIds);
|
||||
// 在事务提交后批量清除缓存
|
||||
executeAfterCommit("批量清除客户缓存", () -> customerIds.forEach(this::evictCache));
|
||||
customerIds.forEach(this::clearCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用方法:事务提交后执行操作
|
||||
*
|
||||
* @param operationDesc 操作描述(用于日志)
|
||||
* @param operation 要执行的操作
|
||||
* 手工清理缓存
|
||||
*/
|
||||
private void executeAfterCommit(String operationDesc, Runnable operation) {
|
||||
TransactionCommitUtil.executeAfterCommit(operationDesc, operation);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新单个缓存
|
||||
* 使用写锁确保并发安全
|
||||
*/
|
||||
public void refreshCache(Long customerId) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
// 先清除可能存在的旧缓存
|
||||
evictCache(customerId);
|
||||
// 重新查询并缓存最新数据
|
||||
CustomerEntity entity = customerDao.selectById(customerId);
|
||||
|
||||
// 手动更新缓存,避免使用@CachePut注解可能导致的问题
|
||||
if (entity != null) {
|
||||
Cache cache = cacheManager.getCache(AdminCacheConst.Base.CUSTOMER_ENTITY);
|
||||
if (cache != null) {
|
||||
cache.put(customerId, entity);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动清除缓存
|
||||
* 使用写锁确保并发安全
|
||||
*/
|
||||
private void evictCache(Long customerId) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
public void clearCache(Long customerId) {
|
||||
if (customerId != null) {
|
||||
Cache cache = cacheManager.getCache(AdminCacheConst.Base.CUSTOMER_ENTITY);
|
||||
if (cache != null) {
|
||||
cache.evict(customerId);
|
||||
}
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,38 +1,16 @@
|
|||
package net.lab1024.sa.admin.module.business.wms.base.customer.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.google.common.collect.Maps;
|
||||
import jakarta.annotation.Resource;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.area.domain.entity.AreaEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.area.domain.form.AreaSelect;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.dao.CustomerDao;
|
||||
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.domain.entity.CustomerEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.domain.form.CustomerQueryForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.domain.form.CustomerSelect;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.domain.vo.CustomerVO;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.manager.CustomerManager;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.dao.CustomerDao;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.domain.entity.CustomerEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.domain.form.CustomerSelect;
|
||||
import net.lab1024.sa.base.common.domain.PageResult;
|
||||
import net.lab1024.sa.base.common.util.SmartPageUtil;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class CustomerQueryService {
|
||||
|
||||
@Resource
|
||||
private CustomerDao customerDao;
|
||||
|
||||
@Resource
|
||||
private CustomerManager customerManager;
|
||||
public interface CustomerQueryService {
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
|
|
@ -40,25 +18,14 @@ public class CustomerQueryService {
|
|||
* @param queryForm 查询参数
|
||||
* @return PageResult<CustomerVO>
|
||||
*/
|
||||
public PageResult<CustomerVO> queryPage(CustomerQueryForm queryForm) {
|
||||
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
|
||||
List<CustomerVO> list = customerDao.queryPage(page, queryForm);
|
||||
return SmartPageUtil.convert2PageResult(page, list);
|
||||
}
|
||||
PageResult<CustomerVO> queryPage(CustomerQueryForm queryForm);
|
||||
|
||||
/**
|
||||
* 查询所有客户信息
|
||||
*
|
||||
* @return List<CustomerEntity>
|
||||
*/
|
||||
public List<CustomerEntity> queryCustomer(CustomerSelect customerSelect) {
|
||||
LambdaQueryWrapper<CustomerEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
//是否启用
|
||||
if (customerSelect.getDisabledFlag() != null) {
|
||||
queryWrapper.eq(CustomerEntity::getDisabledFlag, customerSelect.getDisabledFlag());
|
||||
}
|
||||
return customerDao.selectList(queryWrapper);
|
||||
}
|
||||
List<CustomerEntity> queryCustomer(CustomerSelect customerSelect);
|
||||
|
||||
/**
|
||||
* 根据客户id集合查询客户信息
|
||||
|
|
@ -66,29 +33,13 @@ public class CustomerQueryService {
|
|||
* @param customerIdList 客户id集合
|
||||
* @return Map<Long, CustomerEntity>
|
||||
*/
|
||||
public Map<Long, CustomerEntity> queryCustomerList(List<Long> customerIdList) {
|
||||
if (CollectionUtils.isEmpty(customerIdList)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
customerIdList = customerIdList.stream().distinct().collect(Collectors.toList());
|
||||
Map<Long, CustomerEntity> customerMap = Maps.newHashMap();
|
||||
for (Long customerId : customerIdList) {
|
||||
CustomerEntity customer = customerManager.queryCustomer(customerId);
|
||||
if (customer != null) {
|
||||
customerMap.put(customerId, customer);
|
||||
}
|
||||
}
|
||||
return customerMap;
|
||||
}
|
||||
Map<Long, CustomerEntity> queryByCustomerIdsToMap(List<Long> customerIdList);
|
||||
|
||||
/**
|
||||
* 根据客户名称查询客户信息
|
||||
*
|
||||
* @param customerName 客户名称
|
||||
* @return CustomerEntity
|
||||
*/
|
||||
public CustomerEntity queryByCustomerName(String customerName) {
|
||||
LambdaQueryWrapper<CustomerEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(CustomerEntity::getCustomerName, customerName);
|
||||
return customerDao.selectOne(queryWrapper);
|
||||
}
|
||||
CustomerEntity queryByCustomerName(String customerName);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,9 @@
|
|||
package net.lab1024.sa.admin.module.business.wms.base.customer.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.lab1024.sa.admin.module.business.wms.base.area.domain.entity.AreaEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.dao.CustomerDao;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.domain.entity.CustomerEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.domain.form.CustomerAddForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.domain.form.CustomerUpdateForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.manager.CustomerManager;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.dao.CustomerDao;
|
||||
import net.lab1024.sa.base.common.code.UserErrorCode;
|
||||
import net.lab1024.sa.base.common.util.SmartBeanUtil;
|
||||
import net.lab1024.sa.base.common.domain.ResponseDTO;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* 客户管理 Service
|
||||
|
|
@ -25,15 +12,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
* @since 2025-03-25 10:42:33
|
||||
* copyright 友仓
|
||||
*/
|
||||
|
||||
@Service
|
||||
public class CustomerService {
|
||||
|
||||
@Resource
|
||||
private CustomerManager customerManager;
|
||||
|
||||
@Resource
|
||||
private CustomerQueryService customerQueryService;
|
||||
public interface CustomerService {
|
||||
|
||||
/**
|
||||
* 添加
|
||||
|
|
@ -41,17 +20,7 @@ public class CustomerService {
|
|||
* @param addForm 添加参数
|
||||
* @return ResponseDTO<String>
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<String> add(CustomerAddForm addForm) {
|
||||
CustomerEntity existingCustomer = customerQueryService.queryByCustomerName(addForm.getCustomerName());
|
||||
if (existingCustomer != null) {
|
||||
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
|
||||
}
|
||||
CustomerEntity customerEntity = SmartBeanUtil.copy(addForm, CustomerEntity.class);
|
||||
//新增并新增缓存
|
||||
customerManager.insert(customerEntity);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
ResponseDTO<String> add(CustomerAddForm addForm);
|
||||
|
||||
/**
|
||||
* 更新
|
||||
|
|
@ -59,17 +28,7 @@ public class CustomerService {
|
|||
* @param updateForm 更新参数
|
||||
* @return ResponseDTO<String>
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<String> update(CustomerUpdateForm updateForm) {
|
||||
CustomerEntity existingCustomer = customerQueryService.queryByCustomerName(updateForm.getCustomerName());
|
||||
if (existingCustomer != null && !existingCustomer.getCustomerId().equals(updateForm.getCustomerId())) {
|
||||
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
|
||||
}
|
||||
CustomerEntity customerEntity = SmartBeanUtil.copy(updateForm, CustomerEntity.class);
|
||||
//更新并更新缓存
|
||||
customerManager.update(customerEntity);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
ResponseDTO<String> update(CustomerUpdateForm updateForm);
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
|
|
@ -77,15 +36,7 @@ public class CustomerService {
|
|||
* @param idList id集合
|
||||
* @return ResponseDTO<String>
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<String> batchDelete(List<Long> idList) {
|
||||
if (CollectionUtils.isEmpty(idList)) {
|
||||
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
|
||||
}
|
||||
//批量删除并删除缓存
|
||||
customerManager.batchDelete(idList);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
ResponseDTO<String> batchDelete(List<Long> idList);
|
||||
|
||||
/**
|
||||
* 单个删除
|
||||
|
|
@ -93,13 +44,5 @@ public class CustomerService {
|
|||
* @param customerId id
|
||||
* @return ResponseDTO<String>
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<String> delete(Long customerId) {
|
||||
if (null == customerId) {
|
||||
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
|
||||
}
|
||||
//更新缓存
|
||||
customerManager.deleteById(customerId);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
ResponseDTO<String> delete(Long customerId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,98 @@
|
|||
package net.lab1024.sa.admin.module.business.wms.base.customer.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.google.common.collect.Maps;
|
||||
import jakarta.annotation.Resource;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.dao.CustomerDao;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.domain.entity.CustomerEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.domain.form.CustomerQueryForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.domain.form.CustomerSelect;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.domain.vo.CustomerVO;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.manager.CustomerManager;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.service.CustomerQueryService;
|
||||
import net.lab1024.sa.base.common.domain.PageResult;
|
||||
import net.lab1024.sa.base.common.util.SmartPageUtil;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
|
||||
public class CustomerQueryServiceImpl implements CustomerQueryService {
|
||||
|
||||
@Resource
|
||||
private CustomerDao customerDao;
|
||||
|
||||
@Resource
|
||||
private CustomerManager customerManager;
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
*
|
||||
* @param queryForm 查询参数
|
||||
* @return PageResult<CustomerVO>
|
||||
*/
|
||||
public PageResult<CustomerVO> queryPage(CustomerQueryForm queryForm) {
|
||||
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
|
||||
List<CustomerVO> list = customerDao.queryPage(page, queryForm);
|
||||
return SmartPageUtil.convert2PageResult(page, list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有客户信息
|
||||
*
|
||||
* @return List<CustomerEntity>
|
||||
*/
|
||||
public List<CustomerEntity> queryCustomer(CustomerSelect customerSelect) {
|
||||
LambdaQueryWrapper<CustomerEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
//是否启用
|
||||
if (customerSelect.getDisabledFlag() != null) {
|
||||
queryWrapper.eq(CustomerEntity::getDisabledFlag, customerSelect.getDisabledFlag());
|
||||
}
|
||||
return customerManager.list(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据客户id集合查询客户信息
|
||||
*
|
||||
* @param customerIdList 客户id集合
|
||||
* @return Map<Long, CustomerEntity>
|
||||
*/
|
||||
public Map<Long, CustomerEntity> queryByCustomerIdsToMap(List<Long> customerIdList) {
|
||||
if (CollectionUtils.isEmpty(customerIdList)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
//去重
|
||||
customerIdList = customerIdList.stream().distinct().collect(Collectors.toList());
|
||||
//封装map
|
||||
Map<Long, CustomerEntity> customerMap = Maps.newHashMap();
|
||||
for (Long customerId : customerIdList) {
|
||||
CustomerEntity customer = customerManager.queryCustomer(customerId);
|
||||
if (customer != null) {
|
||||
customerMap.put(customerId, customer);
|
||||
}
|
||||
}
|
||||
return customerMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据客户名称查询客户信息
|
||||
*
|
||||
* @param customerName 客户名称
|
||||
* @return CustomerEntity
|
||||
*/
|
||||
public CustomerEntity queryByCustomerName(String customerName) {
|
||||
if (StringUtils.isBlank(customerName)) {
|
||||
return null;
|
||||
}
|
||||
LambdaQueryWrapper<CustomerEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(CustomerEntity::getCustomerName, customerName);
|
||||
return customerManager.getOne(queryWrapper);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
package net.lab1024.sa.admin.module.business.wms.base.customer.service.impl;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.domain.entity.CustomerEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.domain.form.CustomerAddForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.domain.form.CustomerUpdateForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.manager.CustomerManager;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.service.CustomerQueryService;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.service.CustomerService;
|
||||
import net.lab1024.sa.base.common.code.UserErrorCode;
|
||||
import net.lab1024.sa.base.common.domain.ResponseDTO;
|
||||
import net.lab1024.sa.base.common.util.SmartBeanUtil;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
|
||||
public class CustomerServiceImpl implements CustomerService {
|
||||
|
||||
@Resource
|
||||
private CustomerManager customerManager;
|
||||
|
||||
@Resource
|
||||
private CustomerQueryService customerQueryService;
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param addForm 添加参数
|
||||
* @return ResponseDTO<String>
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<String> add(CustomerAddForm addForm) {
|
||||
CustomerEntity existingCustomer = customerQueryService.queryByCustomerName(addForm.getCustomerName());
|
||||
if (existingCustomer != null) {
|
||||
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
|
||||
}
|
||||
CustomerEntity customerEntity = SmartBeanUtil.copy(addForm, CustomerEntity.class);
|
||||
customerManager.save(customerEntity);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新
|
||||
*
|
||||
* @param updateForm 更新参数
|
||||
* @return ResponseDTO<String>
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<String> update(CustomerUpdateForm updateForm) {
|
||||
CustomerEntity existingCustomer = customerQueryService.queryByCustomerName(updateForm.getCustomerName());
|
||||
if (existingCustomer != null && !existingCustomer.getCustomerId().equals(updateForm.getCustomerId())) {
|
||||
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
|
||||
}
|
||||
CustomerEntity customerEntity = SmartBeanUtil.copy(updateForm, CustomerEntity.class);
|
||||
//更新并更新缓存
|
||||
customerManager.update(customerEntity);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param idList id集合
|
||||
* @return ResponseDTO<String>
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<String> batchDelete(List<Long> idList) {
|
||||
if (CollectionUtils.isEmpty(idList)) {
|
||||
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
|
||||
}
|
||||
//批量删除并删除缓存
|
||||
customerManager.batchDelete(idList);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 单个删除
|
||||
*
|
||||
* @param customerId id
|
||||
* @return ResponseDTO<String>
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<String> delete(Long customerId) {
|
||||
if (null == customerId) {
|
||||
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
|
||||
}
|
||||
//更新缓存
|
||||
customerManager.deleteById(customerId);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
}
|
||||
|
|
@ -111,7 +111,7 @@ public class ItemController {
|
|||
@SaCheckPermission("item:exportItems")
|
||||
@OperateLog
|
||||
public void exportItems(HttpServletResponse response) throws IOException {
|
||||
List<ItemsExcelVO> itemsList = itemQueryService.getItemsExcelVOList();
|
||||
List<ItemsExcelVO> itemsList = itemQueryService.queryItemsExcelVO();
|
||||
SmartExcelUtil.exportExcel(response, "物料信息.xlsx", "物料", ItemsExcelVO.class, itemsList);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,25 +5,23 @@ import lombok.extern.slf4j.Slf4j;
|
|||
import net.lab1024.sa.admin.constant.AdminCacheConst;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.item.dao.ItemDao;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.item.domain.entity.ItemEntity;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import net.lab1024.sa.admin.util.TransactionCommitUtil;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.vo.StockVO;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.cache.CacheManager;
|
||||
|
||||
/**
|
||||
* 物料信息 Manager
|
||||
* 物料信息
|
||||
*
|
||||
* @Author 霍锦
|
||||
* @Date 2024-11-25 17:08:18
|
||||
|
|
@ -31,6 +29,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
@CacheConfig(cacheNames = AdminCacheConst.Base.ITEM_ENTITY)
|
||||
public class ItemManager extends ServiceImpl<ItemDao, ItemEntity> {
|
||||
|
||||
@Resource
|
||||
|
|
@ -39,153 +38,61 @@ public class ItemManager extends ServiceImpl<ItemDao, ItemEntity> {
|
|||
@Resource
|
||||
private CacheManager cacheManager;
|
||||
|
||||
// 使用读写锁保证高并发下的缓存操作安全
|
||||
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
|
||||
private final Lock readLock = rwLock.readLock();
|
||||
private final Lock writeLock = rwLock.writeLock();
|
||||
|
||||
/**
|
||||
* 查询物料(带缓存)
|
||||
* 使用Spring Cache自动缓存查询结果
|
||||
* 使用Spring Cache进行缓存管理
|
||||
*/
|
||||
@Cacheable(value = AdminCacheConst.Base.ITEM_ENTITY, key = "#itemId", unless = "#result == null")
|
||||
@Cacheable(key = "#itemId", unless = "#result == null")
|
||||
public ItemEntity queryItem(Long itemId) {
|
||||
try {
|
||||
readLock.lock();
|
||||
return itemDao.selectById(itemId);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
return itemDao.selectById(itemId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建物料(带缓存)
|
||||
* 事务提交后执行缓存刷新,保证数据一致性
|
||||
* 更新物料(清除缓存)
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ItemEntity insert(ItemEntity entity) {
|
||||
super.save(entity);
|
||||
// 在事务提交后刷新缓存,确保数据库操作成功后再更新缓存
|
||||
executeAfterCommit("刷新物料缓存", () -> refreshCache(entity.getItemId()));
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新物料(带缓存)
|
||||
* 事务提交后执行缓存刷新,保证数据一致性
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ItemEntity update(ItemEntity entity) {
|
||||
@CacheEvict(key = "#entity.itemId")
|
||||
public void update(ItemEntity entity) {
|
||||
super.updateById(entity);
|
||||
// 在事务提交后刷新缓存,确保数据库操作成功后再更新缓存
|
||||
executeAfterCommit("刷新物料缓存", () -> refreshCache(entity.getItemId()));
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除物料(清理缓存)
|
||||
* 事务提交后清除缓存
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@CacheEvict(key = "#itemId")
|
||||
public void deleteById(Long itemId) {
|
||||
super.removeById(itemId);
|
||||
// 在事务提交后清除缓存,确保数据库操作成功后再更新缓存
|
||||
executeAfterCommit("清除物料缓存", () -> evictCache(itemId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量创建物料(带缓存)
|
||||
* 事务提交后执行缓存刷新,保证数据一致性
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchInsert(List<ItemEntity> entities) {
|
||||
super.saveBatch(entities);
|
||||
// 在事务提交后批量刷新缓存
|
||||
executeAfterCommit("批量刷新物料缓存", () -> batchRefreshCache(entities));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新物料(带缓存)
|
||||
* 事务提交后执行缓存刷新,保证数据一致性
|
||||
* 批量更新物料(清理相关缓存)
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchUpdate(List<ItemEntity> entities) {
|
||||
super.updateBatchById(entities);
|
||||
// 在事务提交后批量刷新缓存
|
||||
executeAfterCommit("批量刷新物料缓存", () -> batchRefreshCache(entities));
|
||||
List<Long> itemIds = entities.stream().map(ItemEntity::getItemId).filter(Objects::nonNull).distinct().toList();
|
||||
itemIds.forEach(this::clearCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除物料(清理缓存)
|
||||
* 事务提交后清除缓存
|
||||
* 批量删除物料(清理相关缓存)
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchDelete(List<Long> itemIds) {
|
||||
super.removeByIds(itemIds);
|
||||
// 在事务提交后批量清除缓存
|
||||
executeAfterCommit("批量清除物料缓存", () -> itemIds.forEach(this::evictCache));
|
||||
itemIds.forEach(this::clearCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用方法:事务提交后执行操作
|
||||
*
|
||||
* @param operationDesc 操作描述(用于日志)
|
||||
* @param operation 要执行的操作
|
||||
* 手工清理缓存
|
||||
*/
|
||||
private void executeAfterCommit(String operationDesc, Runnable operation) {
|
||||
TransactionCommitUtil.executeAfterCommit(operationDesc, operation);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新单个缓存
|
||||
* 使用写锁确保并发安全
|
||||
*/
|
||||
public void refreshCache(Long itemId) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
// 先清除可能存在的旧缓存
|
||||
evictCache(itemId);
|
||||
// 重新查询并缓存最新数据
|
||||
ItemEntity entity = itemDao.selectById(itemId);
|
||||
|
||||
// 手动更新缓存,避免使用@CachePut注解可能导致的问题
|
||||
if (entity != null) {
|
||||
Cache cache = cacheManager.getCache(AdminCacheConst.Base.ITEM_ENTITY);
|
||||
if (cache != null) {
|
||||
cache.put(itemId, entity);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量刷新缓存
|
||||
* 先收集所有ID,再逐一刷新,减少锁争用
|
||||
*/
|
||||
private void batchRefreshCache(Collection<ItemEntity> entities) {
|
||||
List<Long> itemIds = entities.stream()
|
||||
.map(ItemEntity::getItemId)
|
||||
.distinct()
|
||||
.toList();
|
||||
itemIds.forEach(this::refreshCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动清除缓存
|
||||
* 使用写锁确保并发安全
|
||||
*/
|
||||
private void evictCache(Long itemId) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
public void clearCache(Long itemId) {
|
||||
if (itemId != null) {
|
||||
Cache cache = cacheManager.getCache(AdminCacheConst.Base.ITEM_ENTITY);
|
||||
if (cache != null) {
|
||||
cache.evict(itemId);
|
||||
}
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,28 +1,14 @@
|
|||
package net.lab1024.sa.admin.module.business.wms.base.item.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.google.common.collect.Maps;
|
||||
import jakarta.annotation.Resource;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.item.dao.ItemDao;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.item.domain.entity.ItemEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.item.domain.form.ItemQueryForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.item.domain.form.ItemSelect;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.item.domain.vo.ItemVO;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.item.domain.vo.ItemsExcelVO;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.item.manager.ItemManager;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.item.dao.ItemDao;
|
||||
import net.lab1024.sa.base.common.domain.PageResult;
|
||||
import net.lab1024.sa.base.common.util.SmartPageUtil;
|
||||
import net.lab1024.sa.base.module.support.dict.constant.DictConst;
|
||||
import net.lab1024.sa.base.module.support.dict.service.DictService;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
public interface ItemQueryService {
|
||||
|
|
@ -49,7 +35,7 @@ public interface ItemQueryService {
|
|||
* @param itemIdList 客户id集合
|
||||
* @return Map<Long, AreaEntity>
|
||||
*/
|
||||
Map<Long, ItemEntity> queryItemList(List<Long> itemIdList);
|
||||
Map<Long, ItemEntity> queryByItemIdsToMap(List<Long> itemIdList);
|
||||
|
||||
/**
|
||||
* 根据物料编码查询
|
||||
|
|
@ -73,12 +59,12 @@ public interface ItemQueryService {
|
|||
* @param itemCodes 物料集合
|
||||
* @return Map<String, ItemEntity>
|
||||
*/
|
||||
Map<String, ItemEntity> queryItemListToMap(List<String> itemCodes);
|
||||
Map<String, ItemEntity> queryByItemCodesToMap(List<String> itemCodes);
|
||||
|
||||
/**
|
||||
* 物料导出
|
||||
*
|
||||
* @return List<LocationsExcelVO>
|
||||
* @return List<ItemsExcelVO>
|
||||
*/
|
||||
List<ItemsExcelVO> getItemsExcelVOList();
|
||||
List<ItemsExcelVO> queryItemsExcelVO();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,11 +17,13 @@ import net.lab1024.sa.base.common.util.SmartPageUtil;
|
|||
import net.lab1024.sa.base.module.support.dict.constant.DictConst;
|
||||
import net.lab1024.sa.base.module.support.dict.service.DictService;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
|
|
@ -60,7 +62,7 @@ public class ItemQueryServiceImpl implements ItemQueryService {
|
|||
if (itemSelect.getDisabledFlag() != null) {
|
||||
queryWrapper.eq(ItemEntity::getDisabledFlag, itemSelect.getDisabledFlag());
|
||||
}
|
||||
return itemDao.selectList(queryWrapper);
|
||||
return itemManager.list(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -69,11 +71,11 @@ public class ItemQueryServiceImpl implements ItemQueryService {
|
|||
* @param itemIdList 客户id集合
|
||||
* @return Map<Long, AreaEntity>
|
||||
*/
|
||||
public Map<Long, ItemEntity> queryItemList(List<Long> itemIdList) {
|
||||
public Map<Long, ItemEntity> queryByItemIdsToMap(List<Long> itemIdList) {
|
||||
if (CollectionUtils.isEmpty(itemIdList)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
itemIdList = itemIdList.stream().mapToLong(Long::longValue).distinct().boxed().toList();
|
||||
itemIdList = itemIdList.stream().filter(Objects::nonNull).distinct().toList();
|
||||
Map<Long, ItemEntity> itemMap = Maps.newHashMap();
|
||||
for (Long itemId : itemIdList) {
|
||||
ItemEntity item = itemManager.queryItem(itemId);
|
||||
|
|
@ -91,9 +93,12 @@ public class ItemQueryServiceImpl implements ItemQueryService {
|
|||
* @return ItemEntity
|
||||
*/
|
||||
public ItemEntity queryByItemCode(String itemCode) {
|
||||
if (StringUtils.isBlank(itemCode)) {
|
||||
return null;
|
||||
}
|
||||
LambdaQueryWrapper<ItemEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(ItemEntity::getItemCode, itemCode);
|
||||
return itemDao.selectOne(queryWrapper);
|
||||
return itemManager.getOne(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -103,9 +108,15 @@ public class ItemQueryServiceImpl implements ItemQueryService {
|
|||
* @return List<ItemEntity>
|
||||
*/
|
||||
public List<ItemEntity> queryByItemCodes(List<String> itemCodes) {
|
||||
if (CollectionUtils.isEmpty(itemCodes)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
//去重
|
||||
itemCodes = itemCodes.stream().filter(Objects::nonNull).distinct().toList();
|
||||
//查询物料
|
||||
LambdaQueryWrapper<ItemEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.in(ItemEntity::getItemCode, itemCodes);
|
||||
return itemDao.selectList(queryWrapper);
|
||||
return itemManager.list(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -114,14 +125,18 @@ public class ItemQueryServiceImpl implements ItemQueryService {
|
|||
* @param itemCodes 物料集合
|
||||
* @return Map<String, ItemEntity>
|
||||
*/
|
||||
public Map<String, ItemEntity> queryItemListToMap(List<String> itemCodes) {
|
||||
public Map<String, ItemEntity> queryByItemCodesToMap(List<String> itemCodes) {
|
||||
if (CollectionUtils.isEmpty(itemCodes)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
List<ItemEntity> items = queryByItemCodes(itemCodes);
|
||||
return items.stream()
|
||||
.collect(Collectors.toMap(ItemEntity::getItemCode, item -> item, (existing, replacement) -> existing));
|
||||
|
||||
//查询物料
|
||||
List<ItemEntity> itemList = queryByItemCodes(itemCodes);
|
||||
//封装成map
|
||||
Map<String, ItemEntity> itemMap = Maps.newHashMap();
|
||||
for (ItemEntity item : itemList) {
|
||||
itemMap.put(item.getItemCode(), item);
|
||||
}
|
||||
return itemMap;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -129,8 +144,8 @@ public class ItemQueryServiceImpl implements ItemQueryService {
|
|||
*
|
||||
* @return List<LocationsExcelVO>
|
||||
*/
|
||||
public List<ItemsExcelVO> getItemsExcelVOList() {
|
||||
List<ItemEntity> itemsList = itemDao.selectList(null);
|
||||
public List<ItemsExcelVO> queryItemsExcelVO() {
|
||||
List<ItemEntity> itemsList = itemManager.list();
|
||||
return itemsList.stream()
|
||||
.map(item ->
|
||||
ItemsExcelVO.builder()
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import net.lab1024.sa.admin.module.business.wms.base.item.service.ItemQueryServi
|
|||
import net.lab1024.sa.admin.module.business.wms.base.item.service.ItemService;
|
||||
import net.lab1024.sa.admin.util.JoinerResult;
|
||||
import net.lab1024.sa.admin.util.ResponseDTOUtil;
|
||||
import net.lab1024.sa.admin.util.ValidateDictKey;
|
||||
import net.lab1024.sa.admin.util.ValidateDictKeyUtil;
|
||||
import net.lab1024.sa.base.common.code.UserErrorCode;
|
||||
import net.lab1024.sa.base.common.domain.ResponseDTO;
|
||||
import net.lab1024.sa.base.common.exception.BusinessException;
|
||||
|
|
@ -40,7 +40,7 @@ public class ItemServiceImpl implements ItemService {
|
|||
private ItemQueryService itemQueryService;
|
||||
|
||||
@Resource
|
||||
private ValidateDictKey validateDictKey;
|
||||
private ValidateDictKeyUtil validateDictKeyUtil;
|
||||
|
||||
/**
|
||||
* 添加
|
||||
|
|
@ -55,8 +55,7 @@ public class ItemServiceImpl implements ItemService {
|
|||
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
|
||||
}
|
||||
ItemEntity itemEntity = SmartBeanUtil.copy(addForm, ItemEntity.class);
|
||||
//新增并新增缓存
|
||||
itemManager.insert(itemEntity);
|
||||
itemManager.save(itemEntity);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
|
|
@ -130,23 +129,23 @@ public class ItemServiceImpl implements ItemService {
|
|||
return ResponseDTO.userErrorParam("数据为空");
|
||||
}
|
||||
|
||||
//获取所有去重后的物料类型
|
||||
List<String> itemTypes = dataList.stream().map(ItemsImportForm::getItemType).distinct().collect(Collectors.toList());
|
||||
//获取所物料类型
|
||||
List<String> itemTypes = dataList.stream().map(ItemsImportForm::getItemType).toList();
|
||||
|
||||
//验证物料类型
|
||||
Map<String, String> itemTypeMap = validateDictKey.validateDictCodes(itemTypes, DictConst.ITEM_TYPE.getValue());
|
||||
Map<String, String> itemTypeMap = validateDictKeyUtil.validateDictCodes(itemTypes, DictConst.ITEM_TYPE.getValue());
|
||||
|
||||
//获取所有去重后的包装单位
|
||||
List<String> units = dataList.stream().map(ItemsImportForm::getUnit).distinct().collect(Collectors.toList());
|
||||
//获取所有包装单位
|
||||
List<String> units = dataList.stream().map(ItemsImportForm::getUnit).toList();
|
||||
|
||||
//验证包装单位
|
||||
Map<String, String> unitMap = validateDictKey.validateDictCodes(units, DictConst.ITEM_UNIT.getValue());
|
||||
Map<String, String> unitMap = validateDictKeyUtil.validateDictCodes(units, DictConst.ITEM_UNIT.getValue());
|
||||
|
||||
//获取所有去重后的容器编码
|
||||
List<String> itemCodes = dataList.stream().map(ItemsImportForm::getItemCode).distinct().collect(Collectors.toList());
|
||||
//获取所有物料
|
||||
List<String> itemCodes = dataList.stream().map(ItemsImportForm::getItemCode).toList();
|
||||
|
||||
//查询数据库存在的物料
|
||||
Map<String, ItemEntity> exitItemMap = itemQueryService.queryItemListToMap(itemCodes);
|
||||
Map<String, ItemEntity> exitItemMap = itemQueryService.queryByItemCodesToMap(itemCodes);
|
||||
|
||||
List<ItemEntity> insertToItem = new ArrayList<>();
|
||||
List<ItemEntity> updateToItem = new ArrayList<>();
|
||||
|
|
@ -169,7 +168,7 @@ public class ItemServiceImpl implements ItemService {
|
|||
}
|
||||
}
|
||||
JoinerResult resultMsg = JoinerResult.createJoiner();
|
||||
return ResponseDTOUtil.buildResponseDTO(insertToItem,updateToItem,itemManager::batchInsert, itemManager::batchUpdate,resultMsg);
|
||||
return ResponseDTOUtil.buildResponseDTO(insertToItem, updateToItem, itemManager::saveBatch, itemManager::batchUpdate, resultMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ public class LocationController {
|
|||
@SaCheckPermission("location:exportLocations")
|
||||
@OperateLog
|
||||
public void exportLocations(HttpServletResponse response) throws IOException {
|
||||
List<LocationsExcelVO> locationsList = locationQueryService.getLocationsExcelVOList();
|
||||
List<LocationsExcelVO> locationsList = locationQueryService.queryLocationsExcelVO();
|
||||
SmartExcelUtil.exportExcel(response, "库位信息.xlsx", "库位", LocationsExcelVO.class, locationsList);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,19 +7,16 @@ import net.lab1024.sa.admin.module.business.wms.base.location.dao.LocationDao;
|
|||
import net.lab1024.sa.admin.module.business.wms.base.location.domain.entity.LocationEntity;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import net.lab1024.sa.admin.util.TransactionCommitUtil;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 库位信息 Manager
|
||||
|
|
@ -30,6 +27,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
@CacheConfig(cacheNames = AdminCacheConst.Base.LOCATION_ENTITY)
|
||||
public class LocationManager extends ServiceImpl<LocationDao, LocationEntity> {
|
||||
|
||||
@Resource
|
||||
|
|
@ -38,153 +36,61 @@ public class LocationManager extends ServiceImpl<LocationDao, LocationEntity> {
|
|||
@Resource
|
||||
private CacheManager cacheManager;
|
||||
|
||||
// 使用读写锁保证高并发下的缓存操作安全
|
||||
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
|
||||
private final Lock readLock = rwLock.readLock();
|
||||
private final Lock writeLock = rwLock.writeLock();
|
||||
|
||||
/**
|
||||
* 查询库位(带缓存)
|
||||
* 使用Spring Cache自动缓存查询结果
|
||||
* 使用Spring Cache进行缓存管理
|
||||
*/
|
||||
@Cacheable(value = AdminCacheConst.Base.LOCATION_ENTITY, key = "#locationId", unless = "#result == null")
|
||||
@Cacheable(key = "#locationId", unless = "#result == null")
|
||||
public LocationEntity queryLocation(Long locationId) {
|
||||
try {
|
||||
readLock.lock();
|
||||
return locationDao.selectById(locationId);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
return locationDao.selectById(locationId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建库位(带缓存)
|
||||
* 事务提交后执行缓存刷新,保证数据一致性
|
||||
* 更新库位(清除缓存)
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public LocationEntity insert(LocationEntity entity) {
|
||||
super.save(entity);
|
||||
// 在事务提交后刷新缓存,确保数据库操作成功后再更新缓存
|
||||
executeAfterCommit("刷新库位缓存", () -> refreshCache(entity.getLocationId()));
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新库位(带缓存)
|
||||
* 事务提交后执行缓存刷新,保证数据一致性
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public LocationEntity update(LocationEntity entity) {
|
||||
@CacheEvict(key = "#entity.locationId")
|
||||
public void update(LocationEntity entity) {
|
||||
super.updateById(entity);
|
||||
// 在事务提交后刷新缓存,确保数据库操作成功后再更新缓存
|
||||
executeAfterCommit("刷新库位缓存", () -> refreshCache(entity.getLocationId()));
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除库位(清理缓存)
|
||||
* 事务提交后清除缓存
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@CacheEvict(key = "#locationId")
|
||||
public void deleteById(Long locationId) {
|
||||
super.removeById(locationId);
|
||||
// 在事务提交后清除缓存,确保数据库操作成功后再更新缓存
|
||||
executeAfterCommit("清除库位缓存", () -> evictCache(locationId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量创建库位(带缓存)
|
||||
* 事务提交后执行缓存刷新,保证数据一致性
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchInsert(List<LocationEntity> entities) {
|
||||
super.saveBatch(entities);
|
||||
// 在事务提交后批量刷新缓存
|
||||
executeAfterCommit("批量刷新库位缓存", () -> batchRefreshCache(entities));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新库位(带缓存)
|
||||
* 事务提交后执行缓存刷新,保证数据一致性
|
||||
* 批量更新库位(清理相关缓存)
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchUpdate(List<LocationEntity> entities) {
|
||||
super.updateBatchById(entities);
|
||||
// 在事务提交后批量刷新缓存
|
||||
executeAfterCommit("批量刷新库位缓存", () -> batchRefreshCache(entities));
|
||||
List<Long> locationIds = entities.stream().map(LocationEntity::getLocationId).filter(Objects::nonNull).distinct().toList();
|
||||
locationIds.forEach(this::clearCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除库位(清理缓存)
|
||||
* 事务提交后清除缓存
|
||||
* 批量删除库位(清理相关缓存)
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchDelete(List<Long> locationIds) {
|
||||
super.removeByIds(locationIds);
|
||||
// 在事务提交后批量清除缓存
|
||||
executeAfterCommit("批量清除库位缓存", () -> locationIds.forEach(this::evictCache));
|
||||
locationIds.forEach(this::clearCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用方法:事务提交后执行操作
|
||||
*
|
||||
* @param operationDesc 操作描述(用于日志)
|
||||
* @param operation 要执行的操作
|
||||
* 手工清理缓存
|
||||
*/
|
||||
private void executeAfterCommit(String operationDesc, Runnable operation) {
|
||||
TransactionCommitUtil.executeAfterCommit(operationDesc, operation);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新单个缓存
|
||||
* 使用写锁确保并发安全
|
||||
*/
|
||||
public void refreshCache(Long locationId) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
// 先清除可能存在的旧缓存
|
||||
evictCache(locationId);
|
||||
// 重新查询并缓存最新数据
|
||||
LocationEntity entity = locationDao.selectById(locationId);
|
||||
|
||||
// 手动更新缓存,避免使用@CachePut注解可能导致的问题
|
||||
if (entity != null) {
|
||||
Cache cache = cacheManager.getCache(AdminCacheConst.Base.LOCATION_ENTITY);
|
||||
if (cache != null) {
|
||||
cache.put(locationId, entity);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量刷新缓存
|
||||
* 先收集所有ID,再逐一刷新,减少锁争用
|
||||
*/
|
||||
private void batchRefreshCache(Collection<LocationEntity> entities) {
|
||||
List<Long> locationIds = entities.stream()
|
||||
.map(LocationEntity::getLocationId)
|
||||
.distinct()
|
||||
.toList();
|
||||
|
||||
locationIds.forEach(this::refreshCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动清除缓存
|
||||
* 使用写锁确保并发安全
|
||||
*/
|
||||
private void evictCache(Long locationId) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
public void clearCache(Long locationId) {
|
||||
if (locationId != null) {
|
||||
Cache cache = cacheManager.getCache(AdminCacheConst.Base.LOCATION_ENTITY);
|
||||
if (cache != null) {
|
||||
cache.evict(locationId);
|
||||
}
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public interface LocationQueryService {
|
|||
* @param locationIdList 库位ID集合
|
||||
* @return Map<Long, LocationEntity>
|
||||
*/
|
||||
Map<Long, LocationEntity> queryLocationList(List<Long> locationIdList);
|
||||
Map<Long, LocationEntity> queryByLocationIdsToMap(List<Long> locationIdList);
|
||||
|
||||
/**
|
||||
* 验证库区是否存在库位
|
||||
|
|
@ -74,13 +74,13 @@ public interface LocationQueryService {
|
|||
* @param locationCodes 库位集合
|
||||
* @return Map<String, LocationEntity>
|
||||
*/
|
||||
Map<String, LocationEntity> queryLocationListToMap(List<String> locationCodes);
|
||||
Map<String, LocationEntity> queryByLocationCodesToMap(List<String> locationCodes);
|
||||
|
||||
/**
|
||||
* 库位导出
|
||||
*
|
||||
* @return List<LocationsExcelVO>
|
||||
*/
|
||||
List<LocationsExcelVO> getLocationsExcelVOList();
|
||||
List<LocationsExcelVO> queryLocationsExcelVO();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import org.springframework.stereotype.Service;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
|
|
@ -60,8 +61,8 @@ public class LocationQueryServiceImpl implements LocationQueryService {
|
|||
List<LocationVO> list = locationDao.queryPage(page, queryForm);
|
||||
|
||||
// 查询库区名称
|
||||
List<Long> areaIdList = list.stream().map(LocationVO::getAreaId).distinct().collect(Collectors.toList());
|
||||
Map<Long, AreaEntity> areaMap = areaQueryService.queryAreaList(areaIdList);
|
||||
List<Long> areaIdList = list.stream().filter(Objects::nonNull).map(LocationVO::getAreaId).toList();
|
||||
Map<Long, AreaEntity> areaMap = areaQueryService.queryByAreaIds(areaIdList);
|
||||
list.forEach(locationVO -> {
|
||||
AreaEntity area = areaMap.get(locationVO.getAreaId());
|
||||
if (area != null) {
|
||||
|
|
@ -110,11 +111,9 @@ public class LocationQueryServiceImpl implements LocationQueryService {
|
|||
}
|
||||
//库区
|
||||
if (CollectionUtils.isNotEmpty(locationSelect.getAreaNames())) {
|
||||
AreaSelect areaSelect = AreaSelect.builder().areaNames(locationSelect.getAreaNames()).build();
|
||||
areaSelect.setAreaNames(locationSelect.getAreaNames());
|
||||
List<AreaEntity> areaList = areaQueryService.queryArea(areaSelect);
|
||||
List<AreaEntity> areaList = areaQueryService.queryByAreaNames(locationSelect.getAreaNames());
|
||||
if (CollectionUtils.isNotEmpty(areaList)) {
|
||||
List<Long> areaIdList = areaList.stream().map(AreaEntity::getAreaId).collect(Collectors.toList());
|
||||
List<Long> areaIdList = areaList.stream().map(AreaEntity::getAreaId).toList();
|
||||
queryWrapper.in(LocationEntity::getAreaId, areaIdList);
|
||||
}
|
||||
}
|
||||
|
|
@ -129,7 +128,7 @@ public class LocationQueryServiceImpl implements LocationQueryService {
|
|||
queryWrapper.eq(LocationEntity::getStatus, locationSelect.getStatus());
|
||||
}
|
||||
|
||||
List<LocationEntity> list = locationDao.selectList(queryWrapper);
|
||||
List<LocationEntity> list = locationManager.list(queryWrapper);
|
||||
|
||||
return list.stream().map(this::entityToVO).collect(Collectors.toList());
|
||||
}
|
||||
|
|
@ -140,11 +139,11 @@ public class LocationQueryServiceImpl implements LocationQueryService {
|
|||
* @param locationIdList 库位ID集合
|
||||
* @return Map<Long, LocationEntity>
|
||||
*/
|
||||
public Map<Long, LocationEntity> queryLocationList(List<Long> locationIdList) {
|
||||
public Map<Long, LocationEntity> queryByLocationIdsToMap(List<Long> locationIdList) {
|
||||
if (CollectionUtils.isEmpty(locationIdList)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
locationIdList = locationIdList.stream().distinct().collect(Collectors.toList());
|
||||
locationIdList = locationIdList.stream().filter(Objects::nonNull).distinct().toList();
|
||||
Map<Long, LocationEntity> locationMap = Maps.newHashMap();
|
||||
for (Long locationId : locationIdList) {
|
||||
LocationEntity location = locationManager.queryLocation(locationId);
|
||||
|
|
@ -161,9 +160,12 @@ public class LocationQueryServiceImpl implements LocationQueryService {
|
|||
* @param areaId 库区
|
||||
*/
|
||||
public Boolean checkLocationExist(Long areaId) {
|
||||
if (areaId == null) {
|
||||
return true;
|
||||
}
|
||||
LambdaQueryWrapper<LocationEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(LocationEntity::getAreaId, areaId);
|
||||
List<LocationEntity> list = locationDao.selectList(queryWrapper);
|
||||
List<LocationEntity> list = locationManager.list(queryWrapper);
|
||||
return list.isEmpty();
|
||||
}
|
||||
|
||||
|
|
@ -174,9 +176,12 @@ public class LocationQueryServiceImpl implements LocationQueryService {
|
|||
* @return LocationEntity
|
||||
*/
|
||||
public LocationEntity queryByLocationCode(String locationCode) {
|
||||
if (StringUtils.isBlank(locationCode)) {
|
||||
return null;
|
||||
}
|
||||
LambdaQueryWrapper<LocationEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(LocationEntity::getLocationCode, locationCode);
|
||||
return locationDao.selectOne(queryWrapper);
|
||||
return locationManager.getOne(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -186,9 +191,13 @@ public class LocationQueryServiceImpl implements LocationQueryService {
|
|||
* @return List<LocationEntity>
|
||||
*/
|
||||
public List<LocationEntity> queryByLocationCodes(List<String> locationCodes) {
|
||||
if (CollectionUtils.isEmpty(locationCodes)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
locationCodes = locationCodes.stream().filter(Objects::nonNull).distinct().toList();
|
||||
LambdaQueryWrapper<LocationEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.in(LocationEntity::getLocationCode, locationCodes);
|
||||
return locationDao.selectList(queryWrapper);
|
||||
return locationManager.list(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -197,14 +206,18 @@ public class LocationQueryServiceImpl implements LocationQueryService {
|
|||
* @param locationCodes 库位集合
|
||||
* @return Map<String, LocationEntity>
|
||||
*/
|
||||
public Map<String, LocationEntity> queryLocationListToMap(List<String> locationCodes) {
|
||||
public Map<String, LocationEntity> queryByLocationCodesToMap(List<String> locationCodes) {
|
||||
if (CollectionUtils.isEmpty(locationCodes)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
List<LocationEntity> locations = queryByLocationCodes(locationCodes);
|
||||
return locations.stream()
|
||||
.collect(Collectors.toMap(LocationEntity::getLocationCode, location -> location, (existing, replacement) -> existing));
|
||||
|
||||
//查询库位
|
||||
List<LocationEntity> locationList = queryByLocationCodes(locationCodes);
|
||||
//封装map
|
||||
Map<String, LocationEntity> locationMap = Maps.newHashMap();
|
||||
for (LocationEntity location : locationList) {
|
||||
locationMap.put(location.getLocationCode(), location);
|
||||
}
|
||||
return locationMap;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -212,11 +225,11 @@ public class LocationQueryServiceImpl implements LocationQueryService {
|
|||
*
|
||||
* @return List<LocationsExcelVO>
|
||||
*/
|
||||
public List<LocationsExcelVO> getLocationsExcelVOList() {
|
||||
List<LocationEntity> locationsList = locationDao.selectList(null);
|
||||
public List<LocationsExcelVO> queryLocationsExcelVO() {
|
||||
List<LocationEntity> locationsList = locationManager.list();
|
||||
//库区
|
||||
List<Long> areaIds = locationsList.stream().map(LocationEntity::getAreaId).distinct().collect(Collectors.toList());
|
||||
Map<Long, AreaEntity> areaMap = areaQueryService.queryAreaList(areaIds);
|
||||
List<Long> areaIds = locationsList.stream().map(LocationEntity::getAreaId).distinct().toList();
|
||||
Map<Long, AreaEntity> areaMap = areaQueryService.queryByAreaIds(areaIds);
|
||||
return locationsList.stream()
|
||||
.map(location ->
|
||||
LocationsExcelVO.builder()
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import lombok.extern.slf4j.Slf4j;
|
|||
import net.lab1024.sa.admin.constant.UsageStatusEnum;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.area.domain.entity.AreaEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.area.service.AreaQueryService;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.location.dao.LocationDao;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.location.domain.entity.LocationEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.location.domain.form.*;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.location.manager.LocationManager;
|
||||
|
|
@ -14,6 +13,7 @@ import net.lab1024.sa.admin.module.business.wms.base.location.service.LocationQu
|
|||
import net.lab1024.sa.admin.module.business.wms.base.location.service.LocationService;
|
||||
import net.lab1024.sa.admin.util.JoinerResult;
|
||||
import net.lab1024.sa.admin.util.ResponseDTOUtil;
|
||||
import net.lab1024.sa.admin.util.ValidateDictKeyUtil;
|
||||
import net.lab1024.sa.base.common.code.UserErrorCode;
|
||||
import net.lab1024.sa.base.common.domain.ResponseDTO;
|
||||
import net.lab1024.sa.base.common.exception.BusinessException;
|
||||
|
|
@ -35,8 +35,6 @@ import java.util.stream.Collectors;
|
|||
@Service
|
||||
@Slf4j
|
||||
public class LocationServiceImpl implements LocationService {
|
||||
@Resource
|
||||
private LocationDao locationDao;
|
||||
|
||||
@Resource
|
||||
private LocationManager locationManager;
|
||||
|
|
@ -48,7 +46,7 @@ public class LocationServiceImpl implements LocationService {
|
|||
private LocationQueryService locationQueryService;
|
||||
|
||||
@Resource
|
||||
private net.lab1024.sa.admin.util.ValidateDictKey ValidateDictKey;
|
||||
private ValidateDictKeyUtil ValidateDictKeyUtil;
|
||||
|
||||
/**
|
||||
* 添加
|
||||
|
|
@ -63,8 +61,7 @@ public class LocationServiceImpl implements LocationService {
|
|||
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
|
||||
}
|
||||
LocationEntity locationEntity = SmartBeanUtil.copy(addForm, LocationEntity.class);
|
||||
//新增并新增缓存
|
||||
locationManager.insert(locationEntity);
|
||||
locationManager.save(locationEntity);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
|
|
@ -133,10 +130,7 @@ public class LocationServiceImpl implements LocationService {
|
|||
}
|
||||
|
||||
//查询库位
|
||||
Map<Long, LocationEntity> locationEntityMap = locationQueryService.queryLocationList(multipleAdjust.getLocationIds());
|
||||
|
||||
//批量更新
|
||||
List<LocationEntity> updateToLocation = new ArrayList<>();
|
||||
Map<Long, LocationEntity> locationEntityMap = locationQueryService.queryByLocationIdsToMap(multipleAdjust.getLocationIds());
|
||||
|
||||
//调整状态,true:空闲;false:占用
|
||||
String status = multipleAdjust.getStatus() ? UsageStatusEnum.FREE.getValue() : UsageStatusEnum.USED.getValue();
|
||||
|
|
@ -144,6 +138,9 @@ public class LocationServiceImpl implements LocationService {
|
|||
//是否启用,true:启用;false:禁用
|
||||
Boolean disabledFlag = multipleAdjust.getDisabledFlag();
|
||||
|
||||
//批量更新
|
||||
List<LocationEntity> updateToLocation = new ArrayList<>();
|
||||
|
||||
//更新状态
|
||||
locationEntityMap.forEach((locationId, location) -> {
|
||||
location.setStatus(status);
|
||||
|
|
@ -220,7 +217,7 @@ public class LocationServiceImpl implements LocationService {
|
|||
}
|
||||
if (CollectionUtils.isNotEmpty(insertToLocation)) {
|
||||
// 批量新增并更新缓存
|
||||
locationManager.batchInsert(insertToLocation);
|
||||
locationManager.saveBatch(insertToLocation);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -283,23 +280,23 @@ public class LocationServiceImpl implements LocationService {
|
|||
return ResponseDTO.userErrorParam("数据为空");
|
||||
}
|
||||
|
||||
//获取所有去重后的库区
|
||||
List<String> areaNames = dataList.stream().map(LocationsImportForm::getAreaName).distinct().collect(Collectors.toList());
|
||||
//获取所有的库区
|
||||
List<String> areaNames = dataList.stream().map(LocationsImportForm::getAreaName).toList();
|
||||
|
||||
//验证库区
|
||||
Map<String, AreaEntity> areaMap = validateArea(areaNames);
|
||||
|
||||
//获取所有去重后的库位类型
|
||||
List<String> locationTypes = dataList.stream().map(LocationsImportForm::getLocationType).distinct().collect(Collectors.toList());
|
||||
//获取所有的库位类型
|
||||
List<String> locationTypes = dataList.stream().map(LocationsImportForm::getLocationType).toList();
|
||||
|
||||
//验证库位类型
|
||||
Map<String, String> locationTypeMap = ValidateDictKey.validateDictCodes(locationTypes, DictConst.LOC_TYPE.getValue());
|
||||
Map<String, String> locationTypeMap = ValidateDictKeyUtil.validateDictCodes(locationTypes, DictConst.LOC_TYPE.getValue());
|
||||
|
||||
//获取所有去重后的库位编码
|
||||
List<String> locationCodes = dataList.stream().map(LocationsImportForm::getLocationCode).distinct().collect(Collectors.toList());
|
||||
//获取所有的库位编码
|
||||
List<String> locationCodes = dataList.stream().map(LocationsImportForm::getLocationCode).toList();
|
||||
|
||||
//查询数据库存在的库位编码
|
||||
Map<String, LocationEntity> exitLocationMap = locationQueryService.queryLocationListToMap(locationCodes);
|
||||
Map<String, LocationEntity> exitLocationMap = locationQueryService.queryByLocationCodesToMap(locationCodes);
|
||||
|
||||
List<LocationEntity> insertToLocation = new ArrayList<>();
|
||||
List<LocationEntity> updateToLocation = new ArrayList<>();
|
||||
|
|
@ -322,7 +319,7 @@ public class LocationServiceImpl implements LocationService {
|
|||
}
|
||||
|
||||
JoinerResult resultMsg = JoinerResult.createJoiner();
|
||||
return ResponseDTOUtil.buildResponseDTO(insertToLocation, updateToLocation, locationManager::batchInsert, locationManager::batchUpdate, resultMsg);
|
||||
return ResponseDTOUtil.buildResponseDTO(insertToLocation, updateToLocation, locationManager::saveBatch, locationManager::batchUpdate, resultMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -333,7 +330,7 @@ public class LocationServiceImpl implements LocationService {
|
|||
*/
|
||||
public Map<String, AreaEntity> validateArea(List<String> areaNames) {
|
||||
//查询数据库存在的库区
|
||||
Map<String, AreaEntity> areaMap = areaQueryService.queryAreaByNameList(areaNames);
|
||||
Map<String, AreaEntity> areaMap = areaQueryService.queryByAreaNamesToMap(areaNames);
|
||||
if (areaMap.isEmpty()) {
|
||||
throw new BusinessException(areaNames + "库区不存在,在库区管理中维护库区");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ public class StockController {
|
|||
@SaCheckPermission("stock:exportStocks")
|
||||
@OperateLog
|
||||
public void stock(HttpServletResponse response) throws IOException {
|
||||
List<StocksExcelVO> stocksList = stockQueryService.getStocksExcelVOList();
|
||||
List<StocksExcelVO> stocksList = stockQueryService.queryStocksExcelVO();
|
||||
SmartExcelUtil.exportExcel(response, "容器信息.xlsx", "容器", StocksExcelVO.class, stocksList);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,19 +7,16 @@ import net.lab1024.sa.admin.module.business.wms.base.stock.dao.StockDao;
|
|||
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.entity.StockEntity;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import net.lab1024.sa.admin.util.TransactionCommitUtil;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 容器信息 Manager
|
||||
|
|
@ -30,6 +27,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
@CacheConfig(cacheNames = AdminCacheConst.Base.STOCK_ENTITY)
|
||||
public class StockManager extends ServiceImpl<StockDao, StockEntity> {
|
||||
|
||||
@Resource
|
||||
|
|
@ -38,153 +36,61 @@ public class StockManager extends ServiceImpl<StockDao, StockEntity> {
|
|||
@Resource
|
||||
private CacheManager cacheManager;
|
||||
|
||||
// 使用读写锁保证高并发下的缓存操作安全
|
||||
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
|
||||
private final Lock readLock = rwLock.readLock();
|
||||
private final Lock writeLock = rwLock.writeLock();
|
||||
|
||||
/**
|
||||
* 查询容器(带缓存)
|
||||
* 使用Spring Cache自动缓存查询结果
|
||||
* 使用Spring Cache进行缓存管理
|
||||
*/
|
||||
@Cacheable(value = AdminCacheConst.Base.STOCK_ENTITY, key = "#stockId", unless = "#result == null")
|
||||
@Cacheable(key = "#stockId", unless = "#result == null")
|
||||
public StockEntity queryStock(Long stockId) {
|
||||
try {
|
||||
readLock.lock();
|
||||
return stockDao.selectById(stockId);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
return stockDao.selectById(stockId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建容器(带缓存)
|
||||
* 事务提交后执行缓存刷新,保证数据一致性
|
||||
* 更新容器(清除缓存)
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public StockEntity insert(StockEntity entity) {
|
||||
super.save(entity);
|
||||
// 在事务提交后刷新缓存,确保数据库操作成功后再更新缓存
|
||||
executeAfterCommit("刷新容器缓存", () -> refreshCache(entity.getStockId()));
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新容器(带缓存)
|
||||
* 事务提交后执行缓存刷新,保证数据一致性
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public StockEntity update(StockEntity entity) {
|
||||
@CacheEvict(key = "#entity.stockId")
|
||||
public void update(StockEntity entity) {
|
||||
super.updateById(entity);
|
||||
// 在事务提交后刷新缓存,确保数据库操作成功后再更新缓存
|
||||
executeAfterCommit("刷新容器缓存", () -> refreshCache(entity.getStockId()));
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除容器(清理缓存)
|
||||
* 事务提交后清除缓存
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@CacheEvict(key = "#stockId")
|
||||
public void deleteById(Long stockId) {
|
||||
super.removeById(stockId);
|
||||
// 在事务提交后清除缓存,确保数据库操作成功后再更新缓存
|
||||
executeAfterCommit("清除容器缓存", () -> evictCache(stockId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量创建容器(带缓存)
|
||||
* 事务提交后执行缓存刷新,保证数据一致性
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchInsert(List<StockEntity> entities) {
|
||||
super.saveBatch(entities);
|
||||
// 在事务提交后批量刷新缓存
|
||||
executeAfterCommit("批量刷新容器缓存", () -> batchRefreshCache(entities));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新容器(带缓存)
|
||||
* 事务提交后执行缓存刷新,保证数据一致性
|
||||
* 批量更新容器(清理相关缓存)
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchUpdate(List<StockEntity> entities) {
|
||||
super.updateBatchById(entities);
|
||||
// 在事务提交后批量刷新缓存
|
||||
executeAfterCommit("批量刷新容器缓存", () -> batchRefreshCache(entities));
|
||||
List<Long> stockIds = entities.stream().map(StockEntity::getStockId).filter(Objects::nonNull).distinct().toList();
|
||||
stockIds.forEach(this::clearCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除容器(清理缓存)
|
||||
* 事务提交后清除缓存
|
||||
* 批量删除容器(清理相关缓存)
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchDelete(List<Long> stockIds) {
|
||||
super.removeByIds(stockIds);
|
||||
// 在事务提交后批量清除缓存
|
||||
executeAfterCommit("批量清除容器缓存", () -> stockIds.forEach(this::evictCache));
|
||||
stockIds.forEach(this::clearCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用方法:事务提交后执行操作
|
||||
*
|
||||
* @param operationDesc 操作描述(用于日志)
|
||||
* @param operation 要执行的操作
|
||||
* 手工清理缓存
|
||||
*/
|
||||
private void executeAfterCommit(String operationDesc, Runnable operation) {
|
||||
TransactionCommitUtil.executeAfterCommit(operationDesc, operation);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新单个缓存
|
||||
* 使用写锁确保并发安全
|
||||
*/
|
||||
public void refreshCache(Long stockId) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
// 先清除可能存在的旧缓存
|
||||
evictCache(stockId);
|
||||
// 重新查询并缓存最新数据
|
||||
StockEntity entity = stockDao.selectById(stockId);
|
||||
|
||||
// 手动更新缓存,避免使用@CachePut注解可能导致的问题
|
||||
if (entity != null) {
|
||||
Cache cache = cacheManager.getCache(AdminCacheConst.Base.STOCK_ENTITY);
|
||||
if (cache != null) {
|
||||
cache.put(stockId, entity);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量刷新缓存
|
||||
* 先收集所有ID,再逐一刷新,减少锁争用
|
||||
*/
|
||||
private void batchRefreshCache(Collection<StockEntity> entities) {
|
||||
List<Long> stockIds = entities.stream()
|
||||
.map(StockEntity::getStockId)
|
||||
.distinct()
|
||||
.toList();
|
||||
|
||||
stockIds.forEach(this::refreshCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动清除缓存
|
||||
* 使用写锁确保并发安全
|
||||
*/
|
||||
private void evictCache(Long stockId) {
|
||||
try {
|
||||
writeLock.lock();
|
||||
public void clearCache(Long stockId) {
|
||||
if (stockId != null) {
|
||||
Cache cache = cacheManager.getCache(AdminCacheConst.Base.STOCK_ENTITY);
|
||||
if (cache != null) {
|
||||
cache.evict(stockId);
|
||||
}
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,14 +21,6 @@ public interface StockQueryService {
|
|||
*/
|
||||
PageResult<StockVO> queryPage(StockQueryForm queryForm);
|
||||
|
||||
/**
|
||||
* 根据容器id集合查询容器信息
|
||||
*
|
||||
* @param stockIdList 容器id集合
|
||||
* @return Map<Long, StockEntity>
|
||||
*/
|
||||
Map<Long, StockEntity> queryStockList(List<Long> stockIdList);
|
||||
|
||||
/**
|
||||
* 容器下拉查询
|
||||
*
|
||||
|
|
@ -37,6 +29,16 @@ public interface StockQueryService {
|
|||
*/
|
||||
List<StockEntity> queryStock(StockSelect stockSelect);
|
||||
|
||||
|
||||
/**
|
||||
* 根据容器id集合查询容器信息
|
||||
*
|
||||
* @param stockIdList 容器id集合
|
||||
* @return Map<Long, StockEntity>
|
||||
*/
|
||||
Map<Long, StockEntity> queryByStockIdsToMap(List<Long> stockIdList);
|
||||
|
||||
|
||||
/**
|
||||
* 根据容器编码查询容器信息
|
||||
*
|
||||
|
|
@ -51,7 +53,7 @@ public interface StockQueryService {
|
|||
* @param stockCodes 容器料编码集合
|
||||
* @return List<StockEntity>
|
||||
*/
|
||||
List<StockEntity> queryByItemCodes(List<String> stockCodes);
|
||||
List<StockEntity> queryByStockCodes(List<String> stockCodes);
|
||||
|
||||
/**
|
||||
* 根据容器编码集合查询容器信息
|
||||
|
|
@ -59,7 +61,7 @@ public interface StockQueryService {
|
|||
* @param stockCodes 容器编码集合
|
||||
* @return Map<String, StockEntity>
|
||||
*/
|
||||
Map<String, StockEntity> queryStockListToMap(List<String> stockCodes);
|
||||
Map<String, StockEntity> queryByStockCodesToMap(List<String> stockCodes);
|
||||
|
||||
/**
|
||||
* 根据库位id查询容器信息
|
||||
|
|
@ -74,5 +76,5 @@ public interface StockQueryService {
|
|||
*
|
||||
* @return List<StocksExcelVO>
|
||||
*/
|
||||
List<StocksExcelVO> getStocksExcelVOList();
|
||||
List<StocksExcelVO> queryStocksExcelVO();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,8 +57,8 @@ public class StockQueryServiceImpl implements StockQueryService {
|
|||
List<StockVO> list = stockDao.queryPage(page, queryForm);
|
||||
|
||||
// 查询库位编码
|
||||
List<Long> locationIdList = list.stream().map(StockVO::getLocationId).filter(Objects::nonNull).distinct().toList();
|
||||
Map<Long, LocationEntity> locationMap = locationQueryService.queryLocationList(locationIdList);
|
||||
List<Long> locationIdList = list.stream().map(StockVO::getLocationId).toList();
|
||||
Map<Long, LocationEntity> locationMap = locationQueryService.queryByLocationIdsToMap(locationIdList);
|
||||
list.forEach(StockVO -> {
|
||||
LocationEntity location = locationMap.get(StockVO.getLocationId());
|
||||
if (location != null) {
|
||||
|
|
@ -68,27 +68,6 @@ public class StockQueryServiceImpl implements StockQueryService {
|
|||
return SmartPageUtil.convert2PageResult(page, list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据容器id集合查询容器信息
|
||||
*
|
||||
* @param stockIdList 容器id集合
|
||||
* @return Map<Long, StockEntity>
|
||||
*/
|
||||
public Map<Long, StockEntity> queryStockList(List<Long> stockIdList) {
|
||||
if (CollectionUtils.isEmpty(stockIdList)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
stockIdList = stockIdList.stream().distinct().collect(Collectors.toList());
|
||||
Map<Long, StockEntity> stockMap = Maps.newHashMap();
|
||||
for (Long stockId : stockIdList) {
|
||||
StockEntity stock = stockManager.queryStock(stockId);
|
||||
if (stock != null) {
|
||||
stockMap.put(stockId, stock);
|
||||
}
|
||||
}
|
||||
return stockMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 容器下拉查询
|
||||
*
|
||||
|
|
@ -105,7 +84,28 @@ public class StockQueryServiceImpl implements StockQueryService {
|
|||
if (StringUtils.isNotBlank(stockSelect.getStatus())) {
|
||||
queryWrapper.eq(StockEntity::getStatus, stockSelect.getStatus());
|
||||
}
|
||||
return stockDao.selectList(queryWrapper);
|
||||
return stockManager.list(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据容器id集合查询容器信息
|
||||
*
|
||||
* @param stockIdList 容器id集合
|
||||
* @return Map<Long, StockEntity>
|
||||
*/
|
||||
public Map<Long, StockEntity> queryByStockIdsToMap(List<Long> stockIdList) {
|
||||
if (CollectionUtils.isEmpty(stockIdList)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
stockIdList = stockIdList.stream().filter(Objects::nonNull).distinct().toList();
|
||||
Map<Long, StockEntity> stockMap = Maps.newHashMap();
|
||||
for (Long stockId : stockIdList) {
|
||||
StockEntity stock = stockManager.queryStock(stockId);
|
||||
if (stock != null) {
|
||||
stockMap.put(stockId, stock);
|
||||
}
|
||||
}
|
||||
return stockMap;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -115,9 +115,12 @@ public class StockQueryServiceImpl implements StockQueryService {
|
|||
* @return StockEntity
|
||||
*/
|
||||
public StockEntity queryByStockCode(String stockCode) {
|
||||
if (StringUtils.isBlank(stockCode)) {
|
||||
return null;
|
||||
}
|
||||
LambdaQueryWrapper<StockEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(StockEntity::getStockCode, stockCode);
|
||||
return stockDao.selectOne(queryWrapper);
|
||||
return stockManager.getOne(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -126,10 +129,14 @@ public class StockQueryServiceImpl implements StockQueryService {
|
|||
* @param stockCodes 容器料编码集合
|
||||
* @return List<StockEntity>
|
||||
*/
|
||||
public List<StockEntity> queryByItemCodes(List<String> stockCodes) {
|
||||
public List<StockEntity> queryByStockCodes(List<String> stockCodes) {
|
||||
if (CollectionUtils.isEmpty(stockCodes)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
stockCodes = stockCodes.stream().filter(Objects::nonNull).distinct().toList();
|
||||
LambdaQueryWrapper<StockEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.in(StockEntity::getStockCode, stockCodes);
|
||||
return stockDao.selectList(queryWrapper);
|
||||
return stockManager.list(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -138,13 +145,18 @@ public class StockQueryServiceImpl implements StockQueryService {
|
|||
* @param stockCodes 容器编码集合
|
||||
* @return Map<String, StockEntity>
|
||||
*/
|
||||
public Map<String, StockEntity> queryStockListToMap(List<String> stockCodes) {
|
||||
public Map<String, StockEntity> queryByStockCodesToMap(List<String> stockCodes) {
|
||||
if (CollectionUtils.isEmpty(stockCodes)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
List<StockEntity> stocks = queryByItemCodes(stockCodes);
|
||||
return stocks.stream()
|
||||
.collect(Collectors.toMap(StockEntity::getStockCode, stock -> stock, (existing, replacement) -> existing));
|
||||
//查询容器
|
||||
List<StockEntity> stockList = queryByStockCodes(stockCodes);
|
||||
//封装map
|
||||
Map<String, StockEntity> stockMap = Maps.newHashMap();
|
||||
for (StockEntity stock : stockList) {
|
||||
stockMap.put(stock.getStockCode(), stock);
|
||||
}
|
||||
return stockMap;
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -155,9 +167,12 @@ public class StockQueryServiceImpl implements StockQueryService {
|
|||
* @return StockEntity
|
||||
*/
|
||||
public StockEntity queryStockByLocationId(Long locationId) {
|
||||
if (locationId == null) {
|
||||
return null;
|
||||
}
|
||||
LambdaQueryWrapper<StockEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(StockEntity::getLocationId, locationId);
|
||||
return stockDao.selectOne(queryWrapper);
|
||||
return stockManager.getOne(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -165,8 +180,8 @@ public class StockQueryServiceImpl implements StockQueryService {
|
|||
*
|
||||
* @return List<StocksExcelVO>
|
||||
*/
|
||||
public List<StocksExcelVO> getStocksExcelVOList() {
|
||||
List<StockEntity> stocksList = stockDao.selectList(null);
|
||||
public List<StocksExcelVO> queryStocksExcelVO() {
|
||||
List<StockEntity> stocksList = stockManager.list();
|
||||
return stocksList.stream()
|
||||
.map(stock ->
|
||||
StocksExcelVO.builder()
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import net.lab1024.sa.admin.module.business.wms.base.stock.service.StockQuerySer
|
|||
import net.lab1024.sa.admin.module.business.wms.base.stock.service.StockService;
|
||||
import net.lab1024.sa.admin.util.JoinerResult;
|
||||
import net.lab1024.sa.admin.util.ResponseDTOUtil;
|
||||
import net.lab1024.sa.admin.util.ValidateDictKeyUtil;
|
||||
import net.lab1024.sa.base.common.code.SystemErrorCode;
|
||||
import net.lab1024.sa.base.common.code.UserErrorCode;
|
||||
import net.lab1024.sa.base.common.domain.ResponseDTO;
|
||||
|
|
@ -31,7 +32,6 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class StockServiceImpl implements StockService {
|
||||
|
|
@ -42,7 +42,7 @@ public class StockServiceImpl implements StockService {
|
|||
private StockManager stockManager;
|
||||
|
||||
@Resource
|
||||
private net.lab1024.sa.admin.util.ValidateDictKey ValidateDictKey;
|
||||
private ValidateDictKeyUtil ValidateDictKeyUtil;
|
||||
|
||||
@Resource
|
||||
private StockQueryService stockQueryService;
|
||||
|
|
@ -64,8 +64,7 @@ public class StockServiceImpl implements StockService {
|
|||
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
|
||||
}
|
||||
StockEntity stockEntity = SmartBeanUtil.copy(addForm, StockEntity.class);
|
||||
//添加并更新缓存
|
||||
stockManager.insert(stockEntity);
|
||||
stockManager.save(stockEntity);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
|
|
@ -158,17 +157,17 @@ public class StockServiceImpl implements StockService {
|
|||
return ResponseDTO.userErrorParam("数据为空");
|
||||
}
|
||||
|
||||
//获取所有去重后的容器类型
|
||||
List<String> stockTypes = dataList.stream().map(StocksImportForm::getStockType).distinct().collect(Collectors.toList());
|
||||
//获取所有容器类型
|
||||
List<String> stockTypes = dataList.stream().map(StocksImportForm::getStockType).toList();
|
||||
|
||||
//验证容器类型
|
||||
Map<String, String> itemTypeMap = ValidateDictKey.validateDictCodes(stockTypes, DictConst.STOCK_TYPE.getValue());
|
||||
Map<String, String> itemTypeMap = ValidateDictKeyUtil.validateDictCodes(stockTypes, DictConst.STOCK_TYPE.getValue());
|
||||
|
||||
//获取所有去重后的容器编码
|
||||
List<String> stockCodes = dataList.stream().map(StocksImportForm::getStockCode).distinct().collect(Collectors.toList());
|
||||
//获取所有的容器编码
|
||||
List<String> stockCodes = dataList.stream().map(StocksImportForm::getStockCode).toList();
|
||||
|
||||
//查询数据库存在的容器
|
||||
Map<String, StockEntity> exitStockMap = stockQueryService.queryStockListToMap(stockCodes);
|
||||
Map<String, StockEntity> exitStockMap = stockQueryService.queryByStockCodesToMap(stockCodes);
|
||||
|
||||
List<StockEntity> insertToStock = new ArrayList<>();
|
||||
List<StockEntity> updateToStock = new ArrayList<>();
|
||||
|
|
@ -189,7 +188,7 @@ public class StockServiceImpl implements StockService {
|
|||
}
|
||||
|
||||
JoinerResult resultMsg = JoinerResult.createJoiner();
|
||||
return ResponseDTOUtil.buildResponseDTO(insertToStock, updateToStock, stockManager::batchInsert, stockManager::batchUpdate, resultMsg);
|
||||
return ResponseDTOUtil.buildResponseDTO(insertToStock, updateToStock, stockManager::saveBatch, stockManager::batchUpdate, resultMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -51,20 +51,20 @@ public class InventoryQueryService {
|
|||
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
|
||||
List<InventoryVO> list = inventoryDao.queryPage(page, queryForm);
|
||||
// 查询物料属性
|
||||
List<Long> itemKeyIds = list.stream().map(InventoryVO::getItemKeyId).distinct().collect(Collectors.toList());
|
||||
Map<Long, ItemKeyEntity> itemKeyMap = itemKeyQueryService.queryItemKeyList(itemKeyIds);
|
||||
List<Long> itemKeyIds = list.stream().map(InventoryVO::getItemKeyId).toList();
|
||||
Map<Long, ItemKeyEntity> itemKeyMap = itemKeyQueryService.queryByItemKeyIds(itemKeyIds);
|
||||
|
||||
//查询物料
|
||||
List<Long> itemIds = itemKeyMap.values().stream().map(ItemKeyEntity::getItemId).distinct().collect(Collectors.toList());
|
||||
Map<Long, ItemEntity> itemMap = itemQueryService.queryItemList(itemIds);
|
||||
List<Long> itemIds = itemKeyMap.values().stream().map(ItemKeyEntity::getItemId).toList();
|
||||
Map<Long, ItemEntity> itemMap = itemQueryService.queryByItemIdsToMap(itemIds);
|
||||
|
||||
//查询容器
|
||||
List<Long> stockIds = list.stream().map(InventoryVO::getStockId).distinct().collect(Collectors.toList());
|
||||
Map<Long, StockEntity> stockMap = stockQueryService.queryStockList(stockIds);
|
||||
List<Long> stockIds = list.stream().map(InventoryVO::getStockId).toList();
|
||||
Map<Long, StockEntity> stockMap = stockQueryService.queryByStockIdsToMap(stockIds);
|
||||
|
||||
//查询库位
|
||||
List<Long> locationIds = list.stream().map(InventoryVO::getLocationId).distinct().collect(Collectors.toList());
|
||||
Map<Long, LocationEntity> locationMap = locationQueryService.queryLocationList(locationIds);
|
||||
List<Long> locationIds = list.stream().map(InventoryVO::getLocationId).toList();
|
||||
Map<Long, LocationEntity> locationMap = locationQueryService.queryByLocationIdsToMap(locationIds);
|
||||
|
||||
list.forEach(InventoryVO -> {
|
||||
ItemKeyEntity itemKey = itemKeyMap.get(InventoryVO.getItemKeyId());
|
||||
|
|
@ -91,7 +91,7 @@ public class InventoryQueryService {
|
|||
* @param ItemKeyId 物料
|
||||
* @return InventoryEntity
|
||||
*/
|
||||
public InventoryEntity queryInventory(Long ItemKeyId) {
|
||||
public InventoryEntity queryInventoryByItemKeyId(Long ItemKeyId) {
|
||||
LambdaQueryWrapper<InventoryEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(InventoryEntity::getItemKeyId, ItemKeyId);
|
||||
return inventoryDao.selectOne(queryWrapper);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import org.springframework.stereotype.Service;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
|
|
@ -48,11 +49,11 @@ public class ItemKeyQueryService {
|
|||
* @param itemKeyIdList 物料属性ID集合
|
||||
* @return Map<Long, ItemKeyEntity>
|
||||
*/
|
||||
public Map<Long, ItemKeyEntity> queryItemKeyList(List<Long> itemKeyIdList) {
|
||||
public Map<Long, ItemKeyEntity> queryByItemKeyIds(List<Long> itemKeyIdList) {
|
||||
if (CollectionUtils.isEmpty(itemKeyIdList)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
itemKeyIdList = itemKeyIdList.stream().distinct().collect(Collectors.toList());
|
||||
itemKeyIdList = itemKeyIdList.stream().filter(Objects::nonNull).distinct().toList();
|
||||
Map<Long, ItemKeyEntity> itemKeyMap = Maps.newHashMap();
|
||||
for (Long itemKeyId : itemKeyIdList) {
|
||||
ItemKeyEntity itemKey = itemKeyManager.queryItemKey(itemKeyId);
|
||||
|
|
@ -68,7 +69,7 @@ public class ItemKeyQueryService {
|
|||
queryWrapper.eq(ItemKeyEntity::getOrderNumber, orderNumber);
|
||||
queryWrapper.eq(ItemKeyEntity::getItemId, itemId);
|
||||
queryWrapper.eq(ItemKeyEntity::getPropC1, propC1);
|
||||
List<ItemKeyEntity> itemKeys = itemKeyDao.selectList(queryWrapper);
|
||||
List<ItemKeyEntity> itemKeys = itemKeyManager.list(queryWrapper);
|
||||
if (CollectionUtils.isEmpty(itemKeys)) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +1,14 @@
|
|||
package net.lab1024.sa.admin.module.business.wms.itemKey.service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import net.lab1024.sa.admin.module.business.wms.itemKey.dao.ItemKeyDao;
|
||||
import net.lab1024.sa.admin.module.business.wms.itemKey.domain.entity.ItemKeyEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.itemKey.domain.form.ItemKeyAddForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.itemKey.domain.form.ItemKeyQueryForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.itemKey.domain.form.ItemKeyUpdateForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.itemKey.domain.vo.ItemKeyVO;
|
||||
import net.lab1024.sa.admin.module.business.wms.itemKey.manager.ItemKeyManager;
|
||||
import net.lab1024.sa.admin.module.business.wms.itemKey.dao.ItemKeyDao;
|
||||
import net.lab1024.sa.admin.module.business.wms.itemKey.domain.entity.ItemKeyEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.itemKey.domain.form.ItemKeyAddForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.itemKey.domain.form.ItemKeyUpdateForm;
|
||||
import net.lab1024.sa.base.common.code.UserErrorCode;
|
||||
import net.lab1024.sa.base.common.util.SmartBeanUtil;
|
||||
import net.lab1024.sa.base.common.util.SmartPageUtil;
|
||||
import net.lab1024.sa.base.common.domain.ResponseDTO;
|
||||
import net.lab1024.sa.base.common.domain.PageResult;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import net.lab1024.sa.base.common.util.SmartRequestUtil;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
|
@ -38,9 +27,6 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
@Service
|
||||
public class ItemKeyService {
|
||||
|
||||
@Resource
|
||||
private ItemKeyDao itemKeyDao;
|
||||
|
||||
@Resource
|
||||
private ItemKeyManager itemKeyManager;
|
||||
|
||||
|
|
@ -53,7 +39,7 @@ public class ItemKeyService {
|
|||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<String> add(ItemKeyAddForm addForm) {
|
||||
ItemKeyEntity itemKeyEntity = SmartBeanUtil.copy(addForm, ItemKeyEntity.class);
|
||||
itemKeyDao.insert(itemKeyEntity);
|
||||
itemKeyManager.save(itemKeyEntity);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
|
|
@ -63,7 +49,7 @@ public class ItemKeyService {
|
|||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<String> update(ItemKeyUpdateForm updateForm) {
|
||||
ItemKeyEntity itemKeyEntity = SmartBeanUtil.copy(updateForm, ItemKeyEntity.class);
|
||||
itemKeyDao.updateById(itemKeyEntity);
|
||||
itemKeyManager.updateById(itemKeyEntity);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
|
|
@ -89,7 +75,7 @@ public class ItemKeyService {
|
|||
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
|
||||
}
|
||||
|
||||
itemKeyDao.deleteById(itemKeyId);
|
||||
itemKeyManager.removeById(itemKeyId);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
|
|
@ -114,7 +100,7 @@ public class ItemKeyService {
|
|||
.createUserId(SmartRequestUtil.getRequestUser().getUserId())
|
||||
.createUserName(SmartRequestUtil.getRequestUser().getUserName())
|
||||
.build();
|
||||
itemKeyDao.insert(itemKey);
|
||||
itemKeyManager.save(itemKey);
|
||||
return itemKey;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,42 +1,15 @@
|
|||
package net.lab1024.sa.admin.module.business.wms.receive.asn.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import jakarta.annotation.Resource;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.address.domain.entity.AddressEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.address.service.AddressQueryService;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.area.domain.entity.AreaEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.domain.entity.CustomerEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.service.CustomerQueryService;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.location.domain.entity.LocationEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.location.domain.vo.LocationVO;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.dao.AsnDao;
|
||||
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.domain.entity.AsnEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.domain.form.AsnQueryForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.domain.vo.AsnVO;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.entity.AsnDetailEntity;
|
||||
import net.lab1024.sa.base.common.domain.PageResult;
|
||||
import net.lab1024.sa.base.common.util.SmartPageUtil;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class AsnQueryService {
|
||||
|
||||
@Resource
|
||||
private AsnDao asnDao;
|
||||
|
||||
@Resource
|
||||
private CustomerQueryService customerQueryService;
|
||||
|
||||
@Resource
|
||||
private AddressQueryService addressQueryService;
|
||||
public interface AsnQueryService {
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
|
|
@ -44,30 +17,7 @@ public class AsnQueryService {
|
|||
* @param queryForm 查询条件
|
||||
* @return PageResult<AsnVO>
|
||||
*/
|
||||
public PageResult<AsnVO> queryPage(AsnQueryForm queryForm) {
|
||||
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
|
||||
List<AsnVO> list = asnDao.queryPage(page, queryForm);
|
||||
|
||||
// 查询客户名称
|
||||
List<Long> customerIdList = list.stream().map(AsnVO::getCustomerId).distinct().collect(Collectors.toList());
|
||||
Map<Long, CustomerEntity> customerMap = customerQueryService.queryCustomerList(customerIdList);
|
||||
|
||||
// 查询收货单位
|
||||
List<Long> addressIdList = list.stream().map(AsnVO::getAddressId).distinct().collect(Collectors.toList());
|
||||
Map<Long, AddressEntity> addressMap = addressQueryService.queryAddressList(addressIdList);
|
||||
|
||||
list.forEach(asnVO -> {
|
||||
CustomerEntity customer = customerMap.get(asnVO.getCustomerId());
|
||||
if (customer != null) {
|
||||
asnVO.setCustomerName(customer.getCustomerName());
|
||||
}
|
||||
AddressEntity address = addressMap.get(asnVO.getAddressId());
|
||||
if (address != null) {
|
||||
asnVO.setName(address.getName());
|
||||
}
|
||||
});
|
||||
return SmartPageUtil.convert2PageResult(page, list);
|
||||
}
|
||||
PageResult<AsnVO> queryPage(AsnQueryForm queryForm);
|
||||
|
||||
/**
|
||||
* 根据客户订单号查询入库单
|
||||
|
|
@ -75,14 +25,7 @@ public class AsnQueryService {
|
|||
* @param customerNumber 客户订单号
|
||||
* @return AsnEntity
|
||||
*/
|
||||
public AsnEntity queryByCustomerNumber(String customerNumber) {
|
||||
if (StringUtils.isBlank(customerNumber)) {
|
||||
return null;
|
||||
}
|
||||
LambdaQueryWrapper<AsnEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(AsnEntity::getCustomerNumber, customerNumber);
|
||||
return asnDao.selectOne(queryWrapper);
|
||||
}
|
||||
AsnEntity queryByCustomerNumber(String customerNumber);
|
||||
|
||||
/**
|
||||
* 根据ids查询入库
|
||||
|
|
@ -90,14 +33,7 @@ public class AsnQueryService {
|
|||
* @param idList 入库集合
|
||||
* @return List<AsnEntity>
|
||||
*/
|
||||
public List<AsnEntity> queryAsnList(List<Long> idList) {
|
||||
if (CollectionUtils.isEmpty(idList)) {
|
||||
return null;
|
||||
}
|
||||
LambdaQueryWrapper<AsnEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.in(AsnEntity::getAsnId, idList);
|
||||
return asnDao.selectList(queryWrapper);
|
||||
}
|
||||
List<AsnEntity> queryByAsnIds(List<Long> idList);
|
||||
|
||||
/**
|
||||
* 根据入库单集合查询入库单信息
|
||||
|
|
@ -105,15 +41,7 @@ public class AsnQueryService {
|
|||
* @param idList 入库单集合
|
||||
* @return Map<String, AsnEntity>
|
||||
*/
|
||||
public Map<Long, AsnEntity> queryAsnListToMap(List<Long> idList) {
|
||||
if (CollectionUtils.isEmpty(idList)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
List<AsnEntity> asnList = queryAsnList(idList);
|
||||
return asnList.stream()
|
||||
.collect(Collectors.toMap(AsnEntity::getAsnId, asn -> asn, (existing, replacement) -> existing));
|
||||
|
||||
}
|
||||
Map<Long, AsnEntity> queryByAsnIdsToMap(List<Long> idList);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import net.lab1024.sa.admin.module.business.wms.receive.asn.domain.form.AsnUpdat
|
|||
import net.lab1024.sa.admin.module.business.wms.receive.asn.manager.AsnManager;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.entity.AsnDetailEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.manager.AsnDetailManager;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.service.AsnDetailQueryService;
|
||||
import net.lab1024.sa.admin.util.JoinerResult;
|
||||
import net.lab1024.sa.admin.util.ResponseDTOUtil;
|
||||
import net.lab1024.sa.base.common.code.UserErrorCode;
|
||||
|
|
@ -37,30 +36,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
* @since 2025-03-26 15:10:02
|
||||
* copyright 友仓
|
||||
*/
|
||||
|
||||
@Service
|
||||
public class AsnService {
|
||||
|
||||
@Resource
|
||||
private AsnDao asnDao;
|
||||
|
||||
@Resource
|
||||
private AsnManager asnManager;
|
||||
|
||||
@Resource
|
||||
private AsnDetailManager asnDetailManager;
|
||||
|
||||
@Resource
|
||||
private AsnQueryService asnQueryService;
|
||||
|
||||
@Resource
|
||||
private AsnDetailQueryService asnDetailQueryService;
|
||||
|
||||
@Resource
|
||||
private SerialNumberService serialNumberService;
|
||||
|
||||
@Resource
|
||||
private DataTracerService dataTracerService;
|
||||
public interface AsnService {
|
||||
|
||||
/**
|
||||
* 添加
|
||||
|
|
@ -68,23 +44,7 @@ public class AsnService {
|
|||
* @param addForm 添加参数
|
||||
* @return ResponseDTO<String>
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<AsnEntity> add(AsnAddForm addForm) {
|
||||
AsnEntity exitAsn = asnQueryService.queryByCustomerNumber(addForm.getCustomerNumber());
|
||||
if (exitAsn != null) {
|
||||
throw new BusinessException(addForm.getCustomerNumber() + "客户订单号已存在");
|
||||
}
|
||||
//自动生成入库编号
|
||||
addForm.setAsnNumber(serialNumberService.generate(SerialNumberIdEnum.ASN));
|
||||
//默认已创建
|
||||
addForm.setStatus(AsnOrderStatusEnum.CREATED.getValue());
|
||||
AsnEntity asnEntity = SmartBeanUtil.copy(addForm, AsnEntity.class);
|
||||
asnDao.insert(asnEntity);
|
||||
|
||||
//操作记录
|
||||
dataTracerService.addTrace(asnEntity.getAsnId(), DataTracerTypeEnum.ASN,"新建入库单:"+asnEntity.getAsnNumber(), null,asnEntity);
|
||||
return ResponseDTO.ok(asnEntity);
|
||||
}
|
||||
ResponseDTO<AsnEntity> add(AsnAddForm addForm);
|
||||
|
||||
/**
|
||||
* 更新
|
||||
|
|
@ -92,18 +52,7 @@ public class AsnService {
|
|||
* @param updateForm 更新参数
|
||||
* @return ResponseDTO<String>
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<AsnEntity> update(AsnUpdateForm updateForm) {
|
||||
AsnEntity exitAsn = asnQueryService.queryByCustomerNumber(updateForm.getCustomerNumber());
|
||||
if (exitAsn != null && !exitAsn.getAsnId().equals(updateForm.getAsnId())) {
|
||||
throw new BusinessException(updateForm.getCustomerNumber() + "客户订单号已存在");
|
||||
}
|
||||
AsnEntity asnEntity = SmartBeanUtil.copy(updateForm, AsnEntity.class);
|
||||
asnDao.updateById(asnEntity);
|
||||
//业务操作记录
|
||||
dataTracerService.addTrace(updateForm.getAsnId(), DataTracerTypeEnum.ASN,"编辑入库单:"+asnEntity.getAsnNumber(), exitAsn,asnEntity);
|
||||
return ResponseDTO.ok(asnEntity);
|
||||
}
|
||||
ResponseDTO<AsnEntity> update(AsnUpdateForm updateForm);
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
|
|
@ -111,63 +60,10 @@ public class AsnService {
|
|||
* @param idList 入库单id集合
|
||||
* @return ResponseDTO<String>
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<String> batchDelete(List<Long> idList) {
|
||||
if (CollectionUtils.isEmpty(idList)) {
|
||||
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
|
||||
}
|
||||
JoinerResult resultMsg = JoinerResult.createJoiner();
|
||||
|
||||
//查询批量订单
|
||||
List<AsnEntity> asnList = asnQueryService.queryAsnList(idList);
|
||||
|
||||
//将订单按状态分组;已创建的一组;非已创建的一组。
|
||||
Map<Boolean, List<AsnEntity>> partitionedAsnList = asnList.stream()
|
||||
.collect(Collectors.partitioningBy(asn -> AsnOrderStatusEnum.CREATED.getValue().equals(asn.getStatus())));
|
||||
//已创建的订单允许删除
|
||||
List<AsnEntity> createAsnList = partitionedAsnList.get(true);
|
||||
//入库单集合
|
||||
List<Long> asnIds = createAsnList.stream().map(AsnEntity::getAsnId).collect(Collectors.toList());
|
||||
//根据入库单ID集合查询入库明细
|
||||
List<AsnDetailEntity> details = asnDetailQueryService.queryByAsnIds(asnIds);
|
||||
if (CollectionUtils.isNotEmpty(details)) {
|
||||
asnDetailManager.removeBatchByIds(details);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(createAsnList)) {
|
||||
Set<String> asnCodes = createAsnList.stream().map(AsnEntity::getAsnNumber).collect(Collectors.toSet());
|
||||
asnManager.removeBatchByIds(createAsnList);
|
||||
resultMsg.getSussMsg().add(asnCodes + "订单删除成功");
|
||||
}
|
||||
|
||||
//非已创建的订单不允许删除
|
||||
List<AsnEntity> noCreateAsnList = partitionedAsnList.get(false);
|
||||
if (CollectionUtils.isNotEmpty(noCreateAsnList)) {
|
||||
Set<String> asnCodes = noCreateAsnList.stream().map(AsnEntity::getAsnNumber).collect(Collectors.toSet());
|
||||
resultMsg.getErrorMsg().add(asnCodes + "订单不允许删除");
|
||||
}
|
||||
|
||||
return ResponseDTOUtil.buildResponseDTO(resultMsg);
|
||||
}
|
||||
ResponseDTO<String> batchDelete(List<Long> idList);
|
||||
|
||||
/**
|
||||
* 单个删除
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<String> delete(Long asnId) {
|
||||
if (null == asnId) {
|
||||
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
|
||||
}
|
||||
AsnEntity asn = asnDao.selectById(asnId);
|
||||
String status = asn.getStatus();
|
||||
// 只有已创建的订单才允许删除
|
||||
if (!AsnOrderStatusEnum.CREATED.getValue().equals(status)) {
|
||||
return ResponseDTO.userErrorParam(AsnOrderStatusEnum.getDescByValue(status) + "的订单不允许删除");
|
||||
}
|
||||
List<AsnDetailEntity> details = asnDetailQueryService.queryByAsnId(asnId);
|
||||
if (CollectionUtils.isNotEmpty(details)) {
|
||||
asnDetailManager.removeBatchByIds(details);
|
||||
}
|
||||
asnDao.deleteById(asnId);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
ResponseDTO<String> delete(Long asnId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,125 @@
|
|||
package net.lab1024.sa.admin.module.business.wms.receive.asn.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.google.common.collect.Maps;
|
||||
import jakarta.annotation.Resource;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.address.domain.entity.AddressEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.address.service.AddressQueryService;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.domain.entity.CustomerEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.service.CustomerQueryService;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.dao.AsnDao;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.domain.entity.AsnEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.domain.form.AsnQueryForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.domain.vo.AsnVO;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.manager.AsnManager;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.service.AsnQueryService;
|
||||
import net.lab1024.sa.base.common.domain.PageResult;
|
||||
import net.lab1024.sa.base.common.util.SmartPageUtil;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@Service
|
||||
public class AsnQueryServiceImpl implements AsnQueryService {
|
||||
|
||||
@Resource
|
||||
private AsnDao asnDao;
|
||||
|
||||
@Resource
|
||||
private AsnManager asnManager;
|
||||
|
||||
@Resource
|
||||
private CustomerQueryService customerQueryService;
|
||||
|
||||
@Resource
|
||||
private AddressQueryService addressQueryService;
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
*
|
||||
* @param queryForm 查询条件
|
||||
* @return PageResult<AsnVO>
|
||||
*/
|
||||
public PageResult<AsnVO> queryPage(AsnQueryForm queryForm) {
|
||||
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
|
||||
List<AsnVO> list = asnDao.queryPage(page, queryForm);
|
||||
|
||||
// 查询客户名称
|
||||
List<Long> customerIdList = list.stream().map(AsnVO::getCustomerId).toList();
|
||||
Map<Long, CustomerEntity> customerMap = customerQueryService.queryByCustomerIdsToMap(customerIdList);
|
||||
|
||||
// 查询收货单位
|
||||
List<Long> addressIdList = list.stream().map(AsnVO::getAddressId).toList();
|
||||
Map<Long, AddressEntity> addressMap = addressQueryService.queryByAddressIdsToMap(addressIdList);
|
||||
list.forEach(asnVO -> {
|
||||
CustomerEntity customer = customerMap.get(asnVO.getCustomerId());
|
||||
if (customer != null) {
|
||||
asnVO.setCustomerName(customer.getCustomerName());
|
||||
}
|
||||
AddressEntity address = addressMap.get(asnVO.getAddressId());
|
||||
if (address != null) {
|
||||
asnVO.setName(address.getName());
|
||||
}
|
||||
});
|
||||
return SmartPageUtil.convert2PageResult(page, list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据客户订单号查询入库单
|
||||
*
|
||||
* @param customerNumber 客户订单号
|
||||
* @return AsnEntity
|
||||
*/
|
||||
public AsnEntity queryByCustomerNumber(String customerNumber) {
|
||||
if (StringUtils.isBlank(customerNumber)) {
|
||||
return null;
|
||||
}
|
||||
LambdaQueryWrapper<AsnEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(AsnEntity::getCustomerNumber, customerNumber);
|
||||
return asnManager.getOne(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ids查询入库
|
||||
*
|
||||
* @param idList 入库集合
|
||||
* @return List<AsnEntity>
|
||||
*/
|
||||
public List<AsnEntity> queryByAsnIds(List<Long> idList) {
|
||||
if (CollectionUtils.isEmpty(idList)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
//去重
|
||||
idList = idList.stream().filter(Objects::nonNull).distinct().toList();
|
||||
return asnManager.listByIds(idList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据入库单集合查询入库单信息
|
||||
*
|
||||
* @param idList 入库单集合
|
||||
* @return Map<String, AsnEntity>
|
||||
*/
|
||||
public Map<Long, AsnEntity> queryByAsnIdsToMap(List<Long> idList) {
|
||||
if (CollectionUtils.isEmpty(idList)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
//查询入库单
|
||||
List<AsnEntity> asnList = queryByAsnIds(idList);
|
||||
//封装map
|
||||
Map<Long, AsnEntity> asnMap = Maps.newHashMap();
|
||||
for (AsnEntity asn : asnList) {
|
||||
asnMap.put(asn.getAsnId(), asn);
|
||||
}
|
||||
return asnMap;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
package net.lab1024.sa.admin.module.business.wms.receive.asn.service.impl;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.constant.AsnOrderStatusEnum;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.dao.AsnDao;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.domain.entity.AsnEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.domain.form.AsnAddForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.domain.form.AsnUpdateForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.manager.AsnManager;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.service.AsnQueryService;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.service.AsnService;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.entity.AsnDetailEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.manager.AsnDetailManager;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.service.AsnDetailQueryService;
|
||||
import net.lab1024.sa.admin.util.JoinerResult;
|
||||
import net.lab1024.sa.admin.util.ResponseDTOUtil;
|
||||
import net.lab1024.sa.base.common.code.UserErrorCode;
|
||||
import net.lab1024.sa.base.common.domain.ResponseDTO;
|
||||
import net.lab1024.sa.base.common.exception.BusinessException;
|
||||
import net.lab1024.sa.base.common.util.SmartBeanUtil;
|
||||
import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerTypeEnum;
|
||||
import net.lab1024.sa.base.module.support.datatracer.service.DataTracerService;
|
||||
import net.lab1024.sa.base.module.support.serialnumber.constant.SerialNumberIdEnum;
|
||||
import net.lab1024.sa.base.module.support.serialnumber.service.SerialNumberService;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class AsnServiceImpl implements AsnService {
|
||||
|
||||
@Resource
|
||||
private AsnManager asnManager;
|
||||
|
||||
@Resource
|
||||
private AsnDetailManager asnDetailManager;
|
||||
|
||||
@Resource
|
||||
private AsnQueryService asnQueryService;
|
||||
|
||||
@Resource
|
||||
private AsnDetailQueryService asnDetailQueryService;
|
||||
|
||||
@Resource
|
||||
private SerialNumberService serialNumberService;
|
||||
|
||||
@Resource
|
||||
private DataTracerService dataTracerService;
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param addForm 添加参数
|
||||
* @return ResponseDTO<String>
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<AsnEntity> add(AsnAddForm addForm) {
|
||||
AsnEntity exitAsn = asnQueryService.queryByCustomerNumber(addForm.getCustomerNumber());
|
||||
if (exitAsn != null) {
|
||||
throw new BusinessException(addForm.getCustomerNumber() + "客户订单号已存在");
|
||||
}
|
||||
//自动生成入库编号
|
||||
addForm.setAsnNumber(serialNumberService.generate(SerialNumberIdEnum.ASN));
|
||||
//默认已创建
|
||||
addForm.setStatus(AsnOrderStatusEnum.CREATED.getValue());
|
||||
AsnEntity asnEntity = SmartBeanUtil.copy(addForm, AsnEntity.class);
|
||||
asnManager.save(asnEntity);
|
||||
|
||||
//操作记录
|
||||
dataTracerService.addTrace(asnEntity.getAsnId(), DataTracerTypeEnum.ASN, "新建入库单:" + asnEntity.getAsnNumber(), null, asnEntity);
|
||||
return ResponseDTO.ok(asnEntity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新
|
||||
*
|
||||
* @param updateForm 更新参数
|
||||
* @return ResponseDTO<String>
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<AsnEntity> update(AsnUpdateForm updateForm) {
|
||||
AsnEntity exitAsn = asnQueryService.queryByCustomerNumber(updateForm.getCustomerNumber());
|
||||
if (exitAsn != null && !exitAsn.getAsnId().equals(updateForm.getAsnId())) {
|
||||
throw new BusinessException(updateForm.getCustomerNumber() + "客户订单号已存在");
|
||||
}
|
||||
AsnEntity asnEntity = SmartBeanUtil.copy(updateForm, AsnEntity.class);
|
||||
asnManager.updateById(asnEntity);
|
||||
//业务操作记录
|
||||
dataTracerService.addTrace(updateForm.getAsnId(), DataTracerTypeEnum.ASN, "编辑入库单:" + asnEntity.getAsnNumber(), exitAsn, asnEntity);
|
||||
return ResponseDTO.ok(asnEntity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param idList 入库单id集合
|
||||
* @return ResponseDTO<String>
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<String> batchDelete(List<Long> idList) {
|
||||
if (CollectionUtils.isEmpty(idList)) {
|
||||
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
|
||||
}
|
||||
JoinerResult resultMsg = JoinerResult.createJoiner();
|
||||
|
||||
//查询批量订单
|
||||
List<AsnEntity> asnList = asnQueryService.queryByAsnIds(idList);
|
||||
|
||||
//将订单按状态分组;已创建的一组;非已创建的一组。
|
||||
Map<Boolean, List<AsnEntity>> partitionedAsnList = asnList.stream()
|
||||
.collect(Collectors.partitioningBy(asn -> AsnOrderStatusEnum.CREATED.getValue().equals(asn.getStatus())));
|
||||
//已创建的订单允许删除
|
||||
List<AsnEntity> createAsnList = partitionedAsnList.get(true);
|
||||
//入库单集合
|
||||
List<Long> asnIds = createAsnList.stream().map(AsnEntity::getAsnId).toList();
|
||||
//根据入库单ID集合查询入库明细
|
||||
List<AsnDetailEntity> details = asnDetailQueryService.queryAsnDetailByAsnIds(asnIds);
|
||||
if (CollectionUtils.isNotEmpty(details)) {
|
||||
asnDetailManager.removeBatchByIds(details);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(createAsnList)) {
|
||||
Set<String> asnCodes = createAsnList.stream().map(AsnEntity::getAsnNumber).collect(Collectors.toSet());
|
||||
asnManager.removeBatchByIds(createAsnList);
|
||||
resultMsg.getSussMsg().add(asnCodes + "订单删除成功");
|
||||
}
|
||||
|
||||
//非已创建的订单不允许删除
|
||||
List<AsnEntity> noCreateAsnList = partitionedAsnList.get(false);
|
||||
if (CollectionUtils.isNotEmpty(noCreateAsnList)) {
|
||||
Set<String> asnCodes = noCreateAsnList.stream().map(AsnEntity::getAsnNumber).collect(Collectors.toSet());
|
||||
resultMsg.getErrorMsg().add(asnCodes + "订单不允许删除");
|
||||
}
|
||||
|
||||
return ResponseDTOUtil.buildResponseDTO(resultMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 单个删除
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<String> delete(Long asnId) {
|
||||
if (asnId == null) {
|
||||
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
|
||||
}
|
||||
AsnEntity asn = asnManager.getById(asnId);
|
||||
String status = asn.getStatus();
|
||||
// 只有已创建的订单才允许删除
|
||||
if (!AsnOrderStatusEnum.CREATED.getValue().equals(status)) {
|
||||
return ResponseDTO.userErrorParam(AsnOrderStatusEnum.getDescByValue(status) + "的订单不允许删除");
|
||||
}
|
||||
List<AsnDetailEntity> details = asnDetailQueryService.queryAsnDetailByAsnId(asnId);
|
||||
if (CollectionUtils.isNotEmpty(details)) {
|
||||
asnDetailManager.removeBatchByIds(details);
|
||||
}
|
||||
asnManager.removeById(asnId);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
}
|
||||
|
|
@ -4,13 +4,6 @@ import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.form.As
|
|||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.form.AsnDetailQueryForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.form.AsnDetailUpdateForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.vo.AsnDetailVO;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.service.AsnDetailQueryService;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.service.AsnDetailService;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.form.AsnDetailAddForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.form.AsnDetailQueryForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.form.AsnDetailUpdateForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.vo.AsnDetailVO;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.service.AsnDetailQueryService;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.service.AsnDetailService;
|
||||
import net.lab1024.sa.base.common.domain.RequestUser;
|
||||
import net.lab1024.sa.base.common.domain.ValidateList;
|
||||
|
|
@ -40,14 +33,13 @@ public class AsnDetailController {
|
|||
@Resource
|
||||
private AsnDetailService asnDetailService;
|
||||
|
||||
@Resource
|
||||
private AsnDetailQueryService asnDetailQueryService;
|
||||
|
||||
|
||||
@Operation(summary = "分页查询 @author 霍锦")
|
||||
@PostMapping("/asnDetail/queryPage")
|
||||
@SaCheckPermission("asnDetail:query")
|
||||
public ResponseDTO<PageResult<AsnDetailVO>> queryPage(@RequestBody @Valid AsnDetailQueryForm queryForm) {
|
||||
return ResponseDTO.ok(asnDetailQueryService.queryPage(queryForm));
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
@Operation(summary = "添加 @author 霍锦")
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@ import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.entity.
|
|||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.dao.AsnDetailDao;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.dao.AsnDetailDao;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.entity.AsnDetailEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,66 +1,22 @@
|
|||
package net.lab1024.sa.admin.module.business.wms.receive.asnDetail.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import jakarta.annotation.Resource;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.address.domain.entity.AddressEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.area.domain.entity.AreaEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.customer.domain.entity.CustomerEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.item.domain.entity.ItemEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.item.manager.ItemManager;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.item.service.ItemQueryService;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.location.domain.entity.LocationEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.location.domain.vo.LocationVO;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.domain.vo.AsnVO;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.dao.AsnDetailDao;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.entity.AsnDetailEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.form.AsnDetailQueryForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.vo.AsnDetailVO;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.manager.AsnDetailManager;
|
||||
import net.lab1024.sa.base.common.domain.PageResult;
|
||||
import net.lab1024.sa.base.common.util.SmartPageUtil;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class AsnDetailQueryService {
|
||||
|
||||
@Resource
|
||||
private AsnDetailDao asnDetailDao;
|
||||
|
||||
@Resource
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Resource
|
||||
private ItemQueryService itemQueryService;
|
||||
|
||||
public interface AsnDetailQueryService {
|
||||
/**
|
||||
* 分页查询
|
||||
*
|
||||
* @param queryForm 查询条件
|
||||
* @return PageResult<AsnDetailVO>
|
||||
*/
|
||||
public PageResult<AsnDetailVO> queryPage(AsnDetailQueryForm queryForm) {
|
||||
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
|
||||
List<AsnDetailVO> list = asnDetailDao.queryPage(page, queryForm);
|
||||
// 查询物料名称
|
||||
List<Long> itemIdList = list.stream().map(AsnDetailVO::getItemId).distinct().collect(Collectors.toList());
|
||||
Map<Long, ItemEntity> itemMap = itemQueryService.queryItemList(itemIdList);
|
||||
list.forEach(asnDetailVO -> {
|
||||
ItemEntity item = itemMap.get(asnDetailVO.getItemId());
|
||||
if (item != null) {
|
||||
asnDetailVO.setItemCode(item.getItemCode());
|
||||
asnDetailVO.setItemName(item.getItemName());
|
||||
}
|
||||
});
|
||||
|
||||
return SmartPageUtil.convert2PageResult(page, list);
|
||||
}
|
||||
PageResult<AsnDetailVO> queryPage(AsnDetailQueryForm queryForm);
|
||||
|
||||
/**
|
||||
* 根据入库单id查询入库单详情
|
||||
|
|
@ -68,14 +24,7 @@ public class AsnDetailQueryService {
|
|||
* @param asnId 入库单id
|
||||
* @return List<AsnDetailEntity>
|
||||
*/
|
||||
public List<AsnDetailEntity> queryByAsnId(Long asnId) {
|
||||
if (asnId == null) {
|
||||
return null;
|
||||
}
|
||||
LambdaQueryWrapper<AsnDetailEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(AsnDetailEntity::getAsnId, asnId);
|
||||
return asnDetailDao.selectList(queryWrapper);
|
||||
}
|
||||
List<AsnDetailEntity> queryAsnDetailByAsnId(Long asnId);
|
||||
|
||||
/**
|
||||
* 根据入库单ids查询入库单详情
|
||||
|
|
@ -83,14 +32,7 @@ public class AsnDetailQueryService {
|
|||
* @param asnIds 入库单id
|
||||
* @return List<AsnDetailEntity>
|
||||
*/
|
||||
public List<AsnDetailEntity> queryByAsnIds(List<Long> asnIds) {
|
||||
if (CollectionUtils.isEmpty(asnIds)) {
|
||||
return null;
|
||||
}
|
||||
LambdaQueryWrapper<AsnDetailEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.in(AsnDetailEntity::getAsnId, asnIds);
|
||||
return asnDetailDao.selectList(queryWrapper);
|
||||
}
|
||||
List<AsnDetailEntity> queryAsnDetailByAsnIds(List<Long> asnIds);
|
||||
|
||||
/**
|
||||
* 根据ids查询入库明细
|
||||
|
|
@ -98,12 +40,7 @@ public class AsnDetailQueryService {
|
|||
* @param idList 入库明细集合
|
||||
* @return List<AsnDetailEntity>
|
||||
*/
|
||||
public List<AsnDetailEntity> queryAsnDetailList(List<Long> idList) {
|
||||
if (CollectionUtils.isEmpty(idList)) {
|
||||
return null;
|
||||
}
|
||||
return asnDetailDao.selectBatchIds(idList);
|
||||
}
|
||||
List<AsnDetailEntity> queryByAsnDetailIds(List<Long> idList);
|
||||
|
||||
/**
|
||||
* 根据明细集合查询明细信息
|
||||
|
|
@ -111,13 +48,5 @@ public class AsnDetailQueryService {
|
|||
* @param idList 明细集合
|
||||
* @return Map<String, AsnDetailEntity>
|
||||
*/
|
||||
public Map<Long, AsnDetailEntity> queryAsnDetailListToMap(List<Long> idList) {
|
||||
if (CollectionUtils.isEmpty(idList)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
List<AsnDetailEntity> asnDetails = queryAsnDetailList(idList);
|
||||
return asnDetails.stream()
|
||||
.collect(Collectors.toMap(AsnDetailEntity::getAsnDetailId, asnDetail -> asnDetail, (existing, replacement) -> existing));
|
||||
|
||||
}
|
||||
Map<Long, AsnDetailEntity> queryByAsnDetailIdsToMap(List<Long> idList);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,33 +1,10 @@
|
|||
package net.lab1024.sa.admin.module.business.wms.receive.asnDetail.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.lab1024.sa.admin.module.business.wms.base.item.dao.ItemDao;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.item.domain.entity.ItemEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.item.service.ItemQueryService;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.constant.AsnOrderStatusEnum;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.dao.AsnDao;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.domain.entity.AsnEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.dao.AsnDetailDao;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.entity.AsnDetailEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.form.AsnDetailAddForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.form.AsnDetailUpdateForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.manager.AsnDetailManager;
|
||||
import net.lab1024.sa.admin.util.JoinerResult;
|
||||
import net.lab1024.sa.admin.util.ResponseDTOUtil;
|
||||
import net.lab1024.sa.base.common.code.UserErrorCode;
|
||||
import net.lab1024.sa.base.common.util.SmartBeanUtil;
|
||||
import net.lab1024.sa.base.common.domain.ResponseDTO;
|
||||
import net.lab1024.sa.base.common.util.SmartBigDecimalUtil;
|
||||
import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerTypeEnum;
|
||||
import net.lab1024.sa.base.module.support.datatracer.service.DataTracerService;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* 入库明细 Service
|
||||
|
|
@ -36,31 +13,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
* @since 2025-03-26 15:16:28
|
||||
* copyright 友仓
|
||||
*/
|
||||
|
||||
@Service
|
||||
public class AsnDetailService {
|
||||
|
||||
@Resource
|
||||
private AsnDao asnDao;
|
||||
|
||||
@Resource
|
||||
private ItemDao itemDao;
|
||||
|
||||
@Resource
|
||||
private AsnDetailDao asnDetailDao;
|
||||
|
||||
@Resource
|
||||
private AsnDetailManager asnDetailManager;
|
||||
|
||||
@Resource
|
||||
private ItemQueryService itemQueryService;
|
||||
|
||||
@Resource
|
||||
private AsnDetailQueryService asnDetailQueryService;
|
||||
|
||||
@Resource
|
||||
private DataTracerService dataTracerService;
|
||||
|
||||
public interface AsnDetailService {
|
||||
|
||||
/**
|
||||
* 添加
|
||||
|
|
@ -68,21 +21,7 @@ public class AsnDetailService {
|
|||
* @param addForm 添加表单
|
||||
* @return ResponseDTO<String>
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<String> add(AsnDetailAddForm addForm) {
|
||||
AsnDetailEntity asnDetailEntity = SmartBeanUtil.copy(addForm, AsnDetailEntity.class);
|
||||
asnDetailDao.insert(asnDetailEntity);
|
||||
|
||||
//刷新出库单
|
||||
refreshAsn(addForm.getAsnId());
|
||||
|
||||
//业务操作记录
|
||||
ItemEntity item = itemDao.selectById(addForm.getItemId());
|
||||
dataTracerService.addTrace(asnDetailEntity.getAsnId(), DataTracerTypeEnum.ASN, "添加:" + item.getItemCode() + "物料明细", null, asnDetailEntity);
|
||||
|
||||
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
ResponseDTO<String> add(AsnDetailAddForm addForm);
|
||||
|
||||
/**
|
||||
* 更新
|
||||
|
|
@ -90,21 +29,7 @@ public class AsnDetailService {
|
|||
* @param updateForm 更新表单
|
||||
* @return ResponseDTO<String>
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<String> update(AsnDetailUpdateForm updateForm) {
|
||||
AsnDetailEntity originEntity = asnDetailDao.selectById(updateForm.getAsnDetailId());
|
||||
AsnDetailEntity asnDetailEntity = SmartBeanUtil.copy(updateForm, AsnDetailEntity.class);
|
||||
asnDetailDao.updateById(asnDetailEntity);
|
||||
|
||||
ItemEntity item = itemDao.selectById(updateForm.getItemId());
|
||||
|
||||
//刷新出库单
|
||||
refreshAsn(updateForm.getAsnId());
|
||||
|
||||
dataTracerService.addTrace(asnDetailEntity.getAsnId(), DataTracerTypeEnum.ASN, "编辑:" + item.getItemCode() + "物料明细", originEntity, asnDetailEntity);
|
||||
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
ResponseDTO<String> update(AsnDetailUpdateForm updateForm);
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
|
|
@ -113,40 +38,7 @@ public class AsnDetailService {
|
|||
* @return ResponseDTO<String>
|
||||
*/
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<String> batchDelete(List<Long> idList) {
|
||||
if (CollectionUtils.isEmpty(idList)) {
|
||||
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
|
||||
}
|
||||
JoinerResult resultMsg = JoinerResult.createJoiner();
|
||||
List<AsnDetailEntity> asnDetails = asnDetailQueryService.queryAsnDetailList(idList);
|
||||
List<Long> asnIds = asnDetails.stream().map(AsnDetailEntity::getAsnId).distinct().collect(Collectors.toList());
|
||||
List<Long> itemIds = asnDetails.stream().map(AsnDetailEntity::getItemId).toList();
|
||||
Map<Long, ItemEntity> mapItem = itemQueryService.queryItemList(itemIds);
|
||||
|
||||
List<Long> toDeleteList = new ArrayList<>();
|
||||
for (AsnDetailEntity asnDetail : asnDetails) {
|
||||
ItemEntity item = mapItem.get(asnDetail.getItemId());
|
||||
if (asnDetail.getReceivedQuantity().compareTo(BigDecimal.ZERO) > 0) {
|
||||
resultMsg.getErrorMsg().add(item.getItemCode() + "明细已收货");
|
||||
continue;
|
||||
}
|
||||
toDeleteList.add(asnDetail.getAsnDetailId());
|
||||
resultMsg.getSussMsg().add(item.getItemCode() + "明细删除成功");
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(toDeleteList)) {
|
||||
//批量删除
|
||||
asnDetailManager.removeBatchByIds(toDeleteList);
|
||||
//操作记录
|
||||
dataTracerService.addTrace(asnIds.get(0), DataTracerTypeEnum.ASN, "批量删除:" + resultMsg.getSussMsg().toString()+ resultMsg.getErrorMsg().toString());
|
||||
}
|
||||
|
||||
//刷新出库单
|
||||
asnIds.forEach(this::refreshAsn);
|
||||
|
||||
return ResponseDTOUtil.buildResponseDTO(resultMsg);
|
||||
}
|
||||
ResponseDTO<String> batchDelete(List<Long> idList);
|
||||
|
||||
/**
|
||||
* 单个删除
|
||||
|
|
@ -154,60 +46,12 @@ public class AsnDetailService {
|
|||
* @param asnDetailId id
|
||||
* @return ResponseDTO<String>
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<String> delete(Long asnDetailId) {
|
||||
if (null == asnDetailId) {
|
||||
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
|
||||
}
|
||||
JoinerResult resultMsg = JoinerResult.createJoiner();
|
||||
AsnDetailEntity asnDetail = asnDetailDao.selectById(asnDetailId);
|
||||
ItemEntity item = itemDao.selectById(asnDetail.getItemId());
|
||||
if (asnDetail.getReceivedQuantity().compareTo(BigDecimal.ZERO) > 0) {
|
||||
resultMsg.getErrorMsg().add(item.getItemCode() + "明细已收货");
|
||||
return ResponseDTOUtil.buildResponseDTO(resultMsg);
|
||||
}
|
||||
ResponseDTO<String> delete(Long asnDetailId);
|
||||
|
||||
Long asnId = asnDetail.getAsnId();
|
||||
asnDetailDao.deleteById(asnDetailId);
|
||||
resultMsg.getSussMsg().add(item.getItemCode() + "删除成功");
|
||||
|
||||
//刷新出库单
|
||||
refreshAsn(asnId);
|
||||
|
||||
//操作记录
|
||||
dataTracerService.addTrace(asnId, DataTracerTypeEnum.ASN, "删除:" + resultMsg.getSussMsg().toString()+ resultMsg.getErrorMsg().toString());
|
||||
|
||||
|
||||
return ResponseDTOUtil.buildResponseDTO(resultMsg);
|
||||
}
|
||||
|
||||
public void refreshAsn(Long asnId) {
|
||||
//入库单
|
||||
AsnEntity asn = asnDao.selectById(asnId);
|
||||
|
||||
//获取订单明细
|
||||
List<AsnDetailEntity> asnDetails = asnDetailQueryService.queryByAsnId(asnId);
|
||||
|
||||
//订单数量
|
||||
BigDecimal orderQuantity = asnDetails.stream().map(AsnDetailEntity::getOrderQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
//收货数量
|
||||
BigDecimal receivedQuantity = asnDetails.stream().map(AsnDetailEntity::getReceivedQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
//当前状态
|
||||
String status = asn.getStatus();
|
||||
if (orderQuantity.compareTo(BigDecimal.ZERO) >= 0 && receivedQuantity.compareTo(BigDecimal.ZERO) == 0) {
|
||||
status = AsnOrderStatusEnum.CREATED.getValue();
|
||||
} else if (SmartBigDecimalUtil.subtract(orderQuantity, receivedQuantity, 2).compareTo(BigDecimal.ZERO) > 0) {
|
||||
status = AsnOrderStatusEnum.IN_PROGRESS.getValue();
|
||||
} else if (SmartBigDecimalUtil.subtract(orderQuantity, receivedQuantity, 2).compareTo(BigDecimal.ZERO) == 0 && receivedQuantity.compareTo(BigDecimal.ZERO) > 0) {
|
||||
status = AsnOrderStatusEnum.COMPLETED.getValue();
|
||||
}
|
||||
|
||||
asn.setOrderQuantity(orderQuantity);
|
||||
asn.setReceivedQuantity(receivedQuantity);
|
||||
asn.setStatus(status);
|
||||
asnDao.updateById(asn);
|
||||
|
||||
}
|
||||
/**
|
||||
* 刷新入库单
|
||||
*
|
||||
* @param asnId 入库单id
|
||||
*/
|
||||
void refreshAsn(Long asnId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,126 @@
|
|||
package net.lab1024.sa.admin.module.business.wms.receive.asnDetail.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.google.common.collect.Maps;
|
||||
import jakarta.annotation.Resource;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.item.domain.entity.ItemEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.item.service.ItemQueryService;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.dao.AsnDetailDao;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.entity.AsnDetailEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.form.AsnDetailQueryForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.vo.AsnDetailVO;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.manager.AsnDetailManager;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.service.AsnDetailQueryService;
|
||||
import net.lab1024.sa.base.common.domain.PageResult;
|
||||
import net.lab1024.sa.base.common.util.SmartPageUtil;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@Service
|
||||
public class AsnDetailQueryServiceImpl implements AsnDetailQueryService {
|
||||
|
||||
@Resource
|
||||
private AsnDetailDao asnDetailDao;
|
||||
|
||||
@Resource
|
||||
private AsnDetailManager asnDetailManager;
|
||||
|
||||
@Resource
|
||||
private ItemQueryService itemQueryService;
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
*
|
||||
* @param queryForm 查询条件
|
||||
* @return PageResult<AsnDetailVO>
|
||||
*/
|
||||
public PageResult<AsnDetailVO> queryPage(AsnDetailQueryForm queryForm) {
|
||||
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
|
||||
List<AsnDetailVO> list = asnDetailDao.queryPage(page, queryForm);
|
||||
// 查询物料名称
|
||||
List<Long> itemIdList = list.stream().map(AsnDetailVO::getItemId).toList();
|
||||
Map<Long, ItemEntity> itemMap = itemQueryService.queryByItemIdsToMap(itemIdList);
|
||||
list.forEach(asnDetailVO -> {
|
||||
ItemEntity item = itemMap.get(asnDetailVO.getItemId());
|
||||
if (item != null) {
|
||||
asnDetailVO.setItemCode(item.getItemCode());
|
||||
asnDetailVO.setItemName(item.getItemName());
|
||||
}
|
||||
});
|
||||
|
||||
return SmartPageUtil.convert2PageResult(page, list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据入库单id查询入库单详情
|
||||
*
|
||||
* @param asnId 入库单id
|
||||
* @return List<AsnDetailEntity>
|
||||
*/
|
||||
public List<AsnDetailEntity> queryAsnDetailByAsnId(Long asnId) {
|
||||
if (asnId == null) {
|
||||
return null;
|
||||
}
|
||||
LambdaQueryWrapper<AsnDetailEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(AsnDetailEntity::getAsnId, asnId);
|
||||
return asnDetailManager.list(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据入库单ids查询入库单详情
|
||||
*
|
||||
* @param asnIds 入库单id
|
||||
* @return List<AsnDetailEntity>
|
||||
*/
|
||||
public List<AsnDetailEntity> queryAsnDetailByAsnIds(List<Long> asnIds) {
|
||||
if (CollectionUtils.isEmpty(asnIds)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
//去重
|
||||
asnIds = asnIds.stream().filter(Objects::nonNull).distinct().toList();
|
||||
LambdaQueryWrapper<AsnDetailEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.in(AsnDetailEntity::getAsnId, asnIds);
|
||||
return asnDetailManager.list(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ids查询入库明细
|
||||
*
|
||||
* @param idList 入库明细集合
|
||||
* @return List<AsnDetailEntity>
|
||||
*/
|
||||
public List<AsnDetailEntity> queryByAsnDetailIds(List<Long> idList) {
|
||||
if (CollectionUtils.isEmpty(idList)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
//去重
|
||||
idList = idList.stream().filter(Objects::nonNull).distinct().toList();
|
||||
return asnDetailManager.listByIds(idList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据明细集合查询明细信息
|
||||
*
|
||||
* @param idList 明细集合
|
||||
* @return Map<String, AsnDetailEntity>
|
||||
*/
|
||||
public Map<Long, AsnDetailEntity> queryByAsnDetailIdsToMap(List<Long> idList) {
|
||||
if (CollectionUtils.isEmpty(idList)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
//查询明细
|
||||
List<AsnDetailEntity> asnDetails = queryByAsnDetailIds(idList);
|
||||
//封装map
|
||||
Map<Long, AsnDetailEntity> asnDetailMap = Maps.newHashMap();
|
||||
for (AsnDetailEntity asnDetail : asnDetails) {
|
||||
asnDetailMap.put(asnDetail.getAsnDetailId(), asnDetail);
|
||||
}
|
||||
return asnDetailMap;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,206 @@
|
|||
package net.lab1024.sa.admin.module.business.wms.receive.asnDetail.service.impl;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.item.domain.entity.ItemEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.item.manager.ItemManager;
|
||||
import net.lab1024.sa.admin.module.business.wms.base.item.service.ItemQueryService;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.constant.AsnOrderStatusEnum;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.domain.entity.AsnEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.manager.AsnManager;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.entity.AsnDetailEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.form.AsnDetailAddForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.form.AsnDetailUpdateForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.manager.AsnDetailManager;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.service.AsnDetailQueryService;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.service.AsnDetailService;
|
||||
import net.lab1024.sa.admin.util.JoinerResult;
|
||||
import net.lab1024.sa.admin.util.ResponseDTOUtil;
|
||||
import net.lab1024.sa.base.common.code.UserErrorCode;
|
||||
import net.lab1024.sa.base.common.domain.ResponseDTO;
|
||||
import net.lab1024.sa.base.common.util.SmartBeanUtil;
|
||||
import net.lab1024.sa.base.common.util.SmartBigDecimalUtil;
|
||||
import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerTypeEnum;
|
||||
import net.lab1024.sa.base.module.support.datatracer.service.DataTracerService;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@Service
|
||||
public class AsnDetailServiceImpl implements AsnDetailService {
|
||||
|
||||
@Resource
|
||||
private AsnManager asnManager;
|
||||
|
||||
@Resource
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Resource
|
||||
private AsnDetailManager asnDetailManager;
|
||||
|
||||
@Resource
|
||||
private ItemQueryService itemQueryService;
|
||||
|
||||
@Resource
|
||||
private AsnDetailQueryService asnDetailQueryService;
|
||||
|
||||
@Resource
|
||||
private DataTracerService dataTracerService;
|
||||
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param addForm 添加表单
|
||||
* @return ResponseDTO<String>
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<String> add(AsnDetailAddForm addForm) {
|
||||
AsnDetailEntity asnDetailEntity = SmartBeanUtil.copy(addForm, AsnDetailEntity.class);
|
||||
asnDetailManager.save(asnDetailEntity);
|
||||
|
||||
//刷新出库单
|
||||
refreshAsn(addForm.getAsnId());
|
||||
|
||||
//业务操作记录
|
||||
ItemEntity item = itemManager.queryItem(addForm.getItemId());
|
||||
dataTracerService.addTrace(asnDetailEntity.getAsnId(), DataTracerTypeEnum.ASN, "添加:" + item.getItemCode() + "物料明细", null, asnDetailEntity);
|
||||
|
||||
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新
|
||||
*
|
||||
* @param updateForm 更新表单
|
||||
* @return ResponseDTO<String>
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<String> update(AsnDetailUpdateForm updateForm) {
|
||||
AsnDetailEntity originEntity = asnDetailManager.getById(updateForm.getAsnDetailId());
|
||||
AsnDetailEntity asnDetailEntity = SmartBeanUtil.copy(updateForm, AsnDetailEntity.class);
|
||||
asnDetailManager.updateById(asnDetailEntity);
|
||||
|
||||
//刷新出库单
|
||||
refreshAsn(updateForm.getAsnId());
|
||||
|
||||
ItemEntity item = itemManager.queryItem(updateForm.getItemId());
|
||||
dataTracerService.addTrace(asnDetailEntity.getAsnId(), DataTracerTypeEnum.ASN, "编辑:" + item.getItemCode() + "物料明细", originEntity, asnDetailEntity);
|
||||
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param idList id集合
|
||||
* @return ResponseDTO<String>
|
||||
*/
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<String> batchDelete(List<Long> idList) {
|
||||
if (CollectionUtils.isEmpty(idList)) {
|
||||
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
|
||||
}
|
||||
JoinerResult resultMsg = JoinerResult.createJoiner();
|
||||
//查询入库明细
|
||||
List<AsnDetailEntity> asnDetails = asnDetailQueryService.queryByAsnDetailIds(idList);
|
||||
//获取入库明细去重后的入库单D集合
|
||||
List<Long> asnIds = asnDetails.stream().filter(Objects::nonNull).map(AsnDetailEntity::getAsnId).distinct().toList();
|
||||
//获取物料id集合
|
||||
List<Long> itemIds = asnDetails.stream().map(AsnDetailEntity::getItemId).toList();
|
||||
//查询物料
|
||||
Map<Long, ItemEntity> mapItem = itemQueryService.queryByItemIdsToMap(itemIds);
|
||||
List<Long> toDeleteList = new ArrayList<>();
|
||||
for (AsnDetailEntity asnDetail : asnDetails) {
|
||||
ItemEntity item = mapItem.get(asnDetail.getItemId());
|
||||
if (asnDetail.getReceivedQuantity().compareTo(BigDecimal.ZERO) > 0) {
|
||||
resultMsg.getErrorMsg().add(item.getItemCode() + "明细已收货");
|
||||
continue;
|
||||
}
|
||||
toDeleteList.add(asnDetail.getAsnDetailId());
|
||||
resultMsg.getSussMsg().add(item.getItemCode() + "明细删除成功");
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(toDeleteList)) {
|
||||
//批量删除
|
||||
asnDetailManager.removeBatchByIds(toDeleteList);
|
||||
//操作记录
|
||||
dataTracerService.addTrace(asnIds.get(0), DataTracerTypeEnum.ASN, "批量删除:" + resultMsg.getSussMsg().toString() + resultMsg.getErrorMsg().toString());
|
||||
}
|
||||
|
||||
//刷新出库单
|
||||
asnIds.forEach(this::refreshAsn);
|
||||
|
||||
return ResponseDTOUtil.buildResponseDTO(resultMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 单个删除
|
||||
*
|
||||
* @param asnDetailId id
|
||||
* @return ResponseDTO<String>
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<String> delete(Long asnDetailId) {
|
||||
if (null == asnDetailId) {
|
||||
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
|
||||
}
|
||||
JoinerResult resultMsg = JoinerResult.createJoiner();
|
||||
AsnDetailEntity asnDetail = asnDetailManager.getById(asnDetailId);
|
||||
ItemEntity item = itemManager.queryItem(asnDetail.getItemId());
|
||||
if (asnDetail.getReceivedQuantity().compareTo(BigDecimal.ZERO) > 0) {
|
||||
resultMsg.getErrorMsg().add(item.getItemCode() + "明细已收货");
|
||||
return ResponseDTOUtil.buildResponseDTO(resultMsg);
|
||||
}
|
||||
|
||||
Long asnId = asnDetail.getAsnId();
|
||||
asnDetailManager.removeById(asnDetailId);
|
||||
resultMsg.getSussMsg().add(item.getItemCode() + "删除成功");
|
||||
|
||||
//刷新出库单
|
||||
refreshAsn(asnId);
|
||||
|
||||
//操作记录
|
||||
dataTracerService.addTrace(asnId, DataTracerTypeEnum.ASN, "删除:" + resultMsg.getSussMsg().toString() + resultMsg.getErrorMsg().toString());
|
||||
|
||||
|
||||
return ResponseDTOUtil.buildResponseDTO(resultMsg);
|
||||
}
|
||||
|
||||
public void refreshAsn(Long asnId) {
|
||||
//入库单
|
||||
AsnEntity asn = asnManager.getById(asnId);
|
||||
|
||||
//获取订单明细
|
||||
List<AsnDetailEntity> asnDetails = asnDetailQueryService.queryAsnDetailByAsnId(asnId);
|
||||
|
||||
//订单数量
|
||||
BigDecimal orderQuantity = asnDetails.stream().map(AsnDetailEntity::getOrderQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
//收货数量
|
||||
BigDecimal receivedQuantity = asnDetails.stream().map(AsnDetailEntity::getReceivedQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
//当前状态
|
||||
String status = asn.getStatus();
|
||||
if (orderQuantity.compareTo(BigDecimal.ZERO) >= 0 && receivedQuantity.compareTo(BigDecimal.ZERO) == 0) {
|
||||
status = AsnOrderStatusEnum.CREATED.getValue();
|
||||
} else if (SmartBigDecimalUtil.subtract(orderQuantity, receivedQuantity, 2).compareTo(BigDecimal.ZERO) > 0) {
|
||||
status = AsnOrderStatusEnum.IN_PROGRESS.getValue();
|
||||
} else if (SmartBigDecimalUtil.subtract(orderQuantity, receivedQuantity, 2).compareTo(BigDecimal.ZERO) == 0 && receivedQuantity.compareTo(BigDecimal.ZERO) > 0) {
|
||||
status = AsnOrderStatusEnum.COMPLETED.getValue();
|
||||
}
|
||||
|
||||
asn.setOrderQuantity(orderQuantity);
|
||||
asn.setReceivedQuantity(receivedQuantity);
|
||||
asn.setStatus(status);
|
||||
asnManager.updateById(asn);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
package net.lab1024.sa.admin.module.business.wms.receive;
|
||||
package net.lab1024.sa.admin.module.business.wms.receive.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.service.ReceiveService;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.domain.form.BatchReceiveForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.domain.form.BatchReturnForm;
|
||||
import net.lab1024.sa.base.common.domain.ResponseDTO;
|
||||
import net.lab1024.sa.base.common.domain.ValidateList;
|
||||
import net.lab1024.sa.base.module.support.operatelog.annotation.OperateLog;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package net.lab1024.sa.admin.module.business.wms.receive.service;
|
||||
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.domain.form.BatchReceiveForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.domain.form.BatchReturnForm;
|
||||
import net.lab1024.sa.base.common.domain.ResponseDTO;
|
||||
|
||||
public interface ReceiveService {
|
||||
|
||||
/**
|
||||
* 批量收货
|
||||
*
|
||||
* @param batchReceiveForm 批量收货参数
|
||||
* @return ResponseDTO<String>
|
||||
*/
|
||||
ResponseDTO<String> batchReceive(BatchReceiveForm batchReceiveForm);
|
||||
|
||||
/**
|
||||
* 批量退货
|
||||
*
|
||||
* @param batchReturnForm 批量退货参数
|
||||
* @return ResponseDTO<String>
|
||||
*/
|
||||
ResponseDTO<String> batchReturn(BatchReturnForm batchReturnForm);
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package net.lab1024.sa.admin.module.business.wms.receive;
|
||||
package net.lab1024.sa.admin.module.business.wms.receive.service.impl;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
|
@ -14,14 +14,15 @@ import net.lab1024.sa.admin.module.business.wms.inventory.service.InventoryQuery
|
|||
import net.lab1024.sa.admin.module.business.wms.inventory.service.InventoryService;
|
||||
import net.lab1024.sa.admin.module.business.wms.itemKey.domain.entity.ItemKeyEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.itemKey.service.ItemKeyService;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.dao.AsnDao;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.domain.entity.AsnEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.domain.form.BatchReceiveForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.domain.form.BatchReturnForm;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asn.manager.AsnManager;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.entity.AsnDetailEntity;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.manager.AsnDetailManager;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.service.AsnDetailQueryService;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.service.AsnDetailService;
|
||||
import net.lab1024.sa.admin.module.business.wms.receive.service.ReceiveService;
|
||||
import net.lab1024.sa.admin.module.business.wms.task.constant.TaskStatusEnum;
|
||||
import net.lab1024.sa.admin.module.business.wms.task.constant.TaskTypeEnum;
|
||||
import net.lab1024.sa.admin.module.business.wms.task.domain.entity.TaskEntity;
|
||||
|
|
@ -42,14 +43,16 @@ import org.springframework.stereotype.Service;
|
|||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class ReceiveService {
|
||||
public class ReceiveServiceImpl implements ReceiveService {
|
||||
@Resource
|
||||
private AsnDao asnDao;
|
||||
private AsnManager asnManager;
|
||||
|
||||
@Resource
|
||||
private AsnDetailManager asnDetailManager;
|
||||
|
|
@ -106,7 +109,7 @@ public class ReceiveService {
|
|||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseDTO<String> batchReceive(BatchReceiveForm batchReceiveForm) {
|
||||
Long startTime = System.currentTimeMillis();
|
||||
List<AsnDetailEntity> asnDetails = asnDetailQueryService.queryAsnDetailList(batchReceiveForm.getAsnDetailIds());
|
||||
List<AsnDetailEntity> asnDetails = asnDetailQueryService.queryByAsnDetailIds(batchReceiveForm.getAsnDetailIds());
|
||||
if (CollectionUtils.isEmpty(asnDetails)) {
|
||||
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
|
||||
}
|
||||
|
|
@ -114,8 +117,8 @@ public class ReceiveService {
|
|||
JoinerResult resultMsg = JoinerResult.createJoiner();
|
||||
|
||||
//查询物料
|
||||
List<Long> itemIds = asnDetails.stream().map(AsnDetailEntity::getItemId).distinct().toList();
|
||||
Map<Long, ItemEntity> itemMap = itemQueryService.queryItemList(itemIds);
|
||||
List<Long> itemIds = asnDetails.stream().map(AsnDetailEntity::getItemId).toList();
|
||||
Map<Long, ItemEntity> itemMap = itemQueryService.queryByItemIdsToMap(itemIds);
|
||||
|
||||
List<AsnDetailEntity> updateToAsnDetail = new ArrayList<>();
|
||||
List<TaskEntity> insertToTask = new ArrayList<>();
|
||||
|
|
@ -129,7 +132,7 @@ public class ReceiveService {
|
|||
StockEntity dstStock = stockQueryService.queryByStockCode(batchReceiveForm.getStockCode());
|
||||
|
||||
//入库单
|
||||
AsnEntity asn = asnDao.selectById(batchReceiveForm.getAsnId());
|
||||
AsnEntity asn = asnManager.getById(batchReceiveForm.getAsnId());
|
||||
|
||||
for (AsnDetailEntity asnDetail : asnDetails) {
|
||||
//物料
|
||||
|
|
@ -163,7 +166,7 @@ public class ReceiveService {
|
|||
insertToTask.add(task);
|
||||
|
||||
//生成库存记录
|
||||
InventoryEntity inventory = inventoryQueryService.queryInventory(itemKey.getItemKeyId());
|
||||
InventoryEntity inventory = inventoryQueryService.queryInventoryByItemKeyId(itemKey.getItemKeyId());
|
||||
if (inventory == null) {
|
||||
inventory = inventoryService.createInventory(itemKey.getItemKeyId(), dstLocation == null ? null : dstLocation.getLocationId(), dstStock == null ? null : dstStock.getStockId(), asnDetail.getOrderQuantity());
|
||||
insertToInventory.add(inventory);
|
||||
|
|
@ -242,12 +245,12 @@ public class ReceiveService {
|
|||
JoinerResult resultMsg = JoinerResult.createJoiner();
|
||||
|
||||
//查询Task任务关联的所以入库明细
|
||||
List<Long> asnDetailIds = tasks.stream().map(TaskEntity::getAsnDetailId).collect(Collectors.toList());
|
||||
Map<Long, AsnDetailEntity> asnDetailMap = asnDetailQueryService.queryAsnDetailListToMap(asnDetailIds);
|
||||
List<Long> asnDetailIds = tasks.stream().map(TaskEntity::getAsnDetailId).toList();
|
||||
Map<Long, AsnDetailEntity> asnDetailMap = asnDetailQueryService.queryByAsnDetailIdsToMap(asnDetailIds);
|
||||
|
||||
//查询物料
|
||||
List<Long> itemIds = asnDetailMap.values().stream().map(AsnDetailEntity::getItemId).distinct().toList();
|
||||
Map<Long, ItemEntity> itemMap = itemQueryService.queryItemList(itemIds);
|
||||
List<Long> itemIds = asnDetailMap.values().stream().map(AsnDetailEntity::getItemId).toList();
|
||||
Map<Long, ItemEntity> itemMap = itemQueryService.queryByItemIdsToMap(itemIds);
|
||||
|
||||
List<AsnDetailEntity> updateToAsnDetail = new ArrayList<>();
|
||||
List<TaskEntity> deleteToTask = new ArrayList<>();
|
||||
|
|
@ -267,7 +270,7 @@ public class ReceiveService {
|
|||
deleteToTask.add(task);
|
||||
|
||||
//库存数退回
|
||||
InventoryEntity inventory = inventoryQueryService.queryInventory(task.getItemKeyId());
|
||||
InventoryEntity inventory = inventoryQueryService.queryInventoryByItemKeyId(task.getItemKeyId());
|
||||
if (inventory != null) {
|
||||
inventory.setQuantity(SmartBigDecimalUtil.subtract(inventory.getQuantity(), task.getPlanQty(), 2));
|
||||
if (inventory.getQuantity().compareTo(BigDecimal.ZERO) == 0) {
|
||||
|
|
@ -42,12 +42,12 @@ public class TaskQueryService {
|
|||
List<TaskVO> list = taskDao.queryPage(page, queryForm);
|
||||
|
||||
// 查询物料属性
|
||||
List<Long> itemKeyIds = list.stream().map(TaskVO::getItemKeyId).distinct().collect(Collectors.toList());
|
||||
Map<Long, ItemKeyEntity> itemKeyMap = itemKeyQueryService.queryItemKeyList(itemKeyIds);
|
||||
List<Long> itemKeyIds = list.stream().map(TaskVO::getItemKeyId).toList();
|
||||
Map<Long, ItemKeyEntity> itemKeyMap = itemKeyQueryService.queryByItemKeyIds(itemKeyIds);
|
||||
|
||||
//查询物料
|
||||
List<Long> itemIds = itemKeyMap.values().stream().map(ItemKeyEntity::getItemId).distinct().toList();
|
||||
Map<Long, ItemEntity> itemMap = itemQueryService.queryItemList(itemIds);
|
||||
List<Long> itemIds = itemKeyMap.values().stream().map(ItemKeyEntity::getItemId).toList();
|
||||
Map<Long, ItemEntity> itemMap = itemQueryService.queryByItemIdsToMap(itemIds);
|
||||
|
||||
list.forEach(TaskVO -> {
|
||||
ItemKeyEntity itemKey = itemKeyMap.get(TaskVO.getItemKeyId());
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
package net.lab1024.sa.admin.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
@Slf4j
|
||||
public class TransactionCommitUtil {
|
||||
public static void executeAfterCommit(String operationDesc, Runnable operation) {
|
||||
boolean inTransaction = TransactionSynchronizationManager.isSynchronizationActive();
|
||||
if (inTransaction) {
|
||||
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
||||
@Override
|
||||
public void afterCommit() {
|
||||
executeOperation(operationDesc, operation);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
executeOperation(operationDesc, operation);
|
||||
}
|
||||
}
|
||||
|
||||
private static void executeOperation(String operationDesc, Runnable operation) {
|
||||
try {
|
||||
operation.run();
|
||||
} catch (Exception e) {
|
||||
log.error("{}失败: {}", operationDesc, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package net.lab1024.sa.admin.util;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import jakarta.annotation.Resource;
|
||||
import net.lab1024.sa.base.common.exception.BusinessException;
|
||||
import net.lab1024.sa.base.common.util.SmartStringUtil;
|
||||
|
|
@ -12,10 +13,11 @@ import org.springframework.stereotype.Service;
|
|||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class ValidateDictKey {
|
||||
public class ValidateDictKeyUtil {
|
||||
|
||||
@Resource
|
||||
private DictDao dictDao;
|
||||
|
|
@ -26,7 +28,7 @@ public class ValidateDictKey {
|
|||
public Map<String, String> validateDictCodes(List<String> dictCodes, String dictCode) {
|
||||
//通过字典编号查询数据库已存在的类型
|
||||
DictEntity dict = dictDao.selectByCode(dictCode);
|
||||
if(dict==null){
|
||||
if (dict == null) {
|
||||
throw new BusinessException("字典中" + dictCode + "参数错误");
|
||||
}
|
||||
List<DictDataVO> selectByKeyCode = dictService.queryDictData(dict.getDictId());
|
||||
|
|
@ -34,16 +36,23 @@ public class ValidateDictKey {
|
|||
throw new BusinessException("字典中" + dictCode + "参数错误");
|
||||
}
|
||||
|
||||
//去重
|
||||
dictCodes = dictCodes.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());
|
||||
|
||||
//获取字典集合中的valueName集合
|
||||
List<String> exitDictCodes = selectByKeyCode.stream().map(DictDataVO::getDataLabel).distinct().collect(Collectors.toList());
|
||||
List<String> exitDictCodes = selectByKeyCode.stream().filter(Objects::nonNull).map(DictDataVO::getDataLabel).distinct().toList();
|
||||
|
||||
//获取两个集合的非交集说明库区不存在;提示错误
|
||||
List<String> diff = SmartStringUtil.getDifference(dictCodes, exitDictCodes);
|
||||
if (CollectionUtils.isNotEmpty(diff)) {
|
||||
throw new BusinessException(diff + "不存在,请在数据字典中维护");
|
||||
}
|
||||
//封装map
|
||||
Map<String, String> map = Maps.newHashMap();
|
||||
for (DictDataVO dictDataVO : selectByKeyCode) {
|
||||
map.put(dictDataVO.getDataLabel(), dictDataVO.getDataValue());
|
||||
}
|
||||
|
||||
return selectByKeyCode.stream()
|
||||
.collect(Collectors.toMap(DictDataVO::getDataLabel,DictDataVO::getDataValue));
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
|
@ -11,11 +11,18 @@ import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
|||
import jakarta.annotation.Resource;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.cache.RedisCacheConfiguration;
|
||||
import org.springframework.data.redis.cache.RedisCacheManager;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.*;
|
||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.RedisSerializationContext;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* redis配置
|
||||
*
|
||||
|
|
@ -57,6 +64,48 @@ public class RedisConfig {
|
|||
return template;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RedisCacheManager redisCacheManager(RedisConnectionFactory connectionFactory) {
|
||||
// 序列化配置
|
||||
ObjectMapper om = new ObjectMapper();
|
||||
om.registerModule(new JavaTimeModule())
|
||||
.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false)
|
||||
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
|
||||
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(om, Object.class);
|
||||
|
||||
// 默认配置
|
||||
RedisCacheConfiguration defaultConfig = RedisCacheConfiguration.defaultCacheConfig()
|
||||
.entryTtl(Duration.ofHours(1)) // 默认过期时间1小时
|
||||
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
|
||||
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer))
|
||||
.disableCachingNullValues();
|
||||
|
||||
// 不同业务数据的缓存配置
|
||||
Map<String, RedisCacheConfiguration> configMap = new HashMap<>();
|
||||
|
||||
// 1. 高频查询且更新不频繁的数据
|
||||
configMap.put("item_cache", defaultConfig.entryTtl(Duration.ofHours(12)));
|
||||
configMap.put("customer_cache", defaultConfig.entryTtl(Duration.ofHours(8)));
|
||||
configMap.put("address_cache", defaultConfig.entryTtl(Duration.ofHours(24)));
|
||||
|
||||
// 2. 高频查询且状态更新比较频繁的数据
|
||||
configMap.put("location_cache", defaultConfig.entryTtl(Duration.ofMinutes(15)));
|
||||
configMap.put("stock_cache", defaultConfig.entryTtl(Duration.ofMinutes(10)));
|
||||
|
||||
// 3. 低频查询且基本不更新的数据
|
||||
configMap.put("area_cache", defaultConfig.entryTtl(Duration.ofDays(3)));
|
||||
|
||||
return RedisCacheManager.builder(connectionFactory)
|
||||
.cacheDefaults(defaultConfig)
|
||||
.withInitialCacheConfigurations(configMap)
|
||||
.transactionAware()
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
|
||||
return redisTemplate.opsForHash();
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import com.google.common.collect.Lists;
|
|||
import jakarta.annotation.Resource;
|
||||
import net.lab1024.sa.base.constant.ReloadConst;
|
||||
import net.lab1024.sa.base.module.support.reload.core.annoation.SmartReload;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.data.redis.cache.RedisCache;
|
||||
import org.springframework.data.redis.cache.RedisCacheManager;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
|
|
@ -42,7 +43,7 @@ public class RedisCacheServiceImpl implements CacheService {
|
|||
*/
|
||||
@Override
|
||||
public List<String> cacheKey(String cacheName) {
|
||||
RedisCache cache = (RedisCache) redisCacheManager.getCache(cacheName);
|
||||
Cache cache = redisCacheManager.getCache(cacheName);
|
||||
if (cache == null) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue