package com.oying.modules.pc.store.service.impl; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.util.ObjUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.oying.exception.EntityExistException; import com.oying.exception.EntityNotFoundException; import com.oying.modules.pc.common.ValueUpdate; import com.oying.modules.pc.store.converter.StoreAssembler; import com.oying.modules.pc.store.converter.StoreQualificationAssembler; import com.oying.modules.pc.store.domain.Store; import com.oying.modules.pc.store.domain.StoreQualification; import com.oying.modules.pc.store.domain.StoreUser; import com.oying.modules.pc.store.domain.dto.StoreCreateRequest; import com.oying.modules.pc.store.domain.dto.StoreQualificationCreateRequest; import com.oying.modules.pc.store.domain.dto.StoreQueryCriteria; import com.oying.modules.pc.store.domain.dto.StoreUpdateRequest; import com.oying.modules.pc.store.mapper.StoreMapper; import com.oying.modules.pc.store.mapper.StoreUserMapper; import com.oying.modules.pc.store.service.StoreQualificationService; import com.oying.modules.pc.store.service.StoreService; import com.oying.service.BucketStorageService; import com.oying.utils.PageResult; import com.oying.utils.PageUtil; import com.oying.utils.SecurityUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.time.LocalTime; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; /** * 店铺Service业务层处理 * * @author lzp * @date 2025-04-22 */ @Slf4j @Service @RequiredArgsConstructor public class StoreServiceImpl extends ServiceImpl implements StoreService { private final StoreMapper storeMapper; private final StoreUserMapper storeUserMapper; private final StoreQualificationService qualificationService; private final BucketStorageService bucketStorageService; @Override public PageResult queryByPage(StoreQueryCriteria criteria) { Page page = new Page<>(criteria.getPage(), criteria.getSize()); return PageUtil.toPage(storeMapper.selectStoreList(criteria, page)); } @Override public List queryAll(StoreQueryCriteria criteria) { return storeMapper.selectStoreList(criteria); } @Override public Store getMerchantStore(Long merchantId) { return storeMapper.selectStoreByMerchantId(merchantId); } @Override public List queryUserStores(Long userId) { return storeMapper.queryUserStores(userId); } @Override @Transactional(rollbackFor = Exception.class) public boolean create(StoreCreateRequest request) { Store store = StoreAssembler.to(request); storeMapper.insert(store); this.processQualificationCreate(store, request.getQualificationList()); this.bindUser(store.getStoreId()); return true; } @Override @Transactional(rollbackFor = Exception.class) public boolean update(StoreUpdateRequest request) { Store existingStore = this.findOrThrow(request); this.processImagesUpdate(request, existingStore); this.processQualificationUpdate(request); existingStore.copy(StoreAssembler.to(request)); LambdaUpdateWrapper wrapper = this.createLambdaUpdateWrapper(existingStore.getStoreId(), existingStore.getVersion()); return this.update(existingStore, wrapper); } @Override @Transactional(rollbackFor = Exception.class) public boolean updateLogo(Long storeId, String logo, Long version) { Store existingStore = this.findOrThrow(storeId, version); LambdaUpdateWrapper wrapper = this.createLambdaUpdateWrapper(storeId, existingStore.getVersion()) .set(Store::getLogoImageId, logo); return update(wrapper); } @Override public boolean updateName(Long storeId, String storeName, Long version) { Store existingStore = this.findOrThrow(storeId, version); LambdaUpdateWrapper wrapper = this.createLambdaUpdateWrapper(storeId, existingStore.getVersion()) .set(Store::getStoreName, storeName); return update(wrapper); } @Override public boolean updateDescription(Long storeId, String description, Long version) { Store existingStore = this.findOrThrow(storeId, version); LambdaUpdateWrapper wrapper = this.createLambdaUpdateWrapper(storeId, existingStore.getVersion()) .set(Store::getDescription, description); return update(wrapper); } @Override public boolean updateContactPhone(Long storeId, String contactPhone, Long version) { Store existingStore = this.findOrThrow(storeId, version); LambdaUpdateWrapper wrapper = this.createLambdaUpdateWrapper(storeId, existingStore.getVersion()) .set(Store::getContactPhone, contactPhone); return update(wrapper); } @Override public boolean updateAddress(Long storeId, String address, Long version) { Store existingStore = this.findOrThrow(storeId, version); LambdaUpdateWrapper wrapper = this.createLambdaUpdateWrapper(storeId, existingStore.getVersion()) .set(Store::getAddress, address); return update(wrapper); } @Override public boolean updateLocation(Long storeId, Double longitude, Double latitude, Long version) { Store existingStore = this.findOrThrow(storeId, version); LambdaUpdateWrapper wrapper = this.createLambdaUpdateWrapper(storeId, existingStore.getVersion()) .set(Store::getLongitude, longitude) .set(Store::getLatitude, latitude); return update(wrapper); } @Override public boolean updateRadius(Long storeId, Integer radius, Long version) { Store existingStore = this.findOrThrow(storeId, version); LambdaUpdateWrapper wrapper = this.createLambdaUpdateWrapper(storeId, existingStore.getVersion()) .set(Store::getRadius, radius); return update(wrapper); } @Override public boolean updatePlatformCategory(Long storeId, Long platformCategory, Long version) { Store existingStore = this.findOrThrow(storeId, version); LambdaUpdateWrapper wrapper = this.createLambdaUpdateWrapper(storeId, existingStore.getVersion()) .set(Store::getPlatformCategoryId, platformCategory); return update(wrapper); } @Override public boolean updateBusinessHours(Long storeId, LocalTime openTime, LocalTime endTime, Long version) { Store existingStore = this.findOrThrow(storeId, version); LambdaUpdateWrapper wrapper = this.createLambdaUpdateWrapper(storeId, existingStore.getVersion()) .set(Store::getOpenTime, openTime) .set(Store::getCloseTime, endTime); return update(wrapper); } @Override public boolean updateDeliveryMinimum(Long storeId, BigDecimal deliveryMinimum, Long version) { Store existingStore = this.findOrThrow(storeId, version); LambdaUpdateWrapper wrapper = this.createLambdaUpdateWrapper(storeId, existingStore.getVersion()) .set(Store::getDeliveryMinimum, deliveryMinimum); return update(wrapper); } @Override public boolean updateDeliveryFee(Long storeId, BigDecimal deliveryFee, Long version) { Store existingStore = this.findOrThrow(storeId, version); LambdaUpdateWrapper wrapper = this.createLambdaUpdateWrapper(storeId, existingStore.getVersion()) .set(Store::getDeliveryFee, deliveryFee); return update(wrapper); } @Override public boolean updateStatus(Long storeId, Integer status, Long version) { Store existingStore = this.findOrThrow(storeId, version); LambdaUpdateWrapper wrapper = this.createLambdaUpdateWrapper(storeId, existingStore.getVersion()) .set(Store::getStatus, status); return update(wrapper); } @Override public boolean existsByIdAndMerchantId(Long storeId, Long merchantId) { if (storeId == null || merchantId == null) { return false; } Store store = getById(storeId); return Optional.ofNullable(store).map(i -> merchantId.equals(i.getMerchantId())).orElse(false); } private void processQualificationCreate(Store store, List qualificationRequests) { if (CollectionUtil.isNotEmpty(qualificationRequests)) { List storeQualificationList = qualificationRequests.stream().map(i -> { i.setStoreId(store.getStoreId()); return StoreQualificationAssembler.to(i); }).collect(Collectors.toList()); storeQualificationList.forEach(i -> i.setStoreId(store.getStoreId())); qualificationService.batchCreate(storeQualificationList); } } private void bindUser(Long storeId) { StoreUser storeUser = new StoreUser(); storeUser.setStoreId(storeId); storeUser.setUserId(SecurityUtils.getCurrentUserId()); storeUser.setRoleType(""); storeUser.setPermissions(""); storeUserMapper.insert(storeUser); } private LambdaUpdateWrapper createLambdaUpdateWrapper(Long storeId, Long version) { Objects.requireNonNull(storeId, String.format("方法 '%s' 调用失败:参数 'storeId'(店铺ID)不能为 null", "createLambdaUpdateWrapper")); LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); updateWrapper.eq(Store::getStoreId, storeId); if (ObjUtil.isNotEmpty(version)) { updateWrapper.eq(Store::getVersion, version); updateWrapper.set(Store::getVersion, version + 1); } updateWrapper.set(Store::getUpdateBy, SecurityUtils.getCurrentUserId()); return updateWrapper; } private Store findOrThrow(StoreUpdateRequest request) { return this.findOrThrow(request.getStoreId(), request.getVersion()); } private Store findOrThrow(Long storeId, Long version) { Objects.requireNonNull(storeId, String.format("方法 '%s' 调用失败:参数 'storeId'(店铺ID)不能为 null", "findOrThrow")); LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(Store::getStoreId, storeId); if (ObjUtil.isNotEmpty(version)) { wrapper.eq(Store::getVersion, version); } Store existingStore = storeMapper.selectOne(wrapper); if (ObjUtil.isEmpty(existingStore)) { throw new EntityNotFoundException(Store.class, "storeId", storeId.toString()); } return existingStore; } private List getDeleteImageIds(List> imageValues) { List deleteImageIds = new ArrayList<>(); for (ValueUpdate imageValue : imageValues) { if (imageValue.isChangeAndOldValueNotEmpty()) { deleteImageIds.add(imageValue.getOldValue()); } } return deleteImageIds; } private void processImagesUpdate(StoreUpdateRequest request, Store existingStore) { List> imageValues = ListUtil.toList( new ValueUpdate<>(request.getLogoImageId(), existingStore.getLogoImageId()), new ValueUpdate<>(request.getCoverImageId(), existingStore.getCoverImageId()) ); bucketStorageService.deleteAll(this.getDeleteImageIds(imageValues)); } private void processQualificationUpdate(StoreUpdateRequest request) { if (CollectionUtil.isNotEmpty(request.getDeletedQualificationIds())) { qualificationService.deleteAll(request.getDeletedQualificationIds()); } if (CollectionUtil.isNotEmpty(request.getUpdatedQualifications())) { qualificationService.batchUpdate(request.getUpdatedQualifications()); } if (CollectionUtil.isNotEmpty(request.getNewQualifications())) { qualificationService.batchCreate(request.getNewQualifications()); } } }