hjl
2024-07-02 242725f795b4cca830421c07f714a3ec36af0add
feat: 代码初始化、腾讯云短信SDK
1 文件已重命名
28个文件已修改
436 ■■■■ 已修改文件
ruoyi-api/ruoyi-api-admin/src/main/java/com/ruoyi/admin/api/entity/ChangeDispatch.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-admin/src/main/java/com/ruoyi/admin/api/factory/AdminFallbackFactory.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-admin/src/main/java/com/ruoyi/admin/api/feignClient/AdminClient.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/GaoDeMapUtil.java 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/vo/Steps.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/pom.xml 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/ChangeDispatchController.java 43 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/MasterWorkerController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/OrderController.java 97 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/entity/ChangeDispatch.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/entity/Order.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/mapper/OrderMapper.java 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/request/OrderQueryRequest.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/OrderService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | 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/OrderServiceImpl.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/impl/SendSmsServiceImpl.java 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/sorcket/WebSocketServer.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/utils/GeneratorCodeConfig.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/vo/OrderByEvaluateVO.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/vo/OrderByServeRecordVO.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/vo/OrderByUserInfoVO.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/vo/OrderInfoVO.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/resources/mapper/admin/OrderMapper.xml 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/controller/OrderController.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/controller/OssController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/service/impl/MasterWorkerServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/service/impl/OrderServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-worker/src/main/resources/mapper/worker/MasterWorkerMapper.xml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-admin/src/main/java/com/ruoyi/admin/api/entity/ChangeDispatch.java
File was renamed from ruoyi-api/ruoyi-api-admin/src/main/java/com/ruoyi/admin/api/entity/ExchangeDispatch.java
@@ -23,7 +23,7 @@
@Setter
@TableName("sys_change_dispatch")
@ApiModel(value = "ExchangeDispatch对象", description = "改派管理")
public class ExchangeDispatch extends BaseEntity {
public class ChangeDispatch extends BaseEntity {
    @TableId("id")
    private Integer id;
ruoyi-api/ruoyi-api-admin/src/main/java/com/ruoyi/admin/api/factory/AdminFallbackFactory.java
@@ -28,11 +28,16 @@
            }
            @Override
            public R<Boolean> changeDispatchSave(ExchangeDispatch changeDispatch) {
            public R<Boolean> changeDispatchSave(ChangeDispatch changeDispatch) {
                return R.fail(Boolean.FALSE);
            }
            @Override
            public R<ChangeDispatch> changeDispatchOne(Integer id) {
                return R.fail("获取订单改派详情失败" + cause.getMessage());
            }
            @Override
            public R<List<Notices>> noticesList() {
                return R.fail("获取通知公告列表失败" + cause.getMessage());
            }
ruoyi-api/ruoyi-api-admin/src/main/java/com/ruoyi/admin/api/feignClient/AdminClient.java
@@ -44,7 +44,16 @@
     * @return 详细数据
     */
    @PostMapping(value = "/changeDispatch/save")
    R<Boolean> changeDispatchSave(@RequestBody ExchangeDispatch changeDispatch);
    R<Boolean> changeDispatchSave(@RequestBody ChangeDispatch changeDispatch);
    /**
     * 订单改派详情
     *
     * @param id 订单id
     * @return 改派订单
     */
    @GetMapping(value = "/changeDispatch/one")
    R<ChangeDispatch> changeDispatchOne(@RequestParam("id") Integer id);
    /**
     * 系统通知列表
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/GaoDeMapUtil.java
@@ -5,7 +5,11 @@
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.ruoyi.common.core.domain.Result;
import com.ruoyi.common.core.enums.GaoDeEnum;
import com.ruoyi.common.core.exception.GlobalException;
import com.ruoyi.common.core.vo.GaoDeMap;
import com.ruoyi.common.core.vo.Path;
import com.ruoyi.common.core.vo.PolylineData;
import com.ruoyi.common.core.vo.Steps;
import java.io.BufferedReader;
import java.io.IOException;
@@ -13,6 +17,10 @@
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
 * @author HJL
@@ -22,9 +30,7 @@
    /**
     * 功能描述: 高德地图Key
     */
    private static final String GAO_DE_KEY = "3f00f94b6e9f470a5c6f510c3df814ea";
    //申请的账户Key
    private static final String GAO_DE_KEY = "37331f325a4f4ea25bc0d4e1900a1730";
    /**
     * 功能描述: 根据地址名称得到两个地址间的距离
@@ -32,7 +38,6 @@
     * @param start 起始位置
     * @param end   结束位置
     * @return long 两个地址间的距离
     * @author isymikasan
     */
    public static Long getDistanceByAddress(String start, String end) {
        String startLonLat = getLonLat(start).getDatas();
@@ -170,11 +175,28 @@
                json.append(inputLine);
            }
            in.close();
        } catch (IOException ignored) {
        } catch (IOException e) {
            throw new GlobalException("获取路线规划失败!");
        }
        String data = json.toString();
        GaoDeMap gaoDeMap = JSONObject.parseObject(data, GaoDeMap.class);
        return gaoDeMap.getRoute().getPaths().get(0);
        Path path = gaoDeMap.getRoute().getPaths().get(0);
        List<Steps> steps = path.getSteps();
        for (Steps step : steps) {
            // 经纬度地址指向
            List<PolylineData> polylineDataList = new ArrayList<>();
            String polyline = step.getPolyline();
            List<String> list = Arrays.stream(polyline.split(";")).collect(Collectors.toList());
            for (String s : list) {
                String[] split = s.split(",");
                // 经纬度
                String longitude = split[0];
                String latitude = split[1];
                polylineDataList.add(new PolylineData(longitude, latitude));
            }
            step.setPolylineList(polylineDataList);
        }
        return path;
    }
}
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/vo/Steps.java
@@ -29,6 +29,10 @@
    @JsonProperty("toll_road")
    private List<String> tollRoad;
    private String duration;
    /**
     * 路段经纬度:
     * 格式为:经度,纬度;经度,纬度;....
     */
    private String polyline;
    /**
     * 转向
@@ -40,4 +44,6 @@
    @JsonProperty("assistant_action")
    private String assistantAction;
    private List<PolylineData> polylineList;
}
ruoyi-service/ruoyi-admin/pom.xml
@@ -19,6 +19,20 @@
    <dependencies>
        <!-- 腾讯短信sdk -->
        <dependency>
            <groupId>com.tencentcloudapi</groupId>
            <artifactId>tencentcloud-sdk-java</artifactId>
            <version>3.1.270</version>
            <!--排除okio-->
            <exclusions>
                <exclusion>
                    <groupId>com.squareup.okio</groupId>
                    <artifactId>okio</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/ChangeDispatchController.java
@@ -20,10 +20,7 @@
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 java.util.Arrays;
@@ -80,6 +77,17 @@
    /**
     * 订单改派详情
     *
     * @param changeDispatch 订单改派信息
     */
    @ApiOperation(value = "新增订单改派", tags = {"后台-系统设置-订单改派管理"})
    @PostMapping(value = "/save")
    public R<Boolean> save(@RequestBody ChangeDispatch changeDispatch) {
        return R.ok(changeDispatchService.save(changeDispatch));
    }
    /**
     * 订单改派详情
     *
     * @param id 订单改派id
     */
    @RequiresPermissions("reassignment_apply")
@@ -90,6 +98,23 @@
    })
    public R<ChangeDispatch> detail(@RequestParam Integer id) {
        return R.ok(changeDispatchService.getById(id));
    }
    /**
     * 订单改派详情 远程调用
     *
     * @param id 订单id
     */
    @GetMapping(value = "/one")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "订单改派id", name = "id", dataType = "Integer", required = true)
    })
    public R<ChangeDispatch> one(@RequestParam("id") Integer id) {
        ChangeDispatch changeDispatch = changeDispatchService.lambdaQuery()
                .eq(ChangeDispatch::getOrderId, id)
                .eq(ChangeDispatch::getState, Constants.ZERO)
                .one();
        return R.ok(changeDispatch);
    }
    /**
@@ -113,7 +138,7 @@
    /**
     * 订单改派师傅
     *
     * @param orderId  订单id
     * @param changeId 改派订单id
     * @param workerId 师傅id
     */
    @RequiresPermissions("reassignment_apply")
@@ -121,16 +146,16 @@
    @GetMapping(value = "/changeWorker")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "改派订单id", name = "changeId", 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> changeWorker(@RequestParam Integer changeId, @RequestParam Integer orderId, @RequestParam Integer workerId) {
    public R<String> changeWorker(@RequestParam Integer changeId, @RequestParam Integer workerId) {
        ChangeDispatch changeDispatch = changeDispatchService.lambdaQuery().eq(ChangeDispatch::getId, changeId)
                .eq(ChangeDispatch::getIsDelete, 0).one();
        if (null == changeDispatch || Constants.ONE.equals(changeDispatch.getState())) {
            throw new GlobalException("改派申请不存在或已改派!");
        }
        Order order = orderService.lambdaQuery().eq(Order::getId, orderId).eq(Order::getIsDelete, 0).one();
        Order order = orderService.lambdaQuery().eq(Order::getId, changeDispatch.getOrderId())
                .eq(Order::getIsDelete, 0).one();
        if (null == order) {
            throw new GlobalException("订单不存在!");
        }
@@ -144,7 +169,7 @@
        if (null == masterWorker) {
            throw new GlobalException("服务人员信息异常!");
        }
        // 原订单状态改为 6:已改派
        // 原订单状态改为 5:已改派
        order.setState(Constants.FIVE);
        boolean orderUpdate = orderService.updateById(order);
        // 生成新订单信息
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/MasterWorkerController.java
@@ -65,6 +65,7 @@
        wrapper = StringUtils.isNotBlank(phone) ? wrapper.like(MasterWorker::getPhone, phone) : wrapper;
        wrapper = StringUtils.isNotBlank(city) ? wrapper.like(MasterWorker::getCity, city) : wrapper;
        return R.ok(wrapper.eq(MasterWorker::getIsDelete, 0)
                        .eq(MasterWorker::getIsEnable,1)
                .orderByDesc(MasterWorker::getCreateTime).page(Page.of(pageNum, pageSize)));
    }
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/OrderController.java
@@ -3,11 +3,9 @@
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.entity.*;
import com.ruoyi.admin.request.OrderQueryRequest;
import com.ruoyi.admin.service.MasterWorkerService;
import com.ruoyi.admin.service.OrderService;
import com.ruoyi.admin.service.*;
import com.ruoyi.admin.sorcket.WebSocketServer;
import com.ruoyi.admin.vo.OrderCountVO;
import com.ruoyi.admin.vo.OrderDetailVO;
@@ -15,7 +13,6 @@
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;
@@ -25,6 +22,7 @@
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@@ -47,6 +45,15 @@
    private OrderService orderService;
    @Resource
    private MasterWorkerService masterWorkerService;
    @Resource
    private SiteService siteService;
    @Resource
    private RecoveryServeService recoveryServeService;
    @Resource
    private RecoveryServePriceService recoveryServePriceService;
    @Resource
    private ChangeDispatchService changeDispatchService;
    /**
     * 雪花算法类
     */
@@ -109,13 +116,11 @@
    /**
     * 订单列表
     *
     * @param orderQueryRequest 订单列表查询参数
     */
    @ApiOperation(value = "订单列表-各订单数量统计", tags = {"后台-订单管理"})
    @PostMapping(value = "/orderPageCount")
    public R<OrderPageCountVO> orderPageCount(@RequestBody OrderQueryRequest orderQueryRequest) {
        return R.ok(orderService.orderPageCount(orderQueryRequest));
    @GetMapping(value = "/orderPageCount")
    public R<OrderPageCountVO> orderPageCount() {
        return R.ok(orderService.orderPageCount());
    }
    /**
@@ -141,7 +146,39 @@
    @ApiOperation(value = "订单列表-新增订单", tags = {"后台-订单管理"})
    @PostMapping(value = "/save")
    public R<String> save(@RequestBody Order order) {
        // 站点信息
        Site site = siteService.lambdaQuery()
                .eq(Site::getId, order.getSiteId())
                .eq(Site::getIsDelete, 0).one();
        order.setSiteName(site.getSiteName());
        // 回收服务信息
        RecoveryServe recoveryServe = recoveryServeService.lambdaQuery()
                .eq(RecoveryServe::getId, order.getServeId())
                .eq(RecoveryServe::getIsDelete, 0).one();
        order.setServeName(recoveryServe.getServeName());
        // 不同城市会有不同的回收价格
        RecoveryServePrice price = recoveryServePriceService.lambdaQuery()
                .eq(RecoveryServePrice::getRecoveryServeId, recoveryServe.getId())
                .eq(RecoveryServePrice::getIsDelete, 0)
                .eq(RecoveryServePrice::getCity, order.getCity()).one();
        if (null == price) {
            order.setServePrice(recoveryServe.getDefaultPrice());
            order.setOrderMoney(recoveryServe.getDefaultPrice());
        } else {
            order.setServePrice(price.getRecoveryPrice());
            order.setOrderMoney(price.getRecoveryPrice());
        }
        // 师傅信息
        MasterWorker masterWorker = masterWorkerService.lambdaQuery()
                .eq(MasterWorker::getId, order.getServerId())
                .eq(MasterWorker::getIsDelete, 0).one();
        order.setServerName(masterWorker.getRealName());
        order.setServerPhone(masterWorker.getPhone());
        // 后台订单
        order.setType(Constants.ONE);
        // 待派单状态
        order.setState(Constants.ZERO);
        order.setSubsidy(BigDecimal.ZERO);
        order.setOrderNumber(String.valueOf(SNOW_FLAKE_ID_WORKER.nextId()));
        return orderService.save(order) ? R.ok() : R.fail();
    }
@@ -157,10 +194,11 @@
    @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)
            @ApiImplicitParam(value = "服务人员id", name = "workerId", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "改派原因", name = "applyReason", dataType = "String")
    })
    public R<String> reassignment(@RequestParam Integer type, @RequestParam Integer orderId,
                                  @RequestParam Integer workerId) {
                                  @RequestParam Integer workerId, String applyReason) {
        Order order = orderService.lambdaQuery().eq(Order::getId, orderId).eq(Order::getIsDelete, 0).one();
        MasterWorker masterWorker = masterWorkerService.lambdaQuery()
                .eq(MasterWorker::getId, workerId)
@@ -172,19 +210,26 @@
            order.setServerName(masterWorker.getRealName());
            order.setServerPhone(masterWorker.getPhone());
            order.setAcceptTime(new Date());
            order.setState(Constants.ONE);
            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);
            order.setServeId(workerId);
            order.setServerName(masterWorker.getRealName());
            order.setServerPhone(masterWorker.getPhone());
            result = orderService.updateById(order);
            // 生成改派信息
            ChangeDispatch changeDispatch = new ChangeDispatch();
            changeDispatch.setWorkerId(order.getServerId());
            changeDispatch.setWorkerName(order.getServerName());
            changeDispatch.setApplyReason(applyReason);
            changeDispatch.setApplyTime(new Date());
            changeDispatch.setState(Constants.ONE);
            changeDispatch.setOrderId(String.valueOf(order.getId()));
            changeDispatch.setOrderNumber(order.getOrderNumber());
            changeDispatch.setUserId(String.valueOf(order.getUserId()));
            changeDispatch.setUserName(order.getReservationName());
            changeDispatch.setIsDelete(Constants.ZERO);
            changeDispatchService.save(changeDispatch);
        }
        try {
            WebSocketServer.sendInfo("您有一条新的订单,请注意查收!", String.valueOf(workerId));
@@ -214,12 +259,12 @@
    /**
     * 订单列表-excel导出
     *
     * @param idList 订单id
     * @param orderQueryRequest 筛选参数
     */
    @ApiOperation(value = "订单列表-excel导出", tags = {"后台-订单管理"})
    @PostMapping(value = "/excelExport")
    public R<String> excelExport(@RequestBody List<String> idList, HttpServletResponse response) {
        return orderService.excelExport(idList, response);
    public R<String> excelExport(@RequestBody OrderQueryRequest orderQueryRequest, HttpServletResponse response) {
        return orderService.excelExport(orderQueryRequest, response);
    }
    /**
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/entity/ChangeDispatch.java
@@ -35,7 +35,7 @@
    @ApiModelProperty("申请师傅姓名")
    @TableField("worker_name")
    private Integer workerName;
    private String workerName;
    @ApiModelProperty("申请原因")
    @TableField("apply_reason")
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/entity/Order.java
@@ -4,11 +4,13 @@
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.core.domain.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.util.Date;
@@ -80,6 +82,8 @@
    @ApiModelProperty("上门时间")
    @TableField("time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date time;
    @ApiModelProperty("接单时间(师傅接单或后台派单,更新该字段时间)")
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/mapper/OrderMapper.java
@@ -119,8 +119,23 @@
    /**
     * 订单管理分页模块,订单数量统计
     *
     * @param orderQueryRequest 请求参数
     * @return 统计数量
     */
    List<Order> orderPageCount(@Param("data") OrderQueryRequest orderQueryRequest);
    List<Order> orderPageCount();
    /**
     * 根据所选id查询
     *
     * @param ids id集合
     * @return 返回列表
     */
    List<Order> exportByIdList(List<String> ids);
    /**
     * 根据筛选条件查询
     *
     * @param orderQueryRequest 筛选条件
     * @return 返回列表
     */
    List<Order> exportList(@Param("data") OrderQueryRequest orderQueryRequest);
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/request/OrderQueryRequest.java
@@ -4,6 +4,8 @@
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
 * @author HJL
 * @version 1.0
@@ -25,7 +27,7 @@
    @ApiModelProperty("预约手机号")
    private String reservationPhone;
    @ApiModelProperty("订单状态((0:待派单;1:待接单;2:待上门;3:待完工;4:已完结;5:已取消))")
    @ApiModelProperty("订单状态(0:待派单;1:待上门;2:待完工;3:已完结;4:已取消;5:已改派)")
    private Integer state;
    @ApiModelProperty("师傅名称")
@@ -55,4 +57,8 @@
    @ApiModelProperty(value = "每页显示条数", required = true)
    private Integer pageSize = 10;
    @ApiModelProperty("导出ids集合")
    private List<String> ids;
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/OrderService.java
@@ -63,11 +63,11 @@
    /**
     * excel模板导出
     *
     * @param idList   订单记录id
     * @param orderQueryRequest   筛选参数
     * @param response 响应体
     * @return 导出结果
     */
    R<String> excelExport(List<String> idList, HttpServletResponse response);
    R<String> excelExport(OrderQueryRequest orderQueryRequest, HttpServletResponse response);
    /**
     * 订单列表
@@ -98,8 +98,7 @@
    /**
     * 订单管理分页模块,订单数量统计
     *
     * @param orderQueryRequest 请求参数
     * @return 统计数量
     */
    OrderPageCountVO orderPageCount(OrderQueryRequest orderQueryRequest);
    OrderPageCountVO orderPageCount();
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/impl/AgreementServiceImpl.java
@@ -32,7 +32,7 @@
    @Transactional(rollbackFor = Exception.class)
    public R<String> saveData(Agreement agreement) {
        Integer type = agreement.getContentType();
        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:司机操作指导)");
        }
        Agreement dbDate = lambdaQuery().eq(Agreement::getContentType, type).one();
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/impl/OrderServiceImpl.java
@@ -58,6 +58,8 @@
    private ServeCoordinateService serveCoordinateService;
    @Resource
    private EvaluateService evaluateService;
    @Resource
    private ChangeDispatchService changeDispatchService;
    @Override
    public OrderResultVO orderCountHome(OrderCountRequest orderCount) {
@@ -108,7 +110,7 @@
    }
    @Override
    public R<String> excelExport(List<String> idList, HttpServletResponse response) {
    public R<String> excelExport(OrderQueryRequest orderQueryRequest, HttpServletResponse response) {
        try {
            response.setCharacterEncoding(Constants.UTF8);
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
@@ -118,7 +120,13 @@
            return R.fail("excel导出失败!");
        }
        try {
            List<Order> list = lambdaQuery().in(Order::getId, idList).eq(Order::getIsDelete, 0).list();
            List<String> ids = orderQueryRequest.getIds();
            List<Order> list;
            if (null != ids && !ids.isEmpty()) {
                list = baseMapper.exportByIdList(ids);
            } else {
                list = baseMapper.exportList(orderQueryRequest);
            }
            // excel模板封装
            ExcelWriterBuilder excelWriterBuilder = EasyExcelFactory.write(response.getOutputStream());
            InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("template/" + Constants.EXCEL_ORDER_FILE_NAME + ".xlsx");
@@ -140,7 +148,18 @@
    public IPage<Order> queryPage(OrderQueryRequest orderQueryRequest) {
        Page<Order> page = Page.of(orderQueryRequest.getPageNum(), orderQueryRequest.getPageSize());
        // 基础查询
        return baseMapper.queryPage(orderQueryRequest, page);
        IPage<Order> pageList = baseMapper.queryPage(orderQueryRequest, page);
        for (Order order : pageList.getRecords()) {
            ChangeDispatch changeDispatch = changeDispatchService.lambdaQuery()
                    .eq(ChangeDispatch::getOrderId, order.getId())
                    .eq(ChangeDispatch::getIsDelete, 0)
                    .orderByDesc(ChangeDispatch::getCreateTime)
                    .last("limit 1").one();
            if (null != changeDispatch) {
                order.setApplyReason(changeDispatch.getApplyReason());
            }
        }
        return pageList;
    }
    @Override
@@ -165,18 +184,17 @@
        Evaluate evaluate = evaluateService.lambdaQuery().eq(Evaluate::getOrderId, order.getId())
                .eq(Evaluate::getIsDelete, 0).one();
        OrderByEvaluateVO orderByEvaluate = new OrderByEvaluateVO();
        orderByEvaluate.setStarRating(evaluate.getStarRating());
        orderByEvaluate.setEvaluateTime(evaluate.getCreateTime());
        orderByEvaluate.setEvaluateContent(evaluate.getContent());
        if (null != evaluate) {
            orderByEvaluate.setStarRating(evaluate.getStarRating());
            orderByEvaluate.setEvaluateTime(evaluate.getCreateTime());
            orderByEvaluate.setEvaluateContent(evaluate.getContent());
        }
        result.setEvaluateInfo(orderByEvaluate);
    }
    private void serveRecordInfo(OrderDetailVO result, Order order) {
        ServeRecord serveRecord = serveRecordService.lambdaQuery().eq(ServeRecord::getOrderId, order.getId())
                .eq(ServeRecord::getIsDelete, 0).one();
        if (null == serveRecord) {
            throw new GlobalException("服务记录信息异常,请重试");
        }
        // 师傅路线轨迹
        List<ServeCoordinate> serveCoordinateList = serveCoordinateService.lambdaQuery().eq(ServeCoordinate::getWorkerId, order.getServerId())
                .eq(ServeCoordinate::getIsDelete, 0).orderByDesc(ServeCoordinate::getCreateTime).list();
@@ -184,7 +202,9 @@
        orderByServeRecord.setAcceptOrderTime(order.getAcceptTime());
        orderByServeRecord.setReachTime(order.getTime());
        orderByServeRecord.setCoordinate(serveCoordinateList.stream().map(ServeCoordinate::getCoordinate).collect(Collectors.toList()));
        orderByServeRecord.setPhoto(Arrays.stream(serveRecord.getPhoto().split(",")).collect(Collectors.toList()));
        if (null != serveRecord) {
            orderByServeRecord.setPhoto(Arrays.stream(serveRecord.getPhoto().split(",")).collect(Collectors.toList()));
        }
        result.setServeRecordInfo(orderByServeRecord);
    }
@@ -233,12 +253,11 @@
    private void userInfo(OrderDetailVO result, Order order) {
        Integer userId = order.getUserId();
        User user = userMapper.selectById(userId);
        if (null == user) {
            throw new GlobalException("预约人信息异常,请重试");
        }
        OrderByUserInfoVO orderByUserInfo = new OrderByUserInfoVO();
        orderByUserInfo.setProfilePicture(user.getProfilePicture());
        orderByUserInfo.setUserNumber(user.getUserNo());
        if (null != user) {
            orderByUserInfo.setProfilePicture(user.getProfilePicture());
            orderByUserInfo.setUserNumber(user.getUserNo());
        }
        orderByUserInfo.setReservationName(order.getReservationName());
        orderByUserInfo.setReservationPhone(order.getReservationPhone());
        orderByUserInfo.setReservationAddress(order.getReservationAddress());
@@ -252,8 +271,8 @@
    }
    @Override
    public OrderPageCountVO orderPageCount(OrderQueryRequest orderQueryRequest) {
        List<Order> orderList = baseMapper.orderPageCount(orderQueryRequest);
    public OrderPageCountVO orderPageCount() {
        List<Order> orderList = baseMapper.orderPageCount();
        int total = 0;
        int toBeDispatched = 0;
        int stayDoorstep = 0;
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/impl/SendSmsServiceImpl.java
@@ -2,6 +2,7 @@
import cn.hutool.core.util.RandomUtil;
import com.ruoyi.admin.service.SendSmsService;
import com.ruoyi.admin.utils.SendSmsUtil;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.constant.RedisConstants;
import com.ruoyi.common.core.exception.GlobalException;
@@ -21,23 +22,28 @@
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private SendSmsUtil sendSmsUtil;
    @Override
    public String workerSettleSms(String phone) {
        return sendPhoneCode(phone, RedisConstants.WORKER_SETTLE_KEY, Constants.FIVE, TimeUnit.MINUTES);
        return sendPhoneCode(phone, RedisConstants.WORKER_SETTLE_KEY,
                sendSmsUtil.applyId);
    }
    @Override
    public String workerLoginSms(String phone) {
        return sendPhoneCode(phone, RedisConstants.WORKER_APPLY_KEY, Constants.FIVE, TimeUnit.MINUTES);
        return sendPhoneCode(phone, RedisConstants.WORKER_APPLY_KEY,
                sendSmsUtil.loginId);
    }
    @Override
    public String userLoginSms(String phone) {
        return sendPhoneCode(phone, RedisConstants.USER_LOGIN_PHONE_CODE, Constants.FIVE, TimeUnit.MINUTES);
        return sendPhoneCode(phone, RedisConstants.USER_LOGIN_PHONE_CODE,
                sendSmsUtil.loginId);
    }
    private String sendPhoneCode(String phone, String redisKey, Integer timeout, TimeUnit timeUnit) {
    private String sendPhoneCode(String phone, String redisKey, String templateId) {
        // 生成随机 6位数字 验证码
        String phoneCode = RandomUtil.randomNumbers(6);
        // 判断redis中是否存在手机验证码
@@ -60,10 +66,13 @@
         * key为 --> phone_code:手机号码 (phone_code表示该业务为 验证码登录)
         * value为 --> 随机验证码:时间戳 (时间戳用于计算是否超过1分钟的重发时间)
         */
        redisTemplate.opsForValue().set(redisKey + phone, phoneCode + ":" + System.currentTimeMillis(), timeout, timeUnit);
        redisTemplate.opsForValue().set(redisKey + phone, phoneCode + ":" + System.currentTimeMillis(),
                Constants.FIVE, TimeUnit.MINUTES);
        String sendMessage = "验证码发送成功,您的验证码为:" + phoneCode + ",该验证码三分钟内有效,请及时完成登陆";
        // todo 发送此消息
        System.out.println(sendMessage);
        String[] param = {phoneCode};
        // 发送验证码
        sendSmsUtil.sendSms(new SendSmsUtil.SendSmsRequest(phone, templateId, param));
        return phoneCode;
    }
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/sorcket/WebSocketServer.java
@@ -75,7 +75,7 @@
            //从set中删除
            subOnlineCount();
        }
        log.info("用户退出:" + userId + ",当前在线人数为:" + getOnlineCount());
        log.info("用户退出: " + userId + ",当前在线人数为: " + getOnlineCount());
    }
    /**
@@ -125,6 +125,7 @@
            WEB_SOCKET_MAP.get(workerId).getSession().getBasicRemote().sendText(message);
        } else {
            log.error("用户" + workerId + ",不在线!");
            throw new IOException("用户" + workerId + ",不在线!");
        }
    }
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/utils/GeneratorCodeConfig.java
@@ -36,7 +36,7 @@
    public static void main(String[] args) {
        // 数据库连接url
        String dbUrl = "jdbc:mysql://localhost:3306/secondary_recovery";
        String dbUrl = "jdbc:mysql://localhost:3306/old_data";
        // 数据库用户名
        String dbUsername = "root";
        // 数据库密码
@@ -61,7 +61,7 @@
                // 包配置
                .packageConfig(builder -> builder
                                // 父包名
                                .parent("com.rouyi.admin")
                                .parent("com.rouyi.user")
                                // 父包模块名 注释即为无
//                         .moduleName(scanner("模块名"))
                                // Entity 包名
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/vo/OrderByEvaluateVO.java
@@ -1,5 +1,6 @@
package com.ruoyi.admin.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -20,6 +21,7 @@
    private BigDecimal starRating;
    @ApiModelProperty("评价时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date evaluateTime;
    @ApiModelProperty("评价内容")
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/vo/OrderByServeRecordVO.java
@@ -1,5 +1,6 @@
package com.ruoyi.admin.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -17,9 +18,11 @@
public class OrderByServeRecordVO {
    @ApiModelProperty("接单时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date acceptOrderTime;
    @ApiModelProperty("到达时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date reachTime;
    @ApiModelProperty("路线经纬度集合")
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/vo/OrderByUserInfoVO.java
@@ -1,5 +1,6 @@
package com.ruoyi.admin.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -31,6 +32,7 @@
    private String reservationAddress;
    @ApiModelProperty("预约上门时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date time;
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/vo/OrderInfoVO.java
@@ -1,5 +1,6 @@
package com.ruoyi.admin.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -19,6 +20,7 @@
    private String orderNumber;
    @ApiModelProperty("下单时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date placeOrderTime;
    @ApiModelProperty("订单状态(0:待派单;1:待上门;2:待完工;3:已完结;4:已取消;5:已改派)")
ruoyi-service/ruoyi-admin/src/main/resources/mapper/admin/OrderMapper.xml
@@ -5,6 +5,8 @@
    <resultMap id="BaseResultMap" type="com.ruoyi.admin.entity.Order">
        <id column="id" property="id"/>
        <result column="site_id" property="siteId"/>
        <result column="order_number" property="orderNumber"/>
        <result column="order_money" property="orderMoney"/>
        <result column="site_name" property="siteName"/>
        <result column="serve_id" property="serveId"/>
        <result column="serve_name" property="serveName"/>
@@ -14,6 +16,7 @@
        <result column="time" property="time"/>
        <result column="server_id" property="serverId"/>
        <result column="server_name" property="serverName"/>
        <result column="server_phone" property="serverPhone"/>
        <result column="reservation_remark" property="reservationRemark"/>
        <result column="state" property="state"/>
        <result column="createBy" property="createBy"/>
@@ -196,12 +199,10 @@
    </select>
    <select id="queryPage" resultMap="BaseResultMap">
        select o.*, c.apply_reason
        select *
        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>
@@ -242,12 +243,41 @@
    </select>
    <select id="orderPageCount" resultMap="BaseResultMap">
        select o.*, c.apply_reason
        select o.*
        from t_order o
        left join sys_change_dispatch c on o.id = c.order_id
        where o.is_delete = 0
    </select>
    <select id="exportByIdList" resultMap="BaseResultMap">
        select reservation_name,
               reservation_phone,
               reservation_address,
               time,
               serve_name,
               server_name,
               server_phone
        from t_order
        <where>
            id in
            <foreach collection="list" item="id" open="(" separator="," close=")">
                #{id}
            </foreach>
        </where>
    </select>
    <select id="exportList" resultMap="BaseResultMap">
        select o.reservation_name,
               o.reservation_phone,
               o.reservation_address,
               o.time,
               o.serve_name,
               o.server_name,
               o.server_phone
        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)
              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>
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/controller/OrderController.java
@@ -1,7 +1,7 @@
package com.ruoyi.worker.controller;
import com.ruoyi.admin.api.entity.ExchangeDispatch;
import com.ruoyi.admin.api.entity.ChangeDispatch;
import com.ruoyi.admin.api.feignClient.AdminClient;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.domain.R;
@@ -89,24 +89,28 @@
        if (null == loginWorker) {
            return R.loginExpire("登录失效!");
        }
        ChangeDispatch data = adminClient.changeDispatchOne(orderId).getData();
        if (null != data) {
            return R.fail("当前订单已提交改派申请!");
        }
        MasterWorker masterWorker = masterWorkerService.getById(loginWorker.getUserid());
        // 订单改派信息
        ExchangeDispatch exchangeDispatch = new ExchangeDispatch();
        exchangeDispatch.setWorkerId(masterWorker.getId());
        exchangeDispatch.setWorkerName(masterWorker.getRealName());
        exchangeDispatch.setApplyReason(reason);
        exchangeDispatch.setApplyTime(DateUtils.getNowDate());
        exchangeDispatch.setState(0);
        ChangeDispatch changeDispatch = new ChangeDispatch();
        changeDispatch.setWorkerId(masterWorker.getId());
        changeDispatch.setWorkerName(masterWorker.getRealName());
        changeDispatch.setApplyReason(reason);
        changeDispatch.setApplyTime(DateUtils.getNowDate());
        changeDispatch.setState(0);
        Order order = orderService.lambdaQuery().eq(Order::getId, orderId).eq(Order::getIsDelete, 0).one();
        if (null == order) {
            throw new GlobalException("订单信息异常!");
        }
        exchangeDispatch.setOrderId(orderId);
        exchangeDispatch.setOrderNumber(order.getOrderNumber());
        exchangeDispatch.setUserId(order.getUserId());
        exchangeDispatch.setUserName(order.getReservationName());
        changeDispatch.setOrderId(orderId);
        changeDispatch.setOrderNumber(order.getOrderNumber());
        changeDispatch.setUserId(order.getUserId());
        changeDispatch.setUserName(order.getReservationName());
        // 添加改派信息
        Boolean save = adminClient.changeDispatchSave(exchangeDispatch).getData();
        Boolean save = adminClient.changeDispatchSave(changeDispatch).getData();
        return save ? R.ok() : R.fail();
    }
@@ -128,7 +132,8 @@
        if (null == loginWorker) {
            return R.loginExpire("登录失效!");
        }
        Order order = orderService.lambdaQuery().eq(Order::getId, orderId).eq(Order::getServerId, loginWorker.getUserid())
        Order order = orderService.lambdaQuery().eq(Order::getId, orderId)
                .eq(Order::getServerId, loginWorker.getUserid())
                .eq(Order::getIsDelete, 0).one();
        if (null == order) {
            throw new GlobalException("请确认当前订单所派单师傅是否是您!");
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/controller/OssController.java
@@ -47,7 +47,7 @@
    }
    @PostMapping("/uploadPhoto")
    @ApiOperation(value = "师傅端-上传完工照片", tags = "公共-文件上传")
    @ApiOperation(value = "师傅端-上传完工照片", tags = "师傅端-文件上传")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "照片", name = "file", dataType = "MultipartFile", required = true),
            @ApiImplicitParam(value = "订单id", name = "orderId", dataType = "Integer", required = true),
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/service/impl/MasterWorkerServiceImpl.java
@@ -45,10 +45,10 @@
    @Override
    public List<OrderListVO> orderNotHandle(Integer userid, String longitude, String latitude) {
        List<Order> orderList = orderService.lambdaQuery().eq(Order::getServerId, 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<OrderNotHandleVO> list = new ArrayList<>();
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/service/impl/OrderServiceImpl.java
@@ -36,11 +36,11 @@
        } else {
            wrapper.in(Order::getState, 1, 2, 3, 4, 5);
        }
        return wrapper.list();
        return wrapper.eq(Order::getServerId, userid).list();
    }
    @Override
    public Object orderNavigation(String userPosition, String workerPosition) {
        return GaoDeMapUtil.routing(userPosition, workerPosition);
        return GaoDeMapUtil.routing(workerPosition, userPosition);
    }
}
ruoyi-service/ruoyi-worker/src/main/resources/mapper/worker/MasterWorkerMapper.xml
@@ -26,9 +26,9 @@
    </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
        SELECT COALESCE(SUM(CASE WHEN o.state IN (1, 2, 3) THEN 1 ELSE 0 END), 0) AS total,
               COALESCE(SUM(CASE WHEN o.state = 1 THEN 1 ELSE 0 END), 0)          AS waitVisit,
               COALESCE(SUM(CASE WHEN o.state = 3 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}