Pu Zhibing
4 天以前 890c290afef9faca8ddaf0fea6197c3daa472141
开发商户端预约列表相关接口
22个文件已修改
14个文件已添加
778 ■■■■ 已修改文件
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/poji/shop/ShopAppointableTime.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/poji/shop/ShopNonAppointableTime.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/vo/MerHomeShopTotalVo.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/vo/ShopRelUserVo.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/OauthUserVo.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/QwH5LoginVo.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-auth/src/main/java/com/ruoyi/auth/controller/QwH5Controller.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/domain/dto/AnswerQuestionDto.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/domain/dto/LotteryEventQuestionsDto.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/domain/vo/LotteryEventQuestionsVo.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/domain/vo/CouponInfoVo.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/controller/business/MerShopController.java 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/controller/console/ShopController.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/controller/miniapp/AppHomeController.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/domain/dto/CancelReservationDto.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/domain/dto/MyAppointmentListDto.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/domain/dto/ShopAppointableTimeListDto.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/domain/dto/ShopNonAppointableTimeDto.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/domain/pojo/shop/ShopRelUser.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/domain/vo/MyAppointmentListVo.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/domain/vo/ShopAppointableTimeListVo.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/domain/vo/ShopReservationConfigVo.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/mapper/shop/ShopAppointableTimeMapper.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/mapper/shop/ShopNonAppointableTimeMapper.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/service/impl/shop/ShopAppointableTimeServiceImpl.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/service/impl/shop/ShopNonAppointableTimeServiceImpl.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/service/impl/shop/ShopRelUserServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/service/impl/shop/ShopServiceImpl.java 85 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/service/shop/ShopAppointableTimeService.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/service/shop/ShopNonAppointableTimeService.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/service/shop/ShopRelUserService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/util/TaskUtil.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/resources/mapper/shop/ShopAppointableTimeMapper.xml 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/resources/mapper/shop/ShopNonAppointableTimeMapper.xml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/poji/shop/ShopAppointableTime.java
@@ -34,7 +34,7 @@
     * 预约时间
     */
    @TableField("appointable_time")
    private String appointableTime;
    private LocalDateTime appointableTime;
    /**
     * 状态(0=已取消,1=待确认,2=等待中,3=已结束)
     */
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/poji/shop/ShopNonAppointableTime.java
@@ -8,6 +8,8 @@
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
/**
 * @author zhibing.pu
 * @Date 2025/5/26 14:25
@@ -31,11 +33,11 @@
     */
    @TableField("non_appointable_start_time")
    @ApiModelProperty("不可预约开始时间")
    private String nonAppointableStartTime;
    private LocalDateTime nonAppointableStartTime;
    /**
     * 不可预约结束时间
     */
    @TableField("non_appointable_end_time")
    @ApiModelProperty("不可预约结束时间")
    private String nonAppointableEndTime;
    private LocalDateTime nonAppointableEndTime;
}
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/vo/MerHomeShopTotalVo.java
@@ -45,4 +45,7 @@
    @ApiModelProperty(value = "生日卡1开2关")
    private Integer platformBirthdayFlag;
    @ApiModelProperty(value = "待处理预约单数量")
    private Integer unHandleReserve;
}
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/vo/ShopRelUserVo.java
@@ -9,6 +9,12 @@
    @ApiModelProperty(value="商户id")
    private Long shopId;
    @ApiModelProperty(value = "商户数量")
    private Integer shopNum;
    @ApiModelProperty(value = "商户名称")
    private String shopName;
    @ApiModelProperty(value="用户姓名")
    private String userName;
}
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/OauthUserVo.java
@@ -9,6 +9,12 @@
    @ApiModelProperty(value="商户id")
    private Long shopId;
    @ApiModelProperty(value = "商户数量")
    private Integer shopNum;
    @ApiModelProperty(value = "商户名称")
    private String shopName;
    @ApiModelProperty(value="成员UserID")
    private String userid;
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/QwH5LoginVo.java
@@ -13,6 +13,12 @@
    @ApiModelProperty(value="商户id")
    private Long shopId;
    @ApiModelProperty(value = "商户数量")
    private Integer shopNum;
    @ApiModelProperty(value = "商户名称")
    private String shopName;
    @ApiModelProperty(value="手机")
    private String mobile;
ruoyi-auth/src/main/java/com/ruoyi/auth/controller/QwH5Controller.java
@@ -89,7 +89,7 @@
    }
    @GetMapping("/h5/oauthUser")
    @ApiOperation("通过code获取商户端用户登录")
    @ApiOperation("通过code获取商户端用户登录【2.0】")
    public R<OauthUserVo> oauthUser(@ApiParam(value = "成员授权获取到的code", required = true) @RequestParam("code") String code) throws IOException {
        // 通过code获取访问用户敏感信息
        JSONObject result = qywxInnerService.getOauthUser(code);
ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java
@@ -257,6 +257,8 @@
        }
    
        userInfo.setShopId(shopInfo.getShopId());
        userInfo.setShopName(shopInfo.getShopName());
        userInfo.setShopNum(shopInfo.getShopNum());
        recordLogService.recordLogininfor(username, Constants.LOGIN_SUCCESS, "登录成功",Constants.FROM_SHOP);
        return userInfo;
    }
ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java
@@ -135,6 +135,8 @@
        // 接口返回信息
        OauthUserVo oauthUserVo = new OauthUserVo();
        oauthUserVo.setShopId(qwH5LoginVo.getShopId());
        oauthUserVo.setShopNum(qwH5LoginVo.getShopNum());
        oauthUserVo.setShopName(qwH5LoginVo.getShopName());
        oauthUserVo.setToken(JwtUtils.createToken(claimsMap));
        oauthUserVo.setExpiresIn(EXPIRE_TIME);
        oauthUserVo.setUserid(qwH5LoginVo.getUserid());
ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/domain/dto/AnswerQuestionDto.java
New file
@@ -0,0 +1,18 @@
package com.ruoyi.goods.domain.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data; /**
 * @author zhibing.pu
 * @Date 2025/5/27 10:45
 */
@Data
@ApiModel
public class AnswerQuestionDto {
    @ApiModelProperty(value = "抽奖id")
    private String id;
    @ApiModelProperty(value = "当前题号")
    private Integer current;
    @ApiModelProperty(value = "答案")
    private String answer;
}
ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/domain/dto/LotteryEventQuestionsDto.java
New file
@@ -0,0 +1,18 @@
package com.ruoyi.goods.domain.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data; /**
 * @author zhibing.pu
 * @Date 2025/5/27 10:22
 */
@Data
@ApiModel
public class LotteryEventQuestionsDto {
    @ApiModelProperty(value = "抽奖id")
    private String id;
    @ApiModelProperty(value = "当前题号")
    private Integer current;
    @ApiModelProperty(value = "-1=上一题,1=下一题")
    private Integer stepOrDown;
}
ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/domain/vo/LotteryEventQuestionsVo.java
New file
@@ -0,0 +1,29 @@
package com.ruoyi.goods.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
import java.util.Map;
/**
 * @author zhibing.pu
 * @Date 2025/5/27 10:05
 */
@Data
@ApiModel
public class LotteryEventQuestionsVo {
    @ApiModelProperty(value = "抽奖id")
    private String id;
    @ApiModelProperty("题干名称")
    private String name;
    @ApiModelProperty("总提数")
    private Integer total;
    @ApiModelProperty("当前题数")
    private Integer current;
    @ApiModelProperty("已答答案")
    private String answer;
    @ApiModelProperty("答题选项")
    private List<Map<String, String>> options;
}
ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/domain/vo/CouponInfoVo.java
New file
@@ -0,0 +1,48 @@
package com.ruoyi.member.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
 * @author zhibing.pu
 * @Date 2025/5/27 12:01
 */
@ApiModel
@Data
public class CouponInfoVo {
    @ApiModelProperty(value = "优惠券id")
    private String id;
    @ApiModelProperty(value = "优惠券名称")
    private String name;
    @ApiModelProperty(value = "优惠券类型1.满减2.折扣3.代金4.商品")
    private Integer type;
    @ApiModelProperty(value = "门槛金额")
    private BigDecimal moneyThreshold;
    @ApiModelProperty(value = "折扣")
    private BigDecimal discountPercent;
    @ApiModelProperty(value = "优惠金额")
    private BigDecimal discountMoney;
    @ApiModelProperty(value = "有效期类型1.时间段2.领取之日起")
    private Integer validType;
    @ApiModelProperty(value = "有效期")
    private Integer validDays;
    @ApiModelProperty(value = "有效期开始时间")
    private String validStartTime;
    @ApiModelProperty(value = "有效期结束时间")
    private String validEndTime;
    @ApiModelProperty(value = "使用范围商品")
    private String useGoods;
    @ApiModelProperty(value = "发放限制0否1是")
    private Integer limitFlag;
    @ApiModelProperty(value = "可领数量")
    private Integer receiveNum;
    @ApiModelProperty(value = "剩余数量")
    private Integer laveNum;
    @ApiModelProperty(value = "宣传海报")
    private String propagandaPoster;
    @ApiModelProperty(value = "优惠券状态-1删除0已过期1已领取2已使用")
    private Integer status;
}
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/controller/business/MerShopController.java
@@ -1,27 +1,37 @@
package com.ruoyi.shop.controller.business;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.shop.domain.dto.*;
import com.ruoyi.shop.domain.pojo.shop.ShopRelUser;
import com.ruoyi.shop.domain.vo.MerAgencyPageVo;
import com.ruoyi.shop.domain.vo.MerShopCertificateListVo;
import com.ruoyi.shop.domain.vo.MerShopSuggestVo;
import com.ruoyi.shop.domain.vo.MerchantBasicdataSettlementVo;
import com.ruoyi.shop.domain.vo.*;
import com.ruoyi.shop.service.shop.*;
import com.ruoyi.system.api.domain.dto.*;
import com.ruoyi.system.api.domain.dto.MerBaseDto;
import com.ruoyi.system.api.domain.dto.MerBaseGetDto;
import com.ruoyi.system.api.domain.dto.MerEditUserDto;
import com.ruoyi.system.api.domain.dto.MerPageDto;
import com.ruoyi.system.api.domain.poji.shop.Shop;
import com.ruoyi.system.api.domain.poji.shop.ShopAppointableTime;
import com.ruoyi.system.api.domain.poji.shop.ShopNonAppointableTime;
import com.ruoyi.system.api.domain.vo.MerHomeShopTotalVo;
import com.ruoyi.system.api.domain.vo.MerStaffInfoVo;
import com.ruoyi.system.api.domain.vo.MgtSimpleShopVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.time.format.DateTimeFormatter;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * @author jqs34
@@ -51,13 +61,21 @@
    @Resource
    private ShopSuggestService shopSuggestService;
    @Resource
    private ShopNonAppointableTimeService shopNonAppointableTimeService;
    @Resource
    private ShopAppointableTimeService shopAppointableTimeService;
    /**
     * 未完成实际统计
     *
     * @param merBaseDto
     * @return
     */
    @RequestMapping(value = "/getMerHomeTotal", method = RequestMethod.POST)
    @ApiOperation(value = "获取商户端商业统计")
    @ApiOperation(value = "获取商户端商业统计【2.0】")
    public R<MerHomeShopTotalVo> getMerHomeTotal(@RequestBody MerBaseDto merBaseDto) {
        Long userId = SecurityUtils.getUserId();
        merBaseDto.setUserId(userId);
@@ -102,11 +120,13 @@
    }
    @RequestMapping(value = "/getShopStaffInfo", method = RequestMethod.POST)
    @ApiOperation(value = "获取员工信息")
    public R<MerStaffInfoVo> getShopStaffInfo() {
    @ApiOperation(value = "获取员工信息【2.0】")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "当前商户id", name = "shopId", required = true, dataType = "Long", paramType = "query")
    })
    public R<MerStaffInfoVo> getShopStaffInfo(@RequestParam("shopId") Long shopId) {
        Long userId = SecurityUtils.getUserId();
        ShopRelUser shopRelUser = shopRelUserService.getByUserId(userId);
        Shop shop = shopService.getByShopId(shopRelUser.getShopId());
        Shop shop = shopService.getByShopId(shopId);
        MerStaffInfoVo merStaffInfoVo = shopStaffService.getShopStaffInfo(userId,shop);
        return R.ok(merStaffInfoVo);
    }
@@ -153,15 +173,12 @@
    }
    @RequestMapping(value = "/listShopByShop", method = RequestMethod.POST)
    @ApiOperation(value = "获取商户下属代理商")
    public R<List<MgtSimpleShopVo>> listShopByShop(@RequestBody MerBaseDto merBaseDto)
    {
    public R<List<MgtSimpleShopVo>> listShopByShop(@RequestBody MerBaseDto merBaseDto) {
        List<MgtSimpleShopVo> mgtShopListSimpleVos = shopService.listShopByShop(merBaseDto.getShopId());
        return R.ok(mgtShopListSimpleVos);
    }
    @RequestMapping(value = "/getShopMerchantBasicDataSettlement", method = RequestMethod.POST)
@@ -169,4 +186,104 @@
    public R<List<MerchantBasicdataSettlementVo>> getMerchantBasicDataSettlement(@Validated @RequestBody MerchantBasicdataSettlementDto mgtShopShareRatioSetDto){
        return shopService.getMerchantBasicDataSettlement(mgtShopShareRatioSetDto);
    }
    @RequestMapping(value = "/getUserShopList", method = RequestMethod.POST)
    @ApiOperation(value = "获取切换门店列表【2.0】")
    public R<List<Shop>> getUserShopList() {
        List<ShopRelUser> shopRelUsers = shopRelUserService.getByUserId(SecurityUtils.getUserId());
        shopRelUsers.sort(Comparator.comparing(ShopRelUser::getIsDefault));
        List<Shop> collect = shopRelUsers.stream().map(shopRelUser -> {
            Shop shop = shopService.getById(shopRelUser.getShopId());
            return shop;
        }).collect(Collectors.toList());
        return R.ok(collect);
    }
    @RequestMapping(value = "/getShopReservationConfig/{shopId}", method = RequestMethod.POST)
    @ApiOperation(value = "获取门店预约管理配置【2.0】")
    public R<ShopReservationConfigVo> getShopReservationConfig(@PathVariable("shopId") Long shopId) {
        Shop shop = shopService.getById(shopId);
        Integer subscribe = shop.getSubscribe();
        ShopReservationConfigVo vo = new ShopReservationConfigVo();
        vo.setSubscribe(subscribe);
        List<ShopNonAppointableTime> list = shopNonAppointableTimeService.list(new LambdaQueryWrapper<ShopNonAppointableTime>().eq(ShopNonAppointableTime::getShopId, shopId)
                .orderByAsc(ShopNonAppointableTime::getNonAppointableStartTime));
        vo.setUnsubscribeTime(list.stream().map(shopNonAppointableTime -> {
            Map<String, String> map = new HashMap<>();
            String time = shopNonAppointableTime.getNonAppointableStartTime().format(DateTimeFormatter.ofPattern("MM月dd日 HH:mm")) + "-" + shopNonAppointableTime.getNonAppointableEndTime().format(DateTimeFormatter.ofPattern("HH:mm"));
            map.put("time", time);
            map.put("id", shopNonAppointableTime.getId());
            return map;
        }).collect(Collectors.toList()));
        return R.ok(vo);
    }
    @RequestMapping(value = "/addShopNonAppointableTime", method = RequestMethod.POST)
    @ApiOperation(value = "门店添加不可预约时间段【2.0】")
    public R addShopNonAppointableTime(@RequestBody ShopNonAppointableTimeDto dto) {
        ShopNonAppointableTime shopNonAppointableTime = new ShopNonAppointableTime();
        shopNonAppointableTime.setShopId(dto.getShopId());
        shopNonAppointableTime.setNonAppointableStartTime(dto.getNonAppointableStartTime());
        shopNonAppointableTime.setNonAppointableEndTime(dto.getNonAppointableEndTime());
        shopNonAppointableTimeService.save(shopNonAppointableTime);
        return R.ok();
    }
    @RequestMapping(value = "/switchAppointment/{shopId}/{subscribe}", method = RequestMethod.POST)
    @ApiOperation(value = "开关门店预约配置【2.0】")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "门店id", name = "shopId", required = true, dataType = "Long", paramType = "path"),
            @ApiImplicitParam(value = "预约开关(0=关,1=开)", name = "subscribe", required = true, dataType = "Integer", paramType = "path")
    })
    public R switchAppointment(@PathVariable("shopId") Long shopId, @PathVariable("subscribe") Integer subscribe) {
        Shop shop = shopService.getById(shopId);
        shop.setSubscribe(subscribe);
        shopService.updateById(shop);
        return R.ok();
    }
    @RequestMapping(value = "/getShopAppointableTimeList", method = RequestMethod.POST)
    @ApiOperation(value = "商户获取预约列表【2.0】")
    public R<Page<ShopAppointableTimeListVo>> getShopAppointableTimeList(@RequestBody ShopAppointableTimeListDto dto) {
        Page<ShopAppointableTimeListVo> page = new Page<>();
        page.setSize(dto.getPageSize());
        page.setCurrent(dto.getPageNum());
        List<ShopAppointableTimeListVo> shopAppointableTimeList = shopAppointableTimeService.getShopAppointableTimeList(page, dto);
        return R.ok(page.setRecords(shopAppointableTimeList));
    }
    @RequestMapping(value = "/confirmReservation/{id}", method = RequestMethod.POST)
    @ApiOperation(value = "商户确认预约【2.0】")
    public R confirmReservation(@PathVariable("id") String id) {
        ShopAppointableTime shopAppointableTime = shopAppointableTimeService.getById(id);
        if (null == shopAppointableTime) {
            return R.fail("预约不存在");
        }
        if (1 != shopAppointableTime.getStatus()) {
            return R.fail("确认预约失败");
        }
        shopAppointableTime.setStatus(2);
        shopAppointableTimeService.updateById(shopAppointableTime);
        return R.ok();
    }
    @RequestMapping(value = "/cancelReservation", method = RequestMethod.POST)
    @ApiOperation(value = "商户取消预约【2.0】")
    public R cancelReservation(@RequestBody CancelReservationDto dto) {
        ShopAppointableTime shopAppointableTime = shopAppointableTimeService.getById(dto.getId());
        if (null == shopAppointableTime) {
            return R.fail("预约不存在");
        }
        if (0 == shopAppointableTime.getStatus()) {
            return R.fail("不能重复操作");
        }
        shopAppointableTime.setStatus(0);
        shopAppointableTime.setReason(dto.getReason());
        shopAppointableTimeService.updateById(shopAppointableTime);
        return R.ok();
    }
}
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/controller/console/ShopController.java
@@ -1,7 +1,6 @@
package com.ruoyi.shop.controller.console;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.ruoyi.common.core.constant.CacheConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.ServiceException;
@@ -16,7 +15,6 @@
import com.ruoyi.system.api.constant.AppErrorConstant;
import com.ruoyi.system.api.domain.dto.*;
import com.ruoyi.system.api.domain.poji.shop.Shop;
import com.ruoyi.system.api.domain.vo.ShopProportionVo;
import com.ruoyi.system.api.domain.poji.sys.SysUser;
import com.ruoyi.system.api.domain.vo.*;
import com.ruoyi.system.api.model.QwH5LoginVo;
@@ -32,7 +30,6 @@
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
 * @author jqs34
@@ -174,17 +171,20 @@
    @PostMapping("/getShopByUserId")
    public R<ShopRelUserVo> getShopByUserId(@RequestBody Long userId)
    {
        ShopRelUser shopRelUser = shopRelUserService.getByUserId(userId);
        List<ShopRelUser> shopRelUser = shopRelUserService.getByUserId(userId);
        Optional.ofNullable(shopRelUser).orElseThrow(() -> new ServiceException("未查询到用户关联商户"));
        ShopRelUserVo shopRelUserVo = new ShopRelUserVo();
        shopRelUserVo.setShopId(shopRelUser.getShopId());
        shopRelUserVo.setUserName(shopRelUser.getUserName());
        ShopRelUser shopRelUser1 = shopRelUser.stream().filter(s -> s.getIsDefault() == 1).collect(Collectors.toList()).get(0);
        shopRelUserVo.setShopId(shopRelUser1.getShopId());
        shopRelUserVo.setUserName(shopRelUser1.getUserName());
        Shop shop = shopService.getById(shopRelUser1.getShopId());
        shopRelUserVo.setShopName(shop.getShopName());
        shopRelUserVo.setShopNum(shopRelUser.size());
        return R.ok(shopRelUserVo);
    }
    @PostMapping("/getShopByBelongUserId")
    public R<ShopRelUserVo> getShopByBelongUserId(@RequestBody Long userId)
    {
    public R<ShopRelUserVo> getShopByBelongUserId(@RequestBody Long userId) {
        List<Shop> shopList = shopService.getShopByBelongUserId(userId);
        Optional.ofNullable(shopList.get(0)).orElseThrow(() -> new ServiceException("未查询到商户信息"));
        ShopRelUserVo shopRelUserVo = new ShopRelUserVo();
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/controller/miniapp/AppHomeController.java
@@ -3,7 +3,7 @@
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.shop.domain.dto.AppNearbyShopDto;
@@ -28,6 +28,7 @@
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
/**
@@ -82,7 +83,7 @@
    @ApiOperation(value = "获取商户不可预约时间段【2.0】")
    public R<List<ShopNonAppointableTime>> getShopAppointmentTime(@RequestBody ShopAppointmentTimeDto dto) {
        List<ShopNonAppointableTime> list = shopNonAppointableTimeService.list(new QueryWrapper<ShopNonAppointableTime>().eq("shop_id", dto.getId())
                .last(" and '" + dto.getDate() + "' like CONCAT('%', non_appointable_start_time, '%') order by non_appointable_start_time"));
                .last(" and '" + dto.getDate() + "' = DATE(non_appointable_start_time) order by non_appointable_start_time"));
        return R.ok(list);
    }
    
@@ -90,14 +91,14 @@
    @ApiOperation(value = "门店详情预约操作【2.0】")
    public R appointmentTime(@RequestBody AppointmentTimeDto dto) {
        ShopAppointableTime one = shopAppointableTimeService.getOne(new LambdaQueryWrapper<ShopAppointableTime>().eq(ShopAppointableTime::getShopId, dto.getShopId())
                .eq(ShopAppointableTime::getAppointableTime, dto.getTime()));
                .last(" and DATE_FORMAT(appointable_time, '%Y-%m-%d %H:%i') = '" + dto.getTime() + "'"));
        if (null != one) {
            return R.fail("不能重复预约");
        }
        Long userId = SecurityUtils.getUserId();
        one = new ShopAppointableTime();
        one.setShopId(dto.getShopId());
        one.setAppointableTime(dto.getTime());
        one.setAppointableTime(LocalDateTime.parse(dto.getTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));
        one.setUserId(userId);
        one.setStatus(1);
        one.setCreateTime(LocalDateTime.now());
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/domain/dto/CancelReservationDto.java
New file
@@ -0,0 +1,16 @@
package com.ruoyi.shop.domain.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data; /**
 * @author zhibing.pu
 * @Date 2025/6/3 16:08
 */
@Data
@ApiModel
public class CancelReservationDto {
    @ApiModelProperty(value = "预约id")
    private String id;
    @ApiModelProperty(value = "取消原因")
    private String reason;
}
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/domain/dto/MyAppointmentListDto.java
New file
@@ -0,0 +1,20 @@
package com.ruoyi.shop.domain.dto;
import com.ruoyi.system.api.domain.dto.MgtBaseDto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author zhibing.pu
 * @Date 2025/5/27 14:29
 */
@ApiModel
@Data
public class MyAppointmentListDto extends MgtBaseDto {
    @ApiModelProperty("页码,首页1")
    private Integer pageNum;
    @ApiModelProperty("页查询条数")
    private Integer pageSize;
    @ApiModelProperty("状态(0=已取消,1=待确认,2=等待中,3=已结束)")
    private Integer status;
}
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/domain/dto/ShopAppointableTimeListDto.java
New file
@@ -0,0 +1,17 @@
package com.ruoyi.shop.domain.dto;
import com.ruoyi.system.api.domain.dto.MgtPageDto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data; /**
 * @author zhibing.pu
 * @Date 2025/6/3 15:17
 */
@Data
@ApiModel
public class ShopAppointableTimeListDto extends MgtPageDto {
    @ApiModelProperty(value = "商户id")
    private Integer shopId;
    @ApiModelProperty(value = "状态(0=已取消,1=待确认,2=等待中,3=已结束)")
    private Integer status;
}
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/domain/dto/ShopNonAppointableTimeDto.java
New file
@@ -0,0 +1,23 @@
package com.ruoyi.shop.domain.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime; /**
 * @author zhibing.pu
 * @Date 2025/6/3 14:59
 */
@Data
@ApiModel
public class ShopNonAppointableTimeDto {
    @ApiModelProperty("门店id")
    private Integer shopId;
    @ApiModelProperty("不可预约开始时间(yyyy-MM-dd HH:mm:ss)")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime nonAppointableStartTime;
    @ApiModelProperty("不可预约结束时间(yyyy-MM-dd HH:mm:ss)")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime nonAppointableEndTime;
}
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/domain/pojo/shop/ShopRelUser.java
@@ -1,15 +1,15 @@
package com.ruoyi.shop.domain.pojo.shop;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.activerecord.Model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
 * <p>
@@ -40,6 +40,11 @@
    @TableField("shop_id")
    private Long shopId;
    /**
     * 默认门店(0=否,1=是)
     */
    @TableField("is_default")
    private Integer isDefault;
    /**
     * 用户id
     */
    @TableField("user_id")
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/domain/vo/MyAppointmentListVo.java
New file
@@ -0,0 +1,22 @@
package com.ruoyi.shop.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data; /**
 * @author zhibing.pu
 * @Date 2025/5/27 14:32
 */
@Data
@ApiModel
public class MyAppointmentListVo {
    @ApiModelProperty(value = "预约id")
    private String id;
    @ApiModelProperty(value = "预约时间")
    private String appointmentTime;
    @ApiModelProperty(value = "预约状态(0=已取消,1=待确认,2=等待中,3=已结束)")
    private Integer status;
    @ApiModelProperty(value = "预约门店")
    private String shopName;
    @ApiModelProperty(value = "商家取消原因")
    private String cancelReason;
}
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/domain/vo/ShopAppointableTimeListVo.java
New file
@@ -0,0 +1,28 @@
package com.ruoyi.shop.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
/**
 * @author zhibing.pu
 * @Date 2025/6/3 15:19
 */
@Data
@ApiModel
public class ShopAppointableTimeListVo {
    @ApiModelProperty("预约数据id")
    private String id;
    @ApiModelProperty("预约时间")
    private LocalDateTime appointableTime;
    @ApiModelProperty("预约状态(0=已取消,1=待确认,2=等待中,3=已结束)")
    private Integer status;
    @ApiModelProperty("预约人")
    private String userName;
    @ApiModelProperty("预约人手机号")
    private String mobile;
    @ApiModelProperty("预约人性别")
    private String sex;
}
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/domain/vo/ShopReservationConfigVo.java
New file
@@ -0,0 +1,22 @@
package com.ruoyi.shop.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
import java.util.Map;
/**
 * @author zhibing.pu
 * @Date 2025/6/3 14:26
 */
@Data
@ApiModel
public class ShopReservationConfigVo {
    @ApiModelProperty("预约开关(0=关,1=开)")
    private Integer subscribe;
    @ApiModelProperty("不可预约时段")
    private List<Map<String, String>> unsubscribeTime;
}
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/mapper/shop/ShopAppointableTimeMapper.java
@@ -1,8 +1,10 @@
package com.ruoyi.shop.mapper.shop;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.shop.domain.dto.ShopAppointableTimeListDto;
import com.ruoyi.shop.domain.vo.MyAppointmentListVo;
import com.ruoyi.shop.domain.vo.ShopAppointableTimeListVo;
import com.ruoyi.system.api.domain.poji.shop.ShopAppointableTime;
import org.apache.ibatis.annotations.Param;
@@ -24,4 +26,20 @@
     * @return
     */
    List<MyAppointmentListVo> pageMyAppointmentList(Page<MyAppointmentListVo> page, @Param("userId") Long userId, @Param("status") Integer status);
    /**
     * 商户端获取预约列表数据
     *
     * @param page
     * @param dto
     * @return
     */
    List<ShopAppointableTime> getShopAppointableTimeList(Page<ShopAppointableTimeListVo> page, @Param("item") ShopAppointableTimeListDto dto);
    /**
     * 定时任务修改预约状态
     */
    void taskUpdateStatus();
}
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/mapper/shop/ShopNonAppointableTimeMapper.java
@@ -8,4 +8,10 @@
 * @Date 2025/5/26 14:31
 */
public interface ShopNonAppointableTimeMapper extends BaseMapper<ShopNonAppointableTime> {
    /**
     * 每天凌晨3点删除3天前的数据
     */
    void taskDelData();
}
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/service/impl/shop/ShopAppointableTimeServiceImpl.java
@@ -1,15 +1,21 @@
package com.ruoyi.shop.service.impl.shop;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.plugins.Page;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.shop.domain.dto.MyAppointmentListDto;
import com.ruoyi.shop.domain.dto.ShopAppointableTimeListDto;
import com.ruoyi.shop.domain.vo.MyAppointmentListVo;
import com.ruoyi.shop.domain.vo.ShopAppointableTimeListVo;
import com.ruoyi.shop.mapper.shop.ShopAppointableTimeMapper;
import com.ruoyi.shop.service.shop.ShopAppointableTimeService;
import com.ruoyi.system.api.domain.poji.member.Member;
import com.ruoyi.system.api.domain.poji.shop.ShopAppointableTime;
import com.ruoyi.system.api.service.RemoteMemberService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
@@ -18,6 +24,9 @@
 */
@Service
public class ShopAppointableTimeServiceImpl extends ServiceImpl<ShopAppointableTimeMapper, ShopAppointableTime> implements ShopAppointableTimeService {
    @Resource
    private RemoteMemberService remoteMemberService;
    
    
    /**
@@ -32,4 +41,39 @@
        Long userId = SecurityUtils.getUserId();
        return this.baseMapper.pageMyAppointmentList(page, userId, dto.getStatus());
    }
    /**
     * 商户端获取预约列表
     *
     * @param page
     * @param dto
     * @return
     */
    @Override
    public List<ShopAppointableTimeListVo> getShopAppointableTimeList(Page<ShopAppointableTimeListVo> page, ShopAppointableTimeListDto dto) {
        List<ShopAppointableTime> shopAppointableTimeList = this.baseMapper.getShopAppointableTimeList(page, dto);
        List<ShopAppointableTimeListVo> list = new ArrayList<>();
        shopAppointableTimeList.forEach(shopAppointableTime -> {
            ShopAppointableTimeListVo shopAppointableTimeListVo = new ShopAppointableTimeListVo();
            shopAppointableTimeListVo.setId(shopAppointableTime.getId());
            shopAppointableTimeListVo.setAppointableTime(shopAppointableTime.getAppointableTime());
            shopAppointableTimeListVo.setStatus(shopAppointableTime.getStatus());
            Member member = remoteMemberService.getMember(shopAppointableTime.getUserId()).getData();
            shopAppointableTimeListVo.setUserName(member.getRealName());
            shopAppointableTimeListVo.setMobile(member.getMobile());
            shopAppointableTimeListVo.setSex(member.getGender() == 1 ? "女" : member.getGender() == 0 ? "男" : "未知");
            list.add(shopAppointableTimeListVo);
        });
        return list;
    }
    /**
     * 定时任务修改预约状态
     */
    @Override
    public void taskUpdateStatus() {
        this.baseMapper.taskUpdateStatus();
    }
}
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/service/impl/shop/ShopNonAppointableTimeServiceImpl.java
@@ -12,4 +12,13 @@
 */
@Service
public class ShopNonAppointableTimeServiceImpl extends ServiceImpl<ShopNonAppointableTimeMapper, ShopNonAppointableTime> implements ShopNonAppointableTimeService {
    /**
     * 每天凌晨3点删除3天前的数据
     */
    @Override
    public void taskDelData() {
        this.baseMapper.taskDelData();
    }
}
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/service/impl/shop/ShopRelUserServiceImpl.java
@@ -3,10 +3,10 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.shop.domain.pojo.shop.ShopRelUser;
import com.ruoyi.shop.mapper.shop.ShopRelUserMapper;
import com.ruoyi.shop.service.shop.ShopRelUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@@ -59,15 +59,14 @@
    /**
     *
     * @param userId
     * @return
     */
    @Override
    public ShopRelUser getByUserId(Long userId){
    public List<ShopRelUser> getByUserId(Long userId) {
        LambdaQueryWrapper<ShopRelUser> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(ShopRelUser::getDelFlag, 0).eq(ShopRelUser::getUserId, userId);
        return this.getOne(queryWrapper,false);
        return this.list(queryWrapper);
    }
    /**
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/service/impl/shop/ShopServiceImpl.java
@@ -1,6 +1,5 @@
package com.ruoyi.shop.service.impl.shop;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -8,7 +7,6 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.github.binarywang.wxpay.bean.ecommerce.ApplymentsResult;
import com.github.binarywang.wxpay.bean.ecommerce.ApplymentsStatusResult;
import com.github.binarywang.wxpay.bean.ecommerce.ProfitSharingReceiverRequest;
@@ -18,7 +16,6 @@
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.ExceptionUtil;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.bean.BeanUtils;
import com.ruoyi.common.core.utils.uuid.IdUtils;
@@ -46,20 +43,18 @@
import com.ruoyi.system.api.domain.poji.config.SysTag;
import com.ruoyi.system.api.domain.poji.member.Member;
import com.ruoyi.system.api.domain.poji.shop.Shop;
import com.ruoyi.system.api.domain.poji.shop.ShopAppointableTime;
import com.ruoyi.system.api.domain.poji.sys.SysUser;
import com.ruoyi.system.api.domain.vo.*;
import com.ruoyi.system.api.service.*;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.rmi.ServerException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -151,9 +146,11 @@
    @Resource
    private RemoteUserService remoteUserService;
    @Resource
    private ShopAppointableTimeService shopAppointableTimeService;
    @Value("${callback_path}")
    private String callback_path;
    /**
@@ -194,6 +191,7 @@
    /**
     * 创建商户
     *
     * @param mgtEditShopDto
     */
    @Override
@@ -203,32 +201,32 @@
        BigDecimal zeroBig = BigDecimal.ZERO;
        //验证关联账号唯一
        String relUserIds = mgtEditShopDto.getRelUserIds();
        if(StringUtils.isNotBlank(relUserIds)) {
            if(relUserIds.startsWith(",")){
                relUserIds = relUserIds.substring(1);
            }
            String[] relUserIdArray = relUserIds.split(",");
            ShopRelUser shopRelUser;
            Long userId;
            if(mgtEditShopDto.getShopId()!=null){
                for (String str : relUserIdArray) {
                    userId = Long.valueOf(str);
                    shopRelUser = shopRelUserService.getByUserId(userId);
                    if(shopRelUser!=null&&!shopRelUser.getShopId().equals(mgtEditShopDto.getShopId())){
                        throw new ServiceException(AppErrorConstant.SHOP_USER_DOUBLE);
                    }
                }
            }else {
                for (String str : relUserIdArray) {
                    userId = Long.valueOf(str);
                    shopRelUser = shopRelUserService.getByUserId(userId);
                    if(shopRelUser!=null){
                        throw new ServiceException(AppErrorConstant.SHOP_USER_DOUBLE);
                    }
                }
            }
        }
//        if(StringUtils.isNotBlank(relUserIds)) {
//            if(relUserIds.startsWith(",")){
//                relUserIds = relUserIds.substring(1);
//            }
//            String[] relUserIdArray = relUserIds.split(",");
//            ShopRelUser shopRelUser;
//            Long userId;
//            if(mgtEditShopDto.getShopId()!=null){
//                for (String str : relUserIdArray) {
//                    userId = Long.valueOf(str);
//                    shopRelUser = shopRelUserService.getByUserId(userId);
//                    if(shopRelUser!=null&&!shopRelUser.getShopId().equals(mgtEditShopDto.getShopId())){
//                        throw new ServiceException(AppErrorConstant.SHOP_USER_DOUBLE);
//                    }
//                }
//            }else {
//                for (String str : relUserIdArray) {
//                    userId = Long.valueOf(str);
//                    shopRelUser = shopRelUserService.getByUserId(userId);
//                    if(shopRelUser!=null){
//                        throw new ServiceException(AppErrorConstant.SHOP_USER_DOUBLE);
//                    }
//                }
//            }
//
//        }
        //验证商户名唯一
        //Shop shopSame = this.getOne(new LambdaQueryWrapper<Shop>().eq(Shop::getDelFlag,0).eq(Shop::getShopName,mgtEditShopDto.getShopName()));
        if(mgtEditShopDto.getShopId()!=null){
@@ -918,8 +916,10 @@
        staffHomeShopTotalVo.setShopTask(shopTaskCount);
        return staffHomeShopTotalVo;
    }
    /**
     * 获取商户端
     *
     * @param merBaseDto
     * @return
     */
@@ -927,14 +927,13 @@
    public MerHomeShopTotalVo getMerHomeTotal(MerBaseDto merBaseDto){
        Long userId = merBaseDto.getUserId();
        MerHomeShopTotalVo merHomeShopTotalVo = new MerHomeShopTotalVo();
        ShopRelUser shopRelUser = shopRelUserService.getByUserId(userId);
        Long shopId = shopRelUser.getShopId();
        Long shopId = merBaseDto.getShopId();
        //如果商户变动刷新token
        if(!shopId.equals(merBaseDto.getShopId())){
            String userKey = SecurityUtils.getUserKey();
            redisService.deleteObject(CacheConstants.LOGIN_TOKEN_KEY+userKey);
            throw new ServiceException("登录状态已过期",401);
        }
//        if(!shopId.equals(merBaseDto.getShopId())){
//            String userKey = SecurityUtils.getUserKey();
//            redisService.deleteObject(CacheConstants.LOGIN_TOKEN_KEY+userKey);
//            throw new ServiceException("登录状态已过期",401);
//        }
        merHomeShopTotalVo.setShopId(shopId);
        Shop shop = this.getById(shopId);
        if(shop.getFrozenFlag()==1){
@@ -955,6 +954,8 @@
        merHomeShopTotalVo.setExplorationSurp(orderVo.getExplorationSurp());
        merHomeShopTotalVo.setPlatformBirthdayFlag(shop.getPlatformBirthdayFlag());
        merHomeShopTotalVo.setPlatformCouponFlag(shop.getPlatformCouponFlag());
        int unHandleReserve = shopAppointableTimeService.count(new LambdaQueryWrapper<ShopAppointableTime>().eq(ShopAppointableTime::getShopId, shopId).eq(ShopAppointableTime::getStatus, 1));
        merHomeShopTotalVo.setUnHandleReserve(unHandleReserve);
        return merHomeShopTotalVo;
    }
@@ -1456,11 +1457,11 @@
    }
    /**
     * @param userId
     * @return Shop
     * @description  获取用户管理商户
     * @author  jqs
     * @date    2023/7/14 10:00
     * @param userId
     * @return  Shop
     */
    @Override
    public List<Shop> getShopByBelongUserId(Long userId){
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/service/shop/ShopAppointableTimeService.java
@@ -1,9 +1,11 @@
package com.ruoyi.shop.service.shop;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.plugins.Page;
import com.ruoyi.shop.domain.dto.MyAppointmentListDto;
import com.ruoyi.shop.domain.dto.ShopAppointableTimeListDto;
import com.ruoyi.shop.domain.vo.MyAppointmentListVo;
import com.ruoyi.shop.domain.vo.ShopAppointableTimeListVo;
import com.ruoyi.system.api.domain.poji.shop.ShopAppointableTime;
import java.util.List;
@@ -23,4 +25,20 @@
     * @return
     */
    List<MyAppointmentListVo> pageMyAppointmentList(Page<MyAppointmentListVo> page, MyAppointmentListDto dto);
    /**
     * 商户端获取预约列表
     *
     * @param page
     * @param dto
     * @return
     */
    List<ShopAppointableTimeListVo> getShopAppointableTimeList(Page<ShopAppointableTimeListVo> page, ShopAppointableTimeListDto dto);
    /**
     * 定时任务修改预约状态
     */
    void taskUpdateStatus();
}
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/service/shop/ShopNonAppointableTimeService.java
@@ -8,4 +8,10 @@
 * @Date 2025/5/26 14:30
 */
public interface ShopNonAppointableTimeService extends IService<ShopNonAppointableTime> {
    /**
     * 每天凌晨3点删除3天前的数据
     */
    void taskDelData();
}
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/service/shop/ShopRelUserService.java
@@ -1,7 +1,7 @@
package com.ruoyi.shop.service.shop;
import com.ruoyi.shop.domain.pojo.shop.ShopRelUser;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.shop.domain.pojo.shop.ShopRelUser;
import java.util.List;
@@ -33,7 +33,7 @@
     * @param userId
     * @return
     */
    ShopRelUser getByUserId(Long userId);
    List<ShopRelUser> getByUserId(Long userId);
    /**
     * 通过用户id删除关联
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/util/TaskUtil.java
New file
@@ -0,0 +1,40 @@
package com.ruoyi.shop.util;
import com.ruoyi.shop.service.shop.ShopAppointableTimeService;
import com.ruoyi.shop.service.shop.ShopNonAppointableTimeService;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
 * @author zhibing.pu
 * @Date 2025/6/3 16:11
 */
@Component
public class TaskUtil {
    @Resource
    private ShopAppointableTimeService shopAppointableTimeService;
    @Resource
    private ShopNonAppointableTimeService shopNonAppointableTimeService;
    /**
     * 每天3点执行的定时任务
     */
    @Scheduled(cron="0 0 3 * * ?")
    public void timingTask(){
        shopNonAppointableTimeService.taskDelData();
    }
    /**
     * 每分钟执行的定时任务
     */
    @Scheduled(cron="0 0/1 * * * ?")
    public void timingTask1(){
        shopAppointableTimeService.taskUpdateStatus();
    }
}
ruoyi-modules/ruoyi-shop/src/main/resources/mapper/shop/ShopAppointableTimeMapper.xml
New file
@@ -0,0 +1,44 @@
<?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="com.ruoyi.shop.mapper.shop.ShopAppointableTimeMapper">
    <select id="pageMyAppointmentList" resultType="com.ruoyi.shop.domain.vo.MyAppointmentListVo">
        select * from (
            select
            a.id,
            DATE_FORMAT(a.appointable_time,  '%Y-%m-%d %H:%i') as appointmentTime,
            a.status,
            b.shop_name as shopName,
            a.reason as cancelReason,
            CASE WHEN a.`status` in (1, 2) THEN 1 WHEN a.`status` = 3 THEN 2 ELSE 3 END as sort
            from t_shop_appointable_time a
            left join t_shop b on (a.shop_id = b.shop_id)
            where a.user_id = #{userId}
            <if test="status != null">
                and a.status = #{status}
            </if>
        ) as aa order by aa.sort, aa.appointmentTime
    </select>
    <select id="getShopAppointableTimeList" resultType="com.ruoyi.system.api.domain.poji.shop.ShopAppointableTime">
        select * from (
            select
                a.*,
                CASE WHEN a.`status` = 3 THEN 3 WHEN a.`status` = 0 THEN 2 ELSE 1 END as sort
            from t_shop_appointable_time a where shop_id = #{item.shopId}
           <if test="null != item.status">
               and a.status = #{item.status}
           </if>
        ) as aa order by aa.sort,aa.appointable_time
    </select>
    <update id="taskUpdateStatus">
        update t_shop_appointable_time set status = 3 where status in (1, 2) and appointment_time &lt; now()
    </update>
</mapper>
ruoyi-modules/ruoyi-shop/src/main/resources/mapper/shop/ShopNonAppointableTimeMapper.xml
New file
@@ -0,0 +1,10 @@
<?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="com.ruoyi.shop.mapper.shop.ShopNonAppointableTimeMapper">
    <delete id="taskDelData">
        delete from t_shop_non_appointable_time where DATE(non_appointable_start_time) &lt; DATE(DATE_SUB(NOW(), INTERVAL 3 DAY))
    </delete>
</mapper>