SSE 消息开发
This commit is contained in:
parent
0ec8e3f0a8
commit
85d06fc9b0
@ -0,0 +1,100 @@
|
||||
package com.suisung.mall.common.utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Slf4j
|
||||
public class SseEmitterUtil {
|
||||
//当前连接数
|
||||
public static final AtomicInteger count = new AtomicInteger(0);
|
||||
//使用 map 对象,便于根据 userId 来获取对应的 SseEmitter,或者放 redis 里面
|
||||
public static final Map<String, SseEmitter> sseEmitterMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 创建用户连接并返回 SseEmitter
|
||||
*
|
||||
* @param channel 通道
|
||||
*/
|
||||
public static SseEmitter connect(String channel) {
|
||||
//设置超时时间,0表示不过期。默认30秒,超过时间未完成会抛出异常:AsyncRequestTimeoutException
|
||||
SseEmitter sseEmitter = new SseEmitter(1200000L); // 20分钟
|
||||
try {
|
||||
//注册回调:完成、失败、超时
|
||||
sseEmitter.onCompletion(completionCallBack(channel));
|
||||
sseEmitter.onError(errorCallBack(channel));
|
||||
sseEmitter.onTimeout(timeoutCallBack(channel));
|
||||
// 缓存
|
||||
sseEmitterMap.put(channel, sseEmitter);
|
||||
// 数量+1
|
||||
count.getAndIncrement();
|
||||
log.debug("创建新的sse连接,当前通道:{}", channel);
|
||||
} catch (Exception e) {
|
||||
log.error("创建新的sse连接异常,当前通道:{}", channel);
|
||||
}
|
||||
return sseEmitter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 给指定通道发送信息
|
||||
*/
|
||||
public static SseEmitter sendMessage(String channel, String message) {
|
||||
SseEmitter sseEmitter = sseEmitterMap.get(channel);
|
||||
if (sseEmitter == null) {
|
||||
sseEmitter = connect(channel);
|
||||
}
|
||||
|
||||
try {
|
||||
sseEmitter.send(message);
|
||||
log.info("向通道:{} 发送了:{}", channel, message);
|
||||
return sseEmitter;
|
||||
} catch (IOException e) {
|
||||
log.error("通道:{} 推送异常:{}", channel, e.getMessage());
|
||||
removeChannel(channel);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除通道连接
|
||||
*/
|
||||
public static void removeChannel(String channel) {
|
||||
sseEmitterMap.remove(channel);
|
||||
// 数量-1
|
||||
count.getAndDecrement();
|
||||
log.debug("移除通道:{}", channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前连接数量
|
||||
*/
|
||||
public static int getUserCount() {
|
||||
return count.intValue();
|
||||
}
|
||||
|
||||
private static Runnable completionCallBack(String channel) {
|
||||
return () -> {
|
||||
log.debug("结束连接:{}", channel);
|
||||
removeChannel(channel);
|
||||
};
|
||||
}
|
||||
|
||||
private static Runnable timeoutCallBack(String channel) {
|
||||
return () -> {
|
||||
log.error("连接超时:{}", channel);
|
||||
removeChannel(channel);
|
||||
};
|
||||
}
|
||||
|
||||
private static Consumer<Throwable> errorCallBack(String channel) {
|
||||
return throwable -> {
|
||||
log.error("连接异常:{}", channel);
|
||||
removeChannel(channel);
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,7 @@
|
||||
package com.suisung.mall.common.utils;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -12,6 +14,8 @@ import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 字符串工具类,继承lang3字符串工具类
|
||||
@ -20,7 +24,18 @@ import java.util.UUID;
|
||||
*/
|
||||
public final class StringUtils extends org.apache.commons.lang3.StringUtils {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(StringUtils.class);
|
||||
public static void main(String[] args) {
|
||||
System.out.println(removeProvinceCityDistrict("广西壮族自治区贵港市桂平市西山镇新安街粤桂花城1102号"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机字符串
|
||||
*/
|
||||
private static final String INT_TEMP = "0123456789";
|
||||
private static final String STR_TEMP = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
private static final String ALL_TEMP = INT_TEMP + STR_TEMP;
|
||||
private static final Random RANDOM = new Random();
|
||||
private static final Logger logger = LoggerFactory.getLogger(StringUtils.class);
|
||||
|
||||
public static String encode(String str) {
|
||||
String encode = null;
|
||||
@ -41,7 +56,6 @@ public final class StringUtils extends org.apache.commons.lang3.StringUtils {
|
||||
return UUID.randomUUID().toString().replace("-", "");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 要求外部订单号必须唯一。
|
||||
*
|
||||
@ -97,33 +111,6 @@ public final class StringUtils extends org.apache.commons.lang3.StringUtils {
|
||||
return txt.replaceAll("[ `·•<C2B7>\\f\\t\\v]", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机字符串
|
||||
*/
|
||||
private static final String INT_TEMP = "0123456789";
|
||||
private static final String STR_TEMP = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
private static final String ALL_TEMP = INT_TEMP + STR_TEMP;
|
||||
|
||||
private static final Random RANDOM = new Random();
|
||||
|
||||
/**
|
||||
* 生成的随机数类型
|
||||
*/
|
||||
public enum RandomType {
|
||||
/**
|
||||
* 整数
|
||||
*/
|
||||
INT,
|
||||
/**
|
||||
* 字符串
|
||||
*/
|
||||
STRING,
|
||||
/**
|
||||
* 所有类型
|
||||
*/
|
||||
ALL
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机数生成
|
||||
*
|
||||
@ -170,12 +157,11 @@ public final class StringUtils extends org.apache.commons.lang3.StringUtils {
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
public static String[] shortUrl(String url) {
|
||||
// 可以自定义生成 MD5 加密字符传前的混合 KEY
|
||||
String key = "alexis";
|
||||
// 要使用生成 URL 的字符
|
||||
String[] chars = new String[] { "a", "b", "c", "d", "e", "f", "g", "h",
|
||||
String[] chars = new String[]{"a", "b", "c", "d", "e", "f", "g", "h",
|
||||
"i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
|
||||
"u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5",
|
||||
"6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H",
|
||||
@ -208,8 +194,10 @@ public final class StringUtils extends org.apache.commons.lang3.StringUtils {
|
||||
}
|
||||
return resUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* MD5加密(32位大写)
|
||||
*
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
@ -235,4 +223,55 @@ public final class StringUtils extends org.apache.commons.lang3.StringUtils {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 全地址去除省市区,保留详细地址
|
||||
* @param fullAddress 比如:广西壮族自治区贵港市桂平市西山镇新安街粤桂花城1102号 -> 西山镇新安街粤桂花城1102号
|
||||
* @return
|
||||
*/
|
||||
public static String removeProvinceCityDistrict(String fullAddress) {
|
||||
if (StrUtil.isBlank(fullAddress)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// 使用正则表达式匹配省市区信息
|
||||
Pattern pattern = Pattern.compile("(.*?省|.*?自治区)?(.*?市|.*?自治州)?(.*?区|.*?县|.*?市辖区|.*?市)?");
|
||||
Matcher matcher = pattern.matcher(fullAddress);
|
||||
if (!matcher.find()) {
|
||||
return fullAddress;
|
||||
}
|
||||
|
||||
if (matcher.group(1) != null) {
|
||||
fullAddress = fullAddress.replace(matcher.group(1), "");
|
||||
}
|
||||
|
||||
if (matcher.group(2) != null) {
|
||||
fullAddress = fullAddress.replace(matcher.group(2), "");
|
||||
}
|
||||
|
||||
if (matcher.group(3) != null) {
|
||||
fullAddress = fullAddress.replace(matcher.group(3), "");
|
||||
}
|
||||
|
||||
return fullAddress;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 生成的随机数类型
|
||||
*/
|
||||
public enum RandomType {
|
||||
/**
|
||||
* 整数
|
||||
*/
|
||||
INT,
|
||||
/**
|
||||
* 字符串
|
||||
*/
|
||||
STRING,
|
||||
/**
|
||||
* 所有类型
|
||||
*/
|
||||
ALL
|
||||
}
|
||||
}
|
||||
6
mall-shop/README.MD
Normal file
6
mall-shop/README.MD
Normal file
@ -0,0 +1,6 @@
|
||||
项目备份录
|
||||
account_user_bind_connect 用户手机、邮件、微博、QQ、微信绑定表
|
||||
|
||||
admin_base_protocol
|
||||
admin_rights_base
|
||||
权限赋值的表
|
||||
@ -8370,6 +8370,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
|
||||
// 顺丰同城给的测试店铺id
|
||||
String shopId = "3243279847393";
|
||||
//3269768224353 到时启用这个正式店铺 type:便利店
|
||||
Integer businessType = 6;// 生鲜分类
|
||||
if (enable_sf_express.equals(CommonConstant.Enable)) {//开启正式配送服务的时候
|
||||
// 顺丰同城业务员给的店铺id
|
||||
@ -8431,6 +8432,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
SFOrderShopReq shop = new SFOrderShopReq();
|
||||
SFOrderReceiveReq receive = new SFOrderReceiveReq();
|
||||
if (enable_sf_express.equals(CommonConstant.Enable)) {//开启正式配送服务的时候
|
||||
|
||||
// 店铺信息(发货人信息)
|
||||
Pair<Boolean, StandardAddressDTO> pairShopAddr = shopStoreBaseService.checkStoreAddress(shopStoreBase);
|
||||
shop.setShop_name(shopStoreBase.getStore_name());
|
||||
@ -8438,6 +8440,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
shop.setShop_address(pairShopAddr.getSecond().getFullAddress());
|
||||
shop.setShop_lng(pairShopAddr.getSecond().getLongitude());
|
||||
shop.setShop_lat(pairShopAddr.getSecond().getLatitude());
|
||||
|
||||
// 收货人信息
|
||||
Pair<Boolean, StandardAddressDTO> pairReceiveAddr = shopOrderDeliveryAddressService.checkAddress(shopOrderDeliveryAddress);
|
||||
receive.setUser_name(shopOrderDeliveryAddress.getDa_name());
|
||||
@ -8445,6 +8448,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
receive.setUser_address(pairReceiveAddr.getSecond().getFullAddress());
|
||||
receive.setUser_lng(pairReceiveAddr.getSecond().getLongitude());
|
||||
receive.setUser_lat(pairReceiveAddr.getSecond().getLatitude());
|
||||
|
||||
} else {
|
||||
// 店铺信息(发货人信息)
|
||||
shop.setShop_name("顺丰同城开放平台");
|
||||
|
||||
@ -3,6 +3,7 @@ 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.core.web.service.impl.BaseServiceImpl;
|
||||
import com.suisung.mall.shop.order.mapper.ShopOrderDeliveryAddressMapper;
|
||||
import com.suisung.mall.shop.order.service.ShopOrderDeliveryAddressService;
|
||||
@ -58,7 +59,7 @@ public class ShopOrderDeliveryAddressServiceImpl extends BaseServiceImpl<ShopOrd
|
||||
sb.append(shopOrderDeliveryAddress.getDa_county());
|
||||
}
|
||||
if(StrUtil.isNotBlank(shopOrderDeliveryAddress.getDa_address())){
|
||||
sb.append(shopOrderDeliveryAddress.getDa_address());
|
||||
sb.append(StringUtils.removeProvinceCityDistrict(shopOrderDeliveryAddress.getDa_address()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -8,18 +8,27 @@
|
||||
|
||||
package com.suisung.mall.shop.sfexpress.controller.api;
|
||||
|
||||
import com.suisung.mall.common.api.CommonResult;
|
||||
import com.suisung.mall.common.pojo.res.SFExpressApiRes;
|
||||
import com.suisung.mall.common.utils.SseEmitterUtil;
|
||||
import com.suisung.mall.shop.sfexpress.service.SFExpressApiService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
@Api(tags = "顺丰同城Api端")
|
||||
@RestController
|
||||
@RequestMapping("/shop/sf-express")
|
||||
public class SFExpressApiController {
|
||||
|
||||
private final CopyOnWriteArrayList<SseEmitter> emitters = new CopyOnWriteArrayList<>();
|
||||
@Autowired
|
||||
private SFExpressApiService sfExpressApiService;
|
||||
|
||||
|
||||
@ -8,15 +8,15 @@
|
||||
|
||||
package com.suisung.mall.shop.sfexpress.controller.mobile;
|
||||
|
||||
import com.suisung.mall.common.api.CommonResult;
|
||||
import com.suisung.mall.common.pojo.res.SFExpressApiRes;
|
||||
import com.suisung.mall.common.utils.SseEmitterUtil;
|
||||
import com.suisung.mall.shop.sfexpress.service.SFExpressApiService;
|
||||
import com.suisung.mall.shop.store.service.ShopStoreSfOrderService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.HashMap;
|
||||
@ -87,4 +87,27 @@ public class SFExpressController {
|
||||
params.put("order_id", shopStoreSfOrderService.getSfOrderIdByShopOrderId(orderId));
|
||||
return sfExpressApiService.riderViewV2(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 顺丰同城订单状态监听 SSE 服务
|
||||
* @param channel
|
||||
* @return
|
||||
*/
|
||||
@CrossOrigin(allowCredentials = "true")
|
||||
@GetMapping(value = "/order/status/listening", produces = "text/event-stream;charset=UTF-8")
|
||||
public SseEmitter sfOrderStatusSseConn(@RequestParam(value = "channel", required = true) String channel) {
|
||||
return SseEmitterUtil.connect(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭顺丰同城订单状态监听 SSE 服务
|
||||
* @param channel
|
||||
* @return
|
||||
*/
|
||||
@CrossOrigin(allowCredentials = "true")
|
||||
@GetMapping(value ="/order/status/listening/close")
|
||||
public CommonResult sfOrderStatusSseClose(@RequestParam(name = "channel") String channel) {
|
||||
SseEmitterUtil.removeChannel(channel);
|
||||
return CommonResult.success();
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,18 +10,22 @@ package com.suisung.mall.shop.sfexpress.service.impl;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.suisung.mall.common.api.CommonResult;
|
||||
import com.suisung.mall.common.api.StateCode;
|
||||
import com.suisung.mall.common.constant.SFExpressConstant;
|
||||
import com.suisung.mall.common.domain.UserDto;
|
||||
import com.suisung.mall.common.exception.ApiException;
|
||||
import com.suisung.mall.common.modules.store.ShopStoreSfOrder;
|
||||
import com.suisung.mall.common.pojo.req.*;
|
||||
import com.suisung.mall.common.pojo.res.SFExpressApiRes;
|
||||
import com.suisung.mall.common.utils.I18nUtil;
|
||||
import com.suisung.mall.common.utils.JsonUtil;
|
||||
import com.suisung.mall.common.utils.SseEmitterUtil;
|
||||
import com.suisung.mall.shop.order.service.ShopOrderBaseService;
|
||||
import com.suisung.mall.shop.order.service.ShopOrderInfoService;
|
||||
import com.suisung.mall.shop.sfexpress.service.SFExpressApiService;
|
||||
@ -42,6 +46,8 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.suisung.mall.common.utils.ContextUtil.getCurrentUser;
|
||||
|
||||
@Service
|
||||
public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
|
||||
@ -147,12 +153,12 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
@Transactional
|
||||
@Override
|
||||
public Pair<Boolean, String> innerCreateSfExpressOrder(String shopOrderId, Long orderPickupNum) {
|
||||
if(StrUtil.isBlank(shopOrderId) || orderPickupNum == null|| orderPickupNum <=0) {
|
||||
if (StrUtil.isBlank(shopOrderId) || orderPickupNum == null || orderPickupNum <= 0) {
|
||||
return Pair.of(false, "顺丰同城下单时,缺少必要参数!");
|
||||
}
|
||||
|
||||
// 检查 shop_store_sf_order 订单是否已存在?
|
||||
if(shopStoreSfOrderService.exists(devId,shopOrderId)){
|
||||
if (shopStoreSfOrderService.exists(devId, shopOrderId)) {
|
||||
return Pair.of(true, "顺丰同城已下单过!");
|
||||
}
|
||||
|
||||
@ -208,7 +214,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
/**
|
||||
* 取消订单
|
||||
*
|
||||
* @param orderId 商家订单号
|
||||
* @param orderId 商家订单号
|
||||
* @param cancelCode 取消码,参考:https://openic.sf-express.com/open/api/docs/index/#/apidoc
|
||||
* @param cancelReason 取消原因
|
||||
* @return
|
||||
@ -235,7 +241,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
public SFExpressApiRes cancelOrder(Map<String, Object> params) {
|
||||
// TODO 检验用户权限
|
||||
|
||||
if (params == null || params.get("order_id") == null) {
|
||||
if (params == null || ObjectUtil.isEmpty(params.get("order_id"))) {
|
||||
return new SFExpressApiRes().fail(1003, "请求参数有误!");
|
||||
}
|
||||
|
||||
@ -267,7 +273,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
// 判断订单的状态,是否已经取消了?已取消,不再执行
|
||||
ShopStoreSfOrder shopStoreSfOrderExist = shopStoreSfOrderService.getBySfOrderId(orderId);
|
||||
if (shopStoreSfOrderExist == null) {
|
||||
return new SFExpressApiRes().fail(2,"订单有误!");
|
||||
return new SFExpressApiRes().fail(2, "订单有误!");
|
||||
}
|
||||
|
||||
if (shopStoreSfOrderExist.getOrder_status() != null
|
||||
@ -306,7 +312,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
*/
|
||||
@Override
|
||||
public SFExpressApiRes addOrderGratuityFee(Map<String, Object> params) {
|
||||
if (params == null || params.get("order_id") == null || params.get("gratuity_fee") == null) {
|
||||
if (params == null || ObjectUtil.isEmpty(params.get("order_id")) || params.get("gratuity_fee") == null) {
|
||||
return new SFExpressApiRes().fail(1003, "请求参数有误!");
|
||||
}
|
||||
|
||||
@ -334,7 +340,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
*/
|
||||
@Override
|
||||
public SFExpressApiRes reminderOrder(Map<String, Object> params) {
|
||||
if (params == null || params.get("order_id") == null) {
|
||||
if (params == null || ObjectUtil.isEmpty(params.get("order_id"))) {
|
||||
return new SFExpressApiRes().fail(1003, "请求参数有误!");
|
||||
}
|
||||
|
||||
@ -364,7 +370,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
*/
|
||||
@Override
|
||||
public SFExpressApiRes listOrderFeed(Map<String, Object> params) {
|
||||
if (params == null || params.get("order_id") == null) {
|
||||
if (params == null || ObjectUtil.isEmpty(params.get("order_id"))) {
|
||||
return new SFExpressApiRes().fail(1003, "请求参数有误!");
|
||||
}
|
||||
|
||||
@ -392,7 +398,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
*/
|
||||
@Override
|
||||
public SFExpressApiRes riderLatestPosition(Map<String, Object> params) {
|
||||
if (params == null || params.get("order_id") == null) {
|
||||
if (params == null || ObjectUtil.isEmpty(params.get("order_id"))) {
|
||||
return new SFExpressApiRes().fail(1003, "请求参数有误!");
|
||||
}
|
||||
|
||||
@ -420,7 +426,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
*/
|
||||
@Override
|
||||
public SFExpressApiRes riderViewV2(Map<String, Object> params) {
|
||||
if (params == null || params.get("order_id") == null) {
|
||||
if (params == null || ObjectUtil.isEmpty(params.get("order_id"))) {
|
||||
return new SFExpressApiRes().fail(1003, "请求参数有误!");
|
||||
}
|
||||
|
||||
@ -564,11 +570,15 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
}
|
||||
|
||||
success = shopOrderInfoService.changeOrderStatus(shopStoreSfOrder.getShop_order_id(), orderStatus, orderIsOutStatus, orderIsShippedStatus);
|
||||
|
||||
if (!success) {
|
||||
throw new ApiException(I18nUtil._("状态处理失败!"));
|
||||
}
|
||||
|
||||
// 注:状态更改之后,给 SSE 监听服务发送更改的数据
|
||||
// logger.debug("准备发送SSE消息...");
|
||||
SseEmitterUtil.sendMessage(shopStoreSfOrder.getSf_order_id(), jsonData);
|
||||
// logger.debug("向 SSE 通道 {} 发送了:{}", shopStoreSfOrder.getSf_order_id(), jsonData);
|
||||
|
||||
return new SFExpressApiRes().success("success");
|
||||
}
|
||||
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
package com.suisung.mall.shop.store.controller.admin;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.suisung.mall.common.api.CommonResult;
|
||||
import com.suisung.mall.common.modules.store.ShopStorePrinter;
|
||||
import com.suisung.mall.common.utils.PositionUtil;
|
||||
import com.suisung.mall.common.utils.SseEmitterUtil;
|
||||
import com.suisung.mall.shop.store.service.ShopStoreEmployeeService;
|
||||
import com.suisung.mall.shop.store.service.ShopStorePrinterService;
|
||||
import com.suisung.mall.shop.store.service.ShopStoreSameCityTransportBaseService;
|
||||
@ -13,10 +15,12 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -43,7 +47,10 @@ public class ShopStorePrinterController {
|
||||
|
||||
// BigDecimal s = new BigDecimal(2.50).setScale(2, RoundingMode.HALF_UP);
|
||||
// List<Integer> list = shopStoreEmployeeService.selectEmployeeByStoreId(3,"店铺管理员");
|
||||
return CommonResult.success(data);
|
||||
String userId = "1";
|
||||
SseEmitterUtil.sendMessage(userId, JSONUtil.toJsonStr(data));
|
||||
|
||||
return CommonResult.success(1);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "测试打印模版消息", notes = "测试打印模版消息")
|
||||
|
||||
@ -1,10 +1,7 @@
|
||||
package com.suisung.mall.shop.store.controller.mobile;
|
||||
|
||||
import com.suisung.mall.common.api.CommonResult;
|
||||
import com.suisung.mall.common.pojo.dto.ShopStoreSameCityTransportBaseDTO;
|
||||
import com.suisung.mall.common.utils.JsonUtil;
|
||||
import com.suisung.mall.shop.store.service.ShopStoreSameCityTransportBaseService;
|
||||
import com.suisung.mall.shop.store.service.ShopStoreSameCityTransportService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@ -14,17 +11,14 @@ import javax.annotation.Resource;
|
||||
@Api(tags = "同城配送运费设置控制器")
|
||||
@RestController
|
||||
@RequestMapping("/mobile/shop/store/same-city-transport")
|
||||
public class ShopStoreSameCityTransportBaseController {
|
||||
public class ShopStoreSameCityTransportBaseMobileController {
|
||||
|
||||
@Resource
|
||||
private ShopStoreSameCityTransportBaseService transportBaseService;
|
||||
|
||||
@Resource
|
||||
private ShopStoreSameCityTransportService transportService;
|
||||
|
||||
@ApiOperation(value = "下单前检测同城订单配送是否符合要求", notes = "下单前检测同城订单配送是否符合要求")
|
||||
@RequestMapping(value = "/check/same-city/delivery", method = {RequestMethod.POST})
|
||||
public CommonResult checkSameCityDelivery(@RequestBody ShopStoreSameCityTransportBaseDTO transportBaseDTO) {
|
||||
public CommonResult checkSameCityDelivery(@RequestParam(name = "store_id", defaultValue = "0") Integer storeId) {
|
||||
return transportBaseService.ShopStoreSameCityTransportBaseDetail();
|
||||
}
|
||||
}
|
||||
@ -40,6 +40,7 @@ import com.suisung.mall.shop.store.service.ShopStoreSameCityTransportBaseService
|
||||
import com.suisung.mall.shop.store.service.ShopStoreSameCityTransportService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.data.util.Pair;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@ -53,6 +54,7 @@ import java.util.List;
|
||||
|
||||
import static com.suisung.mall.common.utils.ContextUtil.getCurrentUser;
|
||||
|
||||
@Lazy
|
||||
@Service
|
||||
public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<ShopStoreSameCityTransportBaseMapper, ShopStoreSameCityTransportBase> implements ShopStoreSameCityTransportBaseService {
|
||||
|
||||
@ -61,8 +63,6 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
|
||||
private ShopStoreSameCityTransportService shopStoreSameCityTransportService;
|
||||
@Resource
|
||||
private ShopStoreBaseService shopStoreBaseService;
|
||||
@Resource
|
||||
private ShopChainUserController user;
|
||||
|
||||
/**
|
||||
* 获取同城配送设置详情信息
|
||||
@ -372,7 +372,7 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
|
||||
return new SameCityDeliveryFeeRespDTO(false, false, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, "同城配送缺少必要的参数。");
|
||||
}
|
||||
|
||||
ShopStoreBase storeBase = shopStoreBaseService.get(storeId);
|
||||
ShopStoreBase storeBase = shopStoreBaseService.get(storeId);
|
||||
if (storeBase == null) {
|
||||
logger.error("同城配送费计算时,缺少店铺基本信息。");
|
||||
if (canThrow) {
|
||||
@ -381,24 +381,25 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
|
||||
return new SameCityDeliveryFeeRespDTO(false, false, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, "同城配送缺少店铺基本信息。");
|
||||
}
|
||||
|
||||
String storeName = storeBase.getStore_name();
|
||||
String storeLng = storeBase.getStore_longitude();
|
||||
String storeLat = storeBase.getStore_latitude();
|
||||
if (StrUtil.isBlank(storeLng) || StrUtil.isBlank(storeLat)) {
|
||||
logger.error("同城配送费计算:店铺经纬度为空");
|
||||
logger.error("{}同城配送费计算:店铺经纬度为空", storeName);
|
||||
if (canThrow) {
|
||||
throw new ApiException(I18nUtil._("无法获取店铺的具体位置,请联系商家。"));
|
||||
throw new ApiException(I18nUtil._("无法获取" + storeName + "的具体位置,请联系商家。"));
|
||||
}
|
||||
return new SameCityDeliveryFeeRespDTO(false, false, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, "无法获取店铺的具体位置,请联系商家。");
|
||||
return new SameCityDeliveryFeeRespDTO(false, false, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, "无法获取" + storeName + "的具体位置,请联系商家。");
|
||||
}
|
||||
|
||||
// 获取基础运费设置记录
|
||||
ShopStoreSameCityTransportBase transportBase = getShopStoreSameCityTransportBaseById(storeId);
|
||||
if (transportBase == null) {
|
||||
logger.error("同城配送费计算:无法获取基础运费设置记录。");
|
||||
logger.error("{}同城配送费计算:无法获取基础运费设置记录。", storeName);
|
||||
if (canThrow) {
|
||||
throw new ApiException(I18nUtil._("商家尚未完成同城配送设置。"));
|
||||
}
|
||||
return new SameCityDeliveryFeeRespDTO(false, false, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, "商家尚未完成同城配送设置。");
|
||||
return new SameCityDeliveryFeeRespDTO(false, false, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, storeName + "尚未完成同城配送设置。");
|
||||
}
|
||||
|
||||
if (transportBase.getDistance_base() == null) {
|
||||
@ -418,7 +419,7 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
|
||||
}
|
||||
// 实际配送距离,单位米
|
||||
Integer distance = distanceD.intValue();
|
||||
logger.debug("下单时,店铺与收货地址两地,经纬度:{},{}|{},{} 距离:{} 米", storeLng, storeLat, orderLongitude, orderLatitude, distance);
|
||||
logger.debug(storeName + "下单时,店铺与收货地址两地,经纬度:{},{}|{},{} 距离:{} 米", storeLng, storeLat, orderLongitude, orderLatitude, distance);
|
||||
|
||||
// ### 基础配送费计算
|
||||
BigDecimal deliveryBaseFee = transportBase.getDelivery_base_fee();
|
||||
@ -456,11 +457,10 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
|
||||
deliveryBaseFee = deliveryBaseFee.add(transportBase.getWeight_increase_fee().multiply(times));
|
||||
}
|
||||
|
||||
logger.debug("下单时,店铺与收货地址超出基础距离和重量:额外增加 {} 元运费。", deliveryBaseFee);
|
||||
logger.debug(storeName + "下单时,店铺与收货地址超出基础距离和重量:额外增加 {} 元运费。", deliveryBaseFee);
|
||||
// #### 基础配送费计算完毕
|
||||
|
||||
|
||||
|
||||
// 优惠(减免)的配送费(重要)
|
||||
BigDecimal reduceDeliveryFee = BigDecimal.ZERO;
|
||||
|
||||
@ -480,7 +480,7 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
|
||||
for (ShopStoreSameCityTransport transport : transportList) {
|
||||
DeliveryFeeResultDTO deliveryFeeResultDTO = new DeliveryFeeResultDTO();
|
||||
deliveryFeeResultDTO.setId(transport.getTransport_id());
|
||||
logger.debug("下单时,店铺与收货地址的距离是{}米,最大配送范围是{}米以内", distance, transport.getMax_delivery_radius());
|
||||
logger.debug(storeName + "下单时,店铺与收货地址的距离是{}米,最大配送范围是{}米以内", distance, transport.getMax_delivery_radius());
|
||||
|
||||
// 判断订单距离在不在配送范围内?
|
||||
if (transport.getMax_delivery_radius() < distance) {
|
||||
@ -488,7 +488,7 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
|
||||
// 订单距离不在配送范围内,返回不送了
|
||||
deliveryFeeResultDTO.setLevel(2);
|
||||
deliveryFeeResultDTO.setDistancePassed(false);
|
||||
deliveryFeeResultDTO.setDistanceReason("订单不在配送范围内,订单无法配送。");
|
||||
deliveryFeeResultDTO.setDistanceReason(storeName + "的订单不在配送范围内,订单无法配送。");
|
||||
|
||||
noPassed.add(deliveryFeeResultDTO);
|
||||
|
||||
@ -502,7 +502,7 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
|
||||
deliveryFeeResultDTO.setMoneyPassed(false);
|
||||
BigDecimal diffMoney = transport.getMin_delivery_amount().subtract(orderProductAmount);
|
||||
deliveryFeeResultDTO.setDiffMoney(diffMoney);
|
||||
deliveryFeeResultDTO.setMoneyReason(String.format("商品原价金额还差%.2f元,才满足配送条件,请检查订单。", diffMoney));
|
||||
deliveryFeeResultDTO.setMoneyReason(String.format("%s商品原价金额还差%.2f元,才满足配送条件,请检查订单。", storeName, diffMoney));
|
||||
} else {
|
||||
deliveryFeeResultDTO.setMoneyPassed(true);
|
||||
}
|
||||
@ -513,7 +513,7 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
|
||||
deliveryFeeResultDTO.setMoneyPassed(false);
|
||||
BigDecimal diffMoney = transport.getMin_delivery_amount().subtract(orderDiscountAmount);
|
||||
deliveryFeeResultDTO.setDiffMoney(diffMoney);
|
||||
deliveryFeeResultDTO.setMoneyReason(String.format("订单折后金额还差%.2f元,才满足配送条件,请检查订单。", diffMoney));
|
||||
deliveryFeeResultDTO.setMoneyReason(String.format("%s订单折后金额还差%.2f元,才满足配送条件,请检查订单。", storeName, diffMoney));
|
||||
} else {
|
||||
deliveryFeeResultDTO.setMoneyPassed(true);
|
||||
}
|
||||
@ -524,7 +524,7 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
|
||||
deliveryFeeResultDTO.setMoneyPassed(false);
|
||||
BigDecimal diffMoney = transport.getMin_delivery_amount().subtract(orderDiscountAmount);
|
||||
deliveryFeeResultDTO.setDiffMoney(diffMoney);
|
||||
deliveryFeeResultDTO.setMoneyReason(String.format("应支付订单金额还差%.2f元,才满足配送条件,请检查订单。", diffMoney));
|
||||
deliveryFeeResultDTO.setMoneyReason(String.format("%s订单应支付金额还差%.2f元,才满足配送条件,请检查订单。", storeName, diffMoney));
|
||||
} else {
|
||||
deliveryFeeResultDTO.setMoneyPassed(true);
|
||||
}
|
||||
@ -557,21 +557,21 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
|
||||
|
||||
}
|
||||
|
||||
logger.debug("下单时,根据商家运费设置规则减免{}元运费", reduceDeliveryFee);
|
||||
logger.debug("下单时,不符合规则的:\n {}\n符合规则的:{}", JSONUtil.toJsonStr(noPassed), JSONUtil.toJsonStr(passed));
|
||||
logger.debug(storeName + "下单时,根据商家运费设置规则减免{}元运费", reduceDeliveryFee);
|
||||
logger.debug(storeName + "下单时,不符合规则的:\n {}\n符合规则的:{}", JSONUtil.toJsonStr(noPassed), JSONUtil.toJsonStr(passed));
|
||||
|
||||
if (passed.size() == 0 && noPassed.size() > 0) {
|
||||
// 没有一个满足起送距离和起送金额的规则订单
|
||||
String canNotDeliveryReason="有订单不在配送范围内或订单未达起送金额,请检查!";
|
||||
String canNotDeliveryReason = storeName + "订单不在配送范围内或未达起送金额,请检查!";
|
||||
|
||||
// 根据 level 优先级升序排序
|
||||
noPassed = CollUtil.sort(noPassed, new FieldsComparator<>(DeliveryFeeResultDTO.class,"level","diffMoney"));
|
||||
noPassed = CollUtil.sort(noPassed, new FieldsComparator<>(DeliveryFeeResultDTO.class, "level", "diffMoney"));
|
||||
DeliveryFeeResultDTO deliveryFeeResultNoPassed = noPassed.get(0);
|
||||
|
||||
// 优先级显示不符合规定的提示语
|
||||
if(!deliveryFeeResultNoPassed.getDistancePassed()){
|
||||
if (!deliveryFeeResultNoPassed.getDistancePassed()) {
|
||||
canNotDeliveryReason = deliveryFeeResultNoPassed.getDistanceReason();
|
||||
}else if(!deliveryFeeResultNoPassed.getMoneyPassed()){
|
||||
} else if (!deliveryFeeResultNoPassed.getMoneyPassed()) {
|
||||
canNotDeliveryReason = deliveryFeeResultNoPassed.getMoneyReason();
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user