hjl
2024-07-01 03c6572c7918beaa20365e69c9694a11f0d9948a
feat: 代码初始化
1 文件已重命名
66个文件已修改
8个文件已添加
2193 ■■■■ 已修改文件
ruoyi-api/ruoyi-api-admin/src/main/java/com/ruoyi/admin/api/entity/Order.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ObsUploadUtil.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/KaptchaTextCreator.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPermissionServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/pom.xml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/config/WebSocketConfig.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/AgreementController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/EvaluateController.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/HomePageController.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/OrderController.java 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/OssController.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/ProblemController.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/RecoveryClassifyController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/RecoveryServeController.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/RoleController.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/RoleMenuController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/RotateController.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/SiteController.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/UserController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/UserManageController.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/WithdrawController.java 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/entity/MasterWorker.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/entity/Order.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/entity/User.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/entity/Withdraw.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/entity/WorkerProcess.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/mapper/EvaluateMapper.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/mapper/OrderMapper.java 47 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/mapper/UserMapper.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/mapper/WithdrawMapper.java 47 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/request/OrderCountRequest.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/request/OrderQueryRequest.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/request/WithdrawExportRequest.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/EvaluateService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/MasterWorkerService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/OrderService.java 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/UserService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/WithdrawService.java 45 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/impl/AgreementServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/impl/EvaluateServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/impl/MasterWorkerServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/impl/OrderServiceImpl.java 81 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/impl/UserServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/impl/WithdrawServiceImpl.java 174 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/impl/WorkerProcessServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/sorcket/WebSocketClient.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/sorcket/WebSocketServer.java 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/utils/vx/HttpUtil.java 195 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/utils/vx/WechatPayV3Util.java 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/vo/OrderPageCountVO.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/vo/UserWithdrawRecordVO.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/resources/mapper/admin/EvaluateMapper.xml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/resources/mapper/admin/OrderMapper.xml 165 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/resources/mapper/admin/UserMapper.xml 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/resources/mapper/admin/WithdrawMapper.xml 89 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/resources/template/提现记录.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-user/src/main/java/com/ruoyi/user/controller/OrderController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-user/src/main/java/com/ruoyi/user/entity/Order.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-user/src/main/java/com/ruoyi/user/entity/Withdraw.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-user/src/main/resources/mapper/user/RecoveryServeMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-user/src/main/resources/mapper/user/UserMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-user/src/main/resources/mapper/user/WithdrawMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/controller/MasterWorkerController.java 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/controller/OssController.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/entity/MasterWorker.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/entity/Order.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/entity/WorkerProcess.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/service/MasterWorkerService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/service/impl/MasterWorkerServiceImpl.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/vo/OrderListVO.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-worker/src/main/resources/mapper/worker/MasterWorkerMapper.xml 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-worker/src/main/resources/mapper/worker/WorkerProcessMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-visual/ruoyi-monitor/src/main/java/com/ruoyi/modules/monitor/config/WebSecurityConfigurer.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-admin/src/main/java/com/ruoyi/admin/api/entity/Order.java
@@ -28,6 +28,14 @@
    @TableId("id")
    private Integer id;
    @ApiModelProperty("下单城市")
    @TableField("city")
    private String city;
    @ApiModelProperty("订单编号")
    @TableField("order_number")
    private String orderNumber;
    @ApiModelProperty("站点id")
    @TableField("site_id")
    private Integer siteId;
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java
@@ -213,6 +213,11 @@
    public static final Integer THREE = 3;
    /**
     * 数字4
     */
    public static final Integer FOUR = 4;
    /**
     * 数字5
     */
    public static final Integer FIVE = 5;
@@ -253,6 +258,11 @@
    public static final String DEFAULT_PASSWORD = "123456";
    /**
     * 三端默认验证码
     */
    public static final String DEFAULT_PHONE_CODE = "123456";
    /**
     * 手机号码正则
     */
    public static final String PHONE = "^1[34578]\\d{9}$";
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ObsUploadUtil.java
File was renamed from ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/utils/ObsUploadUtil.java
@@ -1,4 +1,4 @@
package com.ruoyi.admin.utils;
package com.ruoyi.common.core.utils;
import com.obs.services.ObsClient;
import com.obs.services.model.ObjectMetadata;
ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/KaptchaTextCreator.java
@@ -1,69 +1,55 @@
package com.ruoyi.gateway.config;
import java.util.Random;
import com.google.code.kaptcha.text.impl.DefaultTextCreator;
import java.util.Random;
/**
 * 验证码文本生成器
 *
 *
 * @author ruoyi
 */
public class KaptchaTextCreator extends DefaultTextCreator
{
public class KaptchaTextCreator extends DefaultTextCreator {
    private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(",");
    @Override
    public String getText()
    {
    public String getText() {
        Integer result = 0;
        Random random = new Random();
        int x = random.nextInt(10);
        int y = random.nextInt(10);
        StringBuilder suChinese = new StringBuilder();
        int randomoperands = random.nextInt(3);
        if (randomoperands == 0)
        {
        if (randomoperands == 0) {
            result = x * y;
            suChinese.append(CNUMBERS[x]);
            suChinese.append("*");
            suChinese.append(CNUMBERS[y]);
        }
        else if (randomoperands == 1)
        {
            if ((x != 0) && y % x == 0)
            {
        } else if (randomoperands == 1) {
            if ((x != 0) && y % x == 0) {
                result = y / x;
                suChinese.append(CNUMBERS[y]);
                suChinese.append("/");
                suChinese.append(CNUMBERS[x]);
            }
            else
            {
            } else {
                result = x + y;
                suChinese.append(CNUMBERS[x]);
                suChinese.append("+");
                suChinese.append(CNUMBERS[y]);
            }
        }
        else if (randomoperands == 2)
        {
            if (x >= y)
            {
        } else if (randomoperands == 2) {
            if (x >= y) {
                result = x - y;
                suChinese.append(CNUMBERS[x]);
                suChinese.append("-");
                suChinese.append(CNUMBERS[y]);
            }
            else
            {
            } else {
                result = y - x;
                suChinese.append(CNUMBERS[y]);
                suChinese.append("-");
                suChinese.append(CNUMBERS[x]);
            }
        }
        else
        {
        } else {
            result = x + y;
            suChinese.append(CNUMBERS[x]);
            suChinese.append("+");
ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java
@@ -69,7 +69,7 @@
        }
        String userid = JwtUtils.getUserId(claims);
        String username = JwtUtils.getUserName(claims);
        if (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username)) {
        if (StringUtils.isEmpty(userid)) {
            return unauthorizedResponse(exchange, "令牌验证失败");
        }
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPermissionServiceImpl.java
@@ -44,7 +44,7 @@
    @Override
    public Set<String> getMenuPermission(SysUser user) {
        Set<String> perms = new HashSet<String>();
        Long roleId = user.getSysRole().getRoleId();
        Long roleId = user.getRoleId();
        if (null == roleId) {
            perms.addAll(menuService.selectMenuPermsByUserId(user.getUserId()));
        } else {
ruoyi-service/ruoyi-admin/pom.xml
@@ -20,6 +20,17 @@
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.wechatpay-apiv3</groupId>
            <artifactId>wechatpay-apache-httpclient</artifactId>
            <version>0.4.7</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.3.0</version>
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/config/WebSocketConfig.java
New file
@@ -0,0 +1,20 @@
package com.ruoyi.admin.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
 * @author HJL
 * @version 1.0
 * @since 2024-06-28 16:35
 */
@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/AgreementController.java
@@ -35,7 +35,6 @@
     *
     * @param type 查询类型
     */
    @RequiresPermissions(value = {"system_agreement", "system_operate"}, logical = Logical.OR)
    @ApiOperation(value = "根据类型获取注册协议、隐私政策、司机操作指南", tags = {"后台-隐私政策/司机操作指南"})
    @GetMapping(value = "/dataInfo")
    @ApiImplicitParams({
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/EvaluateController.java
@@ -48,16 +48,16 @@
    @ApiOperation(value = "订单评价分页查询列表", tags = {"后台-系统设置-订单评价管理"})
    @GetMapping(value = "/page")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "评价用户", name = "userName", dataType = "String"),
            @ApiImplicitParam(value = "评价用户", name = "userNo", dataType = "String"),
            @ApiImplicitParam(value = "订单编号", name = "orderNumber", dataType = "String"),
            @ApiImplicitParam(value = "师傅姓名", name = "workerName", dataType = "String"),
            @ApiImplicitParam(value = "页码", name = "pageNum", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "每页条数", name = "pageSize", dataType = "Integer", required = true)
    })
    public R<IPage<EvaluatePageVO>> queryPageList(String userName, String orderNumber, String workerName,
    public R<IPage<EvaluatePageVO>> queryPageList(String userNo, String orderNumber, String workerName,
                                                  @RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum,
                                                  @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        return R.ok(evaluateService.queryPageList(userName, orderNumber, workerName, Page.of(pageNum, pageSize)));
        return R.ok(evaluateService.queryPageList(userNo, orderNumber, workerName, Page.of(pageNum, pageSize)));
    }
    /**
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/HomePageController.java
@@ -50,12 +50,12 @@
    /**
     * 用户增量
     *
     * @param cityIds 城市id
     * @param cityList 城市列表
     */
    @ApiOperation(value = "后台-用户增量", tags = {"后台-首页"})
    @PostMapping(value = "/userTrends")
    public R<List<UserTrendsVO>> userTrends(@RequestBody List<String> cityIds) {
        return R.ok(userService.userTrends(cityIds));
    public R<List<UserTrendsVO>> userTrends(@RequestBody List<String> cityList) {
        return R.ok(userService.userTrends(cityList));
    }
    /**
@@ -72,12 +72,12 @@
    /**
     * 师傅接单排行
     *
     * @param cityIds 城市id集合
     * @param cityList 城市集合
     */
    @ApiOperation(value = "后台-师傅接单排行", tags = {"后台-首页"})
    @PostMapping(value = "/workerRanking")
    public R<List<MasterWorkerRankVO>> workerRanking(@RequestBody List<String> cityIds) {
        return R.ok(masterWorkerService.workerRanking(cityIds));
    public R<List<MasterWorkerRankVO>> workerRanking(@RequestBody List<String> cityList) {
        return R.ok(masterWorkerService.workerRanking(cityList));
    }
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/OrderController.java
@@ -3,14 +3,19 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.admin.entity.MasterWorker;
import com.ruoyi.admin.entity.Order;
import com.ruoyi.admin.request.OrderQueryRequest;
import com.ruoyi.admin.service.MasterWorkerService;
import com.ruoyi.admin.service.OrderService;
import com.ruoyi.admin.sorcket.WebSocketServer;
import com.ruoyi.admin.vo.OrderCountVO;
import com.ruoyi.admin.vo.OrderDetailVO;
import com.ruoyi.admin.vo.OrderPageCountVO;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.SnowflakeIdWorker;
import com.ruoyi.common.core.utils.bean.BeanUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
@@ -19,7 +24,9 @@
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
@@ -38,10 +45,26 @@
    @Resource
    private OrderService orderService;
    @Resource
    private MasterWorkerService masterWorkerService;
    /**
     * 雪花算法类
     */
    private static final SnowflakeIdWorker SNOW_FLAKE_ID_WORKER = new SnowflakeIdWorker(5, 5);
    /**
     * socket测试
     */
    @ApiOperation(value = "socket测试", tags = {"后台-订单管理"})
    @GetMapping(value = "/socketTest")
    public R<String> socketTest(@RequestParam String msg, @RequestParam String id) {
        try {
            WebSocketServer.sendInfo(msg, id);
            return R.ok("消息推送成功!");
        } catch (IOException e) {
            return R.fail();
        }
    }
    /**
     * 根据前台用户id查询所有订单信息
@@ -85,6 +108,17 @@
    }
    /**
     * 订单列表
     *
     * @param orderQueryRequest 订单列表查询参数
     */
    @ApiOperation(value = "订单列表-各订单数量统计", tags = {"后台-订单管理"})
    @PostMapping(value = "/orderPageCount")
    public R<OrderPageCountVO> orderPageCount(@RequestBody OrderQueryRequest orderQueryRequest) {
        return R.ok(orderService.orderPageCount(orderQueryRequest));
    }
    /**
     * 站点详情
     *
     * @param id 站点id
@@ -110,6 +144,54 @@
        order.setType(Constants.ONE);
        order.setOrderNumber(String.valueOf(SNOW_FLAKE_ID_WORKER.nextId()));
        return orderService.save(order) ? R.ok() : R.fail();
    }
    /**
     * 新增订单
     * 后台订单与用户端及师傅端无关联
     *
     * @param type 1:订单派单;2:订单改派
     */
    @ApiOperation(value = "订单列表-订单派单/改派", tags = {"后台-订单管理"})
    @GetMapping(value = "/reassignment")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "操作类型(1:订单派单;2:订单改派)", name = "type", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "订单id", name = "orderId", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "服务人员id", name = "workerId", dataType = "Integer", required = true)
    })
    public R<String> reassignment(@RequestParam Integer type, @RequestParam Integer orderId,
                                  @RequestParam Integer workerId) {
        Order order = orderService.lambdaQuery().eq(Order::getId, orderId).eq(Order::getIsDelete, 0).one();
        MasterWorker masterWorker = masterWorkerService.lambdaQuery()
                .eq(MasterWorker::getId, workerId)
                .eq(MasterWorker::getIsDelete, 0).one();
        // 订单派单
        boolean result = true;
        if (Constants.ONE.equals(type)) {
            order.setServerId(workerId);
            order.setServerName(masterWorker.getRealName());
            order.setServerPhone(masterWorker.getPhone());
            order.setAcceptTime(new Date());
            result = orderService.updateById(order);
        } else if (Constants.TWO.equals(type)) {
            order.setState(Constants.FIVE);
            orderService.updateById(order);
            Order itemOrder = new Order();
            BeanUtils.copyProperties(order, itemOrder);
            itemOrder.setId(null);
            itemOrder.setServerId(workerId);
            itemOrder.setServerName(masterWorker.getRealName());
            itemOrder.setServerPhone(masterWorker.getPhone());
            itemOrder.setAcceptTime(new Date());
            itemOrder.setState(Constants.ONE);
            result = orderService.save(itemOrder);
        }
        try {
            WebSocketServer.sendInfo("您有一条新的订单,请注意查收!", String.valueOf(workerId));
        } catch (IOException e) {
            return R.fail("订单推送失败!");
        }
        return result ? R.ok() : R.fail();
    }
    /**
@@ -151,8 +233,8 @@
    @ApiImplicitParams({
            @ApiImplicitParam(value = "师傅姓名", name = "name", dataType = "String"),
            @ApiImplicitParam(value = "师傅电话", name = "phone", dataType = "String"),
            @ApiImplicitParam(value = "页码", name = "pageNum", dataType = "Integer",required = true),
            @ApiImplicitParam(value = "每页条数", name = "pageSize", dataType = "Integer",required = true)
            @ApiImplicitParam(value = "页码", name = "pageNum", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "每页条数", name = "pageSize", dataType = "Integer", required = true)
    })
    public R<IPage<OrderCountVO>> orderCount(String name, String phone,
                                             @RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum,
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/OssController.java
@@ -1,12 +1,7 @@
package com.ruoyi.admin.controller;
import com.ruoyi.admin.entity.Order;
import com.ruoyi.admin.service.OrderService;
import com.ruoyi.admin.utils.ObsUploadUtil;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.GlobalException;
import com.ruoyi.common.core.utils.GaoDeMapUtil;
import com.ruoyi.common.core.utils.ObsUploadUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
@@ -17,7 +12,6 @@
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.IOException;
/**
@@ -30,9 +24,6 @@
@Api(tags = "公共-文件上传")
public class OssController {
    @Resource
    private OrderService orderService;
    @PostMapping("/upload")
    @ApiOperation(value = "文件上传", tags = "公共-文件上传")
    @ApiImplicitParams({
@@ -41,35 +32,6 @@
    public R<String> upload(@RequestParam("file") MultipartFile file) {
        try {
            return R.ok(ObsUploadUtil.obsUpload(file), "");
        } catch (IOException e) {
            return R.fail("文件上传失败!");
        }
    }
    @PostMapping("/uploadPhoto")
    @ApiOperation(value = "师傅端-上传完工照片", tags = "公共-文件上传")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "照片", name = "file", dataType = "MultipartFile", required = true),
            @ApiImplicitParam(value = "订单id", name = "orderId", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "师傅所在经度", name = "longitude", dataType = "String", required = true),
            @ApiImplicitParam(value = "师傅所在纬度", name = "latitude", dataType = "String", required = true)
    })
    public R<String> uploadPhoto(@RequestParam("file") MultipartFile file, @RequestParam String orderId,
                                 @RequestParam String longitude, @RequestParam String latitude) {
        // 校验经纬度
        Order order = orderService.lambdaQuery().eq(Order::getIsDelete, orderId).eq(Order::getIsDelete, 0).one();
        // 用户下单位置经纬度
        String orderPosition = order.getLongitude() + "," + order.getLatitude();
        // 师傅经纬度
        String workerPosition = longitude + "," + latitude;
        // 师傅当前位置离用户下单位置具体距离
        Long distance = GaoDeMapUtil.getDistance(orderPosition, workerPosition).getDatas();
        // 上传时判断是否在下单位置附件,距离大于某个值则 不允许上传
        if (distance > Constants.THREE_THOUSAND) {
            throw new GlobalException("您当前手机定位超出当前订单预约地址范围 3km,无法提供回收服务!");
        }
        try {
            return R.ok(ObsUploadUtil.obsUpload(file));
        } catch (IOException e) {
            return R.fail("文件上传失败!");
        }
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/ProblemController.java
@@ -6,6 +6,7 @@
import com.ruoyi.admin.entity.Problem;
import com.ruoyi.admin.service.ProblemService;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.security.annotation.RequiresPermissions;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
@@ -39,6 +40,7 @@
     * @param pageNum  页码
     * @param pageSize 每页显示条数
     */
    @RequiresPermissions("system_problem")
    @ApiOperation(value = "常见问题分页查询列表", tags = {"后台-系统设置-常见问题管理"})
    @GetMapping(value = "/page")
    @ApiImplicitParams({
@@ -65,6 +67,7 @@
     *
     * @param id 常见问题id
     */
    @RequiresPermissions("system_problem")
    @ApiOperation(value = "常见问题详情", tags = {"后台-系统设置-常见问题管理"})
    @GetMapping(value = "/detail")
    @ApiImplicitParams({
@@ -79,6 +82,7 @@
     *
     * @param problem 常见问题信息
     */
    @RequiresPermissions("system_problem")
    @ApiOperation(value = "新增常见问题", tags = {"后台-系统设置-常见问题管理"})
    @PostMapping(value = "/save")
    public R<String> save(@RequestBody Problem problem) {
@@ -90,6 +94,7 @@
     *
     * @param problem 常见问题信息
     */
    @RequiresPermissions("system_problem")
    @ApiOperation(value = "修改常见问题", tags = {"后台-系统设置-常见问题管理"})
    @PostMapping(value = "/update")
    public R<String> update(@RequestBody Problem problem) {
@@ -101,6 +106,7 @@
     *
     * @param ids 常见问题多条id拼接
     */
    @RequiresPermissions("system_problem")
    @ApiOperation(value = "批量删除常见问题", tags = {"后台-系统设置-常见问题管理"})
    @GetMapping(value = "/batchDelete")
    @ApiImplicitParams({
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/RecoveryClassifyController.java
@@ -49,6 +49,7 @@
                                                    @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        return R.ok(recoveryClassifyService.lambdaQuery().eq(RecoveryClassify::getIsDelete, 0)
                .orderByDesc(RecoveryClassify::getSupClassify)
                .orderByAsc(RecoveryClassify::getSort)
                .orderByDesc(RecoveryClassify::getCreateTime)
                .page(Page.of(pageNum, pageSize)));
    }
@@ -68,6 +69,25 @@
    }
    /**
     * 是否首页推荐
     */
    @ApiOperation(value = "是否首页推荐", tags = {"后台-回收管理-回收分类管理"})
    @GetMapping(value = "/recommend")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "分类id", name = "id", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "是否推荐 0未推荐;1已推荐", name = "recommend", dataType = "Integer", required = true)
    })
    public R<String> recommend(@RequestParam Integer id, @RequestParam Integer recommend) {
        Integer[] arr = {0, 1};
        boolean contains = Arrays.stream(arr).collect(Collectors.toList()).contains(recommend);
        if (!contains) {
            return R.fail("推荐状态异常!");
        }
        return recoveryClassifyService.lambdaUpdate().set(RecoveryClassify::getIsRecommend, recommend)
                .eq(RecoveryClassify::getId, id).update() ? R.ok() : R.fail();
    }
    /**
     * 新增回收分类
     *
     * @param recoveryClassify 回收分类信息
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/RecoveryServeController.java
@@ -14,6 +14,7 @@
import com.ruoyi.admin.vo.RecoveryServeResultVO;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.security.annotation.RequiresPermissions;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
@@ -52,6 +53,7 @@
     * @param pageNum  页码
     * @param pageSize 每页显示条数
     */
    @RequiresPermissions("serve_recycling_list")
    @ApiOperation(value = "回收服务分页查询列表", tags = {"后台-回收管理-回收服务管理"})
    @GetMapping(value = "/page")
    @ApiImplicitParams({
@@ -75,8 +77,20 @@
    }
    /**
     * 回收服务列表
     */
    @RequiresPermissions("serve_recycling_list")
    @ApiOperation(value = "回收服务列表", tags = {"后台-回收管理-回收服务管理"})
    @GetMapping(value = "/list")
    public R<List<RecoveryServe>> queryPageList() {
        return R.ok(recoveryServeService.lambdaQuery().eq(RecoveryServe::getIsDelete, 0)
                .orderByDesc(RecoveryServe::getCreateTime).list());
    }
    /**
     * 所属分类列表
     */
    @RequiresPermissions("serve_recycling_list")
    @ApiOperation(value = "所属分类列表", tags = {"后台-回收管理-回收服务管理"})
    @GetMapping(value = "/typeList")
    public R<List<RecoveryClassify>> typeList() {
@@ -89,6 +103,7 @@
     *
     * @param id 回收服务id
     */
    @RequiresPermissions("serve_recycling_list")
    @ApiOperation(value = "回收服务详情", tags = {"后台-回收管理-回收服务管理"})
    @GetMapping(value = "/detail")
    @ApiImplicitParams({
@@ -107,6 +122,7 @@
     *
     * @param recoveryServeRequest 回收服务信息
     */
    @RequiresPermissions("serve_recycling_list")
    @ApiOperation(value = "新增回收服务", tags = {"后台-回收管理-回收服务管理"})
    @PostMapping(value = "/save")
    public R<String> save(@RequestBody RecoveryServeRequest recoveryServeRequest) {
@@ -133,6 +149,7 @@
     *
     * @param recoveryServeRequest 回收服务信息
     */
    @RequiresPermissions("serve_recycling_list")
    @ApiOperation(value = "修改回收服务", tags = {"后台-回收管理-回收服务管理"})
    @PostMapping(value = "/update")
    public R<String> update(@RequestBody RecoveryServeRequest recoveryServeRequest) {
@@ -165,6 +182,7 @@
     *
     * @param ids 回收服务多条id拼接
     */
    @RequiresPermissions("serve_recycling_list")
    @ApiOperation(value = "批量删除回收服务", tags = {"后台-回收管理-回收服务管理"})
    @GetMapping(value = "/batchDelete")
    @ApiImplicitParams({
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/RoleController.java
@@ -13,6 +13,7 @@
import com.ruoyi.admin.service.RoleService;
import com.ruoyi.admin.vo.RoleDetailVO;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.security.annotation.RequiresPermissions;
import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.system.api.model.LoginUser;
import io.swagger.annotations.Api;
@@ -55,6 +56,7 @@
     * @param pageNum  页码
     * @param pageSize 每页显示条数
     */
    @RequiresPermissions("power_role")
    @ApiOperation(value = "角色分页查询列表", tags = {"后台-权限管理-角色管理"})
    @GetMapping(value = "/page")
    @ApiImplicitParams({
@@ -70,6 +72,7 @@
    /**
     * 角色列表
     */
    @RequiresPermissions("power_role")
    @ApiOperation(value = "角色列表", tags = {"后台-权限管理-账号管理"})
    @GetMapping(value = "/list")
    public R<List<Role>> list() {
@@ -85,6 +88,7 @@
     *
     * @param id 角色id
     */
    @RequiresPermissions("power_role")
    @ApiOperation(value = "角色详情", tags = {"后台-权限管理-角色管理"})
    @GetMapping(value = "/detail")
    @ApiImplicitParams({
@@ -105,6 +109,7 @@
     *
     * @param roleRequest 角色信息
     */
    @RequiresPermissions("power_role")
    @ApiOperation(value = "编辑角色", tags = {"后台-权限管理-角色管理"})
    @PostMapping(value = "/update")
    public R<RoleDetailVO> update(@RequestBody RoleRequest roleRequest) {
@@ -129,6 +134,7 @@
     *
     * @param roleRequest 角色信息
     */
    @RequiresPermissions("power_role")
    @ApiOperation(value = "新增角色", tags = {"后台-权限管理-角色管理"})
    @PostMapping(value = "/save")
    public R<String> save(@RequestBody RoleRequest roleRequest) {
@@ -144,6 +150,7 @@
     *
     * @param ids 角色id拼接
     */
    @RequiresPermissions("power_role")
    @ApiOperation(value = "批量删除角色", tags = {"后台-权限管理-角色管理"})
    @GetMapping(value = "/batchDelete")
    @ApiImplicitParams({
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/RoleMenuController.java
@@ -4,6 +4,7 @@
import com.ruoyi.admin.entity.Menu;
import com.ruoyi.admin.service.MenuService;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.security.annotation.RequiresPermissions;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
@@ -32,6 +33,7 @@
    /**
     * 菜单树
     */
    @RequiresPermissions("power_role")
    @ApiOperation(value = "菜单树", tags = {"后台-权限管理-菜单权限"})
    @GetMapping(value = "/menuTree")
    public R<List<Menu>> menuTree() {
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/RotateController.java
@@ -9,6 +9,7 @@
import com.ruoyi.admin.service.RotateService;
import com.ruoyi.admin.vo.RotateResultVO;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.security.annotation.RequiresPermissions;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
@@ -45,6 +46,7 @@
     * @param pageSize 每页显示条数
     * @return 封装分页数据
     */
    @RequiresPermissions("system_rotate")
    @ApiOperation(value = "轮播图分页查询列表", tags = {"后台-系统设置-轮播图管理"})
    @GetMapping(value = "/page")
    @ApiImplicitParams({
@@ -59,6 +61,7 @@
    /**
     * 轮播图列表
     */
    @RequiresPermissions("system_rotate")
    @GetMapping(value = "/bannerList")
    public R<List<Rotate>> bannerList() {
        return R.ok(rotateService.lambdaQuery().eq(Rotate::getIsDelete, 0)
@@ -71,6 +74,7 @@
     * @param id 轮播图id
     * @return 封装分页数据
     */
    @RequiresPermissions("system_rotate")
    @ApiOperation(value = "轮播图详情", tags = {"后台-系统设置-轮播图管理"})
    @GetMapping(value = "/detail")
    @ApiImplicitParams({
@@ -95,6 +99,7 @@
     * @param rotate 轮播图信息
     * @return 封装分页数据
     */
    @RequiresPermissions("system_rotate")
    @ApiOperation(value = "新增轮播图", tags = {"后台-系统设置-轮播图管理"})
    @PostMapping(value = "/save")
    public R<String> save(@RequestBody Rotate rotate) {
@@ -107,6 +112,7 @@
     * @param rotate 轮播图信息
     * @return 封装分页数据
     */
    @RequiresPermissions("system_rotate")
    @ApiOperation(value = "修改轮播图", tags = {"后台-系统设置-轮播图管理"})
    @PostMapping(value = "/update")
    public R<String> update(@RequestBody Rotate rotate) {
@@ -119,6 +125,7 @@
     * @param ids 轮播图多条id拼接
     * @return 封装分页数据
     */
    @RequiresPermissions("system_rotate")
    @ApiOperation(value = "批量删除轮播图", tags = {"后台-系统设置-轮播图管理"})
    @GetMapping(value = "/batchDelete")
    @ApiImplicitParams({
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/SiteController.java
@@ -53,6 +53,17 @@
    }
    /**
     * 站点列表
     */
    @ApiOperation(value = "站点列表", tags = {"后台-系统设置-站点管理"})
    @GetMapping(value = "/list")
    public R<List<Site>> list() {
        return R.ok(siteService.lambdaQuery().orderByDesc(Site::getCreateTime)
                .eq(Site::getIsDelete, 0)
                .list());
    }
    /**
     * 站点详情
     *
     * @param id 站点id
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/UserController.java
@@ -83,7 +83,7 @@
     * @param id     后台账号id
     * @param enable 启用/关闭
     */
    @ApiOperation(value = "启用/关闭用户账号", tags = {"后台-师傅管理-师傅列表管理"})
    @ApiOperation(value = "启用/关闭用户账号", tags = {"用户管理-用户列表"})
    @GetMapping(value = "/enable")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "用户id", name = "id", dataType = "Integer", required = true),
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/UserManageController.java
@@ -4,22 +4,23 @@
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.admin.entity.*;
import com.ruoyi.admin.service.EvaluateService;
import com.ruoyi.admin.service.OrderService;
import com.ruoyi.admin.service.UserService;
import com.ruoyi.admin.service.WithdrawService;
import com.ruoyi.admin.vo.UserWithdrawRecordRequestVO;
import com.ruoyi.admin.service.*;
import com.ruoyi.admin.vo.EvaluatePageVO;
import com.ruoyi.admin.vo.UserWithdrawRecordVO;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.GlobalException;
import com.ruoyi.common.core.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
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 javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@@ -42,6 +43,8 @@
    private WithdrawService withdrawService;
    @Resource
    private UserService userService;
    @Resource
    private WithdrawalSettingService withdrawalSettingService;
    /**
     * 用户信息分页列表
@@ -139,11 +142,10 @@
            @ApiImplicitParam(value = "页码", name = "pageNum", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "每页条数", name = "pageSize", dataType = "Integer", required = true)
    })
    public R<IPage<Evaluate>> evaluateList(Integer userId,
                                           @RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum,
                                           @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        return R.ok(evaluateService.lambdaQuery().eq(Evaluate::getUserId, userId)
                .eq(Evaluate::getIsDelete, 0).page(Page.of(pageNum, pageSize)));
    public R<IPage<EvaluatePageVO>> evaluateList(Integer userId,
                                                 @RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum,
                                                 @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        return R.ok(evaluateService.evaluateList(userId, Page.of(pageNum, pageSize)));
    }
    /**
@@ -169,7 +171,10 @@
     */
    @ApiOperation(value = "关闭/开启审核", tags = {"后台-用户管理-用户列表"})
    @GetMapping(value = "/enableProcess")
    public R<Boolean> enableProcess(@RequestParam Integer enableProcess) {
    @ApiImplicitParams({
            @ApiImplicitParam(value = "审核状态(0:未开启,1:已开启)", name = "enableProcess", dataType = "Integer", required = true)
    })
    public R<Boolean> enableProcess(@RequestParam("enableProcess") Integer enableProcess) {
        return R.ok(withdrawService.enableProcess(enableProcess));
    }
@@ -185,6 +190,17 @@
    }
    /**
     * 全局审核状态
     */
    @ApiOperation(value = "全局审核状态", tags = {"后台-用户管理-用户列表"})
    @GetMapping(value = "/withdrawState")
    public R<WithdrawalSetting> withdrawState() {
        // 全局审核设置
        WithdrawalSetting setting = withdrawalSettingService.lambdaQuery().one();
        return R.ok(setting);
    }
    /**
     * 用户所关联提现记录分页列表
     *
     * @param userId   用户id
@@ -192,14 +208,14 @@
     * @param pageSize 每页显示条数
     * @return 分页列表
     */
    @ApiOperation(value = "用户详情/用户提现管理-提现记录分页列表", tags = {"后台-用户管理-用户列表"})
    @ApiOperation(value = "用户详情-提现记录分页列表", tags = {"后台-用户管理-用户列表"})
    @GetMapping(value = "/withdrawList")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "用户id(用户提现管理模块 该值传nul)", name = "userId", dataType = "Integer"),
            @ApiImplicitParam(value = "用户id", name = "userId", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "页码", name = "pageNum", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "每页条数", name = "pageSize", dataType = "Integer", required = true)
    })
    public R<UserWithdrawRecordRequestVO> withdrawList(Integer userId,
    public R<IPage<UserWithdrawRecordVO>> withdrawList(@RequestParam Integer userId,
                                                       @RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum,
                                                       @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        return R.ok(withdrawService.withdrawList(userId, Page.of(pageNum, pageSize)));
@@ -232,10 +248,10 @@
    @GetMapping(value = "/withdrawExamine")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "提现记录id", name = "id", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "审批意见", name = "opinion", dataType = "String", required = true),
            @ApiImplicitParam(value = "审批意见", name = "opinion", dataType = "String"),
            @ApiImplicitParam(value = "审批同意/不同意(1同意;2驳回)", name = "state", dataType = "Integer", required = true)
    })
    public R<String> withdrawExamine(@RequestParam Integer id, @RequestParam Integer state, @RequestParam String opinion) {
    public R<String> withdrawExamine(@RequestParam Integer id, @RequestParam Integer state, String opinion) {
        Withdraw withdraw = withdrawService.lambdaQuery().eq(Withdraw::getId, id).eq(Withdraw::getIsDelete, 0)
                .eq(Withdraw::getState, 0).one();
        if (null == withdraw) {
@@ -243,26 +259,24 @@
        }
        // 修改审批状态及审批意见
        withdraw.setState(state);
        withdraw.setOpinions(opinion);
        withdraw.setOpinion(opinion);
        // 同意提现申请,更改订单提现状态
        boolean update = true;
        if (Constants.ONE.equals(state)) {
            update = orderService.lambdaUpdate().set(Order::getIsWithdrawal, Constants.ONE)
                    .eq(Order::getId, withdraw.getOrderId()).eq(Order::getIsDelete, 0).update();
            // 商家打款至用户微信零钱
            User user = userService.lambdaQuery().eq(User::getId, withdraw.getUserId())
                    .eq(User::getIsDelete, 0).one();
            Order order = orderService.lambdaQuery().eq(Order::getId, withdraw.getOrderId())
                    .eq(Order::getIsDelete, 0).one();
            if (null == order) {
                throw new GlobalException("订单信息异常!");
            }
            Boolean b = withdrawService.confirmWithdraw(user, order);
        }
        update = update && withdrawService.updateById(withdraw);
        return update ? R.ok(null, "审批成功!") : R.fail("审批失败!");
    }
    /**
     * 用户提现记录导出
     *
     * @param idList 提现记录id
     */
    @ApiOperation(value = "用户提现管理-excel导出用户提现记录", tags = {"后台-用户管理-用户列表"})
    @PostMapping(value = "/excelExport")
    public R<String> excelExport(@RequestBody List<String> idList, HttpServletResponse response) {
        return withdrawService.excelExport(idList, response);
    }
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/WithdrawController.java
@@ -1,19 +1,30 @@
package com.ruoyi.admin.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.admin.entity.Order;
import com.ruoyi.admin.entity.User;
import com.ruoyi.admin.entity.Withdraw;
import com.ruoyi.admin.request.WithdrawExportRequest;
import com.ruoyi.admin.service.OrderService;
import com.ruoyi.admin.service.UserService;
import com.ruoyi.admin.service.WithdrawService;
import com.ruoyi.admin.vo.UserWithdrawRecordVO;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.GlobalException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
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 javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
 * <p>
@@ -25,25 +36,125 @@
 */
@RestController
@RequestMapping("/withdraw")
@Api(tags = {"后台-用户管理-用户列表"})
@Api(tags = {"后台-用户管理-提现列表"})
public class WithdrawController {
    @Resource
    private WithdrawService withdrawService;
    @Resource
    private OrderService orderService;
    @Resource
    private UserService userService;
    /**
     * 用户所关联提现记录分页列表
     *
     * @param pageNum  页码
     * @param pageSize 每页显示条数
     * @return 分页列表
     */
    @ApiOperation(value = "用户提现管理-提现记录分页列表", tags = {"后台-用户管理-提现列表"})
    @GetMapping(value = "/withdrawPage")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "用户昵称", name = "nickname", dataType = "String"),
            @ApiImplicitParam(value = "手机号", name = "userPhone", dataType = "String"),
            @ApiImplicitParam(value = "申请时间", name = "applyForTime", dataType = "String"),
            @ApiImplicitParam(value = "审核状态(0待审核;1已通过;2已驳回)", name = "state", dataType = "Integer"),
            @ApiImplicitParam(value = "页码", name = "pageNum", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "每页条数", name = "pageSize", dataType = "Integer", required = true)
    })
    public R<IPage<UserWithdrawRecordVO>> withdrawPage(String nickname, String userPhone,
                                                       String applyForTime, Integer state,
                                                       @RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum,
                                                       @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        return R.ok(withdrawService.withdrawPage(nickname, userPhone, applyForTime, state, Page.of(pageNum, pageSize)));
    }
    /**
     * 查看提现记录详情
     *
     * @param id 提现记录id
     */
    @ApiOperation(value = "提现记录详情", tags = {"后台-用户管理-用户列表"})
    @ApiOperation(value = "提现记录详情", tags = {"后台-用户管理-提现列表"})
    @GetMapping(value = "/withdrawRecordDetail")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "提现记录id", name = "id", dataType = "Integer", required = true)
    })
    public R<Withdraw> withdrawRecordDetail(@RequestParam Integer id) {
        Withdraw withdraw = withdrawService.lambdaQuery().eq(Withdraw::getId, id).eq(Withdraw::getIsDelete, 0).one();
        Withdraw withdraw = withdrawService.lambdaQuery().eq(Withdraw::getId, id)
                .eq(Withdraw::getIsDelete, 0).one();
        return R.ok(withdraw);
    }
    /**
     * 提现管理-提现审批
     *
     * @param id      提现记录id
     * @param state   审批结果
     * @param opinion 审批意见
     */
    @ApiOperation(value = "提现管理-提现审批", tags = {"后台-用户管理-提现列表"})
    @GetMapping(value = "/withdrawExamine")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "提现记录id", name = "id", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "审批意见", name = "opinion", dataType = "String"),
            @ApiImplicitParam(value = "审批同意/不同意(1同意;2驳回)", name = "state", dataType = "Integer", required = true)
    })
    public R<String> withdrawExamine(@RequestParam Integer id, @RequestParam Integer state, String opinion) {
        Withdraw withdraw = withdrawService.lambdaQuery().eq(Withdraw::getId, id).eq(Withdraw::getIsDelete, 0)
                .eq(Withdraw::getState, 0).one();
        if (null == withdraw) {
            return R.fail(503, "当前提现记录审批状态异常!");
        }
        // 修改审批状态及审批意见
        withdraw.setState(state);
        withdraw.setOpinion(opinion);
        // 同意提现申请,更改订单提现状态
        boolean update = true;
        if (Constants.ONE.equals(state)) {
            update = orderService.lambdaUpdate().set(Order::getIsWithdrawal, Constants.ONE)
                    .eq(Order::getId, withdraw.getOrderId()).eq(Order::getIsDelete, 0).update();
            // 商家打款至用户微信零钱
            User user = userService.lambdaQuery().eq(User::getId, withdraw.getUserId())
                    .eq(User::getIsDelete, 0).one();
            Order order = orderService.lambdaQuery().eq(Order::getId, withdraw.getOrderId())
                    .eq(Order::getIsDelete, 0).one();
            if (null == order) {
                throw new GlobalException("订单信息异常!");
            }
            Boolean b = withdrawService.confirmWithdraw(user, order);
        }
        update = update && withdrawService.updateById(withdraw);
        return update ? R.ok(null, "审批成功!") : R.fail("审批失败!");
    }
    /**
     * 用户提现记录导出
     *
     * @param exportRequest 提现记录
     */
    @ApiOperation(value = "用户提现管理-excel导出用户提现记录", tags = {"后台-用户管理-提现列表"})
    @PostMapping(value = "/excelExport")
    public R<String> excelExport(@RequestBody WithdrawExportRequest exportRequest, HttpServletResponse response) {
        return withdrawService.excelExport(exportRequest, response);
    }
    /**
     * 批量删除提现记录
     *
     * @param ids 轮播图多条id拼接
     * @return 封装分页数据
     */
    @ApiOperation(value = "批量删除提现记录", tags = {"后台-用户管理-提现列表"})
    @GetMapping(value = "/batchDelete")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "多个id ',' 拼接", name = "ids", dataType = "String", required = true)
    })
    public R<String> batchDelete(@RequestParam String ids) {
        List<String> idList = Arrays.stream(ids.split(",")).collect(Collectors.toList());
        List<Withdraw> list = withdrawService.lambdaQuery().in(Withdraw::getId, idList).list();
        list.forEach(data -> data.setIsDelete(1));
        return withdrawService.updateBatchById(list) ? R.ok() : R.fail();
    }
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/entity/MasterWorker.java
@@ -33,10 +33,6 @@
    @TableField("city")
    private String city;
    @ApiModelProperty("服务城市id")
    @TableField("city_id")
    private Integer cityId;
    @ApiModelProperty("用户编号(用户昵称/用户id)")
    @TableField("user_number")
    private String userNumber;
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/entity/Order.java
@@ -27,8 +27,12 @@
@ApiModel(value = "Order对象", description = "订单管理")
public class Order extends BaseEntity {
    @TableId(value = "id",type = IdType.AUTO)
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    @ApiModelProperty("下单城市")
    @TableField("city")
    private String city;
    @ApiModelProperty("订单编号")
    @TableField("order_number")
@@ -126,4 +130,8 @@
    @TableField("is_withdrawal")
    private Integer isWithdrawal;
    @ApiModelProperty("再投原因")
    @TableField(exist = false)
    private String applyReason;
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/entity/User.java
@@ -51,4 +51,8 @@
    @TableField("state")
    private Integer state;
    @ApiModelProperty("微信OpenId")
    @TableField("open_id")
    private String openId;
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/entity/Withdraw.java
@@ -52,8 +52,8 @@
    private Integer state;
    @ApiModelProperty("审批意见")
    @TableField("opinions")
    private String opinions;
    @TableField("opinion")
    private String opinion;
    @ApiModelProperty("订单id")
    @TableField("order_id")
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/entity/WorkerProcess.java
@@ -78,7 +78,7 @@
    private Integer state;
    @ApiModelProperty("审批意见")
    @TableField("examine_opinion")
    private String examineOpinion;
    @TableField("opinion")
    private String opinion;
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/mapper/EvaluateMapper.java
@@ -27,4 +27,13 @@
     * @return 分页
     */
    IPage<EvaluatePageVO> queryPageList(@Param("userName") String userName, @Param("orderNumber") String orderNumber, @Param("workerName") String workerName, Page<Object> page);
    /**
     * 用户所关联评价记录分页列表
     *
     * @param userId 用户id
     * @param page   分页
     * @return 分页列表
     */
    IPage<EvaluatePageVO> evaluateList(@Param("userId") Integer userId, Page<EvaluatePageVO> page);
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/mapper/OrderMapper.java
@@ -4,6 +4,7 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.admin.entity.Order;
import com.ruoyi.admin.request.OrderQueryRequest;
import com.ruoyi.admin.vo.OrderCountVO;
import com.ruoyi.admin.vo.OrderQueryVO;
import org.apache.ibatis.annotations.Param;
@@ -24,49 +25,49 @@
    /**
     * 查询本年订单数量
     *
     * @param cityId     城市id集合
     * @param cityList   城市集合
     * @param orderState 订单状态
     * @param startTime  开始日期
     * @param endTime    结束日期
     * @return 本年订单数量
     */
    List<OrderQueryVO> orderCountByYear(@Param("ids") List<String> cityId, @Param("orderState") Integer orderState,
    List<OrderQueryVO> orderCountByYear(@Param("cityList") List<String> cityList, @Param("orderState") Integer orderState,
                                        @Param("startTime") String startTime, @Param("endTime") String endTime);
    /**
     * 查询本月订单数量
     *
     * @param cityId     城市id集合
     * @param cityList   城市集合
     * @param orderState 订单状态
     * @param startTime  开始日期
     * @param endTime    结束日期
     * @return 本年订单数量
     */
    List<OrderQueryVO> orderCountByMonth(@Param("ids") List<String> cityId, @Param("orderState") Integer orderState,
    List<OrderQueryVO> orderCountByMonth(@Param("cityList") List<String> cityList, @Param("orderState") Integer orderState,
                                         @Param("startTime") String startTime, @Param("endTime") String endTime);
    /**
     * 查询本周订单数量
     *
     * @param cityId     城市id集合
     * @param cityList   城市集合
     * @param orderState 订单状态
     * @param startTime  开始日期
     * @param endTime    结束日期
     * @return 本年订单数量
     */
    List<OrderQueryVO> orderCountByWeek(@Param("ids") List<String> cityId, @Param("orderState") Integer orderState,
    List<OrderQueryVO> orderCountByWeek(@Param("cityList") List<String> cityList, @Param("orderState") Integer orderState,
                                        @Param("startTime") String startTime, @Param("endTime") String endTime);
    /**
     * 查询当天订单数量
     *
     * @param cityId     城市id集合
     * @param cityList   城市集合
     * @param orderState 订单状态
     * @param startTime  开始日期
     * @param endTime    结束日期
     * @return 本年订单数量
     */
    List<OrderQueryVO> orderCountByToday(@Param("ids") List<String> cityId, @Param("orderState") Integer orderState,
    List<OrderQueryVO> orderCountByToday(@Param("cityList") List<String> cityList, @Param("orderState") Integer orderState,
                                         @Param("startTime") String startTime, @Param("endTime") String endTime);
    /**
@@ -74,26 +75,27 @@
     *
     * @param startDateStr 季度开始时间
     * @param endDateStr   季度结束时间
     * @param cityIdList   城市id
     * @param cityList     城市集合
     * @return 总交易额
     */
    BigDecimal totalMoneyByQuarter(@Param("start") String startDateStr, @Param("end") String endDateStr, @Param("ids") List<String> cityIdList);
    BigDecimal totalMoneyByQuarter(@Param("start") String startDateStr, @Param("end") String endDateStr,
                                   @Param("cityList") List<String> cityList);
    /**
     * 查询整个年度的交易额(订单状态为:已完工)
     *
     * @param cityIdList 城市id
     * @param cityList 城市集合
     * @return 总交易额
     */
    BigDecimal totalMoneyByYear(@Param("ids") List<String> cityIdList);
    BigDecimal totalMoneyByYear(@Param("cityList") List<String> cityList);
    /**
     * 查询整个月度的交易额(订单状态为:已完工)
     *
     * @param cityIdList 城市id
     * @param cityList 城市列表
     * @return 总交易额
     */
    BigDecimal totalMoneyByMonth(@Param("ids") List<String> cityIdList);
    BigDecimal totalMoneyByMonth(@Param("cityList") List<String> cityList);
    /**
     * 订单管理-订单统计
@@ -104,4 +106,21 @@
     * @return 分页统计
     */
    IPage<OrderCountVO> orderCount(@Param("name") String name, @Param("phone") String phone, Page<OrderCountVO> page);
    /**
     * 订单列表
     *
     * @param orderQueryRequest 订单列表查询参数
     * @param page              分页
     * @return 分页
     */
    IPage<Order> queryPage(@Param("data") OrderQueryRequest orderQueryRequest, Page<Order> page);
    /**
     * 订单管理分页模块,订单数量统计
     *
     * @param orderQueryRequest 请求参数
     * @return 统计数量
     */
    List<Order> orderPageCount(@Param("data") OrderQueryRequest orderQueryRequest);
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/mapper/UserMapper.java
@@ -22,24 +22,24 @@
    /**
     * 获取用户增量趋势
     *
     * @param cityIds 城市id集合
     * @param city 城市id集合
     * @return 折线图数据
     */
    List<UserTrendsVO> userTrends(@Param("ids") List<String> cityIds);
    List<UserTrendsVO> userTrends(@Param("city") List<String> city);
    /**
     * 统计本年度,注册用户数量
     *
     * @param ids 城市id
     * @param cityList 城市集合
     * @return 注册用户数量
     */
    Long increaseNumberByYear(@Param("ids") List<String> ids);
    Long increaseNumberByYear(@Param("cityList") List<String> cityList);
    /**
     * 统计本月,注册用户数量
     *
     * @param cityIdList 城市id
     * @param cityList 城市列表
     * @return 注册用户数量
     */
    Long increaseNumberByMonth(@Param("ids") List<String> cityIdList);
    Long increaseNumberByMonth(@Param("cityList") List<String> cityList);
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/mapper/WithdrawMapper.java
@@ -23,26 +23,26 @@
    /**
     * 获取用户提现金额
     *
     * @param cityIdList 城市id
     * @param cityList 城市集合
     * @return 总金额
     */
    BigDecimal withdrawalTotalMoney(@Param("ids") List<String> cityIdList);
    BigDecimal withdrawalTotalMoney(@Param("cityList") List<String> cityList);
    /**
     * 年度查询
     *
     * @param cityIdList 城市id
     * @param cityList 城市列表
     * @return 年度提现总额
     */
    BigDecimal withdrawalTotalMoneyByYear(@Param("ids") List<String> cityIdList);
    BigDecimal withdrawalTotalMoneyByYear(@Param("cityList") List<String> cityList);
    /**
     * 月度查询
     *
     * @param cityIdList 城市id
     * @param cityList 城市列表
     * @return 年度提现总额
     */
    BigDecimal withdrawalTotalMoneyByMonth(@Param("ids") List<String> cityIdList);
    BigDecimal withdrawalTotalMoneyByMonth(@Param("cityList") List<String> cityList);
    /**
     * 用户所关联提现记录分页列表
@@ -52,4 +52,39 @@
     * @return 分页列表
     */
    IPage<UserWithdrawRecordVO> withdrawList(@Param("userId") Integer userId, Page<UserWithdrawRecordVO> page);
    /**
     * 用户所关联提现记录分页列表
     *
     * @param nickname     用户名称
     * @param userPhone    用户手机号
     * @param applyForTime 申请时间
     * @param state        审核状态
     * @param page         分页
     * @return 分页列表
     */
    IPage<UserWithdrawRecordVO> withdrawPage(@Param("name") String nickname, @Param("phone") String userPhone,
                                             @Param("time") String applyForTime,
                                             @Param("state") Integer state, Page<UserWithdrawRecordVO> page);
    /**
     * 提现记录列表
     *
     * @param nickname     用户名称
     * @param userPhone    用户手机号
     * @param applyForTime 申请时间
     * @param state        审核状态
     * @return 分页列表
     */
    List<UserWithdrawRecordVO> exportList(@Param("name") String nickname, @Param("phone") String userPhone,
                                          @Param("time") String applyForTime,
                                          @Param("state") Integer state);
    /**
     * 根据所选id导出
     *
     * @param ids 提现记录ids
     * @return 列表
     */
    List<UserWithdrawRecordVO> exportByIdList(List<String> ids);
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/request/OrderCountRequest.java
@@ -17,7 +17,7 @@
public class OrderCountRequest {
    @ApiModelProperty("所选城市id集合")
    private List<String> cityIdList;
    private List<String> cityList;
    @ApiModelProperty("查询订单状态(全部订单:该字段不传值;其他状态(0:待派单;1:待上门;2:待完工;3:已完结;4:已取消;5:已改派))")
    private Integer orderState;
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/request/OrderQueryRequest.java
@@ -4,8 +4,6 @@
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
 * @author HJL
 * @version 1.0
@@ -36,19 +34,25 @@
    @ApiModelProperty("师傅电话")
    private String workerPhone;
    @ApiModelProperty("下单时间")
    private Date orderTime;
    @ApiModelProperty("下单开始时间")
    private String orderTimeStart;
    @ApiModelProperty("预约上门时间")
    private Date time;
    @ApiModelProperty("下单结束时间")
    private String orderTimeEnd;
    @ApiModelProperty("预约上门开始时间")
    private String startTime;
    @ApiModelProperty("预约上门结束时间")
    private String endTime;
    @ApiModelProperty("站点名称")
    private String serveName;
    @ApiModelProperty(value = "页码", required = true)
    private Integer pageNum;
    private Integer pageNum = 1;
    @ApiModelProperty(value = "每页显示条数", required = true)
    private Integer pageSize;
    private Integer pageSize = 10;
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/request/WithdrawExportRequest.java
New file
@@ -0,0 +1,31 @@
package com.ruoyi.admin.request;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
 * @author HJL
 * @version 1.0
 * @since 2024-06-28 11:31
 */
@Data
public class WithdrawExportRequest {
    @ApiModelProperty("用户昵称")
    private String nickname;
    @ApiModelProperty("手机号")
    private String userPhone;
    @ApiModelProperty("申请时间")
    private String applyForTime;
    @ApiModelProperty("提现状态")
    private Integer state;
    @ApiModelProperty("所选数据id")
    private List<String> idList;
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/EvaluateService.java
@@ -2,8 +2,8 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.admin.entity.Evaluate;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.admin.entity.Evaluate;
import com.ruoyi.admin.vo.EvaluatePageVO;
/**
@@ -26,4 +26,13 @@
     * @return 分页
     */
    IPage<EvaluatePageVO> queryPageList(String userName, String orderNumber, String workerName, Page<Object> page);
    /**
     * 用户所关联评价记录分页列表
     *
     * @param userId 用户id
     * @param page   分页
     * @return 分页列表
     */
    IPage<EvaluatePageVO> evaluateList(Integer userId, Page<EvaluatePageVO> page);
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/MasterWorkerService.java
@@ -19,8 +19,8 @@
    /**
     * 师傅接单排行
     *
     * @param cityIds 城市id集合
     * @param cityList 城市集合
     * @return 排行榜
     */
    List<MasterWorkerRankVO> workerRanking(List<String> cityIds);
    List<MasterWorkerRankVO> workerRanking(List<String> cityList);
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/OrderService.java
@@ -8,6 +8,7 @@
import com.ruoyi.admin.request.OrderQueryRequest;
import com.ruoyi.admin.vo.OrderCountVO;
import com.ruoyi.admin.vo.OrderDetailVO;
import com.ruoyi.admin.vo.OrderPageCountVO;
import com.ruoyi.admin.vo.OrderResultVO;
import com.ruoyi.common.core.domain.R;
@@ -38,26 +39,26 @@
     *
     * @param startDateStr 季度开始时间
     * @param endDateStr   季度结束时间
     * @param cityIdList   城市id
     * @param cityList     城市列表
     * @return 总交易额
     */
    BigDecimal totalMoneyByQuarter(String startDateStr, String endDateStr, List<String> cityIdList);
    BigDecimal totalMoneyByQuarter(String startDateStr, String endDateStr, List<String> cityList);
    /**
     * 查询整个年度的交易额(订单状态为:已完工)
     *
     * @param cityIdList 城市id
     * @param cityList 城市列表
     * @return 总交易额
     */
    BigDecimal totalMoneyByYear(List<String> cityIdList);
    BigDecimal totalMoneyByYear(List<String> cityList);
    /**
     * 查询整个月度的交易额(订单状态为:已完工)
     *
     * @param cityIdList 城市id
     * @param cityList 城市列表
     * @return 总交易额
     */
    BigDecimal totalMoneyByMonth(List<String> cityIdList);
    BigDecimal totalMoneyByMonth(List<String> cityList);
    /**
     * excel模板导出
@@ -93,4 +94,12 @@
     * @return 分页统计
     */
    IPage<OrderCountVO> orderCount(String name, String phone, Page<OrderCountVO> page);
    /**
     * 订单管理分页模块,订单数量统计
     *
     * @param orderQueryRequest 请求参数
     * @return 统计数量
     */
    OrderPageCountVO orderPageCount(OrderQueryRequest orderQueryRequest);
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/UserService.java
@@ -20,10 +20,10 @@
    /**
     * 获取用户增量趋势
     *
     * @param cityIds 城市id集合
     * @param city 城市集合
     * @return 折线图数据
     */
    List<UserTrendsVO> userTrends(List<String> cityIds);
    List<UserTrendsVO> userTrends(List<String> city);
    /**
     * 用户数据统计
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/WithdrawService.java
@@ -1,10 +1,13 @@
package com.ruoyi.admin.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.admin.entity.Order;
import com.ruoyi.admin.entity.User;
import com.ruoyi.admin.entity.Withdraw;
import com.ruoyi.admin.entity.WithdrawalSetting;
import com.ruoyi.admin.vo.UserWithdrawRecordRequestVO;
import com.ruoyi.admin.request.WithdrawExportRequest;
import com.ruoyi.admin.vo.UserWithdrawRecordVO;
import com.ruoyi.common.core.domain.R;
@@ -25,35 +28,35 @@
    /**
     * excel模板导出
     *
     * @param idList   提现记录id
     * @param exportRequest   提现记录
     * @param response 响应体
     * @return 导出结果
     */
    R<String> excelExport(List<String> idList, HttpServletResponse response);
    R<String> excelExport(WithdrawExportRequest exportRequest, HttpServletResponse response);
    /**
     * 获取用户提现金额
     *
     * @param cityIdList 城市id
     * @param cityList 城市集合
     * @return 总金额
     */
    BigDecimal withdrawalTotalMoney(List<String> cityIdList);
    BigDecimal withdrawalTotalMoney(List<String> cityList);
    /**
     * 年度查询
     *
     * @param cityIdList 城市id
     * @param cityList 城市集合
     * @return 年度提现总额
     */
    BigDecimal withdrawalTotalMoneyByYear(List<String> cityIdList);
    BigDecimal withdrawalTotalMoneyByYear(List<String> cityList);
    /**
     * 月度查询
     *
     * @param cityIdList 城市id
     * @param cityList 城市列表
     * @return 年度提现总额
     */
    BigDecimal withdrawalTotalMoneyByMonth(List<String> cityIdList);
    BigDecimal withdrawalTotalMoneyByMonth(List<String> cityList);
    /**
     * 用户所关联提现记录分页列表
@@ -62,7 +65,7 @@
     * @param page   分页参数
     * @return 分页列表
     */
    UserWithdrawRecordRequestVO withdrawList(Integer userId, Page<UserWithdrawRecordVO> page);
    IPage<UserWithdrawRecordVO> withdrawList(Integer userId, Page<UserWithdrawRecordVO> page);
    /**
     * 关闭/开启审核
@@ -78,4 +81,26 @@
     * @return 审核设置
     */
    WithdrawalSetting withdrawProcess();
    /**
     * 用户所关联提现记录分页列表
     *
     * @param nickname          用户名称
     * @param userPhone         用户手机号
     * @param applyForTime 申请开始时间
     * @param state             审核状态
     * @param page              分页
     * @return 分页列表
     */
    IPage<UserWithdrawRecordVO> withdrawPage(String nickname, String userPhone, String applyForTime,
                                             Integer state, Page<UserWithdrawRecordVO> page);
    /**
     * 提现审批通过,微信打款
     *
     * @param user 下单用户
     * @param order  订单信息
     * @return 打款结果
     */
    Boolean confirmWithdraw(User user, Order order);
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/impl/AgreementServiceImpl.java
@@ -22,7 +22,7 @@
    @Override
    public R<Agreement> dataInfo(Integer type) {
        if (Constants.ZERO.equals(type) || Constants.ONE.equals(type) || Constants.TWO.equals(type)) {
        if (!Constants.ZERO.equals(type) && !Constants.ONE.equals(type) && !Constants.TWO.equals(type)) {
            return R.fail("查询类型异常!(0注册协议;1:隐私政策;2:司机操作指导)");
        }
        return R.ok(lambdaQuery().eq(Agreement::getContentType, type).one());
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/impl/EvaluateServiceImpl.java
@@ -24,4 +24,9 @@
    public IPage<EvaluatePageVO> queryPageList(String userName, String orderNumber, String workerName, Page<Object> page) {
        return baseMapper.queryPageList(userName, orderNumber, workerName, page);
    }
    @Override
    public IPage<EvaluatePageVO> evaluateList(Integer userId, Page<EvaluatePageVO> page) {
        return baseMapper.evaluateList(userId, page);
    }
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/impl/MasterWorkerServiceImpl.java
@@ -23,12 +23,12 @@
public class MasterWorkerServiceImpl extends ServiceImpl<MasterWorkerMapper, MasterWorker> implements MasterWorkerService {
    @Override
    public List<MasterWorkerRankVO> workerRanking(List<String> cityIds) {
    public List<MasterWorkerRankVO> workerRanking(List<String> cityList) {
        List<MasterWorker> masterWorkerList;
        if (null == cityIds || cityIds.isEmpty()) {
        if (null == cityList || cityList.isEmpty()) {
            masterWorkerList = lambdaQuery().eq(MasterWorker::getIsDelete, 0).list();
        } else {
            masterWorkerList = lambdaQuery().in(MasterWorker::getCityId, cityIds).eq(MasterWorker::getIsDelete, 0).list();
            masterWorkerList = lambdaQuery().in(MasterWorker::getCity, cityList).eq(MasterWorker::getIsDelete, 0).list();
        }
        if (null == masterWorkerList || masterWorkerList.isEmpty()) {
            return new ArrayList<>();
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/impl/OrderServiceImpl.java
@@ -5,7 +5,6 @@
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.admin.entity.*;
@@ -19,7 +18,6 @@
import com.ruoyi.common.core.constant.OrderConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.GlobalException;
import com.ruoyi.common.core.utils.StringUtils;
import org.apache.commons.codec.CharEncoding;
import org.springframework.stereotype.Service;
@@ -32,7 +30,6 @@
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
@@ -64,7 +61,7 @@
    @Override
    public OrderResultVO orderCountHome(OrderCountRequest orderCount) {
        List<String> cityId = orderCount.getCityIdList();
        List<String> cityList = orderCount.getCityList();
        Integer orderState = orderCount.getOrderState();
        String countType = orderCount.getCountType();
        String startTime = orderCount.getStartTime();
@@ -72,13 +69,13 @@
        List<OrderQueryVO> list;
        // 根据查询类型查询订单信息
        if (OrderConstants.YEAR.equals(countType)) {
            list = baseMapper.orderCountByYear(cityId, orderState, startTime, endTime);
            list = baseMapper.orderCountByYear(cityList, orderState, startTime, endTime);
        } else if (OrderConstants.MONTH.equals(countType)) {
            list = baseMapper.orderCountByMonth(cityId, orderState, startTime, endTime);
            list = baseMapper.orderCountByMonth(cityList, orderState, startTime, endTime);
        } else if (OrderConstants.WEEK.equals(countType)) {
            list = baseMapper.orderCountByWeek(cityId, orderState, startTime, endTime);
            list = baseMapper.orderCountByWeek(cityList, orderState, startTime, endTime);
        } else if (OrderConstants.TODAY.equals(countType)) {
            list = baseMapper.orderCountByToday(cityId, orderState, startTime, endTime);
            list = baseMapper.orderCountByToday(cityList, orderState, startTime, endTime);
        } else {
            list = new ArrayList<>();
        }
@@ -96,18 +93,18 @@
    }
    @Override
    public BigDecimal totalMoneyByQuarter(String startDateStr, String endDateStr, List<String> cityIdList) {
        return baseMapper.totalMoneyByQuarter(startDateStr, endDateStr, cityIdList);
    public BigDecimal totalMoneyByQuarter(String startDateStr, String endDateStr, List<String> cityList) {
        return baseMapper.totalMoneyByQuarter(startDateStr, endDateStr, cityList);
    }
    @Override
    public BigDecimal totalMoneyByYear(List<String> cityIdList) {
        return baseMapper.totalMoneyByYear(cityIdList);
    public BigDecimal totalMoneyByYear(List<String> cityList) {
        return baseMapper.totalMoneyByYear(cityList);
    }
    @Override
    public BigDecimal totalMoneyByMonth(List<String> cityIdList) {
        return baseMapper.totalMoneyByMonth(cityIdList);
    public BigDecimal totalMoneyByMonth(List<String> cityList) {
        return baseMapper.totalMoneyByMonth(cityList);
    }
    @Override
@@ -141,32 +138,9 @@
    @Override
    public IPage<Order> queryPage(OrderQueryRequest orderQueryRequest) {
        // 查询参数
        String orderNumber = orderQueryRequest.getOrderNumber();
        String cityName = orderQueryRequest.getCityName();
        String reservationName = orderQueryRequest.getReservationName();
        String reservationPhone = orderQueryRequest.getReservationPhone();
        Integer state = orderQueryRequest.getState();
        String workerName = orderQueryRequest.getWorkerName();
        String workerPhone = orderQueryRequest.getWorkerPhone();
        Date orderTime = orderQueryRequest.getOrderTime();
        Date time = orderQueryRequest.getTime();
        String serveName = orderQueryRequest.getServeName();
        Page<Order> page = Page.of(orderQueryRequest.getPageNum(), orderQueryRequest.getPageSize());
        // 构建查询体
        LambdaQueryChainWrapper<Order> wrapper = lambdaQuery();
        wrapper = StringUtils.isNotBlank(orderNumber) ? wrapper.like(Order::getOrderNumber, orderNumber) : wrapper;
        wrapper = StringUtils.isNotBlank(cityName) ? wrapper.like(Order::getReservationAddress, cityName) : wrapper;
        wrapper = StringUtils.isNotBlank(reservationName) ? wrapper.like(Order::getReservationName, reservationName) : wrapper;
        wrapper = StringUtils.isNotBlank(reservationPhone) ? wrapper.like(Order::getReservationPhone, reservationPhone) : wrapper;
        wrapper = null != state ? wrapper.eq(Order::getState, state) : wrapper;
        wrapper = StringUtils.isNotBlank(workerName) ? wrapper.like(Order::getServerName, workerName) : wrapper;
        wrapper = StringUtils.isNotBlank(workerPhone) ? wrapper.like(Order::getServerPhone, workerPhone) : wrapper;
        wrapper = null != orderTime ? wrapper.eq(Order::getCreateTime, orderTime) : wrapper;
        wrapper = null != time ? wrapper.eq(Order::getTime, time) : wrapper;
        wrapper = StringUtils.isNotBlank(serveName) ? wrapper.like(Order::getServeName, serveName) : wrapper;
        // 基础查询
        return wrapper.eq(Order::getIsDelete, 0).orderByDesc(Order::getCreateTime).page(page);
        return baseMapper.queryPage(orderQueryRequest, page);
    }
    @Override
@@ -276,4 +250,35 @@
    public IPage<OrderCountVO> orderCount(String name, String phone, Page<OrderCountVO> page) {
        return baseMapper.orderCount(name, phone, page);
    }
    @Override
    public OrderPageCountVO orderPageCount(OrderQueryRequest orderQueryRequest) {
        List<Order> orderList = baseMapper.orderPageCount(orderQueryRequest);
        int total = 0;
        int toBeDispatched = 0;
        int stayDoorstep = 0;
        int toBeCompleted = 0;
        int completed = 0;
        int canceled = 0;
        int reInvestment = 0;
        for (Order order : orderList) {
            total++;
            Integer state = order.getState();
            if (Constants.ZERO.equals(state)) {
                toBeDispatched++;
            } else if (Constants.ONE.equals(state)) {
                stayDoorstep++;
            } else if (Constants.TWO.equals(state)) {
                toBeCompleted++;
            } else if (Constants.THREE.equals(state)) {
                completed++;
            } else if (Constants.FOUR.equals(state)) {
                canceled++;
            } else if (Constants.FIVE.equals(state)) {
                reInvestment++;
            }
        }
        return new OrderPageCountVO(total, toBeDispatched, stayDoorstep,
                toBeCompleted, completed, canceled, reInvestment);
    }
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/impl/UserServiceImpl.java
@@ -38,11 +38,11 @@
    private WithdrawService withdrawService;
    @Override
    public List<UserTrendsVO> userTrends(List<String> cityIds) {
        if (null == cityIds || cityIds.isEmpty()) {
    public List<UserTrendsVO> userTrends(List<String> city) {
        if (null == city || city.isEmpty()) {
            return new ArrayList<>();
        }
        List<UserTrendsVO> userTrendsList = baseMapper.userTrends(cityIds);
        List<UserTrendsVO> userTrendsList = baseMapper.userTrends(city);
        return null == userTrendsList || userTrendsList.isEmpty() ? new ArrayList<>() : userTrendsList;
    }
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/impl/WithdrawServiceImpl.java
@@ -4,20 +4,29 @@
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.admin.entity.Order;
import com.ruoyi.admin.entity.User;
import com.ruoyi.admin.entity.Withdraw;
import com.ruoyi.admin.entity.WithdrawalSetting;
import com.ruoyi.admin.mapper.WithdrawMapper;
import com.ruoyi.admin.request.WithdrawExportRequest;
import com.ruoyi.admin.service.WithdrawService;
import com.ruoyi.admin.service.WithdrawalSettingService;
import com.ruoyi.admin.vo.UserWithdrawRecordRequestVO;
import com.ruoyi.admin.utils.vx.HttpUtil;
import com.ruoyi.admin.vo.UserWithdrawRecordVO;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.constant.WechatConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.GlobalException;
import com.ruoyi.common.core.utils.SnowflakeIdWorker;
import com.ruoyi.common.core.utils.StringUtils;
import org.apache.commons.codec.CharEncoding;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@@ -27,8 +36,7 @@
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
/**
@@ -45,21 +53,64 @@
    @Resource
    private WithdrawalSettingService withdrawalSettingService;
    /**
     * 雪花算法类
     */
    private static final SnowflakeIdWorker SNOW_FLAKE_ID_WORKER = new SnowflakeIdWorker(5, 5);
    /**
     * 小程序id
     */
    @Value("wx.appid")
    private String appId;
    /**
     * 转账名称
     */
    @Value("wx.batchName")
    private String batchName;
    /**
     * 商户号
     */
    @Value("wx.mchId")
    private String mchId;
    /**
     * 支付证书序列号
     */
    @Value("wx.wechatPayserialNo")
    private String wechatPayserialNo;
    /**
     * 转账备注
     */
    @Value("wx.transferRemark")
    private String transferRemark;
    @Override
    public R<String> excelExport(List<String> ids, HttpServletResponse response) {
    public R<String> excelExport(WithdrawExportRequest exportRequest, HttpServletResponse response) {
        try {
            response.setCharacterEncoding(Constants.UTF8);
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Access-Control-Expose-Headers", "Content-disposition");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(Constants.EXCEL_WITHDRAWAL_FILE_NAME, CharEncoding.UTF_8) + ".xlsx");
            response.setHeader("Content-Disposition", "attachment;filename=" +
                    URLEncoder.encode(Constants.EXCEL_WITHDRAWAL_FILE_NAME, CharEncoding.UTF_8) + ".xlsx");
        } catch (UnsupportedEncodingException e) {
            return R.fail("excel导出失败!");
        }
        try {
            List<Withdraw> list = lambdaQuery().in(Withdraw::getId, ids).eq(Withdraw::getIsDelete, 0).list();
            String nickname = exportRequest.getNickname();
            String userPhone = exportRequest.getUserPhone();
            String applyForTime = exportRequest.getApplyForTime();
            Integer state = exportRequest.getState();
            List<String> ids = exportRequest.getIdList();
            List<UserWithdrawRecordVO> list;
            if (null != ids && !ids.isEmpty()) {
                list = baseMapper.exportByIdList(ids);
            } else {
                list = baseMapper.exportList(nickname, userPhone, applyForTime, state);
            }
            // excel模板封装
            ExcelWriterBuilder excelWriterBuilder = EasyExcelFactory.write(response.getOutputStream());
            InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("template/" + Constants.EXCEL_WITHDRAWAL_FILE_NAME + ".xlsx");
            InputStream stream = Thread.currentThread().getContextClassLoader()
                    .getResourceAsStream("template/" + Constants.EXCEL_WITHDRAWAL_FILE_NAME + ".xlsx");
            // 自动释放资源
            try (ExcelWriter excelWriter = excelWriterBuilder.withTemplate(stream).build()) {
                WriteSheet writeSheet = EasyExcelFactory.writerSheet().build();
@@ -75,32 +126,23 @@
    }
    @Override
    public BigDecimal withdrawalTotalMoney(List<String> cityIdList) {
        return baseMapper.withdrawalTotalMoney(cityIdList);
    public BigDecimal withdrawalTotalMoney(List<String> cityList) {
        return baseMapper.withdrawalTotalMoney(cityList);
    }
    @Override
    public BigDecimal withdrawalTotalMoneyByYear(List<String> cityIdList) {
        return baseMapper.withdrawalTotalMoneyByYear(cityIdList);
    public BigDecimal withdrawalTotalMoneyByYear(List<String> cityList) {
        return baseMapper.withdrawalTotalMoneyByYear(cityList);
    }
    @Override
    public BigDecimal withdrawalTotalMoneyByMonth(List<String> cityIdList) {
        return baseMapper.withdrawalTotalMoneyByMonth(cityIdList);
    public BigDecimal withdrawalTotalMoneyByMonth(List<String> cityList) {
        return baseMapper.withdrawalTotalMoneyByMonth(cityList);
    }
    @Override
    public UserWithdrawRecordRequestVO withdrawList(Integer userId, Page<UserWithdrawRecordVO> page) {
        IPage<UserWithdrawRecordVO> record = baseMapper.withdrawList(userId, page);
        // 全局审核设置
        WithdrawalSetting setting = withdrawalSettingService.lambdaQuery().one();
        Integer enableProcess;
        if (null == setting) {
            enableProcess = 0;
        } else {
            enableProcess = setting.getEnableProcess();
        }
        return new UserWithdrawRecordRequestVO(record, enableProcess);
    public IPage<UserWithdrawRecordVO> withdrawList(Integer userId, Page<UserWithdrawRecordVO> page) {
        return baseMapper.withdrawList(userId, page);
    }
    @Override
@@ -117,4 +159,88 @@
    public WithdrawalSetting withdrawProcess() {
        return withdrawalSettingService.lambdaQuery().one();
    }
    @Override
    public IPage<UserWithdrawRecordVO> withdrawPage(String nickname, String userPhone, String applyForTime, Integer state, Page<UserWithdrawRecordVO> page) {
        return baseMapper.withdrawPage(nickname, userPhone, applyForTime, state, page);
    }
    @Override
    public Boolean confirmWithdraw(User user, Order order) {
        // 校验提现
        List<Withdraw> list = this.lambdaQuery().eq(Withdraw::getUserId, user.getId())
                .eq(Withdraw::getOrderId, order).list();
        List<Integer> stateList = list.stream().map(Withdraw::getState).collect(Collectors.toList());
        if (stateList.contains(Constants.ZERO)) {
            throw new GlobalException("当前订单已提交提现申请,请等待审核!");
        } else if (stateList.contains(Constants.ONE)) {
            throw new GlobalException("当前订单已提现通过!");
        }
        return weChatPay(order.getOrderMoney(), user.getOpenId());
    }
    private boolean weChatPay(BigDecimal orderMoney, String openId) {
        if (StringUtils.isBlank(openId)) {
            return false;
        }
        Map<String, Object> postMap = new HashMap<>(8);
        // 小程序 id
        postMap.put(WechatConstants.APP_ID, appId);
        postMap.put(WechatConstants.OUT_BATCH_NO, String.valueOf(UUID.randomUUID()).replaceAll("-", ""));
        // 该笔批量转账的名称
        postMap.put(WechatConstants.BATCH_NAME, batchName);
        // 转账说明,UTF8编码,最多允许32个字符
        postMap.put(WechatConstants.BATCH_REMARK, batchName);
        // 转账金额单位为“分”。 总金额
        postMap.put(WechatConstants.TOTAL_AMOUNT, orderMoney.multiply(new BigDecimal(Constants.ONE_HUNDRED)));
        // 转账总笔数
        postMap.put(WechatConstants.TOTAL_NUM, Constants.ONE);
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> subMap = new HashMap<>(4);
        // 商家明细单号 该商家下唯一
        // subMap.put("out_detail_no", RandomUtil.randomString(32))
        subMap.put(WechatConstants.OUT_DETAIL_NO, SNOW_FLAKE_ID_WORKER.nextId());
        // 转账金额
        subMap.put(WechatConstants.TRANSFER_AMOUNT, orderMoney);
        // 转账备注
        subMap.put(WechatConstants.TRANSFER_REMARK, transferRemark);
        // 用户在直连商户应用下的用户标示
        subMap.put(WechatConstants.OPEN_ID, openId);
        // 大金额需要传入真实姓名
        /*subMap.put("user_name",
        RsaCryptoUtil.encryptOAEP(userName,WechatPayV3Util.getSaveCertificates(privatekeypath)))*/
        list.add(subMap);
        postMap.put(WechatConstants.TRANSFER_DETAIL_LIST, list);
        // 使用类加载器获取资源 URL
        ClassPathResource classPathResource = new ClassPathResource("vx/apiclient_key.pem");
        /*// 获取 resources 目录下的文件路径,假设文件路径为 "resources/data/example.txt"
        String filePath = "resources/data/vx/apiclient_key.pem";
        File file = new File(filePath);
        // 输出文件的绝对路径
        String absolutePath = file.getAbsolutePath();*/
        String result = HttpUtil.postTransBatRequest(
                WechatConstants.WE_CHAT_URL_PRE,
                JSONObject.toJSONString(postMap),
                // 支付证书序列号
                wechatPayserialNo,
                // 商户号
                mchId,
                classPathResource.getPath(), WechatConstants.WE_CHAT_URL_SUF);
        JSONObject jsonObject = JSONObject.parseObject(result);
        /*
         * 成功示例
         * {
         *   "out_batch_no": "plfk2020042013",
         *   "batch_id": "1030000071100999991182020050700019480001",
         *   "create_time": "2015-05-20T13:29:35.120+08:00"
         * }
         */
        if (null == jsonObject || null != jsonObject.get(WechatConstants.CREATE_TIME)) {
            //转账成功
            return Boolean.TRUE;
        } else {
            return Boolean.FALSE;
        }
    }
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/impl/WorkerProcessServiceImpl.java
@@ -38,7 +38,7 @@
            return R.fail("当前入驻申请已被审核!");
        }
        workerProcess.setState(state);
        workerProcess.setExamineOpinion(opinion);
        workerProcess.setOpinion(opinion);
        if (Constants.PASS_THROUGH_NUMBER.equals(state)) {
            // 审核状态为 1 已通过时,生成登录账号
            MasterWorker masterWorker = new MasterWorker();
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/sorcket/WebSocketClient.java
New file
@@ -0,0 +1,29 @@
package com.ruoyi.admin.sorcket;
import lombok.Data;
import javax.websocket.Session;
/**
 * @author HJL
 * @version 1.0
 * @since 2024-07-01 9:36
 */
@Data
public class WebSocketClient {
    /**
     * 与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    private Session session;
    /**
     * 师傅信息id
     */
    private String workerId;
    public WebSocketClient(Session session, String workerId) {
        this.session = session;
        this.workerId = workerId;
    }
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/sorcket/WebSocketServer.java
New file
@@ -0,0 +1,142 @@
package com.ruoyi.admin.sorcket;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.ruoyi.common.core.utils.StringUtils;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
/**
 * @author hjl
 */
@ServerEndpoint(value = "/websocket/{workerId}")
@Component
public class WebSocketServer {
    static Log log = LogFactory.get(WebSocketServer.class);
    /**
     * 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
     */
    private static int onlineCount = 0;
    /**
     * concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象
     */
    private static final ConcurrentHashMap<String, WebSocketClient> WEB_SOCKET_MAP = new ConcurrentHashMap<>();
    /**
     * 与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    private Session session;
    /**
     * 接收userId
     */
    private String userId = "";
    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("workerId") String workerId) {
        this.session = session;
        this.userId = workerId;
        if (WEB_SOCKET_MAP.containsKey(workerId)) {
            WEB_SOCKET_MAP.remove(workerId);
            WEB_SOCKET_MAP.put(workerId, new WebSocketClient(session, workerId));
            //加入set中
        } else {
            WEB_SOCKET_MAP.put(workerId, new WebSocketClient(session, workerId));
            //加入set中
            addOnlineCount();
        }
        log.info("用户 " + workerId + " 已连接: 当前在线人数为:" + getOnlineCount());
        try {
            sendMessage("socket连接成功!");
        } catch (IOException e) {
            log.error("用户:" + workerId + ",网络异常!!!!!!");
        }
    }
    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        if (WEB_SOCKET_MAP.containsKey(userId)) {
            WEB_SOCKET_MAP.remove(userId);
            //从set中删除
            subOnlineCount();
        }
        log.info("用户退出:" + userId + ",当前在线人数为:" + getOnlineCount());
    }
    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("用户消息:" + userId + ",报文:" + message);
        //可以群发消息
        //消息保存到数据库、redis
        if (StringUtils.isNotBlank(message)) {
            try {
                log.info("请求的userId:" + this.userId + ";接收消息:" + message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * @param session 客户端连接
     * @param error   错误原因
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("用户错误:" + this.userId + ",原因:" + error.getMessage());
        error.printStackTrace();
    }
    /**
     * 实现服务器主动推送
     */
    public void sendMessage(String message) throws IOException {
        synchronized (this.session) {
            this.session.getBasicRemote().sendText(message);
        }
    }
    /**
     * 发送自定义消息
     */
    public static void sendInfo(String message, @PathParam("workerId") String workerId) throws IOException {
        log.info("发送消息到:" + workerId + ",报文:" + message);
        if (StringUtils.isNotBlank(workerId) && WEB_SOCKET_MAP.containsKey(workerId)) {
            WEB_SOCKET_MAP.get(workerId).getSession().getBasicRemote().sendText(message);
        } else {
            log.error("用户" + workerId + ",不在线!");
        }
    }
    public static synchronized int getOnlineCount() {
        return onlineCount;
    }
    public static synchronized void addOnlineCount() {
        WebSocketServer.onlineCount++;
    }
    public static synchronized void subOnlineCount() {
        WebSocketServer.onlineCount--;
    }
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/utils/vx/HttpUtil.java
New file
@@ -0,0 +1,195 @@
package com.ruoyi.admin.utils.vx;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import static com.wechat.pay.contrib.apache.httpclient.constant.WechatPayHttpHeaders.WECHAT_PAY_SERIAL;
import static org.apache.http.HttpHeaders.ACCEPT;
import static org.apache.http.HttpHeaders.CONTENT_TYPE;
import static org.apache.http.entity.ContentType.APPLICATION_JSON;
/**
 * 微信支付专用类 请求操作方法
 *
 * @author hjl
 */
@Slf4j
public class HttpUtil {
    /**
     * 发起批量转账API 批量转账到零钱
     *
     * @param requestUrl        请求路径
     * @param requestJson       组合参数
     * @param wechatPayserialNo 商户证书序列号
     * @param privatekeypath    商户私钥证书路径
     */
    public static String postTransBatRequest(
            String requestUrl,
            String requestJson,
            String wechatPayserialNo,
            String mchId,
            String privatekeypath, String url) {
        CloseableHttpResponse response;
        HttpEntity entity;
        CloseableHttpClient httpClient = null;
        try {
            HttpPost httpPost = createHttpPost(requestUrl, requestJson, wechatPayserialNo, mchId, privatekeypath, url);
            httpClient = HttpClients.createDefault();
            //发起转账请求
            response = httpClient.execute(httpPost);
            log.info("response:{}", response);
            //获取返回的数据
            entity = response.getEntity();
            log.info("-----getHeaders.Request-ID:" + response.getHeaders("Request-ID"));
            return EntityUtils.toString(entity);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭流
            try {
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
    /**
     * 账单查询
     *
     * @param requestUrl        请求完整地址
     * @param wechatPayserialNo 商户证书序列号
     * @param privatekeypath    商户私钥证书路径
     */
    public static String getTransBatRequest(
            String requestUrl,
            String wechatPayserialNo,
            String mchId,
            String privatekeypath, String url) {
        CloseableHttpResponse response;
        HttpEntity entity;
        CloseableHttpClient httpClient = null;
        try {
            HttpGet httpPost = createHttpGet(requestUrl, wechatPayserialNo, mchId, privatekeypath, url);
            httpClient = HttpClients.createDefault();
            //发起转账请求
            response = httpClient.execute(httpPost);
            log.info("response:{}", response);
            //获取返回的数据
            entity = response.getEntity();
            log.info("-----getHeaders.Request-ID:" + response.getHeaders("Request-ID"));
            return EntityUtils.toString(entity);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭流
            try {
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
    /**
     * @param requestUrl        请求完整地址
     * @param requestJson       请求参数
     * @param wechatPayserialNo 支付证书序列号
     * @param mchId             商户号
     * @param privatekeypath    私钥路径
     * @param servletPath       相对路径
     */
    private static HttpPost createHttpPost(String requestUrl,
                                           String requestJson,
                                           String wechatPayserialNo,
                                           String mchId,
                                           String privatekeypath, String servletPath) {
        //商户私钥证书
        HttpPost httpPost = new HttpPost(requestUrl);
        // NOTE: 建议指定charset=utf-8。低于4.4.6版本的HttpCore,不能正确的设置字符集,可能导致签名错误
        httpPost.addHeader(ACCEPT, APPLICATION_JSON.toString());
        httpPost.addHeader(CONTENT_TYPE, APPLICATION_JSON.toString());
        //"55E551E614BAA5A3EA38AE03849A76D8C7DA735A");
        httpPost.addHeader(WECHAT_PAY_SERIAL, wechatPayserialNo);
        //-------------------------核心认证 start-----------------------------------------------------------------
        String strToken = null;
        try {
            log.info("requestJson:{}", requestJson);
            strToken = WechatPayV3Util.getToken("POST",
                    servletPath,
                    requestJson, mchId, wechatPayserialNo, privatekeypath);
        } catch (Exception e) {
            log.error("createHttpPost error:", e);
            e.printStackTrace();
        }
        StringEntity reqEntity = new StringEntity(requestJson, APPLICATION_JSON);
        log.info("token " + strToken);
        // 添加认证信息
        httpPost.addHeader("Authorization",
                "WECHATPAY2-SHA256-RSA2048" + " "
                        + strToken);
        //---------------------------核心认证 end---------------------------------------------------------------
        httpPost.setEntity(reqEntity);
        return httpPost;
    }
    /**
     * 创建get 请求
     *
     * @param requestUrl        请求完整地址
     * @param wechatPayserialNo 支付证书序列号
     * @param mchId             商户号
     * @param privatekeypath    私钥路径
     * @param servletPath       相对路径  请求地址上如果有参数 则此处需要带上参数
     * @return HttpGet
     */
    private static HttpGet createHttpGet(String requestUrl,
                                         String wechatPayserialNo,
                                         String mchId,
                                         String privatekeypath, String servletPath) {
        //商户私钥证书
        HttpGet httpGet = new HttpGet(requestUrl);
        // NOTE: 建议指定charset=utf-8。低于4.4.6版本的HttpCore,不能正确的设置字符集,可能导致签名错误
        httpGet.addHeader("Content-Type", "application/json");
        httpGet.addHeader("Accept", "application/json");
        //"55E551E614BAA5A3EA38AE03849A76D8C7DA735A");
        httpGet.addHeader("Wechatpay-Serial", wechatPayserialNo);
        //-------------------------核心认证 start-----------------------------------------------------------------
        String strToken = null;
        try {
            strToken = WechatPayV3Util.getToken("GET",
                    servletPath,
                    "", mchId, wechatPayserialNo, privatekeypath);
        } catch (Exception e) {
            log.error("createHttpGet error:", e);
            e.printStackTrace();
        }
        log.info("token " + strToken);
        // 添加认证信息
        httpGet.addHeader("Authorization",
                "WECHATPAY2-SHA256-RSA2048" + " "
                        + strToken);
        //---------------------------核心认证 end---------------------------------------------------------------
        return httpGet;
    }
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/utils/vx/WechatPayV3Util.java
New file
@@ -0,0 +1,113 @@
package com.ruoyi.admin.utils.vx;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Random;
/**
 * @author HJL
 */
@Slf4j
public class WechatPayV3Util {
    /**
     * @param method       请求方法 post
     * @param canonicalUrl 请求地址
     * @param body         请求参数   GET请求传空字符
     * @param merchantId   这里用的商户号
     * @param certSerialNo 商户证书序列号
     * @param keyPath      私钥商户证书地址
     */
    public static String getToken(
            String method,
            String canonicalUrl,
            String body,
            String merchantId,
            String certSerialNo,
            String keyPath) throws Exception {
        String signStr;
        //获取32位随机字符串
        String nonceStr = getRandomString(32);
        //当前系统运行时间
        long timestamp = System.currentTimeMillis() / 1000;
        String message = buildMessage(method, canonicalUrl, timestamp, nonceStr, body);
        //签名操作
        //签名操作
        String signature = sign(message.getBytes(StandardCharsets.UTF_8), keyPath);
        //组装参数
        signStr = "mchid=\"" + merchantId + "\"," +
                "timestamp=\"" + timestamp + "\"," +
                "nonce_str=\"" + nonceStr + "\"," +
                "serial_no=\"" + certSerialNo + "\"," +
                "signature=\"" + signature + "\"";
        return signStr;
    }
    public static String buildMessage(String method, String canonicalUrl, long timestamp, String nonceStr, String body) {
//        String canonicalUrl = url.encodedPath();
//        if (url.encodedQuery() != null) {
//            canonicalUrl += "?" + url.encodedQuery();
//        }
        return method + "\n" + canonicalUrl + "\n" + timestamp + "\n" + nonceStr + "\n" + body + "\n";
    }
    public static String sign(byte[] message, String keyPath) throws Exception {
        Signature sign = Signature.getInstance("SHA256withRSA");
        sign.initSign(getPrivateKey(keyPath));
        sign.update(message);
        return Base64.encodeBase64String(sign.sign());
    }
    /**
     * 微信支付-前端唤起支付参数-获取商户私钥
     *
     * @param filename 私钥文件路径  (required)
     * @return 私钥对象
     */
    public static PrivateKey getPrivateKey(String filename) throws IOException {
        log.info("签名 证书地址是 " + filename);
        String content = new String(Files.readAllBytes(Paths.get(filename)), StandardCharsets.UTF_8);
        try {
            String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "")
                    .replace("-----END PRIVATE KEY-----", "")
                    .replaceAll("\\s+", "");
            KeyFactory kf = KeyFactory.getInstance("RSA");
            return kf.generatePrivate(
                    new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey)));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("当前Java环境不支持RSA", e);
        } catch (InvalidKeySpecException e) {
            throw new RuntimeException("无效的密钥格式");
        }
    }
    /**
     * 获取随机位数的字符串
     *
     * @param length 需要的长度
     */
    public static String getRandomString(int length) {
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/vo/OrderPageCountVO.java
New file
@@ -0,0 +1,45 @@
package com.ruoyi.admin.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author HJL
 * @version 1.0
 * @since 2024-06-28 16:13
 */
@Data
public class OrderPageCountVO {
    @ApiModelProperty("全部订单")
    private Integer total;
    @ApiModelProperty("待派单")
    private Integer toBeDispatched;
    @ApiModelProperty("待上门")
    private Integer stayDoorstep;
    @ApiModelProperty("待完成")
    private Integer toBeCompleted;
    @ApiModelProperty("已完成")
    private Integer completed;
    @ApiModelProperty("已取消")
    private Integer canceled;
    @ApiModelProperty("再投订单")
    private Integer reInvestment;
    public OrderPageCountVO(Integer total, Integer toBeDispatched, Integer stayDoorstep, Integer toBeCompleted,
                            Integer completed, Integer canceled, Integer reInvestment) {
        this.total = total;
        this.toBeDispatched = toBeDispatched;
        this.stayDoorstep = stayDoorstep;
        this.toBeCompleted = toBeCompleted;
        this.completed = completed;
        this.canceled = canceled;
        this.reInvestment = reInvestment;
    }
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/vo/UserWithdrawRecordVO.java
@@ -1,6 +1,7 @@
package com.ruoyi.admin.vo;
import com.baomidou.mybatisplus.annotation.TableId;
import com.ruoyi.common.core.constant.Constants;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -38,11 +39,8 @@
    @ApiModelProperty("审批意见")
    private String opinions;
    @ApiModelProperty("用户id")
    @ApiModelProperty("用户编号")
    private String userNo;
    @ApiModelProperty("注册城市id")
    private Integer cityId;
    @ApiModelProperty("用户昵称")
    private String nickname;
@@ -50,19 +48,25 @@
    @ApiModelProperty("头像")
    private String profilePicture;
    @ApiModelProperty("创建人")
    private String createBy;
    @ApiModelProperty("修改人")
    private String updateBy;
    @ApiModelProperty("创建时间")
    private Date createTime;
    @ApiModelProperty("修改时间")
    private Date updateTime;
    @ApiModelProperty("是否软删除 0未删除;1已删除")
    private Integer isDelete;
    /**
     * 申请状态中文(导出用) 0待审核;1已通过;2已驳回
     *
     * @return 中文状态
     */
    public String getStateStr() {
        if (null == state) {
            return "未知";
        } else {
            if (Constants.AUDIT_NUMBER.equals(state)) {
                return Constants.AUDIT_STR;
            } else if (Constants.PASS_THROUGH_NUMBER.equals(state)) {
                return Constants.PASS_THROUGH_STR;
            } else if (Constants.REJECT_NUMBER.equals(state)) {
                return Constants.REJECT_STR;
            } else {
                return "未知";
            }
        }
    }
}
ruoyi-service/ruoyi-admin/src/main/resources/mapper/admin/EvaluateMapper.xml
@@ -59,4 +59,14 @@
        </where>
        order by e.createTime desc
    </select>
    <select id="evaluateList" resultMap="pageMap">
        select *
        from t_evaluate e
                 left join t_order o on e.order_id = o.id
                 left join sys_master_worker mw on e.worker_id = mw.id
        where e.is_delete = 0
          and o.is_delete = 0
          and mw.is_delete = 0
    </select>
</mapper>
ruoyi-service/ruoyi-admin/src/main/resources/mapper/admin/OrderMapper.xml
@@ -21,6 +21,7 @@
        <result column="createTime" property="createTime"/>
        <result column="updateTime" property="updateTime"/>
        <result column="is_delete" property="isDelete"/>
        <result column="apply_reason" property="applyReason"/>
    </resultMap>
@@ -29,12 +30,12 @@
        FROM t_order
        <where>
            YEAR(createTime) = YEAR(NOW())
            <!--<if test="ids != null and ids.size() != 0">
                and city_id in
                <foreach collection="ids" item="id" open="(" separator="," close=")">
        #{id}
            </foreach>
            </if>-->
            <if test="cityList != null and cityList.size() != 0">
                and city in
                <foreach collection="cityList" item="id" open="(" separator="," close=")">
                    #{id}
                </foreach>
            </if>
            <if test="orderState != null and orderState != ''">
                and state = #{orderState}
            </if>
@@ -54,12 +55,12 @@
        FROM t_order
        <where>
            YEARWEEK(DATE_FORMAT(createTime, '%Y-%m-%d')) = YEARWEEK(NOW())
            <!--<if test="ids != null and ids.size() != 0">
                and city_id in
                <foreach collection="ids" item="id" open="(" separator="," close=")">
        #{id}
            </foreach>
            </if>-->
            <if test="cityList != null and cityList.size() != 0">
                and city in
                <foreach collection="cityList" item="id" open="(" separator="," close=")">
                    #{id}
                </foreach>
            </if>
            <if test="orderState != null and orderState != ''">
                and state = #{orderState}
            </if>
@@ -80,12 +81,12 @@
        <where>
            MONTH(createTime) = MONTH(NOW())
              AND YEAR(createTime) = YEAR(NOW())
            <!--<if test="ids != null and ids.size() != 0">
                and city_id in
                <foreach collection="ids" item="id" open="(" separator="," close=")">
        #{id}
            </foreach>
            </if>-->
            <if test="cityList != null and cityList.size() != 0">
                and city in
                <foreach collection="cityList" item="id" open="(" separator="," close=")">
                    #{id}
                </foreach>
            </if>
            <if test="orderState != null and orderState != ''">
                and state = #{orderState}
            </if>
@@ -105,12 +106,12 @@
        FROM t_order
        <where>
            DATE(createTime) = CURDATE()
            <!--<if test="ids != null and ids.size() != 0">
                and city_id in
                <foreach collection="ids" item="id" open="(" separator="," close=")">
        #{id}
            </foreach>
            </if>-->
            <if test="cityList != null and cityList.size() != 0">
                and city in
                <foreach collection="cityList" item="id" open="(" separator="," close=")">
                    #{id}
                </foreach>
            </if>
            <if test="orderState != null and orderState != ''">
                and state = #{orderState}
            </if>
@@ -131,6 +132,12 @@
        <where>
            is_delete = 0
              and state = 4
            <if test="cityList != null and cityList.size() != 0">
                and city in
                <foreach collection="cityList" item="id" open="(" separator="," close=")">
                    #{id}
                </foreach>
            </if>
            <if test="start != null and start != ''">
                and createTime <![CDATA[ >= ]]> #{start}
            </if>
@@ -146,6 +153,12 @@
        where YEAR(createTime) = YEAR(NOW())
          and is_delete = 0
          and state = 4
        <if test="cityList != null and cityList.size() != 0">
            and city in
            <foreach collection="cityList" item="id" open="(" separator="," close=")">
                #{id}
            </foreach>
        </if>
    </select>
    <select id="totalMoneyByMonth" resultType="java.math.BigDecimal">
@@ -155,14 +168,20 @@
          AND YEAR(createTime) = YEAR(NOW())
          and is_delete = 0
          and state = 4
        <if test="cityList != null and cityList.size() != 0">
            and city in
            <foreach collection="cityList" item="id" open="(" separator="," close=")">
                #{id}
            </foreach>
        </if>
    </select>
    <select id="orderCount" resultType="com.ruoyi.admin.vo.OrderCountVO">
        SELECT w.real_name                                  AS realName,
               w.profile_picture                            as profilePicture,
               SUM(CASE WHEN o.state = 3 THEN 1 ELSE 0 END) AS toBeCompletedNumber,
               SUM(CASE WHEN o.state = 4 THEN 1 ELSE 0 END) AS completedNumber,
        SUM(CASE WHEN o.state = 5 THEN 1 ELSE 0 END) AS reInvestment
               SUM(CASE WHEN o.state = 2 THEN 1 ELSE 0 END) AS toBeCompletedNumber,
               SUM(CASE WHEN o.state = 3 THEN 1 ELSE 0 END) AS completedNumber,
               SUM(CASE WHEN o.state = 4 THEN 1 ELSE 0 END) AS reInvestment
        FROM t_order o
                 LEFT JOIN sys_master_worker w ON o.server_id = w.id
        WHERE w.is_delete = 0
@@ -175,4 +194,96 @@
        </if>
        GROUP BY w.real_name, w.profile_picture
    </select>
    <select id="queryPage" resultMap="BaseResultMap">
        select o.*, c.apply_reason
        from t_order o
                 left join sys_change_dispatch c on o.id = c.order_id
        <where>
            o.is_delete = 0
              AND (c.is_delete = 0 OR c.is_delete IS NULL)
            <if test="data.orderNumber != null and data.orderNumber != ''">
                and o.order_number like concat('%', #{data.orderNumber}, '%')
            </if>
            <if test="data.cityName != null and data.cityName != ''">
                and o.city like concat('%', #{data.cityName}, '%')
            </if>
            <if test="data.reservationName != null and data.reservationName != ''">
                and o.reservation_name like concat('%', #{data.reservationName}, '%')
            </if>
            <if test="data.reservationPhone != null and data.reservationPhone != ''">
                and o.reservation_phone like concat('%', #{data.reservationPhone}, '%')
            </if>
            <if test="data.state != null">
                and o.state = #{data.state}
            </if>
            <if test="data.workerName != null and data.workerName != ''">
                and o.server_name like concat('%', #{data.workerName}, '%')
            </if>
            <if test="data.workerPhone != null and data.workerPhone != ''">
                and o.server_phone like concat('%', #{data.workerPhone}, '%')
            </if>
            <if test="data.serveName != null and data.serveName != ''">
                and o.serve_name like concat('%', #{data.serveName}, '%')
            </if>
            <if test="data.orderTimeStart != null and data.orderTimeStart != ''">
                and DATE(o.createTime) <![CDATA[ >= ]]> #{data.orderTimeStart}
            </if>
            <if test="data.orderTimeEnd != null and data.orderTimeEnd != ''">
                and DATE(o.createTime) <![CDATA[ <= ]]> #{data.orderTimeEnd}
            </if>
            <if test="data.startTime != null and data.startTime != ''">
                and DATE(o.time) <![CDATA[ >= ]]> #{data.startTime}
            </if>
            <if test="data.endTime != null and data.endTime != ''">
                and DATE(o.time) <![CDATA[ <= ]]> #{data.endTime}
            </if>
        </where>
    </select>
    <select id="orderPageCount" resultMap="BaseResultMap">
        select o.*, c.apply_reason
        from t_order o
        left join sys_change_dispatch c on o.id = c.order_id
        <where>
            o.is_delete = 0
            AND (c.is_delete = 0 OR c.is_delete IS NULL)
            <if test="data.orderNumber != null and data.orderNumber != ''">
                and o.order_number like concat('%', #{data.orderNumber}, '%')
            </if>
            <if test="data.cityName != null and data.cityName != ''">
                and o.city like concat('%', #{data.cityName}, '%')
            </if>
            <if test="data.reservationName != null and data.reservationName != ''">
                and o.reservation_name like concat('%', #{data.reservationName}, '%')
            </if>
            <if test="data.reservationPhone != null and data.reservationPhone != ''">
                and o.reservation_phone like concat('%', #{data.reservationPhone}, '%')
            </if>
            <if test="data.state != null">
                and o.state = #{data.state}
            </if>
            <if test="data.workerName != null and data.workerName != ''">
                and o.server_name like concat('%', #{data.workerName}, '%')
            </if>
            <if test="data.workerPhone != null and data.workerPhone != ''">
                and o.server_phone like concat('%', #{data.workerPhone}, '%')
            </if>
            <if test="data.serveName != null and data.serveName != ''">
                and o.serve_name like concat('%', #{data.serveName}, '%')
            </if>
            <if test="data.orderTimeStart != null and data.orderTimeStart != ''">
                and DATE(o.createTime) <![CDATA[ >= ]]> #{data.orderTimeStart}
            </if>
            <if test="data.orderTimeEnd != null and data.orderTimeEnd != ''">
                and DATE(o.createTime) <![CDATA[ <= ]]> #{data.orderTimeEnd}
            </if>
            <if test="data.startTime != null and data.startTime != ''">
                and DATE(o.time) <![CDATA[ >= ]]> #{data.startTime}
            </if>
            <if test="data.endTime != null and data.endTime != ''">
                and DATE(o.time) <![CDATA[ <= ]]> #{data.endTime}
            </if>
        </where>
    </select>
</mapper>
ruoyi-service/ruoyi-admin/src/main/resources/mapper/admin/UserMapper.xml
@@ -20,10 +20,10 @@
        SELECT DATE_FORMAT(createTime, '%Y-%m') AS date, COUNT(*) AS number
        FROM t_user
        <where>
            <if test="ids != null and ids.size() != 0">
                city_id in
                <foreach collection="ids" item="id" open="(" separator="," close=")">
                    #{id}
            <if test="city != null and city.size() != 0">
                city in
                <foreach collection="city" item="city" open="(" separator="," close=")">
                #{city}
                </foreach>
            </if>
            and is_delete = 0
@@ -38,6 +38,12 @@
        FROM t_user
        WHERE YEAR(createTime) = YEAR(NOW())
          and is_delete = 0
        <if test="cityList != null and cityList.size() != 0">
            and city in
            <foreach collection="cityList" item="city" open="(" separator="," close=")">
                #{city}
            </foreach>
        </if>
    </select>
    <select id="increaseNumberByMonth" resultType="java.lang.Long">
@@ -45,5 +51,11 @@
        FROM t_user
        WHERE MONTH(createTime) = MONTH(NOW())
          AND YEAR(createTime) = YEAR(NOW())
        <if test="cityList != null and cityList.size() != 0">
            and city in
            <foreach collection="cityList" item="city" open="(" separator="," close=")">
                #{city}
            </foreach>
        </if>
    </select>
</mapper>
ruoyi-service/ruoyi-admin/src/main/resources/mapper/admin/WithdrawMapper.xml
@@ -9,7 +9,7 @@
        <result column="apply_for_time" property="applyForTime"/>
        <result column="apply_for_money" property="applyForMoney"/>
        <result column="state" property="state"/>
        <result column="opinions" property="opinions"/>
        <result column="opinion" property="opinion"/>
        <result column="createBy" property="createBy"/>
        <result column="updateBy" property="updateBy"/>
        <result column="createTime" property="createTime"/>
@@ -22,9 +22,9 @@
        FROM t_withdraw w
                 LEFT JOIN t_user u on w.user_id = u.id
        <where>
            <if test="ids != null and ids.size() != 0">
                u.city_id in
                <foreach collection="ids" item="id" open="(" separator="," close=")">
            <if test="cityList != null and cityList.size() != 0">
                u.city in
                <foreach collection="cityList" item="id" open="(" separator="," close=")">
                    #{id}
                </foreach>
            </if>
@@ -38,9 +38,9 @@
        <where>
            YEAR(w.createTime) = YEAR(NOW())
              and w.is_delete = 0
            <if test="ids != null and ids.size() != 0">
                and u.city_id in
                <foreach collection="ids" item="id" open="(" separator="," close=")">
            <if test="cityList != null and cityList.size() != 0">
                and u.city in
                <foreach collection="cityList" item="id" open="(" separator="," close=")">
                    #{id}
                </foreach>
            </if>
@@ -55,9 +55,9 @@
            YEAR(w.createTime) = YEAR(NOW())
              AND YEAR(w.createTime) = YEAR(NOW())
              and w.is_delete = 0
            <if test="ids != null and ids.size() != 0">
                and u.city_id in
                <foreach collection="ids" item="id" open="(" separator="," close=")">
            <if test="cityList != null and cityList.size() != 0">
                and u.city in
                <foreach collection="cityList" item="id" open="(" separator="," close=")">
                    #{id}
                </foreach>
            </if>
@@ -72,16 +72,12 @@
        <result column="apply_for_money" property="applyForMoney"/>
        <result column="state" property="state"/>
        <result column="opinions" property="opinions"/>
        <result column="createBy" property="createBy"/>
        <result column="updateBy" property="updateBy"/>
        <result column="createTime" property="createTime"/>
        <result column="updateTime" property="updateTime"/>
        <result column="is_delete" property="isDelete"/>
        <result column="user_no" property="userNo"/>
        <result column="profile_picture" property="profilePicture"/>
        <result column="nickname" property="nickname"/>
        <result column="phone" property="userPhone"/>
    </resultMap>
    <select id="withdrawList" resultType="com.ruoyi.admin.vo.UserWithdrawRecordVO">
    <select id="withdrawList" resultMap="voMap">
        SELECT w.*, u.user_no, u.profile_picture, u.nickname
        FROM t_withdraw w
                 LEFT JOIN t_user u on w.user_id = u.id
@@ -93,4 +89,65 @@
            </if>
        </where>
    </select>
    <select id="withdrawPage" resultMap="voMap">
        SELECT w.*, u.user_no, u.profile_picture, u.nickname
        FROM t_withdraw w
                 LEFT JOIN t_user u on w.user_id = u.id
        <where>
            w.is_delete = 0
              and u.is_delete = 0
            <if test="name != null and name != ''">
                and u.nickname like concat('%', #{name}, '%')
            </if>
            <if test="phone != null and phone != ''">
                and u.phone like concat('%', #{phone}, '%')
            </if>
            <if test="time != null and time != ''">
                and DATE(w.apply_for_time) = #{time}
            </if>
            <if test="state != null">
                and w.state = #{state}
            </if>
        </where>
        order by w.createTime desc
    </select>
    <select id="exportList" resultMap="voMap">
        SELECT w.*, u.user_no, u.profile_picture, u.nickname, u.phone
        FROM t_withdraw w
                 LEFT JOIN t_user u on w.user_id = u.id
        <where>
            w.is_delete = 0
              and u.is_delete = 0
            <if test="name != null and name != ''">
                and u.nickname like concat('%', #{name}, '%')
            </if>
            <if test="phone != null and phone != ''">
                and u.phone like concat('%', #{phone}, '%')
            </if>
            <if test="time != null and time != ''">
                and DATE(w.apply_for_time) = #{time}
            </if>
            <if test="state != null">
                and w.state = #{state}
            </if>
        </where>
        order by w.createTime desc
    </select>
    <select id="exportByIdList" resultMap="voMap">
        SELECT w.*, u.user_no, u.profile_picture, u.nickname
        FROM t_withdraw w
                 LEFT JOIN t_user u on w.user_id = u.id
        <where>
            w.is_delete = 0
              and u.is_delete = 0
              and w.id in
            <foreach collection="list" item="id" open="(" separator="," close=")">
                #{id}
            </foreach>
        </where>
        order by w.createTime desc
    </select>
</mapper>
ruoyi-service/ruoyi-admin/src/main/resources/template/提现记录.xlsx
Binary files differ
ruoyi-service/ruoyi-user/src/main/java/com/ruoyi/user/controller/OrderController.java
@@ -7,7 +7,6 @@
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.GlobalException;
import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.system.api.model.LoginUser;
import com.ruoyi.system.api.model.LoginUserInfo;
import com.ruoyi.user.entity.Order;
import com.ruoyi.user.entity.ServeRecord;
ruoyi-service/ruoyi-user/src/main/java/com/ruoyi/user/entity/Order.java
@@ -30,6 +30,10 @@
    @TableId(value = "id",type = IdType.AUTO)
    private Integer id;
    @ApiModelProperty("下单城市")
    @TableField("city")
    private String city;
    @ApiModelProperty("订单编号")
    @TableField("order_number")
    private String orderNumber;
ruoyi-service/ruoyi-user/src/main/java/com/ruoyi/user/entity/Withdraw.java
@@ -51,8 +51,8 @@
    private Integer state;
    @ApiModelProperty("审批意见")
    @TableField("opinions")
    private String opinions;
    @TableField("opinion")
    private String opinion;
    @ApiModelProperty("订单id")
    @TableField("order_id")
ruoyi-service/ruoyi-user/src/main/resources/mapper/user/RecoveryServeMapper.xml
@@ -39,6 +39,6 @@
                 left join sys_recovery_classify c on s.classify_id = c.id
        where s.is_delete = 0
          and c.is_delete = 0
        order by c.`order`
        order by c.sort
    </select>
</mapper>
ruoyi-service/ruoyi-user/src/main/resources/mapper/user/UserMapper.xml
@@ -9,7 +9,6 @@
        <result column="phone" property="phone"/>
        <result column="profile_picture" property="profilePicture"/>
        <result column="state" property="state"/>
        <result column="city_id" property="cityId"/>
        <result column="createBy" property="createBy"/>
        <result column="updateBy" property="updateBy"/>
        <result column="createTime" property="createTime"/>
ruoyi-service/ruoyi-user/src/main/resources/mapper/user/WithdrawMapper.xml
@@ -9,7 +9,7 @@
        <result column="apply_for_time" property="applyForTime"/>
        <result column="apply_for_money" property="applyForMoney"/>
        <result column="state" property="state"/>
        <result column="opinions" property="opinions"/>
        <result column="opinion" property="opinion"/>
        <result column="createBy" property="createBy"/>
        <result column="updateBy" property="updateBy"/>
        <result column="createTime" property="createTime"/>
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/controller/MasterWorkerController.java
@@ -30,7 +30,6 @@
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Pattern;
@@ -115,7 +114,7 @@
        String phone = loginPhoneRequest.getPhone();
        String phoneCode = loginPhoneRequest.getPhoneCode();
        // 默认验证码 123456
        if (!"123456".equals(phoneCode)) {
        if (!Constants.DEFAULT_PHONE_CODE.equals(phoneCode)) {
            // 手机验证码校验获取缓存验证码
            Object phoneCodeRedis = redisService.getCacheObject(RedisConstants.WORKER_APPLY_KEY + phone);
            if (null == phoneCodeRedis) {
@@ -151,14 +150,16 @@
    @PostMapping(value = "/settledApply")
    public R<String> settledApply(@RequestBody WorkerProcess workerProcess) {
        String phone = workerProcess.getPhone();
        String phoneCode = workerProcess.getPhoneCode();
        Object redisCodeObj = redisService.getCacheObject(RedisConstants.WORKER_SETTLE_KEY + phone);
        if (null == redisCodeObj) {
            return R.errorCode("验证码错误或已过期!");
        }
        String redisCodeStr = String.valueOf(redisCodeObj).split(":")[0];
        if (!String.valueOf(redisCodeStr).equalsIgnoreCase(phoneCode)) {
            return R.errorCode("验证码错误或已过期!");
        String phoneCode = workerProcess.getCode();
        if (!Constants.DEFAULT_PHONE_CODE.equals(phoneCode)) {
            Object redisCodeObj = redisService.getCacheObject(RedisConstants.WORKER_SETTLE_KEY + phone);
            if (null == redisCodeObj) {
                return R.errorCode("验证码错误或已过期!");
            }
            String redisCodeStr = String.valueOf(redisCodeObj).split(":")[0];
            if (!String.valueOf(redisCodeStr).equalsIgnoreCase(phoneCode)) {
                return R.errorCode("验证码错误或已过期!");
            }
        }
        // 校验手机号是否已注册
        MasterWorker masterWorker = masterWorkerService.lambdaQuery().eq(MasterWorker::getPhone, phone)
@@ -205,14 +206,16 @@
            @ApiImplicitParam(value = "手机验证码", name = "phoneCode", dataType = "String", required = true)
    })
    public R<String> verifyPhone(@RequestParam String phone, @RequestParam String phoneCode) {
        // 验证码是否一致
        Object redisCode = redisService.getCacheObject(RedisConstants.WORKER_APPLY_KEY + phone);
        if (null == redisCode) {
            return R.errorCode("验证码错误或已过期!");
        }
        String redisCodeStr = String.valueOf(redisCode).split(",")[0];
        if (!String.valueOf(redisCodeStr).equalsIgnoreCase(phoneCode)) {
            return R.errorCode("验证码错误或已过期!");
        if (!Constants.DEFAULT_PHONE_CODE.equals(phoneCode)) {
            // 验证码是否一致
            Object redisCode = redisService.getCacheObject(RedisConstants.WORKER_APPLY_KEY + phone);
            if (null == redisCode) {
                return R.errorCode("验证码错误或已过期!");
            }
            String redisCodeStr = String.valueOf(redisCode).split(",")[0];
            if (!String.valueOf(redisCodeStr).equalsIgnoreCase(phoneCode)) {
                return R.errorCode("验证码错误或已过期!");
            }
        }
        // 手机号是否注册
        MasterWorker worker = masterWorkerService.lambdaQuery().eq(MasterWorker::getPhone, phone)
@@ -237,7 +240,7 @@
    })
    public R<Boolean> updatePassword(@RequestParam String phone, @RequestParam String password, HttpServletRequest request) {
        // 密码长度至少为8位,且不能全是英文字母或数字
        String regex = "^(?=.*[0-9])(?=.*[a-zA-Z])(?!.*[a-zA-Z]{8,})(?!.*\\d{8,}).{8,}$";
        String regex = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,}$";
        if (!Pattern.matches(regex, password)) {
            return R.passwordIllegality("密码至少8个字符,不能全是字母或数字");
        }
@@ -302,6 +305,19 @@
    }
    /**
     * 师傅端-订单代办列表
     */
    @ApiOperation(value = "订单置顶", tags = {"师傅端-首页"})
    @GetMapping(value = "/orderTop")
    public R<Boolean> orderTop(@RequestParam Integer orderId) {
        LoginUserInfo loginWorker = tokenService.getLoginUserByWorker();
        if (null == loginWorker) {
            return R.loginExpire("登录已失效!");
        }
        return masterWorkerService.orderTop(orderId, loginWorker.getUserid()) ? R.ok() : R.fail();
    }
    /**
     * 师傅端-登录用户详情
     */
    @ApiOperation(value = "登录用户详情", tags = {"师傅端-个人中心"})
@@ -330,6 +346,25 @@
            AuthUtil.logoutByTokenWorker(token);
        }
        return R.ok("退出登录成功!");
    }
    /**
     * 师傅端-修改头像
     */
    @ApiOperation(value = "修改头像", tags = {"师傅端-个人中心"})
    @GetMapping(value = "/updateProfilePicture")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "头像地址", name = "profilePicture", dataType = "String", required = true)
    })
    public R<String> updateProfilePicture(@RequestParam String profilePicture) {
        LoginUserInfo loginWorker = tokenService.getLoginUserByWorker();
        if (null == loginWorker) {
            return R.loginExpire("登录已失效!");
        }
        boolean update = masterWorkerService.lambdaUpdate().set(MasterWorker::getProfilePicture, profilePicture)
                .eq(MasterWorker::getId, loginWorker.getUserid())
                .eq(MasterWorker::getIsDelete, 0).update();
        return update ? R.ok("修改成功!") : R.fail("修改失败!");
    }
    /**
@@ -376,12 +411,13 @@
    @ApiImplicitParams({
            @ApiImplicitParam(value = "生日", name = "birthday", dataType = "Date", required = true)
    })
    public R<String> updateBirthday(@RequestParam Date birthday) {
    public R<String> updateBirthday(@RequestParam String birthday) {
        LoginUserInfo loginWorker = tokenService.getLoginUserByWorker();
        if (null == loginWorker) {
            return R.loginExpire("登录已失效!");
        }
        boolean update = masterWorkerService.lambdaUpdate().set(MasterWorker::getBirthday, birthday).eq(MasterWorker::getId, loginWorker.getUserid())
        boolean update = masterWorkerService.lambdaUpdate().set(MasterWorker::getBirthday, birthday)
                .eq(MasterWorker::getId, loginWorker.getUserid())
                .eq(MasterWorker::getIsDelete, 0).update();
        return update ? R.ok("修改成功!") : R.fail("修改失败!");
    }
@@ -396,14 +432,16 @@
            @ApiImplicitParam(value = "手机验证码", name = "code", dataType = "String", required = true)
    })
    public R<String> updatePhone(@RequestParam String phone, @RequestParam String code, HttpServletRequest request) {
        // 验证码是否一致
        Object redisCode = redisService.getCacheObject(RedisConstants.WORKER_APPLY_KEY + phone);
        if (null == redisCode) {
            return R.errorCode("验证码错误或已过期!");
        }
        String redisCodeStr = String.valueOf(redisCode).split(",")[0];
        if (!String.valueOf(redisCodeStr).equalsIgnoreCase(code)) {
            return R.errorCode("验证码错误或已过期!");
        if (!Constants.DEFAULT_PHONE_CODE.equals(code)) {
            // 验证码是否一致
            Object redisCode = redisService.getCacheObject(RedisConstants.WORKER_APPLY_KEY + phone);
            if (null == redisCode) {
                return R.errorCode("验证码错误或已过期!");
            }
            String redisCodeStr = String.valueOf(redisCode).split(",")[0];
            if (!String.valueOf(redisCodeStr).equalsIgnoreCase(code)) {
                return R.errorCode("验证码错误或已过期!");
            }
        }
        LoginUserInfo loginWorker = tokenService.getLoginUserByWorker();
        if (null == loginWorker) {
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/controller/OssController.java
New file
@@ -0,0 +1,78 @@
package com.ruoyi.worker.controller;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.GlobalException;
import com.ruoyi.common.core.utils.GaoDeMapUtil;
import com.ruoyi.common.core.utils.ObsUploadUtil;
import com.ruoyi.worker.entity.Order;
import com.ruoyi.worker.service.OrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
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.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.IOException;
/**
 * @author HJL
 * @version 1.0
 * @since 2024-05-30 9:27
 */
@RestController
@RequestMapping("/oss")
@Api(tags = "师傅端-文件上传")
public class OssController {
    @Resource
    private OrderService orderService;
    @PostMapping("/upload")
    @ApiOperation(value = "文件上传", tags = "师傅端-文件上传")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "文件", name = "file", dataType = "MultipartFile", required = true)
    })
    public R<String> upload(@RequestParam("file") MultipartFile file) {
        try {
            return R.ok(ObsUploadUtil.obsUpload(file), "");
        } catch (IOException e) {
            return R.fail("文件上传失败!");
        }
    }
    @PostMapping("/uploadPhoto")
    @ApiOperation(value = "师傅端-上传完工照片", tags = "公共-文件上传")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "照片", name = "file", dataType = "MultipartFile", required = true),
            @ApiImplicitParam(value = "订单id", name = "orderId", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "师傅所在经度", name = "longitude", dataType = "String", required = true),
            @ApiImplicitParam(value = "师傅所在纬度", name = "latitude", dataType = "String", required = true)
    })
    public R<String> uploadPhoto(@RequestParam("file") MultipartFile file, @RequestParam String orderId,
                                 @RequestParam String longitude, @RequestParam String latitude) {
        // 校验经纬度
        Order order = orderService.lambdaQuery().eq(Order::getIsDelete, orderId).eq(Order::getIsDelete, 0).one();
        // 用户下单位置经纬度
        String orderPosition = order.getLongitude() + "," + order.getLatitude();
        // 师傅经纬度
        String workerPosition = longitude + "," + latitude;
        // 师傅当前位置离用户下单位置具体距离
        Long distance = GaoDeMapUtil.getDistance(orderPosition, workerPosition).getDatas();
        // 上传时判断是否在下单位置附件,距离大于某个值则 不允许上传
        if (distance > Constants.THREE_THOUSAND) {
            throw new GlobalException("您当前手机定位超出当前订单预约地址范围 3km,无法提供回收服务!");
        }
        try {
            return R.ok(ObsUploadUtil.obsUpload(file));
        } catch (IOException e) {
            return R.fail("文件上传失败!");
        }
    }
}
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/entity/MasterWorker.java
@@ -10,8 +10,6 @@
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
/**
 * <p>
 * 师傅信息表
@@ -33,10 +31,6 @@
    @TableField("city")
    private String city;
    @ApiModelProperty("服务城市id")
    @TableField("city_id")
    private Integer cityId;
    @ApiModelProperty("用户编号(用户昵称/用户id)")
    @TableField("user_number")
    private String userNumber;
@@ -55,7 +49,7 @@
    @ApiModelProperty("生日")
    @TableField("birthday")
    private Date birthday;
    private String birthday;
    @ApiModelProperty("身份证号码")
    @TableField("id_number")
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/entity/Order.java
@@ -27,8 +27,12 @@
@ApiModel(value = "Order对象", description = "订单管理")
public class Order extends BaseEntity {
    @TableId(value = "id",type = IdType.AUTO)
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    @ApiModelProperty("下单城市")
    @TableField("city")
    private String city;
    @ApiModelProperty("订单编号")
    @TableField("order_number")
@@ -134,4 +138,8 @@
    @TableField("address")
    private String address;
    @ApiModelProperty("置顶顺序")
    @TableField("top_sort")
    private Integer topSort;
}
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/entity/WorkerProcess.java
@@ -85,11 +85,11 @@
    private Integer state;
    @ApiModelProperty("审批意见")
    @TableField("examine_opinion")
    private String examineOpinion;
    @TableField("opinion")
    private String opinion;
    @ApiModelProperty("手机验证码")
    @TableField(exist = false)
    private String phoneCode;
    private String code;
}
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/service/MasterWorkerService.java
@@ -36,4 +36,12 @@
     */
    List<OrderListVO> orderNotHandle(Integer userid, String longitude, String latitude);
    /**
     * 订单置顶
     *
     * @param orderId 订单id
     * @param userid  用户id
     * @return 操作结果
     */
    Boolean orderTop(Integer orderId, Integer userid);
}
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/service/impl/MasterWorkerServiceImpl.java
@@ -45,14 +45,18 @@
    @Override
    public List<OrderListVO> orderNotHandle(Integer userid, String longitude, String latitude) {
        List<Order> orderList = orderService.lambdaQuery().eq(Order::getServerId, userid).eq(Order::getState, Constants.TWO)
                .eq(Order::getIsDelete, 0).eq(Order::getType, Constants.ZERO).list();
        List<Order> orderList = orderService.lambdaQuery().eq(Order::getServerId, userid)
                .eq(Order::getState, Constants.ONE)
                .eq(Order::getIsDelete, 0)
                .eq(Order::getType, Constants.ZERO)
                .orderByAsc(Order::getTopSort).list();
        // 根据经纬度距离封装
        List<OrderNotHandleVO> list = new ArrayList<>();
        for (Order order : orderList) {
            // 用户下单经纬度
            Double orderLongitude = order.getLongitude();
            Double orderLatitude = order.getLatitude();
            Integer topSort = order.getTopSort();
            String orderPosition = orderLongitude + "," + orderLatitude;
            // 根据经纬度计算与师傅的距离
            Result<Long> result = GaoDeMapUtil.getDistance(orderPosition, longitude + "," + latitude);
@@ -86,6 +90,7 @@
            orderListVO.setType(order.getType());
            orderListVO.setLongitude(order.getLongitude());
            orderListVO.setLatitude(order.getLatitude());
            orderListVO.setTopSort(topSort);
            OrderNotHandleVO vo = new OrderNotHandleVO(distance, orderListVO);
            list.add(vo);
        }
@@ -104,4 +109,23 @@
        return resultList;
    }
    @Override
    public Boolean orderTop(Integer orderId, Integer userid) {
        // 订单代办列表
        List<Order> orderList = orderService.lambdaQuery().eq(Order::getServerId, userid)
                .eq(Order::getState, Constants.ONE)
                .eq(Order::getIsDelete, 0)
                .eq(Order::getType, Constants.ZERO)
                .orderByAsc(Order::getTopSort).list();
        List<Order> orders = orderList.stream().filter(data -> null != data.getTopSort()).collect(Collectors.toList());
        int itemSort = 2;
        for (Order order : orders) {
            order.setTopSort(itemSort);
            itemSort++;
        }
        return orderService.lambdaUpdate().set(Order::getTopSort, Constants.ONE)
                .eq(Order::getServerId, userid)
                .eq(Order::getIsDelete, 0).update();
    }
}
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/vo/OrderListVO.java
@@ -1,5 +1,6 @@
package com.ruoyi.worker.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -86,6 +87,10 @@
    @ApiModelProperty("下单用户纬度")
    private Double latitude;
    @ApiModelProperty("置顶顺序")
    @TableField("top_sort")
    private Integer topSort;
    public OrderListVO(Integer orderId) {
        this.orderId = orderId;
    }
ruoyi-service/ruoyi-worker/src/main/resources/mapper/worker/MasterWorkerMapper.xml
@@ -5,7 +5,6 @@
    <resultMap id="BaseResultMap" type="com.ruoyi.worker.entity.MasterWorker">
        <id column="id" property="id"/>
        <result column="city" property="city"/>
        <result column="city_id" property="cityId"/>
        <result column="user_number" property="userNumber"/>
        <result column="password" property="password"/>
        <result column="real_name" property="realName"/>
@@ -27,12 +26,11 @@
    </resultMap>
    <select id="orderCount" resultType="com.ruoyi.worker.vo.OrderCountVO">
        SELECT
            COALESCE(SUM(CASE WHEN o.state IN (2, 3, 4) THEN 1 ELSE 0 END), 0) AS total,
            COALESCE(SUM(CASE WHEN o.state = 2 THEN 1 ELSE 0 END), 0) AS waitVisit,
            COALESCE(SUM(CASE WHEN o.state = 4 THEN 1 ELSE 0 END), 0) AS completed
        FROM
            t_order o left join sys_master_worker m on o.server_id = m.id
        SELECT COALESCE(SUM(CASE WHEN o.state IN (2, 3, 4) THEN 1 ELSE 0 END), 0) AS total,
               COALESCE(SUM(CASE WHEN o.state = 2 THEN 1 ELSE 0 END), 0)          AS waitVisit,
               COALESCE(SUM(CASE WHEN o.state = 4 THEN 1 ELSE 0 END), 0)          AS completed
        FROM t_order o
                 left join sys_master_worker m on o.server_id = m.id
        where m.id = #{id}
    </select>
</mapper>
ruoyi-service/ruoyi-worker/src/main/resources/mapper/worker/WorkerProcessMapper.xml
@@ -21,6 +21,6 @@
        <result column="createTime" property="createTime"/>
        <result column="updateTime" property="updateTime"/>
        <result column="is_delete" property="isDelete"/>
        <result column="examine_opinion" property="examineOpinion"/>
        <result column="opinion" property="opinion"/>
    </resultMap>
</mapper>
ruoyi-visual/ruoyi-monitor/src/main/java/com/ruoyi/modules/monitor/config/WebSecurityConfigurer.java
@@ -9,22 +9,19 @@
/**
 * 监控权限配置
 *
 *
 * @author ruoyi
 */
@EnableWebSecurity
public class WebSecurityConfigurer
{
public class WebSecurityConfigurer {
    private final String adminContextPath;
    public WebSecurityConfigurer(AdminServerProperties adminServerProperties)
    {
    public WebSecurityConfigurer(AdminServerProperties adminServerProperties) {
        this.adminContextPath = adminServerProperties.getContextPath();
    }
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception
    {
    public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
        SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
        successHandler.setTargetUrlParameter("redirectTo");
        successHandler.setDefaultTargetUrl(adminContextPath + "/");