1 files added
15 files modified
181 ■■■■ changed files
oying-common/src/main/java/com/oying/config/webConfig/ConfigurerAdapter.java 1 ●●●● patch | view | raw | blame | history
oying-common/src/main/java/com/oying/exception/handler/GlobalExceptionHandler.java 16 ●●●● patch | view | raw | blame | history
oying-common/src/main/java/com/oying/utils/DuplicateKeyExceptionUtil.java 51 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/category/view/PlatformCategoryAdminView.java 2 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductController.java 12 ●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQueryCriteria.java 33 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreMapper.java 7 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreController.java 3 ●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCustomerController.java 6 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreMerchantController.java 3 ●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreCreateService.java 3 ●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreService.java 9 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreCreateServiceImpl.java 5 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreServiceImpl.java 22 ●●●● patch | view | raw | blame | history
oying-system/src/main/resources/mapper/pc/category/PlatformCategoryMapper.xml 4 ●●●● patch | view | raw | blame | history
oying-system/src/main/resources/mapper/pc/store/StoreMapper.xml 4 ●●● patch | view | raw | blame | history
oying-common/src/main/java/com/oying/config/webConfig/ConfigurerAdapter.java
@@ -70,6 +70,7 @@
        config.setDateFormat("yyyy-MM-dd HH:mm:ss");
        // 开启引用检测,枚举支持
        config.setWriterFeatures(
                JSONWriter.Feature.WriteLongAsString,
                JSONWriter.Feature.WriteEnumUsingToString,
                JSONWriter.Feature.ReferenceDetection
        );
oying-common/src/main/java/com/oying/exception/handler/GlobalExceptionHandler.java
@@ -1,10 +1,12 @@
package com.oying.exception.handler;
import com.oying.exception.BadRequestException;
import com.oying.exception.EntityExistException;
import com.oying.exception.EntityNotFoundException;
import lombok.extern.slf4j.Slf4j;
import com.oying.exception.BadRequestException;
import com.oying.utils.DuplicateKeyExceptionUtil;
import com.oying.utils.ThrowableUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.validation.FieldError;
@@ -89,6 +91,16 @@
    }
    /**
     * 处理 DuplicateKeyException
     */
    @ExceptionHandler(value = DuplicateKeyException.class)
    public ResponseEntity<ApiError> handleDuplicateKeyException(DuplicateKeyException e) {
        // 打印堆栈信息
        log.error(ThrowableUtil.getStackTrace(e));
        return buildResponseEntity(ApiError.error(BAD_REQUEST.value(), DuplicateKeyExceptionUtil.getDisplayMessage(e)));
    }
    /**
     * 统一返回
     */
    private ResponseEntity<ApiError> buildResponseEntity(ApiError apiError) {
oying-common/src/main/java/com/oying/utils/DuplicateKeyExceptionUtil.java
New file
@@ -0,0 +1,51 @@
package com.oying.utils;
import cn.hutool.core.map.MapUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import java.sql.SQLException;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Slf4j
public class DuplicateKeyExceptionUtil {
    public static final Map<String, String> INDEX_MAPPING = MapUtil.ofEntries(
            MapUtil.entry("pc_store.uk_store_name", "店铺名称")
    );
    /**
     * 获取错误消息
     */
    public static String getDisplayMessage(DuplicateKeyException e) {
        try {
            String indexName = findMySQLDuplicateKey(e);
            String fieldDisplayName = INDEX_MAPPING.getOrDefault(indexName, indexName);
            return Optional.ofNullable(fieldDisplayName).map(o -> o + "已存在").orElse(e.getMessage());
        } catch (Exception ex) {
            log.error("解析'DuplicateKeyException'消息失败", ex);
            return e.getMessage();
        }
    }
    /**
     * 提取索引名称
     */
    public static String findMySQLDuplicateKey(DuplicateKeyException e) {
        if (e.getCause() instanceof SQLException) {
            SQLException sqlEx = (SQLException) e.getCause();
            if (sqlEx.getErrorCode() == 1062) { // MySQL duplicate key error code
                String errorMsg = sqlEx.getMessage();
                // 使用正则提取索引名
                Matcher matcher = Pattern.compile("for key '(.+?)'").matcher(errorMsg);
                if (matcher.find()) {
                    return matcher.group(1);
                }
            }
        }
        return null;
    }
}
oying-system/src/main/java/com/oying/modules/pc/category/view/PlatformCategoryAdminView.java
@@ -14,6 +14,8 @@
    private Integer sortWeight;
    private Long iconId;
    private String iconUrl;
    private Integer active;
oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductController.java
@@ -11,11 +11,13 @@
import com.oying.modules.pc.product.service.ProductImageService;
import com.oying.modules.pc.product.service.ProductLabelService;
import com.oying.modules.pc.product.service.ProductService;
import com.oying.utils.PageResult;
import com.oying.utils.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@@ -65,7 +67,13 @@
    // @PreAuthorize("@el.check('product:list')")
    public ResponseEntity<?> getProductsByPage(ProductQueryCriteria criteria) {
        Page<Object> page = new Page<>(criteria.getPage(), criteria.getSize());
        return ResponseEntity.ok(R.success(productService.queryAll(criteria, page)));
        PageResult<Product> pageResult = productService.queryAll(criteria, page);
        pageResult.getContent().forEach(product -> {
            Long productId = product.getProductId();
            product.setImages(productImageService.queryImagesByProductId(productId));
            product.setLabels(productLabelService.queryLabelsByProductId(productId));
        });
        return ResponseEntity.ok(R.success(pageResult));
    }
    @GetMapping(value = "/{productId}}")
@@ -112,7 +120,7 @@
    //@PreAuthorize("@el.check('merchant:product:add')")
    public ResponseEntity<?> createProduct(@Validated @RequestBody ProductMerchantCreateRequest request) {
        productAdminService.create(request);
        return ResponseEntity.noContent().build();
        return ResponseEntity.status(HttpStatus.CREATED).build();
    }
    @PutMapping
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQueryCriteria.java
@@ -1,8 +1,7 @@
package com.oying.modules.pc.store.domain.dto;
import com.oying.utils.StringUtils;
import lombok.Data;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.util.DigestUtils;
import java.io.Serializable;
@@ -18,13 +17,13 @@
    @ApiModelProperty(value = "商户ID", example = "1")
    private Long merchantId;
    private String storeName;
    private Integer status;
    private Long storeId;
    private Long platformCategoryId;
    private String storeName;
    private Integer status;
    private String blurry;
@@ -44,19 +43,15 @@
    public String buildConditionCacheKey() {
        StringJoiner baseKeyJoiner = new StringJoiner("|");
        if (platformCategoryId != null) {
            baseKeyJoiner.add("platformCategoryId=" + platformCategoryId);
        }
        if (StringUtils.isNotEmpty(blurry)) {
            baseKeyJoiner.add("blurry=" + blurry);
        }
        if (longitude != null && latitude != null) {
            baseKeyJoiner.add("longitude=" + longitude);
            baseKeyJoiner.add("latitude=" + latitude);
        }
        if (StringUtils.isNotEmpty(blurry)) {
            baseKeyJoiner.add("radius=" + radius);
        }
        baseKeyJoiner.add("merchantId=" + merchantId);
        baseKeyJoiner.add("storeId=" + storeId);
        baseKeyJoiner.add("platformCategoryId=" + platformCategoryId);
        baseKeyJoiner.add("storeName=" + storeName);
        baseKeyJoiner.add("status=" + status);
        baseKeyJoiner.add("blurry=" + blurry);
        baseKeyJoiner.add("longitude=" + longitude);
        baseKeyJoiner.add("latitude=" + latitude);
        baseKeyJoiner.add("radius=" + radius);
        // 使用MD5或SHA缩短键长度
        return "store:search:page:" + DigestUtils.md5DigestAsHex(baseKeyJoiner.toString().getBytes());
    }
oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreMapper.java
@@ -3,11 +3,10 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.oying.modules.pc.store.domain.Store;
import com.oying.modules.pc.search.domain.dto.NearbyStoreQueryCriteria;
import com.oying.modules.pc.store.domain.dto.StoreCustomerQueryCriteria;
import com.oying.modules.pc.store.domain.dto.StoreQueryCriteria;
import com.oying.modules.pc.search.domain.dto.StoreSearchDto;
import com.oying.modules.pc.store.domain.Store;
import com.oying.modules.pc.store.domain.dto.StoreQueryCriteria;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@@ -22,7 +21,7 @@
@Mapper
public interface StoreMapper extends BaseMapper<Store> {
    List<Store> selectStoreList(@Param("criteria") StoreQueryCriteria criteria, Page<Store> page);
    IPage<Store> selectStoreList(@Param("criteria") StoreQueryCriteria criteria, Page<Store> page);
    List<Store> selectStoreList(@Param("criteria") StoreQueryCriteria criteria);
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreController.java
@@ -57,8 +57,7 @@
    @PostMapping
    @ApiOperation("创建店铺")
    public ResponseEntity<?> create(@RequestBody StoreCreateRequest request) {
        storeService.create(request);
        return ResponseEntity.status(HttpStatus.CREATED).build();
        return ResponseEntity.status(HttpStatus.CREATED).body(R.success(storeService.create(request)));
    }
    @PostMapping(value = "/{storeId}")
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCustomerController.java
@@ -46,11 +46,9 @@
    @GetMapping(value = "/page")
    @ApiOperation("查询店铺")
    public ResponseEntity<?> getStoresByPage(StoreQueryCriteria criteria) {
        criteria.setLimit(1000);
        PageResult<Store> pagedStores = storeQueryService.findPagedStores(criteria);
        List<Store> stores = pagedStores.getContent();
        for (Store store : stores) {
            store.setProducts(this.getProductsByStoreId(store.getStoreId()));
        }
        pagedStores.getContent().forEach(store -> store.setProducts(this.getProductsByStoreId(store.getStoreId())));
        return ResponseEntity.ok(R.success(pagedStores));
    }
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreMerchantController.java
@@ -93,8 +93,7 @@
    @ApiOperation("创建店铺")
    //@PreAuthorize("@el.check('merchant:store:create')")
    public ResponseEntity<?> create(@RequestBody StoreCreateRequest request) {
        storeCreateService.create(request);
        return ResponseEntity.status(HttpStatus.CREATED).build();
        return ResponseEntity.status(HttpStatus.CREATED).body(storeCreateService.create(request));
    }
    /**
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreCreateService.java
@@ -1,7 +1,8 @@
package com.oying.modules.pc.store.service;
import com.oying.modules.pc.store.domain.Store;
import com.oying.modules.pc.store.domain.dto.StoreCreateRequest;
public interface StoreCreateService {
    void create(StoreCreateRequest request);
    Store create(StoreCreateRequest request);
}
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreService.java
@@ -2,8 +2,9 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.oying.modules.pc.store.domain.Store;
import com.oying.modules.pc.store.domain.StoreCategory;
import com.oying.modules.pc.store.domain.dto.*;
import com.oying.modules.pc.store.domain.dto.StoreCreateRequest;
import com.oying.modules.pc.store.domain.dto.StoreQueryCriteria;
import com.oying.modules.pc.store.domain.dto.StoreUpdateRequest;
import com.oying.utils.PageResult;
import java.math.BigDecimal;
@@ -26,7 +27,7 @@
    List<Store> queryUserStores(Long userId);
    boolean create(StoreCreateRequest request);
    Store create(StoreCreateRequest request);
    boolean update(StoreUpdateRequest request);
@@ -55,4 +56,6 @@
    boolean updateStatus(Long storeId, Integer status, Long version);
    boolean existsByIdAndMerchantId(Long storeId, Long merchantId);
    boolean existsStoreName(String storeName);
}
oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreCreateServiceImpl.java
@@ -1,5 +1,6 @@
package com.oying.modules.pc.store.service.impl;
import com.oying.modules.pc.store.domain.Store;
import com.oying.modules.pc.store.domain.dto.StoreCreateRequest;
import com.oying.modules.pc.store.service.StoreCreateService;
import com.oying.modules.pc.store.service.StoreService;
@@ -16,7 +17,7 @@
    private final StoreService storeService;
    @Transactional(rollbackFor = Exception.class)
    public void create(StoreCreateRequest request) {
        storeService.create(request);
    public Store create(StoreCreateRequest request) {
        return storeService.create(request);
    }
}
oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreServiceImpl.java
@@ -7,7 +7,7 @@
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.BadRequestException;
import com.oying.exception.EntityNotFoundException;
import com.oying.modules.pc.common.ValueUpdate;
import com.oying.modules.pc.store.converter.StoreAssembler;
@@ -27,6 +27,7 @@
import com.oying.utils.PageResult;
import com.oying.utils.PageUtil;
import com.oying.utils.SecurityUtils;
import com.oying.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -79,12 +80,17 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean create(StoreCreateRequest request) {
    public Store create(StoreCreateRequest request) {
        // 检查店铺名称是否存在
        if (this.existsStoreName(request.getStoreName())) {
            throw new BadRequestException("店铺名称已存在");
        }
        // 创建店铺
        Store store = StoreAssembler.to(request);
        storeMapper.insert(store);
        this.processQualificationCreate(store, request.getQualificationList());
        this.bindUser(store.getStoreId());
        return true;
        return store;
    }
    @Override
@@ -198,6 +204,16 @@
    }
    @Override
    public boolean existsStoreName(String storeName) {
        if (StringUtils.isEmpty(storeName)) {
            return true;
        }
        LambdaQueryWrapper<Store> wrapper = new LambdaQueryWrapper<Store>()
                .eq(Store::getStoreName, storeName);
        return storeMapper.selectCount(wrapper) > 0;
    }
    @Override
    public boolean existsByIdAndMerchantId(Long storeId, Long merchantId) {
        if (storeId == null || merchantId == null) {
            return false;
oying-system/src/main/resources/mapper/pc/category/PlatformCategoryMapper.xml
@@ -8,7 +8,7 @@
        <result column="level" property="level"/>
        <result column="sort_weight" property="sortWeight"/>
        <result column="icon_id" property="iconId"/>
        <result column="icon_url" property="iconId"/>
        <result column="icon_url" property="iconUrl"/>
        <result column="status" property="status"/>
        <result column="active" property="active"/>
        <result column="create_by" property="createBy"/>
@@ -18,7 +18,7 @@
    </resultMap>
    <sql id="Base_Column_List">
        category_id, parent_id, name, level, sort_weight, icon_id, status, active, create_by, create_time, update_by, update_time
        category_id, parent_id, name, level, sort_weight, icon_id, icon_url, status, active, create_by, create_time, update_by, update_time
    </sql>
    <select id="findAll" resultMap="BaseResultMap">
oying-system/src/main/resources/mapper/pc/store/StoreMapper.xml
@@ -135,7 +135,9 @@
                AND s.platform_category_id = #{criteria.platformCategoryId}
            </if>
        </where>
        LIMIT 1000
        <if test="criteria.limit != null">
            limit #{criteria.limit}
        </if>
    </select>
    <select id="queryUserStores" parameterType="java.lang.Long" resultMap="StoreResult">