From d624879f22c7efd5fd57f2f350e7a988949c2e24 Mon Sep 17 00:00:00 2001 From: js199000131 <2728757160@qq.com> Date: Sun, 14 May 2023 15:44:42 +0800 Subject: [PATCH] =?UTF-8?q?=E5=95=86=E5=93=81=E5=92=8C=E6=94=AF=E4=BB=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/common/enums/Constants.java | 9 + .../common/exception/ServiceException.java | 2 +- .../framework/common/util/date/DateUtils.java | 58 +- .../yudao-module-product-api/pom.xml | 10 + .../property/ProductPropertyValueApiImpl.java | 2 + .../property/ProductPropertyValueService.java | 8 + .../ProductPropertyValueServiceImpl.java | 6 + .../response/order/OrderDataResponse.java | 14 +- .../order/OrderPayResultResponse.java | 5 +- .../module/shop/vo/order/WxPayJsResultVo.java | 52 + .../app/order/StoreOrderController.java | 4 +- .../shop/convert/order/StoreOrderConvert.java | 17 + .../convert/order/StoreOrderOneConvert.java | 15 + .../dataobject/product/StoreProductReply.java | 2 +- .../dal/mysql/order/StoreOrderMapper.java | 3 +- .../shop/service/order/OrderService.java | 7 +- .../shop/service/order/OrderTaskService.java | 3 + .../order/impl/OrderPayServiceImpl.java | 272 +++- .../service/order/impl/OrderServiceImpl.java | 1225 ++++++++++++++++- .../order/impl/OrderTaskServiceImpl.java | 279 +++- .../order/impl/StoreOrderTaskServiceImpl.java | 2 +- .../service/product/StoreCartService.java | 2 +- .../product/impl/StoreCartServiceImpl.java | 2 +- .../product/impl/StoreProductServiceImpl.java | 6 +- .../yudao/module/shop/utils/OrderUtil.java | 53 + .../service/order/TradeOrderServiceTest.java | 2 +- .../yudao-module-member-api/pom.xml | 12 + .../module/member/api/address/AddressApi.java | 9 + .../api/address/dto/AddressRespDTO.java | 33 +- .../module/member/api/user/MemberUserApi.java | 12 + .../api/user/dto/MemberUserBillDTO.java | 98 ++ .../api/user/dto/MemberUserRespDTO.java | 3 + .../member/api/address/AddressApiImpl.java | 33 + .../member/api/user/MemberUserApiImpl.java | 62 + .../dal/dataobject/address/AddressDO.java | 7 + 35 files changed, 2269 insertions(+), 60 deletions(-) create mode 100644 yudao-module-mall/yudao-module-shop-api/src/main/java/cn/iocoder/yudao/module/shop/vo/order/WxPayJsResultVo.java create mode 100644 yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/convert/order/StoreOrderConvert.java create mode 100644 yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/convert/order/StoreOrderOneConvert.java create mode 100644 yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/MemberUserBillDTO.java diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/Constants.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/Constants.java index 1b71079ae..bc56ceb67 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/Constants.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/Constants.java @@ -563,4 +563,13 @@ public class Constants { /** 公共JS配置 */ // CRMEB chat 统计 public static final String JS_CONFIG_CRMEB_CHAT_TONGJI="crmeb_tongji_js"; + + + /** 退款理由 */ + public static final String CONFIG_KEY_STOR_REASON = "stor_reason"; + + /** 订单支付成功后Task */ + public static final String ORDER_TASK_PAY_SUCCESS_AFTER = "orderPaySuccessTask"; + /** 订单收货后Task */ + public static final String ORDER_TASK_REDIS_KEY_AFTER_TAKE_BY_USER = "alterOrderTakeByUser"; } diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/ServiceException.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/ServiceException.java index 02dc242a7..2bc598a66 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/ServiceException.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/ServiceException.java @@ -34,7 +34,7 @@ public final class ServiceException extends RuntimeException { this.message = errorCode.getMsg(); } public ServiceException( String message) { - this.code = GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(); +// this.code = GlobalErrorCodeants.INTERNAL_SERVER_ERROR.getCode(); this.message = message; } public ServiceException(Integer code, String message) { diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java index e7878f8b2..a6701c8c1 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java @@ -198,15 +198,7 @@ public class DateUtils { public static Date nowDateTime() { return strToDate(nowDateTimeStr(), Constants.DATE_FORMAT); } - /** - * 获取当前日期,指定格式 - * 描述:<描述函数实现的功能>. - * - * @return - */ - public static String nowDateTimeStr() { - return nowDate(Constants.DATE_FORMAT); - } + /** * 获取当前日期,指定格式 * 描述:<描述函数实现的功能>. @@ -218,6 +210,27 @@ public class DateUtils { return dft.format(new Date()); } + /** + * 获取当前日期,指定格式 + * 描述:<描述函数实现的功能>. + * + * @return + */ + public static String nowDateTimeStr() { + return nowDate(Constants.DATE_FORMAT); + } + + /** + * 获取当前日期,指定格式 + * 描述:<描述函数实现的功能>. + * + * @return + */ + public static Integer getNowTime() { + long t = (System.currentTimeMillis()/1000L); + return Integer.parseInt(String.valueOf(t)); + } + /** * 指定日期加上天数后的日期 * @@ -461,4 +474,31 @@ public class DateUtils { } return new DateLimitUtilVo(startTime, endTime); } + + /** + * compare two date String with a pattern + * + * @param date1 + * @param date2 + * @param pattern + * @return + */ + public static int compareDate(String date1, String date2, String pattern) { + SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(pattern); + try { + Date dt1 = DATE_FORMAT.parse(date1); + Date dt2 = DATE_FORMAT.parse(date2); + if (dt1.getTime() > dt2.getTime()) { + return 1; + } else if (dt1.getTime() < dt2.getTime()) { + return -1; + } else { + return 0; + } + + } catch (ParseException e) { + e.printStackTrace(); + return 0; + } + } } diff --git a/yudao-module-mall/yudao-module-product-api/pom.xml b/yudao-module-mall/yudao-module-product-api/pom.xml index 123e7c334..4b5c09e7d 100644 --- a/yudao-module-mall/yudao-module-product-api/pom.xml +++ b/yudao-module-mall/yudao-module-product-api/pom.xml @@ -29,6 +29,16 @@ spring-boot-starter-validation true + + com.baomidou + mybatis-plus-annotation + 3.5.3.1 + compile + + + cn.iocoder.boot + yudao-spring-boot-starter-biz-tenant + diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApiImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApiImpl.java index 9aab9e560..92ab023cd 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApiImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApiImpl.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.product.api.property; import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; import cn.iocoder.yudao.module.product.convert.propertyvalue.ProductPropertyValueConvert; import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -28,4 +29,5 @@ public class ProductPropertyValueApiImpl implements ProductPropertyValueApi { productPropertyValueService.getPropertyValueDetailList(ids)); } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueService.java index 553e2578d..b2fe9b06d 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueService.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.product.service.property; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO; import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO; import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO; @@ -87,4 +88,11 @@ public interface ProductPropertyValueService { */ void deletePropertyValueByPropertyId(Long propertyId); + /** + * 根据id、类型查询 + * @param id ID + * @param type 类型 + * @return StoreProductAttrValue + */ + ProductPropertyValueDetailRespDTO getByIdAndProductIdAndType(Integer id, Integer productId, Integer type); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java index 231b79b68..cdedf6aa8 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.product.service.property; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO; import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO; import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO; @@ -125,4 +126,9 @@ public class ProductPropertyValueServiceImpl implements ProductPropertyValueServ productPropertyValueMapper.deleteByPropertyId(propertyId); } + @Override + public ProductPropertyValueDetailRespDTO getByIdAndProductIdAndType(Integer id, Integer productId, Integer type) { + return null; + } + } diff --git a/yudao-module-mall/yudao-module-shop-api/src/main/java/cn/iocoder/yudao/module/shop/response/order/OrderDataResponse.java b/yudao-module-mall/yudao-module-shop-api/src/main/java/cn/iocoder/yudao/module/shop/response/order/OrderDataResponse.java index 65f4e2a31..f0dcb3516 100644 --- a/yudao-module-mall/yudao-module-shop-api/src/main/java/cn/iocoder/yudao/module/shop/response/order/OrderDataResponse.java +++ b/yudao-module-mall/yudao-module-shop-api/src/main/java/cn/iocoder/yudao/module/shop/response/order/OrderDataResponse.java @@ -29,29 +29,29 @@ public class OrderDataResponse implements Serializable { private static final long serialVersionUID = 1387727608277207652L; @Schema(description = "已完成订单数量") - private Integer completeCount; + private Long completeCount; @Schema(description = "待核销订单数量") - private Integer evaluatedCount; + private Long evaluatedCount; // @Schema(description = "用户昵称") // private Integer verificationCount; @Schema(description = "支付订单总数") - private Integer orderCount; + private Long orderCount; @Schema(description = "待收货订单数量") - private Integer receivedCount; + private Long receivedCount; @Schema(description = "退款订单数量") - private Integer refundCount; + private Long refundCount; @Schema(description = "总消费钱数") private BigDecimal sumPrice; @Schema(description = "未支付订单数量") - private Integer unPaidCount; + private Long unPaidCount; @Schema(description = "待发货订单数量") - private Integer unShippedCount; + private Long unShippedCount; } diff --git a/yudao-module-mall/yudao-module-shop-api/src/main/java/cn/iocoder/yudao/module/shop/response/order/OrderPayResultResponse.java b/yudao-module-mall/yudao-module-shop-api/src/main/java/cn/iocoder/yudao/module/shop/response/order/OrderPayResultResponse.java index 31831a849..8effdba9e 100644 --- a/yudao-module-mall/yudao-module-shop-api/src/main/java/cn/iocoder/yudao/module/shop/response/order/OrderPayResultResponse.java +++ b/yudao-module-mall/yudao-module-shop-api/src/main/java/cn/iocoder/yudao/module/shop/response/order/OrderPayResultResponse.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.shop.response.order; +import cn.iocoder.yudao.module.shop.vo.order.WxPayJsResultVo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @@ -28,8 +29,8 @@ public class OrderPayResultResponse { @Schema(description = "支付状态") private Boolean status; -// @Schema(description = "微信调起支付参数对象") -// private WxPayJsResultVo jsConfig; + @Schema(description = "微信调起支付参数对象") + private WxPayJsResultVo jsConfig; @Schema(description = "支付类型") private String payType; diff --git a/yudao-module-mall/yudao-module-shop-api/src/main/java/cn/iocoder/yudao/module/shop/vo/order/WxPayJsResultVo.java b/yudao-module-mall/yudao-module-shop-api/src/main/java/cn/iocoder/yudao/module/shop/vo/order/WxPayJsResultVo.java new file mode 100644 index 000000000..60b2a1793 --- /dev/null +++ b/yudao-module-mall/yudao-module-shop-api/src/main/java/cn/iocoder/yudao/module/shop/vo/order/WxPayJsResultVo.java @@ -0,0 +1,52 @@ +package cn.iocoder.yudao.module.shop.vo.order; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * 微信调起支付参数对象 + * +---------------------------------------------------------------------- + * | CRMEB [ CRMEB赋能开发者,助力企业发展 ] + * +---------------------------------------------------------------------- + * | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权 + * +---------------------------------------------------------------------- + * | Author: CRMEB Team + * +---------------------------------------------------------------------- + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@Schema(description="微信调起支付参数对象") +public class WxPayJsResultVo { + + @Schema(description = "微信分配的小程序ID", required = true) + private String appId; + + @Schema(description = "随机字符串,不长于32位", required = true) + private String nonceStr; + + @Schema(description = "统一下单接口返回的 prepay_id 参数值", required = true) + private String packages; + + @Schema(description = "签名类型,默认为MD5,支持HMAC-SHA256和MD5。", required = true) + private String signType; + + @Schema(description = "时间戳从1970年1月1日00:00:00至今的秒数,即当前的时间", required = true) + private String timeStamp; + + @Schema(description = "支付签名", required = true) + private String paySign; + + @Schema(description = "H5支付跳转链接", required = true) + private String mwebUrl; + + @Schema(description = "微信商户号", required = true) + private String partnerid; + + @Schema(description = "拉起收银台的ticket", required = true) + private String ticket; +} diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/app/order/StoreOrderController.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/app/order/StoreOrderController.java index f2ad77e5c..c1f9087bb 100644 --- a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/app/order/StoreOrderController.java +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/app/order/StoreOrderController.java @@ -110,8 +110,8 @@ public class StoreOrderController { */ @Operation(summary = "订单头部数量") @RequestMapping(value = "/data", method = RequestMethod.GET) - public CommonResult orderData() { - return CommonResult.success(orderService.orderData()); + public CommonResult orderData(String dateLimit, Integer type,String payType) { + return CommonResult.success(orderService.orderData(dateLimit, type,payType)); } /** diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/convert/order/StoreOrderConvert.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/convert/order/StoreOrderConvert.java new file mode 100644 index 000000000..7b7f4fa7a --- /dev/null +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/convert/order/StoreOrderConvert.java @@ -0,0 +1,17 @@ +package cn.iocoder.yudao.module.shop.convert.order; + +import cn.iocoder.yudao.module.shop.dal.dataobject.order.StoreOrder; +import cn.iocoder.yudao.module.shop.response.order.OrderDetailResponse; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface StoreOrderConvert { + + StoreOrderConvert INSTANCE = Mappers.getMapper(StoreOrderConvert.class); + + List convert(List list); + +} diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/convert/order/StoreOrderOneConvert.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/convert/order/StoreOrderOneConvert.java new file mode 100644 index 000000000..2268697e8 --- /dev/null +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/convert/order/StoreOrderOneConvert.java @@ -0,0 +1,15 @@ +package cn.iocoder.yudao.module.shop.convert.order; + +import cn.iocoder.yudao.module.shop.dal.dataobject.order.StoreOrder; +import cn.iocoder.yudao.module.shop.response.order.StoreOrderDetailInfoResponse; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface StoreOrderOneConvert { + + StoreOrderOneConvert INSTANCE = Mappers.getMapper(StoreOrderOneConvert.class); + + StoreOrderDetailInfoResponse convert(StoreOrder storeOrder); + +} diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/dal/dataobject/product/StoreProductReply.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/dal/dataobject/product/StoreProductReply.java index 931feb20d..73b6942f6 100644 --- a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/dal/dataobject/product/StoreProductReply.java +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/dal/dataobject/product/StoreProductReply.java @@ -38,7 +38,7 @@ public class StoreProductReply implements Serializable { private Integer id; @Schema(description= "用户ID") - private Integer uid; + private Long uid; @Schema(description= "订单ID") private Integer oid; diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/dal/mysql/order/StoreOrderMapper.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/dal/mysql/order/StoreOrderMapper.java index 3a13aa660..ee135c8dd 100644 --- a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/dal/mysql/order/StoreOrderMapper.java +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/dal/mysql/order/StoreOrderMapper.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.shop.dal.mysql.order; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.module.shop.dal.dataobject.order.StoreOrder; import cn.iocoder.yudao.module.shop.request.order.StoreOrderStaticsticsRequest; import cn.iocoder.yudao.module.shop.response.order.OrderBrokerageData; @@ -26,7 +27,7 @@ import java.util.List; * +---------------------------------------------------------------------- */ @Mapper -public interface StoreOrderMapper extends BaseMapper { +public interface StoreOrderMapper extends BaseMapperX { /** * 订单总金额 diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/order/OrderService.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/order/OrderService.java index 348f0b0ad..7a6ea875e 100644 --- a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/order/OrderService.java +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/order/OrderService.java @@ -2,6 +2,9 @@ package cn.iocoder.yudao.module.shop.service.order; import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.shop.controller.admin.order.vo.StoreOrderPageQueryReqVo; +import cn.iocoder.yudao.module.shop.dal.dataobject.order.StoreOrder; import cn.iocoder.yudao.module.shop.request.order.*; import cn.iocoder.yudao.module.shop.request.product.StoreProductReplyAddRequest; import cn.iocoder.yudao.module.shop.response.order.*; @@ -26,8 +29,6 @@ public interface OrderService { /** * 订单列表 - * @param type 类型 - * @param pageRequest 分页 * @return 订单集合 */ PageInfo list(Integer type, PageParam pageRequest); @@ -42,7 +43,7 @@ public interface OrderService { * 订单状态数量 * @return 订单状态数据量 */ - OrderDataResponse orderData(); + OrderDataResponse orderData(String dateLimit, Integer type,String payType); /** * 查询退款理由 diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/order/OrderTaskService.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/order/OrderTaskService.java index a64f274d1..38dcda29d 100644 --- a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/order/OrderTaskService.java +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/order/OrderTaskService.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.shop.service.order; +import org.springframework.stereotype.Service; + /** * 订单任务服务 StoreOrderService 接口 * +---------------------------------------------------------------------- @@ -13,6 +15,7 @@ package cn.iocoder.yudao.module.shop.service.order; * | Author: CRMEB Team * +---------------------------------------------------------------------- */ +@Service public interface OrderTaskService{ void cancelByUser(); diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/order/impl/OrderPayServiceImpl.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/order/impl/OrderPayServiceImpl.java index c916b8213..57571ca00 100644 --- a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/order/impl/OrderPayServiceImpl.java +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/order/impl/OrderPayServiceImpl.java @@ -1,13 +1,38 @@ package cn.iocoder.yudao.module.shop.service.order.impl; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.common.enums.Constants; +import cn.iocoder.yudao.framework.common.exception.ServiceException; +import cn.iocoder.yudao.framework.common.util.date.DateUtils; +import cn.iocoder.yudao.module.infra.api.config.ApiConfigApi; +import cn.iocoder.yudao.module.member.api.user.MemberUserApi; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserBillDTO; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.shop.constants.PayConstants; import cn.iocoder.yudao.module.shop.dal.dataobject.order.StoreOrder; import cn.iocoder.yudao.module.shop.request.order.OrderPayRequest; import cn.iocoder.yudao.module.shop.response.order.OrderPayResultResponse; import cn.iocoder.yudao.module.shop.service.order.OrderPayService; +import cn.iocoder.yudao.module.shop.service.order.StoreOrderInfoService; +import cn.iocoder.yudao.module.shop.service.order.StoreOrderService; +import cn.iocoder.yudao.module.shop.service.order.StoreOrderStatusService; +import cn.iocoder.yudao.module.shop.service.product.StoreProductAttrValueService; +import cn.iocoder.yudao.module.shop.service.product.StoreProductService; +import cn.iocoder.yudao.module.shop.utils.OrderUtil; +import cn.iocoder.yudao.module.shop.utils.RedisUtil; +import cn.iocoder.yudao.module.shop.vo.order.WxPayJsResultVo; import lombok.Data; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.support.TransactionTemplate; + +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** @@ -27,6 +52,41 @@ import org.springframework.stereotype.Service; public class OrderPayServiceImpl implements OrderPayService { private static final Logger logger = LoggerFactory.getLogger(OrderPayServiceImpl.class); + @Autowired + private StoreOrderService storeOrderService; + + @Autowired + private StoreOrderStatusService storeOrderStatusService; + + @Autowired + private StoreOrderInfoService storeOrderInfoService; + + @Autowired + private MemberUserApi userService; + + @Autowired + private OrderUtil orderUtil; + + //订单类 + private StoreOrder order; + + @Autowired + private TransactionTemplate transactionTemplate; + + @Autowired + private RedisUtil redisUtil; + + @Autowired + private StoreProductService storeProductService; + + + @Autowired + private StoreProductAttrValueService storeProductAttrValueService; + + @Autowired + private ApiConfigApi apiConfigApi; + + /** * 支付成功处理 * @@ -34,7 +94,67 @@ public class OrderPayServiceImpl implements OrderPayService { */ @Override public Boolean paySuccess(StoreOrder storeOrder) { - return null; + + MemberUserRespDTO user = userService.getUser(storeOrder.getUid()); + + List billList = CollUtil.newArrayList(); + + // 订单支付记录 +// MemberUserBillDTO userBill = userBillInit(storeOrder, user); +// billList.add(userBill); + + // 更新用户下单数量 + // user.setPayCount(user.getPayCount() + 1); + + + Boolean execute = transactionTemplate.execute(e -> { + //订单日志 + storeOrderStatusService.createLog(storeOrder.getId(), Constants.ORDER_LOG_PAY_SUCCESS, Constants.ORDER_LOG_MESSAGE_PAY_SUCCESS); + + // 用户信息变更 + userService.updateById(user); + + return Boolean.TRUE; + }); + + if (execute) { + try { + // 发送短信 + + // 发送用户支付成功管理员提醒短信 + + // 根据配置 打印小票 + + } catch (Exception e) { + e.printStackTrace(); + logger.error("短信、模板通知、优惠券或打印小票异常"); + } + } + return execute; + } + + /** + * 余额支付 + * @param storeOrder 订单 + * @return Boolean Boolean + */ + private Boolean yuePay(StoreOrder storeOrder) { + + // 用户余额扣除 + MemberUserRespDTO user = userService.getUser(storeOrder.getUid()); + if (ObjectUtil.isNull(user)) throw new ServiceException("用户不存在"); + storeOrder.setPaid(true); + storeOrder.setPayTime(DateUtils.nowDateTime()); + Boolean execute = transactionTemplate.execute(e -> { + // 订单修改 + storeOrderService.updateById(storeOrder); + // 这里只扣除金额,账单记录在task中处理 + // 添加支付成功redis队列 + redisUtil.lPush(Constants.ORDER_TASK_PAY_SUCCESS_AFTER, storeOrder.getOrderId()); + return Boolean.TRUE; + }); + if (!execute) throw new ServiceException("余额支付订单失败"); + return execute; } /** @@ -46,6 +166,154 @@ public class OrderPayServiceImpl implements OrderPayService { */ @Override public OrderPayResultResponse payment(OrderPayRequest orderPayRequest, String ip) { - return null; + StoreOrder storeOrder = storeOrderService.getByOderId(orderPayRequest.getOrderNo()); + if (ObjectUtil.isNull(storeOrder)) { + throw new ServiceException("订单不存在"); + } + if (storeOrder.getIsDel()) { + throw new ServiceException("订单已被删除"); + } + if (storeOrder.getPaid()) { + throw new ServiceException("订单已支付"); + } + MemberUserRespDTO user = userService.getUser(storeOrder.getUid()); + if (ObjectUtil.isNull(user)) throw new ServiceException("用户不存在"); + + // 判断订单是否还是之前的支付类型 + if (!storeOrder.getPayType().equals(orderPayRequest.getPayType())) { + // 根据支付类型进行校验,更换支付类型 + storeOrder.setPayType(orderPayRequest.getPayType()); + // 余额支付 + if (orderPayRequest.getPayType().equals(PayConstants.PAY_TYPE_YUE)) { +// if (user.getNowMoney().compareTo(storeOrder.getPayPrice()) < 0) { +// throw new ServiceException("用户余额不足"); +// } + storeOrder.setIsChannel(3); + } + if (orderPayRequest.getPayType().equals(PayConstants.PAY_TYPE_WE_CHAT)) { + switch (orderPayRequest.getPayChannel()){ + case PayConstants.PAY_CHANNEL_WE_CHAT_H5:// H5 + storeOrder.setIsChannel(2); + break; + case PayConstants.PAY_CHANNEL_WE_CHAT_PUBLIC:// 公众号 + storeOrder.setIsChannel(0); + break; + case PayConstants.PAY_CHANNEL_WE_CHAT_PROGRAM:// 小程序 + storeOrder.setIsChannel(1); + break; + } + } + + boolean changePayType = storeOrderService.updateById(storeOrder); + if (!changePayType) { + throw new ServiceException("变更订单支付类型失败!"); + } + } + + // +// if (user.getIntegral() < storeOrder.getUseIntegral()) { +// throw new ServiceException("用户积分不足"); +// } + + OrderPayResultResponse response = new OrderPayResultResponse(); + response.setOrderNo(storeOrder.getOrderId()); + response.setPayType(storeOrder.getPayType()); + // 0元付 + if (storeOrder.getPayPrice().compareTo(BigDecimal.ZERO) <= 0) { + Boolean aBoolean = yuePay(storeOrder); + response.setPayType(PayConstants.PAY_TYPE_YUE); + response.setStatus(aBoolean); + return response; + } + + // 微信支付,调用微信预下单,返回拉起微信支付需要的信息 + if (storeOrder.getPayType().equals(PayConstants.PAY_TYPE_WE_CHAT)) { + // 预下单 + Map unifiedorder = unifiedorder(storeOrder, ip); + response.setStatus(true); + WxPayJsResultVo vo = new WxPayJsResultVo(); + vo.setAppId(unifiedorder.get("appId")); + vo.setNonceStr(unifiedorder.get("nonceStr")); + vo.setPackages(unifiedorder.get("package")); + vo.setSignType(unifiedorder.get("signType")); + vo.setTimeStamp(unifiedorder.get("timeStamp")); + vo.setPaySign(unifiedorder.get("paySign")); + if (storeOrder.getIsChannel() == 2) { + vo.setMwebUrl(unifiedorder.get("mweb_url")); + response.setPayType(PayConstants.PAY_CHANNEL_WE_CHAT_H5); + } + if (storeOrder.getIsChannel() == 4 || storeOrder.getIsChannel() == 5) { + vo.setPartnerid(unifiedorder.get("partnerid")); + } + // 更新商户订单号 + storeOrder.setOutTradeNo(unifiedorder.get("outTradeNo")); + storeOrderService.updateById(storeOrder); + response.setJsConfig(vo); + return response; + } + // 余额支付 + if (storeOrder.getPayType().equals(PayConstants.PAY_TYPE_YUE)) { + Boolean yueBoolean = yuePay(storeOrder); + response.setStatus(yueBoolean); + return response; + } + if (storeOrder.getPayType().equals(PayConstants.PAY_TYPE_OFFLINE)) { + throw new ServiceException("暂时不支持线下支付"); + } + response.setStatus(false); + return response; + } + + /** + * 预下单 + * @param storeOrder 订单 + * @param ip ip + * @return 预下单返回对象 + */ + private Map unifiedorder(StoreOrder storeOrder, String ip) { + // 获取用户openId + // 根据订单支付类型来判断获取公众号openId还是小程序openId + + // 获取appid、mch_id + // 微信签名key + String appId = ""; + String mchId = ""; + String signKey = ""; + if (storeOrder.getIsChannel() == 0) {// 公众号 + appId = apiConfigApi.getConfigKey(Constants.CONFIG_KEY_PAY_WE_CHAT_APP_ID).toString(); + mchId = apiConfigApi.getConfigKey(Constants.CONFIG_KEY_PAY_WE_CHAT_MCH_ID).toString(); + signKey = apiConfigApi.getConfigKey(Constants.CONFIG_KEY_PAY_WE_CHAT_APP_KEY).toString(); + } + if (storeOrder.getIsChannel() == 1) {// 小程序 + appId = apiConfigApi.getConfigKey(Constants.CONFIG_KEY_PAY_ROUTINE_APP_ID).toString(); + mchId = apiConfigApi.getConfigKey(Constants.CONFIG_KEY_PAY_ROUTINE_MCH_ID).toString(); + signKey = apiConfigApi.getConfigKey(Constants.CONFIG_KEY_PAY_ROUTINE_APP_KEY).toString(); + } + if (storeOrder.getIsChannel() == 2) {// H5,使用公众号的 + appId = apiConfigApi.getConfigKey(Constants.CONFIG_KEY_PAY_WE_CHAT_APP_ID).toString(); + mchId = apiConfigApi.getConfigKey(Constants.CONFIG_KEY_PAY_WE_CHAT_MCH_ID).toString(); + signKey = apiConfigApi.getConfigKey(Constants.CONFIG_KEY_PAY_WE_CHAT_APP_KEY).toString(); + } + // 获取微信预下单对象 + //CreateOrderRequestVo unifiedorderVo = getUnifiedorderVo(storeOrder, userToken.getToken(), ip, appId, mchId, signKey); + // 预下单(统一下单) + //CreateOrderResponseVo responseVo = wechatNewService.payUnifiedorder(unifiedorderVo); + // 组装前端预下单参数 + Map map = new HashMap<>(); +// map.put("appId", unifiedorderVo.getAppid()); +// map.put("nonceStr", unifiedorderVo.getAppid()); +// map.put("package", "prepay_id=".concat(responseVo.getPrepayId())); +// map.put("signType", unifiedorderVo.getSign_type()); +// Long currentTimestamp = WxPayUtil.getCurrentTimestamp(); +// map.put("timeStamp", Long.toString(currentTimestamp)); +// String paySign = WxPayUtil.getSign(map, signKey); +// map.put("paySign", paySign); +// map.put("prepayId", responseVo.getPrepayId()); +// map.put("prepayTime", DateUtil.nowDateTimeStr()); +// map.put("outTradeNo", unifiedorderVo.getOut_trade_no()); +// if (storeOrder.getIsChannel() == 2) { +// map.put("mweb_url", responseVo.getMWebUrl()); +// } + return map; } } diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/order/impl/OrderServiceImpl.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/order/impl/OrderServiceImpl.java index 377d7cf83..757e928ed 100644 --- a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/order/impl/OrderServiceImpl.java +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/order/impl/OrderServiceImpl.java @@ -1,17 +1,73 @@ package cn.iocoder.yudao.module.shop.service.order.impl; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; +import cn.iocoder.yudao.module.member.api.address.AddressApi; +import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; +import cn.iocoder.yudao.module.member.api.user.MemberUserApi; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.product.api.express.ShippingTemplatesApi; +import cn.iocoder.yudao.module.product.api.express.ShippingTemplatesFreeApi; +import cn.iocoder.yudao.module.product.api.express.ShippingTemplatesRegionApi; +import cn.iocoder.yudao.module.product.api.express.dto.ShippingTemplatesDO; +import cn.iocoder.yudao.module.product.api.express.dto.ShippingTemplatesFreeDO; +import cn.iocoder.yudao.module.product.api.express.dto.ShippingTemplatesRegionDO; +import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi; +import cn.iocoder.yudao.module.shop.constants.PayConstants; +import cn.iocoder.yudao.framework.common.enums.Constants; +import cn.iocoder.yudao.framework.common.exception.ServiceException; +import cn.iocoder.yudao.framework.common.pojo.DateLimitUtilVo; import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.module.infra.api.config.ApiConfigApi; +import cn.iocoder.yudao.module.shop.constants.SysConfigConstants; +import cn.iocoder.yudao.module.shop.convert.order.StoreOrderConvert; +import cn.iocoder.yudao.module.shop.convert.order.StoreOrderOneConvert; +import cn.iocoder.yudao.module.shop.dal.dataobject.cat.StoreCart; +import cn.iocoder.yudao.module.shop.dal.dataobject.order.StoreOrder; +import cn.iocoder.yudao.module.shop.dal.dataobject.order.StoreOrderInfo; +import cn.iocoder.yudao.module.shop.dal.dataobject.product.StoreProduct; +import cn.iocoder.yudao.module.shop.dal.dataobject.product.StoreProductAttrValue; +import cn.iocoder.yudao.module.shop.dal.mysql.order.StoreOrderMapper; import cn.iocoder.yudao.module.shop.request.order.*; import cn.iocoder.yudao.module.shop.request.product.StoreProductReplyAddRequest; -import cn.iocoder.yudao.module.shop.service.order.OrderService; import cn.iocoder.yudao.module.shop.response.order.*; +import cn.iocoder.yudao.module.shop.service.order.OrderService; +import cn.iocoder.yudao.module.shop.service.order.StoreOrderInfoService; +import cn.iocoder.yudao.module.shop.service.order.StoreOrderService; +import cn.iocoder.yudao.module.shop.service.order.StoreOrderStatusService; +import cn.iocoder.yudao.module.shop.service.product.StoreCartService; +import cn.iocoder.yudao.module.shop.service.product.StoreProductAttrValueService; +import cn.iocoder.yudao.module.shop.service.product.StoreProductReplyService; +import cn.iocoder.yudao.module.shop.service.product.StoreProductService; +import cn.iocoder.yudao.module.shop.utils.CrmebUtil; +import cn.iocoder.yudao.module.shop.utils.OrderUtil; +import cn.iocoder.yudao.module.shop.utils.RedisUtil; +import cn.iocoder.yudao.module.shop.vo.order.*; import cn.iocoder.yudao.module.shop.vo.product.MyRecord; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; +import org.apache.commons.lang3.StringEscapeUtils; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.annotation.OrderUtils; import org.springframework.stereotype.Service; +import org.springframework.transaction.support.TransactionTemplate; +import cn.iocoder.yudao.framework.common.util.date.DateUtils; +import javax.annotation.Resource; +import java.math.BigDecimal; import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; /** * H5端订单操作 @@ -30,6 +86,59 @@ public class OrderServiceImpl implements OrderService { private final Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class); + @Autowired + private OrderUtil orderUtil; + + @Resource + private StoreOrderMapper dao; + + @Autowired + private StoreOrderService storeOrderService; + + @Autowired + private StoreProductReplyService storeProductReplyService; + + @Autowired + private RedisUtil redisUtil; + + @Autowired + private ApiConfigApi apiConfigApi; + + @Autowired + private StoreOrderStatusService storeOrderStatusService; + + @Autowired + private StoreOrderInfoService storeOrderInfoService; + + @Autowired + private TransactionTemplate transactionTemplate; + + @Autowired + private MemberUserApi memberUserApi; + + @Autowired + private AddressApi addressApi; + + @Autowired + private GetProductReply getProductReply; + + @Autowired + private ShippingTemplatesApi shippingTemplatesApi; + + @Autowired + private ShippingTemplatesFreeApi shippingTemplatesFreeApi; + + @Autowired + private ShippingTemplatesRegionApi shippingTemplatesRegionApi; + + @Autowired + private StoreProductService storeProductService; + + @Autowired + private StoreCartService storeCartService; + + @Autowired + private StoreProductAttrValueService storeProductAttrValueService; /** * 订单列表 * @@ -39,7 +148,14 @@ public class OrderServiceImpl implements OrderService { */ @Override public PageInfo list(Integer type, PageParam pageRequest) { - return null; + PageHelper.startPage(pageRequest.getPageNo(), pageRequest.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + if(null != type){ + lambdaQueryWrapper.eq(StoreOrder::getType, type); + } + lambdaQueryWrapper.orderByDesc(StoreOrder::getId); + List storeOrders = dao.selectList(lambdaQueryWrapper); + return new PageInfo<>(StoreOrderConvert.INSTANCE.convert(storeOrders)); } /** @@ -49,7 +165,123 @@ public class OrderServiceImpl implements OrderService { */ @Override public StoreOrderDetailInfoResponse detailOrder(String orderId) { - return null; + StoreOrder storeOrder = storeOrderService.getByOderId(orderId); + return StoreOrderOneConvert.INSTANCE.convert(storeOrder); + } + + /** + * 获取订单总数 + * @param dateLimit 时间端 + * @param status String 状态 + * @return Integer + */ + private Long getCount(String dateLimit, String status, Integer type) { + //总数只计算时间 + QueryWrapper queryWrapper = new QueryWrapper<>(); + if (StrUtil.isNotBlank(dateLimit)) { + DateLimitUtilVo dateLimitUtilVo = DateUtils.getDateLimit(dateLimit); + queryWrapper.between("create_time", dateLimitUtilVo.getStartTime(), dateLimitUtilVo.getEndTime()); + } + getStatusWhereNew(queryWrapper, status); + if (ObjectUtil.isNotNull(type)) { + queryWrapper.eq("type", type); + } + return dao.selectCount(queryWrapper); + } + + /** + * 获取订单金额 + * @param dateLimit 时间端 + * @param type 支付类型 + * @return BigDecimal + */ + private BigDecimal getAmount(String dateLimit, String type) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.select("sum(pay_price) as pay_price"); + if (StringUtils.isNotBlank(type)) { + queryWrapper.eq("pay_type", type); + } + queryWrapper.isNotNull("pay_time"); + queryWrapper.eq("paid", 1); + if (StringUtils.isNotBlank(dateLimit)) { + DateLimitUtilVo dateLimitUtilVo = DateUtils.getDateLimit(dateLimit); + queryWrapper.between("create_time", dateLimitUtilVo.getStartTime(), dateLimitUtilVo.getEndTime()); + } + StoreOrder storeOrder = dao.selectOne(queryWrapper); + if (ObjectUtil.isNull(storeOrder)) { + return BigDecimal.ZERO; + } + return storeOrder.getPayPrice(); + } + + /** + * 根据订单状态获取where条件 + * @param queryWrapper QueryWrapper 表达式 + * @param status String 类型 + */ + private void getStatusWhereNew(QueryWrapper queryWrapper, String status) { + if (StrUtil.isBlank(status)) { + return; + } + switch (status) { + case Constants.ORDER_STATUS_ALL: //全部 + break; + case Constants.ORDER_STATUS_UNPAID: //未支付 + queryWrapper.eq("paid", 0);//支付状态 + queryWrapper.eq("status", 0); //订单状态 + queryWrapper.eq("is_del", 0);//删除状态 + break; + case Constants.ORDER_STATUS_NOT_SHIPPED: //未发货 + queryWrapper.eq("paid", 1); + queryWrapper.eq("status", 0); + queryWrapper.eq("refund_status", 0); + queryWrapper.eq("shipping_type", 1);//配送方式 + queryWrapper.eq("is_del", 0); + break; + case Constants.ORDER_STATUS_SPIKE: //待收货 + queryWrapper.eq("paid", 1); + queryWrapper.eq("status", 1); + queryWrapper.eq("refund_status", 0); + queryWrapper.eq("is_del", 0); + break; + case Constants.ORDER_STATUS_BARGAIN: //待评价 + queryWrapper.eq("paid", 1); + queryWrapper.eq("status", 2); + queryWrapper.eq("refund_status", 0); + queryWrapper.eq("is_del", 0); + break; + case Constants.ORDER_STATUS_COMPLETE: //交易完成 + queryWrapper.eq("paid", 1); + queryWrapper.eq("status", 3); + queryWrapper.eq("refund_status", 0); + queryWrapper.eq("is_del", 0); + break; + case Constants.ORDER_STATUS_TOBE_WRITTEN_OFF: //待核销 + queryWrapper.eq("paid", 1); + queryWrapper.eq("status", 0); + queryWrapper.eq("refund_status", 0); + queryWrapper.eq("shipping_type", 2);//配送方式 + queryWrapper.eq("is_del", 0); + break; + case Constants.ORDER_STATUS_REFUNDING: //退款中 + queryWrapper.eq("paid", 1); + queryWrapper.in("refund_status", 1,3); + queryWrapper.eq("is_del", 0); + break; + case Constants.ORDER_STATUS_REFUNDED: //已退款 + queryWrapper.eq("paid", 1); + queryWrapper.eq("refund_status", 2); + queryWrapper.eq("is_del", 0); + break; + case Constants.ORDER_STATUS_DELETED: //已删除 + queryWrapper.eq("is_del", 1); + break; + default: + queryWrapper.eq("paid", 1); + queryWrapper.ne("refund_status", 2); + break; + } + queryWrapper.eq("is_system_del", 0); } /** @@ -58,8 +290,28 @@ public class OrderServiceImpl implements OrderService { * @return 订单状态数据量 */ @Override - public OrderDataResponse orderData() { - return null; + public OrderDataResponse orderData(String dateLimit, Integer type,String payType) { + OrderDataResponse response = new OrderDataResponse(); + if (type.equals(2)) { + type = null; + } + // 已完成订单数量 + response.setCompleteCount(getCount(dateLimit, Constants.ORDER_STATUS_COMPLETE, type)); + // 待核销订单数量 + response.setEvaluatedCount(getCount(dateLimit, Constants.ORDER_STATUS_STR_TOBE_WRITTEN_OFF, type)); + // 支付订单总数 + response.setOrderCount(getCount(dateLimit, Constants.ORDER_STATUS_ALL, type)); + // 待收货订单数量 + response.setReceivedCount(getCount(dateLimit, Constants.ORDER_STATUS_SPIKE, type)); + // 退款订单数量 + response.setRefundCount(getCount(dateLimit, Constants.ORDER_STATUS_REFUNDED, type)); + // 总消费钱数 + response.setSumPrice(getAmount(dateLimit,payType)); + // 未支付订单数量 + response.setUnPaidCount(getCount(dateLimit, Constants.ORDER_STATUS_UNPAID, type)); + // 待发货订单数量 + response.setUnShippedCount(getCount(dateLimit, Constants.ORDER_STATUS_NOT_SHIPPED, type)); + return response; } /** @@ -69,9 +321,26 @@ public class OrderServiceImpl implements OrderService { */ @Override public List getRefundReason() { - return null; + String reasonString = apiConfigApi.getConfigKey(Constants.CONFIG_KEY_STOR_REASON).toString(); + reasonString = CrmebUtil.UnicodeToCN(reasonString); + reasonString = reasonString.replace("rn", "n"); + return Arrays.asList(reasonString.split("\\n")); } + /** + * 查询单条订单 + *@param orderNo 订单编号 + * @return 退款理由集合 + */ + private StoreOrder getInfoException(Integer orderNo) { + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(StoreOrder::getOrderId, orderNo); + StoreOrder storeOrder = dao.selectOne(lqw); + if (ObjectUtil.isNull(storeOrder)) { + throw new ServiceException("没有找到订单信息"); + } + return storeOrder; + } /** * 订单删除 * @@ -80,7 +349,15 @@ public class OrderServiceImpl implements OrderService { */ @Override public Boolean delete(Integer id) { - return null; + StoreOrder storeOrder = getInfoException(id); + if (!storeOrder.getIsDel()) { + throw new ServiceException("您选择的的订单存在用户未删除的订单,无法删除用户未删除的订单!"); + } + if (storeOrder.getIsSystemDel()) { + throw new ServiceException("此订单已经被删除了!"); + } + storeOrder.setIsSystemDel(true); + return storeOrderService.updateById(storeOrder); } /** @@ -91,7 +368,10 @@ public class OrderServiceImpl implements OrderService { */ @Override public Boolean reply(StoreProductReplyAddRequest request) { - return null; + if (StrUtil.isBlank(request.getOrderNo())) { + throw new ServiceException("订单号参数不能为空"); + } + return storeProductReplyService.create(request); } /** @@ -102,7 +382,18 @@ public class OrderServiceImpl implements OrderService { */ @Override public Boolean take(Integer id) { - return null; + StoreOrder storeOrder = orderUtil.getInfoById(id); + if (!storeOrder.getStatus().equals(Constants.ORDER_STATUS_INT_SPIKE)) { + throw new ServiceException("订单状态错误"); + } + //已收货,待评价 + storeOrder.setStatus(Constants.ORDER_STATUS_INT_BARGAIN); + boolean result = storeOrderService.updateById(storeOrder); + if (result) { + //后续操作放入redis + redisUtil.lPush(Constants.ORDER_TASK_REDIS_KEY_AFTER_TAKE_BY_USER, id); + } + return result; } /** @@ -113,7 +404,15 @@ public class OrderServiceImpl implements OrderService { */ @Override public Boolean cancel(Integer id) { - return null; + StoreOrder storeOrder = orderUtil.getInfoById(id); + //已收货,待评价 + storeOrder.setIsDel(true); + storeOrder.setIsSystemDel(true); + boolean result = storeOrderService.updateById(storeOrder); + + //后续操作放入redis + redisUtil.lPush(Constants.ORDER_TASK_REDIS_KEY_AFTER_CANCEL_BY_USER, id); + return result; } /** @@ -124,7 +423,41 @@ public class OrderServiceImpl implements OrderService { */ @Override public Boolean refundApply(OrderRefundApplyRequest request) { - return null; + StoreOrder storeOrderPram = new StoreOrder(); + storeOrderPram.setOrderId(request.getUni()); + storeOrderPram.setIsDel(false); + storeOrderPram.setPaid(true); + StoreOrder existStoreOrder = storeOrderService.getByEntityOne(storeOrderPram); + if (null == existStoreOrder) throw new ServiceException("支付订单不存在"); + if (existStoreOrder.getRefundStatus() == 1) { + throw new ServiceException("正在申请退款中"); + } + + if (existStoreOrder.getRefundStatus() == 2) { + throw new ServiceException("订单已退款"); + } + + if (existStoreOrder.getRefundStatus() == 3) { + throw new ServiceException("订单退款中"); + } + + existStoreOrder.setRefundStatus(1); + existStoreOrder.setRefundReasonTime(DateUtils.nowDateTime()); + existStoreOrder.setRefundReasonWap(request.getText()); + existStoreOrder.setRefundReasonWapExplain(request.getExplain()); + existStoreOrder.setRefundReasonWapImg(request.getReasonImage()); + existStoreOrder.setRefundPrice(BigDecimal.ZERO); + + Boolean execute = transactionTemplate.execute(e -> { + storeOrderService.updateById(existStoreOrder); + storeOrderStatusService.createLog(existStoreOrder.getId(), Constants.ORDER_LOG_REFUND_APPLY, "用户申请退款原因:" + request.getText()); + return Boolean.TRUE; + }); + + //TODO 发送用户退款管理员提醒短信 + + if (!execute) throw new ServiceException("申请退款失败"); + return execute; } /** @@ -135,7 +468,45 @@ public class OrderServiceImpl implements OrderService { */ @Override public Boolean refundApplyTask(List applyList) { - return null; + if (CollUtil.isEmpty(applyList)) { + return false; + } + List orderList = CollUtil.newArrayList(); + for (OrderRefundApplyRequest request : applyList) { + StoreOrder storeOrder = storeOrderService.getById(request.getId()); + if (ObjectUtil.isNull(storeOrder)) { + //订单号错误 + logger.error("拼团自动处理订单申请退款:没有找到相关订单信息!"); + continue; + } + if (storeOrder.getRefundStatus() == 1) { + logger.error("拼团自动处理订单申请退款:正在申请退款中!"); + continue; + } + + if (storeOrder.getRefundStatus() == 2) { + logger.error("拼团自动处理订单申请退款:订单已退款!"); + continue; + } + + if (storeOrder.getRefundStatus() == 3) { + logger.error("拼团自动处理订单申请退款:订单退款中!"); + continue; + } + + storeOrder.setRefundReasonWapImg(request.getReasonImage()); + storeOrder.setRefundStatus(1); + storeOrder.setRefundReasonWapExplain(request.getExplain()); + storeOrder.setRefundReason(request.getText()); + storeOrder.setRefundPrice(BigDecimal.ZERO); + storeOrder.setRefundReasonTime(DateUtils.nowDateTime()); + orderList.add(storeOrder); + + // 发送用户退款管理员提醒短信 + + } + + return storeOrderService.updateBatchById(orderList, 100); } /** @@ -145,7 +516,38 @@ public class OrderServiceImpl implements OrderService { */ @Override public Object expressOrder(String orderId) { - return null; + HashMap resultMap = new HashMap<>(); + StoreOrder storeOrderPram = new StoreOrder(); + storeOrderPram.setOrderId(orderId); + StoreOrder existOrder = storeOrderService.getByEntityOne(storeOrderPram); + if (ObjectUtil.isNull(existOrder)) throw new ServiceException("未找到该订单信息"); + if (!existOrder.getDeliveryType().equals(Constants.ORDER_LOG_EXPRESS) || StringUtils.isBlank(existOrder.getDeliveryType())) + throw new ServiceException("该订单不存在快递订单号"); + + //TODO 视频订单 + + //TODO 快递 + //LogisticsResultVo expressInfo = logisticsService.info(existOrder.getDeliveryId(), null, Optional.ofNullable(existOrder.getDeliveryCode()).orElse(""), storeOrderPram.getUserPhone()); + + List list = storeOrderInfoService.getVoListByOrderId(existOrder.getId()); + List> cartInfos = CollUtil.newArrayList(); + for (StoreOrderInfoVo infoVo : list) { + HashMap cartInfo = new HashMap<>(); + cartInfo.put("payNum", infoVo.getInfo().getPayNum()); + cartInfo.put("price", infoVo.getInfo().getPrice()); + cartInfo.put("productName", infoVo.getInfo().getProductName()); + cartInfo.put("productImg", infoVo.getInfo().getImage()); + cartInfos.add(cartInfo); + } + HashMap orderInfo = new HashMap<>(); + orderInfo.put("deliveryId", existOrder.getDeliveryId()); + orderInfo.put("deliveryName", existOrder.getDeliveryName()); + orderInfo.put("deliveryType", existOrder.getDeliveryType()); + orderInfo.put("info", cartInfos); + + resultMap.put("order", orderInfo); + // resultMap.put("express", expressInfo); + return resultMap; } /** @@ -156,7 +558,16 @@ public class OrderServiceImpl implements OrderService { */ @Override public OrderProductReplyResponse getReplyProduct(GetProductReply getProductReply) { - return null; + StoreOrderInfo storeOrderInfo = storeOrderInfoService.getByUniAndOrderId(getProductReply.getUni(), getProductReply.getOrderId()); + OrderInfoDetailVo scr = JsonUtils.parseObject(storeOrderInfo.getInfo(), OrderInfoDetailVo.class); + OrderProductReplyResponse response = new OrderProductReplyResponse(); + response.setCartNum(scr.getPayNum()); + response.setTruePrice(scr.getPrice()); + response.setProductId(scr.getProductId()); + response.setImage(scr.getImage()); + response.setSku(scr.getSku()); + response.setStoreName(scr.getProductName()); + return response; } /** @@ -167,7 +578,149 @@ public class OrderServiceImpl implements OrderService { */ @Override public ApplyRefundOrderInfoResponse applyRefundOrderInfo(String orderId) { - return null; + StoreOrder storeOrder = getByOrderIdException(orderId); + ApplyRefundOrderInfoResponse response = new ApplyRefundOrderInfoResponse(); + BeanUtils.copyProperties(storeOrder, response); + // 订单详情对象列表 + List infoVoList = storeOrderInfoService.getOrderListByOrderId(storeOrder.getId()); + List infoResponseList = CollUtil.newArrayList(); + infoVoList.forEach(e -> { + OrderInfoResponse orderInfoResponse = new OrderInfoResponse(); + orderInfoResponse.setStoreName(e.getInfo().getProductName()); + orderInfoResponse.setImage(e.getInfo().getImage()); + orderInfoResponse.setCartNum(e.getInfo().getPayNum()); + orderInfoResponse.setPrice(e.getInfo().getPrice()); + orderInfoResponse.setProductId(e.getProductId()); + infoResponseList.add(orderInfoResponse); + }); + response.setOrderInfoList(infoResponseList); + return response; + } + + private StoreOrder getByOrderIdException(String orderId) { + StoreOrder storeOrder = storeOrderService.getByOderId(orderId); + if (ObjectUtil.isNull(storeOrder)) { + throw new ServiceException("订单不存在"); + } + if (storeOrder.getIsDel() || storeOrder.getIsSystemDel()) { + throw new ServiceException("订单不存在"); + } + return storeOrder; + } + + /** + * 计算订单运费 + */ + private void getFreightFee(OrderInfoVo orderInfoVo, AddressRespDTO userAddress) { + // 判断是否满额包邮 type=1按件数 2按重量 3按体积 + // 全场满额包邮开关 + String postageSwitchString = apiConfigApi.getConfigKey(SysConfigConstants.STORE_FEE_POSTAGE_SWITCH).toString(); + // 全场满额包邮金额 + String storeFreePostageString = apiConfigApi.getConfigKey(SysConfigConstants.STORE_FEE_POSTAGE).toString(); + BigDecimal storePostage = BigDecimal.ZERO; + if (postageSwitchString.equals("true") && (storeFreePostageString.equals("0") || orderInfoVo.getProTotalFee().compareTo(new BigDecimal(storeFreePostageString)) >= 0)) { + storePostage = BigDecimal.ZERO; + } else if (ObjectUtil.isNull(userAddress) || userAddress.getCityId() <= 0) { + // 用户地址不存在,默认运费为0元 + storePostage = BigDecimal.ZERO; + } else { + // 有用户地址的情况下 + // 运费根据商品计算 + Map proMap = new HashMap<>(); + orderInfoVo.getOrderDetailList().forEach(e -> { + Integer proId = e.getProductId(); + if (proMap.containsKey(proId)) { + MyRecord record = proMap.get(proId); + record.set("totalPrice", record.getBigDecimal("totalPrice").add(e.getPrice().multiply(BigDecimal.valueOf(e.getPayNum())))); + record.set("totalNum", record.getInt("totalNum") + e.getPayNum()); + BigDecimal weight = e.getWeight().multiply(BigDecimal.valueOf(e.getPayNum())); + record.set("weight", record.getBigDecimal("weight").add(weight)); + BigDecimal volume = e.getVolume().multiply(BigDecimal.valueOf(e.getPayNum())); + record.set("volume", record.getBigDecimal("volume").add(volume)); + } else { + MyRecord record = new MyRecord(); + record.set("totalPrice", e.getPrice().multiply(BigDecimal.valueOf(e.getPayNum()))); + record.set("totalNum", e.getPayNum()); + record.set("tempId", e.getTempId()); + record.set("proId", proId); + BigDecimal weight = e.getWeight().multiply(BigDecimal.valueOf(e.getPayNum())); + record.set("weight", weight); + BigDecimal volume = e.getVolume().multiply(BigDecimal.valueOf(e.getPayNum())); + record.set("volume", volume); + + proMap.put(proId, record); + } + }); + + // 指定包邮(单品运费模板)> 指定区域配送(单品运费模板) + int cityId = userAddress.getCityId(); + + for (Map.Entry m : proMap.entrySet()) { + MyRecord value = m.getValue(); + Integer tempId = value.getInt("tempId"); + ShippingTemplatesDO shippingTemplatesDO = shippingTemplatesApi.getById(tempId); + if (shippingTemplatesDO.getAppoint()) {// 指定包邮 + // 判断是否在指定包邮区域内 + // 必须满足件数 + 金额 才能包邮 + ShippingTemplatesFreeDO shippingTemplatesFree = shippingTemplatesFreeApi.getByTempIdAndCityId(tempId, cityId); + if (ObjectUtil.isNotNull(shippingTemplatesFree)) { // 在包邮区域内 + BigDecimal freeNum = shippingTemplatesFree.getNumber(); + BigDecimal multiply = value.getBigDecimal("totalPrice"); + if (new BigDecimal(value.getInt("totalNum")).compareTo(freeNum) >= 0 && multiply.compareTo(shippingTemplatesFree.getPrice()) >= 0) { + // 满足件数 + 金额 = 包邮 + continue; + } + } + } + // 不满足指定包邮条件,走指定区域配送 + ShippingTemplatesRegionDO shippingTemplatesRegion = shippingTemplatesRegionApi.getByTempIdAndCityId(tempId, cityId); + if (ObjectUtil.isNull(shippingTemplatesRegion)) { + throw new ServiceException("计算运费时,未找到全国运费配置"); + } + + // 判断计费方式:件数、重量、体积 + switch (shippingTemplatesDO.getType()) { + case 1: // 件数 + // 判断件数是否超过首件 + Integer num = value.getInt("totalNum"); + if (num <= shippingTemplatesRegion.getFirst().intValue()) { + storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice()); + } else {// 超过首件的需要计算续件 + int renewalNum = num - shippingTemplatesRegion.getFirst().intValue(); + // 剩余件数/续件 = 需要计算的续件费用的次数 + BigDecimal divide = new BigDecimal(renewalNum).divide(shippingTemplatesRegion.getRenewal(), 0, BigDecimal.ROUND_UP); + BigDecimal renewalPrice = shippingTemplatesRegion.getRenewalPrice().multiply(divide); + storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice()).add(renewalPrice); + } + break; + case 2: // 重量 + BigDecimal weight = value.getBigDecimal("weight"); + if (weight.compareTo(shippingTemplatesRegion.getFirst()) <= 0) { + storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice()); + } else {// 超过首件的需要计算续件 + BigDecimal renewalNum = weight.subtract(shippingTemplatesRegion.getFirst()); + // 剩余件数/续件 = 需要计算的续件费用的次数 + BigDecimal divide = renewalNum.divide(shippingTemplatesRegion.getRenewal(), 0, BigDecimal.ROUND_UP); + BigDecimal renewalPrice = shippingTemplatesRegion.getRenewalPrice().multiply(divide); + storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice()).add(renewalPrice); + } + break; + case 3: // 体积 + BigDecimal volume = value.getBigDecimal("volume"); + if (volume.compareTo(shippingTemplatesRegion.getFirst()) <= 0) { + storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice()); + } else {// 超过首件的需要计算续件 + BigDecimal renewalNum = volume.subtract(shippingTemplatesRegion.getFirst()); + // 剩余件数/续件 = 需要计算的续件费用的次数 + BigDecimal divide = renewalNum.divide(shippingTemplatesRegion.getRenewal(), 0, BigDecimal.ROUND_UP); + BigDecimal renewalPrice = shippingTemplatesRegion.getRenewalPrice().multiply(divide); + storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice()).add(renewalPrice); + } + break; + } + } + } + orderInfoVo.setFreightFee(storePostage); } /** @@ -178,9 +731,265 @@ public class OrderServiceImpl implements OrderService { */ @Override public MyRecord preOrder(PreOrderRequest request) { - return null; + if (CollUtil.isEmpty(request.getOrderDetails())) { + throw new ServiceException("预下单订单详情列表不能为空"); + } + MemberUserRespDTO user = memberUserApi.getInfoException(); + // 校验预下单商品信息 + OrderInfoVo orderInfoVo = validatePreOrderRequest(request, user); + // 商品总计金额 + BigDecimal totalPrice; + if (orderInfoVo.getOrderDetailList().get(0).getProductType().equals(Constants.PRODUCT_TYPE_NORMAL)) { + // 普通商品 + totalPrice = orderInfoVo.getOrderDetailList().stream().map(e -> e.getVipPrice().multiply(new BigDecimal(e.getPayNum()))).reduce(BigDecimal.ZERO, BigDecimal::add); + } else { + totalPrice = orderInfoVo.getOrderDetailList().stream().map(e -> e.getPrice().multiply(new BigDecimal(e.getPayNum()))).reduce(BigDecimal.ZERO, BigDecimal::add); + } + orderInfoVo.setProTotalFee(totalPrice); + // 购买商品总数量 + int orderProNum = orderInfoVo.getOrderDetailList().stream().mapToInt(OrderInfoDetailVo::getPayNum).sum(); + orderInfoVo.setOrderProNum(orderProNum); + // 获取默认地址 + AddressRespDTO userAddress = addressApi.getDefaultByUid(user.getId()); + if (ObjectUtil.isNotNull(userAddress)) { + // 计算运费 + getFreightFee(orderInfoVo, userAddress); + orderInfoVo.setAddressId(userAddress.getId()); + orderInfoVo.setRealName(userAddress.getName()); + orderInfoVo.setPhone(userAddress.getMobile()); + orderInfoVo.setProvince(userAddress.getProvince()); + orderInfoVo.setCity(userAddress.getCity()); + orderInfoVo.setDistrict(userAddress.getDistrict()); + orderInfoVo.setDetail(userAddress.getDetailAddress()); + } else { + orderInfoVo.setFreightFee(BigDecimal.ZERO); + } + // 实际支付金额 + orderInfoVo.setPayFee(orderInfoVo.getProTotalFee().add(orderInfoVo.getFreightFee())); + //用户剩余积分 + //用户剩余经验 + // 缓存订单 + String key = user.getId() + DateUtils.getNowTime().toString()+CrmebUtil.getUuid(); + redisUtil.set("user_order:" + key, JSONUtil.parseObj(orderInfoVo), Constants.ORDER_CASH_CONFIRM, TimeUnit.MINUTES); + MyRecord record = new MyRecord(); + record.set("preOrderNo", key); + return record; } + /** + * 校验预下单商品信息 + * @param request 预下单请求参数 + * @return OrderInfoVo + */ + private OrderInfoVo validatePreOrderRequest(PreOrderRequest request, MemberUserRespDTO user) { + OrderInfoVo orderInfoVo = new OrderInfoVo(); + List detailVoList = CollUtil.newArrayList(); + if (request.getPreOrderType().equals("shoppingCart")) {// 购物车购买 + detailVoList = validatePreOrderShopping(request, user); + List cartIdList = request.getOrderDetails().stream().map(PreOrderDetailRequest::getShoppingCartId).distinct().collect(Collectors.toList()); + orderInfoVo.setCartIdList(cartIdList); + } + if (request.getPreOrderType().equals("buyNow")) {// 立即购买 + // 立即购买只会有一条详情 + PreOrderDetailRequest detailRequest = request.getOrderDetails().get(0); + //TODO 秒杀、砍价、拼团 +// if (detailRequest.getSeckillId() > 0) {// 秒杀 +// detailVoList.add(validatePreOrderSeckill(detailRequest, user)); +// orderInfoVo.setSeckillId(detailRequest.getSeckillId()); +// } else if (detailRequest.getBargainId() > 0) {// 砍价 +// detailVoList.add(validatePreOrderBargain(detailRequest, user)); +// orderInfoVo.setBargainId(detailRequest.getBargainId()); +// orderInfoVo.setBargainUserId(detailRequest.getBargainUserId()); +// } else if (detailRequest.getCombinationId() > 0) {// 拼团 +// detailVoList.add(validatePreOrderCombination(detailRequest, user)); +// orderInfoVo.setCombinationId(detailRequest.getCombinationId()); +// orderInfoVo.setPinkId(detailRequest.getPinkId()); +// } else { + // 普通商品 + if (ObjectUtil.isNull(detailRequest.getProductId())) { + throw new ServiceException("商品编号不能为空"); + } + if (ObjectUtil.isNull(detailRequest.getAttrValueId())) { + throw new ServiceException("商品规格属性值不能为空"); + } + if (ObjectUtil.isNull(detailRequest.getProductNum()) || detailRequest.getProductNum() < 0) { + throw new ServiceException("购买数量必须大于0"); + } + // 查询商品信息 + StoreProduct storeProduct = storeProductService.getById(detailRequest.getProductId()); + if (ObjectUtil.isNull(storeProduct)) { + throw new ServiceException("商品信息不存在,请刷新后重新选择"); + } + if (storeProduct.getIsDel()) { + throw new ServiceException("商品已删除,请刷新后重新选择"); + } + if (!storeProduct.getIsShow()) { + throw new ServiceException("商品已下架,请刷新后重新选择"); + } + if (storeProduct.getStock() < detailRequest.getProductNum()) { + throw new ServiceException("商品库存不足,请刷新后重新选择"); + } + // 查询商品规格属性值信息 + StoreProductAttrValue attrValue = storeProductAttrValueService.getByIdAndProductIdAndType(detailRequest.getAttrValueId(), detailRequest.getProductId(), Constants.PRODUCT_TYPE_NORMAL); + if (ObjectUtil.isNull(attrValue)) { + throw new ServiceException("商品规格信息不存在,请刷新后重新选择"); + } + if (attrValue.getStock() < detailRequest.getProductNum()) { + throw new ServiceException("商品规格库存不足,请刷新后重新选择"); + } + OrderInfoDetailVo detailVo = new OrderInfoDetailVo(); + detailVo.setProductId(storeProduct.getId()); + detailVo.setProductName(storeProduct.getStoreName()); + detailVo.setAttrValueId(attrValue.getId()); + detailVo.setSku(attrValue.getSuk()); + detailVo.setPrice(attrValue.getPrice()); + detailVo.setPayNum(detailRequest.getProductNum()); + detailVo.setImage(StrUtil.isNotBlank(attrValue.getImage()) ? attrValue.getImage() : storeProduct.getImage()); + detailVo.setVolume(attrValue.getVolume()); + detailVo.setWeight(attrValue.getWeight()); + detailVo.setTempId(storeProduct.getTempId()); + detailVo.setIsSub(storeProduct.getIsSub()); + detailVo.setProductType(Constants.PRODUCT_TYPE_NORMAL); + detailVo.setVipPrice(detailVo.getPrice()); + detailVo.setGiveIntegral(storeProduct.getGiveIntegral()); + detailVoList.add(detailVo); + //} + } + if (request.getPreOrderType().equals("again")) {// 再次购买 + PreOrderDetailRequest detailRequest = request.getOrderDetails().get(0); + detailVoList = validatePreOrderAgain(detailRequest, user); + } + orderInfoVo.setOrderDetailList(detailVoList); + return orderInfoVo; + } + + /** + * 再次下单预下单校验 + * @param detailRequest 请求参数 + * @return List + */ + private List validatePreOrderAgain(PreOrderDetailRequest detailRequest, MemberUserRespDTO user) { + List detailVoList = CollUtil.newArrayList(); + if (StrUtil.isBlank(detailRequest.getOrderNo())) { + throw new ServiceException("再次购买订单编号不能为空"); + } + StoreOrder storeOrder = getByOrderIdException(detailRequest.getOrderNo()); + if (storeOrder.getRefundStatus() > 0 || storeOrder.getStatus() != 3) { + throw new ServiceException("只有已完成状态订单才能再次购买"); + } + if (storeOrder.getSeckillId() > 0 || storeOrder.getBargainId() > 0 || storeOrder.getCombinationId() > 0) { + throw new ServiceException("活动商品订单不能再次购买"); + } + if (storeOrder.getType().equals(1)) { + throw new ServiceException("视频订单不能再次购买"); + } + // 获取订单详情 + List infoVoList = storeOrderInfoService.getVoListByOrderId(storeOrder.getId()); + if (CollUtil.isEmpty(infoVoList)) { + throw new ServiceException("订单详情未找到"); + } + infoVoList.forEach(e -> { + OrderInfoDetailVo detailVo = e.getInfo(); + // 查询商品信息 + StoreProduct storeProduct = storeProductService.getById(detailVo.getProductId()); + if (ObjectUtil.isNull(storeProduct)) { + throw new ServiceException("商品信息不存在,请刷新后重新选择"); + } + if (storeProduct.getIsDel()) { + throw new ServiceException("商品已删除,请刷新后重新选择"); + } + if (!storeProduct.getIsShow()) { + throw new ServiceException("商品已下架,请刷新后重新选择"); + } + if (storeProduct.getStock() < detailVo.getPayNum()) { + throw new ServiceException("商品库存不足,请刷新后重新选择"); + } + // 查询商品规格属性值信息 + StoreProductAttrValue attrValue = storeProductAttrValueService.getByIdAndProductIdAndType(detailVo.getAttrValueId(), detailVo.getProductId(), Constants.PRODUCT_TYPE_NORMAL); + if (ObjectUtil.isNull(attrValue)) { + throw new ServiceException("商品规格信息不存在,请刷新后重新选择"); + } + if (attrValue.getStock() < detailVo.getPayNum()) { + throw new ServiceException("商品规格库存不足,请刷新后重新选择"); + } + OrderInfoDetailVo tempDetailVo = new OrderInfoDetailVo(); + tempDetailVo.setProductId(storeProduct.getId()); + tempDetailVo.setProductName(storeProduct.getStoreName()); + tempDetailVo.setAttrValueId(attrValue.getId()); + tempDetailVo.setSku(attrValue.getSuk()); + tempDetailVo.setPrice(attrValue.getPrice()); + tempDetailVo.setPayNum(detailVo.getPayNum()); + tempDetailVo.setImage(StrUtil.isNotBlank(attrValue.getImage()) ? attrValue.getImage() : storeProduct.getImage()); + tempDetailVo.setVolume(attrValue.getVolume()); + tempDetailVo.setWeight(attrValue.getWeight()); + tempDetailVo.setTempId(storeProduct.getTempId()); + tempDetailVo.setGiveIntegral(storeProduct.getGiveIntegral()); + tempDetailVo.setIsSub(storeProduct.getIsSub()); + tempDetailVo.setProductType(Constants.PRODUCT_TYPE_NORMAL); + tempDetailVo.setVipPrice(attrValue.getPrice()); + detailVoList.add(tempDetailVo); + }); + return detailVoList; + } + + /** + * 购物车预下单校验 + * @param request 请求参数 + * @param user 用户 + * @return List + */ + private List validatePreOrderShopping(PreOrderRequest request, MemberUserRespDTO user) { + List detailVoList = CollUtil.newArrayList(); + + request.getOrderDetails().forEach(e -> { + if (ObjectUtil.isNull(e.getShoppingCartId())) { + throw new ServiceException("购物车编号不能为空"); + } + StoreCart storeCart = storeCartService.getByIdAndUid(e.getShoppingCartId(), user.getId()); + if (ObjectUtil.isNull(storeCart)) { + throw new ServiceException("未找到对应的购物车信息"); + } + // 查询商品信息 + StoreProduct storeProduct = storeProductService.getById(storeCart.getProductId()); + if (ObjectUtil.isNull(storeProduct)) { + throw new ServiceException("商品信息不存在,请刷新后重新选择"); + } + if (storeProduct.getIsDel()) { + throw new ServiceException("商品已删除,请刷新后重新选择"); + } + if (!storeProduct.getIsShow()) { + throw new ServiceException("商品已下架,请刷新后重新选择"); + } + if (storeProduct.getStock() < storeCart.getCartNum()) { + throw new ServiceException("商品库存不足,请刷新后重新选择"); + } + // 查询商品规格属性值信息 + StoreProductAttrValue attrValue = storeProductAttrValueService.getByIdAndProductIdAndType(Integer.valueOf(storeCart.getProductAttrUnique()), storeCart.getProductId(), Constants.PRODUCT_TYPE_NORMAL); + if (ObjectUtil.isNull(attrValue)) { + throw new ServiceException("商品规格信息不存在,请刷新后重新选择"); + } + if (attrValue.getStock() < storeCart.getCartNum()) { + throw new ServiceException("商品规格库存不足,请刷新后重新选择"); + } + OrderInfoDetailVo detailVo = new OrderInfoDetailVo(); + detailVo.setProductId(storeProduct.getId()); + detailVo.setProductName(storeProduct.getStoreName()); + detailVo.setAttrValueId(attrValue.getId()); + detailVo.setSku(attrValue.getSuk()); + detailVo.setPrice(attrValue.getPrice()); + detailVo.setPayNum(storeCart.getCartNum()); + detailVo.setImage(StrUtil.isNotBlank(attrValue.getImage()) ? attrValue.getImage() : storeProduct.getImage()); + detailVo.setVolume(attrValue.getVolume()); + detailVo.setWeight(attrValue.getWeight()); + detailVo.setTempId(storeProduct.getTempId()); + detailVo.setGiveIntegral(storeProduct.getGiveIntegral()); + detailVo.setIsSub(storeProduct.getIsSub()); + detailVo.setProductType(Constants.PRODUCT_TYPE_NORMAL); + detailVo.setVipPrice(detailVo.getPrice()); + detailVoList.add(detailVo); + }); + return detailVoList; + } /** * 加载预下单信息 * @@ -189,7 +998,79 @@ public class OrderServiceImpl implements OrderService { */ @Override public PreOrderResponse loadPreOrder(String preOrderNo) { - return null; + // 通过缓存获取预下单对象 + String key = "user_order:" + preOrderNo; + boolean exists = redisUtil.exists(key); + if (!exists) { + throw new ServiceException("预下单订单不存在"); + } + String orderVoString = redisUtil.get(key).toString(); + OrderInfoVo orderInfoVo = JSONUtil.toBean(orderVoString, OrderInfoVo.class); + PreOrderResponse preOrderResponse = new PreOrderResponse(); + preOrderResponse.setOrderInfoVo(orderInfoVo); + String payWeixinOpen = apiConfigApi.getConfigKey(SysConfigConstants.CONFIG_PAY_WEIXIN_OPEN).toString(); + if (orderInfoVo.getIsVideo()) { + // 关闭余额支付和到店自提 + preOrderResponse.setYuePayStatus("0"); + preOrderResponse.setPayWeixinOpen(payWeixinOpen); + preOrderResponse.setStoreSelfMention("false"); + preOrderResponse.setAliPayStatus("0"); + return preOrderResponse; + } + String yuePayStatus = apiConfigApi.getConfigKey(SysConfigConstants.CONFIG_YUE_PAY_STATUS).toString();// 1开启 2关闭 + String storeSelfMention = apiConfigApi.getConfigKey(SysConfigConstants.CONFIG_KEY_STORE_SELF_MENTION).toString(); + String aliPayStatus = apiConfigApi.getConfigKey(SysConfigConstants.CONFIG_ALI_PAY_STATUS).toString();// 1开启 + preOrderResponse.setYuePayStatus(yuePayStatus); + preOrderResponse.setPayWeixinOpen(payWeixinOpen); + preOrderResponse.setStoreSelfMention(storeSelfMention); + preOrderResponse.setAliPayStatus(aliPayStatus); + return preOrderResponse; + } + + + /** + * 计算订单价格 + * @param request 计算订单价格请求对象 + * @return ComputedOrderPriceResponse + */ + private ComputedOrderPriceResponse computedPrice(OrderComputedPriceRequest request, OrderInfoVo orderInfoVo, MemberUserRespDTO user) { + // 计算各种价格 + ComputedOrderPriceResponse priceResponse = new ComputedOrderPriceResponse(); + // 计算运费 + if (request.getShippingType().equals(2)) {// 到店自提,不计算运费 + priceResponse.setFreightFee(BigDecimal.ZERO); + } else if (ObjectUtil.isNull(request.getAddressId()) || request.getAddressId() <= 0) { + // 快递配送,无地址 + priceResponse.setFreightFee(BigDecimal.ZERO); + } else {// 快递配送,有地址 + AddressRespDTO userAddress = addressApi.getById(request.getAddressId()); + if (ObjectUtil.isNull(userAddress)) { + priceResponse.setFreightFee(BigDecimal.ZERO); + } else { + getFreightFee(orderInfoVo, userAddress); + priceResponse.setFreightFee(orderInfoVo.getFreightFee()); + } + } + // 计算优惠券金额 + +// if (orderInfoVo.getProTotalFee().compareTo(storeCouponUser.getMoney()) <= 0) { +// priceResponse.setCouponFee(orderInfoVo.getProTotalFee()); +// priceResponse.setDeductionPrice(BigDecimal.ZERO); +// priceResponse.setSurplusIntegral(user.getIntegral()); +// priceResponse.setPayFee(priceResponse.getFreightFee()); +// priceResponse.setUsedIntegral(0); +// priceResponse.setUseIntegral(false); +// priceResponse.setProTotalFee(orderInfoVo.getProTotalFee()); +// return priceResponse; +// } else { +// priceResponse.setCouponFee(storeCouponUser.getMoney()); +// } + + // 积分部分 + + // 使用积分 + // 查询积分使用比例 + return priceResponse; } /** @@ -200,7 +1081,16 @@ public class OrderServiceImpl implements OrderService { */ @Override public ComputedOrderPriceResponse computedOrderPrice(OrderComputedPriceRequest request) { - return null; + // 通过缓存获取预下单对象 + String key = "user_order:" + request.getPreOrderNo(); + boolean exists = redisUtil.exists(key); + if (!exists) { + throw new ServiceException("预下单订单不存在"); + } + String orderVoString = redisUtil.get(key).toString(); + OrderInfoVo orderInfoVo = JSONUtil.toBean(orderVoString, OrderInfoVo.class); + MemberUserRespDTO user = memberUserApi.getInfoException(); + return computedPrice(request, orderInfoVo, user); } /** @@ -211,9 +1101,295 @@ public class OrderServiceImpl implements OrderService { */ @Override public MyRecord createOrder(CreateOrderRequest orderRequest) { - return null; + MemberUserRespDTO user = memberUserApi.getInfoException(); + // 通过缓存获取预下单对象 + String key = "user_order:" + orderRequest.getPreOrderNo(); + boolean exists = redisUtil.exists(key); + if (!exists) { + throw new ServiceException("预下单订单不存在"); + } + String orderVoString = redisUtil.get(key).toString(); + OrderInfoVo orderInfoVo = JSONUtil.toBean(orderVoString, OrderInfoVo.class); + + // 检测支付方式 + if (!orderUtil.checkPayType(orderRequest.getPayType())) throw new ServiceException("暂不支持该支付方式,请刷新页面或者联系管理员"); + + if (orderRequest.getPayType().equals(PayConstants.PAY_TYPE_WE_CHAT)) { + // 检测支付渠道 + if (StrUtil.isBlank(orderRequest.getPayChannel())) throw new ServiceException("支付渠道不能为空!"); + //if (!OrderUtils.checkPayChannel(orderRequest.getPayChannel())) throw new ServiceException("支付渠道不存在!"); + } + + // 校验商品库存 + List skuRecordList = validateProductStock(orderInfoVo, user); + + // 校验收货信息 + String verifyCode = ""; + String userAddressStr = ""; + if (orderRequest.getShippingType() == 1) { // 快递配送 + if (orderRequest.getAddressId() <= 0) throw new ServiceException("请选择收货地址"); + AddressRespDTO userAddress = addressApi.getById(orderRequest.getAddressId()); + if (ObjectUtil.isNull(userAddress) || userAddress.getIsDel()) { + throw new ServiceException("收货地址有误"); + } + orderRequest.setRealName(userAddress.getName()); + orderRequest.setPhone(userAddress.getMobile()); + userAddressStr = userAddress.getProvince() + userAddress.getCity() + userAddress.getDistrict() + userAddress.getDetailAddress(); + }else if (orderRequest.getShippingType() == 2) { // 到店自提 + if (StringUtils.isBlank(orderRequest.getRealName()) || StringUtils.isBlank(orderRequest.getPhone())) { + throw new ServiceException("请填写姓名和电话"); + } + // 自提开关是否打开 + String storeSelfMention = apiConfigApi.getConfigKey(SysConfigConstants.CONFIG_KEY_STORE_SELF_MENTION).toString(); + if (storeSelfMention.equals("false")) { + throw new ServiceException("请先联系管理员开启门店自提"); + } +// SystemStore systemStore = systemStoreService.getById(orderRequest.getStoreId()); +// if (ObjectUtil.isNull(systemStore) || systemStore.getIsDel() || !systemStore.getIsShow()) { +// throw new ServiceException("暂无门店无法选择门店自提"); +// } + verifyCode = CrmebUtil.randomCount(1111111111,999999999)+""; + //userAddressStr = systemStore.getName(); + } + + // 活动商品校验 + //TODO 秒杀 +// if (ObjectUtil.isNotNull(orderInfoVo.getSeckillId()) && orderInfoVo.getSeckillId() > 0) { +// StoreSeckill storeSeckill = storeSeckillService.getByIdException(orderInfoVo.getSeckillId()); +// if (storeSeckill.getStatus().equals(0)) { +// throw new ServiceException("秒杀商品已关闭"); +// } +// OrderInfoDetailVo detailVo = orderInfoVo.getOrderDetailList().get(0); +// StoreProductAttrValue seckillAttrValue = storeProductAttrValueService.getByIdAndProductIdAndType(detailVo.getAttrValueId(), orderInfoVo.getSeckillId(), Constants.PRODUCT_TYPE_SECKILL); +// if (ObjectUtil.isNull(seckillAttrValue)) { +// throw new ServiceException("秒杀商品规格不存在"); +// } +// commonValidateSeckill(storeSeckill, seckillAttrValue, user, detailVo.getPayNum()); +// } + + // 计算订单各种价格 + OrderComputedPriceRequest orderComputedPriceRequest = new OrderComputedPriceRequest(); + orderComputedPriceRequest.setShippingType(orderRequest.getShippingType()); + orderComputedPriceRequest.setAddressId(orderRequest.getAddressId()); + orderComputedPriceRequest.setCouponId(orderRequest.getCouponId()); + orderComputedPriceRequest.setUseIntegral(orderRequest.getUseIntegral()); + ComputedOrderPriceResponse computedOrderPriceResponse = computedPrice(orderComputedPriceRequest, orderInfoVo, user); + + // 生成订单号 + String orderNo = CrmebUtil.getOrderNo("order"); + + // 购买赠送的积分 + int gainIntegral = 0; + List storeOrderInfos = new ArrayList<>(); + for (OrderInfoDetailVo detailVo : orderInfoVo.getOrderDetailList()) { + // 赠送积分 + if (ObjectUtil.isNotNull(detailVo.getGiveIntegral()) && detailVo.getGiveIntegral() > 0) { + gainIntegral += detailVo.getGiveIntegral() * detailVo.getPayNum(); + } + // 订单详情 + StoreOrderInfo soInfo = new StoreOrderInfo(); + soInfo.setProductId(detailVo.getProductId()); + soInfo.setInfo(JSONUtil.toJsonStr(detailVo)); + soInfo.setUnique(detailVo.getAttrValueId().toString()); + soInfo.setOrderNo(orderNo); + soInfo.setProductName(detailVo.getProductName()); + soInfo.setAttrValueId(detailVo.getAttrValueId()); + soInfo.setImage(detailVo.getImage()); + soInfo.setSku(detailVo.getSku()); + soInfo.setPrice(detailVo.getPrice()); + soInfo.setPayNum(detailVo.getPayNum()); + soInfo.setWeight(detailVo.getWeight()); + soInfo.setVolume(detailVo.getVolume()); + if (ObjectUtil.isNotNull(detailVo.getGiveIntegral()) && detailVo.getGiveIntegral() > 0) { + soInfo.setGiveIntegral(detailVo.getGiveIntegral()); + } else { + soInfo.setGiveIntegral(0); + } + soInfo.setIsReply(false); + soInfo.setIsSub(detailVo.getIsSub()); + soInfo.setProductType(detailVo.getProductType()); + if (ObjectUtil.isNotNull(detailVo.getVipPrice())) { + soInfo.setVipPrice(detailVo.getVipPrice()); + } else { + soInfo.setVipPrice(detailVo.getPrice()); + } + + storeOrderInfos.add(soInfo); + } + + // 下单赠送积分 + + // 支付渠道 默认:余额支付 + int isChannel = 3; + if (orderRequest.getPayType().equals(PayConstants.PAY_TYPE_WE_CHAT)) { + switch (orderRequest.getPayChannel()) { + case PayConstants.PAY_CHANNEL_WE_CHAT_H5:// H5 + isChannel = 2; + break; + case PayConstants.PAY_CHANNEL_WE_CHAT_PUBLIC:// 公众号 + isChannel = 0; + break; + case PayConstants.PAY_CHANNEL_WE_CHAT_PROGRAM:// 小程序 + isChannel = 1; + break; + case PayConstants.PAY_CHANNEL_WE_CHAT_APP_IOS:// app ios + isChannel = 4; + break; + case PayConstants.PAY_CHANNEL_WE_CHAT_APP_ANDROID:// app android + isChannel = 5; + break; + } + } + if (orderRequest.getPayType().equals(PayConstants.PAY_TYPE_ALI_PAY)) { + isChannel = 6; + if (orderRequest.getPayChannel().equals(PayConstants.PAY_CHANNEL_ALI_APP_PAY)) { + isChannel = 7; + } + } + + StoreOrder storeOrder = new StoreOrder(); + storeOrder.setUid(user.getId()); + storeOrder.setOrderId(orderNo); + storeOrder.setRealName(orderRequest.getRealName()); + storeOrder.setUserPhone(orderRequest.getPhone()); + storeOrder.setUserAddress(userAddressStr); + // 如果是自提 + if (orderRequest.getShippingType() == 2) { + storeOrder.setVerifyCode(verifyCode); + storeOrder.setStoreId(orderRequest.getStoreId()); + } + storeOrder.setTotalNum(orderInfoVo.getOrderProNum()); + storeOrder.setCouponId(Optional.ofNullable(orderRequest.getCouponId()).orElse(0)); + + // 订单总价 + BigDecimal totalPrice = computedOrderPriceResponse.getProTotalFee().add(computedOrderPriceResponse.getFreightFee()); + + storeOrder.setTotalPrice(totalPrice); + storeOrder.setProTotalPrice(computedOrderPriceResponse.getProTotalFee()); + storeOrder.setTotalPostage(computedOrderPriceResponse.getFreightFee()); + storeOrder.setCouponPrice(computedOrderPriceResponse.getCouponFee()); + storeOrder.setPayPrice(computedOrderPriceResponse.getPayFee()); + storeOrder.setPayPostage(computedOrderPriceResponse.getFreightFee()); + storeOrder.setDeductionPrice(computedOrderPriceResponse.getDeductionPrice()); + storeOrder.setPayType(orderRequest.getPayType()); + storeOrder.setUseIntegral(computedOrderPriceResponse.getUsedIntegral()); + storeOrder.setGainIntegral(gainIntegral); + storeOrder.setMark(StringEscapeUtils.escapeHtml4(orderRequest.getMark())); + storeOrder.setCombinationId(orderInfoVo.getCombinationId()); + storeOrder.setPinkId(orderInfoVo.getPinkId()); + storeOrder.setSeckillId(orderInfoVo.getSeckillId()); + storeOrder.setBargainId(orderInfoVo.getBargainId()); + storeOrder.setBargainUserId(orderInfoVo.getBargainUserId()); + storeOrder.setCreateTime(DateUtils.nowDateTime()); + storeOrder.setShippingType(orderRequest.getShippingType()); + storeOrder.setIsChannel(isChannel); + storeOrder.setPaid(false); + storeOrder.setCost(BigDecimal.ZERO); + storeOrder.setType(0); + if (orderInfoVo.getIsVideo()) { + storeOrder.setType(1);// 视频号订单 + } + + // StoreCouponUser storeCouponUser = new StoreCouponUser(); + // 优惠券修改 +// if (storeOrder.getCouponId() > 0) { +// storeCouponUser = storeCouponUserService.getById(storeOrder.getCouponId()); +// storeCouponUser.setStatus(1); +// } + //StoreCouponUser finalStoreCouponUser = storeCouponUser; + + Boolean execute = transactionTemplate.execute(e -> { + // 扣减库存 + // 需要根据是否活动商品,扣减不同的库存 + // 普通商品 + for (MyRecord skuRecord : skuRecordList) { + // 普通商品口库存 + storeProductService.operationStock(skuRecord.getInt("productId"), skuRecord.getInt("num"), "sub"); + // 普通商品规格扣库存 + //storeProductAttrValueService.operationStock(skuRecord.getInt("attrValueId"), skuRecord.getInt("num"), "sub", Constants.PRODUCT_TYPE_NORMAL); + }// + + storeOrderService.create(storeOrder); + storeOrderInfos.forEach(info -> info.setOrderId(storeOrder.getId())); + // 保存购物车商品详情 + storeOrderInfoService.saveOrderInfos(storeOrderInfos); + // 生成订单日志 + storeOrderStatusService.createLog(storeOrder.getId(), Constants.ORDER_STATUS_CACHE_CREATE_ORDER, "订单生成"); + + // 清除购物车数据 + if (CollUtil.isNotEmpty(orderInfoVo.getCartIdList())) { + storeCartService.deleteCartByIds(orderInfoVo.getCartIdList()); + } + return Boolean.TRUE; + }); + if (!execute) { + throw new ServiceException("订单生成失败"); + } + + // 删除缓存订单 + if (redisUtil.exists(key)) { + redisUtil.delete(key); + } + + // 加入自动未支付自动取消队列 + redisUtil.lPush(Constants.ORDER_AUTO_CANCEL_KEY, storeOrder.getOrderId()); + + // TODO 发送后台管理员下单提醒通知短信 + // sendAdminOrderNotice(storeOrder.getOrderId()); + + MyRecord record = new MyRecord(); + record.set("orderNo", storeOrder.getOrderId()); + return record; } + /** + * 校验商品库存(生成订单) + * @param orderInfoVo 订单详情Vo + * @return List + * skuRecord 扣减库存对象 + * ——activityId 活动商品id + * ——activityAttrValueId 活动商品skuId + * ——productId 普通(主)商品id + * ——attrValueId 普通(主)商品skuId + * ——num 购买数量 + */ + private List validateProductStock(OrderInfoVo orderInfoVo, MemberUserRespDTO user) { + List recordList = CollUtil.newArrayList(); + if (orderInfoVo.getSeckillId() > 0) { + // 普通商品 + List orderDetailList = orderInfoVo.getOrderDetailList(); + orderDetailList.forEach(e -> { + // 查询商品信息 + StoreProduct storeProduct = storeProductService.getById(e.getProductId()); + if (ObjectUtil.isNull(storeProduct)) { + throw new ServiceException("购买的商品信息不存在"); + } + if (storeProduct.getIsDel()) { + throw new ServiceException("购买的商品已删除"); + } + if (!storeProduct.getIsShow()) { + throw new ServiceException("购买的商品已下架"); + } + if (storeProduct.getStock().equals(0) || e.getPayNum() > storeProduct.getStock()) { + throw new ServiceException("购买的商品库存不足"); + } + // 查询商品规格属性值信息 + StoreProductAttrValue attrValue = storeProductAttrValueService.getByIdAndProductIdAndType(e.getAttrValueId(), e.getProductId(), Constants.PRODUCT_TYPE_NORMAL); + if (ObjectUtil.isNull(attrValue)) { + throw new ServiceException("购买的商品规格信息不存在"); + } + if (attrValue.getStock() < e.getPayNum()) { + throw new ServiceException("购买的商品库存不足"); + } + MyRecord record = new MyRecord(); + record.set("productId", e.getProductId()); + record.set("num", e.getPayNum()); + record.set("attrValueId", e.getAttrValueId()); + recordList.add(record); + }); + } + return recordList; + } /** * 获取支付配置 * @@ -221,6 +1397,15 @@ public class OrderServiceImpl implements OrderService { */ @Override public PreOrderResponse getPayConfig() { - return null; + PreOrderResponse preOrderResponse = new PreOrderResponse(); + String payWeixinOpen = apiConfigApi.getConfigKey(SysConfigConstants.CONFIG_PAY_WEIXIN_OPEN).toString(); + String yuePayStatus = apiConfigApi.getConfigKey(SysConfigConstants.CONFIG_YUE_PAY_STATUS).toString();// 1开启 2关闭 + String storeSelfMention = apiConfigApi.getConfigKey(SysConfigConstants.CONFIG_KEY_STORE_SELF_MENTION).toString(); + String aliPayStatus = apiConfigApi.getConfigKey(SysConfigConstants.CONFIG_ALI_PAY_STATUS).toString();// 1开启 + preOrderResponse.setYuePayStatus(yuePayStatus); + preOrderResponse.setPayWeixinOpen(payWeixinOpen); + preOrderResponse.setStoreSelfMention(storeSelfMention); + preOrderResponse.setAliPayStatus(aliPayStatus); + return preOrderResponse; } } diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/order/impl/OrderTaskServiceImpl.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/order/impl/OrderTaskServiceImpl.java index 85fd320ff..bf5f46496 100644 --- a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/order/impl/OrderTaskServiceImpl.java +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/order/impl/OrderTaskServiceImpl.java @@ -1,10 +1,28 @@ package cn.iocoder.yudao.module.shop.service.order.impl; -import cn.iocoder.yudao.module.shop.service.order.OrderTaskService; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import cn.iocoder.yudao.framework.common.util.date.DateUtils; +import cn.iocoder.yudao.module.member.api.user.MemberUserApi; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.shop.dal.dataobject.order.StoreOrderStatus; +import cn.iocoder.yudao.module.shop.dal.dataobject.product.StoreProductReply; +import cn.iocoder.yudao.module.shop.vo.order.StoreOrderInfoOldVo; +import cn.iocoder.yudao.framework.common.enums.Constants; +import cn.iocoder.yudao.framework.common.exception.ServiceException; +import cn.iocoder.yudao.module.shop.dal.dataobject.order.StoreOrder; +import cn.iocoder.yudao.module.shop.service.order.*; +import cn.iocoder.yudao.module.shop.service.product.StoreProductReplyService; +import cn.iocoder.yudao.module.shop.utils.RedisUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.support.TransactionTemplate; + +import java.util.List; /** * StoreOrderServiceImpl 接口实现 @@ -20,27 +38,156 @@ import org.springframework.stereotype.Service; */ @Service public class OrderTaskServiceImpl implements OrderTaskService { + + @Autowired + private RedisUtil redisUtil; + + @Autowired + private StoreOrderTaskService storeOrderTaskService; + + @Autowired + private StoreOrderService storeOrderService; + + @Autowired + private StoreOrderStatusService storeOrderStatusService; + + @Autowired + private StoreOrderInfoService storeOrderInfoService; + + @Autowired + private MemberUserApi userService; + + @Autowired + private StoreProductReplyService storeProductReplyService; + + @Autowired + private TransactionTemplate transactionTemplate; + + @Autowired + private OrderPayService orderPayService; //日志 private static final Logger logger = LoggerFactory.getLogger(OrderTaskServiceImpl.class); @Override public void cancelByUser() { + String redisKey = Constants.ORDER_TASK_REDIS_KEY_AFTER_CANCEL_BY_USER; + Long size = redisUtil.getListSize(redisKey); + logger.info("OrderTaskServiceImpl.cancelByUser | size:" + size); + if (size < 1) { + return; + } + for (int i = 0; i < size; i++) { + //如果10秒钟拿不到一个数据,那么退出循环 + Object data = redisUtil.getRightPop(redisKey, 10L); + if (null == data) { + continue; + } + try { +// StoreOrder storeOrder = getJavaBeanStoreOrder(data); + StoreOrder storeOrder = storeOrderService.getById(Integer.valueOf(data.toString())); + boolean result = storeOrderTaskService.cancelByUser(storeOrder); + if (!result) { + redisUtil.lPush(redisKey, data); + } + } catch (Exception e) { + redisUtil.lPush(redisKey, data); + } + } } @Override public void refundApply() { + String redisKey = Constants.ORDER_TASK_REDIS_KEY_AFTER_REFUND_BY_USER; + Long size = redisUtil.getListSize(redisKey); + logger.info("OrderTaskServiceImpl.refundApply | size:" + size); + if (size < 1) { + return; + } + for (int i = 0; i < size; i++) { + //如果10秒钟拿不到一个数据,那么退出循环 + Object orderId = redisUtil.getRightPop(redisKey, 10L); + if (null == orderId) { + continue; + } + try { + StoreOrder storeOrder = storeOrderService.getById(Integer.valueOf(orderId.toString())); + if (ObjectUtil.isNull(storeOrder)) { + throw new ServiceException("订单不存在,orderNo = " + orderId); + } +// boolean result = storeOrderTaskService.refundApply(storeOrder); + boolean result = storeOrderTaskService.refundOrder(storeOrder); + if (!result) { + logger.error("订单退款错误:result = " + result); + redisUtil.lPush(redisKey, orderId); + } + } catch (Exception e) { + logger.error("订单退款错误:" + e.getMessage()); + redisUtil.lPush(redisKey, orderId); + } + } } @Override public void complete() { + String redisKey = Constants.ORDER_TASK_REDIS_KEY_AFTER_COMPLETE_BY_USER; + Long size = redisUtil.getListSize(redisKey); + logger.info("OrderTaskServiceImpl.complete | size:" + size); + if (size < 1) { + return; + } + for (int i = 0; i < size; i++) { + //如果10秒钟拿不到一个数据,那么退出循环 + Object data = redisUtil.getRightPop(redisKey, 10L); + if (null == data) { + continue; + } + try { + StoreOrder storeOrder = getJavaBeanStoreOrder(data); + boolean result = storeOrderTaskService.complete(storeOrder); + if (!result) { + redisUtil.lPush(redisKey, data); + } + } catch (Exception e) { + redisUtil.lPush(redisKey, data); + } + } } + private StoreOrder getJavaBeanStoreOrder(Object data) { + return JSONUtil.toBean(JSONUtil.parseObj(data.toString()), StoreOrder.class); + } @Override public void orderPaySuccessAfter() { - + String redisKey = Constants.ORDER_TASK_PAY_SUCCESS_AFTER; + Long size = redisUtil.getListSize(redisKey); + logger.info("OrderTaskServiceImpl.orderPaySuccessAfter | size:" + size); + if (size < 1) { + return; + } + for (int i = 0; i < size; i++) { + //如果10秒钟拿不到一个数据,那么退出循环 + Object data = redisUtil.getRightPop(redisKey, 10L); + if (ObjectUtil.isNull(data)) { + continue; + } + try { + StoreOrder storeOrder = storeOrderService.getByOderId(String.valueOf(data)); + if (ObjectUtil.isNull(storeOrder)) { + logger.error("OrderTaskServiceImpl.orderPaySuccessAfter | 订单不存在,orderNo: " + data); + throw new ServiceException("订单不存在,orderNo: " + data); + } + boolean result = orderPayService.paySuccess(storeOrder); + if (!result) { + redisUtil.lPush(redisKey, data); + } + } catch (Exception e) { + e.printStackTrace(); + redisUtil.lPush(redisKey, data); + } + } } /** @@ -48,7 +195,33 @@ public class OrderTaskServiceImpl implements OrderTaskService { */ @Override public void autoCancel() { - + String redisKey = Constants.ORDER_AUTO_CANCEL_KEY; + Long size = redisUtil.getListSize(redisKey); + logger.info("OrderTaskServiceImpl.autoCancel | size:" + size); + if (size < 1) { + return; + } + for (int i = 0; i < size; i++) { + //如果10秒钟拿不到一个数据,那么退出循环 + Object data = redisUtil.getRightPop(redisKey, 10L); + if (null == data) { + continue; + } + try { + StoreOrder storeOrder = storeOrderService.getByOderId(String.valueOf(data)); + if (ObjectUtil.isNull(storeOrder)) { + logger.error("OrderTaskServiceImpl.autoCancel | 订单不存在,orderNo: " + data); + throw new ServiceException("订单不存在,orderNo: " + data); + } + boolean result = storeOrderTaskService.autoCancel(storeOrder); + if (!result) { + redisUtil.lPush(redisKey, data); + } + } catch (Exception e) { + e.printStackTrace(); + redisUtil.lPush(redisKey, data); + } + } } /** @@ -56,7 +229,27 @@ public class OrderTaskServiceImpl implements OrderTaskService { */ @Override public void orderReceiving() { - + String redisKey = Constants.ORDER_TASK_REDIS_KEY_AFTER_TAKE_BY_USER; + Long size = redisUtil.getListSize(redisKey); + logger.info("OrderTaskServiceImpl.orderReceiving | size:" + size); + if (size < 1) { + return; + } + for (int i = 0; i < size; i++) { + //如果10秒钟拿不到一个数据,那么退出循环 + Object id = redisUtil.getRightPop(redisKey, 10L); + if (null == id) { + continue; + } + try { + Boolean result = storeOrderTaskService.orderReceiving(Integer.valueOf(id.toString())); + if (!result) { + redisUtil.lPush(redisKey, id); + } + } catch (Exception e) { + redisUtil.lPush(redisKey, id); + } + } } /** @@ -64,6 +257,84 @@ public class OrderTaskServiceImpl implements OrderTaskService { */ @Override public void autoComplete() { +// 查找所有收获状态订单 + List orderList = storeOrderService.findIdAndUidListByReceipt(); + if (CollUtil.isEmpty(orderList)) { + return ; + } + logger.info("OrderTaskServiceImpl.autoComplete | size:0"); + // 根据订单状态表判断订单是否可以自动完成 + for (StoreOrder order : orderList) { + StoreOrderStatus orderStatus = storeOrderStatusService.getLastByOrderId(order.getId()); + if (!orderStatus.getChangeType().equals("user_take_delivery")) { + logger.error("订单自动完成:订单记录最后一条不是收货状态,orderId = " + order.getId()); + continue ; + } + // 判断是否到自动完成时间(收货时间向后偏移7天) + String comTime = DateUtils.addDay(orderStatus.getCreateTime(), 7, Constants.DATE_FORMAT); + int compareDate = DateUtils.compareDate(comTime, DateUtils.nowDateTime(Constants.DATE_FORMAT), Constants.DATE_FORMAT); + if (compareDate < 0) { + continue ; + } + + /** + * --------------- + * 自动好评转完成 + * --------------- + */ + // 获取订单详情 + List orderInfoVoList = storeOrderInfoService.getOrderListByOrderId(order.getId()); + if (CollUtil.isEmpty(orderInfoVoList)) { + logger.error("订单自动完成:无订单详情数据,orderId = " + order.getId()); + continue; + } + List replyList = CollUtil.newArrayList(); + MemberUserRespDTO user = userService.getUser(order.getUid()); + // 生成评论 + for (StoreOrderInfoOldVo orderInfo : orderInfoVoList) { + // 判断是否已评论 + if (orderInfo.getInfo().getIsReply().equals(1)) { + continue; + } + String replyType = Constants.STORE_REPLY_TYPE_PRODUCT; +// if (ObjectUtil.isNotNull(orderInfo.getInfo().getSeckillId()) && orderInfo.getInfo().getSeckillId() > 0) { +// replyType = Constants.STORE_REPLY_TYPE_SECKILL; +// } +// if (ObjectUtil.isNotNull(orderInfo.getInfo().getBargainId()) && orderInfo.getInfo().getBargainId() > 0) { +// replyType = Constants.STORE_REPLY_TYPE_BARGAIN; +// } +// if (ObjectUtil.isNotNull(orderInfo.getInfo().getCombinationId()) && orderInfo.getInfo().getCombinationId() > 0) { +// replyType = Constants.STORE_REPLY_TYPE_PINTUAN; +// } + StoreProductReply reply = new StoreProductReply(); + reply.setUid(order.getUid()); + reply.setOid(order.getId()); + reply.setProductId(orderInfo.getProductId()); + reply.setUnique(orderInfo.getUnique()); + reply.setReplyType(replyType); + reply.setProductScore(5); + reply.setServiceScore(5); + reply.setComment(""); + reply.setPics(""); + reply.setNickname(user.getNickname()); + reply.setAvatar(user.getAvatar()); + reply.setSku(orderInfo.getInfo().getSku()); + reply.setCreateTime(DateUtils.nowDateTime()); + replyList.add(reply); + } + order.setStatus(Constants.ORDER_STATUS_INT_COMPLETE); + Boolean execute = transactionTemplate.execute(e -> { + storeOrderService.updateById(order); + storeProductReplyService.saveBatch(replyList); + return Boolean.TRUE; + }); + if (execute) { + redisUtil.lPush(Constants.ORDER_TASK_REDIS_KEY_AFTER_COMPLETE_BY_USER, order.getId()); + } else { + logger.error("订单自动完成:更新数据库失败,orderId = " + order.getId()); + } + } } } + diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/order/impl/StoreOrderTaskServiceImpl.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/order/impl/StoreOrderTaskServiceImpl.java index d954c88a6..7e76cbadf 100644 --- a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/order/impl/StoreOrderTaskServiceImpl.java +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/order/impl/StoreOrderTaskServiceImpl.java @@ -106,7 +106,7 @@ public class StoreOrderTaskServiceImpl implements StoreOrderTaskService { attrValueService.operationStock(orderInfoVo.getAttrValueId(), orderInfoVo.getPayNum(), "add", Constants.PRODUCT_TYPE_NORMAL); } }catch (Exception e){ -// throw new CrmebException(e.getMessage()); +// throw new ServiceException(e.getMessage()); logger.error("回滚库存失败,error = " + e.getMessage()); return true; } diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/product/StoreCartService.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/product/StoreCartService.java index db49ddfc1..f4bd1d2fe 100644 --- a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/product/StoreCartService.java +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/product/StoreCartService.java @@ -88,7 +88,7 @@ public interface StoreCartService extends IService { * @param uid 用户uid * @return StoreCart */ - StoreCart getByIdAndUid(Long id, Integer uid); + StoreCart getByIdAndUid(Long id, Long uid); /** * 获取购物车商品数量(不区分规格) diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/product/impl/StoreCartServiceImpl.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/product/impl/StoreCartServiceImpl.java index e0e239d8b..b04ef44e2 100644 --- a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/product/impl/StoreCartServiceImpl.java +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/product/impl/StoreCartServiceImpl.java @@ -300,7 +300,7 @@ public class StoreCartServiceImpl extends ServiceImpl lqw = Wrappers.lambdaQuery(); lqw.eq(StoreCart::getId, id); lqw.eq(StoreCart::getUid, uid); diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/product/impl/StoreProductServiceImpl.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/product/impl/StoreProductServiceImpl.java index e4e4188ee..688675da2 100644 --- a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/product/impl/StoreProductServiceImpl.java +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/product/impl/StoreProductServiceImpl.java @@ -403,13 +403,13 @@ public class StoreProductServiceImpl extends ServiceImplcn.iocoder.boot yudao-common + + com.baomidou + mybatis-plus-annotation + 3.5.3.1 + compile + + + com.baomidou + mybatis-plus-annotation + 3.5.3.1 + compile + diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/address/AddressApi.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/address/AddressApi.java index 75ba02563..93597ec02 100644 --- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/address/AddressApi.java +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/address/AddressApi.java @@ -18,4 +18,13 @@ public interface AddressApi { */ AddressRespDTO getAddress(Long id, Long userId); + + AddressRespDTO getById(Integer addressId); + + /** + * 获取默认地址 + * @return UserAddress + */ + AddressRespDTO getDefaultByUid(Long uid); + } diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/address/dto/AddressRespDTO.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/address/dto/AddressRespDTO.java index cc8eb4701..050d72965 100644 --- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/address/dto/AddressRespDTO.java +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/address/dto/AddressRespDTO.java @@ -13,7 +13,7 @@ public class AddressRespDTO { /** * 编号 */ - private Long id; + private Integer id; /** * 用户编号 */ @@ -45,4 +45,35 @@ public class AddressRespDTO { */ private Boolean defaulted; + /** + * + *收货人所在省 + */ + private String province; + + /** + * + * 收货人所在市 + */ + private String city; + + /** + * + * 城市id + */ + private Integer cityId; + + /** + * + * 收货人所在区 + */ + + private String district; + + /** + * 是否删除 0未删除 1删除 + * + * true - 收货人所在区 + */ + private Boolean isDel; } diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApi.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApi.java index 4e9dd5e7f..043f1c8f3 100644 --- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApi.java +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApi.java @@ -64,4 +64,16 @@ public interface MemberUserApi { */ int updateById(MemberUserRespDTO member); + /** + * 获取当前用户id + * + * @return Integer + */ + Long getUserIdException(); + + MemberUserRespDTO getInfoException(); + + Long getUserId(); + + MemberUserRespDTO getInfo(); } diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/MemberUserBillDTO.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/MemberUserBillDTO.java new file mode 100644 index 000000000..e4acfa194 --- /dev/null +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/MemberUserBillDTO.java @@ -0,0 +1,98 @@ +package cn.iocoder.yudao.module.member.api.user.dto; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; +import java.util.Date; +/** + * 用户账单表 + * +---------------------------------------------------------------------- + * | CRMEB [ CRMEB赋能开发者,助力企业发展 ] + * +---------------------------------------------------------------------- + * | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权 + * +---------------------------------------------------------------------- + * | Author: CRMEB Team + * +---------------------------------------------------------------------- + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("eb_user_bill") +public class MemberUserBillDTO { + + private static final long serialVersionUID=1L; + + /** + *用户账单id + */ + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + /** + *用户uid + */ + private Long uid; + + /** + *关联id + */ + private String linkId; + + /** + *0 = 支出 1 = 获得 + */ + private int pm; + + /** + *账单标题 + */ + private String title; + + /** + *明细种类 + */ + private String category; + + /** + *明细类型 + */ + private String type; + + /** + *明细数字 + */ + private BigDecimal number; + + /** + *剩余 + */ + private BigDecimal balance; + + /** + *备注 + */ + private String mark; + + /** + *"0 = 带确定 1 = 有效 -1 = 无效" + */ + private Integer status; + + /** + *创建时间 + */ + private Date updateTime; + + /** + *创建时间 + */ + private Date createTime; + +} diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/MemberUserRespDTO.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/MemberUserRespDTO.java index 10d96365f..78d070873 100644 --- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/MemberUserRespDTO.java +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/MemberUserRespDTO.java @@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.member.api.user.dto; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import lombok.Data; +import java.math.BigDecimal; + /** * 用户信息 Response DTO * @@ -34,4 +36,5 @@ public class MemberUserRespDTO { */ private String mobile; + } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/address/AddressApiImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/address/AddressApiImpl.java index fd0f4843d..1eb4ccf1d 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/address/AddressApiImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/address/AddressApiImpl.java @@ -2,7 +2,13 @@ package cn.iocoder.yudao.module.member.api.address; import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; import cn.iocoder.yudao.module.member.convert.address.AddressConvert; +import cn.iocoder.yudao.module.member.dal.dataobject.address.AddressDO; +import cn.iocoder.yudao.module.member.dal.mysql.address.AddressMapper; import cn.iocoder.yudao.module.member.service.address.AddressService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import org.checkerframework.checker.units.qual.A; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -20,9 +26,36 @@ public class AddressApiImpl implements AddressApi { @Resource private AddressService addressService; + @Resource + private AddressMapper addressMapper; + + @Autowired + private AddressConvert addressConvert; + @Override public AddressRespDTO getAddress(Long id, Long userId) { return AddressConvert.INSTANCE.convert02(addressService.getAddress(userId, id)); } + @Override + public AddressRespDTO getById(Integer addressId) { + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + lambdaQueryWrapper.eq(AddressDO::getId, addressId); + lambdaQueryWrapper.eq(AddressDO::getIsDel, false); + return addressConvert.convert02(addressMapper.selectOne(lambdaQueryWrapper)); + } + + /** + * 获取默认地址 + * @return UserAddress + */ + @Override + public AddressRespDTO getDefaultByUid(Long uid) { + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.eq(AddressDO::getDefaulted, true); + lambdaQueryWrapper.eq(AddressDO::getId, uid); + return addressConvert.convert02(addressMapper.selectOne(lambdaQueryWrapper)); + } + + } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApiImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApiImpl.java index b96ea9c31..a2d1e9788 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApiImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApiImpl.java @@ -1,9 +1,12 @@ package cn.iocoder.yudao.module.member.api.user; +import cn.iocoder.yudao.framework.common.exception.ServiceException; +import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; import cn.iocoder.yudao.module.member.convert.user.UserConvert; import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; import cn.iocoder.yudao.module.member.service.user.MemberUserService; +import com.thoughtworks.xstream.core.SecurityUtils; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -49,4 +52,63 @@ public class MemberUserApiImpl implements MemberUserApi { return userService.updateById(UserConvert.INSTANCE.convert3(member)); } + @Override + public Long getUserIdException() { + Long id = SecurityFrameworkUtils.getLoginUserId(); + if (null == id) { + throw new ServiceException("登录信息已过期,请重新登录!"); + } + return id; + } + + /** + * 获取当前用户id + * + * @return Integer + * @author Mr.Zhang + * @since 2020-04-28 + */ + @Override + public Long getUserId() { + Long id = SecurityFrameworkUtils.getLoginUserId(); + if (null == id) { + return 0L; + } + return id; + } + + /** + * 获取个人资料 + * + * @return User + * @author Mr.Zhang + * @since 2020-04-28 + */ + @Override + public MemberUserRespDTO getInfo() { + if (getUserId() == 0L) { + return null; + } + return UserConvert.INSTANCE.convert2(userService.getById(getUserId())); + } + + /** + * 获取个人资料 + * + * @return User + * @author Mr.Zhang + * @since 2020-04-28 + */ + @Override + public MemberUserRespDTO getInfoException() { + MemberUserRespDTO user = getInfo(); + if (user == null) { + throw new ServiceException("用户信息不存在!"); + } + + if (user.getStatus() == 0) { + throw new ServiceException("用户已经被禁用!"); + } + return user; + } } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/AddressDO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/AddressDO.java index 467432460..2a888dc9d 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/AddressDO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/AddressDO.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.member.dal.dataobject.address; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; @@ -55,4 +56,10 @@ public class AddressDO extends BaseDO { */ private Boolean defaulted; + /** + *是否删除 + */ + @TableLogic + private Boolean isDel; + }