From 029af9c4503d6838bddd55a6ecd6b73705ca1522 Mon Sep 17 00:00:00 2001
From: phpcjl <phpcjl@gmail.com>
Date: 星期二, 26 十一月 2024 17:08:00 +0800
Subject: [PATCH] 1.完善接口的定义 2.完成部分接口的开发 3.集成基于Redisson的分布式锁

---
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/UserPointServiceImpl.java           |    5 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/OrderVO.java                                      |   34 +++
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/TechnicianSubscribeService.java              |    1 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/OrderDetailVO.java                                |   61 ++++++
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/OrderGoodsVO.java                                 |   32 +++
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/UserPointService.java                    |    2 
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TechnicianSubscribeController.java        |   18 +
 ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/annotation/DistributedLock.java         |   34 +++
 ruoyi-api/ruoyi-api-order/src/main/java/model/Order.java                                                     |    4 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/OrderController.java                      |   57 ++++
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/OrderService.java                            |   10 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java                   |   18 +
 ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/aspectj/DistributedLockAspect.java      |  142 ++++++++++++++
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/vo/UserPointDetailVO.java                        |   23 ++
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/UserPointController.java              |   47 ++++
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/vo/UserPointVO.java                              |   31 +++
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TechnicianSubscribeServiceImpl.java     |   33 +++
 ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/TechnicianSubscribe.java                  |    2 
 ruoyi-common/ruoyi-common-redis/pom.xml                                                                      |    6 
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/distributedservice/DistributedTechnicianService.java |   27 ++
 20 files changed, 568 insertions(+), 19 deletions(-)

diff --git a/ruoyi-api/ruoyi-api-order/src/main/java/model/Order.java b/ruoyi-api/ruoyi-api-order/src/main/java/model/Order.java
index 1c171b2..fba67dd 100644
--- a/ruoyi-api/ruoyi-api-order/src/main/java/model/Order.java
+++ b/ruoyi-api/ruoyi-api-order/src/main/java/model/Order.java
@@ -84,6 +84,10 @@
     @TableField("express_json")
     private String expressJson;
 
+    @ApiModelProperty(value = "收货地址信息")
+    @TableField("address_json")
+    private String addressJson;
+
     @ApiModelProperty(value = "平台分佣")
     @TableField("share_amount")
     private BigDecimal shareAmount;
diff --git a/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/TechnicianSubscribe.java b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/TechnicianSubscribe.java
index 0fe1a4a..6d91ea3 100644
--- a/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/TechnicianSubscribe.java
+++ b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/TechnicianSubscribe.java
@@ -38,7 +38,7 @@
 
     @ApiModelProperty(value = "技师id")
     @TableField("technician_id")
-    private Integer technicianId;
+    private Long technicianId;
 
     @ApiModelProperty(value = "预约时间")
     @TableField("subscribe_time")
diff --git a/ruoyi-common/ruoyi-common-redis/pom.xml b/ruoyi-common/ruoyi-common-redis/pom.xml
index 97c986b..46d20b4 100644
--- a/ruoyi-common/ruoyi-common-redis/pom.xml
+++ b/ruoyi-common/ruoyi-common-redis/pom.xml
@@ -22,6 +22,12 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-redis</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>org.redisson</groupId>
+            <artifactId>redisson</artifactId>
+            <version>3.10.1</version>
+        </dependency>
         
         <!-- RuoYi Common Core-->
         <dependency>
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/annotation/DistributedLock.java b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/annotation/DistributedLock.java
new file mode 100644
index 0000000..93a38a7
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/annotation/DistributedLock.java
@@ -0,0 +1,34 @@
+package com.ruoyi.common.redis.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * @Descreption: 分布式锁注解
+ * @Author: luofl
+ * @Date: 2024/11/26 16:43
+ */
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface DistributedLock {
+
+    /**
+     * 锁名字(没有EL解析)
+     */
+    String lockName() default "";
+
+    /**
+     * 锁前缀(有EL解析)
+     */
+    String lockNamePre() default "";
+
+    /**
+     * 锁后缀(有EL解析)
+     */
+    String lockNamePost() default "";
+
+    /**
+     * 锁前后缀拼接分隔符
+     */
+    String separator() default "_";
+}
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/aspectj/DistributedLockAspect.java b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/aspectj/DistributedLockAspect.java
new file mode 100644
index 0000000..fa06f8c
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/aspectj/DistributedLockAspect.java
@@ -0,0 +1,142 @@
+package com.ruoyi.common.redis.aspectj;
+
+import com.ruoyi.common.redis.annotation.DistributedLock;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.redisson.api.RLock;
+import org.redisson.api.RedissonClient;
+import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
+import org.springframework.expression.ExpressionParser;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.expression.spel.support.StandardEvaluationContext;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.GetMapping;
+
+import javax.annotation.Resource;
+import java.lang.reflect.Method;
+import java.util.Objects;
+
+/**
+ * @Description 分布式锁切面
+ * 注意!!!分布式锁不能加在事务方法当中:因为当锁释放,事务还没有提交
+ * @Author luofl
+ * @Date 2024/11/26 16:42
+ */
+@Aspect
+@Component
+@Slf4j
+public class DistributedLockAspect {
+    @Resource
+    private RedissonClient redissonClient;
+
+    /**
+     * @Descreption: 定义切面:以注解为切面
+     * @Author: luofl
+     * @Date: 2024/11/26 16:44
+     */
+    @Pointcut("@annotation(com.ruoyi.common.redis.annotation.DistributedLock)")
+    public void distributedLockAspect() {
+    }
+
+    @Around(value = "distributedLockAspect()")
+    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
+
+        //切点所在的类
+        MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
+        Method method = methodSignature.getMethod();
+        //
+        DistributedLock annotation = method.getAnnotation(DistributedLock.class);
+        String lockName = getLockName(annotation, pjp.getArgs(), method);
+        //log.info("lockName:"+lockName);
+        RLock lock = redissonClient.getLock(lockName);
+        lock.lock();
+        try {
+            return pjp.proceed();
+        } finally {
+            if (lock.isLocked() && lock.isHeldByCurrentThread()) {
+                //释放锁
+                lock.unlock();
+            }
+        }
+    }
+
+    /**
+     * @Descreption: 获取锁名字,优先获取注解中锁名
+     * @Author: luofl
+     * @Date: 2024/11/26 16:45
+     */
+    private String getLockName(DistributedLock distributedLock, Object[] args, Method method) {
+        //优先获取注解名称
+        if (StringUtils.isNotBlank(distributedLock.lockName())) {
+            return distributedLock.lockName();
+        }
+        //根据参数匹配有参数就使用动态参数,没有就使用定义参数
+        String lockNamePre = distributedLock.lockNamePre();
+        String lockNamePost = distributedLock.lockNamePost();
+        String separator = distributedLock.separator();
+
+        String preExpression = parseExpression(lockNamePre, method, args);
+        String postExpression = parseExpression(lockNamePost, method, args);
+        StringBuilder sb = new StringBuilder();
+        if (StringUtils.isNotBlank(preExpression)) {
+            sb.append(preExpression);
+        } else {
+            sb.append(lockNamePre);
+        }
+        sb.append(separator);
+        if (StringUtils.isNotBlank(postExpression)) {
+            sb.append(postExpression);
+        } else {
+            sb.append(lockNamePost);
+        }
+        return sb.toString();
+    }
+
+    /**
+     * el表达式解析
+     *
+     * @param expressionString 解析值
+     * @param method           方法
+     * @param args             参数
+     */
+    private String parseExpression(String expressionString, Method method, Object[] args) {
+        //获取被拦截方法参数名列表
+        LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
+        String[] paramNameArr = discoverer.getParameterNames(method);
+        //SPEL解析
+        ExpressionParser parser = new SpelExpressionParser();
+        StandardEvaluationContext context = new StandardEvaluationContext();
+        for (int i = 0; i < Objects.requireNonNull(paramNameArr).length; i++) {
+            context.setVariable(paramNameArr[i], args[i]);
+        }
+        return parser.parseExpression(expressionString).getValue(context, String.class);
+    }
+
+    //    ==========================示例=============================
+
+    //固定静态参数锁:product_lock
+    @DistributedLock(lockName = "product_lock")
+    @GetMapping(value = "/test1")
+    public void test1() {
+        System.out.println("执行事务");
+    }
+
+    //未匹配到参数,因此仍然是静态参数锁:#param1_#param2
+    @DistributedLock(lockNamePre = "#param1", lockNamePost = "#param2")
+    @GetMapping(value = "/test2")
+    public void test2() {
+        System.out.println("执行事务");
+    }
+
+    //匹配到参数,动态参数锁:hello_world
+    @DistributedLock(lockNamePre = "#order", lockNamePost = "#param2")
+    @GetMapping(value = "/test3")
+    public void test3(String param1, String param2) {
+        System.out.println("执行事务");
+    }
+}
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/UserPointController.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/UserPointController.java
index 50fec32..4152c2c 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/UserPointController.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/UserPointController.java
@@ -1,9 +1,23 @@
 package com.ruoyi.account.controller;
 
 
+import com.ruoyi.account.service.UserPointService;
+import com.ruoyi.account.vo.UserPointDetailVO;
+import com.ruoyi.account.vo.UserPointVO;
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.core.web.controller.BaseController;
+import com.ruoyi.common.security.utils.SecurityUtils;
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
 
 /**
  * <p>
@@ -16,10 +30,39 @@
 @RestController
 @RequestMapping("/user-point")
 @Api("用户积分")
-public class UserPointController {
+public class UserPointController extends BaseController {
+    @Resource
+    private UserPointService userPointService;
+
 
     /**
-     * 积分
+     * 获取个人积分
      */
+    @GetMapping("/getUserPoint")
+    @ApiOperation("获取个人积分")
+    public R<UserPointVO> getUserPoint(){
+        return R.ok(userPointService.getUserPoint(SecurityUtils.getUserId()));
+    }
+
+    /**
+     * 获取变更明细
+     */
+    @GetMapping("/getUserPointDetail")
+    @ApiOperation("获取变更明细")
+    public R<UserPointDetailVO> getUserPointDetail(@ApiParam("指定日期") LocalDateTime date,
+                                                   @ApiParam("变动类型(1=消费积分,2=返佣积分,3=拉新人积分,4=兑换商品 " +
+                                                           "5 = 门店业绩积分 6 =门店返佣积分7=技师业绩积分8 =转赠积分 9 =做工积分 " +
+                                                           "10 =注册积分)") Integer type){
+        return R.ok();
+    }
+
+    /**
+     * 转赠积分
+     */
+    @PostMapping("/transferPoint")
+    @ApiOperation("转赠积分")
+    public R<Void> transferPoint(@ApiParam("积分") BigDecimal point, @ApiParam("手机号") Long phone){
+        return R.ok();
+    }
 }
 
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/UserPointService.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/UserPointService.java
index a77887d..1e104a9 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/UserPointService.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/UserPointService.java
@@ -2,6 +2,7 @@
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.ruoyi.account.api.model.UserPoint;
+import com.ruoyi.account.vo.UserPointVO;
 
 /**
  * <p>
@@ -13,4 +14,5 @@
  */
 public interface UserPointService extends IService<UserPoint> {
 
+    UserPointVO getUserPoint(Long userId);
 }
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/UserPointServiceImpl.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/UserPointServiceImpl.java
index 0b4a3fb..0b091af 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/UserPointServiceImpl.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/UserPointServiceImpl.java
@@ -4,6 +4,7 @@
 import com.ruoyi.account.mapper.UserPointMapper;
 import com.ruoyi.account.api.model.UserPoint;
 import com.ruoyi.account.service.UserPointService;
+import com.ruoyi.account.vo.UserPointVO;
 import org.springframework.stereotype.Service;
 
 /**
@@ -17,4 +18,8 @@
 @Service
 public class UserPointServiceImpl extends ServiceImpl<UserPointMapper, UserPoint> implements UserPointService {
 
+    @Override
+    public UserPointVO getUserPoint(Long userId) {
+        return null;
+    }
 }
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/vo/UserPointDetailVO.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/vo/UserPointDetailVO.java
new file mode 100644
index 0000000..92dc03c
--- /dev/null
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/vo/UserPointDetailVO.java
@@ -0,0 +1,23 @@
+package com.ruoyi.account.vo;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Data
+@ApiModel(value="UserPointDetail对象", description="")
+public class UserPointDetailVO {
+
+    @ApiModelProperty(value = "变动类型(1=消费积分,2=返佣积分,3=拉新人积分,4=兑换商品 5 = 门店业绩积分 6 =门店返佣积分7=技师业绩积分8 =转赠积分 9 =做工积分 10 =注册积分)")
+    private Integer type;
+
+    @ApiModelProperty(value = "变动金额")
+    private BigDecimal variablePoint;
+
+    @ApiModelProperty(value = "变动时间")
+    private LocalDateTime createTime;
+}
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/vo/UserPointVO.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/vo/UserPointVO.java
new file mode 100644
index 0000000..d81b7c9
--- /dev/null
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/vo/UserPointVO.java
@@ -0,0 +1,31 @@
+package com.ruoyi.account.vo;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+@ApiModel(value="UserPoint对象", description="")
+public class UserPointVO {
+
+    @ApiModelProperty(value = "总积分")
+    private Integer totalPoint;
+
+    @ApiModelProperty(value = "消费积分数")
+    private BigDecimal shopPoint;
+
+    @ApiModelProperty(value = "返佣积分数")
+    private BigDecimal sharePoint;
+
+    @ApiModelProperty(value = "拉新积分")
+    private BigDecimal pullNewPoint;
+
+    @ApiModelProperty(value = "门店业绩积分")
+    private BigDecimal shopAchievementPoint;
+
+    @ApiModelProperty(value = "门店返佣积分")
+    private BigDecimal shopSharePoint;
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/OrderController.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/OrderController.java
index e913905..b943e89 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/OrderController.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/OrderController.java
@@ -1,8 +1,10 @@
 package com.ruoyi.order.controller;
 
 
-import com.ruoyi.common.core.web.domain.AjaxResult;
+import com.ruoyi.common.core.domain.R;
 import com.ruoyi.order.service.OrderService;
+import com.ruoyi.order.vo.OrderDetailVO;
+import com.ruoyi.order.vo.OrderVO;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
@@ -13,6 +15,7 @@
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
+import java.util.List;
 
 /**
  * <p>
@@ -31,6 +34,30 @@
 
 
     /**
+     * 我的订单列表
+     */
+    @ApiOperation(value = "我的订单列表", tags = {"小程序-个人中心-我的订单"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(value = "订单状态", name = "status", required = true, dataType = "int"),
+    })
+    @GetMapping("/list/{status}")
+    public R<List<OrderVO>> list(@PathVariable("status") Integer status){
+        return R.ok(orderService.getOrderList(status));
+    }
+
+    /**
+     * 订单详情
+     */
+    @ApiOperation(value = "订单详情", tags = {"小程序-订单详情"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(value = "订单id", name = "orderId", required = true, dataType = "int"),
+    })
+    @GetMapping("/detail/{orderId}")
+    public R<OrderDetailVO> detail(@PathVariable("orderId") Long orderId){
+        return R.ok(orderService.getOrderDetail(orderId));
+    }
+
+    /**
      * 扫码校验
      */
     @ApiOperation(value = "扫码校验", tags = {"小程序-个人中心-门店管理-扫码核销校验"})
@@ -38,21 +65,35 @@
             @ApiImplicitParam(value = "分享id", name = "shareId", required = true, dataType = "int"),
     })
     @GetMapping("/check/{orderId}/{shopId}")
-    public AjaxResult check(@PathVariable("orderId") Integer orderId, @PathVariable("shopId") Integer shopId){
-        return AjaxResult.ok(orderService.check(orderId, shopId));
+    public R<Boolean> check(@PathVariable("orderId") Long orderId, @PathVariable("shopId") Long shopId){
+        return R.ok(orderService.check(orderId, shopId));
     }
 
     /**
-     * 订单详情
+     * 订单核销
      */
-    @ApiOperation(value = "订单详情", tags = {"订单详情"})
+    @ApiOperation(value = "订单核销", tags = {"小程序-个人中心-门店管理-扫码核销"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(value = "核销码", name = "code", required = true, dataType = "String"),
+    })
+    @GetMapping("/writeOff/{code}")
+    public R<Void> writeOff(@PathVariable("code") String code){
+        return R.ok();
+    }
+
+    /**
+     * 取消订单
+     */
+    @ApiOperation(value = "取消订单", tags = {"小程序-个人中心-我的订单-取消订单"})
     @ApiImplicitParams({
             @ApiImplicitParam(value = "订单id", name = "orderId", required = true, dataType = "int"),
     })
-    @GetMapping("/detail/{orderId}")
-    public AjaxResult detail(@PathVariable("orderId") Integer orderId){
-        return AjaxResult.success(orderService.getById(orderId));
+    @GetMapping("/cancel/{orderId}")
+    public R<Void> cancel(@PathVariable("orderId") Long orderId){
+        return R.ok();
     }
 
+
+
 }
 
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/OrderService.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/OrderService.java
index 541715a..0961a26 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/OrderService.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/OrderService.java
@@ -1,7 +1,11 @@
 package com.ruoyi.order.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.order.vo.OrderDetailVO;
+import com.ruoyi.order.vo.OrderVO;
 import model.Order;
+
+import java.util.List;
 
 /**
  * <p>
@@ -12,5 +16,9 @@
  * @since 2024-11-21
  */
 public interface OrderService extends IService<Order> {
-    boolean check(Integer orderId, Integer shopId);
+    List<OrderVO> getOrderList(Integer status);
+
+    OrderDetailVO getOrderDetail(Long orderId);
+
+    boolean check(Long orderId, Long shopId);
 }
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java
index a969b93..8b83866 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java
@@ -3,8 +3,13 @@
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.order.mapper.OrderMapper;
 import com.ruoyi.order.service.OrderService;
+import com.ruoyi.order.vo.OrderDetailVO;
+import com.ruoyi.order.vo.OrderVO;
 import model.Order;
 import org.springframework.stereotype.Service;
+
+import java.util.Collections;
+import java.util.List;
 
 /**
  * <p>
@@ -18,7 +23,18 @@
 public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
 
     @Override
-    public boolean check(Integer orderId, Integer shopId) {
+    public List<OrderVO> getOrderList(Integer status) {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public OrderDetailVO getOrderDetail(Long orderId) {
+        return null;
+    }
+
+    @Override
+    public boolean check(Long orderId, Long shopId) {
+        // TODO 待实现
         return false;
     }
 }
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/OrderDetailVO.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/OrderDetailVO.java
new file mode 100644
index 0000000..eef904e
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/OrderDetailVO.java
@@ -0,0 +1,61 @@
+package com.ruoyi.order.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Data
+@ApiModel(value = "订单明细")
+public class OrderDetailVO {
+    @ApiModelProperty(value = "订单id")
+    private Long id;
+
+    @ApiModelProperty(value = "订单商品")
+    private List<OrderGoodsVO> goodsList;
+
+    @ApiModelProperty(value = "使用积分")
+    private BigDecimal point;
+
+    @ApiModelProperty(value = "收货地址id")
+    private Long addressId;
+
+    @ApiModelProperty(value = "收货联系人")
+    private String recieveName;
+
+    @ApiModelProperty(value = "收货联系电话")
+    private String recievePhone;
+
+    @ApiModelProperty(value = "收货地址")
+    private String recieveAddress;
+
+    @ApiModelProperty(value = "订单编号")
+    private String orderNumber;
+
+    @ApiModelProperty("下单时间")
+    private String createTime;
+
+    @ApiModelProperty(value = "订单总金额")
+    private BigDecimal totalAmount;
+
+    @ApiModelProperty(value = "优惠券名称")
+    private String couponName;
+
+    @ApiModelProperty(value = "参与活动名称")
+    private String activityName;
+
+    @ApiModelProperty(value = "抵扣金额")
+    private BigDecimal couponAmount;
+
+    @ApiModelProperty(value = "快递费")
+    private BigDecimal expressAmount;
+
+    @ApiModelProperty(value = "可获得积分")
+    private BigDecimal pointAmount;
+
+    @ApiModelProperty(value = "实际支付价格")
+    private BigDecimal paymentAmount;
+
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/OrderGoodsVO.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/OrderGoodsVO.java
new file mode 100644
index 0000000..e19f665
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/OrderGoodsVO.java
@@ -0,0 +1,32 @@
+package com.ruoyi.order.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+@ApiModel(value = "订单商品")
+public class OrderGoodsVO {
+    @ApiModelProperty(value = "商品id")
+    private Long goodsId;
+
+    @ApiModelProperty(value = "商品名称")
+    private String goodsName;
+
+    @ApiModelProperty(value = "类型(1=服务商品,2=单品商品)")
+    private Integer type;
+
+    @ApiModelProperty(value = "数量")
+    private Integer num;
+
+    @ApiModelProperty(value = "商品图片")
+    private String goodsPic;
+
+    @ApiModelProperty(value = "基础售价")
+    private BigDecimal sellingPrice;
+
+    @ApiModelProperty(value = "划线价")
+    private BigDecimal originalPrice;
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/OrderVO.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/OrderVO.java
new file mode 100644
index 0000000..796f3d8
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/OrderVO.java
@@ -0,0 +1,34 @@
+package com.ruoyi.order.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Data
+public class OrderVO {
+    @ApiModelProperty(value = "订单id")
+    private Long id;
+
+    @ApiModelProperty(value = "订单编号")
+    private String orderNumber;
+
+    @ApiModelProperty(value = "1待发货2待收货3待使用4已完成待评论5已取消6已退款7售后中8已完成已评论")
+    private Integer orderStatus;
+
+    @ApiModelProperty(value = "商品图片")
+    private List<String> goodsPics;
+
+    @ApiModelProperty(value = "商品名称")
+    private String goodsName;
+
+    @ApiModelProperty(value = "使用积分")
+    private BigDecimal point;
+
+    @ApiModelProperty(value = "实际支付价格")
+    private BigDecimal paymentAmount;
+
+    @ApiModelProperty(value = "商品数量")
+    private Integer num;
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TechnicianSubscribeController.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TechnicianSubscribeController.java
index 6aa2f8b..a651153 100644
--- a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TechnicianSubscribeController.java
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TechnicianSubscribeController.java
@@ -7,15 +7,13 @@
 import com.ruoyi.common.core.web.page.TableDataInfo;
 import com.ruoyi.common.security.utils.SecurityUtils;
 import com.ruoyi.other.api.domain.TechnicianSubscribe;
+import com.ruoyi.other.distributedservice.DistributedTechnicianService;
 import com.ruoyi.other.service.TechnicianSubscribeService;
 import com.ruoyi.other.vo.TechnicianSubscribeVO;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 import java.util.List;
@@ -34,6 +32,8 @@
 public class TechnicianSubscribeController extends BaseController {
     @Resource
     private TechnicianSubscribeService technicianSubscribeService;
+    @Resource
+    private DistributedTechnicianService distributedTechnicianService;
 
     /**
      * 预约列表
@@ -49,6 +49,16 @@
     }
 
     /**
+     * 预约技师
+     */
+    @PostMapping("/subscribe")
+    @ApiOperation(value = "预约技师", notes = "预约技师", tags = {"小程序-个人中心-门店管理-预约列表-预约技师"})
+    public R<Void> subscribe(@RequestBody TechnicianSubscribe technicianSubscribe){
+        distributedTechnicianService.subscribe(technicianSubscribe,technicianSubscribe.getTechnicianId());
+        return R.ok();
+    }
+
+    /**
      * 取消服务
      */
     @GetMapping("/cancel")
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/distributedservice/DistributedTechnicianService.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/distributedservice/DistributedTechnicianService.java
new file mode 100644
index 0000000..b357343
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/distributedservice/DistributedTechnicianService.java
@@ -0,0 +1,27 @@
+package com.ruoyi.other.distributedservice;
+
+import com.ruoyi.common.redis.annotation.DistributedLock;
+import com.ruoyi.other.api.domain.TechnicianSubscribe;
+import com.ruoyi.other.service.TechnicianSubscribeService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+/**
+ * @Desecription: 技师业务分布式锁业务处理
+ * 由于service被事务包裹,因此需要单独建立包来存放分布式锁业务,
+ * 分布式锁不能在业务方法中执行
+ * 事务隔离问题: 如果将分布式锁放在业务方法内部,并且业务方法处于事务中,那么在事务提交之前,分布式锁可能无法释放,导致其他事务无法获取到该锁,从而造成死锁或长时间的阻塞。
+ * @Autor: luofl
+ * @Date: 2024/11/26 16:50
+ */
+@Service
+public class DistributedTechnicianService {
+    @Resource
+    private TechnicianSubscribeService technicianSubscribeService;
+
+    @DistributedLock(lockNamePre = "#TECHNICIAN_SUBSCRIBE_LOCK", lockNamePost = "#technicianId")
+    public void subscribe(TechnicianSubscribe technicianSubscribe,Long technicianId){
+        technicianSubscribeService.subscribe(technicianSubscribe);
+    }
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/TechnicianSubscribeService.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/TechnicianSubscribeService.java
index 2bbdf42..f2e2555 100644
--- a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/TechnicianSubscribeService.java
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/TechnicianSubscribeService.java
@@ -21,4 +21,5 @@
      */
     List<TechnicianSubscribeVO> getTechnicianSubscribeByUserAndShop(Long userId, Long shopId);
 
+    void subscribe(TechnicianSubscribe technicianSubscribe);
 }
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TechnicianSubscribeServiceImpl.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TechnicianSubscribeServiceImpl.java
index a1e6e7f..6fb0962 100644
--- a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TechnicianSubscribeServiceImpl.java
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TechnicianSubscribeServiceImpl.java
@@ -1,19 +1,25 @@
 package com.ruoyi.other.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.core.exception.ServiceException;
+import com.ruoyi.common.security.utils.SecurityUtils;
+import com.ruoyi.other.api.domain.Technician;
+import com.ruoyi.other.mapper.TechnicianMapper;
 import com.ruoyi.other.mapper.TechnicianSubscribeMapper;
 import com.ruoyi.other.api.domain.TechnicianSubscribe;
 import com.ruoyi.other.service.TechnicianSubscribeService;
 import com.ruoyi.other.vo.TechnicianSubscribeVO;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
-import java.util.Collections;
+import java.time.LocalDateTime;
 import java.util.List;
 
 /**
  * <p>
- *  服务实现类
+ * 服务实现类
  * </p>
  *
  * @author luodangjia
@@ -23,9 +29,32 @@
 public class TechnicianSubscribeServiceImpl extends ServiceImpl<TechnicianSubscribeMapper, TechnicianSubscribe> implements TechnicianSubscribeService {
     @Resource
     private TechnicianSubscribeMapper technicianSubscribeMapper;
+    @Resource
+    private TechnicianMapper technicianMapper;
 
     @Override
     public List<TechnicianSubscribeVO> getTechnicianSubscribeByUserAndShop(Long userId, Long shopId) {
         return technicianSubscribeMapper.getTechnicianSubscribeByUserAndShop(userId, shopId);
     }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void subscribe(TechnicianSubscribe technicianSubscribe) {
+        Long technicianId = technicianSubscribe.getTechnicianId();
+        Technician technician = technicianMapper.selectOne(new LambdaQueryWrapper<Technician>()
+                .eq(Technician::getId, technicianId)
+                .eq(Technician::getStatus, 1)
+                .eq(Technician::getSubscribeStatus, 1));
+        if (null == technician) {
+            throw new ServiceException("不满足预约条件");
+        }
+        Long userId = SecurityUtils.getUserId();
+        TechnicianSubscribe subscribe = new TechnicianSubscribe();
+        subscribe.setAppUserId(userId);
+        subscribe.setDelFlag(0);
+        subscribe.setCreateTime(LocalDateTime.now());
+        technicianSubscribeMapper.insert(subscribe);
+        technician.setSubscribeStatus(2);
+        technicianMapper.updateById(technician);
+    }
 }

--
Gitblit v1.7.1