Pu Zhibing
2024-12-02 c67297af61ab9d897adae96f7e199c72c16d764b
Merge remote-tracking branch 'origin/master'
5个文件已添加
12个文件已修改
385 ■■■■ 已修改文件
ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserClientFallbackFactory.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/AppUserClient.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/AppUser.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/TechnicianClientFallbackFactory.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/feignClient/TechnicianClient.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/AppUserShopController.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/vo/WalletVO.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/OrderController.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/enums/OrderStatus.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/enums/OrderType.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/OrderService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TechnicianController.java 57 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TechnicianSubscribeController.java 36 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/enums/TechnicianStatus.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/TechnicianSubscribeService.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TechnicianSubscribeServiceImpl.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserClientFallbackFactory.java
@@ -2,9 +2,12 @@
import com.ruoyi.account.api.feignClient.AppUserClient;
import com.ruoyi.account.api.model.AppUser;
import com.ruoyi.account.api.model.AppUserShop;
import com.ruoyi.common.core.domain.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import java.util.List;
/**
 * @author zhibing.pu
@@ -37,6 +40,11 @@
                throw new RuntimeException("获取优惠券数量失败");
            }
            @Override
            public R<List<AppUserShop>> getAppUserShop(Long userId) {
                log.error("获取用户门店信息失败:{}", cause.getMessage());
                throw new RuntimeException("获取用户门店信息失败");
            }
        };
    }
}
ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/AppUserClient.java
@@ -2,11 +2,16 @@
import com.ruoyi.account.api.factory.AppUserClientFallbackFactory;
import com.ruoyi.account.api.model.AppUser;
import com.ruoyi.account.api.model.AppUserShop;
import com.ruoyi.common.core.constant.ServiceNameConstants;
import com.ruoyi.common.core.domain.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
/**
 * @author zhibing.pu
@@ -31,4 +36,11 @@
    @PostMapping("/appUser/getCouponCount")
    R<Long> getCouponCount(@RequestParam("userId")Long userId, @RequestParam("couponId") Integer couponId );
    /**
     *  根据用户id查询用户门店信息
     */
    @GetMapping("/appUserShop/shop/{userId}")
    R<List<AppUserShop>> getAppUserShop(@PathVariable("userId") Long userId);
}
ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/AppUser.java
@@ -33,6 +33,9 @@
    @TableId("id")
    private Long id;
    @ApiModelProperty(value = "用户类型(1-普通用户,2-门店员工)")
    private Integer userType;
    @ApiModelProperty(value = "用户")
    @TableField("name")
    private String name;
@@ -122,6 +125,10 @@
    @TableField("last_shop_time")
    private LocalDateTime lastShopTime;
    @ApiModelProperty(value = "账户余额")
    @TableField("balance")
    private BigDecimal balance;
    @ApiModelProperty(value = "可提现金额")
    @TableField("withdrawable_amount")
    private BigDecimal withdrawableAmount;
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/TechnicianClientFallbackFactory.java
New file
@@ -0,0 +1,23 @@
package com.ruoyi.other.api.factory;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.other.api.domain.Technician;
import com.ruoyi.other.api.feignClient.TechnicianClient;
import org.springframework.cloud.openfeign.FallbackFactory;
public class TechnicianClientFallbackFactory implements FallbackFactory<TechnicianClient> {
    @Override
    public TechnicianClient create(Throwable cause) {
        return new TechnicianClient() {
            @Override
            public R<Technician> shopdetail(Integer techId) {
                return R.fail("根据省市区获取地区价格配置失败:" + cause.getMessage());
            }
            @Override
            public R<Void> updateStatus(Integer status, Integer subscribeId) {
                return R.fail("跟新技师预约状态失败:" + cause.getMessage());
            }
        };
    }
}
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/feignClient/TechnicianClient.java
New file
@@ -0,0 +1,20 @@
package com.ruoyi.other.api.feignClient;
import com.ruoyi.common.core.constant.ServiceNameConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.other.api.domain.Technician;
import com.ruoyi.other.api.factory.TechnicianClientFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(contextId = "TechnicianClient", value = ServiceNameConstants.ORDER_SERVICE, fallbackFactory = TechnicianClientFallbackFactory.class)
public interface TechnicianClient {
    @PostMapping("/technician/shop/detail")
    R<Technician> shopdetail(@RequestParam Integer techId);
    @PutMapping("/technician-subscribe/updateStatus")
    R<Void> updateStatus(@RequestParam Integer status, @RequestParam Integer subscribeId);
}
ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/AppUserShopController.java
@@ -1,6 +1,13 @@
package com.ruoyi.account.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.account.api.model.AppUserShop;
import com.ruoyi.account.service.AppUserShopService;
import com.ruoyi.common.core.domain.R;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
@@ -10,6 +17,14 @@
@RestController
@RequestMapping("/appUserShop")
public class AppUserShopController {
    @Resource
    private AppUserShopService appUserShopService;
    @GetMapping("/shop/{userId}")
    public R<List<AppUserShop>> getAppUserShop(@PathVariable("userId") Long userId) {
        return R.ok(appUserShopService.list(new LambdaQueryWrapper<AppUserShop>()
                .eq(AppUserShop::getAppUserId,userId)));
    }
    
    
ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/vo/WalletVO.java
@@ -10,6 +10,9 @@
@ApiModel(value="钱包对象", description="")
public class WalletVO {
    @ApiModelProperty(value = "账户余额")
    private BigDecimal balance;
    @ApiModelProperty(value = "可提现金额")
    private BigDecimal withdrawalAmount;
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/OrderController.java
@@ -1,6 +1,7 @@
package com.ruoyi.order.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.order.service.OrderService;
@@ -11,6 +12,7 @@
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import model.Order;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -70,8 +72,11 @@
            @ApiImplicitParam(value = "分享id", name = "shareId", required = true, dataType = "int", paramType="query"),
    })
    @GetMapping("/check/{orderNumber}/{shopId}")
    public R<Boolean> check(@PathVariable("orderNumber") String orderNumber, @PathVariable("shopId") Long shopId){
        return R.ok(orderService.check(orderNumber, shopId));
    public R<Boolean> check(@PathVariable("orderNumber") String orderNumber, @PathVariable("shopId") Integer shopId){
        LoginUser loginUserApplet = tokenService.getLoginUserApplet();
        Order order = orderService.getOne(new LambdaQueryWrapper<Order>()
                .eq(Order::getOrderNumber, orderNumber));
        return R.ok(orderService.check(order, shopId, loginUserApplet.getUserid()));
    }
    /**
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/enums/OrderStatus.java
New file
@@ -0,0 +1,32 @@
package com.ruoyi.order.enums;
import lombok.Getter;
@Getter
public enum OrderStatus {
    PENDING_SHIPMENT(1, "待发货"),
    PENDING_RECEIPT(2, "待收货"),
    PENDING_USE(3, "待使用"),
    COMPLETED(4, "已完成"),
    CANCELLED(5, "已取消"),
    REFUNDED(6, "已退款"),
    AFTER_SALE(7, "售后中");
    private final int code;
    private final String description;
    OrderStatus(int code, String description) {
        this.code = code;
        this.description = description;
    }
    // 根据代码获取对应的OrderStatus
    public static OrderStatus fromCode(int code) {
        for (OrderStatus status : values()) {
            if (status.getCode() == code) {
                return status;
            }
        }
        throw new IllegalArgumentException("Unknown order status code: " + code);
    }
}
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/enums/OrderType.java
New file
@@ -0,0 +1,26 @@
package com.ruoyi.order.enums;
import lombok.Getter;
@Getter
public enum OrderType {
    SERVICE(1, "服务单"),
    GOOD(2, "商品单");
    private final int code;
    private final String description;
    OrderType(int code, String description) {
        this.code = code;
        this.description = description;
    }
    public static OrderType fromCode(int code) {
        for (OrderType type : OrderType.values()) {
            if (type.getCode() == code) {
                return type;
            }
        }
        return null;
    }
}
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/OrderService.java
@@ -20,7 +20,7 @@
    OrderDetailVO getOrderDetail(Long orderId);
    boolean check(String orderNumber, Long shopId);
    boolean check(Order order, Integer shopId, Long userId);
    void writeOff(String code);
    void writeOff(String code,Integer shopId);
}
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java
@@ -3,9 +3,15 @@
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.account.api.feignClient.AppUserClient;
import com.ruoyi.account.api.model.AppUserShop;
import com.ruoyi.account.api.model.UserAddress;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.order.enums.OrderStatus;
import com.ruoyi.order.enums.OrderType;
import com.ruoyi.order.mapper.OrderGoodMapper;
import com.ruoyi.order.mapper.OrderMapper;
import com.ruoyi.order.service.OrderService;
@@ -15,13 +21,18 @@
import com.ruoyi.other.api.domain.CouponInfo;
import com.ruoyi.other.api.domain.Goods;
import com.ruoyi.other.api.domain.OrderActivityInfo;
import com.ruoyi.other.api.domain.Technician;
import com.ruoyi.other.api.feignClient.TechnicianClient;
import com.ruoyi.system.api.model.LoginUser;
import model.Order;
import model.OrderGood;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
 * <p>
@@ -35,7 +46,14 @@
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    @Resource
    private OrderMapper orderMapper;
    @Resource
    private OrderGoodMapper orderGoodMapper;
    @Resource
    private AppUserClient appUserClient;
    @Resource
    private TokenService tokenService;
    @Resource
    private TechnicianClient technicianClient;
    @Override
    public List<OrderVO> selectOrderListByUserId(Integer status, Long userId) {
@@ -115,15 +133,55 @@
    }
    @Override
    public boolean check(String orderNumber, Long shopId) {
        Order order = getOne(new LambdaQueryWrapper<Order>()
                .eq(Order::getOrderNumber, orderNumber)
                .eq(Order::getShopId, shopId));
        return order != null;
    public boolean check(Order order, Integer shopId, Long userId) {
        R<List<AppUserShop>> r = appUserClient.getAppUserShop(userId);
        if (r.getCode() != R.SUCCESS){
            throw new ServiceException("获取用户门店信息失败");
        }
        List<AppUserShop> appUserShopList = r.getData();
        if (appUserShopList == null || appUserShopList.isEmpty()){
            return false;
        }
        // 判断用户是否拥有该门店
        List<AppUserShop> userShopList = appUserShopList.stream()
                .filter(appUserShop -> appUserShop.getShopId().equals(shopId))
                .collect(Collectors.toList());
        if (userShopList.isEmpty()){
            return false;
        }
        // 判断订单是否属于该门店
        if (order == null){
            throw new ServiceException("订单不存在");
        }
        return order.getShopId().equals(shopId);
    }
    @Override
    public void writeOff(String code) {
    @Transactional(rollbackFor = Exception.class)
    public void writeOff(String code,Integer shopId) {
        LoginUser loginUserApplet = tokenService.getLoginUserApplet();
        Order order = orderMapper.selectOne(new LambdaQueryWrapper<Order>()
                .eq(Order::getOrderNumber, code));
        boolean check = check(order, shopId, loginUserApplet.getUserid());
        if (!check){
            throw new ServiceException("订单不存在");
        }
        order.setOrderStatus(OrderStatus.COMPLETED.getCode());
        orderMapper.updateById(order);
        Integer orderType = order.getOrderType();
        if (orderType.equals(OrderType.SERVICE.getCode())){
            R<Technician> shopdetail = technicianClient.shopdetail(order.getTechnicianId());
            if (shopdetail.getCode() != R.SUCCESS){
                throw new ServiceException("获取技师信息失败");
            }
            Technician technician = shopdetail.getData();
            R<Void> r = technicianClient.updateStatus(2, technician.getId());
            if (r.getCode() != R.SUCCESS){
                throw new ServiceException("修改技师状态失败");
            }
        }
    }
}
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TechnicianController.java
@@ -79,36 +79,37 @@
            return R.ok(page);
        }
                @PostMapping("/shop/detail")
                @ApiOperation(value = "获取门店的技师详情", tags = {"小程序-门店详情-技师预约"})
                public R<Technician> shopdetail(@RequestParam Integer techId){
                //查出技师列表
                   Technician technician = technicianService.getById(techId);
    @PostMapping("/shop/detail")
    @ApiOperation(value = "获取门店的技师详情", tags = {"小程序-门店详情-技师预约"})
    public R<Technician> shopdetail(@RequestParam Integer techId) {
        //查出技师列表
        Technician technician = technicianService.getById(techId);
                 //查出技师订单
                R<List<Long>> orderIdsByTechId = orderClient.getOrderIdsByTechId(technician.getId());
                if (orderIdsByTechId.getData().isEmpty()){
                    technician.setGrade(new BigDecimal(0));
                    technician.setServeCount(0);
                    return R.ok(technician);
                }
                //查出技师评价
                List<GoodsEvaluate> list = goodsEvaluateService.lambdaQuery().in(GoodsEvaluate::getOrderId, orderIdsByTechId.getData()).list();
        //查出技师订单
        R<List<Long>> orderIdsByTechId = orderClient.getOrderIdsByTechId(technician.getId());
        if (orderIdsByTechId.getData().isEmpty()) {
            technician.setGrade(new BigDecimal(0));
            technician.setServeCount(0);
            return R.ok(technician);
        }
        //查出技师评价
        List<GoodsEvaluate> list = goodsEvaluateService.lambdaQuery().in(GoodsEvaluate::getOrderId, orderIdsByTechId.getData()).list();
                //算出平均分并保留一位小数
                BigDecimal avg = list.stream().map(GoodsEvaluate::getGrade).reduce(BigDecimal.ZERO, BigDecimal::add).divide(new BigDecimal(list.size()), 1, BigDecimal.ROUND_HALF_UP);
                technician.setGrade(avg);
                technician.setServeCount(orderIdsByTechId.getData().size());
                    return R.ok(technician);
                 }
           @PostMapping("/shop/tech")
          @ApiOperation(value = "预约操作", tags = {"小程序-门店详情-技师预约"})
          public R<Technician> shoptech(@RequestBody TechnicianSubscribe subscribe){
               Long userId = tokenService.getLoginUserApplet().getUserid();
                subscribe.setAppUserId(userId);
                technicianSubscribeService.save(subscribe);
                return R.ok();
           }
        //算出平均分并保留一位小数
        BigDecimal avg = list.stream().map(GoodsEvaluate::getGrade).reduce(BigDecimal.ZERO, BigDecimal::add).divide(new BigDecimal(list.size()), 1, BigDecimal.ROUND_HALF_UP);
        technician.setGrade(avg);
        technician.setServeCount(orderIdsByTechId.getData().size());
        return R.ok(technician);
    }
    @PostMapping("/shop/tech")
    @ApiOperation(value = "预约操作", tags = {"小程序-门店详情-技师预约"})
    public R<Technician> shoptech(@RequestBody TechnicianSubscribe subscribe) {
        Long userId = tokenService.getLoginUserApplet().getUserid();
        subscribe.setAppUserId(userId);
        technicianSubscribeService.save(subscribe);
        return R.ok();
    }
    /**
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TechnicianSubscribeController.java
@@ -2,6 +2,7 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.page.TableDataInfo;
@@ -19,7 +20,7 @@
/**
 * <p>
 *  前端控制器
 * 前端控制器
 * </p>
 *
 * @author luodangjia
@@ -38,10 +39,10 @@
    @GetMapping("/list")
    @ApiOperation(value = "预约列表", notes = "预约列表", tags = {"小程序-个人中心-门店管理-预约列表"})
    public TableDataInfo list(@ApiParam(value = "状态") @RequestParam Integer status,
                              @ApiParam(value = "门店id") @RequestParam Long shopId){
                              @ApiParam(value = "门店id") @RequestParam Long shopId) {
        startPage();
        List<TechnicianSubscribeVO> list = technicianSubscribeService
                .getTechnicianSubscribeByUserAndShop(SecurityUtils.getUserId(),shopId);
                .getTechnicianSubscribeByUserAndShop(SecurityUtils.getUserId(), shopId);
        return getDataTable(list);
    }
@@ -50,8 +51,8 @@
     */
    @PostMapping("/subscribe")
    @ApiOperation(value = "预约技师", notes = "预约技师", tags = {"小程序-个人中心-门店管理-预约列表-预约技师"})
    public R<Void> subscribe(@RequestBody TechnicianSubscribe technicianSubscribe){
        technicianSubscribeService.subscribe(technicianSubscribe);
    public R<Void> subscribe(@RequestBody TechnicianSubscribe technicianSubscribe) {
        technicianSubscribeService.subscribe(technicianSubscribe, technicianSubscribe.getTechnicianId());
        return R.ok();
    }
@@ -60,12 +61,12 @@
     */
    @GetMapping("/cancel")
    @ApiOperation(value = "取消服务", notes = "取消服务", tags = {"小程序-个人中心-门店管理-预约列表-取消服务"})
    public R<Void> cancel(@ApiParam(value = "预约id") @RequestParam Long id){
    public R<Void> cancel(@ApiParam(value = "预约id") @RequestParam Long id) {
        TechnicianSubscribe subscribe = technicianSubscribeService.getOne(new LambdaQueryWrapper<TechnicianSubscribe>()
                .eq(TechnicianSubscribe::getId, id)
                .eq(TechnicianSubscribe::getStatus, 0));
        if (null == subscribe){
        if (null == subscribe) {
            return R.fail("不满足取消条件");
        }
        subscribe.setStatus(2);
@@ -73,13 +74,30 @@
        return R.ok();
    }
    /**
     * 跟新技师预约状态
     *
     * @param status
     */
    @PutMapping("/updateStatus")
    @ApiOperation(value = "跟新技师预约状态", notes = "跟新技师预约状态", tags = {"后台-技师预约管理-跟新技师预约状态"})
    public R<Void> updateStatus(@ApiParam @RequestParam Integer status, @ApiParam @RequestParam Long subscribeId) {
        boolean update = technicianSubscribeService.update(new LambdaUpdateWrapper<TechnicianSubscribe>()
                .eq(TechnicianSubscribe::getId, subscribeId)
                .set(TechnicianSubscribe::getStatus, status));
        if (!update) {
            return R.fail("更新失败");
        }
        return R.ok();
    }
    @GetMapping("/home/list")
    @ApiOperation(value = "列表", notes = "列表", tags = {"小程序-个人中心-我的预约"})
    public TableDataInfo homelist(@ApiParam(value = "状态 0=待服务,1=已服务,2=已取消 4 已到期") @RequestParam Integer status){
    public TableDataInfo homelist(@ApiParam(value = "状态 0=待服务,1=已服务,2=已取消 4 已到期") @RequestParam Integer status) {
        startPage();
        List<TechnicianSubscribeVO> list = technicianSubscribeService
                .getTechnicianSubscribeByUser(SecurityUtils.getUserId(),status);
                .getTechnicianSubscribeByUser(SecurityUtils.getUserId(), status);
        return getDataTable(list);
    }
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/enums/TechnicianStatus.java
New file
@@ -0,0 +1,26 @@
package com.ruoyi.other.enums;
import lombok.Getter;
@Getter
public enum TechnicianStatus {
    UNSUBSCRIBE(0, "待服务"),
    SERVE(1, "已服务"),
    CANCEL(2, "已取消");
    private final Integer code;
    private final String message;
    TechnicianStatus(Integer code, String message) {
        this.code = code;
        this.message = message;
    }
    public static String getMessage(Integer code) {
        for (TechnicianStatus value : TechnicianStatus.values()) {
            if (value.getCode().equals(code)) {
                return value.getMessage();
            }
        }
        return null;
    }
}
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/TechnicianSubscribeService.java
@@ -20,7 +20,8 @@
     * 查询用于指定门店的相关预约记录
     */
    List<TechnicianSubscribeVO> getTechnicianSubscribeByUserAndShop(Long userId, Long shopId);
    List<TechnicianSubscribeVO> getTechnicianSubscribeByUser(Long userId, Integer status);
    void subscribe(TechnicianSubscribe technicianSubscribe);
    void subscribe(TechnicianSubscribe technicianSubscribe, Long technicianId);
}
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TechnicianSubscribeServiceImpl.java
@@ -1,18 +1,18 @@
package com.ruoyi.other.service.impl;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
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.redis.annotation.DistributedLock;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.other.api.domain.Technician;
import com.ruoyi.other.api.domain.TechnicianSubscribe;
import com.ruoyi.other.enums.TechnicianErrorCode;
import com.ruoyi.other.enums.TechnicianStatus;
import com.ruoyi.other.mapper.TechnicianMapper;
import com.ruoyi.other.mapper.TechnicianSubscribeMapper;
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.time.LocalDateTime;
@@ -43,26 +43,22 @@
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void subscribe(TechnicianSubscribe technicianSubscribe) {
    @DistributedLock(lockNamePre = "#technician_subscribe_lock", lockNamePost = "#technicianId")
    public void subscribe(TechnicianSubscribe subscribe, Long technicianId) {
        Long count = technicianSubscribeMapper.selectCount(new LambdaQueryWrapper<TechnicianSubscribe>()
                .eq(TechnicianSubscribe::getTechnicianId, technicianId)
                .eq(TechnicianSubscribe::getSubscribeTime, subscribe.getSubscribeTime())
                .eq(TechnicianSubscribe::getStatus, TechnicianStatus.UNSUBSCRIBE.getCode()));
        if (count > 0) {
            throw new ServiceException("当前时间段已被预约", TechnicianErrorCode.TECHNICIAN_ALREADY_SUBSCRIBED.getCode());
        }
        // 创建技师预约单
        Long technicianId = technicianSubscribe.getTechnicianId();
        Long userId = SecurityUtils.getUserId();
        TechnicianSubscribe subscribe = new TechnicianSubscribe();
        subscribe.setAppUserId(userId);
        subscribe.setStatus(TechnicianStatus.UNSUBSCRIBE.getCode());
        subscribe.setDelFlag(0);
        subscribe.setCreateTime(LocalDateTime.now());
        technicianSubscribeMapper.insert(subscribe);
        // 更新技师状态
        UpdateWrapper<Technician> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", technicianId);
        updateWrapper.eq("subscribe_status", 1);
        updateWrapper.eq("status", 2);
        updateWrapper.set("subscribe_status", 2);
        updateWrapper.set("create_time", LocalDateTime.now());
        int update = technicianMapper.update(null, updateWrapper);
        if (update == 0){
            throw new ServiceException("该技师已被预约", TechnicianErrorCode.TECHNICIAN_ALREADY_SUBSCRIBED.getCode());
        }
    }
}