删除已废弃店铺分类 shop_store_biz_category 表,增加顺丰创建店铺方法,配送表增加三个字段

This commit is contained in:
Jack 2025-08-14 19:23:27 +08:00
parent 1100878b92
commit bf7489138f
17 changed files with 362 additions and 567 deletions

View File

@ -67,6 +67,14 @@ public class CommonConstant {
public static final Integer CONTRACT_SIGN_STA_REJECT = 7;
// 配送品牌1-顺丰同城2-美团配送3-达达快送4-京东秒送5-闪送6-UU跑腿
public static final Integer DELIVERY_BRAND_SF = 1;
public static final Integer DELIVERY_BRAND_MT = 2;
public static final Integer DELIVERY_BRAND_DD = 3;
public static final Integer DELIVERY_BRAND_JDMS = 4;
public static final Integer DELIVERY_BRAND_SS = 5;
public static final Integer DELIVERY_BRAND_UUPT = 6;
/**
* 推送消息类别Contract-商家入驻合同orderList-商家订单列表orderDetail-商家订单详情
* * mchContract-商家入驻合同
@ -83,5 +91,5 @@ public class CommonConstant {
public static final String PUSH_MSG_CATE_MCH_RETURN_ORDER_LIST = "mchRetrunOrderList";
public static final String CONF_KEY_SAME_CITY_ORDER_EXPIRE_SECONDS = "sameCityOrderExpireSeconds";
}

View File

@ -46,7 +46,7 @@ public class ShopStoreSameCityTransportBase implements Serializable {
@ApiModelProperty(value = "店铺ID")
private Long store_id;
@ApiModelProperty(value = "顺丰同城店铺ID")
@ApiModelProperty(value = "顺丰同城(第三方)店铺ID")
private String shop_id;
@ApiModelProperty(value = "店铺主营商品分类ID")
@ -88,6 +88,15 @@ public class ShopStoreSameCityTransportBase implements Serializable {
@ApiModelProperty(value = "重量每增加n公斤的配送费增加")
private BigDecimal weight_increase_fee;
@ApiModelProperty(value = "第三方店铺审核状态1-已审核2-未审核;")
private Integer shop_state;
@ApiModelProperty(value = "配送品牌1-顺丰同城2-美团配送3-达达快送4-京东秒送5-闪送6-UU跑腿")
private Integer delivery_brand;
@ApiModelProperty(value = "第三方店铺信息 JSON 格式")
private String shop_info;
@ApiModelProperty(value = "状态1-有效2-无效;")
private Integer status;

View File

@ -0,0 +1,138 @@
/*
* Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.suisung.mall.common.pojo.to;
/**
* 地址解析结果类
*/
public class AddressParseResultTO implements java.io.Serializable {
/**
* /自治区/直辖市
*/
private String province;
/**
* /自治州/地区
*/
private String city;
/**
* //县级市
*/
private String district;
/**
* // 拼接的地址格式如"广西壮族自治区/贵港市/桂平市"
*/
private String joinArea;
/**
* 详细地址
*/
private String detailAddress;
public AddressParseResultTO() {
this.province = "";
this.city = "";
this.district = "";
this.joinArea = "";
this.detailAddress = "";
}
public AddressParseResultTO(String province, String city, String district, String detailAddress) {
this.province = province != null ? province : "";
this.city = city != null ? city : "";
this.district = district != null ? district : "";
this.detailAddress = detailAddress != null ? detailAddress : "";
this.joinArea = buildJoinArea();
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province != null ? province : "";
this.joinArea = buildJoinArea();
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city != null ? city : "";
this.joinArea = buildJoinArea();
}
public String getDistrict() {
return district;
}
public void setDistrict(String district) {
this.district = district != null ? district : "";
this.joinArea = buildJoinArea();
}
public String getJoinArea() {
return joinArea;
}
public void setJoinArea(String joinArea) {
this.joinArea = joinArea != null ? joinArea : "";
}
public String getDetailAddress() {
return detailAddress;
}
public void setDetailAddress(String detailAddress) {
this.detailAddress = detailAddress != null ? detailAddress : "";
}
/**
* 构建省//区拼接地址
*
* @return 拼接后的地址格式如"广西壮族自治区/贵港市/桂平市"
*/
private String buildJoinArea() {
StringBuilder sb = new StringBuilder();
if (province != null && !province.isEmpty()) {
sb.append(province);
}
if (city != null && !city.isEmpty()) {
if (sb.length() > 0) {
sb.append("/");
}
sb.append(city);
}
if (district != null && !district.isEmpty()) {
if (sb.length() > 0) {
sb.append("/");
}
sb.append(district);
}
return sb.toString();
}
@Override
public String toString() {
return "AddressParseResultTO{" +
"province='" + province + '\'' +
", city='" + city + '\'' +
", district='" + district + '\'' +
", joinArea='" + joinArea + '\'' +
", detailAddress='" + detailAddress + '\'' +
'}';
}
}

View File

@ -0,0 +1,123 @@
package com.suisung.mall.common.utils;
import com.suisung.mall.common.pojo.to.AddressParseResultTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 地址处理工具类
* 用于解析完整地址为省区和详细地址等部分
*/
public class AddressUtil {
private static final Logger logger = LoggerFactory.getLogger(AddressUtil.class);
// 省级行政区划关键词
private static final String[] PROVINCE_KEYWORDS = {
"", "自治区", "特别行政区", "" // 直辖市
};
// 市级行政区划关键词
private static final String[] CITY_KEYWORDS = {
"", "自治州", "地区", ""
};
// 区县级行政区划关键词
private static final String[] DISTRICT_KEYWORDS = {
"", "", "", "自治县", "", "自治旗", "县级市"
};
/**
* 将完整地址切分为省区和详细地址
*
* @param fullAddress 完整地址例如"广西壮族自治区贵港市桂平市西山镇新安街粤桂花城1102号"
* @return AddressParseResultTO 包含provincecitydistrictdetailAddress的地址解析结果对象
*/
public static AddressParseResultTO parseAddress(String fullAddress) {
AddressParseResultTO result = new AddressParseResultTO();
if (com.suisung.mall.common.utils.StringUtils.isBlank(fullAddress)) {
return result;
}
try {
String remainingAddress = fullAddress;
// 提取省/自治区/直辖市
String province = extractArea(remainingAddress, PROVINCE_KEYWORDS);
if (!province.isEmpty()) {
result.setProvince(province);
remainingAddress = remainingAddress.substring(province.length());
}
// 提取市/自治州/地区
String city = extractArea(remainingAddress, CITY_KEYWORDS);
if (!city.isEmpty()) {
result.setCity(city);
remainingAddress = remainingAddress.substring(city.length());
}
// 提取区//县级市
String district = extractArea(remainingAddress, DISTRICT_KEYWORDS);
if (!district.isEmpty()) {
result.setDistrict(district);
remainingAddress = remainingAddress.substring(district.length());
}
// 剩余部分为详细地址
result.setDetailAddress(remainingAddress.trim());
} catch (Exception e) {
logger.error("解析地址时发生异常: {}", e.getMessage(), e);
result.setDetailAddress(fullAddress);
}
return result;
}
/**
* 从地址中提取指定级别的行政区域
*
* @param address 地址字符串
* @param keywords 匹配关键词数组
* @return 提取到的行政区域名称
*/
private static String extractArea(String address, String[] keywords) {
for (String keyword : keywords) {
int index = address.indexOf(keyword);
if (index != -1) {
// 特殊处理直辖市的情况"北京市"
if (keyword.equals("") && index == 0) {
// 查找下一个""可能是区县
int nextIndex = address.indexOf("", index + 1);
if (nextIndex > 0) {
return address.substring(0, nextIndex + 1);
}
}
return address.substring(0, index + keyword.length());
}
}
return "";
}
/**
* 使用示例
* <p>
* String fullAddress = "广西壮族自治区贵港市桂平市西山镇新安街粤桂花城1102号";
* AddressParseResultTO parsedAddress = AddressUtil.parseAddress(fullAddress);
* <p>
* System.out.println("省: " + parsedAddress.getProvince()); // 广西壮族自治区
* System.out.println("市: " + parsedAddress.getCity()); // 贵港市
* System.out.println("区: " + parsedAddress.getDistrict()); // 桂平市
* System.out.println("详细地址: " + parsedAddress.getDetailAddress()); // 西山镇新安街粤桂花城1102号
*/
public static void main(String[] args) {
String fullAddress = "广西壮族自治区贵港市桂平市西山镇新安街粤桂花城1102号";
AddressParseResultTO parsedAddress = AddressUtil.parseAddress(fullAddress);
System.out.println("省: " + parsedAddress.getProvince());
System.out.println("市: " + parsedAddress.getCity());
System.out.println("区: " + parsedAddress.getDistrict());
System.out.println("省市区: " + parsedAddress.getJoinArea());
System.out.println("详细地址: " + parsedAddress.getDetailAddress());
}
}

View File

@ -23,7 +23,6 @@ import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
@ -62,8 +61,7 @@ public final class StringUtils extends org.apache.commons.lang3.StringUtils {
"(?<province>(\\w+省|\\w+自治区))?(?<city>(\\w+市|\\w+自治州))?(?<district>(\\w+区|\\w+县|\\w+市辖区|\\w+市))?";
public static void main(String[] args) {
// System.out.println(removeProvinceCityDistrict("广西壮族自治区贵港市桂平市西山镇新安街粤桂花城1102号"));
System.out.println(validateIDCard("45088119970105771X"));
// System.out.println(validateIDCard("45088119970105771X"));
}
public static String encode(String str) {
@ -300,66 +298,6 @@ public final class StringUtils extends org.apache.commons.lang3.StringUtils {
return base64.substring(0, length);
}
/**
* 去除省市区保留详细地址
*
* @param fullAddress
* @return
*/
public static String removeProvinceCityDistrict(String fullAddress) {
if (StringUtils.isBlank(fullAddress)) {
return "";
}
try {
Pattern pattern = Pattern.compile(PROVINCE_CITY_DISTRICT_REGEX);
Matcher matcher = pattern.matcher(fullAddress);
if (!matcher.find()) {
return fullAddress;
}
StringBuilder result = new StringBuilder(fullAddress);
// Remove matched groups in reverse order to avoid index shifting issues
if (matcher.group("district") != null) {
result.replace(matcher.start("district"), matcher.end("district"), "");
}
if (matcher.group("city") != null) {
result.replace(matcher.start("city"), matcher.end("city"), "");
}
if (matcher.group("province") != null) {
result.replace(matcher.start("province"), matcher.end("province"), "");
}
return result.toString().trim();
} catch (Exception e) {
// Log the exception for debugging purposes
System.err.println("Error processing address: " + e.getMessage());
return fullAddress; // Return original address on failure
}
}
/**
* 去除省市区保留详细地址
*
* @param fullAddress
* @return
*/
public static String removeProvinceCityDistrict2(String fullAddress) {
// 定义省市县区的关键字
String[] keywords = {"", "", "自治区", "特别行政区", "地区", "", "自治州", "", "", "自治县", "", "自治旗", "县级市"};
for (String keyword : keywords) {
int index = fullAddress.indexOf(keyword);
if (index != -1) {
// 若找到关键字截取关键字之后的部分
fullAddress = fullAddress.substring(index + keyword.length());
}
}
return fullAddress;
}
/**
* 判断字符串是否是XML或JSON格式
*

View File

@ -19,9 +19,10 @@ import com.suisung.mall.common.api.ResultCode;
import com.suisung.mall.common.constant.CommonConstant;
import com.suisung.mall.common.domain.UserDto;
import com.suisung.mall.common.modules.store.ShopMchEntry;
import com.suisung.mall.common.pojo.to.AddressParseResultTO;
import com.suisung.mall.common.service.impl.CommonService;
import com.suisung.mall.common.utils.AddressUtil;
import com.suisung.mall.common.utils.RestTemplateHttpUtil;
import com.suisung.mall.common.utils.StringUtils;
import com.suisung.mall.common.utils.UploadUtil;
import com.suisung.mall.core.web.service.RedisService;
import com.suisung.mall.shop.lakala.service.LklBanksService;
@ -349,7 +350,8 @@ public class LklTkServiceImpl {
formData.put("email", shopMchEntry.getEmail());
formData.put("merRegName", shopMchEntry.getStore_name());
formData.put("merName", shopMchEntry.getStore_name());
formData.put("merAddr", StringUtils.removeProvinceCityDistrict(shopMchEntry.getStore_address()));
AddressParseResultTO addressParseResultTO = AddressUtil.parseAddress(shopMchEntry.getStore_address());
formData.put("merAddr", addressParseResultTO.getDetailAddress());
// 是企业类型商家
Boolean isQy = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type());

View File

@ -3,7 +3,8 @@ package com.suisung.mall.shop.order.service.impl;
import cn.hutool.core.util.StrUtil;
import com.suisung.mall.common.modules.order.ShopOrderDeliveryAddress;
import com.suisung.mall.common.pojo.dto.StandardAddressDTO;
import com.suisung.mall.common.utils.StringUtils;
import com.suisung.mall.common.pojo.to.AddressParseResultTO;
import com.suisung.mall.common.utils.AddressUtil;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.shop.order.mapper.ShopOrderDeliveryAddressMapper;
import com.suisung.mall.shop.order.service.ShopOrderDeliveryAddressService;
@ -59,10 +60,10 @@ public class ShopOrderDeliveryAddressServiceImpl extends BaseServiceImpl<ShopOrd
sb.append(shopOrderDeliveryAddress.getDa_county());
}
if (StrUtil.isNotBlank(shopOrderDeliveryAddress.getDa_address())) {
sb.append(StringUtils.removeProvinceCityDistrict(shopOrderDeliveryAddress.getDa_address()));
AddressParseResultTO addressParseResultTO = AddressUtil.parseAddress(shopOrderDeliveryAddress.getDa_address());
sb.append(addressParseResultTO.getDetailAddress());
}
StandardAddressDTO standardAddressDTO = new StandardAddressDTO();
if (StrUtil.isBlank(shopOrderDeliveryAddress.getDa_address()) || StrUtil.isBlank(shopOrderDeliveryAddress.getDa_longitude()) || StrUtil.isBlank(shopOrderDeliveryAddress.getDa_latitude())) {
if (StrUtil.isBlank(shopOrderDeliveryAddress.getDa_longitude())) {

View File

@ -21,11 +21,16 @@ import org.springframework.web.bind.annotation.*;
@RequestMapping("/shop/sf-express")
public class SFExpressApiController {
//private final CopyOnWriteArrayList<SseEmitter> emitters = new CopyOnWriteArrayList<>();
@Lazy
@Autowired
private SFExpressApiService sfExpressApiService;
@ApiOperation(value = "创建顺丰同城店铺-连锁店铺回调", notes = "创建顺丰同城店铺-连锁店铺回调")
@RequestMapping(value = "/create-shop/notify", method = RequestMethod.POST)
public ThirdApiRes createSfExpressShopNotify(@RequestBody String requestBody, @RequestParam(name = "sign") String sign) {
return sfExpressApiService.createSfExpressShopNotify(requestBody, sign);
}
@ApiOperation(value = "顺丰原因订单取消回调", notes = "顺丰原因订单取消回调")
@RequestMapping(value = "/cancel-order/notify", method = RequestMethod.POST)
public ThirdApiRes cancelOrderNotify(@RequestBody String requestBody, @RequestParam(name = "sign") String sign) {

View File

@ -31,6 +31,16 @@ public interface SFExpressApiService {
*/
Pair<Boolean, String> createSfExpressShop(Integer storeId, String shopName, String cityName, String shopAddress, String contactName, String contactPhone, String longitude, String latitude);
/**
* 创建顺丰同城店铺-连锁店铺回调
*
* @param jsonData
* @param sign
* @return
*/
ThirdApiRes createSfExpressShopNotify(String jsonData, String sign);
ThirdApiRes createOrder(String shopOrderId);
/**

View File

@ -108,15 +108,16 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
*/
@Override
public Pair<Boolean, String> createSfExpressShop(Integer storeId, String shopName, String cityName,
String shopAddress, String contactName, String contactPhone, String longitude, String latitude) {
String shopAddress, String contactName, String contactPhone,
String longitude, String latitude) {
logger.info("开始创建顺丰同城店铺, storeId: {}", storeId);
// 验证必要参数
// 1. 验证必要参数
if (CheckUtil.isEmpty(storeId) || StringUtils.isAnyBlank(shopName, shopAddress, contactName, contactPhone)) {
return Pair.of(false, "顺丰同城店铺,缺少必要参数!");
}
// 获取或初始化商家配送信息
// 2. 获取或初始化商家配送信息
ShopStoreSameCityTransportBase transportBase = shopStoreSameCityTransportBaseService
.getShopStoreSameCityTransportBaseById(Long.valueOf(storeId));
@ -124,29 +125,33 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
// 如果没有商家配送运费设置则初始化
Pair<Boolean, String> initResult = shopStoreSameCityTransportBaseService.initDefaultSameCityTransport(storeId);
if (!initResult.getFirst()) {
logger.error("初始化商家配送运费设置失败!");
return initResult;
}
transportBase = shopStoreSameCityTransportBaseService.getShopStoreSameCityTransportBaseById(Long.valueOf(storeId));
}
// 如果已存在顺丰店铺ID验证其有效性
// if (CheckUtil.isNotEmpty(transportBase.getShop_id())) {
// ThirdApiRes shopInfo = getSfShopInfo(transportBase.getShop_id());
// if (shopInfo != null && shopInfo.getError_code().equals(0)) {
// return Pair.of(true, transportBase.getShop_id());
// }
// }
// 3. 如果已存在顺丰店铺ID验证其有效性
if (CheckUtil.isNotEmpty(transportBase.getShop_id())) {
ThirdApiRes shopInfo = getSfShopInfo(transportBase.getShop_id());
if (shopInfo != null && shopInfo.getError_code().equals(0)) {
logger.info("已成功创建顺丰同城店铺!");
return Pair.of(true, transportBase.getShop_id());
}
}
// 构建请求参数
// 4. 构建请求参数
Map<String, Object> params = buildCommonParams();
params.put("supplier_id", supplierId); // 店铺所属商家id
params.put("out_shop_id", storeId); // 外部店铺ID
params.put("shop_name", shopName); // 店铺名称
params.put("city_name", cityName); // 城市名称
//1:快餐 2:药品 3:百货 4:脏衣服收 5:干净衣服派 6:生鲜 8:高端饮品 9:现场勘验 10:快递 12:文件 13:蛋糕 14:鲜花 15:数码 16:服装 17:
// RMK 1:快餐 2:药品 3:百货 4:脏衣服收 5:干净衣服派 6:生鲜 8:高端饮品 9:现场勘验 10:快递 12:文件 13:蛋糕 14:鲜花 15:数码 16:服装 17:
//汽配 18:珠宝 20:披萨 21:中餐 22:水产 27:专人直送 32:中端饮品 33:便利店 34:面包糕点 35:火锅 36:证照 40:烧烤小龙虾 41:外部落地配 47:烟酒
// 48:成人用品 99:其他
params.put("shop_product_types", "1,3,6,8,13,14,15,16,20,22,32,33,34,47,99"); // 经营类型: 快餐,百货,生鲜,便利店
// 经营类型: 快餐,百货,生鲜,高端饮品,蛋糕,鲜花,数码,服装,披萨,水产,中端饮品,便利店,面包糕点,烟酒,其他
params.put("shop_product_types", "1,3,6,8,13,14,15,16,20,22,32,33,34,47,99");
params.put("shop_type", 1); // 店铺类型: 1-普通型 2-平台型
params.put("shop_address", shopAddress); // 店铺地址
params.put("longitude", longitude); // 经度
@ -154,33 +159,35 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
params.put("shop_contact_name", contactName); // 联系人姓名
params.put("shop_contact_phone", contactPhone); // 联系电话
// 发送请求到顺丰接口
// 5. 发送请求到顺丰接口
String paramJSON = JsonUtil.toJSONString(params);
String sendUrl = buildUrl("createShop", paramJSON);
String responseStr = HttpUtil.post(sendUrl, paramJSON);
if (StrUtil.isBlank(responseStr)) {
logger.error("创建顺丰同城店铺异常,无返回值!");
return Pair.of(false, "创建顺丰同城店铺异常,无返回值!");
logger.error("创建顺丰店铺异常,无返回值!");
return Pair.of(false, "创建顺丰店铺异常,无返回值!");
}
ThirdApiRes apiRes = JSONUtil.toBean(responseStr, ThirdApiRes.class);
if (apiRes == null) {
logger.error("创建顺丰同城店铺异常,返回值有误!!");
return Pair.of(false, "创建顺丰同城店铺异常,返回值有误!");
logger.error("创建顺丰店铺异常,返回值有误!!");
return Pair.of(false, "创建顺丰店铺异常,返回值有误!");
}
// 检查接口调用结果
// 6. 检查接口调用结果
if (!apiRes.getError_code().equals(0) || apiRes.getResult() == null) {
String errMsg = apiRes.getError_code().equals(0) ? "创建顺丰同城店铺失败!" : apiRes.getError_msg();
logger.error("创建顺丰同城店铺失败: {}", errMsg);
String errMsg = apiRes.getError_code().equals(0) ? "创建顺丰店铺失败!" : "创建顺丰店铺失败: " + apiRes.getError_msg();
logger.error("创建顺丰店铺失败: {}", errMsg);
return Pair.of(false, errMsg);
}
// 提取顺丰店铺ID并更新数据库
// 7. 提取顺丰店铺ID并更新数据库
JSONObject result = (JSONObject) apiRes.getResult();
String sfShopId = result.getStr("shop_id");
transportBase.setShop_id(sfShopId);
transportBase.setShop_state(CommonConstant.Enable);// 顺丰同城快递商品特惠
transportBase.setDelivery_brand(CommonConstant.DELIVERY_BRAND_SF);
Pair<Long, String> updateResult = shopStoreSameCityTransportBaseService
.saveOrUpdateShopStoreSameCityTransportBase(transportBase);
@ -190,9 +197,35 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
return Pair.of(false, "更新店铺信息失败");
}
logger.info("成功创建顺丰店铺店铺ID: {}", sfShopId);
return Pair.of(true, sfShopId);
}
/**
* 创建顺丰同城店铺异步通知回调
*
* @param jsonData
* @param sign
* @return
*/
public ThirdApiRes createSfExpressShopNotify(String jsonData, String sign) {
logger.info("开始创建顺丰店铺异步通知回调");
if (StrUtil.isBlank(jsonData) || StrUtil.isBlank(sign)) {
return new ThirdApiRes().fail(1003, "缺少必要参数!");
}
if (!checkOpenSign(sign, jsonData)) {
return new ThirdApiRes().fail(2002, "请求签名sign校验失败");
}
logger.info("接收创建顺丰店铺异步通知回调返回的 JSON 数据:{}", jsonData);
// return new ThirdApiRes().success("处理成功");
return new ThirdApiRes().fail(1003, "处理成功");
}
@Override
public ThirdApiRes createOrder(String shopOrderId) {
// 组织请求参数
@ -373,7 +406,6 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
payload.put("orderId", shopOrderId);
pushMessageService.noticeMerchantEmployeeOrderAction(null, shopOrderId, "您有一笔新的订单", "您有一笔同城订单[" + shopOrderId + "],请及时处理。", payload);
return Pair.of(true, "顺丰同城下单成功!");
}

View File

@ -1,62 +0,0 @@
/*
* Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.suisung.mall.shop.store.controller.admin;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.service.impl.BaseControllerImpl;
import com.suisung.mall.shop.store.service.ShopStoreBizCategoryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@Api(tags = "店铺分类(类目),此类决定商家分成比例")
@RestController
@RequestMapping("/admin/shop/store/biz-category")
public class ShopStoreBizCategoryAdminController extends BaseControllerImpl {
@Resource
private ShopStoreBizCategoryService shopStoreBizCategoryService;
@ApiOperation(value = "搜索店铺分类(类目)", notes = "搜索店铺分类(类目)")
@RequestMapping(value = "/search", method = RequestMethod.POST)
public CommonResult shopStoreBizCategorySearchList(@RequestBody(required = false) JSONObject params) {
String keyword = "";
if (params != null && StrUtil.isNotBlank(params.getStr("keyword"))) {
keyword = params.getStr("keyword");
}
return CommonResult.success(shopStoreBizCategoryService.selectParentListWithChildren(keyword));
}
@ApiOperation(value = "新增店铺分类(类目)", notes = "新增店铺分类(类目)")
@RequestMapping(value = "/add/new", method = RequestMethod.POST)
public CommonResult shopStoreBusinessCategoryAddNew(@RequestBody JSONObject params) {
return shopStoreBizCategoryService.addNew(params);
}
@ApiOperation(value = "修改店铺分类(类目)", notes = "修改店铺分类(类目)")
@RequestMapping(value = "/modify", method = RequestMethod.POST)
public CommonResult shopStoreBusinessCategoryModify(@RequestBody JSONObject params) {
return shopStoreBizCategoryService.modify(params);
}
@ApiOperation(value = "屏蔽/开启店铺分类(类目)", notes = "屏蔽/开启店铺分类(类目)")
@RequestMapping(value = "/status/modify", method = RequestMethod.POST)
public CommonResult shopStoreBusinessCategoryDisable(@RequestBody JSONObject params) {
return shopStoreBizCategoryService.modifyStatus(params);
}
}

View File

@ -1,44 +0,0 @@
/*
* Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.suisung.mall.shop.store.controller.mobile;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.service.impl.BaseControllerImpl;
import com.suisung.mall.shop.store.service.ShopStoreBizCategoryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@Api(tags = "店铺分类(类目),此类决定商家分成比例")
@RestController
@RequestMapping("/mobile/shop/store/biz-category")
public class ShopStoreBizCategoryController extends BaseControllerImpl {
@Resource
private ShopStoreBizCategoryService shopStoreBizCategoryService;
@ApiOperation(value = "店铺分类(类目)", notes = "店铺分类(类目)")
@RequestMapping(value = "/list", method = RequestMethod.POST)
public CommonResult shopStoreBusinessCategoryList(@RequestBody(required = false) JSONObject params) {
String keyword = "";
if (params != null && StrUtil.isNotBlank(params.getStr("keyword"))) {
keyword = params.getStr("keyword");
}
return CommonResult.success(shopStoreBizCategoryService.selectParentListWithChildren(keyword));
}
}

View File

@ -1,29 +0,0 @@
package com.suisung.mall.shop.store.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.suisung.mall.common.modules.store.ShopStoreBizCategory;
import com.suisung.mall.common.modules.store.dto.ShopStoreBizCategoryDTO;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* <p>
* 店铺营业分类表用于存储超市商品的分类信息支持二级分类 Mapper 接口
* </p>
*
* @author panjunjie
* @since 2025-03-17
*/
@Repository
public interface ShopStoreBizCategoryMapper extends BaseMapper<ShopStoreBizCategory> {
/**
* 根据关键字查询店铺一级营业分类信息
*
* @param keyword
* @return
*/
List<ShopStoreBizCategoryDTO> selectParentListWithChildren(@Param("keyword") String keyword);
}

View File

@ -1,61 +0,0 @@
package com.suisung.mall.shop.store.service;
import cn.hutool.json.JSONObject;
import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.modules.store.ShopStoreBizCategory;
import com.suisung.mall.common.modules.store.dto.ShopStoreBizCategoryDTO;
import com.suisung.mall.core.web.service.IBaseService;
import java.util.List;
/**
* <p>
* 店铺营业分类表用于存储超市商品的分类信息支持二级分类会影响分成比例 服务类
* </p>
*
* @author panjunjie
* @since 2025-03-17
*/
public interface ShopStoreBizCategoryService extends IBaseService<ShopStoreBizCategory> {
/**
* 根据关键字查询店铺一级营业分类信息
*
* @param keyword
* @return
*/
List<ShopStoreBizCategoryDTO> selectParentListWithChildren(String keyword);
/**
* 新增店铺营业分类信息
*
* @param params
* @return
*/
CommonResult addNew(JSONObject params);
/**
* 修改店铺营业分类信息
*
* @param params
* @return
*/
CommonResult modify(JSONObject params);
/**
* 删除店铺营业分类信息
*
* @param params
* @return
*/
CommonResult modifyStatus(JSONObject params);
/**
* 根据分类编号查询店铺营业分类信息是否存在
*
* @param categoryCode
* @return
*/
Boolean isExists(String categoryCode);
}

View File

@ -1,196 +0,0 @@
package com.suisung.mall.shop.store.service.impl;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.constant.CommonConstant;
import com.suisung.mall.common.modules.store.ShopStoreBizCategory;
import com.suisung.mall.common.modules.store.dto.ShopStoreBizCategoryDTO;
import com.suisung.mall.common.utils.I18nUtil;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.shop.store.mapper.ShopStoreBizCategoryMapper;
import com.suisung.mall.shop.store.service.ShopStoreBizCategoryService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
* <p>
* 店铺营业分类表用于存储超市商品的分类信息支持二级分类会影响分成比例 服务实现类
* </p>
*
* @author panjunjie
* @since 2025-03-17
*/
@Service
public class ShopStoreBizCategoryServiceImpl extends BaseServiceImpl<ShopStoreBizCategoryMapper, ShopStoreBizCategory> implements ShopStoreBizCategoryService {
@Resource
private ShopStoreBizCategoryMapper shopStoreBizCategoryMapper;
/**
* 根据关键字查询店铺一级营业分类信息
*
* @param keyword
* @return
*/
@Override
public List<ShopStoreBizCategoryDTO> selectParentListWithChildren(String keyword) {
return shopStoreBizCategoryMapper.selectParentListWithChildren(keyword);
}
/**
* 新增店铺营业分类信息
*
* @param params
* @return
*/
@Override
public CommonResult addNew(JSONObject params) {
String userId = "0";
// UserDto user = getCurrentUser();
// if (!user.isAdmin()) {
// return CommonResult.failed("权限不足!");
// }
// userId = user.getId().toString();
if (params == null) {
return CommonResult.failed(I18nUtil._("参数不能为空"));
}
if (!params.containsKey("category_code") || !params.containsKey("category_name")) {
return CommonResult.failed(I18nUtil._("缺少必要参数"));
}
ShopStoreBizCategory record = JSONUtil.toBean(params, ShopStoreBizCategory.class);
if (record == null) {
return CommonResult.failed(I18nUtil._("参数转化错误"));
}
if (!params.containsKey("parent_category_code") || StrUtil.isBlank(params.getStr("parent_category_code"))) {
record.setParent_category_code("0");
}
// 判断 category_code 是不是存在
if (isExists(record.getCategory_code())) {
return CommonResult.failed(I18nUtil._("分类编号已存在!"));
}
record.setCreated_by(userId);
record.setUpdated_by(userId);
boolean success = save(record);
if (!success) {
return CommonResult.failed(I18nUtil._("保存失败!"));
}
return CommonResult.success();
}
/**
* 修改店铺营业分类信息
*
* @param params
* @return
*/
@Override
public CommonResult modify(JSONObject params) {
String userId = "0";
// UserDto user = getCurrentUser();
// if (!user.isAdmin()) {
// return CommonResult.failed("权限不足!");
// }
// userId = user.getId().toString();
if (params == null) {
return CommonResult.failed(I18nUtil._("参数不能为空"));
}
if (!params.containsKey("id")) {
return CommonResult.failed(I18nUtil._("缺少必要参数"));
}
ShopStoreBizCategory record = JSONUtil.toBean(params, ShopStoreBizCategory.class);
if (record == null) {
return CommonResult.failed(I18nUtil._("参数转化错误"));
}
record.setUpdated_by(userId);
if (record.getStatus().equals(CommonConstant.Enable)) {
record.setStatus(CommonConstant.Disable2);
}
boolean success = updateById(record);
if (!success) {
return CommonResult.failed(I18nUtil._("保存失败!"));
}
return CommonResult.success();
}
/**
* 删除店铺营业分类信息
*
* @param params
* @return
*/
@Override
public CommonResult modifyStatus(JSONObject params) {
String userId = "0";
// UserDto user = getCurrentUser();
// if (!user.isAdmin()) {
// return CommonResult.failed("权限不足!");
// }
// userId = user.getId().toString();
if (params == null) {
return CommonResult.failed(I18nUtil._("参数不能为空"));
}
if (!params.containsKey("id") || !params.containsKey("status")) {
return CommonResult.failed(I18nUtil._("缺少必要参数"));
}
Long id = params.getLong("id");
Integer status = params.getInt("status");
if (!CommonConstant.Enable.equals(status)) {
status = CommonConstant.Disable2;
}
ShopStoreBizCategory record = new ShopStoreBizCategory();
record.setStatus(status);
record.setUpdated_by(userId);
record.setId(id);
boolean success = updateById(record);
if (!success) {
return CommonResult.failed(I18nUtil._("保存失败!"));
}
return CommonResult.success();
}
/**
* 根据分类编号查询店铺营业分类信息是否存在
*
* @param categoryCode
* @return
*/
@Override
public Boolean isExists(String categoryCode) {
if (StrUtil.isBlank(categoryCode)) {
return true;
}
QueryWrapper<ShopStoreBizCategory> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("category_code", categoryCode).select("id");
return count(queryWrapper) > 0;
}
}

View File

@ -1,79 +0,0 @@
<?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="com.suisung.mall.shop.store.mapper.ShopStoreBizCategoryMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Parent_Column_List">
id
, category_code, category_name, parent_category_code, description,split_ratio,seq,status,created_by,updated_by,created_at,updated_at
</sql>
<resultMap id="CategoryResultMap" type="com.suisung.mall.common.modules.store.dto.ShopStoreBizCategoryDTO">
<id property="id" column="id"/>
<result property="category_code" column="category_code"/>
<result property="category_name" column="category_name"/>
<result property="description" column="description"/>
<result property="split_ratio" column="split_ratio"/>
<result property="seq" column="seq"/>
<result property="status" column="status"/>
<result property="created_by" column="created_by"/>
<result property="updated_by" column="updated_by"/>
<result property="created_at" column="created_at"/>
<result property="updated_at" column="updated_at"/>
<result property="parent_category_code" column="parent_category_code"/>
<collection property="children" ofType="com.suisung.mall.common.modules.store.ShopStoreBizCategory">
<id property="id" column="child_id"/>
<result property="category_code" column="child_category_code"/>
<result property="category_name" column="child_category_name"/>
<result property="parent_category_code" column="child_parent_category_code"/>
<result property="description" column="child_description"/>
<result property="split_ratio" column="child_split_ratio"/>
<result property="seq" column="child_seq"/>
<result property="status" column="child_status"/>
<result property="created_by" column="child_created_by"/>
<result property="updated_by" column="child_updated_by"/>
<result property="created_at" column="child_created_at"/>
<result property="updated_at" column="child_updated_at"/>
</collection>
</resultMap>
<select id="selectParentListWithChildren" resultMap="CategoryResultMap">
SELECT p.id,
p.category_code,
p.category_name,
p.parent_category_code,
p.description,
p.split_ratio,
p.seq,
p.status,
p.created_by,
p.updated_by,
p.created_at,
p.updated_at,
c.id AS child_id,
c.category_code AS child_category_code,
c.category_name AS child_category_name,
c.parent_category_code AS child_parent_category_code,
c.description AS child_description,
c.split_ratio AS child_split_ratio,
c.seq AS child_seq,
c.status AS child_status,
c.created_by AS child_created_by,
c.updated_by AS child_updated_by,
c.created_at AS child_created_at,
c.updated_at AS child_updated_at
FROM shop_store_biz_category p
LEFT JOIN
shop_store_biz_category c ON p.category_code = c.parent_category_code and c.status = 1
WHERE p.parent_category_code = 0 and p.status = 1
<if test="keyword != null and keyword != ''">
AND (p.category_code LIKE CONCAT('%', #{keyword}, '%')
OR p.category_name LIKE CONCAT('%', #{keyword}, '%')
OR p.description LIKE CONCAT('%', #{keyword}, '%')
OR c.category_code LIKE CONCAT('%', #{keyword}, '%')
OR c.category_name LIKE CONCAT('%', #{keyword}, '%')
OR c.description LIKE CONCAT('%', #{keyword}, '%'))
</if>
ORDER BY p.seq asc, c.seq asc, p.id asc
</select>
</mapper>

View File

@ -324,7 +324,7 @@
<mysql.port>3306</mysql.port>
<mysql.db>mall_dev</mysql.db>
<mysql.user>root</mysql.user>
<mysql.pwd>123456</mysql.pwd>
<mysql.pwd>12345678</mysql.pwd>
<mysql.driver>com.mysql.cj.jdbc.Driver</mysql.driver>
<!-- redis配置 -->
<redis.host>114.132.210.208</redis.host>