no message

main
HUOJIN\92525 2025-04-18 17:20:23 +08:00
parent 184717674f
commit 8a2337e458
34 changed files with 2948 additions and 1550 deletions

View File

@ -5,16 +5,21 @@ import lombok.extern.slf4j.Slf4j;
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.module.business.wms.base.address.dao.AddressDao;
import net.lab1024.sa.admin.module.business.wms.base.address.domain.entity.AddressEntity;
import org.springframework.cache.annotation.CacheEvict;
import net.lab1024.sa.admin.util.TransactionCommitUtil;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
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;
/**
* Manager
* Manager
*
* @author hj
* @since 2024-12-26 15:35:23
@ -27,19 +32,156 @@ public class AddressManager extends ServiceImpl<AddressDao, AddressEntity> {
@Resource
private AddressDao addressDao;
@Resource
private CacheManager cacheManager;
// 使用读写锁保证高并发下的缓存操作安全
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
private final Lock readLock = rwLock.readLock();
private final Lock writeLock = rwLock.writeLock();
/**
* id
*
* 使Spring Cache
*/
@CacheEvict(value = {AdminCacheConst.Base.ADDRESS_ENTITY}, allEntries = true)
public void removeCache() {
log.info("clear ADDRESS_ENTITY");
@Cacheable(value = AdminCacheConst.Base.ADDRESS_ENTITY, key = "#addressId", unless = "#result == null")
public AddressEntity queryAddress(Long addressId) {
try {
readLock.lock();
return addressDao.selectById(addressId);
} finally {
readLock.unlock();
}
}
/**
*
*
*
*/
@Cacheable(AdminCacheConst.Base.ADDRESS_ENTITY)
public AddressEntity queryAddress(Long addressId) {
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) {
super.updateById(entity);
// 在事务提交后刷新缓存,确保数据库操作成功后再更新缓存
executeAfterCommit("刷新收货单位缓存", () -> refreshCache(entity.getAddressId()));
return entity;
}
/**
*
*
*/
@Transactional(rollbackFor = Exception.class)
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));
}
/**
*
*
*/
@Transactional(rollbackFor = Exception.class)
public void batchDelete(List<Long> addressIds) {
super.removeByIds(addressIds);
// 在事务提交后批量清除缓存
executeAfterCommit("批量清除收货单位缓存", () -> addressIds.forEach(this::evictCache));
}
/**
*
*
* @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();
Cache cache = cacheManager.getCache(AdminCacheConst.Base.ADDRESS_ENTITY);
if (cache != null) {
cache.evict(addressId);
}
} finally {
writeLock.unlock();
}
}
}

View File

@ -1,50 +1,23 @@
package net.lab1024.sa.admin.module.business.wms.base.address.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.address.dao.AddressDao;
import net.lab1024.sa.admin.module.business.wms.base.address.domain.entity.AddressEntity;
import net.lab1024.sa.admin.module.business.wms.base.address.domain.form.AddressQueryForm;
import net.lab1024.sa.admin.module.business.wms.base.address.domain.form.AddressSelect;
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.admin.module.business.wms.base.address.manager.AddressManager;
import net.lab1024.sa.admin.module.business.wms.base.item.domain.entity.ItemEntity;
import net.lab1024.sa.admin.module.business.wms.base.item.domain.vo.ItemsExcelVO;
import net.lab1024.sa.admin.module.business.wms.base.address.dao.AddressDao;
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 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 AddressQueryService {
@Resource
private AddressDao addressDao;
@Resource
private AddressManager addressManager;
public interface AddressQueryService {
/**
*
*
* @param queryForm
* @return PageResult<AddressVO>
*/
public PageResult<AddressVO> queryPage(AddressQueryForm queryForm) {
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
List<AddressVO> list = addressDao.queryPage(page, queryForm);
return SmartPageUtil.convert2PageResult(page, list);
}
PageResult<AddressVO> queryPage(AddressQueryForm queryForm);
/**
*
@ -52,9 +25,7 @@ public class AddressQueryService {
* @param addressSelect
* @return List<AddressEntity>
*/
public List<AddressEntity> queryAddress(AddressSelect addressSelect) {
return addressDao.selectList(null);
}
List<AddressEntity> queryAddress(AddressSelect addressSelect);
/**
* id
@ -62,20 +33,8 @@ public class AddressQueryService {
* @param addressIdList id
* @return Map<Long, AreaEntity>
*/
public Map<Long, AddressEntity> queryAddressList(List<Long> addressIdList) {
if (CollectionUtils.isEmpty(addressIdList)) {
return Collections.emptyMap();
}
addressIdList = addressIdList.stream().distinct().collect(Collectors.toList());
Map<Long, AddressEntity> addressMap = Maps.newHashMap();
for (Long addressId : addressIdList) {
AddressEntity address = addressManager.queryAddress(addressId);
if (address != null) {
addressMap.put(addressId, address);
}
}
return addressMap;
}
Map<Long, AddressEntity> queryAddressList(List<Long> addressIdList);
/**
* name
@ -83,49 +42,13 @@ public class AddressQueryService {
* @param addressNameList name
* @return Map<Long, AddressEntity>
*/
public Map<String, AddressEntity> queryAddressByNameList(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();
}
return addressList.stream()
.collect(Collectors.toMap(AddressEntity::getName, address -> address, (existing, replacement) -> existing));
}
/**
*
*
* @param addressName
* @return AddressEntity
*/
public AddressEntity queryByAddressName(String addressName) {
LambdaQueryWrapper<AddressEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(AddressEntity::getName, addressName);
return addressDao.selectOne(queryWrapper);
}
Map<String, AddressEntity> queryAddressByNameList(List<String> addressNameList);
/**
*
*
* @return List<AddressExcelVO>
*/
public List<AddressExcelVO> getAddressExcelVOList() {
List<AddressEntity> addressList = addressDao.selectList(null);
return addressList.stream()
.map(address ->
AddressExcelVO.builder()
.name(address.getName())
.person(address.getPerson())
.telephone(address.getTelephone())
.address(address.getAddress())
.build()
)
.collect(Collectors.toList());
}
List<AddressExcelVO> getAddressExcelVOList();
}

View File

@ -1,38 +1,12 @@
package net.lab1024.sa.admin.module.business.wms.base.address.service;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import cn.idev.excel.FastExcel;
import net.lab1024.sa.admin.module.business.wms.base.address.dao.AddressDao;
import java.util.List;
import net.lab1024.sa.admin.module.business.wms.base.address.domain.entity.AddressEntity;
import net.lab1024.sa.admin.module.business.wms.base.address.domain.form.AddressAddForm;
import net.lab1024.sa.admin.module.business.wms.base.address.domain.form.AddressImportForm;
import net.lab1024.sa.admin.module.business.wms.base.address.domain.form.AddressUpdateForm;
import net.lab1024.sa.admin.module.business.wms.base.address.manager.AddressManager;
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.ItemsImportForm;
import net.lab1024.sa.admin.module.business.wms.base.address.dao.AddressDao;
import net.lab1024.sa.admin.module.business.wms.base.address.domain.entity.AddressEntity;
import net.lab1024.sa.admin.module.business.wms.base.address.domain.form.AddressImportForm;
import net.lab1024.sa.admin.module.business.wms.base.address.domain.form.AddressUpdateForm;
import net.lab1024.sa.admin.module.business.wms.base.address.manager.AddressManager;
import net.lab1024.sa.admin.util.JoinerResult;
import net.lab1024.sa.admin.util.ResponseDTOUtils;
import net.lab1024.sa.base.common.exception.BusinessException;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
import net.lab1024.sa.base.module.support.dict.constant.DictConst;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
/**
@ -43,17 +17,7 @@ import org.springframework.web.multipart.MultipartFile;
* copyright
*/
@Service
public class AddressService {
@Resource
private AddressDao addressDao;
@Resource
private AddressManager addressManager;
@Resource
private AddressQueryService addressQueryService;
public interface AddressService {
/**
*
@ -61,15 +25,7 @@ public class AddressService {
* @param addForm
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> add(AddressAddForm addForm) {
AddressEntity addressEntity = SmartBeanUtil.copy(addForm, AddressEntity.class);
addressDao.insert(addressEntity);
//更新缓存
addressManager.removeCache();
return ResponseDTO.ok();
}
ResponseDTO<String> add(AddressAddForm addForm);
/**
*
@ -77,15 +33,7 @@ public class AddressService {
* @param updateForm
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> update(AddressUpdateForm updateForm) {
AddressEntity addressEntity = SmartBeanUtil.copy(updateForm, AddressEntity.class);
addressDao.updateById(addressEntity);
//更新缓存
addressManager.removeCache();
return ResponseDTO.ok();
}
ResponseDTO<String> update(AddressUpdateForm updateForm);
/**
*
@ -93,18 +41,7 @@ public class AddressService {
* @param idList
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> batchDelete(List<Long> idList) {
if (CollectionUtils.isEmpty(idList)) {
return ResponseDTO.ok();
}
addressManager.removeBatchByIds(idList);
//更新缓存
addressManager.removeCache();
return ResponseDTO.ok();
}
ResponseDTO<String> batchDelete(List<Long> idList);
/**
*
@ -112,17 +49,7 @@ public class AddressService {
* @param addressId id
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> delete(Long addressId) {
if (null == addressId) {
return ResponseDTO.ok();
}
addressDao.deleteById(addressId);
//更新缓存
addressManager.removeCache();
return ResponseDTO.ok();
}
ResponseDTO<String> delete(Long addressId);
/**
*
@ -130,45 +57,7 @@ public class AddressService {
* @param file
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> importAddress(MultipartFile file) {
List<AddressImportForm> dataList;
try {
dataList = FastExcel.read(file.getInputStream()).head(AddressImportForm.class)
.sheet()
.doReadSync();
} catch (IOException e) {
throw new BusinessException("数据格式存在问题,无法读取");
}
if (CollectionUtils.isEmpty(dataList)) {
return ResponseDTO.userErrorParam("数据为空");
}
//获取所有去重后的收货单位
List<String> addressName = dataList.stream().map(AddressImportForm::getName).distinct().collect(Collectors.toList());
//查询数据库存在的物料
Map<String, AddressEntity> exitAddressMap = addressQueryService.queryAddressByNameList(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 {
updateToAddress.add(createAddress(addressImportForm.getName(), addressImportForm.getPerson(), addressImportForm.getTelephone(), addressImportForm.getAddress()));
}
}
JoinerResult resultMsg = JoinerResult.createJoiner();
return ResponseDTOUtils.buildResponseSussDTO(insertToAddress, updateToAddress, addressManager::saveBatch, addressManager::updateBatchById, resultMsg);
}
ResponseDTO<String> importAddress(MultipartFile file);
/**
*
@ -179,14 +68,5 @@ public class AddressService {
* @param address
* @return AddressEntity
*/
public AddressEntity createAddress(String name, String person, String telephone, String address) {
return AddressEntity.builder()
.name(name)
.person(person)
.telephone(telephone)
.address(address)
.createUserId(SmartRequestUtil.getRequestUser().getUserId())
.createUserName(SmartRequestUtil.getRequestUser().getUserName())
.build();
}
AddressEntity createAddress(String name, String person, String telephone, String address);
}

View File

@ -0,0 +1,116 @@
package net.lab1024.sa.admin.module.business.wms.base.address.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.dao.AddressDao;
import net.lab1024.sa.admin.module.business.wms.base.address.domain.entity.AddressEntity;
import net.lab1024.sa.admin.module.business.wms.base.address.domain.form.AddressQueryForm;
import net.lab1024.sa.admin.module.business.wms.base.address.domain.form.AddressSelect;
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.admin.module.business.wms.base.address.manager.AddressManager;
import net.lab1024.sa.admin.module.business.wms.base.address.service.AddressQueryService;
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 AddressQueryServiceImpl implements AddressQueryService {
@Resource
private AddressDao addressDao;
@Resource
private AddressManager addressManager;
/**
*
*
* @param queryForm
* @return PageResult<AddressVO>
*/
public PageResult<AddressVO> queryPage(AddressQueryForm queryForm) {
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
List<AddressVO> list = addressDao.queryPage(page, queryForm);
return SmartPageUtil.convert2PageResult(page, list);
}
/**
*
*
* @param addressSelect
* @return List<AddressEntity>
*/
public List<AddressEntity> queryAddress(AddressSelect addressSelect) {
return addressDao.selectList(null);
}
/**
* id
*
* @param addressIdList id
* @return Map<Long, AreaEntity>
*/
public Map<Long, AddressEntity> queryAddressList(List<Long> addressIdList) {
if (CollectionUtils.isEmpty(addressIdList)) {
return Collections.emptyMap();
}
addressIdList = addressIdList.stream().distinct().collect(Collectors.toList());
Map<Long, AddressEntity> addressMap = Maps.newHashMap();
for (Long addressId : addressIdList) {
AddressEntity address = addressManager.queryAddress(addressId);
if (address != null) {
addressMap.put(addressId, address);
}
}
return addressMap;
}
/**
* name
*
* @param addressNameList name
* @return Map<Long, AddressEntity>
*/
public Map<String, AddressEntity> queryAddressByNameList(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();
}
return addressList.stream()
.collect(Collectors.toMap(AddressEntity::getName, address -> address, (existing, replacement) -> existing));
}
/**
*
*
* @return List<AddressExcelVO>
*/
public List<AddressExcelVO> getAddressExcelVOList() {
List<AddressEntity> addressList = addressDao.selectList(null);
return addressList.stream()
.map(address ->
AddressExcelVO.builder()
.name(address.getName())
.person(address.getPerson())
.telephone(address.getTelephone())
.address(address.getAddress())
.build()
)
.collect(Collectors.toList());
}
}

View File

@ -0,0 +1,166 @@
package net.lab1024.sa.admin.module.business.wms.base.address.service.impl;
import cn.idev.excel.FastExcel;
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.domain.form.AddressAddForm;
import net.lab1024.sa.admin.module.business.wms.base.address.domain.form.AddressImportForm;
import net.lab1024.sa.admin.module.business.wms.base.address.domain.form.AddressUpdateForm;
import net.lab1024.sa.admin.module.business.wms.base.address.manager.AddressManager;
import net.lab1024.sa.admin.module.business.wms.base.address.service.AddressQueryService;
import net.lab1024.sa.admin.module.business.wms.base.address.service.AddressService;
import net.lab1024.sa.admin.util.JoinerResult;
import net.lab1024.sa.admin.util.ResponseDTOUtil;
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.common.util.SmartRequestUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
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 {
@Resource
private AddressManager addressManager;
@Resource
private AddressQueryService addressQueryService;
/**
*
*
* @param addForm
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> add(AddressAddForm addForm) {
AddressEntity addressEntity = SmartBeanUtil.copy(addForm, AddressEntity.class);
//新增并更新缓存
addressManager.insert(addressEntity);
return ResponseDTO.ok();
}
/**
*
*
* @param updateForm
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> update(AddressUpdateForm updateForm) {
AddressEntity addressEntity = SmartBeanUtil.copy(updateForm, AddressEntity.class);
//更新并更新缓存
addressManager.update(addressEntity);
return ResponseDTO.ok();
}
/**
*
*
* @param idList
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> batchDelete(List<Long> idList) {
if (CollectionUtils.isEmpty(idList)) {
return ResponseDTO.ok();
}
//删除并删除缓存
addressManager.batchDelete(idList);
return ResponseDTO.ok();
}
/**
*
*
* @param addressId id
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> delete(Long addressId) {
if (null == addressId) {
return ResponseDTO.ok();
}
//删除并删除缓存
addressManager.deleteById(addressId);
return ResponseDTO.ok();
}
/**
*
*
* @param file
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> importAddress(MultipartFile file) {
List<AddressImportForm> dataList;
try {
dataList = FastExcel.read(file.getInputStream()).head(AddressImportForm.class)
.sheet()
.doReadSync();
} catch (IOException e) {
throw new BusinessException("数据格式存在问题,无法读取");
}
if (CollectionUtils.isEmpty(dataList)) {
return ResponseDTO.userErrorParam("数据为空");
}
//获取所有去重后的收货单位
List<String> addressName = dataList.stream().map(AddressImportForm::getName).distinct().collect(Collectors.toList());
//查询数据库存在的物料
Map<String, AddressEntity> exitAddressMap = addressQueryService.queryAddressByNameList(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 {
updateToAddress.add(createAddress(addressImportForm.getName(), addressImportForm.getPerson(), addressImportForm.getTelephone(), addressImportForm.getAddress()));
}
}
JoinerResult resultMsg = JoinerResult.createJoiner();
return ResponseDTOUtil.buildResponseDTO(insertToAddress,updateToAddress,addressManager::batchInsert,addressManager::batchUpdate,resultMsg);
}
/**
*
*
* @param name
* @param person
* @param telephone
* @param address
* @return AddressEntity
*/
public AddressEntity createAddress(String name, String person, String telephone, String address) {
return AddressEntity.builder()
.name(name)
.person(person)
.telephone(telephone)
.address(address)
.createUserId(SmartRequestUtil.getRequestUser().getUserId())
.createUserName(SmartRequestUtil.getRequestUser().getUserName())
.build();
}
}

View File

@ -7,15 +7,24 @@ 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 org.springframework.cache.annotation.CacheEvict;
import net.lab1024.sa.admin.util.TransactionCommitUtil;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
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;
/**
* Manager
* Manager
*
* @author hj
* @since 2025-03-11 11:12:36
* @since 2025-03-11 11:12:36
* copyright
*/
@Service
@ -25,20 +34,121 @@ public class AreaManager extends ServiceImpl<AreaDao, AreaEntity> {
@Resource
private AreaDao areaDao;
/**
* id
*/
@CacheEvict(value = {AdminCacheConst.Base.AREA_ENTITY}, allEntries = true)
public void removeCache() {
log.info("clear AREA_ENTITY");
}
@Resource
private CacheManager cacheManager;
// 使用读写锁保证高并发下的缓存操作安全
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
private final Lock readLock = rwLock.readLock();
private final Lock writeLock = rwLock.writeLock();
/**
*
*
* 使Spring Cache
*/
@Cacheable(AdminCacheConst.Base.AREA_ENTITY)
@Cacheable(value = AdminCacheConst.Base.AREA_ENTITY, key = "#areaId", unless = "#result == null")
public AreaEntity queryArea(Long areaId) {
return areaDao.selectById(areaId);
try {
readLock.lock();
return areaDao.selectById(areaId);
} finally {
readLock.unlock();
}
}
/**
*
*
*/
@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) {
super.updateById(entity);
// 在事务提交后刷新缓存,确保数据库操作成功后再更新缓存
executeAfterCommit("刷新库区缓存", () -> refreshCache(entity.getAreaId()));
return entity;
}
/**
*
*
*/
@Transactional(rollbackFor = Exception.class)
public void deleteById(Long areaId) {
super.removeById(areaId);
// 在事务提交后清除缓存,确保数据库操作成功后再更新缓存
executeAfterCommit("清除库区缓存", () -> evictCache(areaId));
}
/**
*
*
*/
@Transactional(rollbackFor = Exception.class)
public void batchDelete(List<Long> areaIds) {
super.removeByIds(areaIds);
// 在事务提交后批量清除缓存
executeAfterCommit("批量清除库区缓存", () -> areaIds.forEach(this::evictCache));
}
/**
*
*
* @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();
Cache cache = cacheManager.getCache(AdminCacheConst.Base.AREA_ENTITY);
if (cache != null) {
cache.evict(areaId);
}
} finally {
writeLock.unlock();
}
}
}

View File

@ -1,33 +1,18 @@
package net.lab1024.sa.admin.module.business.wms.base.area.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.dao.AreaDao;
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.AreaQueryForm;
import net.lab1024.sa.admin.module.business.wms.base.area.domain.form.AreaSelect;
import net.lab1024.sa.admin.module.business.wms.base.area.domain.vo.AreaVO;
import net.lab1024.sa.admin.module.business.wms.base.area.manager.AreaManager;
import net.lab1024.sa.admin.module.business.wms.base.area.domain.vo.AreaVO;
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 AreaQueryService {
@Resource
private AreaDao areaDao;
@Resource
private AreaManager areaManager;
public interface AreaQueryService {
/**
*
@ -35,11 +20,7 @@ public class AreaQueryService {
* @param queryForm
* @return PageResult<AreaVO>
*/
public PageResult<AreaVO> queryPage(AreaQueryForm queryForm) {
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
List<AreaVO> list = areaDao.queryPage(page, queryForm);
return SmartPageUtil.convert2PageResult(page, list);
}
PageResult<AreaVO> queryPage(AreaQueryForm queryForm);
/**
*
@ -47,18 +28,7 @@ public class AreaQueryService {
* @param areaSelect
* @return List<AreaEntity>
*/
public List<AreaEntity> queryArea(AreaSelect areaSelect) {
LambdaQueryWrapper<AreaEntity> queryWrapper = new LambdaQueryWrapper<>();
//是否启用
if (areaSelect.getDisabledFlag() != null) {
queryWrapper.eq(AreaEntity::getDisabledFlag, areaSelect.getDisabledFlag());
}
//库区名称
if (CollectionUtils.isNotEmpty(areaSelect.getAreaNames())) {
queryWrapper.in(AreaEntity::getAreaName, areaSelect.getAreaNames());
}
return areaDao.selectList(queryWrapper);
}
List<AreaEntity> queryArea(AreaSelect areaSelect);
/**
* id
@ -66,20 +36,7 @@ public class AreaQueryService {
* @param areaIdList id
* @return Map<Long, AreaEntity>
*/
public Map<Long, AreaEntity> queryAreaList(List<Long> areaIdList) {
if (CollectionUtils.isEmpty(areaIdList)) {
return Collections.emptyMap();
}
areaIdList = areaIdList.stream().distinct().collect(Collectors.toList());
Map<Long, AreaEntity> areaMap = Maps.newHashMap();
for (Long areaId : areaIdList) {
AreaEntity area = areaManager.queryArea(areaId);
if (area != null) {
areaMap.put(areaId, area);
}
}
return areaMap;
}
Map<Long, AreaEntity> queryAreaList(List<Long> areaIdList);
/**
* name
@ -87,20 +44,7 @@ public class AreaQueryService {
* @param areaNameList name
* @return Map<Long, AreaEntity>
*/
public Map<String, AreaEntity> queryAreaByNameList(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();
}
return areaList.stream()
.collect(Collectors.toMap(AreaEntity::getAreaName, area -> area, (existing, replacement) -> existing));
}
Map<String, AreaEntity> queryAreaByNameList(List<String> areaNameList);
/**
*
@ -108,10 +52,6 @@ public class AreaQueryService {
* @param areaName
* @return AreaEntity
*/
public AreaEntity queryByAreaName(String areaName) {
LambdaQueryWrapper<AreaEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(AreaEntity::getAreaName, areaName);
return areaDao.selectOne(queryWrapper);
}
AreaEntity queryByAreaName(String areaName);
}

View File

@ -2,26 +2,10 @@ package net.lab1024.sa.admin.module.business.wms.base.area.service;
import java.util.*;
import net.lab1024.sa.admin.module.business.wms.base.area.dao.AreaDao;
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.AreaAddForm;
import net.lab1024.sa.admin.module.business.wms.base.area.domain.form.AreaUpdateForm;
import net.lab1024.sa.admin.module.business.wms.base.area.manager.AreaManager;
import net.lab1024.sa.admin.module.business.wms.base.location.service.LocationQueryService;
import net.lab1024.sa.admin.module.business.wms.base.area.dao.AreaDao;
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.AreaAddForm;
import net.lab1024.sa.admin.module.business.wms.base.area.domain.form.AreaUpdateForm;
import net.lab1024.sa.admin.module.business.wms.base.area.manager.AreaManager;
import net.lab1024.sa.admin.util.JoinerResult;
import net.lab1024.sa.admin.util.ResponseDTOUtils;
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
@ -31,21 +15,8 @@ import org.springframework.transaction.annotation.Transactional;
* copyright
*/
@Service
public class AreaService {
@Resource
private AreaDao areaDao;
@Resource
private AreaManager areaManager;
@Resource
private AreaQueryService areaQueryService;
@Resource
private LocationQueryService locationQueryService;
public interface AreaService {
/**
*
@ -53,18 +24,7 @@ public class AreaService {
* @param addForm
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> add(AreaAddForm addForm) {
AreaEntity existingArea = areaQueryService.queryByAreaName(addForm.getAreaName());
if (existingArea != null) {
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
}
AreaEntity areaEntity = SmartBeanUtil.copy(addForm, AreaEntity.class);
areaDao.insert(areaEntity);
//更新缓存
areaManager.removeCache();
return ResponseDTO.ok();
}
ResponseDTO<String> add(AreaAddForm addForm);
/**
*
@ -72,18 +32,7 @@ public class AreaService {
* @param updateForm
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> update(AreaUpdateForm updateForm) {
AreaEntity existingArea = areaQueryService.queryByAreaName(updateForm.getAreaName());
if (existingArea != null && !existingArea.getAreaId().equals(updateForm.getAreaId())) {
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
}
AreaEntity areaEntity = SmartBeanUtil.copy(updateForm, AreaEntity.class);
areaDao.updateById(areaEntity);
//更新缓存
areaManager.removeCache();
return ResponseDTO.ok();
}
ResponseDTO<String> update(AreaUpdateForm updateForm);
/**
*
@ -91,33 +40,7 @@ public class AreaService {
* @param idList
* @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 joiner = JoinerResult.createJoiner();
List<Long> idsToDelete = new ArrayList<>();
for (Long id : idList) {
AreaEntity area = areaManager.queryArea(id);
if (!locationQueryService.checkLocationExist(id)) {
joiner.getErrorMsg().add(area.getAreaName() + "已关联库位,无法删除");
} else {
idsToDelete.add(id);
joiner.getSussMsg().add(area.getAreaName() + "删除成功");
}
}
//删除库区
if (CollectionUtils.isNotEmpty(idsToDelete)) {
areaManager.removeBatchByIds(idsToDelete);
//更新缓存
areaManager.removeCache();
}
return ResponseDTOUtils.buildResponseDTO(joiner);
}
ResponseDTO<String> batchDelete(List<Long> idList);
/**
*
@ -125,23 +48,5 @@ public class AreaService {
* @param areaId
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> delete(Long areaId) {
if (null == areaId) {
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
}
AreaEntity area = areaManager.queryArea(areaId);
if (!locationQueryService.checkLocationExist(areaId)) {
return ResponseDTO.userErrorParam(area.getAreaName() + "已关联库位,无法删除");
}
areaDao.deleteById(areaId);
//更新缓存
areaManager.removeCache();
return ResponseDTO.ok();
}
ResponseDTO<String> delete(Long areaId);
}

View File

@ -0,0 +1,118 @@
package net.lab1024.sa.admin.module.business.wms.base.area.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.area.dao.AreaDao;
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.AreaQueryForm;
import net.lab1024.sa.admin.module.business.wms.base.area.domain.form.AreaSelect;
import net.lab1024.sa.admin.module.business.wms.base.area.domain.vo.AreaVO;
import net.lab1024.sa.admin.module.business.wms.base.area.manager.AreaManager;
import net.lab1024.sa.admin.module.business.wms.base.area.service.AreaQueryService;
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 AreaQueryServiceImpl implements AreaQueryService {
@Resource
private AreaDao areaDao;
@Resource
private AreaManager areaManager;
/**
*
*
* @param queryForm
* @return PageResult<AreaVO>
*/
public PageResult<AreaVO> queryPage(AreaQueryForm queryForm) {
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
List<AreaVO> list = areaDao.queryPage(page, queryForm);
return SmartPageUtil.convert2PageResult(page, list);
}
/**
*
*
* @param areaSelect
* @return List<AreaEntity>
*/
public List<AreaEntity> queryArea(AreaSelect areaSelect) {
LambdaQueryWrapper<AreaEntity> queryWrapper = new LambdaQueryWrapper<>();
//是否启用
if (areaSelect.getDisabledFlag() != null) {
queryWrapper.eq(AreaEntity::getDisabledFlag, areaSelect.getDisabledFlag());
}
//库区名称
if (CollectionUtils.isNotEmpty(areaSelect.getAreaNames())) {
queryWrapper.in(AreaEntity::getAreaName, areaSelect.getAreaNames());
}
return areaDao.selectList(queryWrapper);
}
/**
* id
*
* @param areaIdList id
* @return Map<Long, AreaEntity>
*/
public Map<Long, AreaEntity> queryAreaList(List<Long> areaIdList) {
if (CollectionUtils.isEmpty(areaIdList)) {
return Collections.emptyMap();
}
areaIdList = areaIdList.stream().distinct().collect(Collectors.toList());
Map<Long, AreaEntity> areaMap = Maps.newHashMap();
for (Long areaId : areaIdList) {
AreaEntity area = areaManager.queryArea(areaId);
if (area != null) {
areaMap.put(areaId, area);
}
}
return areaMap;
}
/**
* name
*
* @param areaNameList name
* @return Map<Long, AreaEntity>
*/
public Map<String, AreaEntity> queryAreaByNameList(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();
}
return areaList.stream()
.collect(Collectors.toMap(AreaEntity::getAreaName, area -> area, (existing, replacement) -> existing));
}
/**
*
*
* @param areaName
* @return AreaEntity
*/
public AreaEntity queryByAreaName(String areaName) {
LambdaQueryWrapper<AreaEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(AreaEntity::getAreaName, areaName);
return areaDao.selectOne(queryWrapper);
}
}

View File

@ -0,0 +1,127 @@
package net.lab1024.sa.admin.module.business.wms.base.area.service.impl;
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.AreaAddForm;
import net.lab1024.sa.admin.module.business.wms.base.area.domain.form.AreaUpdateForm;
import net.lab1024.sa.admin.module.business.wms.base.area.manager.AreaManager;
import net.lab1024.sa.admin.module.business.wms.base.area.service.AreaQueryService;
import net.lab1024.sa.admin.module.business.wms.base.area.service.AreaService;
import net.lab1024.sa.admin.module.business.wms.base.location.service.LocationQueryService;
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 org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
@Service
public class AreaServiceImpl implements AreaService {
@Resource
private AreaManager areaManager;
@Resource
private AreaQueryService areaQueryService;
@Resource
private LocationQueryService locationQueryService;
/**
*
*
* @param addForm
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> add(AreaAddForm addForm) {
AreaEntity existingArea = areaQueryService.queryByAreaName(addForm.getAreaName());
if (existingArea != null) {
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
}
AreaEntity areaEntity = SmartBeanUtil.copy(addForm, AreaEntity.class);
//新增并新增缓存
areaManager.insert(areaEntity);
return ResponseDTO.ok();
}
/**
*
*
* @param updateForm
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> update(AreaUpdateForm updateForm) {
AreaEntity existingArea = areaQueryService.queryByAreaName(updateForm.getAreaName());
if (existingArea != null && !existingArea.getAreaId().equals(updateForm.getAreaId())) {
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
}
AreaEntity areaEntity = SmartBeanUtil.copy(updateForm, AreaEntity.class);
//更新并更新缓存
areaManager.update(areaEntity);
return ResponseDTO.ok();
}
/**
*
*
* @param idList
* @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<Long> idsToDelete = new ArrayList<>();
for (Long id : idList) {
AreaEntity area = areaManager.queryArea(id);
if (!locationQueryService.checkLocationExist(id)) {
resultMsg.getErrorMsg().add(area.getAreaName() + "已关联库位,无法删除");
} else {
idsToDelete.add(id);
resultMsg.getSussMsg().add(area.getAreaName() + "删除成功");
}
}
//删除库区
if (CollectionUtils.isNotEmpty(idsToDelete)) {
//删除并删除缓存
areaManager.batchDelete(idsToDelete);
}
return ResponseDTOUtil.buildResponseDTO(resultMsg);
}
/**
*
*
* @param areaId
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> delete(Long areaId) {
if (null == areaId) {
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
}
AreaEntity area = areaManager.queryArea(areaId);
if (!locationQueryService.checkLocationExist(areaId)) {
return ResponseDTO.userErrorParam(area.getAreaName() + "已关联库位,无法删除");
}
//单个删除并删除缓存
areaManager.deleteById(areaId);
return ResponseDTO.ok();
}
}

View File

@ -7,14 +7,21 @@ 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.module.business.wms.base.customer.dao.CustomerDao;
import net.lab1024.sa.admin.module.business.wms.base.customer.domain.entity.CustomerEntity;
import org.springframework.cache.annotation.CacheEvict;
import net.lab1024.sa.admin.util.TransactionCommitUtil;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
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;
/**
* Manager
* Manager
*
* @author
* @since 2025-03-25 10:42:33
@ -27,19 +34,121 @@ public class CustomerManager extends ServiceImpl<CustomerDao, CustomerEntity> {
@Resource
private CustomerDao customerDao;
@Resource
private CacheManager cacheManager;
// 使用读写锁保证高并发下的缓存操作安全
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
private final Lock readLock = rwLock.readLock();
private final Lock writeLock = rwLock.writeLock();
/**
* id
*
* 使Spring Cache
*/
@CacheEvict(value = {AdminCacheConst.Base.CUSTOMER_ENTITY}, allEntries = true)
public void removeCache() {
log.info("clear CUSTOMER_ENTITY");
@Cacheable(value = AdminCacheConst.Base.CUSTOMER_ENTITY, key = "#customerId", unless = "#result == null")
public CustomerEntity queryCustomer(Long customerId) {
try {
readLock.lock();
return customerDao.selectById(customerId);
} finally {
readLock.unlock();
}
}
/**
*
*
*
*/
@Cacheable(AdminCacheConst.Base.CUSTOMER_ENTITY)
public CustomerEntity queryCustomer(Long customerId) {
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) {
super.updateById(entity);
// 在事务提交后刷新缓存,确保数据库操作成功后再更新缓存
executeAfterCommit("刷新客户缓存", () -> refreshCache(entity.getCustomerId()));
return entity;
}
/**
*
*
*/
@Transactional(rollbackFor = Exception.class)
public void deleteById(Long customerId) {
super.removeById(customerId);
// 在事务提交后清除缓存,确保数据库操作成功后再更新缓存
executeAfterCommit("清除客户缓存", () -> evictCache(customerId));
}
/**
*
*
*/
@Transactional(rollbackFor = Exception.class)
public void batchDelete(List<Long> customerIds) {
super.removeByIds(customerIds);
// 在事务提交后批量清除缓存
executeAfterCommit("批量清除客户缓存", () -> customerIds.forEach(this::evictCache));
}
/**
*
*
* @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();
Cache cache = cacheManager.getCache(AdminCacheConst.Base.CUSTOMER_ENTITY);
if (cache != null) {
cache.evict(customerId);
}
} finally {
writeLock.unlock();
}
}
}

View File

@ -29,9 +29,6 @@ import org.springframework.transaction.annotation.Transactional;
@Service
public class CustomerService {
@Resource
private CustomerDao customerDao;
@Resource
private CustomerManager customerManager;
@ -51,9 +48,8 @@ public class CustomerService {
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
}
CustomerEntity customerEntity = SmartBeanUtil.copy(addForm, CustomerEntity.class);
customerDao.insert(customerEntity);
//更新缓存
customerManager.removeCache();
//新增并新增缓存
customerManager.insert(customerEntity);
return ResponseDTO.ok();
}
@ -70,9 +66,8 @@ public class CustomerService {
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
}
CustomerEntity customerEntity = SmartBeanUtil.copy(updateForm, CustomerEntity.class);
customerDao.updateById(customerEntity);
//更新缓存
customerManager.removeCache();
//更新并更新缓存
customerManager.update(customerEntity);
return ResponseDTO.ok();
}
@ -87,10 +82,8 @@ public class CustomerService {
if (CollectionUtils.isEmpty(idList)) {
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
}
customerManager.removeBatchByIds(idList);
//更新缓存
customerManager.removeCache();
//批量删除并删除缓存
customerManager.batchDelete(idList);
return ResponseDTO.ok();
}
@ -105,10 +98,8 @@ public class CustomerService {
if (null == customerId) {
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
}
customerDao.deleteById(customerId);
//更新缓存
customerManager.removeCache();
customerManager.deleteById(customerId);
return ResponseDTO.ok();
}
}

View File

@ -3,20 +3,27 @@ package net.lab1024.sa.admin.module.business.wms.base.item.manager;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.constant.AdminCacheConst;
import net.lab1024.sa.admin.module.business.wms.base.area.dao.AreaDao;
import net.lab1024.sa.admin.module.business.wms.base.area.domain.entity.AreaEntity;
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.module.business.wms.base.item.dao.ItemDao;
import net.lab1024.sa.admin.module.business.wms.base.item.domain.entity.ItemEntity;
import org.springframework.cache.annotation.CacheEvict;
import net.lab1024.sa.admin.util.TransactionCommitUtil;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
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;
/**
* Manager
* Manager
*
* @Author
* @Date 2024-11-25 17:08:18
@ -25,23 +32,160 @@ import org.springframework.stereotype.Service;
@Service
@Slf4j
public class ItemManager extends ServiceImpl<ItemDao, ItemEntity> {
@Resource
private ItemDao itemDao;
/**
*
*/
@CacheEvict(value = {AdminCacheConst.Base.ITEM_ENTITY}, allEntries = true)
public void removeCache() {
log.info("clear ITEM_ENTITY");
}
@Resource
private CacheManager cacheManager;
// 使用读写锁保证高并发下的缓存操作安全
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
private final Lock readLock = rwLock.readLock();
private final Lock writeLock = rwLock.writeLock();
/**
*
*
* 使Spring Cache
*/
@Cacheable(AdminCacheConst.Base.ITEM_ENTITY)
@Cacheable(value = AdminCacheConst.Base.ITEM_ENTITY, key = "#itemId", unless = "#result == null")
public ItemEntity queryItem(Long itemId) {
return itemDao.selectById(itemId);
try {
readLock.lock();
return itemDao.selectById(itemId);
} finally {
readLock.unlock();
}
}
}
/**
*
*
*/
@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) {
super.updateById(entity);
// 在事务提交后刷新缓存,确保数据库操作成功后再更新缓存
executeAfterCommit("刷新物料缓存", () -> refreshCache(entity.getItemId()));
return entity;
}
/**
*
*
*/
@Transactional(rollbackFor = Exception.class)
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));
}
/**
*
*
*/
@Transactional(rollbackFor = Exception.class)
public void batchDelete(List<Long> itemIds) {
super.removeByIds(itemIds);
// 在事务提交后批量清除缓存
executeAfterCommit("批量清除物料缓存", () -> itemIds.forEach(this::evictCache));
}
/**
*
*
* @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();
Cache cache = cacheManager.getCache(AdminCacheConst.Base.ITEM_ENTITY);
if (cache != null) {
cache.evict(itemId);
}
} finally {
writeLock.unlock();
}
}
}

View File

@ -24,17 +24,8 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
public class ItemQueryService {
@Resource
private ItemDao itemDao;
@Resource
private ItemManager itemManager;
@Resource
private DictService dictService;
public interface ItemQueryService {
/**
*
@ -42,11 +33,7 @@ public class ItemQueryService {
* @param queryForm
* @return PageResult<ItemVO>
*/
public PageResult<ItemVO> queryPage(ItemQueryForm queryForm) {
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
List<ItemVO> list = itemDao.queryPage(page, queryForm);
return SmartPageUtil.convert2PageResult(page, list);
}
PageResult<ItemVO> queryPage(ItemQueryForm queryForm);
/**
*
@ -54,14 +41,7 @@ public class ItemQueryService {
* @param itemSelect
* @return List<ItemEntity>
*/
public List<ItemEntity> queryItem(ItemSelect itemSelect) {
LambdaQueryWrapper<ItemEntity> queryWrapper = new LambdaQueryWrapper<>();
//是否启用
if (itemSelect.getDisabledFlag() != null) {
queryWrapper.eq(ItemEntity::getDisabledFlag, itemSelect.getDisabledFlag());
}
return itemDao.selectList(queryWrapper);
}
List<ItemEntity> queryItem(ItemSelect itemSelect);
/**
* id
@ -69,20 +49,7 @@ public class ItemQueryService {
* @param itemIdList id
* @return Map<Long, AreaEntity>
*/
public Map<Long, ItemEntity> queryItemList(List<Long> itemIdList) {
if (CollectionUtils.isEmpty(itemIdList)) {
return Collections.emptyMap();
}
itemIdList = itemIdList.stream().distinct().collect(Collectors.toList());
Map<Long, ItemEntity> itemMap = Maps.newHashMap();
for (Long itemId : itemIdList) {
ItemEntity item = itemManager.queryItem(itemId);
if (item != null) {
itemMap.put(itemId, item);
}
}
return itemMap;
}
Map<Long, ItemEntity> queryItemList(List<Long> itemIdList);
/**
*
@ -90,11 +57,7 @@ public class ItemQueryService {
* @param itemCode
* @return ItemEntity
*/
public ItemEntity queryByItemCode(String itemCode) {
LambdaQueryWrapper<ItemEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ItemEntity::getItemCode, itemCode);
return itemDao.selectOne(queryWrapper);
}
ItemEntity queryByItemCode(String itemCode);
/**
*
@ -102,11 +65,7 @@ public class ItemQueryService {
* @param itemCodes
* @return List<ItemEntity>
*/
public List<ItemEntity> queryByItemCodes(List<String> itemCodes) {
LambdaQueryWrapper<ItemEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(ItemEntity::getItemCode, itemCodes);
return itemDao.selectList(queryWrapper);
}
List<ItemEntity> queryByItemCodes(List<String> itemCodes);
/**
*
@ -114,33 +73,12 @@ public class ItemQueryService {
* @param itemCodes
* @return Map<String, ItemEntity>
*/
public Map<String, ItemEntity> queryItemListToMap(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));
}
Map<String, ItemEntity> queryItemListToMap(List<String> itemCodes);
/**
*
*
* @return List<LocationsExcelVO>
*/
public List<ItemsExcelVO> getItemsExcelVOList() {
List<ItemEntity> itemsList = itemDao.selectList(null);
return itemsList.stream()
.map(item ->
ItemsExcelVO.builder()
.itemCode(item.getItemCode())
.itemName(item.getItemName())
.itemType(dictService.getDictDataLabel(DictConst.ITEM_TYPE.getValue(), item.getItemType()))
.unit(dictService.getDictDataLabel(DictConst.ITEM_UNIT.getValue(), item.getUnit()))
.disabledFlag(item.getDisabledFlag() ? "启用" : "禁用")
.build()
)
.collect(Collectors.toList());
}
List<ItemsExcelVO> getItemsExcelVOList();
}

View File

@ -1,35 +1,12 @@
package net.lab1024.sa.admin.module.business.wms.base.item.service;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import cn.idev.excel.FastExcel;
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.ItemAddForm;
import net.lab1024.sa.admin.module.business.wms.base.item.domain.form.ItemUpdateForm;
import net.lab1024.sa.admin.module.business.wms.base.item.domain.form.ItemsImportForm;
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.admin.module.business.wms.base.item.domain.form.ItemAddForm;
import net.lab1024.sa.admin.util.JoinerResult;
import net.lab1024.sa.admin.util.ResponseDTOUtils;
import net.lab1024.sa.admin.util.ValidateDictKey;
import net.lab1024.sa.base.common.code.UserErrorCode;
import net.lab1024.sa.base.common.exception.BusinessException;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
import net.lab1024.sa.base.module.support.dict.constant.DictConst;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
/**
@ -39,21 +16,7 @@ import org.springframework.web.multipart.MultipartFile;
* @since 2024-11-25 17:08:18
* copyright
*/
@Service
public class ItemService {
@Resource
private ItemDao itemDao;
@Resource
private ItemManager itemManager;
@Resource
private ItemQueryService itemQueryService;
@Resource
private ValidateDictKey ValidateDictKey;
public interface ItemService {
/**
*
@ -61,19 +24,7 @@ public class ItemService {
* @param addForm
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> add(ItemAddForm addForm) {
ItemEntity existingItem = itemQueryService.queryByItemCode(addForm.getItemCode());
if (existingItem != null) {
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
}
ItemEntity itemEntity = SmartBeanUtil.copy(addForm, ItemEntity.class);
itemDao.insert(itemEntity);
//更新缓存
itemManager.removeCache();
return ResponseDTO.ok();
}
ResponseDTO<String> add(ItemAddForm addForm);
/**
*
@ -81,18 +32,7 @@ public class ItemService {
* @param updateForm
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> update(ItemUpdateForm updateForm) {
ItemEntity existingItem = itemQueryService.queryByItemCode(updateForm.getItemCode());
if (existingItem != null && !existingItem.getItemId().equals(updateForm.getItemId())) {
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
}
ItemEntity itemEntity = SmartBeanUtil.copy(updateForm, ItemEntity.class);
itemDao.updateById(itemEntity);
//更新缓存
itemManager.removeCache();
return ResponseDTO.ok();
}
ResponseDTO<String> update(ItemUpdateForm updateForm);
/**
*
@ -100,18 +40,7 @@ public class ItemService {
* @param idList
* @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());
}
itemManager.removeBatchByIds(idList);
//更新缓存
itemManager.removeCache();
return ResponseDTO.ok();
}
ResponseDTO<String> batchDelete(List<Long> idList);
/**
*
@ -119,18 +48,7 @@ public class ItemService {
* @param itemId
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> delete(Long itemId) {
if (null == itemId) {
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
}
itemDao.deleteById(itemId);
//更新缓存
itemManager.removeCache();
return ResponseDTO.ok();
}
ResponseDTO<String> delete(Long itemId);
/**
*
@ -138,62 +56,7 @@ public class ItemService {
* @param file
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> importItems(MultipartFile file) {
List<ItemsImportForm> dataList;
try {
dataList = FastExcel.read(file.getInputStream()).head(ItemsImportForm.class)
.sheet()
.doReadSync();
} catch (IOException e) {
throw new BusinessException("数据格式存在问题,无法读取");
}
if (CollectionUtils.isEmpty(dataList)) {
return ResponseDTO.userErrorParam("数据为空");
}
//获取所有去重后的物料类型
List<String> itemTypes = dataList.stream().map(ItemsImportForm::getItemType).distinct().collect(Collectors.toList());
//验证物料类型
Map<String, String> itemTypeMap = ValidateDictKey.validateDictCodes(itemTypes, DictConst.ITEM_TYPE.getValue());
//获取所有去重后的包装单位
List<String> units = dataList.stream().map(ItemsImportForm::getUnit).distinct().collect(Collectors.toList());
//验证包装单位
Map<String, String> unitMap = ValidateDictKey.validateDictCodes(units, DictConst.ITEM_UNIT.getValue());
//获取所有去重后的容器编码
List<String> itemCodes = dataList.stream().map(ItemsImportForm::getItemCode).distinct().collect(Collectors.toList());
//查询数据库存在的物料
Map<String, ItemEntity> exitItemMap = itemQueryService.queryItemListToMap(itemCodes);
List<ItemEntity> insertToItem = new ArrayList<>();
List<ItemEntity> updateToItem = new ArrayList<>();
for (ItemsImportForm itemsImportForm : dataList) {
//物料类型
String itemType = itemTypeMap.get(itemsImportForm.getItemType());
//包装单位
String unit = unitMap.get(itemsImportForm.getUnit());
//物料
ItemEntity item = exitItemMap.get(itemsImportForm.getItemCode());
//物料为空则新增,否则更新
if (item == null) {
insertToItem.add(createItem(itemsImportForm.getItemCode(), itemsImportForm.getItemName(), unit, BigDecimal.ONE, itemType));
} else {
updateToItem.add(createItem(itemsImportForm.getItemCode(), itemsImportForm.getItemName(), unit, BigDecimal.ONE, itemType));
}
}
JoinerResult resultMsg = JoinerResult.createJoiner();
return ResponseDTOUtils.buildResponseSussDTO(insertToItem, updateToItem, itemManager::saveBatch, itemManager::updateBatchById, resultMsg);
}
ResponseDTO<String> importItems(MultipartFile file);
/**
*
@ -205,18 +68,6 @@ public class ItemService {
* @param itemType
* @return ItemEntity
*/
public ItemEntity createItem(String itemCode, String itemName, String unit, BigDecimal packFactor, String itemType) {
return ItemEntity.builder()
.itemCode(itemCode)
.itemName(itemName)
.unit(unit)
.packFactor(packFactor)
.disabledFlag(true)
.itemType(itemType)
.createUserId(SmartRequestUtil.getRequestUser().getUserId())
.createUserName(SmartRequestUtil.getRequestUser().getUserName())
.build();
}
ItemEntity createItem(String itemCode, String itemName, String unit, BigDecimal packFactor, String itemType);
}

View File

@ -0,0 +1,146 @@
package net.lab1024.sa.admin.module.business.wms.base.item.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.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.service.ItemQueryService;
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;
@Service
public class ItemQueryServiceImpl implements ItemQueryService {
@Resource
private ItemDao itemDao;
@Resource
private ItemManager itemManager;
@Resource
private DictService dictService;
/**
*
*
* @param queryForm
* @return PageResult<ItemVO>
*/
public PageResult<ItemVO> queryPage(ItemQueryForm queryForm) {
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
List<ItemVO> list = itemDao.queryPage(page, queryForm);
return SmartPageUtil.convert2PageResult(page, list);
}
/**
*
*
* @param itemSelect
* @return List<ItemEntity>
*/
public List<ItemEntity> queryItem(ItemSelect itemSelect) {
LambdaQueryWrapper<ItemEntity> queryWrapper = new LambdaQueryWrapper<>();
//是否启用
if (itemSelect.getDisabledFlag() != null) {
queryWrapper.eq(ItemEntity::getDisabledFlag, itemSelect.getDisabledFlag());
}
return itemDao.selectList(queryWrapper);
}
/**
* id
*
* @param itemIdList id
* @return Map<Long, AreaEntity>
*/
public Map<Long, ItemEntity> queryItemList(List<Long> itemIdList) {
if (CollectionUtils.isEmpty(itemIdList)) {
return Collections.emptyMap();
}
itemIdList = itemIdList.stream().mapToLong(Long::longValue).distinct().boxed().toList();
Map<Long, ItemEntity> itemMap = Maps.newHashMap();
for (Long itemId : itemIdList) {
ItemEntity item = itemManager.queryItem(itemId);
if (item != null) {
itemMap.put(itemId, item);
}
}
return itemMap;
}
/**
*
*
* @param itemCode
* @return ItemEntity
*/
public ItemEntity queryByItemCode(String itemCode) {
LambdaQueryWrapper<ItemEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ItemEntity::getItemCode, itemCode);
return itemDao.selectOne(queryWrapper);
}
/**
*
*
* @param itemCodes
* @return List<ItemEntity>
*/
public List<ItemEntity> queryByItemCodes(List<String> itemCodes) {
LambdaQueryWrapper<ItemEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(ItemEntity::getItemCode, itemCodes);
return itemDao.selectList(queryWrapper);
}
/**
*
*
* @param itemCodes
* @return Map<String, ItemEntity>
*/
public Map<String, ItemEntity> queryItemListToMap(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));
}
/**
*
*
* @return List<LocationsExcelVO>
*/
public List<ItemsExcelVO> getItemsExcelVOList() {
List<ItemEntity> itemsList = itemDao.selectList(null);
return itemsList.stream()
.map(item ->
ItemsExcelVO.builder()
.itemCode(item.getItemCode())
.itemName(item.getItemName())
.itemType(dictService.getDictDataLabel(DictConst.ITEM_TYPE.getValue(), item.getItemType()))
.unit(dictService.getDictDataLabel(DictConst.ITEM_UNIT.getValue(), item.getUnit()))
.disabledFlag(item.getDisabledFlag() ? "启用" : "禁用")
.build()
)
.collect(Collectors.toList());
}
}

View File

@ -0,0 +1,197 @@
package net.lab1024.sa.admin.module.business.wms.base.item.service.impl;
import cn.idev.excel.FastExcel;
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.domain.form.ItemAddForm;
import net.lab1024.sa.admin.module.business.wms.base.item.domain.form.ItemUpdateForm;
import net.lab1024.sa.admin.module.business.wms.base.item.domain.form.ItemsImportForm;
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.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.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.common.util.SmartRequestUtil;
import net.lab1024.sa.base.module.support.dict.constant.DictConst;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
public class ItemServiceImpl implements ItemService {
@Resource
private ItemManager itemManager;
@Resource
private ItemQueryService itemQueryService;
@Resource
private ValidateDictKey validateDictKey;
/**
*
*
* @param addForm
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> add(ItemAddForm addForm) {
ItemEntity existingItem = itemQueryService.queryByItemCode(addForm.getItemCode());
if (existingItem != null) {
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
}
ItemEntity itemEntity = SmartBeanUtil.copy(addForm, ItemEntity.class);
//新增并新增缓存
itemManager.insert(itemEntity);
return ResponseDTO.ok();
}
/**
*
*
* @param updateForm
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> update(ItemUpdateForm updateForm) {
ItemEntity existingItem = itemQueryService.queryByItemCode(updateForm.getItemCode());
if (existingItem != null && !existingItem.getItemId().equals(updateForm.getItemId())) {
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
}
ItemEntity itemEntity = SmartBeanUtil.copy(updateForm, ItemEntity.class);
//更新并更新缓存
itemManager.update(itemEntity);
return ResponseDTO.ok();
}
/**
*
*
* @param idList
* @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());
}
//批量删除并删除缓存
itemManager.batchDelete(idList);
return ResponseDTO.ok();
}
/**
*
*
* @param itemId
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> delete(Long itemId) {
if (null == itemId) {
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
}
//单个删除并删除缓存
itemManager.deleteById(itemId);
return ResponseDTO.ok();
}
/**
*
*
* @param file
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> importItems(MultipartFile file) {
List<ItemsImportForm> dataList;
try {
dataList = FastExcel.read(file.getInputStream()).head(ItemsImportForm.class)
.sheet()
.doReadSync();
} catch (IOException e) {
throw new BusinessException("数据格式存在问题,无法读取");
}
if (CollectionUtils.isEmpty(dataList)) {
return ResponseDTO.userErrorParam("数据为空");
}
//获取所有去重后的物料类型
List<String> itemTypes = dataList.stream().map(ItemsImportForm::getItemType).distinct().collect(Collectors.toList());
//验证物料类型
Map<String, String> itemTypeMap = validateDictKey.validateDictCodes(itemTypes, DictConst.ITEM_TYPE.getValue());
//获取所有去重后的包装单位
List<String> units = dataList.stream().map(ItemsImportForm::getUnit).distinct().collect(Collectors.toList());
//验证包装单位
Map<String, String> unitMap = validateDictKey.validateDictCodes(units, DictConst.ITEM_UNIT.getValue());
//获取所有去重后的容器编码
List<String> itemCodes = dataList.stream().map(ItemsImportForm::getItemCode).distinct().collect(Collectors.toList());
//查询数据库存在的物料
Map<String, ItemEntity> exitItemMap = itemQueryService.queryItemListToMap(itemCodes);
List<ItemEntity> insertToItem = new ArrayList<>();
List<ItemEntity> updateToItem = new ArrayList<>();
for (ItemsImportForm itemsImportForm : dataList) {
//物料类型
String itemType = itemTypeMap.get(itemsImportForm.getItemType());
//包装单位
String unit = unitMap.get(itemsImportForm.getUnit());
//物料
ItemEntity item = exitItemMap.get(itemsImportForm.getItemCode());
//物料为空则新增,否则更新
if (item == null) {
insertToItem.add(createItem(itemsImportForm.getItemCode(), itemsImportForm.getItemName(), unit, BigDecimal.ONE, itemType));
} else {
updateToItem.add(createItem(itemsImportForm.getItemCode(), itemsImportForm.getItemName(), unit, BigDecimal.ONE, itemType));
}
}
JoinerResult resultMsg = JoinerResult.createJoiner();
return ResponseDTOUtil.buildResponseDTO(insertToItem,updateToItem,itemManager::batchInsert, itemManager::batchUpdate,resultMsg);
}
/**
*
*
* @param itemCode
* @param itemName
* @param unit
* @param packFactor
* @param itemType
* @return ItemEntity
*/
public ItemEntity createItem(String itemCode, String itemName, String unit, BigDecimal packFactor, String itemType) {
return ItemEntity.builder()
.itemCode(itemCode)
.itemName(itemName)
.unit(unit)
.packFactor(packFactor)
.disabledFlag(true)
.itemType(itemType)
.createUserId(SmartRequestUtil.getRequestUser().getUserId())
.createUserName(SmartRequestUtil.getRequestUser().getUserName())
.build();
}
}

View File

@ -7,40 +7,184 @@ 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.module.business.wms.base.location.domain.entity.LocationEntity;
import org.springframework.cache.annotation.CacheEvict;
import net.lab1024.sa.admin.util.TransactionCommitUtil;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
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;
/**
* Manager
* Manager
*
* @author
* @since 2024-11-18 14:17:31
* @since 2024-11-18 14:17:31
* copyright
*/
@Service
@Slf4j
public class LocationManager extends ServiceImpl<LocationDao, LocationEntity> {
@Resource
private LocationDao locationDao;
/**
* id
*/
@CacheEvict(value = {AdminCacheConst.Base.LOCATION_ENTITY}, allEntries = true)
public void removeCache() {
log.info("clear LOCATION_ENTITY");
}
@Resource
private CacheManager cacheManager;
// 使用读写锁保证高并发下的缓存操作安全
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
private final Lock readLock = rwLock.readLock();
private final Lock writeLock = rwLock.writeLock();
/**
*
*
* 使Spring Cache
*/
@Cacheable(AdminCacheConst.Base.LOCATION_ENTITY)
@Cacheable(value = AdminCacheConst.Base.LOCATION_ENTITY, key = "#locationId", unless = "#result == null")
public LocationEntity queryLocation(Long locationId) {
return locationDao.selectById(locationId);
try {
readLock.lock();
return locationDao.selectById(locationId);
} finally {
readLock.unlock();
}
}
/**
*
*
*/
@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) {
super.updateById(entity);
// 在事务提交后刷新缓存,确保数据库操作成功后再更新缓存
executeAfterCommit("刷新库位缓存", () -> refreshCache(entity.getLocationId()));
return entity;
}
/**
*
*
*/
@Transactional(rollbackFor = Exception.class)
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));
}
/**
*
*
*/
@Transactional(rollbackFor = Exception.class)
public void batchDelete(List<Long> locationIds) {
super.removeByIds(locationIds);
// 在事务提交后批量清除缓存
executeAfterCommit("批量清除库位缓存", () -> locationIds.forEach(this::evictCache));
}
/**
*
*
* @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();
Cache cache = cacheManager.getCache(AdminCacheConst.Base.LOCATION_ENTITY);
if (cache != null) {
cache.evict(locationId);
}
} finally {
writeLock.unlock();
}
}
}

View File

@ -1,63 +1,16 @@
package net.lab1024.sa.admin.module.business.wms.base.location.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.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.domain.form.AreaSelect;
import net.lab1024.sa.admin.module.business.wms.base.area.manager.AreaManager;
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.LocationQueryForm;
import net.lab1024.sa.admin.module.business.wms.base.location.domain.form.LocationSelect;
import net.lab1024.sa.admin.module.business.wms.base.location.domain.form.LocationsExcelVO;
import net.lab1024.sa.admin.module.business.wms.base.location.domain.vo.LocationVO;
import net.lab1024.sa.admin.module.business.wms.base.location.manager.LocationManager;
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.area.manager.AreaManager;
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.LocationQueryForm;
import net.lab1024.sa.admin.module.business.wms.base.location.domain.form.LocationSelect;
import net.lab1024.sa.admin.module.business.wms.base.location.domain.form.LocationsExcelVO;
import net.lab1024.sa.admin.module.business.wms.base.location.domain.vo.LocationVO;
import net.lab1024.sa.admin.module.business.wms.base.location.manager.LocationManager;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.util.SmartEnumUtil;
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.stream.Collectors;
@Service
public class LocationQueryService {
@Resource
private LocationDao locationDao;
@Resource
private AreaManager areaManager;
@Resource
private LocationManager locationManager;
@Resource
private AreaQueryService areaQueryService;
@Resource
private DictService dictService;
public interface LocationQueryService {
/**
*
@ -65,21 +18,7 @@ public class LocationQueryService {
* @param queryForm
* @return PageResult<LocationVO>
*/
public PageResult<LocationVO> queryPage(LocationQueryForm queryForm) {
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
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.forEach(locationVO -> {
AreaEntity area = areaMap.get(locationVO.getAreaId());
if (area != null) {
locationVO.setAreaName(area.getAreaName());
}
});
return SmartPageUtil.convert2PageResult(page, list);
}
PageResult<LocationVO> queryPage(LocationQueryForm queryForm);
/**
* VO
@ -87,23 +26,7 @@ public class LocationQueryService {
* @param entity
* @return LocationVO
*/
public LocationVO entityToVO(LocationEntity entity) {
AreaEntity area = areaManager.queryArea(entity.getAreaId());
return LocationVO.builder()
.locationId(entity.getLocationId())
.locationCode(entity.getLocationCode())
.status(entity.getStatus())
.areaId(entity.getAreaId())
.areaName(area == null ? null : area.getAreaName())
.disabledFlag(entity.getDisabledFlag())
.locationRow(entity.getLocationRow())
.locationLine(entity.getLocationLine())
.locationCow(entity.getLocationCow())
.locationType(entity.getLocationType())
.remark(entity.getRemark())
.createTime(entity.getCreateTime())
.build();
}
LocationVO entityToVO(LocationEntity entity);
/**
@ -112,37 +35,7 @@ public class LocationQueryService {
* @param locationSelect
* @return List<LocationVO>
*/
public List<LocationVO> queryLocation(LocationSelect locationSelect) {
LambdaQueryWrapper<LocationEntity> queryWrapper = new LambdaQueryWrapper<>();
//是否启用
if (locationSelect.getDisabledFlag() != null) {
queryWrapper.eq(LocationEntity::getDisabledFlag, locationSelect.getDisabledFlag());
}
//库区
if (CollectionUtils.isNotEmpty(locationSelect.getAreaNames())) {
AreaSelect areaSelect = AreaSelect.builder().areaNames(locationSelect.getAreaNames()).build();
areaSelect.setAreaNames(locationSelect.getAreaNames());
List<AreaEntity> areaList = areaQueryService.queryArea(areaSelect);
if (CollectionUtils.isNotEmpty(areaList)) {
List<Long> areaIdList = areaList.stream().map(AreaEntity::getAreaId).collect(Collectors.toList());
queryWrapper.in(LocationEntity::getAreaId, areaIdList);
}
}
//库位类型
if (StringUtils.isNotBlank(locationSelect.getLocationType())) {
queryWrapper.eq(LocationEntity::getLocationType, locationSelect.getLocationType());
}
//库位状态
if (StringUtils.isNotBlank(locationSelect.getStatus())) {
queryWrapper.eq(LocationEntity::getStatus, locationSelect.getStatus());
}
List<LocationEntity> list = locationDao.selectList(queryWrapper);
return list.stream().map(this::entityToVO).collect(Collectors.toList());
}
List<LocationVO> queryLocation(LocationSelect locationSelect);
/**
* ID
@ -150,32 +43,14 @@ public class LocationQueryService {
* @param locationIdList ID
* @return Map<Long, LocationEntity>
*/
public Map<Long, LocationEntity> queryLocationList(List<Long> locationIdList) {
if (CollectionUtils.isEmpty(locationIdList)) {
return Collections.emptyMap();
}
locationIdList = locationIdList.stream().distinct().collect(Collectors.toList());
Map<Long, LocationEntity> locationMap = Maps.newHashMap();
for (Long locationId : locationIdList) {
LocationEntity location = locationManager.queryLocation(locationId);
if (location != null) {
locationMap.put(locationId, location);
}
}
return locationMap;
}
Map<Long, LocationEntity> queryLocationList(List<Long> locationIdList);
/**
*
*
* @param areaId
*/
public Boolean checkLocationExist(Long areaId) {
LambdaQueryWrapper<LocationEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(LocationEntity::getAreaId, areaId);
List<LocationEntity> list = locationDao.selectList(queryWrapper);
return list.isEmpty();
}
Boolean checkLocationExist(Long areaId);
/**
*
@ -183,11 +58,7 @@ public class LocationQueryService {
* @param locationCode
* @return LocationEntity
*/
public LocationEntity queryByLocationCode(String locationCode) {
LambdaQueryWrapper<LocationEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(LocationEntity::getLocationCode, locationCode);
return locationDao.selectOne(queryWrapper);
}
LocationEntity queryByLocationCode(String locationCode);
/**
*
@ -195,11 +66,7 @@ public class LocationQueryService {
* @param locationCodes
* @return List<LocationEntity>
*/
public List<LocationEntity> queryByLocationCodes(List<String> locationCodes) {
LambdaQueryWrapper<LocationEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(LocationEntity::getLocationCode, locationCodes);
return locationDao.selectList(queryWrapper);
}
List<LocationEntity> queryByLocationCodes(List<String> locationCodes);
/**
*
@ -207,39 +74,13 @@ public class LocationQueryService {
* @param locationCodes
* @return Map<String, LocationEntity>
*/
public Map<String, LocationEntity> queryLocationListToMap(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));
}
Map<String, LocationEntity> queryLocationListToMap(List<String> locationCodes);
/**
*
*
* @return List<LocationsExcelVO>
*/
public List<LocationsExcelVO> getLocationsExcelVOList() {
List<LocationEntity> locationsList = locationDao.selectList(null);
//库区
List<Long> areaIds = locationsList.stream().map(LocationEntity::getAreaId).distinct().collect(Collectors.toList());
Map<Long, AreaEntity> areaMap = areaQueryService.queryAreaList(areaIds);
return locationsList.stream()
.map(location ->
LocationsExcelVO.builder()
.areaName(areaMap.get(location.getAreaId()).getAreaName())
.locationCode(location.getLocationCode())
.locationType(dictService.getDictDataLabel(DictConst.LOC_TYPE.getValue(), location.getLocationType()))
.status(SmartEnumUtil.getEnumDescByValue(location.getStatus(), UsageStatusEnum.class))
.disabledFlag(location.getDisabledFlag() ? "启用" : "禁用")
.build()
)
.collect(Collectors.toList());
}
List<LocationsExcelVO> getLocationsExcelVOList();
}

View File

@ -1,32 +1,9 @@
package net.lab1024.sa.admin.module.business.wms.base.location.service;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
import cn.idev.excel.FastExcel;
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;
import net.lab1024.sa.admin.util.JoinerResult;
import net.lab1024.sa.admin.util.ResponseDTOUtils;
import net.lab1024.sa.admin.util.ValidateDictKey;
import net.lab1024.sa.base.common.code.UserErrorCode;
import net.lab1024.sa.base.common.exception.BusinessException;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
import net.lab1024.sa.base.common.util.SmartStringUtil;
import net.lab1024.sa.base.module.support.dict.constant.DictConst;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
/**
@ -37,24 +14,7 @@ import org.springframework.web.multipart.MultipartFile;
* copyright
*/
@Service
@Slf4j
public class LocationService {
@Resource
private LocationDao locationDao;
@Resource
private LocationManager locationManager;
@Resource
private AreaQueryService areaQueryService;
@Resource
private LocationQueryService locationQueryService;
@Resource
private ValidateDictKey ValidateDictKey;
public interface LocationService {
/**
*
@ -62,19 +22,7 @@ public class LocationService {
* @param addForm
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> add(LocationAddForm addForm) {
LocationEntity existingLocation = locationQueryService.queryByLocationCode(addForm.getLocationCode());
if (existingLocation != null) {
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
}
LocationEntity locationEntity = SmartBeanUtil.copy(addForm, LocationEntity.class);
locationDao.insert(locationEntity);
//更新缓存
locationManager.removeCache();
return ResponseDTO.ok();
}
ResponseDTO<String> add(LocationAddForm addForm);
/**
*
@ -82,18 +30,7 @@ public class LocationService {
* @param updateForm
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> update(LocationUpdateForm updateForm) {
LocationEntity existingLocation = locationQueryService.queryByLocationCode(updateForm.getLocationCode());
if (existingLocation != null && !existingLocation.getLocationId().equals(updateForm.getLocationId())) {
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
}
LocationEntity locationEntity = SmartBeanUtil.copy(updateForm, LocationEntity.class);
locationDao.updateById(locationEntity);
//更新缓存
locationManager.removeCache();
return ResponseDTO.ok();
}
ResponseDTO<String> update(LocationUpdateForm updateForm);
/**
*
@ -101,17 +38,7 @@ public class LocationService {
* @param idList
* @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());
}
locationManager.removeBatchByIds(idList);
//更新缓存
locationManager.removeCache();
return ResponseDTO.ok();
}
ResponseDTO<String> batchDelete(List<Long> idList);
/**
*
@ -119,17 +46,7 @@ public class LocationService {
* @param locationId
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> delete(Long locationId) {
if (null == locationId) {
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
}
locationDao.deleteById(locationId);
//更新缓存
locationManager.removeCache();
return ResponseDTO.ok();
}
ResponseDTO<String> delete(Long locationId);
/**
*
@ -137,107 +54,7 @@ public class LocationService {
* @param multipleAdjust
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> multipleAdjust(MultipleAdjust multipleAdjust) {
if (CollectionUtils.isEmpty(multipleAdjust.getLocationIds())) {
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
}
//查询库位
Map<Long, LocationEntity> locationEntityMap = locationQueryService.queryLocationList(multipleAdjust.getLocationIds());
//批量更新
List<LocationEntity> updateToLocation = new ArrayList<>();
//调整状态true:空闲;false:占用
String status = multipleAdjust.getStatus() ? UsageStatusEnum.FREE.getValue() : UsageStatusEnum.USED.getValue();
//是否启用true:启用;false:禁用
Boolean disabledFlag = multipleAdjust.getDisabledFlag();
//更新状态
locationEntityMap.forEach((locationId, location) -> {
location.setStatus(status);
location.setDisabledFlag(disabledFlag);
updateToLocation.add(location);
});
if (CollectionUtils.isNotEmpty(updateToLocation)) {
locationManager.updateBatchById(updateToLocation);
}
//更新缓存
locationManager.removeCache();
return ResponseDTO.ok();
}
/**
*
*
* @param locationCode
* @param areaId ID
* @param locationRow
* @param locationLine
* @param locationCow
* @param locationType
* @return LocationEntity
*/
public LocationEntity createLocation(String locationCode, Long areaId, String locationRow, String locationLine, String locationCow, String locationType) {
return LocationEntity.builder()
.locationCode(locationCode)
.locationName(locationCode)
.status(UsageStatusEnum.FREE.getValue())
.areaId(areaId)
.disabledFlag(true)
.locationRow(locationRow)
.locationLine(locationLine)
.locationCow(locationCow)
.locationType(locationType)
.createUserId(SmartRequestUtil.getRequestUser().getUserId())
.createUserName(SmartRequestUtil.getRequestUser().getUserName())
.build();
}
public LocationEntity createLocation(String locationCode, Long areaId, String locationType) {
int firstDashIndex = locationCode.indexOf('-');
if (firstDashIndex == -1) {
return createLocation(locationCode, areaId, null, null, null, locationType);
}
String[] parts = locationCode.substring(firstDashIndex + 1).split("-");
if (parts.length < 3) {
return createLocation(locationCode, areaId, null, null, null, locationType);
}
String row = parts[0];
String col = parts[1];
String layer = parts[2];
return createLocation(locationCode, areaId, row, col, layer, locationType);
}
/**
*
*
* @param locationCodes
* @param areaId
* @param locationType
*/
public void multipleInsert(List<String> locationCodes, Long areaId, String locationType) {
List<LocationEntity> insertToLocation = new ArrayList<>();
for (String locationCode : locationCodes) {
LocationEntity location = createLocation(locationCode, areaId, locationType);
insertToLocation.add(location);
}
//批量新增
if (CollectionUtils.isNotEmpty(insertToLocation)) {
locationManager.saveBatch(insertToLocation);
}
// 更新缓存
locationManager.removeCache();
}
ResponseDTO<String> multipleAdjust(MultipleAdjust multipleAdjust);
/**
*
@ -245,38 +62,7 @@ public class LocationService {
* @param multipleInsert
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> multipleInsert(MultipleInsert multipleInsert) {
//入参的所以库位集合
List<String> locationCodes = multipleInsert.getLocationCodes();
//查询数据库已存在的库位集合
List<LocationEntity> list = locationQueryService.queryByLocationCodes(locationCodes);
JoinerResult joiner = JoinerResult.createJoiner();
if (CollectionUtils.isNotEmpty(list)) {
List<String> existingLocationCodes = list.stream()
.map(LocationEntity::getLocationCode)
.toList();
// 获取两个集合的交集说明库位已存在;提示错误
List<String> getIntersection = SmartStringUtil.getIntersection(locationCodes, existingLocationCodes);
joiner.getErrorMsg().add(getIntersection + "库位已存在,新增失败");
// 获取两个集合的非交集说明库位不存在;批量新增
List<String> difference = SmartStringUtil.getDifference(locationCodes, existingLocationCodes);
if (CollectionUtils.isNotEmpty(difference)) {
//批量新增
multipleInsert(difference, multipleInsert.getAreaId(), multipleInsert.getLocationType());
joiner.getSussMsg().add(difference + "库位新增成功");
}
return ResponseDTOUtils.buildResponseDTO(joiner);
}
// 没有查询到库位,直接新增
multipleInsert(locationCodes, multipleInsert.getAreaId(), multipleInsert.getLocationType());
joiner.getSussMsg().add(locationCodes + "库位新增成功");
return ResponseDTOUtils.buildResponseDTO(joiner);
}
ResponseDTO<String> multipleInsert(MultipleInsert multipleInsert);
/**
*
@ -284,100 +70,14 @@ public class LocationService {
* @param file
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> importLocations(MultipartFile file) {
List<LocationsImportForm> dataList;
try {
dataList = FastExcel.read(file.getInputStream()).head(LocationsImportForm.class)
.sheet()
.doReadSync();
} catch (IOException e) {
throw new BusinessException("数据格式存在问题,无法读取");
}
if (CollectionUtils.isEmpty(dataList)) {
return ResponseDTO.userErrorParam("数据为空");
}
ResponseDTO<String> importLocations(MultipartFile file);
//获取所有去重后的库区
List<String> areaNames = dataList.stream().map(LocationsImportForm::getAreaName).distinct().collect(Collectors.toList());
//验证库区
Map<String, AreaEntity> areaMap = validateArea(areaNames);
//获取所有去重后的库位类型
List<String> locationTypes = dataList.stream().map(LocationsImportForm::getLocationType).distinct().collect(Collectors.toList());
//验证库位类型
Map<String, String> locationTypeMap = ValidateDictKey.validateDictCodes(locationTypes, DictConst.LOC_TYPE.getValue());
//获取所有去重后的库位编码
List<String> locationCodes = dataList.stream().map(LocationsImportForm::getLocationCode).distinct().collect(Collectors.toList());
//查询数据库存在的库位编码
Map<String, LocationEntity> exitLocationMap = locationQueryService.queryLocationListToMap(locationCodes);
List<LocationEntity> insertToLocation = new ArrayList<>();
List<LocationEntity> updateToLocation = new ArrayList<>();
for (LocationsImportForm locationsImportForm : dataList) {
//库区
AreaEntity area = areaMap.get(locationsImportForm.getAreaName());
//库位类型
String locationType = locationTypeMap.get(locationsImportForm.getLocationType());
//库位
LocationEntity location = exitLocationMap.get(locationsImportForm.getLocationCode());
//库位为空则新增,否则更新
if (location == null) {
insertToLocation.add(createLocation(locationsImportForm.getLocationCode(), area.getAreaId(), locationType));
} else {
updateToLocation.add(createLocation(locationsImportForm.getLocationCode(), area.getAreaId(), locationType));
}
}
JoinerResult resultMsg = JoinerResult.createJoiner();
return ResponseDTOUtils.buildResponseSussDTO(insertToLocation, updateToLocation, locationManager::saveBatch, locationManager::updateBatchById, resultMsg);
}
/**
*
*
* @param areaNames
* @return Map<String, AreaEntity>
*/
public Map<String, AreaEntity> validateArea(List<String> areaNames) {
//查询数据库存在的库区
Map<String, AreaEntity> areaMap = areaQueryService.queryAreaByNameList(areaNames);
if (areaMap.isEmpty()) {
throw new BusinessException(areaNames + "库区不存在,在库区管理中维护库区");
}
//获取map的key集合
List<String> exitAreaNameList = areaMap.keySet().stream().toList();
//获取两个集合的非交集说明库区不存在;提示错误
List<String> diffAreaName = SmartStringUtil.getDifference(areaNames, exitAreaNameList);
if (CollectionUtils.isNotEmpty(diffAreaName)) {
throw new BusinessException(diffAreaName + "库区不存在,在库区管理中维护库区");
}
return areaMap;
}
/**
/**
*
*
* @param locationId id
* @param status
*/
@Transactional(rollbackFor = Exception.class)
public void updateLocationStatus(Long locationId, String status) {
if (locationId != null) {
LocationEntity location = locationDao.selectById(locationId);
if (location != null) {
location.setStatus(status);
locationDao.updateById(location);
}
}
}
void updateLocationStatus(Long locationId, String status);
}

View File

@ -0,0 +1,234 @@
package net.lab1024.sa.admin.module.business.wms.base.location.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.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.domain.form.AreaSelect;
import net.lab1024.sa.admin.module.business.wms.base.area.manager.AreaManager;
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.LocationQueryForm;
import net.lab1024.sa.admin.module.business.wms.base.location.domain.form.LocationSelect;
import net.lab1024.sa.admin.module.business.wms.base.location.domain.form.LocationsExcelVO;
import net.lab1024.sa.admin.module.business.wms.base.location.domain.vo.LocationVO;
import net.lab1024.sa.admin.module.business.wms.base.location.manager.LocationManager;
import net.lab1024.sa.admin.module.business.wms.base.location.service.LocationQueryService;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.util.SmartEnumUtil;
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.stream.Collectors;
@Service
public class LocationQueryServiceImpl implements LocationQueryService {
@Resource
private LocationDao locationDao;
@Resource
private AreaManager areaManager;
@Resource
private LocationManager locationManager;
@Resource
private AreaQueryService areaQueryService;
@Resource
private DictService dictService;
/**
*
*
* @param queryForm
* @return PageResult<LocationVO>
*/
public PageResult<LocationVO> queryPage(LocationQueryForm queryForm) {
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
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.forEach(locationVO -> {
AreaEntity area = areaMap.get(locationVO.getAreaId());
if (area != null) {
locationVO.setAreaName(area.getAreaName());
}
});
return SmartPageUtil.convert2PageResult(page, list);
}
/**
* VO
*
* @param entity
* @return LocationVO
*/
public LocationVO entityToVO(LocationEntity entity) {
AreaEntity area = areaManager.queryArea(entity.getAreaId());
return LocationVO.builder()
.locationId(entity.getLocationId())
.locationCode(entity.getLocationCode())
.status(entity.getStatus())
.areaId(entity.getAreaId())
.areaName(area == null ? null : area.getAreaName())
.disabledFlag(entity.getDisabledFlag())
.locationRow(entity.getLocationRow())
.locationLine(entity.getLocationLine())
.locationCow(entity.getLocationCow())
.locationType(entity.getLocationType())
.remark(entity.getRemark())
.createTime(entity.getCreateTime())
.build();
}
/**
*
*
* @param locationSelect
* @return List<LocationVO>
*/
public List<LocationVO> queryLocation(LocationSelect locationSelect) {
LambdaQueryWrapper<LocationEntity> queryWrapper = new LambdaQueryWrapper<>();
//是否启用
if (locationSelect.getDisabledFlag() != null) {
queryWrapper.eq(LocationEntity::getDisabledFlag, locationSelect.getDisabledFlag());
}
//库区
if (CollectionUtils.isNotEmpty(locationSelect.getAreaNames())) {
AreaSelect areaSelect = AreaSelect.builder().areaNames(locationSelect.getAreaNames()).build();
areaSelect.setAreaNames(locationSelect.getAreaNames());
List<AreaEntity> areaList = areaQueryService.queryArea(areaSelect);
if (CollectionUtils.isNotEmpty(areaList)) {
List<Long> areaIdList = areaList.stream().map(AreaEntity::getAreaId).collect(Collectors.toList());
queryWrapper.in(LocationEntity::getAreaId, areaIdList);
}
}
//库位类型
if (StringUtils.isNotBlank(locationSelect.getLocationType())) {
queryWrapper.eq(LocationEntity::getLocationType, locationSelect.getLocationType());
}
//库位状态
if (StringUtils.isNotBlank(locationSelect.getStatus())) {
queryWrapper.eq(LocationEntity::getStatus, locationSelect.getStatus());
}
List<LocationEntity> list = locationDao.selectList(queryWrapper);
return list.stream().map(this::entityToVO).collect(Collectors.toList());
}
/**
* ID
*
* @param locationIdList ID
* @return Map<Long, LocationEntity>
*/
public Map<Long, LocationEntity> queryLocationList(List<Long> locationIdList) {
if (CollectionUtils.isEmpty(locationIdList)) {
return Collections.emptyMap();
}
locationIdList = locationIdList.stream().distinct().collect(Collectors.toList());
Map<Long, LocationEntity> locationMap = Maps.newHashMap();
for (Long locationId : locationIdList) {
LocationEntity location = locationManager.queryLocation(locationId);
if (location != null) {
locationMap.put(locationId, location);
}
}
return locationMap;
}
/**
*
*
* @param areaId
*/
public Boolean checkLocationExist(Long areaId) {
LambdaQueryWrapper<LocationEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(LocationEntity::getAreaId, areaId);
List<LocationEntity> list = locationDao.selectList(queryWrapper);
return list.isEmpty();
}
/**
*
*
* @param locationCode
* @return LocationEntity
*/
public LocationEntity queryByLocationCode(String locationCode) {
LambdaQueryWrapper<LocationEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(LocationEntity::getLocationCode, locationCode);
return locationDao.selectOne(queryWrapper);
}
/**
*
*
* @param locationCodes
* @return List<LocationEntity>
*/
public List<LocationEntity> queryByLocationCodes(List<String> locationCodes) {
LambdaQueryWrapper<LocationEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(LocationEntity::getLocationCode, locationCodes);
return locationDao.selectList(queryWrapper);
}
/**
*
*
* @param locationCodes
* @return Map<String, LocationEntity>
*/
public Map<String, LocationEntity> queryLocationListToMap(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));
}
/**
*
*
* @return List<LocationsExcelVO>
*/
public List<LocationsExcelVO> getLocationsExcelVOList() {
List<LocationEntity> locationsList = locationDao.selectList(null);
//库区
List<Long> areaIds = locationsList.stream().map(LocationEntity::getAreaId).distinct().collect(Collectors.toList());
Map<Long, AreaEntity> areaMap = areaQueryService.queryAreaList(areaIds);
return locationsList.stream()
.map(location ->
LocationsExcelVO.builder()
.areaName(areaMap.get(location.getAreaId()).getAreaName())
.locationCode(location.getLocationCode())
.locationType(dictService.getDictDataLabel(DictConst.LOC_TYPE.getValue(), location.getLocationType()))
.status(SmartEnumUtil.getEnumDescByValue(location.getStatus(), UsageStatusEnum.class))
.disabledFlag(location.getDisabledFlag() ? "启用" : "禁用")
.build()
)
.collect(Collectors.toList());
}
}

View File

@ -0,0 +1,367 @@
package net.lab1024.sa.admin.module.business.wms.base.location.service.impl;
import cn.idev.excel.FastExcel;
import jakarta.annotation.Resource;
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;
import net.lab1024.sa.admin.module.business.wms.base.location.service.LocationQueryService;
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.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.common.util.SmartRequestUtil;
import net.lab1024.sa.base.common.util.SmartStringUtil;
import net.lab1024.sa.base.module.support.dict.constant.DictConst;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
@Slf4j
public class LocationServiceImpl implements LocationService {
@Resource
private LocationDao locationDao;
@Resource
private LocationManager locationManager;
@Resource
private AreaQueryService areaQueryService;
@Resource
private LocationQueryService locationQueryService;
@Resource
private net.lab1024.sa.admin.util.ValidateDictKey ValidateDictKey;
/**
*
*
* @param addForm
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> add(LocationAddForm addForm) {
LocationEntity existingLocation = locationQueryService.queryByLocationCode(addForm.getLocationCode());
if (existingLocation != null) {
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
}
LocationEntity locationEntity = SmartBeanUtil.copy(addForm, LocationEntity.class);
//新增并新增缓存
locationManager.insert(locationEntity);
return ResponseDTO.ok();
}
/**
*
*
* @param updateForm
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> update(LocationUpdateForm updateForm) {
LocationEntity existingLocation = locationQueryService.queryByLocationCode(updateForm.getLocationCode());
if (existingLocation != null && !existingLocation.getLocationId().equals(updateForm.getLocationId())) {
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
}
LocationEntity locationEntity = SmartBeanUtil.copy(updateForm, LocationEntity.class);
//更新并更新缓存
locationManager.update(locationEntity);
return ResponseDTO.ok();
}
/**
*
*
* @param idList
* @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());
}
//删除并删除缓存
locationManager.batchDelete(idList);
return ResponseDTO.ok();
}
/**
*
*
* @param locationId
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> delete(Long locationId) {
if (null == locationId) {
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
}
//删除并删除缓存
locationManager.deleteById(locationId);
return ResponseDTO.ok();
}
/**
*
*
* @param multipleAdjust
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> multipleAdjust(MultipleAdjust multipleAdjust) {
if (CollectionUtils.isEmpty(multipleAdjust.getLocationIds())) {
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
}
//查询库位
Map<Long, LocationEntity> locationEntityMap = locationQueryService.queryLocationList(multipleAdjust.getLocationIds());
//批量更新
List<LocationEntity> updateToLocation = new ArrayList<>();
//调整状态true:空闲;false:占用
String status = multipleAdjust.getStatus() ? UsageStatusEnum.FREE.getValue() : UsageStatusEnum.USED.getValue();
//是否启用true:启用;false:禁用
Boolean disabledFlag = multipleAdjust.getDisabledFlag();
//更新状态
locationEntityMap.forEach((locationId, location) -> {
location.setStatus(status);
location.setDisabledFlag(disabledFlag);
updateToLocation.add(location);
});
if (CollectionUtils.isNotEmpty(updateToLocation)) {
//更新并更新缓存
locationManager.batchUpdate(updateToLocation);
}
return ResponseDTO.ok();
}
/**
*
*
* @param locationCode
* @param areaId ID
* @param locationRow
* @param locationLine
* @param locationCow
* @param locationType
* @return LocationEntity
*/
public LocationEntity createLocation(String locationCode, Long areaId, String locationRow, String locationLine, String locationCow, String locationType) {
return LocationEntity.builder()
.locationCode(locationCode)
.locationName(locationCode)
.status(UsageStatusEnum.FREE.getValue())
.areaId(areaId)
.disabledFlag(true)
.locationRow(locationRow)
.locationLine(locationLine)
.locationCow(locationCow)
.locationType(locationType)
.createUserId(SmartRequestUtil.getRequestUser().getUserId())
.createUserName(SmartRequestUtil.getRequestUser().getUserName())
.build();
}
public LocationEntity createLocation(String locationCode, Long areaId, String locationType) {
int firstDashIndex = locationCode.indexOf('-');
if (firstDashIndex == -1) {
return createLocation(locationCode, areaId, null, null, null, locationType);
}
String[] parts = locationCode.substring(firstDashIndex + 1).split("-");
if (parts.length < 3) {
return createLocation(locationCode, areaId, null, null, null, locationType);
}
String row = parts[0];
String col = parts[1];
String layer = parts[2];
return createLocation(locationCode, areaId, row, col, layer, locationType);
}
/**
*
*
* @param locationCodes
* @param areaId
* @param locationType
*/
public void multipleInsert(List<String> locationCodes, Long areaId, String locationType) {
List<LocationEntity> insertToLocation = new ArrayList<>();
for (String locationCode : locationCodes) {
LocationEntity location = createLocation(locationCode, areaId, locationType);
insertToLocation.add(location);
}
if (CollectionUtils.isNotEmpty(insertToLocation)) {
// 批量新增并更新缓存
locationManager.batchInsert(insertToLocation);
}
}
/**
*
*
* @param multipleInsert
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> multipleInsert(MultipleInsert multipleInsert) {
//入参的所以库位集合
List<String> locationCodes = multipleInsert.getLocationCodes();
//查询数据库已存在的库位集合
List<LocationEntity> list = locationQueryService.queryByLocationCodes(locationCodes);
JoinerResult resultMsg = JoinerResult.createJoiner();
if (CollectionUtils.isNotEmpty(list)) {
List<String> existingLocationCodes = list.stream()
.map(LocationEntity::getLocationCode)
.toList();
// 获取两个集合的交集说明库位已存在;提示错误
List<String> getIntersection = SmartStringUtil.getIntersection(locationCodes, existingLocationCodes);
resultMsg.getErrorMsg().add(getIntersection + "库位已存在,新增失败");
// 获取两个集合的非交集说明库位不存在;批量新增
List<String> difference = SmartStringUtil.getDifference(locationCodes, existingLocationCodes);
if (CollectionUtils.isNotEmpty(difference)) {
//批量新增
multipleInsert(difference, multipleInsert.getAreaId(), multipleInsert.getLocationType());
resultMsg.getSussMsg().add(difference + "库位新增成功");
}
return ResponseDTOUtil.buildResponseDTO(resultMsg);
}
// 没有查询到库位,直接新增
multipleInsert(locationCodes, multipleInsert.getAreaId(), multipleInsert.getLocationType());
resultMsg.getSussMsg().add(locationCodes + "库位新增成功");
return ResponseDTOUtil.buildResponseDTO(resultMsg);
}
/**
*
*
* @param file
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> importLocations(MultipartFile file) {
List<LocationsImportForm> dataList;
try {
dataList = FastExcel.read(file.getInputStream()).head(LocationsImportForm.class)
.sheet()
.doReadSync();
} catch (IOException e) {
throw new BusinessException("数据格式存在问题,无法读取");
}
if (CollectionUtils.isEmpty(dataList)) {
return ResponseDTO.userErrorParam("数据为空");
}
//获取所有去重后的库区
List<String> areaNames = dataList.stream().map(LocationsImportForm::getAreaName).distinct().collect(Collectors.toList());
//验证库区
Map<String, AreaEntity> areaMap = validateArea(areaNames);
//获取所有去重后的库位类型
List<String> locationTypes = dataList.stream().map(LocationsImportForm::getLocationType).distinct().collect(Collectors.toList());
//验证库位类型
Map<String, String> locationTypeMap = ValidateDictKey.validateDictCodes(locationTypes, DictConst.LOC_TYPE.getValue());
//获取所有去重后的库位编码
List<String> locationCodes = dataList.stream().map(LocationsImportForm::getLocationCode).distinct().collect(Collectors.toList());
//查询数据库存在的库位编码
Map<String, LocationEntity> exitLocationMap = locationQueryService.queryLocationListToMap(locationCodes);
List<LocationEntity> insertToLocation = new ArrayList<>();
List<LocationEntity> updateToLocation = new ArrayList<>();
for (LocationsImportForm locationsImportForm : dataList) {
//库区
AreaEntity area = areaMap.get(locationsImportForm.getAreaName());
//库位类型
String locationType = locationTypeMap.get(locationsImportForm.getLocationType());
//库位
LocationEntity location = exitLocationMap.get(locationsImportForm.getLocationCode());
//库位为空则新增,否则更新
if (location == null) {
insertToLocation.add(createLocation(locationsImportForm.getLocationCode(), area.getAreaId(), locationType));
} else {
updateToLocation.add(createLocation(locationsImportForm.getLocationCode(), area.getAreaId(), locationType));
}
}
JoinerResult resultMsg = JoinerResult.createJoiner();
return ResponseDTOUtil.buildResponseDTO(insertToLocation, updateToLocation, locationManager::batchInsert, locationManager::batchUpdate, resultMsg);
}
/**
*
*
* @param areaNames
* @return Map<String, AreaEntity>
*/
public Map<String, AreaEntity> validateArea(List<String> areaNames) {
//查询数据库存在的库区
Map<String, AreaEntity> areaMap = areaQueryService.queryAreaByNameList(areaNames);
if (areaMap.isEmpty()) {
throw new BusinessException(areaNames + "库区不存在,在库区管理中维护库区");
}
//获取map的key集合
List<String> exitAreaNameList = areaMap.keySet().stream().toList();
//获取两个集合的非交集说明库区不存在;提示错误
List<String> diffAreaName = SmartStringUtil.getDifference(areaNames, exitAreaNameList);
if (CollectionUtils.isNotEmpty(diffAreaName)) {
throw new BusinessException(diffAreaName + "库区不存在,在库区管理中维护库区");
}
return areaMap;
}
/**
*
*
* @param locationId id
* @param status
*/
@Transactional(rollbackFor = Exception.class)
public void updateLocationStatus(Long locationId, String status) {
if (locationId != null) {
LocationEntity location = locationManager.queryLocation(locationId);
if (location != null) {
location.setStatus(status);
locationManager.update(location);
}
}
}
}

View File

@ -7,15 +7,25 @@ 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 org.springframework.cache.annotation.CacheEvict;
import net.lab1024.sa.admin.util.TransactionCommitUtil;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
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;
/**
* Manager
* Manager
*
* @author
* @since 2024-11-26 11:37:48
* @since 2024-11-26 11:37:48
* copyright
*/
@Service
@ -25,20 +35,156 @@ public class StockManager extends ServiceImpl<StockDao, StockEntity> {
@Resource
private StockDao stockDao;
/**
* id
*/
@CacheEvict(value = {AdminCacheConst.Base.STOCK_ENTITY}, allEntries = true)
public void removeCache() {
log.info("clear LOCATION_ENTITY");
}
@Resource
private CacheManager cacheManager;
// 使用读写锁保证高并发下的缓存操作安全
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
private final Lock readLock = rwLock.readLock();
private final Lock writeLock = rwLock.writeLock();
/**
*
*
* 使Spring Cache
*/
@Cacheable(AdminCacheConst.Base.STOCK_ENTITY)
@Cacheable(value = AdminCacheConst.Base.STOCK_ENTITY, key = "#stockId", unless = "#result == null")
public StockEntity queryStock(Long stockId) {
return stockDao.selectById(stockId);
try {
readLock.lock();
return stockDao.selectById(stockId);
} finally {
readLock.unlock();
}
}
/**
*
*
*/
@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) {
super.updateById(entity);
// 在事务提交后刷新缓存,确保数据库操作成功后再更新缓存
executeAfterCommit("刷新容器缓存", () -> refreshCache(entity.getStockId()));
return entity;
}
/**
*
*
*/
@Transactional(rollbackFor = Exception.class)
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));
}
/**
*
*
*/
@Transactional(rollbackFor = Exception.class)
public void batchDelete(List<Long> stockIds) {
super.removeByIds(stockIds);
// 在事务提交后批量清除缓存
executeAfterCommit("批量清除容器缓存", () -> stockIds.forEach(this::evictCache));
}
/**
*
*
* @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();
Cache cache = cacheManager.getCache(AdminCacheConst.Base.STOCK_ENTITY);
if (cache != null) {
cache.evict(stockId);
}
} finally {
writeLock.unlock();
}
}
}

View File

@ -1,58 +1,17 @@
package net.lab1024.sa.admin.module.business.wms.base.stock.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.item.domain.entity.ItemEntity;
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.base.location.manager.LocationManager;
import net.lab1024.sa.admin.module.business.wms.base.location.service.LocationQueryService;
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 net.lab1024.sa.admin.module.business.wms.base.stock.domain.form.StockQueryForm;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.form.StockSelect;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.vo.StockVO;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.vo.StocksExcelVO;
import net.lab1024.sa.admin.module.business.wms.base.location.domain.entity.LocationEntity;
import net.lab1024.sa.admin.module.business.wms.base.location.manager.LocationManager;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.entity.StockEntity;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.form.StockQueryForm;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.form.StockSelect;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.vo.StocksExcelVO;
import net.lab1024.sa.admin.module.business.wms.base.stock.manager.StockManager;
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.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 StockQueryService {
@Resource
private StockDao stockDao;
@Resource
private LocationManager locationManager;
@Resource
private StockManager stockManager;
@Resource
private DictService dictService;
@Resource
private LocationQueryService locationQueryService;
public interface StockQueryService {
/**
*
@ -60,21 +19,7 @@ public class StockQueryService {
* @param queryForm
* @return PageResult<StockVO>
*/
public PageResult<StockVO> queryPage(StockQueryForm queryForm) {
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
List<StockVO> list = stockDao.queryPage(page, queryForm);
// 查询库位编码
List<Long> locationIdList = list.stream().map(StockVO::getLocationId).distinct().collect(Collectors.toList());
Map<Long, LocationEntity> locationMap = locationQueryService.queryLocationList(locationIdList);
list.forEach(StockVO -> {
LocationEntity location = locationMap.get(StockVO.getLocationId());
if (location != null) {
StockVO.setLocationCode(location.getLocationCode());
}
});
return SmartPageUtil.convert2PageResult(page, list);
}
PageResult<StockVO> queryPage(StockQueryForm queryForm);
/**
* id
@ -82,20 +27,7 @@ public class StockQueryService {
* @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;
}
Map<Long, StockEntity> queryStockList(List<Long> stockIdList);
/**
*
@ -103,18 +35,7 @@ public class StockQueryService {
* @param stockSelect
* @return List<StockEntity>
*/
public List<StockEntity> queryStock(StockSelect stockSelect) {
LambdaQueryWrapper<StockEntity> queryWrapper = new LambdaQueryWrapper<>();
//是否启用
if (stockSelect.getDisabledFlag() != null) {
queryWrapper.eq(StockEntity::getDisabledFlag, stockSelect.getDisabledFlag());
}
//状态
if (StringUtils.isNotBlank(stockSelect.getStatus())) {
queryWrapper.eq(StockEntity::getStatus, stockSelect.getStatus());
}
return stockDao.selectList(queryWrapper);
}
List<StockEntity> queryStock(StockSelect stockSelect);
/**
*
@ -122,11 +43,7 @@ public class StockQueryService {
* @param stockCode
* @return StockEntity
*/
public StockEntity queryByStockCode(String stockCode) {
LambdaQueryWrapper<StockEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(StockEntity::getStockCode, stockCode);
return stockDao.selectOne(queryWrapper);
}
StockEntity queryByStockCode(String stockCode);
/**
*
@ -134,11 +51,7 @@ public class StockQueryService {
* @param stockCodes
* @return List<StockEntity>
*/
public List<StockEntity> queryByItemCodes(List<String> stockCodes) {
LambdaQueryWrapper<StockEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(StockEntity::getStockCode, stockCodes);
return stockDao.selectList(queryWrapper);
}
List<StockEntity> queryByItemCodes(List<String> stockCodes);
/**
*
@ -146,15 +59,7 @@ public class StockQueryService {
* @param stockCodes
* @return Map<String, StockEntity>
*/
public Map<String, StockEntity> queryStockListToMap(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));
}
Map<String, StockEntity> queryStockListToMap(List<String> stockCodes);
/**
* id
@ -162,28 +67,12 @@ public class StockQueryService {
* @param locationId
* @return StockEntity
*/
public StockEntity queryStockByLocationId(Long locationId) {
LambdaQueryWrapper<StockEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(StockEntity::getLocationId, locationId);
return stockDao.selectOne(queryWrapper);
}
StockEntity queryStockByLocationId(Long locationId);
/**
*
*
* @return List<StocksExcelVO>
*/
public List<StocksExcelVO> getStocksExcelVOList() {
List<StockEntity> stocksList = stockDao.selectList(null);
return stocksList.stream()
.map(stock ->
StocksExcelVO.builder()
.stockCode(stock.getStockCode())
.stockType(dictService.getDictDataLabel(DictConst.STOCK_TYPE.getValue(), stock.getStockType()))
.locationCode(locationManager.queryLocation(stock.getLocationId()) == null ? "" : locationManager.queryLocation(stock.getLocationId()).getLocationCode())
.disabledFlag(stock.getDisabledFlag() ? "启用" : "禁用")
.build()
)
.collect(Collectors.toList());
}
List<StocksExcelVO> getStocksExcelVOList();
}

View File

@ -1,44 +1,12 @@
package net.lab1024.sa.admin.module.business.wms.base.stock.service;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import cn.idev.excel.FastExcel;
import net.lab1024.sa.admin.constant.UsageStatusEnum;
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.ItemsImportForm;
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.service.LocationQueryService;
import net.lab1024.sa.admin.module.business.wms.base.location.service.LocationService;
import net.lab1024.sa.admin.module.business.wms.base.stock.dao.StockDao;
import java.util.List;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.entity.StockEntity;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.form.StockAddForm;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.form.StockUpdateForm;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.form.StocksImportForm;
import net.lab1024.sa.admin.module.business.wms.base.stock.manager.StockManager;
import net.lab1024.sa.admin.module.business.wms.base.location.domain.entity.LocationEntity;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.form.StockUpdateForm;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.form.StocksImportForm;
import net.lab1024.sa.admin.util.JoinerResult;
import net.lab1024.sa.admin.util.ResponseDTOUtils;
import net.lab1024.sa.admin.util.ValidateDictKey;
import net.lab1024.sa.base.common.code.SystemErrorCode;
import net.lab1024.sa.base.common.code.UserErrorCode;
import net.lab1024.sa.base.common.exception.BusinessException;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
import net.lab1024.sa.base.module.support.dict.constant.DictConst;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
/**
@ -49,27 +17,7 @@ import org.springframework.web.multipart.MultipartFile;
* copyright
*/
@Service
public class StockService {
@Resource
private StockDao stockDao;
@Resource
private LocationDao locationDao;
@Resource
private StockManager stockManager;
@Resource
private ValidateDictKey ValidateDictKey;
@Resource
private StockQueryService stockQueryService;
@Resource
private LocationService locationService;
public interface StockService {
/**
*
@ -77,19 +25,7 @@ public class StockService {
* @param addForm
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> add(StockAddForm addForm) {
StockEntity existingStock = stockQueryService.queryByStockCode(addForm.getStockCode());
if (existingStock != null) {
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
}
StockEntity stockEntity = SmartBeanUtil.copy(addForm, StockEntity.class);
stockDao.insert(stockEntity);
//更新缓存
stockManager.removeCache();
return ResponseDTO.ok();
}
ResponseDTO<String> add(StockAddForm addForm);
/**
*
@ -97,36 +33,7 @@ public class StockService {
* @param updateForm
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> update(StockUpdateForm updateForm) {
StockEntity existingStock = stockQueryService.queryByStockCode(updateForm.getStockCode());
if (existingStock != null && !existingStock.getStockId().equals(updateForm.getStockId())) {
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
}
//当前更新的容器的库位
if (existingStock != null && existingStock.getLocationId() != null) {
//更新库位状态
locationService.updateLocationStatus(existingStock.getLocationId(), UsageStatusEnum.FREE.getValue());
}
if (updateForm.getLocationId() != null) {
LocationEntity location = locationDao.selectById(updateForm.getLocationId());
StockEntity curStock = stockQueryService.queryStockByLocationId(updateForm.getLocationId());
if (curStock != null && existingStock != null) {
if (!curStock.getStockId().equals(existingStock.getStockId())) {
return ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR, location.getLocationCode() + "库位绑定的当前容器为" + curStock.getStockCode());
}
}
//更新库位状态
locationService.updateLocationStatus(updateForm.getLocationId(), UsageStatusEnum.USED.getValue());
}
StockEntity stockEntity = SmartBeanUtil.copy(updateForm, StockEntity.class);
stockDao.updateById(stockEntity);
//更新缓存
stockManager.removeCache();
return ResponseDTO.ok();
}
ResponseDTO<String> update(StockUpdateForm updateForm);
/**
*
@ -134,19 +41,7 @@ public class StockService {
* @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());
}
//批量删除
stockManager.removeBatchByIds(idList);
//更新缓存
stockManager.removeCache();
return ResponseDTO.ok();
}
ResponseDTO<String> batchDelete(List<Long> idList);
/**
*
@ -154,18 +49,7 @@ public class StockService {
* @param stockId Id
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> delete(Long stockId) {
if (null == stockId) {
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
}
stockDao.deleteById(stockId);
//更新缓存
stockManager.removeCache();
return ResponseDTO.ok();
}
ResponseDTO<String> delete(Long stockId);
/**
*
@ -173,53 +57,7 @@ public class StockService {
* @param file
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> importStocks(MultipartFile file) {
List<StocksImportForm> dataList;
try {
dataList = FastExcel.read(file.getInputStream()).head(StocksImportForm.class)
.sheet()
.doReadSync();
} catch (IOException e) {
throw new BusinessException("数据格式存在问题,无法读取");
}
if (CollectionUtils.isEmpty(dataList)) {
return ResponseDTO.userErrorParam("数据为空");
}
//获取所有去重后的容器类型
List<String> stockTypes = dataList.stream().map(StocksImportForm::getStockType).distinct().collect(Collectors.toList());
//验证容器类型
Map<String, String> itemTypeMap = ValidateDictKey.validateDictCodes(stockTypes, DictConst.STOCK_TYPE.getValue());
//获取所有去重后的容器编码
List<String> stockCodes = dataList.stream().map(StocksImportForm::getStockCode).distinct().collect(Collectors.toList());
//查询数据库存在的容器
Map<String, StockEntity> exitStockMap = stockQueryService.queryStockListToMap(stockCodes);
List<StockEntity> insertToStock = new ArrayList<>();
List<StockEntity> updateToStock = new ArrayList<>();
for (StocksImportForm stocksImportForm : dataList) {
//容器类型
String stockType = itemTypeMap.get(stocksImportForm.getStockType());
//容器
StockEntity stock = exitStockMap.get(stocksImportForm.getStockCode());
//容器为空新增,否则更新
if (stock == null) {
insertToStock.add(createStock(stocksImportForm.getStockCode(), stockType));
} else {
updateToStock.add(createStock(stocksImportForm.getStockCode(), stockType));
}
}
JoinerResult resultMsg = JoinerResult.createJoiner();
return ResponseDTOUtils.buildResponseSussDTO(insertToStock, updateToStock, stockManager::saveBatch, stockManager::updateBatchById, resultMsg);
}
ResponseDTO<String> importStocks(MultipartFile file);
/**
*
@ -228,14 +66,5 @@ public class StockService {
* @param stockType
* @return StockEntity
*/
public StockEntity createStock(String stockCode, String stockType) {
return StockEntity.builder()
.stockCode(stockCode)
.stockType(stockType)
.status(UsageStatusEnum.FREE.getValue())
.disabledFlag(true)
.createUserId(SmartRequestUtil.getRequestUser().getUserId())
.createUserName(SmartRequestUtil.getRequestUser().getUserName())
.build();
}
StockEntity createStock(String stockCode, String stockType);
}

View File

@ -0,0 +1,181 @@
package net.lab1024.sa.admin.module.business.wms.base.stock.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.location.domain.entity.LocationEntity;
import net.lab1024.sa.admin.module.business.wms.base.location.manager.LocationManager;
import net.lab1024.sa.admin.module.business.wms.base.location.service.LocationQueryService;
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 net.lab1024.sa.admin.module.business.wms.base.stock.domain.form.StockQueryForm;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.form.StockSelect;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.vo.StockVO;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.vo.StocksExcelVO;
import net.lab1024.sa.admin.module.business.wms.base.stock.manager.StockManager;
import net.lab1024.sa.admin.module.business.wms.base.stock.service.StockQueryService;
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.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
public class StockQueryServiceImpl implements StockQueryService {
@Resource
private StockDao stockDao;
@Resource
private LocationManager locationManager;
@Resource
private StockManager stockManager;
@Resource
private DictService dictService;
@Resource
private LocationQueryService locationQueryService;
/**
*
*
* @param queryForm
* @return PageResult<StockVO>
*/
public PageResult<StockVO> queryPage(StockQueryForm queryForm) {
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
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.forEach(StockVO -> {
LocationEntity location = locationMap.get(StockVO.getLocationId());
if (location != null) {
StockVO.setLocationCode(location.getLocationCode());
}
});
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;
}
/**
*
*
* @param stockSelect
* @return List<StockEntity>
*/
public List<StockEntity> queryStock(StockSelect stockSelect) {
LambdaQueryWrapper<StockEntity> queryWrapper = new LambdaQueryWrapper<>();
//是否启用
if (stockSelect.getDisabledFlag() != null) {
queryWrapper.eq(StockEntity::getDisabledFlag, stockSelect.getDisabledFlag());
}
//状态
if (StringUtils.isNotBlank(stockSelect.getStatus())) {
queryWrapper.eq(StockEntity::getStatus, stockSelect.getStatus());
}
return stockDao.selectList(queryWrapper);
}
/**
*
*
* @param stockCode
* @return StockEntity
*/
public StockEntity queryByStockCode(String stockCode) {
LambdaQueryWrapper<StockEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(StockEntity::getStockCode, stockCode);
return stockDao.selectOne(queryWrapper);
}
/**
*
*
* @param stockCodes
* @return List<StockEntity>
*/
public List<StockEntity> queryByItemCodes(List<String> stockCodes) {
LambdaQueryWrapper<StockEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(StockEntity::getStockCode, stockCodes);
return stockDao.selectList(queryWrapper);
}
/**
*
*
* @param stockCodes
* @return Map<String, StockEntity>
*/
public Map<String, StockEntity> queryStockListToMap(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));
}
/**
* id
*
* @param locationId
* @return StockEntity
*/
public StockEntity queryStockByLocationId(Long locationId) {
LambdaQueryWrapper<StockEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(StockEntity::getLocationId, locationId);
return stockDao.selectOne(queryWrapper);
}
/**
*
*
* @return List<StocksExcelVO>
*/
public List<StocksExcelVO> getStocksExcelVOList() {
List<StockEntity> stocksList = stockDao.selectList(null);
return stocksList.stream()
.map(stock ->
StocksExcelVO.builder()
.stockCode(stock.getStockCode())
.stockType(dictService.getDictDataLabel(DictConst.STOCK_TYPE.getValue(), stock.getStockType()))
.locationCode(locationManager.queryLocation(stock.getLocationId()) == null ? "" : locationManager.queryLocation(stock.getLocationId()).getLocationCode())
.disabledFlag(stock.getDisabledFlag() ? "启用" : "禁用")
.build()
)
.collect(Collectors.toList());
}
}

View File

@ -0,0 +1,212 @@
package net.lab1024.sa.admin.module.business.wms.base.stock.service.impl;
import cn.idev.excel.FastExcel;
import jakarta.annotation.Resource;
import net.lab1024.sa.admin.constant.UsageStatusEnum;
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.service.LocationService;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.entity.StockEntity;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.form.StockAddForm;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.form.StockUpdateForm;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.form.StocksImportForm;
import net.lab1024.sa.admin.module.business.wms.base.stock.manager.StockManager;
import net.lab1024.sa.admin.module.business.wms.base.stock.service.StockQueryService;
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.base.common.code.SystemErrorCode;
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.common.util.SmartRequestUtil;
import net.lab1024.sa.base.module.support.dict.constant.DictConst;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
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 {
@Resource
private LocationDao locationDao;
@Resource
private StockManager stockManager;
@Resource
private net.lab1024.sa.admin.util.ValidateDictKey ValidateDictKey;
@Resource
private StockQueryService stockQueryService;
@Resource
private LocationService locationService;
/**
*
*
* @param addForm
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> add(StockAddForm addForm) {
StockEntity existingStock = stockQueryService.queryByStockCode(addForm.getStockCode());
if (existingStock != null) {
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
}
StockEntity stockEntity = SmartBeanUtil.copy(addForm, StockEntity.class);
//添加并更新缓存
stockManager.insert(stockEntity);
return ResponseDTO.ok();
}
/**
*
*
* @param updateForm
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> update(StockUpdateForm updateForm) {
StockEntity existingStock = stockQueryService.queryByStockCode(updateForm.getStockCode());
if (existingStock != null && !existingStock.getStockId().equals(updateForm.getStockId())) {
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
}
//当前更新的容器的库位
if (existingStock != null && existingStock.getLocationId() != null) {
//更新库位状态
locationService.updateLocationStatus(existingStock.getLocationId(), UsageStatusEnum.FREE.getValue());
}
if (updateForm.getLocationId() != null) {
LocationEntity location = locationDao.selectById(updateForm.getLocationId());
StockEntity curStock = stockQueryService.queryStockByLocationId(updateForm.getLocationId());
if (curStock != null && existingStock != null) {
if (!curStock.getStockId().equals(existingStock.getStockId())) {
return ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR, location.getLocationCode() + "库位绑定的当前容器为" + curStock.getStockCode());
}
}
//更新库位状态
locationService.updateLocationStatus(updateForm.getLocationId(), UsageStatusEnum.USED.getValue());
}
StockEntity stockEntity = SmartBeanUtil.copy(updateForm, StockEntity.class);
//更新并更新缓存
stockManager.update(stockEntity);
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());
}
//删除并删除缓存
stockManager.batchDelete(idList);
return ResponseDTO.ok();
}
/**
*
*
* @param stockId Id
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> delete(Long stockId) {
if (null == stockId) {
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
}
//删除并删除缓存
stockManager.deleteById(stockId);
return ResponseDTO.ok();
}
/**
*
*
* @param file
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> importStocks(MultipartFile file) {
List<StocksImportForm> dataList;
try {
dataList = FastExcel.read(file.getInputStream()).head(StocksImportForm.class)
.sheet()
.doReadSync();
} catch (IOException e) {
throw new BusinessException("数据格式存在问题,无法读取");
}
if (CollectionUtils.isEmpty(dataList)) {
return ResponseDTO.userErrorParam("数据为空");
}
//获取所有去重后的容器类型
List<String> stockTypes = dataList.stream().map(StocksImportForm::getStockType).distinct().collect(Collectors.toList());
//验证容器类型
Map<String, String> itemTypeMap = ValidateDictKey.validateDictCodes(stockTypes, DictConst.STOCK_TYPE.getValue());
//获取所有去重后的容器编码
List<String> stockCodes = dataList.stream().map(StocksImportForm::getStockCode).distinct().collect(Collectors.toList());
//查询数据库存在的容器
Map<String, StockEntity> exitStockMap = stockQueryService.queryStockListToMap(stockCodes);
List<StockEntity> insertToStock = new ArrayList<>();
List<StockEntity> updateToStock = new ArrayList<>();
for (StocksImportForm stocksImportForm : dataList) {
//容器类型
String stockType = itemTypeMap.get(stocksImportForm.getStockType());
//容器
StockEntity stock = exitStockMap.get(stocksImportForm.getStockCode());
//容器为空新增,否则更新
if (stock == null) {
insertToStock.add(createStock(stocksImportForm.getStockCode(), stockType));
} else {
updateToStock.add(createStock(stocksImportForm.getStockCode(), stockType));
}
}
JoinerResult resultMsg = JoinerResult.createJoiner();
return ResponseDTOUtil.buildResponseDTO(insertToStock, updateToStock, stockManager::batchInsert, stockManager::batchUpdate, resultMsg);
}
/**
*
*
* @param stockCode
* @param stockType
* @return StockEntity
*/
public StockEntity createStock(String stockCode, String stockType) {
return StockEntity.builder()
.stockCode(stockCode)
.stockType(stockType)
.status(UsageStatusEnum.FREE.getValue())
.disabledFlag(true)
.createUserId(SmartRequestUtil.getRequestUser().getUserId())
.createUserName(SmartRequestUtil.getRequestUser().getUserName())
.build();
}
}

View File

@ -1,14 +1,11 @@
package net.lab1024.sa.admin.module.business.wms.receive;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
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.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.service.LocationQueryService;
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 net.lab1024.sa.admin.module.business.wms.base.stock.service.StockQueryService;
import net.lab1024.sa.admin.module.business.wms.inventory.domain.entity.InventoryEntity;
@ -16,16 +13,12 @@ import net.lab1024.sa.admin.module.business.wms.inventory.manager.InventoryManag
import net.lab1024.sa.admin.module.business.wms.inventory.service.InventoryQueryService;
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.manager.ItemKeyManager;
import net.lab1024.sa.admin.module.business.wms.itemKey.service.ItemKeyQueryService;
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.service.AsnQueryService;
import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.entity.AsnDetailEntity;
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.admin.module.business.wms.receive.asnDetail.service.AsnDetailService;
@ -35,14 +28,11 @@ import net.lab1024.sa.admin.module.business.wms.task.domain.entity.TaskEntity;
import net.lab1024.sa.admin.module.business.wms.task.manager.TaskManager;
import net.lab1024.sa.admin.module.business.wms.task.service.TaskQueryService;
import net.lab1024.sa.admin.module.business.wms.task.service.TaskService;
import net.lab1024.sa.admin.module.business.wms.itemKey.domain.entity.ItemKeyEntity;
import net.lab1024.sa.admin.module.business.wms.receive.asn.service.AsnQueryService;
import net.lab1024.sa.admin.util.JoinerResult;
import net.lab1024.sa.admin.util.ResponseDTOUtils;
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.SmartBigDecimalUtil;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
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;
@ -115,13 +105,13 @@ public class ReceiveService {
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> batchReceive(BatchReceiveForm batchReceiveForm) {
Long statrTime = System.currentTimeMillis();
Long startTime = System.currentTimeMillis();
List<AsnDetailEntity> asnDetails = asnDetailQueryService.queryAsnDetailList(batchReceiveForm.getAsnDetailIds());
if (CollectionUtils.isEmpty(asnDetails)) {
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
}
//消息提示
JoinerResult joiner = JoinerResult.createJoiner();
JoinerResult resultMsg = JoinerResult.createJoiner();
//查询物料
List<Long> itemIds = asnDetails.stream().map(AsnDetailEntity::getItemId).distinct().toList();
@ -146,12 +136,12 @@ public class ReceiveService {
ItemEntity item = itemMap.get(asnDetail.getItemId());
if (SmartBigDecimalUtil.subtract(asnDetail.getOrderQuantity(), asnDetail.getReceivedQuantity(), 2).compareTo(BigDecimal.ZERO) == 0) {
joiner.getErrorMsg().add(item.getItemCode() + "明细已收货");
resultMsg.getErrorMsg().add(item.getItemCode() + "明细已收货");
continue;
}
if (asnDetail.getReceivedQuantity().compareTo(asnDetail.getOrderQuantity()) > 0) {
joiner.getErrorMsg().add(item.getItemCode() + "收货数量不能大于订单数量");
resultMsg.getErrorMsg().add(item.getItemCode() + "收货数量不能大于订单数量");
continue;
}
@ -185,7 +175,7 @@ public class ReceiveService {
//生成库存日志
joiner.getSussMsg().add(item.getItemCode() + "收货成功");
resultMsg.getSussMsg().add(item.getItemCode() + "收货成功");
}
//批量操作
@ -195,12 +185,12 @@ public class ReceiveService {
asnDetailService.refreshAsn(batchReceiveForm.getAsnId());
//操作日志
dataTracerService.addTrace(asn.getAsnId(), DataTracerTypeEnum.ASN, "批量收货:" + joiner.getSussMsg().toString() + joiner.getErrorMsg().toString());
dataTracerService.addTrace(asn.getAsnId(), DataTracerTypeEnum.ASN, "批量收货:" + resultMsg.getSussMsg().toString() + resultMsg.getErrorMsg().toString());
Long endTime = System.currentTimeMillis();
log.info("批量收货耗时:{}ms", endTime - statrTime);
log.info("批量收货耗时:{}ms", endTime - startTime);
return ResponseDTOUtils.buildResponseDTO(joiner);
return ResponseDTOUtil.buildResponseDTO(resultMsg);
}
/**
@ -242,14 +232,14 @@ public class ReceiveService {
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> batchReturn(BatchReturnForm batchReturnForm) {
Long statrTime = System.currentTimeMillis();
Long startTime = System.currentTimeMillis();
List<TaskEntity> tasks = taskQueryService.queryByTaskIds(batchReturnForm.getTaskIds());
if (CollectionUtils.isEmpty(tasks)) {
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
}
//消息提示
JoinerResult joiner = JoinerResult.createJoiner();
JoinerResult resultMsg = JoinerResult.createJoiner();
//查询Task任务关联的所以入库明细
List<Long> asnDetailIds = tasks.stream().map(TaskEntity::getAsnDetailId).collect(Collectors.toList());
@ -288,7 +278,7 @@ public class ReceiveService {
}
//生成库存日志
joiner.getSussMsg().add(item.getItemCode() + "退货成功");
resultMsg.getSussMsg().add(item.getItemCode() + "退货成功");
}
//批量操作
returnUpdateOrInsert(updateToAsnDetail, deleteToTask, updateToInventory, deleteToInventory);
@ -297,12 +287,12 @@ public class ReceiveService {
asnDetailService.refreshAsn(batchReturnForm.getAsnId());
//操作日志
dataTracerService.addTrace(batchReturnForm.getAsnId(), DataTracerTypeEnum.ASN, "批量退货:" + joiner.getSussMsg().toString());
dataTracerService.addTrace(batchReturnForm.getAsnId(), DataTracerTypeEnum.ASN, "批量退货:" + resultMsg.getSussMsg().toString());
Long endTime = System.currentTimeMillis();
log.info("批量退货耗时:{}ms", endTime - statrTime);
log.info("批量退货耗时:{}ms", endTime - startTime);
return ResponseDTOUtils.buildResponseDTO(joiner);
return ResponseDTOUtil.buildResponseDTO(resultMsg);
}
/**

View File

@ -9,29 +9,18 @@ import net.lab1024.sa.admin.module.business.wms.receive.asn.constant.AsnOrderSta
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.AsnQueryForm;
import net.lab1024.sa.admin.module.business.wms.receive.asn.domain.form.AsnUpdateForm;
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.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.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.AsnUpdateForm;
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.ResponseDTOUtils;
import net.lab1024.sa.admin.util.ResponseDTOUtil;
import net.lab1024.sa.base.common.code.UserErrorCode;
import net.lab1024.sa.base.common.exception.BusinessException;
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.module.support.datatracer.constant.DataTracerTypeEnum;
import net.lab1024.sa.base.module.support.datatracer.domain.form.DataTracerForm;
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;
@ -127,7 +116,7 @@ public class AsnService {
if (CollectionUtils.isEmpty(idList)) {
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
}
JoinerResult joiner = JoinerResult.createJoiner();
JoinerResult resultMsg = JoinerResult.createJoiner();
//查询批量订单
List<AsnEntity> asnList = asnQueryService.queryAsnList(idList);
@ -147,17 +136,17 @@ public class AsnService {
if (CollectionUtils.isNotEmpty(createAsnList)) {
Set<String> asnCodes = createAsnList.stream().map(AsnEntity::getAsnNumber).collect(Collectors.toSet());
asnManager.removeBatchByIds(createAsnList);
joiner.getSussMsg().add(asnCodes + "订单删除成功");
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());
joiner.getErrorMsg().add(asnCodes + "订单不允许删除");
resultMsg.getErrorMsg().add(asnCodes + "订单不允许删除");
}
return ResponseDTOUtils.buildResponseDTO(joiner);
return ResponseDTOUtil.buildResponseDTO(resultMsg);
}
/**

View File

@ -4,11 +4,9 @@ import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import net.lab1024.sa.admin.module.business.goods.domain.entity.GoodsEntity;
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.base.item.service.ItemService;
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;
@ -17,9 +15,8 @@ import net.lab1024.sa.admin.module.business.wms.receive.asnDetail.domain.entity.
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.base.item.dao.ItemDao;
import net.lab1024.sa.admin.util.JoinerResult;
import net.lab1024.sa.admin.util.ResponseDTOUtils;
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;
@ -121,7 +118,7 @@ public class AsnDetailService {
if (CollectionUtils.isEmpty(idList)) {
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
}
JoinerResult joiner = JoinerResult.createJoiner();
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();
@ -131,24 +128,24 @@ public class AsnDetailService {
for (AsnDetailEntity asnDetail : asnDetails) {
ItemEntity item = mapItem.get(asnDetail.getItemId());
if (asnDetail.getReceivedQuantity().compareTo(BigDecimal.ZERO) > 0) {
joiner.getErrorMsg().add(item.getItemCode() + "明细已收货");
resultMsg.getErrorMsg().add(item.getItemCode() + "明细已收货");
continue;
}
toDeleteList.add(asnDetail.getAsnDetailId());
joiner.getSussMsg().add(item.getItemCode() + "明细删除成功");
resultMsg.getSussMsg().add(item.getItemCode() + "明细删除成功");
}
if (CollectionUtils.isNotEmpty(toDeleteList)) {
//批量删除
asnDetailManager.removeBatchByIds(toDeleteList);
//操作记录
dataTracerService.addTrace(asnIds.get(0), DataTracerTypeEnum.ASN, "批量删除:" + joiner.getSussMsg().toString()+ joiner.getErrorMsg().toString());
dataTracerService.addTrace(asnIds.get(0), DataTracerTypeEnum.ASN, "批量删除:" + resultMsg.getSussMsg().toString()+ resultMsg.getErrorMsg().toString());
}
//刷新出库单
asnIds.forEach(this::refreshAsn);
return ResponseDTOUtils.buildResponseDTO(joiner);
return ResponseDTOUtil.buildResponseDTO(resultMsg);
}
/**
@ -162,26 +159,26 @@ public class AsnDetailService {
if (null == asnDetailId) {
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
}
JoinerResult joiner = JoinerResult.createJoiner();
JoinerResult resultMsg = JoinerResult.createJoiner();
AsnDetailEntity asnDetail = asnDetailDao.selectById(asnDetailId);
ItemEntity item = itemDao.selectById(asnDetail.getItemId());
if (asnDetail.getReceivedQuantity().compareTo(BigDecimal.ZERO) > 0) {
joiner.getErrorMsg().add(item.getItemCode() + "明细已收货");
return ResponseDTOUtils.buildResponseDTO(joiner);
resultMsg.getErrorMsg().add(item.getItemCode() + "明细已收货");
return ResponseDTOUtil.buildResponseDTO(resultMsg);
}
Long asnId = asnDetail.getAsnId();
asnDetailDao.deleteById(asnDetailId);
joiner.getSussMsg().add(item.getItemCode() + "删除成功");
resultMsg.getSussMsg().add(item.getItemCode() + "删除成功");
//刷新出库单
refreshAsn(asnId);
//操作记录
dataTracerService.addTrace(asnId, DataTracerTypeEnum.ASN, "删除:" + joiner.getSussMsg().toString()+ joiner.getErrorMsg().toString());
dataTracerService.addTrace(asnId, DataTracerTypeEnum.ASN, "删除:" + resultMsg.getSussMsg().toString()+ resultMsg.getErrorMsg().toString());
return ResponseDTOUtils.buildResponseDTO(joiner);
return ResponseDTOUtil.buildResponseDTO(resultMsg);
}
public void refreshAsn(Long asnId) {

View File

@ -7,8 +7,8 @@ import org.apache.commons.collections4.CollectionUtils;
import java.util.List;
import java.util.function.Consumer;
public class ResponseDTOUtils {
private ResponseDTOUtils() {
public class ResponseDTOUtil {
private ResponseDTOUtil() {
// 私有构造函数,防止实例化
}
@ -26,7 +26,7 @@ public class ResponseDTOUtils {
if (joiner.getErrorMsg() != null) {
jsonObject.put("error", joiner.getErrorMsg().toString());
}
return ResponseDTO.okMsg(jsonObject.toString());
return ResponseDTO.ok(jsonObject.toString());
}
/**
@ -37,7 +37,7 @@ public class ResponseDTOUtils {
* @param updateBatchFunction
* @param joiner Msg
*/
public static <T> ResponseDTO<String> buildResponseSussDTO(
public static <T> ResponseDTO<String> buildResponseDTO(
List<T> insertList,
List<T> updateList,
Consumer<List<T>> saveBatchFunction,

View File

@ -0,0 +1,30 @@
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);
}
}
}

View File

@ -33,7 +33,6 @@ public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate() {
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
ObjectMapper om = new ObjectMapper();
om.registerModule(new JavaTimeModule())
.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false)
@ -45,7 +44,8 @@ public class RedisConfig {
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// enableDefaultTyping 官方已弃用 所以改为 activateDefaultTyping
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(om,Object.class);
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
template.setKeySerializer(new StringRedisSerializer());

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="example.dao.OrdersDao">
<!-- 查询结果列 -->
<sql id="base_columns">
orders.id,
orders.order_number,
orders.status,
orders.create_time,
orders.updateInfo.operatorName,
orders.updateInfo.operateTime
<!-- 其他列... -->
</sql>
<!-- 分页查询 -->
<select id="queryPage" resultType="example.domain.vo.OrderVO">
SELECT
<include refid="base_columns"/>
FROM orders
<where>
<!-- 其他查询条件... -->
<!-- 用户过滤条件如果是admin则不过滤否则只显示当前操作员的数据 -->
AND (orders.updateInfo.operatorName=#{SESSION_USERS} or orders.updateInfo.operatorName='admin')
</where>
ORDER BY orders.create_time DESC
</select>
<!-- 另一种实现方式使用动态SQL更灵活控制 -->
<select id="queryPageAlt" resultType="example.domain.vo.OrderVO">
SELECT
<include refid="base_columns"/>
FROM orders
<where>
<!-- 其他查询条件... -->
<!-- 当前操作员为admin时不添加过滤条件否则只显示当前操作员的数据 -->
<if test="SESSION_USERS != 'admin'">
AND orders.updateInfo.operatorName=#{SESSION_USERS}
</if>
</where>
ORDER BY orders.create_time DESC
</select>
</mapper>