no message
parent
184717674f
commit
8a2337e458
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
@Resource
|
||||
private CacheManager cacheManager;
|
||||
|
||||
// 使用读写锁保证高并发下的缓存操作安全
|
||||
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
|
||||
private final Lock readLock = rwLock.readLock();
|
||||
private final Lock writeLock = rwLock.writeLock();
|
||||
|
||||
/**
|
||||
* 移除所以缓存
|
||||
* 查询物料(带缓存)
|
||||
* 使用Spring Cache自动缓存查询结果
|
||||
*/
|
||||
@CacheEvict(value = {AdminCacheConst.Base.ITEM_ENTITY}, allEntries = true)
|
||||
public void removeCache() {
|
||||
log.info("clear ITEM_ENTITY");
|
||||
@Cacheable(value = AdminCacheConst.Base.ITEM_ENTITY, key = "#itemId", unless = "#result == null")
|
||||
public ItemEntity queryItem(Long itemId) {
|
||||
try {
|
||||
readLock.lock();
|
||||
return itemDao.selectById(itemId);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查詢物料
|
||||
* 创建物料(带缓存)
|
||||
* 事务提交后执行缓存刷新,保证数据一致性
|
||||
*/
|
||||
@Cacheable(AdminCacheConst.Base.ITEM_ENTITY)
|
||||
public ItemEntity queryItem(Long itemId) {
|
||||
return itemDao.selectById(itemId);
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ItemEntity insert(ItemEntity entity) {
|
||||
super.save(entity);
|
||||
// 在事务提交后刷新缓存,确保数据库操作成功后再更新缓存
|
||||
executeAfterCommit("刷新物料缓存", () -> refreshCache(entity.getItemId()));
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新物料(带缓存)
|
||||
* 事务提交后执行缓存刷新,保证数据一致性
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ItemEntity update(ItemEntity entity) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
Loading…
Reference in New Issue