Pārlūkot izejas kodu

商家端,用户端,平台端 订单管理

lyx 4 mēneši atpakaļ
vecāks
revīzija
e628d8ac50
20 mainītis faili ar 1126 papildinājumiem un 14 dzēšanām
  1. 19 0
      alien-entity/src/main/java/shop/alien/entity/store/LifeUserOrder.java
  2. 60 0
      alien-entity/src/main/java/shop/alien/entity/store/OrderCouponMiddle.java
  3. 83 0
      alien-entity/src/main/java/shop/alien/entity/store/dto/LifeUserOrderDto.java
  4. 74 0
      alien-entity/src/main/java/shop/alien/entity/store/vo/LifeUserOrderVo.java
  5. 6 0
      alien-entity/src/main/java/shop/alien/entity/store/vo/OrderCouponMiddleVo.java
  6. 27 0
      alien-entity/src/main/java/shop/alien/mapper/LifeUserOrderMapper.java
  7. 8 0
      alien-entity/src/main/java/shop/alien/mapper/OrderCouponMiddleMapper.java
  8. 1 1
      alien-entity/src/main/java/shop/alien/mapper/StoreIncomeDetailsRecordMapper.java
  9. 97 0
      alien-entity/src/main/resources/mapper/LifeUserOrderMapper.xml
  10. 67 0
      alien-job/src/main/java/shop/alien/job/store/LifeUserOrderJob.java
  11. 210 0
      alien-store/src/main/java/shop/alien/store/controller/LifeUserOrderController.java
  12. 70 0
      alien-store/src/main/java/shop/alien/store/controller/PlatformOrderController.java
  13. 1 8
      alien-store/src/main/java/shop/alien/store/controller/StoreIncomeDetailsRecordController.java
  14. 3 1
      alien-store/src/main/java/shop/alien/store/controller/UserOrderController.java
  15. 2 0
      alien-store/src/main/java/shop/alien/store/controller/UserStoreController.java
  16. 316 2
      alien-store/src/main/java/shop/alien/store/service/LifeUserOrderService.java
  17. 8 0
      alien-store/src/main/java/shop/alien/store/service/OrderCouponMiddleService.java
  18. 13 0
      alien-store/src/main/java/shop/alien/store/service/impl/OrderCouponMiddleServiceImpl.java
  19. 2 2
      alien-store/src/main/java/shop/alien/store/service/impl/StoreIncomeDetailsRecordServiceImpl.java
  20. 59 0
      alien-util/src/main/java/shop/alien/util/common/constant/OrderStatusEnum.java

+ 19 - 0
alien-entity/src/main/java/shop/alien/entity/store/LifeUserOrder.java

@@ -45,6 +45,25 @@ public class LifeUserOrder {
 
     private Date refundTime;
 
+    /**
+     * 购买类型(订单类型,0,代金券;1,团购订单)
+     */
+    private Integer couponType;
+
+
+    @ApiModelProperty(value = "取消时间")
+    @TableField("cancel_time")
+    private Date cancelTime;
+    /**
+     * 取消原因
+     */
+    @ApiModelProperty(value = "取消原因")
+    @TableField("cancel_reason")
+    private String cancelReason;
+
+    @ApiModelProperty(value = "结束时间")
+    private Date finishTime;
+
     @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
     @TableField("delete_flag")
     @TableLogic

+ 60 - 0
alien-entity/src/main/java/shop/alien/entity/store/OrderCouponMiddle.java

@@ -0,0 +1,60 @@
+package shop.alien.entity.store;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+@JsonInclude
+@TableName("order_coupon_middle")
+public class OrderCouponMiddle {
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    private String couponCode; // 券编号
+
+    private String orderId; // 订单id
+
+    private Integer status; // 订单状态,0.待使用, 1.已核销, 2.已过期, 3.待退款,4.已退款,5.退款失败,6.已取消,
+
+    private BigDecimal price; // 券价格
+
+    private String refundReason; // 退款原因
+
+    @TableField(exist = false)
+    private Integer count;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Long usedTime; // 使用时间
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Long refundTime; // 退款时间
+    private Integer couponId; // 团购/代金券id
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+}

+ 83 - 0
alien-entity/src/main/java/shop/alien/entity/store/dto/LifeUserOrderDto.java

@@ -0,0 +1,83 @@
+package shop.alien.entity.store.dto;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 用户订单
+ */
+@Data
+@JsonInclude
+@ApiModel(description = "订单接收参数用")
+public class LifeUserOrderDto {
+
+    @TableId(value = "id", type = IdType.AUTO)
+    @ApiModelProperty(value = "订单id")
+    private Integer id;
+
+    @ApiModelProperty(value = "用户id")
+    private String userId;
+
+    @ApiModelProperty(value = "商户id")
+    private String storeId;
+
+    @ApiModelProperty(value = "订单编号")
+    private String orderNo;
+
+    @ApiModelProperty(value = "优惠券id")
+    private String yhquanId;
+
+    @ApiModelProperty(value = "优惠券码(没用)")
+    private String couponCode;
+
+    @ApiModelProperty(value = "订单状态")
+    private Integer status;
+
+    @ApiModelProperty(value = "团购/代金券id")
+    private Integer couponId;
+
+    @ApiModelProperty(value = "购买类型(订单类型,0,代金券;1,团购订单)")
+    private Integer couponType;
+
+    @ApiModelProperty(value = "原价")
+    private String price;
+
+    @ApiModelProperty(value = "付款金额")
+    private String finalPrice;
+
+    @ApiModelProperty(value = "购买数量")
+    private Integer count;
+
+    @ApiModelProperty(value = "付款方式")
+    private String payMethod;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+}

+ 74 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/LifeUserOrderVo.java

@@ -5,9 +5,11 @@ import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+import shop.alien.entity.store.OrderCouponMiddle;
 
 import java.math.BigDecimal;
 import java.util.Date;
+import java.util.List;
 
 /**
  * 用户订单
@@ -59,6 +61,78 @@ public class LifeUserOrderVo {
 
     private Integer count;
 
+    private String storeName;
+
+    private Integer couponCount;
+
+    private Integer couponType;
+
+    private BigDecimal nominalValue;
+
+    private String imgUrl;
+
+    private String userName;
+
+    private String storeAddress;
+
+    /**
+     * 距离
+     */
+    private String dist;
+
+    @ApiModelProperty(value = "取消时间")
+    private Date cancelTime;
+
+    @ApiModelProperty(value = "取消原因")
+    private String cancelReason;
+
+    @ApiModelProperty(value = "结束时间")
+    private Date finishTime;
+
+    @ApiModelProperty(value = "佣金比例")
+    private String commissionRate;
+
+    @ApiModelProperty(value = "订单优惠券中间表")
+    List<OrderCouponMiddle> orderCouponMiddleList;
+
+    @ApiModelProperty(value = "退款列表")
+    List<OrderCouponMiddle> refundList;
+
+    @ApiModelProperty(value = "预期收入")
+    private BigDecimal expectIncome;
+
+    @ApiModelProperty(value = "有效日期类型")
+    private Integer effectiveDateType;
+
+    @ApiModelProperty(value = "有效日期")
+    private Integer effectiveDateValue;
+
+    @ApiModelProperty(value = "使用规则")
+    private String useRules;
+
+    @ApiModelProperty(value = "适用人数")
+    private Integer applicableNum;
+
+    @ApiModelProperty(value = "优惠券额度类型")
+    private Integer quotaType;
+
+    @ApiModelProperty(value = "限购数量")
+    private BigDecimal quotaValue;
+
+    @ApiModelProperty(value = "预约规则")
+    private String reservationRules;
+
+    @ApiModelProperty(value = "营业时间类型")
+    private String businessType;
+    @ApiModelProperty(value = "营业日")
+    private String businessDate;
+    @ApiModelProperty(value = "营业开始时间")
+    private String startTime;
+    @ApiModelProperty(value = "营业结束时间")
+    private String endTime;
+
+
+
     @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
     @TableField("delete_flag")
     @TableLogic

+ 6 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/OrderCouponMiddleVo.java

@@ -0,0 +1,6 @@
+package shop.alien.entity.store.vo;
+
+import shop.alien.entity.store.OrderCouponMiddle;
+
+public class OrderCouponMiddleVo extends OrderCouponMiddle {
+}

+ 27 - 0
alien-entity/src/main/java/shop/alien/mapper/LifeUserOrderMapper.java

@@ -2,6 +2,7 @@ package shop.alien.mapper;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Constants;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
@@ -25,4 +26,30 @@ public interface LifeUserOrderMapper extends BaseMapper<LifeUserOrder> {
 
     @Select("SELECT quan_id quanId, count(id) count FROM life_user_order ${ew.customSqlSegment}")
     List<LifeUserOrderVo> getQuanCount(@Param(Constants.WRAPPER) QueryWrapper<LifeUserOrderVo> queryWrapper);
+
+    LifeUserOrderVo queryUserOrderDetail(@Param("orderId") String orderId,@Param("position") String position);
+
+    @Select("with total_coupon as(\n" +
+            "-- 团购\n" +
+            "\tselect id coupon_id,1 coupon_type,lgbm.group_name coupon_name, SUBSTRING_INDEX(image_id, ',', 1) AS image_id \n" +
+            "from life_group_buy_main lgbm where lgbm.delete_flag = 0\n" +
+            "\tunion all\n" +
+            "-- 代金券\n" +
+            "\tselect id coupon_id,0 coupon_type,lc.name coupon_name, SUBSTRING_INDEX(image_path, ',', 1) AS image_id \n" +
+            "from life_coupon lc where lc.delete_flag = 0\n" +
+            ")\n" +
+            "select luo.id,luo.buy_time,luo.status,luo.price,luo.final_price,luo.user_id,luo.store_id,luo.order_no,luo.pay_time,luo.cancel_time,luo.finish_time,\n" +
+            "si.store_name,si.commission_rate,\n" +
+            "count(ocm.coupon_code) coupon_count,\n" +
+            "simg.img_url,\n" +
+            "lu.user_phone,\n" +
+            "tc.*\n" +
+            "from life_user_order luo\n" +
+            "left join store_info si on si.id = luo.store_id and si.delete_flag = 0 -- 查询店铺相关 \n" +
+            "left join life_user lu on lu.id = luo.user_id and lu.delete_flag = 0 -- 查询用户相关 \n" +
+            "left join order_coupon_middle ocm on ocm.order_id = luo.id and ocm.delete_flag = 0\n" +
+            "inner join total_coupon tc on tc.coupon_id = ocm.coupon_id and tc.coupon_type = luo.coupon_type\n" +
+            "left join  store_img simg on simg.id = tc.image_id and simg.delete_flag = 0 \n" +
+            "${ew.customSqlSegment}")
+    IPage<LifeUserOrderVo> queryUserOrderList(IPage<LifeUserOrderVo> brandedPage,@Param(Constants.WRAPPER) QueryWrapper<LifeUserOrderVo> lifeUserOrderQueryWrapper);
 }

+ 8 - 0
alien-entity/src/main/java/shop/alien/mapper/OrderCouponMiddleMapper.java

@@ -0,0 +1,8 @@
+package shop.alien.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import shop.alien.entity.store.OrderCouponMiddle;
+import shop.alien.entity.store.StoreMenu;
+
+public interface OrderCouponMiddleMapper extends BaseMapper<OrderCouponMiddle> {
+}

+ 1 - 1
alien-entity/src/main/java/shop/alien/mapper/StoreIncomeDetailsRecordMapper.java

@@ -25,7 +25,7 @@ public interface StoreIncomeDetailsRecordMapper extends BaseMapper<StoreIncomeDe
             "join store_info store on store.id = income.store_id " +
             "left join life_user_order uorder on uorder.id = income.user_order_id " +
             "left join life_coupon coupon on coupon.id = uorder.quan_id " +
-            "left join life_refund_order lfo on coupon.id = lfo.order_id and lfo.status = 0 " +
+            "left join life_refund_order lfo on uorder.id = lfo.order_id and lfo.status = 0 " +
             "${ew.customSqlSegment}")
     List<StoreIncomeDetailsRecordVo> getIncomeList(@Param(Constants.WRAPPER) QueryWrapper<StoreIncomeDetailsRecordVo> wrapper);
 

+ 97 - 0
alien-entity/src/main/resources/mapper/LifeUserOrderMapper.xml

@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="shop.alien.mapper.LifeUserOrderMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="shop.alien.entity.store.vo.LifeUserOrderVo">
+        <id column="id" property="id" />
+        <result column="order_no" property="orderNo"/>
+        <result column="created_time" property="createdTime"/>
+        <result column="price" property="price"/>
+        <result column="final_price" property="finalPrice"/>
+        <result column="coupon_name" property="couponName"/>
+        <result column="nominal_value" property="nominalValue"/>
+        <result column="user_phone" property="userPhone"/>
+        <result column="commission_rate" property="commissionRate"/>
+        <result column="img_url" property="imgUrl"/>
+        <result column="pay_method" property="payMethod"/>
+        <result column="buy_time" property="buyTime"/>
+        <result column="cancel_time" property="cancelTime"/>
+        <result column="pay_time" property="payTime"/>
+        <result column="finish_time" property="finishTime"/>
+        <result column="coupon_type" property="couponType"/>
+        <result column="offprice" property="finalPrice"/>
+        <result column="store_id" property="storeId"/>
+        <result column="store_name" property="storeName"/>
+        <result column="commission_rate" property="commissionRate"/>
+        <result column="img_url" property="imgUrl"/>
+        <result column="user_name" property="userName"/>
+        <result column="order_status" property="status"/>
+        <result column="dist" property="dist"/>
+        <result column="store_address" property="storeAddress"/>
+        <result column="effective_date_type" property="effectiveDateType"/>
+        <result column="effective_date_value" property="effectiveDateValue"/>
+        <result column="use_rules" property="useRules"/>
+        <result column="applicable_num" property="applicableNum"/>
+        <result column="quota_type" property="quotaType"/>
+        <result column="quota_value" property="quotaValue"/>
+
+        <result column="business_type" property="businessType"/>
+        <result column="business_date" property="businessDate"/>
+        <result column="start_time" property="startTime"/>
+        <result column="end_time" property="endTime"/>
+
+        <collection property="orderCouponMiddleList" ofType="shop.alien.entity.store.vo.OrderCouponMiddleVo">
+            <id column="ocmId" property="id" />
+            <result column="status" property="status"/>
+            <result column="coupon_code" property="couponCode"/>
+            <result column="refund_time" property="refundTime"/>
+            <result column="refund_reason" property="refundReason"/>
+            <result column="refundPrice" property="price"/>
+        </collection>
+    </resultMap>
+
+
+    <!-- 查询用户订单详情 -->
+    <select id="queryUserOrderDetail" resultMap="BaseResultMap">
+        with total_coupon as(
+        select id coupon_id,1 coupon_type,lgbm.group_name coupon_name,preferential_price offprice,SUBSTRING_INDEX(image_id, ',', 1) AS image_id,
+               effective_date_type,effective_date_value,use_rules,reservation_rules,applicable_num,quota_type,quota_value
+        from life_group_buy_main lgbm where lgbm.delete_flag = 0
+        union all
+        select id coupon_id,0 coupon_type,lc.name coupon_name,lc.offprice offprice,SUBSTRING_INDEX(image_path, ',', 1) AS image_id,
+               0 effective_date_type,expiration_date effective_date_value,use_rule use_rules,reservation_rules,applicable_num,1 quota_type,buy_limit quota_value
+        from life_coupon lc where lc.delete_flag = 0
+        )
+        select luo.id,luo.order_no,luo.created_time , luo.price ,luo.final_price
+        ,luo.pay_method,luo.buy_time,luo.cancel_time,luo.pay_time,luo.finish_time,luo.status order_status,
+        tc.*,
+        ldc.nominal_value,
+        lu.user_phone,lu.user_name,lu.id user_id,
+        ocm.id ocmId,ocm.status,ocm.coupon_code,ocm.refund_time,ocm.refund_reason,ocm.price refundPrice,
+        si.id store_id,si.store_name,si.commission_rate,si.store_address,
+        <if test="position != null and position != ''">
+            ROUND(
+            ST_Distance_Sphere(
+            ST_GeomFromText(CONCAT('POINT(', REPLACE(#{position}, ',', ' '), ')')),
+            ST_GeomFromText(CONCAT('POINT(', REPLACE(si.store_position, ',', ' '), ')'))
+            ) / 1000,
+            2
+            ) AS dist,
+        </if>
+        simg.img_url,
+        sbi.business_type,sbi.business_date,sbi.start_time,sbi.end_time
+        from life_user_order luo
+        left join store_info si on si.id = luo.store_id and si.delete_flag = 0
+        left join order_coupon_middle ocm on ocm.order_id = luo.id and ocm.delete_flag = 0
+        left join total_coupon tc on tc.coupon_id = ocm.coupon_id and tc.coupon_type = luo.coupon_type
+        left join life_discount_coupon ldc on ldc.id = luo.quan_id and ldc.delete_flag = 0
+        left join life_user lu on lu.id = luo.user_id and lu.delete_flag = 0
+        left join store_img simg on simg.id = tc.image_id and simg.delete_flag = 0
+        left join store_business_info sbi on sbi.store_id = si.id and sbi.delete_flag = 0
+        where luo.id = #{orderId}
+        order by luo.created_time desc
+    </select>
+</mapper>

+ 67 - 0
alien-job/src/main/java/shop/alien/job/store/LifeUserOrderJob.java

@@ -0,0 +1,67 @@
+package shop.alien.job.store;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+import shop.alien.entity.store.LifeUserOrder;
+import shop.alien.entity.store.OrderCouponMiddle;
+import shop.alien.mapper.LifeUserOrderMapper;
+import shop.alien.mapper.OrderCouponMiddleMapper;
+import shop.alien.util.common.constant.OrderStatusEnum;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 用户订单任务
+ * 待支付订单超时处理
+ *
+ * @author lyx
+ * @date 2023/12/20 14:20
+ * @see shop.alien.entity.store.LifeUserOrder
+ */
+
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class LifeUserOrderJob {
+
+    private final LifeUserOrderMapper lifeUserOrderMapper;
+    private final OrderCouponMiddleMapper orderCouponMiddleMapper;
+
+    /**
+     * 待支付订单超时处理
+     */
+    @XxlJob("autoCancelUnpaidOrders")
+    public String autoCancelUnpaidOrders(){
+        //1.查询待支付超时订单
+        List<LifeUserOrder> lifeUserOrders = lifeUserOrderMapper.selectList(new LambdaQueryWrapper<LifeUserOrder>()
+                .eq(LifeUserOrder::getStatus, OrderStatusEnum.WAIT_PAY.getStatus())
+                .le(LifeUserOrder::getBuyTime, LocalDateTime.now().minusMinutes(15)));
+        if( CollectionUtils.isEmpty(lifeUserOrders) ){
+            return "无待支付超时订单";
+        }
+        //2.超时则取消订单id
+        List<String> orderIds = lifeUserOrders.stream().map(LifeUserOrder::getId).collect(Collectors.toList());
+        lifeUserOrderMapper.update(null,new LambdaUpdateWrapper<LifeUserOrder>()
+                .set(LifeUserOrder::getStatus,OrderStatusEnum.CANCEL.getStatus())
+                .set(LifeUserOrder::getCancelTime,LocalDateTime.now())
+                .set(LifeUserOrder::getCancelReason,"订单超时未支付")
+                .in(LifeUserOrder::getId,orderIds));
+        orderCouponMiddleMapper.selectList(new LambdaQueryWrapper<OrderCouponMiddle>()
+                .in(OrderCouponMiddle::getOrderId,orderIds));
+        List<Map<String, Object>> maps = orderCouponMiddleMapper.selectMaps(new QueryWrapper<OrderCouponMiddle>()
+                .select("coupon_id", "count(*) as count")
+                .in("order_id", orderIds)
+                .groupBy("coupon_id"));
+        //3.更改相对应的券状态
+        return null;
+    }
+}

+ 210 - 0
alien-store/src/main/java/shop/alien/store/controller/LifeUserOrderController.java

@@ -0,0 +1,210 @@
+package shop.alien.store.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.*;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.map.HashedMap;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+import shop.alien.entity.result.BusinessException;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.LifeCoupon;
+import shop.alien.entity.store.LifeGroupBuyMain;
+import shop.alien.entity.store.LifeUserOrder;
+import shop.alien.entity.store.OrderCouponMiddle;
+import shop.alien.entity.store.dto.LifeUserOrderDto;
+import shop.alien.entity.store.vo.LifeUserOrderVo;
+import shop.alien.mapper.LifeCouponMapper;
+import shop.alien.mapper.LifeGroupBuyMainMapper;
+import shop.alien.mapper.LifeUserOrderMapper;
+import shop.alien.mapper.OrderCouponMiddleMapper;
+import shop.alien.store.service.LifeUserOrderService;
+import shop.alien.util.common.AlipayTradeAppPay;
+import shop.alien.util.common.UniqueRandomNumGenerator;
+import shop.alien.util.common.constant.OrderStatusEnum;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Api(tags = {"2.5期-订单"})
+@Slf4j
+@CrossOrigin
+@RestController
+@RequestMapping("/userOrder")
+@RequiredArgsConstructor
+public class LifeUserOrderController {
+
+    private final LifeUserOrderService lifeUserOrderService;
+    private final LifeUserOrderMapper lifeUserOrderMapper;
+    private final OrderCouponMiddleMapper orderCouponMiddleMapper;
+    private final LifeCouponMapper lifeCouponMapper;
+    private final LifeGroupBuyMainMapper lifeGroupBuyMainMapper;
+
+    @ApiOperation("获取支付信息")
+    @ApiOperationSupport(order = 4)
+    @ApiImplicitParams({@ApiImplicitParam(name = "payPrice", value = "payPrice", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "quanName", value = "quanName", dataType = "String", paramType = "query")})
+    @GetMapping("/getOrderStrForPay")
+    public R<Map<String, Object>> getOrderStrForPay(@RequestParam("payPrice") String payPrice,
+                                                    @RequestParam("quanName") String quanName) {
+        log.info("LifeUserStoreController.getOrderStrForPay?payPrice={},quanName={}", payPrice, quanName);
+        String orderNo = UniqueRandomNumGenerator.generateUniqueCode(19);
+        String orderStr = AlipayTradeAppPay.executeAlipayPayment(orderNo, payPrice, quanName);
+        if (!orderStr.equals("调用失败") && !orderStr.isEmpty()) {
+            Map<String, Object> returnMap = new HashedMap<>();
+            returnMap.put("orderStr", orderStr);
+            returnMap.put("orderNo", orderNo);
+            return R.data(returnMap);
+        } else {
+            return R.fail("支付失败");
+        }
+    }
+
+
+    @ApiOperation("创建订单")
+    @ApiOperationSupport(order = 1)
+    @PostMapping("/createUserOrder")
+    public R<Map<String, Object>> createUserOrder(@RequestBody LifeUserOrderDto LifeUserOrderDto) {
+        log.info("userOrder.createUserOrder:{}", LifeUserOrderDto);
+        return R.data(lifeUserOrderService.createUserOrder(LifeUserOrderDto));
+    }
+
+    @ApiOperation("更新订单")
+    @ApiOperationSupport(order = 2)
+    @PostMapping("/updateUserOrder")
+    public R<Map<String, Object>> updateUserOrder(@RequestBody LifeUserOrderDto LifeUserOrderDto) {
+        log.info("userOrder.updateUserOrder:{}", LifeUserOrderDto);
+        if (!lifeUserOrderService.updateUserOrder(LifeUserOrderDto)) {
+            return R.fail("更新失败");
+        }
+        return R.success("更新成功");
+
+    }
+
+
+    @ApiOperation("删除订单")
+    @ApiOperationSupport(order = 3)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "orderId", value = "订单id", required = true)
+    })
+    @DeleteMapping("/deleteUserOrder")
+    public R<Map<String, Object>> deleteUserOrder(@RequestParam(value = "orderId") String orderId) {
+        log.info("userOrder.deleteUserOrder:{}", orderId);
+        if (!lifeUserOrderService.deleteUserOrder(orderId)) {
+            return R.fail("删除失败");
+        }
+        return R.success("删除成功");
+    }
+
+    @ApiOperation("查询订单列表")
+    @ApiOperationSupport(order = 5)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page", value = "当前页", required = true),
+            @ApiImplicitParam(name = "size", value = "每页数量", required = true),
+            @ApiImplicitParam(name = "userId", value = "用户id", required = false),
+            @ApiImplicitParam(name = "storeId", value = "商户id", required = false),
+            @ApiImplicitParam(name = "couponType", value = "订单类型,-1,全部(可以不传),0,代金券;1,团购;", required = false),
+            @ApiImplicitParam(name = "orderStatus", value = "订单状态,-1,全部(可以不传);0,待支付;1,已支付/待使用;2,已核销;3,已过期;4,已取消;5.已退款,全退款了才算", required = false),
+            @ApiImplicitParam(name = "name", value = "订单名称", required = false)
+    })
+    @GetMapping("/queryUserOrderList")
+    public R<IPage<LifeUserOrderVo>> queryUserOrderList(@RequestParam(value = "page", defaultValue = "1") Integer page,
+                                                        @RequestParam(value = "size", defaultValue = "10") Integer size,
+                                                        @RequestParam(required = false) String userId,
+                                                        @RequestParam(required = false) String storeId,
+                                                        @RequestParam(required = false, defaultValue = "-1") String couponType,
+                                                        @RequestParam(required = false, defaultValue = "-1") String orderStatus,
+                                                        @RequestParam(required = false) String name,
+                                                        @RequestParam(value = "startTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd 00:00:00") String startTime,
+                                                        @RequestParam(value = "endTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd 23:59:59") String endTime) {
+        log.info("userOrder.queryUserOrderList:page={}&size={}&userId={}&storeId={}&orderType={}&orderStatus={}&name={}&startTime={}&endTime={}", page, size, userId, storeId, couponType, orderStatus, name, startTime, endTime);
+        if (StringUtils.isNotBlank(userId) && StringUtils.isNotBlank(storeId)) {
+            return R.fail("用户id和商户id不能同时为空");
+        }
+        return R.data(lifeUserOrderService.queryUserOrderList(page, size, userId, storeId, couponType, orderStatus, name, startTime, endTime));
+    }
+
+    @ApiOperation("查询订单详情")
+    @ApiOperationSupport(order = 6)
+    @ApiImplicitParams({@ApiImplicitParam(name = "longitude", value = "经度", dataType = "String", paramType = "query", required = false),
+            @ApiImplicitParam(name = "latitude", value = "纬度", dataType = "String", paramType = "query", required = false),
+            @ApiImplicitParam(name = "orderId", value = "订单id", dataType = "String", paramType = "query", required = true)})
+    @GetMapping("/queryUserOrderDetail")
+    public R queryUserOrderDetail(@RequestParam String orderId,
+                                  @RequestParam(value = "longitude", required = false) String longitude,
+                                  @RequestParam(value = "latitude", required = false) String latitude) {
+        log.info("userOrder.queryUserOrderDetail:orderId={}&longitude={}&latitude={}", orderId, longitude, latitude);
+        return lifeUserOrderService.queryUserOrderDetail(orderId, longitude, latitude);
+    }
+
+
+    @GetMapping("/test")
+    public String get() {
+        //1.查询待支付超时订单
+        List<LifeUserOrder> lifeUserOrders = lifeUserOrderMapper.selectList(new LambdaQueryWrapper<LifeUserOrder>()
+                .eq(LifeUserOrder::getStatus, OrderStatusEnum.WAIT_PAY.getStatus())
+                .le(LifeUserOrder::getBuyTime, LocalDateTime.now().minusMinutes(15)));
+        if( CollectionUtils.isEmpty(lifeUserOrders) ){
+            return "无待支付超时订单";
+        }
+        //2.超时则取消订单id
+        List<String> orderIds = lifeUserOrders.stream().map(LifeUserOrder::getId).collect(Collectors.toList());
+        lifeUserOrderMapper.update(null,new LambdaUpdateWrapper<LifeUserOrder>()
+                .set(LifeUserOrder::getStatus,OrderStatusEnum.CANCEL.getStatus())
+                .set(LifeUserOrder::getCancelTime,LocalDateTime.now())
+                .set(LifeUserOrder::getCancelReason,"订单超时未支付")
+                .in(LifeUserOrder::getId,orderIds));
+        // 根据类型分组
+        Map<Integer, List<String>> collect = lifeUserOrders.stream()
+                .collect(Collectors.groupingBy(
+                        LifeUserOrder::getCouponType,  // 按订单类型分组
+                        Collectors.mapping(  // 对每个分组中的元素提取ID
+                                LifeUserOrder::getId,
+                                Collectors.toList()
+                        )
+                ));
+        int updateNum = 0;
+        if(collect.containsKey(0)){
+            //3.1代金券订单
+            List<String> couponOrderIds = collect.get(0);
+            QueryWrapper<OrderCouponMiddle> queryWrapper = new QueryWrapper<OrderCouponMiddle>().in("order_id", couponOrderIds)
+                    .eq("status", 0)
+                    .groupBy("coupon_id")  // 按coupon_id分组
+                    .select("coupon_id, COUNT(*) as count");  // 选择分组字段和统计数量
+            List<OrderCouponMiddle> orderCouponMiddles = orderCouponMiddleMapper.selectList(queryWrapper);
+            for (OrderCouponMiddle orderCouponMiddle : orderCouponMiddles) {
+                // 恢复库存
+                updateNum += lifeCouponMapper.update(null, new LambdaUpdateWrapper<LifeCoupon>()
+                        .setSql("stock_qty=stock_qty+" + orderCouponMiddle.getCount())
+                        .eq(LifeCoupon::getId, orderCouponMiddle.getCouponId()));
+            }
+        }
+        if(collect.containsKey("1")){
+            //3.2团购订单
+            List<String> groupOrderIds = collect.get(1);
+            QueryWrapper<OrderCouponMiddle> queryWrapper = new QueryWrapper<OrderCouponMiddle>().in("order_id", groupOrderIds)
+                    .eq("status", 0)
+                    .groupBy("coupon_id")  // 按coupon_id分组
+                    .select("coupon_id, COUNT(*) as count");
+            List<OrderCouponMiddle> orderCouponMiddles = orderCouponMiddleMapper.selectList(queryWrapper);
+            for (OrderCouponMiddle orderCouponMiddle : orderCouponMiddles) {
+                // 恢复库存
+                updateNum += lifeGroupBuyMainMapper.update(null,new LambdaUpdateWrapper<LifeGroupBuyMain>()
+                        .setSql("stock_qty=stock_qty+" + orderCouponMiddle.getCount())
+                        .eq(LifeGroupBuyMain::getId, orderCouponMiddle.getCouponId()));
+            }
+        }
+        if(updateNum!=lifeUserOrders.size()){
+            throw new BusinessException("恢复团购库存失败");
+        }
+        return "success";
+    }
+}

+ 70 - 0
alien-store/src/main/java/shop/alien/store/controller/PlatformOrderController.java

@@ -0,0 +1,70 @@
+package shop.alien.store.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.*;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.*;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.vo.LifeUserOrderVo;
+import shop.alien.store.service.LifeUserOrderService;
+
+@Api(tags = {"二期平台-订单管理"})
+@Slf4j
+@RestController
+@CrossOrigin
+@RequestMapping("/platformLifeUserOrder")
+@RequiredArgsConstructor
+public class PlatformOrderController {
+
+    private final LifeUserOrderService lifeUserOrderService;
+
+
+
+    @ApiOperation("查询订单列表")
+    @ApiOperationSupport(order = 5)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page", value = "当前页", required = true),
+            @ApiImplicitParam(name = "size", value = "每页数量", required = true),
+            @ApiImplicitParam(name = "orderStatus", value = "订单状态,-1,全部(可以不传);0,待支付;1,已支付/待使用;2,已核销;3,已过期;4,已取消;5.已退款,全退款了才算", required = false),
+            @ApiImplicitParam(name = "orderNo", value = "订单号", required = false),
+            @ApiImplicitParam(name = "couponName", value = "优惠券名称", required = false),
+            @ApiImplicitParam(name = "couponType", value = "优惠券类型", required = false),
+            @ApiImplicitParam(name = "storeName", value = "门店名称", required = false),
+            @ApiImplicitParam(name = "buyStartTime", value = "购买时间开始", required = false),
+            @ApiImplicitParam(name = "buyEndTime", value = "购买时间结束", required = false),
+            @ApiImplicitParam(name = "payStartTime", value = "支付时间开始", required = false),
+            @ApiImplicitParam(name = "payEndTime", value = "支付时间结束", required = false),
+            @ApiImplicitParam(name = "finishStartTime", value = "核销时间开始", required = false),
+            @ApiImplicitParam(name = "finishEndTime", value = "核销时间结束", required = false),
+    })
+    @GetMapping("/queryOrderList")
+    public R<IPage<LifeUserOrderVo>> queryOrderList(@RequestParam(value = "page", defaultValue = "1") Integer page,
+                                                        @RequestParam(value = "size", defaultValue = "10") Integer size,
+                                                        @RequestParam(value = "orderNo", required = false) String orderNo,
+                                                        @RequestParam(required = false, defaultValue = "-1") String orderStatus,
+                                                        @RequestParam(required = false) String couponName,
+                                                        @RequestParam(required = false) String couponType,
+                                                        @RequestParam(required = false) String storeName,
+                                                        @RequestParam(value = "buyStartTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd 00:00:00")String buyStartTime,
+                                                        @RequestParam(value = "buyEndTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd 23:59:59") String buyEndTime,
+                                                        @RequestParam(value = "payStartTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd 00:00:00")String payStartTime,
+                                                        @RequestParam(value = "payEndTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd 23:59:59") String payEndTime,
+                                                        @RequestParam(value = "finishStartTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd 00:00:00")String finishStartTime,
+                                                        @RequestParam(value = "finishEndTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd 23:59:59") String finishEndTime
+                                                        ) {
+            log.info("查询订单列表,page={},size={},orderNo={},orderStatus={},couponName={},couponType={},storeName={},buyStartTime={},buyEndTime={},payStartTime={},payEndTime={},finishStartTime={},finishEndTime={}",
+                    page, size, orderNo, orderStatus, couponName, couponType, storeName, buyStartTime, buyEndTime, payStartTime, payEndTime, finishStartTime, finishEndTime);
+        return R.data(lifeUserOrderService.queryOrderList(page, size, orderNo, orderStatus, couponName, couponType, storeName, buyStartTime, buyEndTime, payStartTime, payEndTime, finishStartTime, finishEndTime));
+    }
+
+    @ApiOperation("查询订单详情")
+    @ApiOperationSupport(order = 6)
+    @GetMapping("/queryOrderDetail")
+    public R queryOrderDetail(@RequestParam String orderId) {
+        log.info("userOrder.queryOrderDetail:{}", orderId);
+        return lifeUserOrderService.queryOrderDetail(orderId);
+    }
+}

+ 1 - 8
alien-store/src/main/java/shop/alien/store/controller/StoreIncomeDetailsRecordController.java

@@ -9,7 +9,7 @@ import shop.alien.entity.result.R;
 import shop.alien.entity.store.StoreIncomeDetailsRecord;
 import shop.alien.entity.store.vo.StoreIncomeDetailsRecordVo;
 import shop.alien.store.service.StoreIncomeDetailsRecordService;
-import shop.alien.store.task.ScheduledTask;
+
 
 import java.util.Map;
 
@@ -30,7 +30,6 @@ public class StoreIncomeDetailsRecordController {
 
     private final StoreIncomeDetailsRecordService storeIncomeDetailsRecordService;
 
-    private final ScheduledTask scheduledTask;
 
     @ApiOperation("提现-提现全部/部分提现")
     @ApiOperationSupport(order = 1)
@@ -128,10 +127,4 @@ public class StoreIncomeDetailsRecordController {
         return R.data(storeIncomeDetailsRecordService.groupIncome(storeId, date, incomeType,page,size));
     }
 
-    //团购详情
-
-    @GetMapping("/autoTransferAccounts")
-    public void autoTransferAccounts() {
-        scheduledTask.autoTransferAccounts();
-    }
 }

+ 3 - 1
alien-store/src/main/java/shop/alien/store/controller/UserOrderController.java

@@ -33,6 +33,7 @@ public class UserOrderController {
             @ApiImplicitParam(name = "quanName", value = "quanName", dataType = "String", paramType = "query"),
             @ApiImplicitParam(name = "storeType", value = "storeType", dataType = "String", paramType = "query")})
     @GetMapping("/getOrderListByStatus")
+    @Deprecated
     public R<IPage<Map<String, Object>>> getOrderListByStatus(@RequestParam(value = "page", defaultValue = "1") Integer page,
                                                               @RequestParam(value = "size", defaultValue = "10") Integer size,
                                                               @RequestParam(required = false) String userId,
@@ -54,6 +55,7 @@ public class UserOrderController {
             @ApiImplicitParam(name = "jingdu", value = "jingdu", dataType = "String", paramType = "query"),
             @ApiImplicitParam(name = "weidu", value = "weidu", dataType = "String", paramType = "query")})
     @GetMapping("/getOrderByOrderId")
+    @Deprecated
     public R<Map<String, Object>> getOrderByOrderId(@RequestParam(required = false) String orderId,
                                                     @RequestParam(required = false) String jingdu,
                                                     @RequestParam(required = false) String weidu) {
@@ -76,7 +78,7 @@ public class UserOrderController {
 
     @ApiOperation("订单是否可以退款")
     @ApiOperationSupport(order = 4)
-    @PostMapping("/refundCheck")
+    @PostMapping("/refundCfheck")
     public R<Map<String, Object>> refundCheck(LifeRefundOrder refundOrder) {
         log.info("UserOrderController.refundCheck?refundOrder={}", refundOrder.toString());
         return R.data(userOrderService.refundCheck(refundOrder));

+ 2 - 0
alien-store/src/main/java/shop/alien/store/controller/UserStoreController.java

@@ -82,6 +82,7 @@ public class UserStoreController {
     @ApiImplicitParams({@ApiImplicitParam(name = "payPrice", value = "payPrice", dataType = "String", paramType = "query"),
             @ApiImplicitParam(name = "quanName", value = "quanName", dataType = "String", paramType = "query")})
     @GetMapping("/getOrderStrForPay")
+    @Deprecated
     public R<Map<String, Object>> getOrderStrForPay(@RequestParam("payPrice") String payPrice,
                                                     @RequestParam("quanName") String quanName) {
         log.info("LifeUserStoreController.getOrderStrForPay?payPrice={},quanName={}", payPrice, quanName);
@@ -106,6 +107,7 @@ public class UserStoreController {
             @ApiImplicitParam(name = "payPrice", value = "payPrice", dataType = "String", paramType = "query"),
             @ApiImplicitParam(name = "orderNo", value = "orderNo", dataType = "String", paramType = "query")})
     @GetMapping("/buyQuan")
+    @Deprecated
     public R<Map<String, Object>> buyQuan(@RequestParam("quanId") String quanId,
                                           @RequestParam("couponId") String couponId,
                                           @RequestParam("userId") String userId,

+ 316 - 2
alien-store/src/main/java/shop/alien/store/service/LifeUserOrderService.java

@@ -3,20 +3,30 @@ package shop.alien.store.service;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import shop.alien.entity.result.BusinessException;
+import shop.alien.entity.result.R;
 import shop.alien.entity.store.*;
+import shop.alien.entity.store.dto.LifeUserOrderDto;
 import shop.alien.entity.store.excelVo.LifeUserOrderExcelVo;
-import shop.alien.entity.store.excelVo.StoreInfoExcelVo;
 import shop.alien.entity.store.excelVo.util.ExcelGenerator;
+import shop.alien.entity.store.vo.LifeUserOrderVo;
 import shop.alien.entity.store.vo.StoreInfoVo;
 import shop.alien.mapper.*;
 import shop.alien.store.config.GaoDeMapUtil;
 import shop.alien.util.ali.AliOSSUtil;
 import shop.alien.util.common.AlipayTradeRefund;
+import shop.alien.util.common.UniqueRandomNumGenerator;
+import shop.alien.util.common.constant.DiscountCouponEnum;
 
 import java.io.File;
 import java.io.IOException;
@@ -32,7 +42,7 @@ import java.util.stream.Collectors;
 
 @Service
 @RequiredArgsConstructor
-public class LifeUserOrderService {
+public class LifeUserOrderService extends ServiceImpl<LifeUserOrderMapper, LifeUserOrder> {
 
     private final LifeUserOrderMapper lifeUserOrderMapper;
 
@@ -61,8 +71,12 @@ public class LifeUserOrderService {
     private final StoreImgMapper storeImgMapper;
 
     private final StoreUserMapper storeUserMapper;
+    private final LifeDiscountCouponUserMapper lifeDiscountCouponUserMapper;
+    private final OrderCouponMiddleService orderCouponMiddleService;
 
     private final AliOSSUtil aliOSSUtil;
+    private final OrderCouponMiddleMapper orderCouponMiddleMapper;
+    private final LifeGroupBuyMainMapper lifeGroupBuyMainMapper;
 
     @Value("${spring.web.resources.excel-path}")
     private String excelPath;
@@ -551,4 +565,304 @@ public class LifeUserOrderService {
         String filePath = ExcelGenerator.generateExcel(excelPath + excelGeneratePath + fileName + ".xlsx", lifeUserOrderExcelVos, LifeUserOrderExcelVo.class);
         return aliOSSUtil.uploadFile(new File(filePath), "excel/" + fileName + ".xlsx");
     }
+
+    /**
+     * 创建用户订单
+     * @param lifeUserOrderDto 构造数据用
+     */
+    @Transactional
+    public Map<String, Object> createUserOrder(LifeUserOrderDto lifeUserOrderDto) {
+        Date date = new Date();
+        //1.创建订单
+        LifeUserOrder lifeUserOrder = new LifeUserOrder();
+        // 用户id
+        lifeUserOrder.setUserId(lifeUserOrderDto.getUserId());
+        // 店铺id
+        lifeUserOrder.setStoreId(lifeUserOrderDto.getStoreId());
+        // 订单号
+        lifeUserOrder.setOrderNo(lifeUserOrderDto.getOrderNo());
+        // 优惠券id
+        lifeUserOrder.setQuanId(lifeUserOrderDto.getYhquanId());
+        // 付款金额
+        lifeUserOrder.setPrice(lifeUserOrderDto.getPrice());
+        // 订单金额
+        lifeUserOrder.setFinalPrice(lifeUserOrderDto.getFinalPrice());
+        // 订单类型
+        lifeUserOrder.setCouponType(null == lifeUserOrderDto.getCouponType() ? 0 : lifeUserOrderDto.getCouponType());
+        // 订单状态
+        lifeUserOrder.setStatus(null == lifeUserOrderDto.getStatus() ? 0 : lifeUserOrderDto.getStatus());
+        // 购买时间
+        lifeUserOrder.setBuyTime(date);
+        this.saveOrUpdate(lifeUserOrder);
+        //2.判断是否使用优惠券
+        //查询优惠券信息
+        if (StringUtils.isNotEmpty(lifeUserOrderDto.getYhquanId())) {
+            LifeDiscountCouponUser lifeDiscountCouponUser = lifeDiscountCouponUserMapper.selectById(lifeUserOrderDto.getYhquanId());
+            //将优惠券状态变更为已使用
+            lifeDiscountCouponUser.setStatus(Integer.parseInt(DiscountCouponEnum.HAVE_BEEN_USED.getValue()));
+            //将优惠券使用时间存入
+            lifeDiscountCouponUser.setUseTime(date);
+            lifeDiscountCouponUserMapper.updateById(lifeDiscountCouponUser);
+        }
+        //3.根据购买数量增加中间关系 订单id+券编号 确定一条数据
+        BigDecimal sumPrice = new BigDecimal(0);
+        for (int i = 0; i < lifeUserOrderDto.getCount(); i++) {
+            String code = UniqueRandomNumGenerator.generateUniqueCode(12);
+            OrderCouponMiddle orderCouponMiddle = new OrderCouponMiddle();
+            // 订单id
+            orderCouponMiddle.setOrderId(lifeUserOrder.getId());
+            // 团购/代金券id
+            orderCouponMiddle.setCouponId(lifeUserOrderDto.getCouponId());
+            // 团购/代金券 code
+            orderCouponMiddle.setCouponCode(code);
+            // 团购/代金券价格
+            if(i == lifeUserOrderDto.getCount() - 1){
+                orderCouponMiddle.setPrice(new BigDecimal(lifeUserOrderDto.getFinalPrice()).subtract(sumPrice).setScale(2,BigDecimal.ROUND_HALF_UP));
+            } else {
+                BigDecimal divide = new BigDecimal(lifeUserOrderDto.getFinalPrice()).divide(new BigDecimal(lifeUserOrderDto.getCount()), 2, BigDecimal.ROUND_HALF_UP);
+                orderCouponMiddle.setPrice(divide);
+                sumPrice = sumPrice.add(divide);
+            }
+            // 订单状态
+            orderCouponMiddle.setStatus(0);
+            orderCouponMiddleService.save(orderCouponMiddle);
+            // 使用时间
+            // 退款时间
+            // 删除标记
+        }
+        //4. 代金券/团购库存扣除 coupon_type 0 代金券 1团购
+        int successful = 0;
+        if(lifeUserOrderDto.getCouponType() == 1){
+            // 团购库存扣除
+            successful = lifeGroupBuyMainMapper.update(null, new UpdateWrapper<LifeGroupBuyMain>()
+                    .eq("id", lifeUserOrderDto.getCouponId()).setSql("inventory_num = inventory_num - " + lifeUserOrderDto.getCount()));
+        } else {
+            successful = lifeCouponMapper.update(null, new UpdateWrapper<LifeCoupon>()
+                    .eq("id", lifeUserOrderDto.getCouponId()).setSql("stock_qty = stock_qty - " + lifeUserOrderDto.getCount()));
+        }
+        if(successful == 0){
+            log.error("库存不足");
+            throw new BusinessException("库存不足");
+        }
+        Map<String, Object> returnMap = new HashMap<>();
+        returnMap.put("success", "下单成功");
+        returnMap.put("orderNo", lifeUserOrderDto.getOrderNo());
+        returnMap.put("lifeUserOrder", lifeUserOrder);
+        return returnMap;
+    }
+
+    /**
+     * 更新用户订单
+     *
+     * @param lifeUserOrderDto 构造数据用
+     */
+    @Transactional
+    public boolean updateUserOrder(LifeUserOrderDto lifeUserOrderDto) {
+        Date date = new Date();
+        LifeUserOrder lifeUserOrder = lifeUserOrderMapper.selectById(lifeUserOrderDto.getId());
+        if ( null == lifeUserOrder){
+            log.error("updateUserOrder未查询到订单");
+            return false;
+        }
+        UpdateWrapper<OrderCouponMiddle> orderCouponMiddleUpdateWrapper = new UpdateWrapper<>();
+        orderCouponMiddleUpdateWrapper.eq("order_id",lifeUserOrderDto.getId());
+        // 根据状态判断怎么更新数据 目前只进行已支付,已取消,已过期判断
+        // TODO 后续再进行已核销和已退款判断 ()
+        switch (lifeUserOrderDto.getStatus()){
+            case 1:
+                lifeUserOrder.setPayTime(date);
+                lifeUserOrder.setPayMethod(lifeUserOrderDto.getPayMethod());
+            case 3:
+            case 4:
+                lifeUserOrder.setStatus(lifeUserOrderDto.getStatus());
+                orderCouponMiddleUpdateWrapper.set("status",lifeUserOrderDto.getStatus());
+                break;
+        }
+
+        return this.saveOrUpdate(lifeUserOrder) && orderCouponMiddleService.update(orderCouponMiddleUpdateWrapper);
+    }
+
+    /**
+     * 删除用户订单,删除需要判断订单状态并且删除中间关系
+     * @param orderId 订单id
+     */
+    @Transactional
+    public boolean deleteUserOrder(String orderId) {
+        LifeUserOrder lifeUserOrder = lifeUserOrderMapper.selectById(orderId);
+        if ( null == lifeUserOrder){
+            log.error("deleteUserOrder未查询到订单");
+            return false;
+        }
+        // 判断订单状态
+        // 已核销才可以删除
+        if (lifeUserOrder.getStatus() != 2) {
+            log.error("deleteUserOrder订单状态错误,订单已核销才可以删除");
+            return false;
+        }
+        // 删除中间关系
+        UpdateWrapper<OrderCouponMiddle> orderCouponMiddleUpdateWrapper = new UpdateWrapper<>();
+        orderCouponMiddleUpdateWrapper.eq("order_id",orderId);
+        return this.removeById(orderId) && orderCouponMiddleService.remove(orderCouponMiddleUpdateWrapper);
+    }
+
+    /**
+     * 查询用户订单列表
+     * @param page 页码
+     * @param size 每页数量
+     * @param userId 用户id
+     * @param couponType 订单类型
+     * @param name 店铺名称
+     */
+    public IPage<LifeUserOrderVo> queryUserOrderList(Integer page, Integer size, String userId, String storeId, String couponType,String orderStatus, String name, String startTime, String endTime) {
+        IPage<LifeUserOrderVo> brandedPage = new Page<>(page, size);
+        QueryWrapper<LifeUserOrderVo> lifeUserOrderQueryWrapper = new QueryWrapper<>();
+        lifeUserOrderQueryWrapper.eq(org.apache.commons.lang3.StringUtils.isNotBlank(userId),"luo.user_id",userId);
+        lifeUserOrderQueryWrapper.eq(org.apache.commons.lang3.StringUtils.isNotBlank(storeId),"luo.store_id",storeId);
+        lifeUserOrderQueryWrapper.eq(null != couponType && !"-1".equals(couponType),"luo.coupon_type",couponType);
+
+        // 提取SQL基础部分,避免重复定义
+        String baseSql = "select DISTINCT ocm1.order_id from order_coupon_middle ocm1 where 1=1";
+
+        if (!"-1".equals(orderStatus)) {
+            // 非-1状态:直接添加状态条件
+            String sql = baseSql + " and ocm1.status = " + orderStatus;
+            lifeUserOrderQueryWrapper.inSql("luo.id", sql);
+        } else {
+            // -1状态且storeId不为空时添加条件
+            if (org.apache.commons.lang3.StringUtils.isNotBlank(storeId)) {
+                // 注意:原代码中的concat不会修改原字符串,需要重新赋值
+                String sql = baseSql + " and ocm1.status != 0";
+                lifeUserOrderQueryWrapper.inSql("luo.id", sql);
+            }
+        }
+        lifeUserOrderQueryWrapper.like(org.apache.commons.lang3.StringUtils.isNotBlank(name),"tc.coupon_name",name);
+        lifeUserOrderQueryWrapper.gt(org.apache.commons.lang3.StringUtils.isNotBlank(startTime),"luo.created_time",startTime + " 00:00:00");
+        lifeUserOrderQueryWrapper.lt(org.apache.commons.lang3.StringUtils.isNotBlank(endTime),"luo.created_time",endTime + " 23:59:59");
+        lifeUserOrderQueryWrapper.orderByDesc("luo.created_time");
+        lifeUserOrderQueryWrapper.groupBy("tc.coupon_type","tc.coupon_id");
+        IPage<LifeUserOrderVo> lifeUserOrderVoIPage = lifeUserOrderMapper.queryUserOrderList(brandedPage, lifeUserOrderQueryWrapper);
+        if (!"-1".equals(orderStatus)) {
+            lifeUserOrderVoIPage.getRecords().forEach(x->x.setStatus(Integer.parseInt(orderStatus)));
+        }
+        // 计算退款金额
+        for (LifeUserOrderVo record : lifeUserOrderVoIPage.getRecords()) {
+            record.setOrderCouponMiddleList(orderCouponMiddleMapper.selectList(new QueryWrapper<OrderCouponMiddle>().eq("order_id",record.getId())));
+            calcExpectIncome(record);
+        }
+        return lifeUserOrderVoIPage;
+    }
+
+    /**
+     * 查询用户订单详情
+     * @param orderId
+     * @return
+     */
+    public R<LifeUserOrderVo> queryUserOrderDetail(String orderId,String longitude, String latitude) {
+        LifeUserOrderVo lifeUserOrderVo = lifeUserOrderMapper.queryUserOrderDetail(orderId,longitude+","+latitude);
+        if ( null == lifeUserOrderVo){
+            log.error("queryUserOrderDetail未查询到订单");
+            return R.fail("未查询到订单");
+        }
+        calcExpectIncome(lifeUserOrderVo);
+        return R.data(lifeUserOrderVo);
+    }
+
+    private static void calcExpectIncome(LifeUserOrderVo lifeUserOrderVo) {
+        // 退款记录
+        List<OrderCouponMiddle> orderCouponMiddleList = lifeUserOrderVo.getOrderCouponMiddleList();
+        List<OrderCouponMiddle> refundList = orderCouponMiddleList.stream().filter(x -> x.getStatus() == 5).collect(Collectors.toList());
+        lifeUserOrderVo.setRefundList(refundList);
+        // 预计收入
+        // 退款金额
+        BigDecimal refundAmount = new BigDecimal(0);
+        if(!CollectionUtils.isEmpty(refundList)){
+            refundAmount = refundList.stream().map(OrderCouponMiddle::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
+        }
+        // 预计收入
+        BigDecimal expectIncome = new BigDecimal(lifeUserOrderVo.getPrice()).subtract(refundAmount);
+        String commissionRateStr = lifeUserOrderVo.getCommissionRate();
+        BigDecimal commissionRate = BigDecimal.ZERO;
+        if (org.apache.commons.lang3.StringUtils.isNotBlank(commissionRateStr)) {
+            try {
+                // 将字符串转换为 BigDecimal,并除以 100(转换为小数)
+                commissionRate = new BigDecimal(commissionRateStr)
+                        .divide(new BigDecimal("100"), 4, RoundingMode.HALF_UP);
+                // 保留 4 位小数,四舍五入(确保计算精度)
+            } catch (NumberFormatException e) {
+                // 处理非数字格式的异常(如 commissionRate 为空或非法字符)
+                e.printStackTrace();
+                // 可根据业务需求设置默认值或抛出提示
+            } catch (ArithmeticException e) {
+                // 处理除法异常(理论上除以 100 不会出现,此处为稳妥处理)
+                e.printStackTrace();
+            }
+        }
+        expectIncome = expectIncome.subtract(expectIncome.multiply(commissionRate)).setScale(2, RoundingMode.HALF_UP);
+        lifeUserOrderVo.setExpectIncome(expectIncome);
+    }
+
+    /**
+     * 平台端-查询订单列表
+     * @param page 页码
+     * @param size 每页数量
+     * @param orderNo 订单号
+     * @param orderStatus 订单状态
+     * @param couponName 优惠券名称
+     * @param couponType 优惠券类型
+     * @param storeName 店铺名称
+     * @param buyStartTime 购买时间开始
+     * @param buyEndTime 购买时间结束
+     * @param payStartTime 支付时间开始
+     * @param payEndTime 支付时间结束
+     * @param finishStartTime 完成时间开始
+     * @param finishEndTime 完成时间结束
+     */
+    public IPage<LifeUserOrderVo> queryOrderList(Integer page, Integer size, String orderNo, String orderStatus, String couponName, String couponType, String storeName, String buyStartTime, String buyEndTime, String payStartTime, String payEndTime, String finishStartTime, String finishEndTime) {
+        IPage<LifeUserOrderVo> brandedPage = new Page<>(page, size);
+        QueryWrapper<LifeUserOrderVo> lifeUserOrderQueryWrapper = new QueryWrapper<>();
+        lifeUserOrderQueryWrapper.like(org.apache.commons.lang3.StringUtils.isNotBlank(orderNo),"luo.order_no",orderNo);
+        lifeUserOrderQueryWrapper.like(org.apache.commons.lang3.StringUtils.isNotBlank(couponName),"tc.coupon_name",couponName);
+        lifeUserOrderQueryWrapper.eq(org.apache.commons.lang3.StringUtils.isNotBlank(couponType),"tc.coupon_type",couponType);
+        lifeUserOrderQueryWrapper.like(org.apache.commons.lang3.StringUtils.isNotBlank(storeName),"si.store_name",storeName);
+        lifeUserOrderQueryWrapper.gt(org.apache.commons.lang3.StringUtils.isNotBlank(buyStartTime),"luo.buy_time",buyStartTime + " 00:00:00");
+        lifeUserOrderQueryWrapper.lt(org.apache.commons.lang3.StringUtils.isNotBlank(buyEndTime),"luo.buy_time",buyEndTime + " 23:59:59");
+        lifeUserOrderQueryWrapper.gt(org.apache.commons.lang3.StringUtils.isNotBlank(payStartTime),"luo.pay_time",payStartTime + " 00:00:00");
+        lifeUserOrderQueryWrapper.lt(org.apache.commons.lang3.StringUtils.isNotBlank(payEndTime),"luo.pay_time",payEndTime + " 23:59:59");
+        lifeUserOrderQueryWrapper.gt(org.apache.commons.lang3.StringUtils.isNotBlank(finishStartTime),"luo.finish_time",finishStartTime + " 00:00:00");
+        lifeUserOrderQueryWrapper.lt(org.apache.commons.lang3.StringUtils.isNotBlank(finishEndTime),"luo.finish_time",finishEndTime + " 23:59:59");
+//            @ApiImplicitParam(name = "orderStatus", value = "订单状态,-1,全部(可以不传);0,待支付;1,已支付/待使用;2,已核销;3,已过期;4,已取消;5.已退款,全退款了才算", required = false),
+        // 提取SQL基础部分,避免重复定义
+//        String baseSql = "select DISTINCT ocm1.order_id from order_coupon_middle ocm1 where 1=1";
+
+        if (!"-1".equals(orderStatus)) {
+            // 非-1状态:直接添加状态条件
+//            String sql = baseSql + " and ocm1.status = " + orderStatus;
+//            lifeUserOrderQueryWrapper.inSql("luo.id", sql);
+            lifeUserOrderQueryWrapper.eq("ocm.status",orderStatus);
+        }
+        lifeUserOrderQueryWrapper.groupBy("tc.coupon_type","tc.coupon_id");
+        IPage<LifeUserOrderVo> lifeUserOrderVoIPage = lifeUserOrderMapper.queryUserOrderList(brandedPage, lifeUserOrderQueryWrapper);
+
+        if (!"-1".equals(orderStatus)) {
+            lifeUserOrderVoIPage.getRecords().forEach(x->x.setStatus(Integer.parseInt(orderStatus)));
+        }
+        return lifeUserOrderVoIPage;
+    }
+
+    /**
+     * 平台端-查询订单详情
+     * @param orderId
+     * @return
+     */
+    public R queryOrderDetail(String orderId) {
+        LifeUserOrderVo lifeUserOrderVo = lifeUserOrderMapper.queryUserOrderDetail(orderId,null);
+        if ( null == lifeUserOrderVo){
+            log.error("queryUserOrderDetail未查询到订单");
+            return R.fail("未查询到订单");
+        }
+        // 退款记录
+        calcExpectIncome(lifeUserOrderVo);
+        lifeUserOrderVo.setCouponCount(lifeUserOrderVo.getOrderCouponMiddleList().size());
+        return R.data(lifeUserOrderVo);
+    }
 }

+ 8 - 0
alien-store/src/main/java/shop/alien/store/service/OrderCouponMiddleService.java

@@ -0,0 +1,8 @@
+package shop.alien.store.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.entity.store.LifeReverseGroupBuying;
+import shop.alien.entity.store.OrderCouponMiddle;
+
+public interface OrderCouponMiddleService extends IService<OrderCouponMiddle> {
+}

+ 13 - 0
alien-store/src/main/java/shop/alien/store/service/impl/OrderCouponMiddleServiceImpl.java

@@ -0,0 +1,13 @@
+package shop.alien.store.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import shop.alien.entity.store.OrderCouponMiddle;
+import shop.alien.mapper.OrderCouponMiddleMapper;
+import shop.alien.store.service.OrderCouponMiddleService;
+
+@Service
+@RequiredArgsConstructor
+public class OrderCouponMiddleServiceImpl extends ServiceImpl<OrderCouponMiddleMapper, OrderCouponMiddle> implements OrderCouponMiddleService {
+}

+ 2 - 2
alien-store/src/main/java/shop/alien/store/service/impl/StoreIncomeDetailsRecordServiceImpl.java

@@ -155,7 +155,7 @@ public class StoreIncomeDetailsRecordServiceImpl extends ServiceImpl<StoreIncome
             }
             return R.fail("余额不足");
         }
-        return "支付密码错误";
+        return R.fail("支付密码错误");
     }
 
     /**
@@ -289,7 +289,7 @@ public class StoreIncomeDetailsRecordServiceImpl extends ServiceImpl<StoreIncome
      * @return 未到账期
      */
     @Override
-    public JSONObject noYetPayment(Integer storeId, Integer incomeType, Integer paymentType) {
+    public JSONObject noYetPayment(Integer storeId, Integer incomeType, Integer paymentType, String startTime, String endTime, int page, int size) {
         LambdaQueryWrapper<StoreIncomeDetailsRecord> wrapper = new LambdaQueryWrapper<>();
         JSONObject jsonObject = new JSONObject();
         Date now = new Date();

+ 59 - 0
alien-util/src/main/java/shop/alien/util/common/constant/OrderStatusEnum.java

@@ -0,0 +1,59 @@
+package shop.alien.util.common.constant;
+
+/**
+ * 订单状态枚举
+ */
+public enum OrderStatusEnum {
+    //(0,待支付;1,已支付/待使用;2,已核销;3,已过期;4,已取消;5.已退款,全退款了才算;
+    /**
+     * 待支付
+     */
+    WAIT_PAY(0, "待支付"),
+    /**
+     * 已支付/待使用
+     */
+    WAIT_USE(1, "已支付/待使用"),
+    /**
+     * 已核销
+     */
+    USED(2, "已核销"),
+    /**
+     * 已过期
+     */
+    EXPIRE(3, "已过期"),
+    /**
+     * 已取消
+     */
+    CANCEL(4, "已取消"),
+    /**
+     * 已退款
+     */
+    REFUND(5, "已退款");
+
+
+    private final Integer status;
+    // 属性值
+    private final String description;
+    // 构造方法,用于初始化描述信息
+    OrderStatusEnum(Integer status, String description) {
+        this.status = status;
+        this.description = description;
+    }
+    // 提供获取描述信息的方法
+    public static String getDescription(Integer status) {
+        for (OrderStatusEnum orderStatusEnum : OrderStatusEnum.values()) {
+            if (orderStatusEnum.status.equals(status)) {
+                return orderStatusEnum.description;
+            }
+        }
+        return null;
+    }
+
+    public Integer getStatus() {
+        return status;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+}