1.0 完成

This commit is contained in:
hupeng
2023-07-31 11:16:50 +08:00
parent 0ae51f9ee7
commit 0e0b2d7624
31 changed files with 516 additions and 233 deletions

View File

@ -1,3 +1,11 @@
**yshop-pro**
<h1 style="text-align: center">yshop-pro意向电商商城系统</h1>
#### 项目简介
YSHOP-PRO 技术特色移动端uniapp全新的ui、vue3全新全家桶、高并发高性能支持消息队列、异步任务、分布式锁、限流、冥等性等、支持多种支付(微信、支付宝)、支持批量上传商品、支持电子面单、支持微信统一登录各端等新特性!!! 其他新特性尽情期待;
#### 官网地址https://www.yixiang.co

View File

@ -3,7 +3,7 @@ set -e
DATE=$(date +%Y%m%d%H%M)
# 基础路径
BASE_PATH=/work/projects/yshop-server
BASE_PATH=/work/projects/yshop-pro-server
# 编译后 jar 的地址。部署时Jenkins 会上传 jar 包到该目录下
SOURCE_PATH=$BASE_PATH/build
# 服务名称。同时约定部署服务的 jar 包名字也为它。
@ -18,12 +18,6 @@ HEAP_ERROR_PATH=$BASE_PATH/heapError
# JVM 参数
JAVA_OPS="-Xms512m -Xmx512m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$HEAP_ERROR_PATH"
# SkyWalking Agent 配置
#export SW_AGENT_NAME=$SERVER_NAME
#export SW_AGENT_COLLECTOR_BACKEND_SERVICES=192.168.0.84:11800
#export SW_GRPC_LOG_SERVER_HOST=192.168.0.84
#export SW_AGENT_TRACE_IGNORE_PATH="Redisson/PING,/actuator/**,/admin/**"
#export JAVA_AGENT=-javaagent:/work/skywalking/apache-skywalking-apm-bin/agent/skywalking-agent.jar
# 备份
function backup() {

View File

@ -20,7 +20,6 @@
<module>yshop-module-mp</module>
<module>yshop-module-mall</module>
<!-- 示例项目 -->
<module>yshop-sso-example</module>
<module>yshop-module-express</module>
<module>yshop-module-message</module>
</modules>
@ -30,7 +29,7 @@
<properties>
<revision>1.7.2-snapshot</revision>
<revision>1.0.0</revision>
<!-- Maven 相关 -->
<java.version>1.8</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>

View File

@ -14,7 +14,7 @@
<url>https://github.com/guchengwuyue/yshop-pro</url>
<properties>
<revision>1.7.2-snapshot</revision>
<revision>1.0.0</revision>
<!-- 统一依赖管理 -->
<spring.boot.version>2.7.10</spring.boot.version>
<!-- Web 相关 -->

View File

@ -23,7 +23,7 @@ public interface ShopConstants {
/**
* redis订单未付款key
*/
String REDIS_ORDER_OUTTIME_UNPAY = "order:unpay:";
String REDIS_ORDER_OUTTIME_UNPAY_QUEUE = "order-unpay-cancel-queue";
/**
* redis订单收货key
*/

View File

@ -28,10 +28,6 @@ public class BannerApplicationRunner implements ApplicationRunner {
"http://localhost/doc.html",
"https://www.yixiang.co");
// 商城
if (isNotPresent("co.yixiang.yshop.module.trade.framework.web.config.TradeWebConfiguration")) {
System.out.println("[商城系统 yshop-module-mall -需要购买才有哦,我们开源的是整个商城后台管理系统,移动端需要购买才有");
}
});
}

View File

@ -109,7 +109,7 @@ public class ExpressController {
}
@PostMapping("/set")
@Operation(summary = "获得快递鸟配置")
@Operation(summary = "快递鸟配置")
public CommonResult<Boolean> postExpressSet(@RequestBody KdniaoApiBaseDTO kdniaoApiBaseDTO) {
expressRedisDAO.set(kdniaoApiBaseDTO);
return success(true);

View File

@ -33,6 +33,12 @@
<version>${revision}</version>
</dependency>
<!-- Job 定时任务相关 -->
<dependency>
<groupId>co.yixiang.boot</groupId>
<artifactId>yshop-spring-boot-starter-job</artifactId>
</dependency>
<!-- 业务组件 -->
<dependency>
<groupId>co.yixiang.boot</groupId>

View File

@ -64,6 +64,7 @@ public class AppCartController {
@PreAuthenticated
@PostMapping("/add")
@Operation(summary = "添加购物车")
public CommonResult<Map<String,Object>> add(@Validated @RequestBody AppCartParam cartParam){
Map<String,Object> map = new LinkedHashMap<>();
Long uid = getLoginUserId();

View File

@ -20,6 +20,10 @@ import co.yixiang.yshop.module.product.service.storeproductattrvalue.StoreProduc
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@ -40,6 +44,7 @@ import static co.yixiang.yshop.module.cart.enums.ErrorCodeConstants.STORE_CART_N
*
* @author yshop
*/
@Slf4j
@Service
@Validated
public class AppStoreCartServiceImpl extends ServiceImpl<StoreCartMapper,StoreCartDO> implements AppStoreCartService {
@ -53,6 +58,7 @@ public class AppStoreCartServiceImpl extends ServiceImpl<StoreCartMapper,StoreCa
@Resource
private StoreProductAttrValueService storeProductAttrValueService;
/**
* 返回当前用户购物车总数量
*
@ -119,7 +125,7 @@ public class AppStoreCartServiceImpl extends ServiceImpl<StoreCartMapper,StoreCa
}
/**
* 检测商品库存
* 检测商品库存 库存加锁
*
* @param uid 用户ID
* @param productId 产品ID
@ -271,9 +277,11 @@ public class AppStoreCartServiceImpl extends ServiceImpl<StoreCartMapper,StoreCa
* 修改购物车支付状态
* @param cartIds
*/
@Async
@Override
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
//@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public void updateCartPayStatus(List<String> cartIds) {
log.info("==========修改购物车支付状态start===========");
StoreCartDO cartObj = new StoreCartDO();
cartObj.setIsPay(OrderInfoEnum.PAY_STATUS_1.getValue());
storeCartMapper.update(cartObj, Wrappers.<StoreCartDO>lambdaQuery()

View File

@ -78,11 +78,7 @@
<artifactId>yshop-spring-boot-starter-excel</artifactId>
</dependency>
<!-- Job 定时任务相关 -->
<dependency>
<groupId>co.yixiang.boot</groupId>
<artifactId>yshop-spring-boot-starter-job</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -8,7 +8,10 @@ import co.yixiang.yshop.module.order.controller.admin.storeorder.vo.*;
import co.yixiang.yshop.module.order.convert.storeorder.StoreOrderConvert;
import co.yixiang.yshop.module.order.dal.dataobject.storeorder.StoreOrderDO;
import co.yixiang.yshop.module.order.dal.dataobject.storeorderstatus.StoreOrderStatusDO;
import co.yixiang.yshop.module.order.dal.redis.order.AsyncCountRedisDAO;
import co.yixiang.yshop.module.order.service.storeorder.AsyncStoreOrderService;
import co.yixiang.yshop.module.order.service.storeorder.StoreOrderService;
import co.yixiang.yshop.module.order.service.storeorder.dto.OrderTimeDataDto;
import co.yixiang.yshop.module.order.service.storeorderstatus.StoreOrderStatusService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.v3.oas.annotations.Operation;
@ -39,6 +42,10 @@ public class StoreOrderController {
private StoreOrderService storeOrderService;
@Resource
private StoreOrderStatusService storeOrderStatusService;
@Resource
private AsyncCountRedisDAO asyncCountRedisDAO;
@Resource
private AsyncStoreOrderService asyncStoreOrderService;
@PostMapping("/create")
@Operation(summary = "创建订单")
@ -140,5 +147,13 @@ public class StoreOrderController {
}
@GetMapping("/count")
@Operation(summary = "获得订单统计")
public CommonResult<OrderTimeDataDto> getStoreOrderCount() {
asyncStoreOrderService.getOrderTimeData();
return success(asyncCountRedisDAO.get());
}
}

View File

@ -0,0 +1,38 @@
package co.yixiang.yshop.module.order.controller.admin.storeorder.vo;
import lombok.Data;
import java.io.Serializable;
/**
* @ClassName OrderTimeDataDTO
* @Author hupeng <610796224@qq.com>
* @Date 2023/7/26
**/
@Data
public class ShoperOrderTimeDataVo implements Serializable {
/**今日成交额*/
private Double todayPrice;
/**今日订单数*/
private Long todayCount;
/**昨日成交额*/
private Double proPrice;
/**昨日订单数*/
private Long proCount;
/**本月成交额*/
private Double monthPrice;
/**本月订单数*/
private Long monthCount;
/**上周订单数*/
private Long lastWeekCount;
/**上周成交额*/
private Double lastWeekPrice;
}

View File

@ -1,5 +1,6 @@
package co.yixiang.yshop.module.order.controller.admin.storeorder.vo;
import co.yixiang.yshop.framework.desensitize.core.slider.annotation.MobileDesensitize;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
@ -32,6 +33,7 @@ public class StoreOrderBaseVO {
@NotNull(message = "用户姓名不能为空")
private String realName;
@MobileDesensitize
@Schema(description = "用户电话", required = true)
@NotNull(message = "用户电话不能为空")
private String userPhone;

View File

@ -12,13 +12,17 @@ import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import co.yixiang.yshop.framework.common.pojo.CommonResult;
import co.yixiang.yshop.framework.security.core.annotations.PreAuthenticated;
import co.yixiang.yshop.module.express.dal.redis.express.ExpressRedisDAO;
import co.yixiang.yshop.module.express.kdniao.model.dto.KdniaoApiBaseDTO;
import co.yixiang.yshop.module.express.kdniao.model.dto.KdniaoApiDTO;
import co.yixiang.yshop.module.express.kdniao.model.vo.KdniaoApiVO;
import co.yixiang.yshop.module.express.kdniao.util.KdniaoUtil;
import co.yixiang.yshop.module.member.controller.app.user.vo.AppUserOrderCountVo;
import co.yixiang.yshop.module.order.controller.app.order.param.*;
import co.yixiang.yshop.module.order.controller.app.order.vo.AppConfirmOrderVo;
import co.yixiang.yshop.module.order.controller.app.order.vo.AppStoreOrderQueryVo;
import co.yixiang.yshop.module.order.dal.redis.order.AsyncOrderRedisDAO;
import co.yixiang.yshop.module.order.service.storeorder.AppStoreOrderService;
import co.yixiang.yshop.module.pay.mq.producer.PayNoticeProducer;
import com.egzosn.pay.spring.boot.core.PayServiceManager;
import com.egzosn.pay.web.support.HttpRequestNoticeParams;
import io.swagger.v3.oas.annotations.Operation;
@ -34,7 +38,8 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.*;
import java.util.List;
import java.util.Map;
import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil.exception;
import static co.yixiang.yshop.framework.common.pojo.CommonResult.success;
@ -61,18 +66,8 @@ public class AppOrderController {
private final AsyncOrderRedisDAO asyncOrderRedisDAO;
private final PayServiceManager manager;
@Resource
private PayNoticeProducer payNoticeProducer;
// @Autowired
// private MerchantDetailsManager<PaymentPlatformMerchantDetails> merchantDetailsManager;
// @GetMapping("merchantExists")
// public Map<String, Object> merchantExists() {
// return new MapGen<String, Object>("exist", merchantDetailsManager.merchantExists("1")).getAttr();
// }
private ExpressRedisDAO expressRedisDAO;
@ -109,45 +104,7 @@ public class AppOrderController {
public CommonResult<Map<String, Object>> create(@Valid @RequestBody AppOrderParam param,
@PathVariable String key) {
Long uid = getLoginUserId();
// ComputeOrderParam computeOrderParam = new ComputeOrderParam();
// BeanUtil.copyProperties(param, computeOrderParam);
// Map<String, Object> map = orderSupplyService.check(yxUser.getUid(), key, computeOrderParam);
// if (OrderLogEnum.EXTEND_ORDER.getValue().equals(map.get("status"))
// || OrderLogEnum.PINK_ORDER_FAIL_2.getValue().equals(map.get("status"))
// || OrderLogEnum.PINK_ORDER_FAIL_1.getValue().equals(map.get("status"))) {
// return ApiResult.ok(map, map.get("msg").toString());
// }
//
//
// //创建订单
// YxStoreOrder order = appStoreOrderService.createOrder(uid, key, param);
return success(appStoreOrderService.createOrder(uid, key, param));
// if (ObjectUtil.isNull(order)) {
// throw new YshopException("订单生成失败");
// }
//
// String orderId = order.getOrderId();
//
// OrderExtendDto orderDTO = new OrderExtendDto();
// orderDTO.setKey(key);
// orderDTO.setOrderId(orderId);
// map.put("status", OrderLogEnum.CREATE_ORDER_SUCCESS.getValue());
// map.put("result", orderDTO);
// map.put("createTime", order.getCreateTime());
//开始处理支付
//处理金额为0的情况
// if(order.getPayPrice().compareTo(BigDecimal.ZERO) <= 0&&!param.getPayType().equals(PayTypeEnum.INTEGRAL.getValue())){
// storeOrderService.yuePay(orderId,yxUser.getUid());
// map.put("payMsg","支付成功");
// return ApiResult.ok(map,"支付成功");
// }
//
// orderSupplyService.goPay(map,orderId,yxUser.getUid(),
// param.getPayType(),param.getFrom(),orderDTO);
// return ApiResult.ok(map, map.get("payMsg").toString());
}
@ -293,47 +250,28 @@ public class AppOrderController {
// /**
// * 获取物流信息
// */
// @AuthCheck
// @PostMapping("/order/express")
// @ApiOperation(value = "获取物流信息", notes = "获取物流信息")
// public ApiResult<ExpressInfo> express(@RequestBody ExpressParam expressInfoDo) {
//
// //顺丰轨迹查询处理
// String lastFourNumber = "";
// if (expressInfoDo.getShipperCode().equals(ShipperCodeEnum.SF.getValue())) {
// YxStoreOrderQueryVo yxStoreOrderDto;
// yxStoreOrderDto = storeOrderService.getOrderInfo(expressInfoDo.getOrderCode(),null);
// lastFourNumber = yxStoreOrderDto.getUserPhone();
// if (lastFourNumber.length() == 11) {
// lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
// }
// }
//
// ExpressService expressService = ExpressAutoConfiguration.expressService();
// ExpressInfo expressInfo = expressService.getExpressInfo(expressInfoDo.getOrderCode(),
// expressInfoDo.getShipperCode(), expressInfoDo.getLogisticCode(), lastFourNumber);
// if (!expressInfo.isSuccess()) {
// throw new YshopException(expressInfo.getReason());
// }
// return ApiResult.ok(expressInfo);
// }
/**
* 获取物流信息
*/
@PreAuthenticated
@PostMapping("/order/express")
@Operation(summary = "获取物流信息")
public CommonResult<KdniaoApiVO> express(@RequestBody AppExpressParam appExpressParam) {
KdniaoApiBaseDTO kdniaoApiBaseDTO = expressRedisDAO.get();
KdniaoApiDTO params = new KdniaoApiDTO();
params.setLogisticCode(appExpressParam.getLogisticCode());
params.setShipperCode(appExpressParam.getShipperCode());
params.setApiKey(kdniaoApiBaseDTO.getApiKey());
params.setEBusinessID(kdniaoApiBaseDTO.getEBusinessID());
//此处注意 这个地方分收费与免费当 目前用当免费免费当只支持圆通 申通 百世 如果是收费当 改里面RequestType参数 函数里有说明
return success(KdniaoUtil.getLogisticInfo(params));
}
// @AuthCheck
// @GetMapping("/order/getSubscribeTemplate")
// @ApiOperation(value = "获取订阅消息模板ID", notes = "获取订阅消息模板ID")
// public ApiResult<List<String>> getSubscribeTemplate() {
// List<YxWechatTemplate> yxWechatTemplate = yxWechatTemplateService.lambdaQuery()
// .eq(YxWechatTemplate::getType, "subscribe")
// .eq(YxWechatTemplate::getStatus, ShopCommonEnum.IS_STATUS_1.getValue()).list();
// List<String> temId = yxWechatTemplate.stream().map(tem -> tem.getTempid()).collect(Collectors.toList());
// return ApiResult.ok(temId);
// }
}

View File

@ -0,0 +1,24 @@
package co.yixiang.yshop.module.order.controller.app.order.param;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
/**
* @ClassName ExpressParam
* @Author hupeng <610796224@qq.com>
* @Date 2023/7/26
**/
@Data
public class AppExpressParam implements Serializable {
@Schema(description = "订单编号", required = true)
private String orderCode;
@Schema(description = "快递公司编码", required = true)
private String shipperCode;
@Schema(description = "物流单号", required = true)
private String logisticCode;
}

View File

@ -11,6 +11,8 @@ import co.yixiang.yshop.framework.mybatis.core.mapper.BaseMapperX;
import co.yixiang.yshop.module.order.dal.dataobject.storeorder.StoreOrderDO;
import co.yixiang.yshop.module.order.enums.AdminOrderStatusEnum;
import co.yixiang.yshop.module.order.enums.OrderStatusEnum;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Mapper;
import co.yixiang.yshop.module.order.controller.admin.storeorder.vo.*;
import org.apache.ibatis.annotations.Param;
@ -98,4 +100,12 @@ public interface StoreOrderMapper extends BaseMapperX<StoreOrderDO> {
"where paid=1 and deleted=0 and refund_status=0 and uid=#{uid}")
double sumPrice(@Param("uid") Long uid);
@Select("SELECT IFNULL(sum(pay_price),0) " +
" FROM yshop_store_order ${ew.customSqlSegment}")
Double todayPrice(@Param(Constants.WRAPPER) Wrapper<StoreOrderDO> wrapper);
@Select( "select IFNULL(sum(pay_price),0) from yshop_store_order " +
"where refund_status=0 and deleted=0 and paid=1")
Double sumTotalPrice();
}

View File

@ -25,5 +25,9 @@ public interface RedisKeyConstants {
"yshop_order_count_cache:%s", // 参数为访问uid
STRING, CacheDto.class, RedisKeyDefine.TimeoutTypeEnum.FOREVER);
RedisKeyDefine YSHOP_ADMIN_ORDER_COUNT_CACHE_KEY = new RedisKeyDefine("后台统计订单数据缓存",
"yshop_admin_order_count_cache:", // 参数为访问uid
STRING, CacheDto.class, RedisKeyDefine.TimeoutTypeEnum.FOREVER);
}

View File

@ -0,0 +1,45 @@
package co.yixiang.yshop.module.order.dal.redis.order;
import co.yixiang.yshop.framework.common.util.json.JsonUtils;
import co.yixiang.yshop.module.member.controller.app.user.vo.AppUserOrderCountVo;
import co.yixiang.yshop.module.order.controller.admin.storeorder.vo.ShoperOrderTimeDataVo;
import co.yixiang.yshop.module.order.service.storeorder.dto.OrderTimeDataDto;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import static co.yixiang.yshop.module.order.dal.redis.RedisKeyConstants.YSHOP_ADMIN_ORDER_COUNT_CACHE_KEY;
/**
* {@link AppUserOrderCountVo} 的 RedisDAO
*
* @author yshop
*/
@Repository
public class AsyncCountRedisDAO {
@Resource
private StringRedisTemplate stringRedisTemplate;
public OrderTimeDataDto get() {
String redisKey = YSHOP_ADMIN_ORDER_COUNT_CACHE_KEY.getKeyTemplate();
return JsonUtils.parseObject(stringRedisTemplate.opsForValue().get(redisKey), OrderTimeDataDto.class);
}
public void set(OrderTimeDataDto orderTimeDataDto) {
String redisKey = YSHOP_ADMIN_ORDER_COUNT_CACHE_KEY.getKeyTemplate();
stringRedisTemplate.opsForValue().set(redisKey, JsonUtils.toJsonString(orderTimeDataDto));
}
public void delete(Long uid) {
String redisKey = YSHOP_ADMIN_ORDER_COUNT_CACHE_KEY.getKeyTemplate();
stringRedisTemplate.delete(redisKey);
}
private static String formatKey(String key) {
return String.format(YSHOP_ADMIN_ORDER_COUNT_CACHE_KEY.getKeyTemplate(), key);
}
}

View File

@ -0,0 +1,74 @@
package co.yixiang.yshop.module.order.handle;
import cn.hutool.core.thread.ExecutorBuilder;
import cn.hutool.core.thread.ThreadFactoryBuilder;
import cn.hutool.core.util.StrUtil;
import co.yixiang.yshop.framework.common.constant.ShopConstants;
import co.yixiang.yshop.module.order.service.storeorder.AppStoreOrderService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadFactory;
/**
* 延时队列消费
* @author hupeng
* @date 2023.7.27
*/
@Component
@Slf4j
public class RedisDelayHandle {
@Resource
private RedissonClient redissonClient;
@Resource
private AppStoreOrderService appStoreOrderService;
@PostConstruct
public void startJobTimer() {
ThreadFactory threadFactory = new ThreadFactoryBuilder().setNamePrefix("delay-job-service").build();
log.info("========延时队列开始=========");
ExecutorService executorService = ExecutorBuilder.create()
.setCorePoolSize(2)
.setMaxPoolSize(10)
.setKeepAliveTime(0)
.setThreadFactory(threadFactory)
.build();
executorService.execute(new ExecutorTask());
}
class ExecutorTask implements Runnable {
@SneakyThrows
@Override
public void run() {
RBlockingDeque<String> blockingDeque = redissonClient
.getBlockingDeque(ShopConstants.REDIS_ORDER_OUTTIME_UNPAY_QUEUE);
RBlockingDeque<String> blockingDeque2 = redissonClient
.getBlockingDeque(ShopConstants.REDIS_ORDER_OUTTIME_UNCONFIRM);
while (true) {
String orderId = "";
String orderId2 = "";
try {
orderId = blockingDeque.take();
orderId2 = blockingDeque2.take();
} catch (Exception e) {
log.error(e.getMessage());
}
if(StrUtil.isNotEmpty(orderId)) {
appStoreOrderService.cancelOrder(orderId,null);
}
if(StrUtil.isNotEmpty(orderId2)) {
appStoreOrderService.takeOrder(orderId,null);
}
}
}
}
}

View File

@ -8,6 +8,7 @@ import cn.hutool.core.util.StrUtil;
import co.yixiang.yshop.framework.common.constant.ShopConstants;
import co.yixiang.yshop.framework.common.enums.OrderInfoEnum;
import co.yixiang.yshop.framework.common.enums.ShopCommonEnum;
import co.yixiang.yshop.framework.common.exception.ErrorCode;
import co.yixiang.yshop.module.cart.service.storecart.AppStoreCartService;
import co.yixiang.yshop.module.member.controller.app.user.vo.AppUserQueryVo;
import co.yixiang.yshop.module.member.dal.dataobject.user.MemberUserDO;
@ -57,6 +58,12 @@ import com.egzosn.pay.common.bean.RefundResult;
import com.egzosn.pay.spring.boot.core.PayServiceManager;
import com.egzosn.pay.spring.boot.core.bean.MerchantPayOrder;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@ -66,6 +73,7 @@ import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil.exception;
@ -77,6 +85,7 @@ import static co.yixiang.yshop.module.order.enums.ErrorCodeConstants.*;
*
* @author yshop
*/
@Slf4j
@Service
@Validated
public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper,StoreOrderDO> implements AppStoreOrderService {
@ -111,6 +120,11 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper,Store
private PayServiceManager manager;
@Resource
private WeixinNoticeProducer weixinNoticeProducer;
@Resource
private RedissonClient redissonClient;
private static final String LOCK_KEY = "cart:check:stock:lock";
private static final String STOCK_LOCK_KEY = "cart:do:stock:lock";
@ -286,12 +300,23 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper,Store
CacheDto cacheDTO = orderRedisDAO.get(key, uid);
List<AppStoreCartQueryVo> cartInfo = cacheDTO.getCartInfo();
for (AppStoreCartQueryVo cart : cartInfo) {
//检测库存
appStoreCartService.checkProductStock(uid, cart.getProductId(), cart.getCartNum(), cart.getProductAttrUnique());
//对库存检查加锁
RLock lock = redissonClient.getLock(LOCK_KEY);
if (lock.tryLock()){
try {
for (AppStoreCartQueryVo cart : cartInfo) {
//检测库存
appStoreCartService.checkProductStock(uid, cart.getProductId(), cart.getCartNum(), cart.getProductAttrUnique());
cartIds.add(cart.getId().toString());
totalNum += cart.getCartNum();
cartIds.add(cart.getId().toString());
totalNum += cart.getCartNum();
}
}catch (Exception ex) {
log.error("[checkProductStock][执行异常]", ex);
throw exception(new ErrorCode(999999,ex.getMessage()));
} finally {
lock.unlock();
}
}
@ -336,11 +361,11 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper,Store
this.deStockIncSale(cartInfo);
//保存购物车商品信息
//保存购物车商品信息,异步执行
storeOrderCartInfoService.saveCartInfo(storeOrder.getId(), storeOrder.getOrderId(),cartInfo);
//购物车状态修改
//购物车状态修改异步执行
appStoreCartService.updateCartPayStatus(cartIds);
@ -352,11 +377,16 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper,Store
OrderLogEnum.CREATE_ORDER.getDesc());
//加入redis30分钟自动取消 todo 延时队列
// String redisKey = String.valueOf(StrUtil.format("{}{}",
// ShopConstants.REDIS_ORDER_OUTTIME_UNPAY, storeOrder.getId()));
// redisTemplate.opsForValue().set(redisKey, storeOrder.getOrderId(),
// ShopConstants.ORDER_OUTTIME_UNPAY, TimeUnit.MINUTES);
//加入延时队列30分钟自动取消
try {
RBlockingDeque<Object> blockingDeque = redissonClient.getBlockingDeque(ShopConstants.REDIS_ORDER_OUTTIME_UNPAY_QUEUE);
RDelayedQueue<Object> delayedQueue = redissonClient.getDelayedQueue(blockingDeque);
delayedQueue.offer(orderSn, ShopConstants.ORDER_OUTTIME_UNPAY, TimeUnit.MINUTES);
String s = TimeUnit.SECONDS.toSeconds(ShopConstants.ORDER_OUTTIME_UNPAY) + "分钟";
log.info("添加延时队列成功 ,延迟时间:" + s);
} catch (Exception e) {
log.error(e.getMessage());
}
OrderExtendDto orderDTO = new OrderExtendDto();
orderDTO.setKey(key);
@ -522,9 +552,21 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper,Store
*/
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public void deStockIncSale(List<AppStoreCartQueryVo> cartInfo) {
for (AppStoreCartQueryVo storeCartVO : cartInfo) {
appStoreProductService.decProductStock(storeCartVO.getCartNum(), storeCartVO.getProductId(),
storeCartVO.getProductAttrUnique(), 0L, "");
log.info("========减库存增加销量start=========");
//对库存加锁
RLock lock = redissonClient.getLock(STOCK_LOCK_KEY);
if (lock.tryLock()) {
try {
for (AppStoreCartQueryVo storeCartVO : cartInfo) {
appStoreProductService.decProductStock(storeCartVO.getCartNum(), storeCartVO.getProductId(),
storeCartVO.getProductAttrUnique(), 0L, "");
}
}catch (Exception ex) {
log.error("[deStockIncSale][执行异常]", ex);
throw exception(new ErrorCode(999999,ex.getMessage()));
} finally {
lock.unlock();
}
}
}
@ -714,7 +756,7 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper,Store
this.updateById(storeOrder);
//增加状态
storeOrderStatusService.create(uid,order.getId(), OrderLogEnum.TAKE_ORDER_DELIVERY.getValue(), OrderLogEnum.TAKE_ORDER_DELIVERY.getDesc());
storeOrderStatusService.create(order.getUid(),order.getId(), OrderLogEnum.TAKE_ORDER_DELIVERY.getValue(), OrderLogEnum.TAKE_ORDER_DELIVERY.getDesc());
//奖励积分
this.gainUserIntegral(order);
@ -817,6 +859,7 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper,Store
@Override
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public void cancelOrder(String orderId, Long uid) {
log.info("订单取消:({})",orderId);
AppStoreOrderQueryVo order = this.getOrderInfo(orderId, uid);
if (ObjectUtil.isNull(order)) {
throw exception(STORE_ORDER_NOT_EXISTS);

View File

@ -1,19 +1,28 @@
package co.yixiang.yshop.module.order.service.storeorder;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import co.yixiang.yshop.framework.common.enums.OrderInfoEnum;
import co.yixiang.yshop.module.member.controller.app.user.vo.AppUserOrderCountVo;
import co.yixiang.yshop.module.member.service.user.MemberUserService;
import co.yixiang.yshop.module.order.controller.admin.storeorder.vo.ShoperOrderTimeDataVo;
import co.yixiang.yshop.module.order.dal.dataobject.storeaftersales.StoreAfterSalesDO;
import co.yixiang.yshop.module.order.dal.dataobject.storeorder.StoreOrderDO;
import co.yixiang.yshop.module.order.dal.mysql.storeorder.StoreOrderMapper;
import co.yixiang.yshop.module.order.dal.redis.order.AsyncCountRedisDAO;
import co.yixiang.yshop.module.order.dal.redis.order.AsyncOrderRedisDAO;
import co.yixiang.yshop.module.order.service.storeaftersales.AppStoreAfterSalesService;
import co.yixiang.yshop.module.order.service.storeorder.dto.OrderTimeDataDto;
import co.yixiang.yshop.module.product.service.storeproduct.StoreProductService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Date;
import java.util.Objects;
/**
@ -23,6 +32,7 @@ import java.util.Objects;
*/
@Service
@Validated
@Slf4j
public class AsynStoreOrderServiceImpl implements AsyncStoreOrderService {
@Resource
@ -31,6 +41,12 @@ public class AsynStoreOrderServiceImpl implements AsyncStoreOrderService {
private AppStoreAfterSalesService appStoreAfterSalesService;
@Resource
private AsyncOrderRedisDAO asyncOrderRedisDAO;
@Resource
private AsyncCountRedisDAO asyncCountRedisDAO;
@Resource
private MemberUserService userService;
@Resource
private StoreProductService productService;
/**
* 获取某个用户的订单统计数据
@ -41,6 +57,7 @@ public class AsynStoreOrderServiceImpl implements AsyncStoreOrderService {
@Override
@Async
public void orderData(Long uid) {
log.info("========获取某个用户的订单统计数据=========");
//订单支付没有退款 数量
LambdaQueryWrapper<StoreOrderDO> wrapperOne = new LambdaQueryWrapper<>();
if (uid != null) {
@ -103,15 +120,6 @@ public class AsynStoreOrderServiceImpl implements AsyncStoreOrderService {
.eq(StoreOrderDO::getStatus, OrderInfoEnum.STATUS_3.getValue());
Long completeCount = storeOrderMapper.selectCount(wrapperSix);
//订单退款
// LambdaQueryWrapper<StoreOrderDO> wrapperSeven = new LambdaQueryWrapper<>();
// if (uid != null) {
// wrapperSeven.eq(StoreOrderDO::getUid, uid);
// }
// String[] strArr = {"1", "2"};
// wrapperSeven.eq(StoreOrderDO::getPaid, OrderInfoEnum.PAY_STATUS_1.getValue())
// .in(StoreOrderDO::getRefundStatus, Arrays.asList(strArr));
// Long refundCount = storeOrderMapper.selectCount(wrapperSeven);
//售后退款
Long salesCount = appStoreAfterSalesService.lambdaQuery()
.eq(Objects.nonNull(uid), StoreAfterSalesDO::getUserId, uid)
@ -130,6 +138,91 @@ public class AsynStoreOrderServiceImpl implements AsyncStoreOrderService {
//存redis
asyncOrderRedisDAO.set(appUserOrderCountVo,uid);
this.getOrderTimeData();
}
/**
* 首页订单/用户等统计
*
* @return OrderTimeDataDto
*/
@Async
@Override
public void getOrderTimeData() {
OrderTimeDataDto orderTimeDataDto = new OrderTimeDataDto();
ShoperOrderTimeDataVo shoperOrderTimeData = this.getShoperOrderTimeData();
BeanUtil.copyProperties(shoperOrderTimeData, orderTimeDataDto);
orderTimeDataDto.setUserCount(userService.count());
orderTimeDataDto.setOrderCount(storeOrderMapper.selectCount());
orderTimeDataDto.setPriceCount(storeOrderMapper.sumTotalPrice());
orderTimeDataDto.setGoodsCount(productService.count());
asyncCountRedisDAO.set(orderTimeDataDto);
}
/**
* 异步后台统计
*/
public ShoperOrderTimeDataVo getShoperOrderTimeData() {
Date today = DateUtil.beginOfDay(new Date());
Date yesterday = DateUtil.beginOfDay(DateUtil.yesterday());
Date nowMonth = DateUtil.beginOfMonth(new Date());
Date lastWeek = DateUtil.beginOfDay(DateUtil.lastWeek());
ShoperOrderTimeDataVo orderTimeDataVo = new ShoperOrderTimeDataVo();
//今日成交额
LambdaQueryWrapper<StoreOrderDO> wrapperOne = new LambdaQueryWrapper<>();
wrapperOne
.ge(StoreOrderDO::getPayTime, today)
.eq(StoreOrderDO::getPaid, OrderInfoEnum.PAY_STATUS_1.getValue())
.eq(StoreOrderDO::getRefundStatus, OrderInfoEnum.REFUND_STATUS_0.getValue());
orderTimeDataVo.setTodayPrice(storeOrderMapper.todayPrice(wrapperOne));
//今日订单数
orderTimeDataVo.setTodayCount(storeOrderMapper.selectCount(wrapperOne));
//昨日成交额
LambdaQueryWrapper<StoreOrderDO> wrapperTwo = new LambdaQueryWrapper<>();
wrapperTwo
.lt(StoreOrderDO::getPayTime, today)
.ge(StoreOrderDO::getPayTime, yesterday)
.eq(StoreOrderDO::getPaid, OrderInfoEnum.PAY_STATUS_1.getValue())
.eq(StoreOrderDO::getRefundStatus, OrderInfoEnum.REFUND_STATUS_0.getValue());
orderTimeDataVo.setProPrice(storeOrderMapper.todayPrice(wrapperTwo));
//昨日订单数
orderTimeDataVo.setProCount(storeOrderMapper.selectCount(wrapperTwo));
//本月成交额
LambdaQueryWrapper<StoreOrderDO> wrapperThree = new LambdaQueryWrapper<>();
wrapperThree
.ge(StoreOrderDO::getPayTime, nowMonth)
.eq(StoreOrderDO::getPaid, OrderInfoEnum.PAY_STATUS_1.getValue())
.eq(StoreOrderDO::getRefundStatus, OrderInfoEnum.REFUND_STATUS_0.getValue());
orderTimeDataVo.setMonthPrice(storeOrderMapper.todayPrice(wrapperThree));
//本月订单数
orderTimeDataVo.setMonthCount(storeOrderMapper.selectCount(wrapperThree));
//上周成交额
LambdaQueryWrapper<StoreOrderDO> wrapperLastWeek = new LambdaQueryWrapper<>();
wrapperLastWeek
.lt(StoreOrderDO::getPayTime, today)
.ge(StoreOrderDO::getPayTime, lastWeek)
.eq(StoreOrderDO::getPaid, OrderInfoEnum.PAY_STATUS_1.getValue())
.eq(StoreOrderDO::getRefundStatus, OrderInfoEnum.REFUND_STATUS_0.getValue());
orderTimeDataVo.setLastWeekPrice(storeOrderMapper.todayPrice(wrapperLastWeek));
//上周订单数
orderTimeDataVo.setLastWeekCount(storeOrderMapper.selectCount(wrapperLastWeek));
return orderTimeDataVo;
}

View File

@ -1,6 +1,8 @@
package co.yixiang.yshop.module.order.service.storeorder;
import co.yixiang.yshop.module.member.controller.app.user.vo.AppUserOrderCountVo;
import co.yixiang.yshop.module.order.controller.admin.storeorder.vo.ShoperOrderTimeDataVo;
import co.yixiang.yshop.module.order.service.storeorder.dto.OrderTimeDataDto;
/**
* 异步订单 Service 接口
@ -16,4 +18,11 @@ public interface AsyncStoreOrderService {
*/
void orderData(Long uid);
/**
* 异步后台数据统计
*/
void getOrderTimeData();
}

View File

@ -2,6 +2,7 @@ package co.yixiang.yshop.module.order.service.storeorder;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import co.yixiang.yshop.framework.common.constant.ShopConstants;
import co.yixiang.yshop.framework.common.enums.OrderInfoEnum;
import co.yixiang.yshop.framework.common.enums.ShopCommonEnum;
import co.yixiang.yshop.framework.common.exception.ErrorCode;
@ -22,6 +23,9 @@ import co.yixiang.yshop.module.member.controller.admin.user.vo.UserRespVO;
import co.yixiang.yshop.module.member.convert.user.UserConvert;
import co.yixiang.yshop.module.member.dal.dataobject.user.MemberUserDO;
import co.yixiang.yshop.module.member.dal.mysql.user.MemberUserMapper;
import co.yixiang.yshop.module.member.service.user.MemberUserService;
import co.yixiang.yshop.module.message.enums.WechatTempateEnum;
import co.yixiang.yshop.module.message.mq.producer.WeixinNoticeProducer;
import co.yixiang.yshop.module.order.controller.admin.storeorder.vo.*;
import co.yixiang.yshop.module.order.controller.admin.storeorderelectronics.vo.StoreOrderElectronicsCreateReqVO;
import co.yixiang.yshop.module.order.convert.storeorder.StoreOrderConvert;
@ -29,6 +33,7 @@ import co.yixiang.yshop.module.order.dal.dataobject.storeorder.StoreOrderDO;
import co.yixiang.yshop.module.order.dal.dataobject.storeordercartinfo.StoreOrderCartInfoDO;
import co.yixiang.yshop.module.order.dal.mysql.storeorder.StoreOrderMapper;
import co.yixiang.yshop.module.order.dal.mysql.storeordercartinfo.StoreOrderCartInfoMapper;
import co.yixiang.yshop.module.order.enums.AppFromEnum;
import co.yixiang.yshop.module.order.enums.OrderLogEnum;
import co.yixiang.yshop.module.order.enums.UpdateOrderEnum;
import co.yixiang.yshop.module.order.service.storeorderelectronics.StoreOrderElectronicsService;
@ -36,6 +41,10 @@ import co.yixiang.yshop.module.order.service.storeorderstatus.StoreOrderStatusSe
import co.yixiang.yshop.module.product.controller.app.cart.vo.AppStoreCartQueryVo;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@ -45,6 +54,7 @@ import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;
import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil.exception;
import static co.yixiang.yshop.module.order.enums.ErrorCodeConstants.STORE_ORDER_NOT_EXISTS;
@ -54,6 +64,7 @@ import static co.yixiang.yshop.module.order.enums.ErrorCodeConstants.STORE_ORDER
*
* @author yshop
*/
@Slf4j
@Service
@Validated
public class StoreOrderServiceImpl implements StoreOrderService {
@ -76,6 +87,12 @@ public class StoreOrderServiceImpl implements StoreOrderService {
private ExpressRedisDAO expressRedisDAO;
@Resource
private StoreOrderElectronicsService storeOrderElectronicsService;
@Resource
private MemberUserService userService;
@Resource
private WeixinNoticeProducer weixinNoticeProducer;
@Resource
private RedissonClient redissonClient;
@Override
public Long createStoreOrder(StoreOrderCreateReqVO createReqVO) {
@ -102,6 +119,32 @@ public class StoreOrderServiceImpl implements StoreOrderService {
//增加状态
storeOrderStatusService.create(updateObj.getUid(),updateObj.getId(), OrderLogEnum.DELIVERY_GOODS.getValue(),
"已发货 快递公司:" + updateObj.getDeliveryName() + "快递单号:" + updateObj.getDeliveryId());
MemberUserDO userInfo = userService.getUser(updateObj.getUid());
//发送消息队列进行推送消息
if(userInfo.getLoginType().equals(AppFromEnum.ROUNTINE.getValue())){
weixinNoticeProducer.sendNoticeMessage(updateObj.getUid(), WechatTempateEnum.DELIVERY_SUCCESS.getValue(),
WechatTempateEnum.SUBSCRIBE.getValue(),updateObj.getOrderId(),
updateObj.getPayPrice().toString(),"",updateObj.getDeliveryName(),
updateObj.getDeliveryId());
}else if(userInfo.getLoginType().equals(AppFromEnum.WECHAT.getValue())){
weixinNoticeProducer.sendNoticeMessage(updateObj.getUid(),WechatTempateEnum.PAY_SUCCESS.getValue(),
WechatTempateEnum.TEMPLATES.getValue(),updateObj.getOrderId(),
updateObj.getPayPrice().toString(),"",updateObj.getDeliveryName(),
updateObj.getDeliveryId());
}
//延时队列 七天自动收货
try {
RBlockingDeque<Object> blockingDeque = redissonClient.getBlockingDeque(ShopConstants.REDIS_ORDER_OUTTIME_UNCONFIRM);
RDelayedQueue<Object> delayedQueue = redissonClient.getDelayedQueue(blockingDeque);
delayedQueue.offer(updateReqVO.getOrderId(), ShopConstants.ORDER_OUTTIME_UNCONFIRM, TimeUnit.DAYS);
String s = TimeUnit.SECONDS.toSeconds(ShopConstants.ORDER_OUTTIME_UNCONFIRM) + "";
log.info("添加延时队列成功 ,延迟时间:" + s);
} catch (Exception e) {
log.error(e.getMessage());
}
}
}

View File

@ -6,6 +6,8 @@ import co.yixiang.yshop.module.order.dal.mysql.storeordercartinfo.StoreOrderCart
import co.yixiang.yshop.module.product.controller.app.cart.vo.AppStoreCartQueryVo;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@ -19,6 +21,7 @@ import java.util.List;
*
* @author yshop
*/
@Slf4j
@Service
@Validated
public class StoreOrderCartInfoServiceImpl extends ServiceImpl<StoreOrderCartInfoMapper, StoreOrderCartInfoDO> implements StoreOrderCartInfoService {
@ -29,10 +32,11 @@ public class StoreOrderCartInfoServiceImpl extends ServiceImpl<StoreOrderCartInf
* @param orderId
* @param cartInfo 购物车信息
*/
@Async
@Override
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
//@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public void saveCartInfo(Long oid, String orderId, List<AppStoreCartQueryVo> cartInfo) {
log.info("==========添加购物车商品信息start===========");
List<StoreOrderCartInfoDO> list = new ArrayList<>();
for (AppStoreCartQueryVo cart : cartInfo) {
StoreOrderCartInfoDO info = new StoreOrderCartInfoDO();

View File

@ -31,22 +31,17 @@ public interface StoreProductMapper extends BaseMapperX<StoreProductDO> {
.eqIfPresent(StoreProductDO::getIsPostage, reqVO.getIsPostage())
.orderByDesc(StoreProductDO::getId);
//if(ShopCommonEnum.SHOW_1.getValue().equals(Convert.toInt(reqVO.getIsShow()))){
wrapper.eq(StoreProductDO::getIsShow,Convert.toInt(reqVO.getIsShow()));
// }
wrapper.eq(StoreProductDO::getIsShow,Convert.toInt(reqVO.getIsShow()));
if(DefaultEnum.DEFAULT_0.getValue().equals(Convert.toInt(reqVO.getStock()))){
wrapper.eq(StoreProductDO::getStock,DefaultEnum.DEFAULT_0.getValue());
}
// CollUtil.isNotEmpty()
if(CollUtil.isNotEmpty(reqVO.getCatIds())){
wrapper.in(StoreProductDO::getCateId,reqVO.getCatIds());
}
return selectPage(reqVO, wrapper);
// return selectPage(reqVO, new LambdaQueryWrapperX<StoreProductDO>()
// .likeIfPresent(StoreProductDO::getStoreName, reqVO.getStoreName())
// .eqIfPresent(StoreProductDO::getIsPostage, reqVO.getIsPostage())
// .orderByDesc(StoreProductDO::getId));
}
default List<StoreProductDO> selectList(StoreProductExportReqVO reqVO) {
@ -70,4 +65,14 @@ public interface StoreProductMapper extends BaseMapperX<StoreProductDO> {
" where id=#{productId}")
int incStockDecSales(@Param("num") Integer num,@Param("productId") Long productId);
/**
* 正常商品库存 减库存 加销量
* @param num
* @param productId
* @return
*/
@Update("update yshop_store_product set stock=stock-#{num}, sales=sales+#{num}" +
" where id=#{productId} and stock >= #{num}")
int decStockIncSales(@Param("num") Integer num,@Param("productId") Long productId);
}

View File

@ -122,7 +122,6 @@ public class AppStoreProductServiceImpl extends ServiceImpl<StoreProductMapper,S
LambdaQueryWrapper<StoreProductDO> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(StoreProductDO::getIsShow, ShopCommonEnum.SHOW_1.getValue());
// wrapper.eq(YxStoreProduct::getIsIntegral, CommonEnum.SHOW_STATUS_1.getValue());
if(productQueryParam.getIsIntegral()!=null){
wrapper.eq(StoreProductDO::getIsIntegral, productQueryParam.getIsIntegral());
@ -281,41 +280,16 @@ public class AppStoreProductServiceImpl extends ServiceImpl<StoreProductMapper,S
int res = 0;
// if(ProductTypeEnum.COMBINATION.getValue().equals(type)){
// res = yxStoreProductAttrValueMapper.decCombinationStockIncSales(num,productId,unique);
// }else if(ProductTypeEnum.SECKILL.getValue().equals(type)){
// res = yxStoreProductAttrValueMapper.decSeckillStockIncSales(num,productId,unique);
// }else {
res = storeProductAttrValueMapper.decStockIncSales(num,productId,unique);
// }
res = storeProductAttrValueMapper.decStockIncSales(num,productId,unique);
if(res == 0) {
throw exception(PRODUCT_STOCK_LESS);
}
// //处理属性sku
// if (StrUtil.isNotEmpty(unique)) {
// yxStoreProductAttrService.decProductAttrStock(num, productId, unique, type);
// }
// //先处理商品库存,活动商品也要处理,因为共享库存
// int product = storeProductMapper.decStockIncSales(num, productId);
// if (product == 0) {
// throw new YshopException("共享商品库存不足");
// }
// //处理商品外层显示的库存
// if (ProductTypeEnum.COMBINATION.getValue().equals(type)) {
// int combinationRes = storeProductMapper.decCombinationStockIncSales(num, productId, activityId);
// if (combinationRes == 0) {
// throw new YshopException("拼团商品库存不足");
// }
// } else if (ProductTypeEnum.SECKILL.getValue().equals(type)) {
// int seckillRes = storeProductMapper.decSeckillStockIncSales(num, productId, activityId);
// if (seckillRes == 0) {
// throw new YshopException("秒杀商品库存不足");
// }
// }
int product = this.baseMapper.decStockIncSales(num, productId);
if (product == 0) {
throw exception(PRODUCT_STOCK_LESS);
}
}

View File

@ -70,6 +70,11 @@
<artifactId>yshop-spring-boot-starter-redis</artifactId>
</dependency>
<dependency>
<groupId>co.yixiang.boot</groupId>
<artifactId>yshop-spring-boot-starter-desensitize</artifactId>
</dependency>
<!-- 消息队列相关 -->
<dependency>
<groupId>co.yixiang.boot</groupId>
@ -87,6 +92,7 @@
<artifactId>yshop-spring-boot-starter-biz-ip</artifactId>
</dependency>
<!-- 工具类相关 -->
</dependencies>

View File

@ -1,5 +1,6 @@
package co.yixiang.yshop.module.member.controller.admin.useraddress.vo;
import co.yixiang.yshop.framework.desensitize.core.slider.annotation.MobileDesensitize;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
@ -22,6 +23,7 @@ public class UserAddressBaseVO {
@NotNull(message = "收货人姓名不能为空")
private String realName;
@MobileDesensitize
@Schema(description = "收货人电话", required = true)
@NotNull(message = "收货人电话不能为空")
private String phone;

View File

@ -1,51 +0,0 @@
### 请求 /login 接口 => 成功
POST {{appApi}}/member/auth/login
Content-Type: application/json
tenant-id: {{appTenentId}}
{
"mobile": "15601691300",
"password": "admin123"
}
### 请求 /send-sms-code 接口 => 成功
POST {{appApi}}/member/auth/send-sms-code
Content-Type: application/json
tenant-id: {{appTenentId}}
{
"mobile": "15601691399",
"scene": 1
}
### 请求 /sms-login 接口 => 成功
POST {{appApi}}/member/auth/sms-login
Content-Type: application/json
tenant-id: {{appTenentId}}
{
"mobile": "15601691301",
"code": 9999
}
### 请求 /weixin-mini-app-login 接口 => 成功
POST {{appApi}}/member/auth/weixin-mini-app-login
Content-Type: application/json
tenant-id: {{appTenentId}}
{
"phoneCode": "618e6412e0c728f5b8fc7164497463d0158a923c9e7fd86af8bba393b9decbc5",
"loginCode": "001frTkl21JUf94VGxol2hSlff1frTkR"
}
### 请求 /logout 接口 => 成功
POST {{appApi}}/member/auth/logout
Content-Type: application/json
Authorization: Bearer c1b76bdaf2c146c581caa4d7fd81ee66
tenant-id: {{appTenentId}}
### 请求 /auth/refresh-token 接口 => 成功
POST {{appApi}}/member/auth/refresh-token?refreshToken=bc43d929094849a28b3a69f6e6940d70
Content-Type: application/json
tenant-id: {{appTenentId}}

View File

@ -14,9 +14,6 @@ public class YshopServerApplication {
public static void main(String[] args) {
SpringApplication.run(YshopServerApplication.class, args);
// new SpringApplicationBuilder(YshopServerApplication.class)
// .applicationStartup(new BufferingApplicationStartup(20480))
// .run(args);
}