8.9
luodangjia
2024-09-03 2855ae89d2ab6268e1edc42c3e9d7e73c8e7259e
8.9
28个文件已修改
15个文件已添加
1307 ■■■■■ 已修改文件
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/entity/OrderQueryRequest.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/entity/OrderQueryVO.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-auth/src/main/resources/bootstrap.yml 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-gateway/src/main/resources/bootstrap.yml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/resources/bootstrap.yml 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/libs/java-sdk-core-3.2.5.jar 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/pom.xml 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/config/MyDateObjectHandler.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/HomePageController.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/OrderController.java 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/RegionController.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/entity/AppVersion.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/mapper/AppMapper.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/impl/OrderServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/impl/SendSmsServiceImpl.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/utils/ALiSendSms.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/utils/Constant.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/utils/DescribeInstances.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/utils/HostName.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/utils/SSLCipherSuiteUtil.java 209 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/utils/UnsupportProtocolException.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/vo/OrderInfoVO.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/vo/OrderReasinDto.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/vo/PageDto.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/vo/ReassinDto.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/resources/bootstrap.yaml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-admin/src/main/resources/template/订单记录.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/ChangeDispatchController.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/OrderController.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/OrderQueryRequest.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/OrderQueryVO.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/resources/bootstrap.yaml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/resources/mapper/order/OrderMapper.xml 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-user/src/main/resources/bootstrap.yaml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-worker/pom.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/controller/MasterWorkerController.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/controller/OssController.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/entity/AppVersion.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/entity/MultipartFileDto.java 189 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/mapper/AppMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/utils/FileImageWatermarkUtils.java 276 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-worker/src/main/resources/bootstrap.yaml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/entity/OrderQueryRequest.java
@@ -54,6 +54,7 @@
    @ApiModelProperty("站点名称")
    private String serveName;
    private String address;
    @ApiModelProperty(value = "页码", required = true)
    private Integer pageNum = 1;
@@ -61,6 +62,7 @@
    @ApiModelProperty(value = "订单类型0:正常订单,1:后台订单")
    private Integer type ;
    private Integer fake ;
    @ApiModelProperty(value = "每页显示条数", required = true)
    private Integer pageSize = 10;
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/entity/OrderQueryVO.java
@@ -23,5 +23,8 @@
    @ApiModelProperty("订单数量")
    private Integer number;
    private Integer fakeNumber;
    private Integer fakeCount;
}
ruoyi-auth/src/main/resources/bootstrap.yml
@@ -23,16 +23,20 @@
        group: DEFAULT_GROUP
        namespace: 5b0cc96f-d058-4986-a46f-64644ff8a467
        # 线上nacos需要鉴权
#        username: nacos
#        password: jdhs_nacos!
        username: nacos
        password: jdhs_nacos!
        password: nacos
      config:
        # 配置中心地址
        server-addr: localhost:8848
        group: DEFAULT_GROUP
        namespace: 5b0cc96f-d058-4986-a46f-64644ff8a467
        # 线上nacos需要鉴权
#        username: nacos
#        password: jdhs_nacos!
        username: nacos
        password: jdhs_nacos!
        password: nacos
        name: ${spring.application.name}
        # 配置文件格式
        file-extension: yml
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java
@@ -265,7 +265,7 @@
    /**
     * 数字 3000
     */
    public static final Integer THREE_THOUSAND = 3000;
    public static final Integer THREE_THOUSAND = 2000;
    /**
     * 师傅端默认用户ID前缀
@@ -300,6 +300,6 @@
    /**
     * 手机号码正则
     */
    public static final String PHONE = "^1[345789]\\d{9}$";
    public static final String PHONE = "^1[3456789]\\d{9}$";
}
ruoyi-gateway/src/main/resources/bootstrap.yml
@@ -19,6 +19,8 @@
        group: DEFAULT_GROUP
        namespace: 5b0cc96f-d058-4986-a46f-64644ff8a467
        # 线上nacos需要鉴权
        username: nacos
        password: nacos
#        username: nacos
#        password: jdhs_nacos!
      config:
@@ -28,6 +30,8 @@
        namespace: 5b0cc96f-d058-4986-a46f-64644ff8a467
        name: ${spring.application.name}
        # 线上nacos需要鉴权
        username: nacos
        password: nacos
#        username: nacos
#        password: jdhs_nacos!
        # 配置文件格式
ruoyi-modules/ruoyi-system/src/main/resources/bootstrap.yml
@@ -23,16 +23,20 @@
        group: DEFAULT_GROUP
        namespace: 5b0cc96f-d058-4986-a46f-64644ff8a467
        # 线上nacos需要鉴权
#        username: nacos
#        password: jdhs_nacos!
        username: nacos
        password: jdhs_nacos!
        password: nacos
      config:
        # 配置中心地址
        server-addr: 127.0.0.1:8848
        group: DEFAULT_GROUP
        namespace: 5b0cc96f-d058-4986-a46f-64644ff8a467
        # 线上nacos需要鉴权
#        username: nacos
#        password: jdhs_nacos!
        username: nacos
        password: jdhs_nacos!
        password: nacos
        name: ${spring.application.name}
        # 配置文件格式
        file-extension: yml
ruoyi-service/ruoyi-admin/libs/java-sdk-core-3.2.5.jar
Binary files differ
ruoyi-service/ruoyi-admin/pom.xml
@@ -18,6 +18,19 @@
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.openeuler</groupId>
            <artifactId>bgmprovider</artifactId>
            <version>1.0.4</version>
            <exclusions>
                <exclusion>
                    <groupId>org.bouncycastle</groupId>
                    <artifactId>bcprov-jdk15on</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
<!--        <dependency>-->
<!--            <groupId>com.tencentcloudapi</groupId>-->
<!--            <artifactId>tencentcloud-sdk-java</artifactId>-->
@@ -48,7 +61,11 @@
<!--            <groupId>org.springframework.boot</groupId>-->
<!--            <artifactId>spring-boot-starter-websocket</artifactId>-->
<!--        </dependency>-->
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>4.4.3</version>
        </dependency>
        <dependency>
            <groupId>com.github.wechatpay-apiv3</groupId>
            <artifactId>wechatpay-apache-httpclient</artifactId>
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/config/MyDateObjectHandler.java
@@ -30,8 +30,8 @@
        // 更新时间
        this.setFieldValByName("updateTime", new Date(), metaObject);
        // 创建人
        this.setFieldValByName("createBy", "", metaObject);
        this.setFieldValByName("updateBy", "", metaObject);
//        this.setFieldValByName("createBy", "", metaObject);
//        this.setFieldValByName("updateBy", "", metaObject);
        // 是否软删除
        this.setFieldValByName("isDelete", 0, metaObject);
        // 是否启用 默认启用
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/HomePageController.java
@@ -140,6 +140,10 @@
//                cityList.addAll(loginUser.getCityList());
            }
        }
        List<MasterWorkerRankVO> masterWorkerRankVOS = masterWorkerService.workerRanking(cityList);
        if (masterWorkerRankVOS.size()>10){
            return R.ok(masterWorkerRankVOS.subList(0,10));
        }
        return R.ok(masterWorkerService.workerRanking(cityList));
    }
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/OrderController.java
@@ -12,6 +12,8 @@
import com.ruoyi.admin.utils.OcrBase;
import com.ruoyi.admin.vo.OrderByServeRecordVO;
import com.ruoyi.admin.vo.OrderDetailVO;
import com.ruoyi.admin.vo.OrderReasinDto;
import com.ruoyi.admin.vo.ReassinDto;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.core.domain.R;
@@ -52,6 +54,7 @@
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -119,7 +122,13 @@
    })
    public R<OrderDetailVO> orderDetail(@RequestParam String id) {
        // 独立orderService
        return R.ok(orderService.orderListDetail(id));
        OrderDetailVO orderDetailVO = orderService.orderListDetail(id);
        if (orderDetailVO.getServeRecordInfo().getPhoto()!=null&&!orderDetailVO.getServeRecordInfo().getPhoto().isEmpty()){
            if (orderDetailVO.getServeRecordInfo().getPhoto().get(0).equals("")){
                orderDetailVO.getServeRecordInfo().setPhoto(null);
            }
        }
        return R.ok(orderDetailVO);
    }
    @Resource
    private RecoveryClassifyService recoveryClassifyService;
@@ -239,6 +248,7 @@
                    .eq(MasterWorker::getIsDelete, 0).one();
            order.setServerName(masterWorker.getRealName());
            order.setServerPhone(masterWorker.getPhone());
            order.setAcceptTime(new Date());
            // 待上门
            order.setState(Constants.ONE);
        } else {
@@ -334,7 +344,7 @@
     */
    @RequiresPermissions("order_reassignment")
    @ApiOperation(value = "订单列表-订单派单/改派", tags = {"后台-订单管理"})
    @GetMapping(value = "/reassignment")
    @PostMapping(value = "/reassignment")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "操作类型(1:订单派单;2:订单改派)", name = "type", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "订单id", name = "orderId", dataType = "Integer", required = true),
@@ -342,44 +352,43 @@
            @ApiImplicitParam(value = "改派原因", name = "applyReason", dataType = "String")
    })
    @Transactional(rollbackFor = Exception.class)
    public R<String> reassignment(@RequestParam Integer type, @RequestParam String orderIds,
                                  @RequestParam Integer workerId, String applyReason) {
        String[] split = orderIds.split(",");
        for (String orderId : split) {
    public R<String> reassignment(@RequestBody OrderReasinDto orderReasinDto) {
//        String[] split = orderIds.split(",");
        for (ReassinDto orderId : orderReasinDto.getReassinDtos()) {
        MasterWorker masterWorker = masterWorkerService.lambdaQuery()
                .eq(MasterWorker::getId, workerId)
                .eq(MasterWorker::getId, orderReasinDto.getWorkerId())
                .eq(MasterWorker::getIsDelete, 0).one();
        Order item = orderClient.detail(orderId).getData();
        Order order = orderClient.exchangeOrder(type, orderId, workerId,
        Order item = orderClient.detail(orderId.getOrderId()).getData();
        Order order = orderClient.exchangeOrder(orderId.getType(), orderId.getOrderId(), orderReasinDto.getWorkerId(),
                masterWorker.getRealName(), masterWorker.getPhone()).getData();
        // 订单派单
        boolean result = true;
        if (Constants.TWO.equals(type)) {
        if (Constants.TWO.equals(orderId.getType())) {
            if (order.getState().equals(Constants.SIX) || order.getState().equals(Constants.THREE)) {
                orderClient.updateState(order.getId(), Constants.ONE);
            }
            // 订单状态为 待完工时,需要更改状态 待上门且清空师傅到达预约点时间
            if (order.getState().equals(Constants.TWO)) {
                orderClient.updateStateAndArrivalTime(orderId, Constants.ONE);
                orderClient.updateStateAndArrivalTime(orderId.getOrderId(), Constants.ONE);
            }
            // 生成改派信息
            ChangeDispatch changeDispatch = new ChangeDispatch();
            changeDispatch.setWorkerId(item.getServerId());
            changeDispatch.setWorkerName(item.getServerName());
            changeDispatch.setApplyReason(applyReason);
            changeDispatch.setApplyTime(new Date());
            changeDispatch.setState(Constants.ONE);
            changeDispatch.setOrderId(orderId);
            changeDispatch.setOrderNumber(item.getOrderNumber());
            if (null != item.getUserId()) {
                changeDispatch.setUserId(item.getUserId());
            }
            changeDispatch.setUserName(item.getReservationName());
            changeDispatch.setIsDelete(Constants.ZERO);
            result = dispatchClient.saveRecord(changeDispatch).getData();
//            ChangeDispatch changeDispatch = new ChangeDispatch();
//            changeDispatch.setWorkerId(item.getServerId());
//            changeDispatch.setWorkerName(item.getServerName());
//            changeDispatch.setApplyReason(orderReasinDto.getApplyReason());
//            changeDispatch.setApplyTime(new Date());
//            changeDispatch.setState(Constants.ONE);
//            changeDispatch.setOrderId(orderId.getOrderId());
//            changeDispatch.setOrderNumber(item.getOrderNumber());
//            if (null != item.getUserId()) {
//                changeDispatch.setUserId(item.getUserId());
//            }
//            changeDispatch.setUserName(item.getReservationName());
//            changeDispatch.setIsDelete(Constants.ZERO);
//            result = dispatchClient.saveRecord(changeDispatch).getData();
        }
        ChannelHandlerContext context = NettyChannelMap.getData(String.valueOf(workerId));
        ChannelHandlerContext context = NettyChannelMap.getData(String.valueOf(orderReasinDto.getWorkerId()));
        if (null != context) {
            NettyWebSocketController.sendMsgToClient(context, "您有一条新的订单,请注意查收!");
        }
@@ -419,6 +428,14 @@
    @ApiOperation(value = "订单列表-excel导出", tags = {"后台-订单管理"})
    @PostMapping(value = "/excelExport")
    public R<String> excelExport(@RequestBody OrderQueryRequest orderQueryRequest, HttpServletResponse response) {
        List<Integer> servIds = new ArrayList<>();
        if (orderQueryRequest.getClassNameId()!=null){
            List<Integer> classIds = recoveryClassifyService.lambdaQuery().eq(RecoveryClassify::getId, orderQueryRequest.getClassNameId()).list().stream().map(RecoveryClassify::getId).collect(Collectors.toList());
            servIds = recoveryServeService.lambdaQuery().eq(BaseEntity::getIsDelete,0).in(RecoveryServe::getClassifyId, classIds).list().stream().map(RecoveryServe::getId).collect(Collectors.toList());
        }
        orderQueryRequest.setServIds(servIds);
        R<List<Order>> result = orderClient.excelExport(orderQueryRequest);
        // 独立orderService
        return orderService.excelExport(result.getData(), response);
@@ -440,6 +457,10 @@
    @PostMapping (value = "/ocr")
    public R<JSONObject> ocr(String ocrAddress) {
        return R.ok(DescribeInstances.ocr(ocrAddress));
    }
    public static void main(String[] args) {
        System.out.println(LocalDateTime.now().plusMonths(1));
    }
    /**
@@ -531,7 +552,7 @@
    private RedisService redisService;
    @ApiOperation(value = "地图统计", tags = {"后台-订单管理-地图统计"})
    @PostMapping(value = "/map/works")
    public R<List<MasterWorker>> map(String cityCode) {
    public R<List<MasterWorker>> map(String cityCode,String name) {
        LoginUser loginUser = tokenService.getLoginUser();
        if (null == loginUser) {
@@ -548,7 +569,7 @@
        if (workIds==null||workIds.isEmpty()){
            return R.ok(new ArrayList<>());
        }
        List<MasterWorker> list = masterWorkerService.lambdaQuery().in(MasterWorker::getId, workIds).list();
        List<MasterWorker> list = masterWorkerService.lambdaQuery().in(MasterWorker::getId, workIds).eq(name!=null&&name!="",MasterWorker::getRealName,name).eq(cityCode!=null&&cityCode!="", MasterWorker::getCityCode,cityCode).list();
        for (MasterWorker masterWorker : list) {
            masterWorker.setLacation(redisService.getCacheObject("work:"+masterWorker.getId()+":"));
        }
@@ -564,14 +585,14 @@
        for (Order datum : workday.getData()) {
            OrderByServeRecordVO orderByServeRecord = new OrderByServeRecordVO();
//            String masterFolderPath = "/usr/local/coordinate/" + datum.getServerId();
//            File masterFolder = new File(masterFolderPath);
            // 检查师傅ID的文件夹是否存在,存在就读取轨迹数据
//            System.out.println("文件是否存在:" + masterFolder.exists());
//            if (masterFolder.exists()) {
                // 检查订单ID的JSON文件是否存在,不存在则创建
//                String jsonFilePath = masterFolderPath + "/" + datum.getId() + ".json";
                String jsonFilePath = "C:\\Users\\Admin\\Desktop\\1814257493315514369.json";
            String masterFolderPath = "/usr/local/coordinate/" + datum.getServerId();
            File masterFolder = new File(masterFolderPath);
//             检查师傅ID的文件夹是否存在,存在就读取轨迹数据
            System.out.println("文件是否存在:" + masterFolder.exists());
            if (masterFolder.exists()) {
//                 检查订单ID的JSON文件是否存在,不存在则创建
                String jsonFilePath = masterFolderPath + "/" + datum.getId() + ".json";
//                String jsonFilePath = "C:\\Users\\Admin\\Desktop\\1814257493315514369.json";
                File jsonFile = new File(jsonFilePath);
                System.out.println("订单Json文件是否存在:" + jsonFile.exists());
                if (jsonFile.exists()) {
@@ -590,9 +611,10 @@
                    } catch (IOException e) {
                        System.out.println(e.getMessage());
                    }
//                }
                    list.add(orderByServeRecord);
                }
            }
            list.add(orderByServeRecord);
        }
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/RegionController.java
@@ -1,16 +1,23 @@
package com.ruoyi.admin.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.admin.entity.AppVersion;
import com.ruoyi.admin.entity.Region;
import com.ruoyi.admin.entity.SysUser;
import com.ruoyi.admin.mapper.AppMapper;
import com.ruoyi.admin.service.RegionService;
import com.ruoyi.admin.service.SysUserService;
import com.ruoyi.admin.service.UserService;
import com.ruoyi.admin.vo.PageDto;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.system.api.model.LoginUser;
import io.swagger.annotations.Api;
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.RestController;
import org.apache.commons.collections4.Get;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.ArrayList;
@@ -33,6 +40,37 @@
    private RegionService regionService;
    @Resource
    private TokenService tokenService;
    @Resource
    private AppMapper appMapper;
    @Resource
    private SysUserService sysUserService;
    @PostMapping("/version/list")
    @ApiOperation(value = "列表", tags = {"后台-版本管理"})
    public R<Page<AppVersion>> versionList(@RequestBody PageDto pageDto) {
        Page<AppVersion> appVersionPage = appMapper.selectPage(Page.of(pageDto.getPageNum(), pageDto.getPageSize()), new QueryWrapper<AppVersion>().orderByDesc("createTime"));
        for (AppVersion record : appVersionPage.getRecords()) {
            SysUser byId = sysUserService.getById(record.getCreateBy());
            record.setCreateBy(byId.getNickName());
        }
        return R.ok(appVersionPage);
    }
    @PostMapping("/version/add")
    @ApiOperation(value = "添加", tags = {"后台-版本管理"})
    public R versionAdd(@RequestBody AppVersion appVersion) {
        com.ruoyi.system.api.domain.SysUser sysUser = tokenService.getLoginUser().getSysUser();
        appVersion.setCreateBy(String.valueOf(sysUser.getUserId()));
        appMapper.insert(appVersion);
        return R.ok();
    }
    @PostMapping("/version/delete/{id}")
    @ApiOperation(value = "删除", tags = {"后台-版本管理"})
    public R versionDelete(@PathVariable Integer id) {
        appMapper.deleteById(id);
        return R.ok();
    }
    /**
     * 收货地址省市二级联动
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/entity/AppVersion.java
New file
@@ -0,0 +1,49 @@
package com.ruoyi.admin.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.ruoyi.common.core.domain.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
/**
 * <p>
 * 菜单权限表
 * </p>
 *
 * @author hjl
 * @since 2024-06-25
 */
@Getter
@Setter
@TableName("app_version")
@ApiModel(value = "版本管理")
public class AppVersion  extends BaseEntity {
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    @ApiModelProperty("版本号")
    @TableField("version")
    private String version;
    @ApiModelProperty("安卓下载地址")
    @TableField("android_url")
    private String androidUrl;
    @ApiModelProperty("二维码")
    @TableField("code")
    private String code;
    @ApiModelProperty("备注")
    @TableField("remark")
    private String remark;
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/mapper/AppMapper.java
New file
@@ -0,0 +1,17 @@
package com.ruoyi.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.admin.entity.AppVersion;
import com.ruoyi.admin.entity.Notices;
/**
 * <p>
 * 系统通知管理 Mapper 接口
 * </p>
 *
 * @author hjl
 * @since 2024-05-29
 */
public interface AppMapper extends BaseMapper<AppVersion> {
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/impl/OrderServiceImpl.java
@@ -215,6 +215,7 @@
            orderInfo.setOrderNumber(order.getOrderNumber());
            orderInfo.setPlaceOrderTime(order.getCreateTime());
            orderInfo.setState(order.getState());
            orderInfo.setReservationRemark(order.getReservationRemark());
        }
        result.setOrderInfo(orderInfo);
    }
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.ALiSendSms;
import com.ruoyi.admin.utils.SendSmsUtil;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.constant.RedisConstants;
@@ -25,6 +26,9 @@
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private SendSmsUtil sendSmsUtil;
    @Resource
    private ALiSendSms aLiSendSms;
    @Override
    public String workerSettleSms(String phone) {
@@ -49,7 +53,8 @@
        // 发送验证码
        String phone = order.getReservationPhone();
        String[] arr = {order.getOrderNumber()};
        sendSmsUtil.sendSms(new SendSmsUtil.SendSmsRequest(phone, sendSmsUtil.reservationId, arr));
//        sendSmsUtil.sendSms(new SendSmsUtil.SendSmsRequest(phone, sendSmsUtil.reservationId, arr));
        aLiSendSms.send(phone, order.getServerPhone());
        return "发送成功!";
    }
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/utils/ALiSendSms.java
New file
@@ -0,0 +1,62 @@
package com.ruoyi.admin.utils;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.google.gson.Gson;
import org.apache.http.HttpResponse;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
 * 阿里云短信工具类
 */
@Component
public class ALiSendSms {
    public void send(String phone,String workerPhone) {
        String host = "https://gyytz.market.alicloudapi.com";
        String path = "/sms/smsSend";
        String method = "POST";
        String appcode = "0efeed6a5fe94240b143fec8910c5053";
        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
        Map<String, String> querys = new HashMap<String, String>();
        querys.put("mobile", phone);
        querys.put("param", "**phone**:"+workerPhone);
        //smsSignId(短信前缀)和templateId(短信模板),可登录国阳云控制台自助申请。参考文档:http://help.guoyangyun.com/Problem/Qm.html
        querys.put("smsSignId", "d946ebc659714663955e73540ea47185");
        querys.put("templateId", "f534b5fb27594fbf89c4f78288a5932d");
        Map<String, String> bodys = new HashMap<String, String>();
        try {
            /**
             * 重要提示如下:
             * HttpUtils请从\r\n\t    \t* https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/src/main/java/com/aliyun/api/gateway/demo/util/HttpUtils.java\r\n\t    \t* 下载
             *
             * 相应的依赖请参照
             * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/pom.xml
             */
            HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
            System.out.println(response.toString());
            //获取response的body
            //System.out.println(EntityUtils.toString(response.getEntity()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/utils/Constant.java
New file
@@ -0,0 +1,24 @@
/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
 */
package com.ruoyi.admin.utils;
public final class Constant {
    // verify ssl certificate (true) or do not verify (false)
    public static final boolean DO_VERIFY = false;
    public static final String HTTPS = "HTTPS";
    public static final String TRUST_MANAGER_FACTORY = "SunX509";
    public static final String GM_PROTOCOL = "GMTLS";
    public static final String INTERNATIONAL_PROTOCOL = "TLSv1.2";
    public static final String SIGNATURE_ALGORITHM_SDK_HMAC_SHA256 = "SDK-HMAC-SHA256";
    public static final String SIGNATURE_ALGORITHM_SDK_HMAC_SM3 = "SDK-HMAC-SM3";
    public static final String[] SUPPORTED_CIPHER_SUITES = {"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
            "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
            "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"};
    public static final String SECURE_RANDOM_ALGORITHM_NATIVE_PRNG_NON_BLOCKING = "NativePRNGNonBlocking";
    private Constant() {
    }
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/utils/DescribeInstances.java
@@ -23,7 +23,7 @@
        String host = "https://addre.market.alicloudapi.com";
        String path = "/format";
        String method = "GET";
        String appcode = "44145c4c95004841985608a86eb4a4b7";
        String appcode = "0efeed6a5fe94240b143fec8910c5053";
        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/utils/HostName.java
New file
@@ -0,0 +1,17 @@
/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
 */
package com.ruoyi.admin.utils;
public class HostName {
    private static String urlHostName;
    public static void setUrlHostName(String hostName) {
        urlHostName = hostName;
    }
    public static boolean checkHostName(String SSLHostName) {
        return urlHostName.equals(SSLHostName);
    }
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/utils/SSLCipherSuiteUtil.java
New file
@@ -0,0 +1,209 @@
/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
 */
package com.ruoyi.admin.utils;
import okhttp3.OkHttpClient;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.engines.AESEngine;
import org.bouncycastle.crypto.prng.SP800SecureRandomBuilder;
import org.openeuler.BGMProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.net.ssl.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.*;
import java.security.cert.X509Certificate;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
public class SSLCipherSuiteUtil {
    private static final Logger LOGGER = LoggerFactory.getLogger(SSLCipherSuiteUtil.class);
    private static CloseableHttpClient httpClient;
    private static OkHttpClient okHttpClient;
    private static final int CIPHER_LEN = 256;
    private static final int ENTROPY_BITS_REQUIRED = 384;
    public static HttpClient createHttpClient(String protocol) throws Exception {
        SSLContext sslContext = getSslContext(protocol);
        // create factory
        SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext,
                new String[]{protocol}, Constant.SUPPORTED_CIPHER_SUITES, new TrustAllHostnameVerifier());
        httpClient = HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory).build();
        return httpClient;
    }
    public static HttpClient createHttpClientWithVerify(String protocol) throws Exception {
        SSLContext sslContext = getSslContextWithVerify(protocol);
        // create factory
        SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext,
            new String[] {protocol}, Constant.SUPPORTED_CIPHER_SUITES, new TheRealHostnameVerifier());
        httpClient = HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory).build();
        return httpClient;
    }
    public static OkHttpClient createOkHttpClient(String protocol) throws Exception {
        SSLContext sslContext = getSslContext(protocol);
        // Create an ssl socket factory with our all-trusting manager
        SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
        OkHttpClient.Builder builder = new OkHttpClient.Builder()
                .sslSocketFactory(sslSocketFactory, new TrustAllManager())
                .hostnameVerifier(new TrustAllHostnameVerifier());
        okHttpClient = builder.connectTimeout(10, TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS).build();
        return okHttpClient;
    }
    public static OkHttpClient createOkHttpClientWithVerify(String protocol) throws Exception {
        SSLContext sslContext = getSslContextWithVerify(protocol);
        SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(Constant.TRUST_MANAGER_FACTORY);
        tmf.init((KeyStore) null);
        TrustManager[] verify = tmf.getTrustManagers();
        OkHttpClient.Builder builder = new OkHttpClient.Builder().sslSocketFactory(sslSocketFactory,
            (X509TrustManager) verify[0]).hostnameVerifier(new TheRealHostnameVerifier());
        okHttpClient = builder.connectTimeout(10, TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS).build();
        return okHttpClient;
    }
    public static HttpURLConnection createHttpsOrHttpURLConnection(URL uUrl, String protocol) throws Exception {
        // initial connection
        if (uUrl.getProtocol().toUpperCase(Locale.getDefault()).equals(Constant.HTTPS)) {
            SSLContext sslContext = getSslContext(protocol);
            HttpsURLConnection.setDefaultHostnameVerifier(new TrustAllHostnameVerifier());
            HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
            return (HttpsURLConnection) uUrl.openConnection();
        }
        return (HttpURLConnection) uUrl.openConnection();
    }
    public static HttpURLConnection createHttpsOrHttpURLConnectionWithVerify(URL uUrl, String protocol) throws Exception {
        // initial connection
        if (uUrl.getProtocol().toUpperCase(Locale.getDefault()).equals(Constant.HTTPS)) {
            SSLContext sslContext = getSslContextWithVerify(protocol);
            HttpsURLConnection.setDefaultHostnameVerifier(new TheRealHostnameVerifier());
            HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
            return (HttpsURLConnection) uUrl.openConnection();
        }
        return (HttpURLConnection) uUrl.openConnection();
    }
    private static SSLContext getSslContext(String protocol) throws UnsupportProtocolException,
            NoSuchAlgorithmException, NoSuchProviderException, KeyManagementException {
        if (!Constant.GM_PROTOCOL.equals(protocol) && !Constant.INTERNATIONAL_PROTOCOL.equals(protocol)) {
            LOGGER.info("Unsupport protocol: {}, Only support GMTLS TLSv1.2", protocol);
            throw new UnsupportProtocolException("Unsupport protocol, Only support GMTLS TLSv1.2");
        }
        // Create a trust manager that does not validate certificate chains
        TrustAllManager[] trust = {new TrustAllManager()};
        KeyManager[] kms = null;
        SSLContext sslContext;
        sslContext = SSLContext.getInstance(Constant.INTERNATIONAL_PROTOCOL, "SunJSSE");
        if (Constant.GM_PROTOCOL.equals(protocol)) {
            Security.insertProviderAt(new BGMProvider(), 1);
            sslContext = SSLContext.getInstance(Constant.GM_PROTOCOL, "BGMProvider");
        }
        SecureRandom secureRandom = getSecureRandom();
        sslContext.init(kms, trust, secureRandom);
        sslContext.getServerSessionContext().setSessionCacheSize(8192);
        sslContext.getServerSessionContext().setSessionTimeout(3600);
        return sslContext;
    }
    private static SSLContext getSslContextWithVerify(String protocol)
        throws UnsupportProtocolException, NoSuchAlgorithmException, NoSuchProviderException, KeyManagementException,
        KeyStoreException {
        if (!Constant.GM_PROTOCOL.equals(protocol) && !Constant.INTERNATIONAL_PROTOCOL.equals(protocol)) {
            LOGGER.info("Unsupport protocol: {}, Only support GMTLS TLSv1.2", protocol);
            throw new UnsupportProtocolException("Unsupport protocol, Only support GMTLS TLSv1.2");
        }
        KeyManager[] kms = null;
        SSLContext sslContext = SSLContext.getInstance(Constant.INTERNATIONAL_PROTOCOL, "SunJSSE");
        SecureRandom secureRandom = getSecureRandom();
        if (Constant.GM_PROTOCOL.equals(protocol)) {
            Security.insertProviderAt(new BGMProvider(), 1);
            sslContext = SSLContext.getInstance(Constant.GM_PROTOCOL, "BGMProvider");
        }
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(Constant.TRUST_MANAGER_FACTORY);
        tmf.init((KeyStore) null);
        TrustManager[] verify = tmf.getTrustManagers();
        sslContext.init(kms, verify, secureRandom);
        sslContext.getServerSessionContext().setSessionCacheSize(8192);
        sslContext.getServerSessionContext().setSessionTimeout(3600);
        return sslContext;
    }
    // 不校验域名
    private static class TrustAllHostnameVerifier implements HostnameVerifier {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }
    // 校验域名
    private static class TheRealHostnameVerifier implements HostnameVerifier {
        public boolean verify(String hostname, SSLSession session) {
            if (HostName.checkHostName(hostname)) {
                return true;
            } else {
                HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
                return hv.verify(hostname, session);
            }
        }
    }
    // 不校验服务端证书
    private static class TrustAllManager implements X509TrustManager {
        private X509Certificate[] issuers;
        public TrustAllManager() {
            this.issuers = new X509Certificate[0];
        }
        public X509Certificate[] getAcceptedIssuers() {
            return issuers;
        }
        public void checkClientTrusted(X509Certificate[] chain, String authType) {
        }
        public void checkServerTrusted(X509Certificate[] chain, String authType) {
        }
    }
    private static SecureRandom getSecureRandom() {
        SecureRandom source;
        try {
            source = SecureRandom.getInstance(Constant.SECURE_RANDOM_ALGORITHM_NATIVE_PRNG_NON_BLOCKING);
        } catch (NoSuchAlgorithmException e) {
            try {
                source = SecureRandom.getInstanceStrong();
            } catch (NoSuchAlgorithmException ex) {
                LOGGER.error("get SecureRandom failed", e);
                throw new RuntimeException("get SecureRandom failed");
            }
        }
        boolean predictionResistant = true;
        BlockCipher cipher = new AESEngine();
        boolean reSeed = false;
        return new SP800SecureRandomBuilder(source, predictionResistant).setEntropyBitsRequired(
                ENTROPY_BITS_REQUIRED).buildCTR(cipher, CIPHER_LEN, null, reSeed);
    }
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/utils/UnsupportProtocolException.java
New file
@@ -0,0 +1,15 @@
/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 */
package com.ruoyi.admin.utils;
public class UnsupportProtocolException extends Exception {
    private static final long serialVersionUID = 4312820110480855928L;
    private String msgDes; // 异常对应的描述信息
    public UnsupportProtocolException(String message) {
        super(message);
        msgDes = message;
    }
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/vo/OrderInfoVO.java
@@ -25,5 +25,7 @@
    @ApiModelProperty("订单状态(0:待派单;1:待上门;2:待完工;3:已完结;4:已取消;5:已改派)")
    private Integer state;
    @ApiModelProperty("预约备注")
    private String reservationRemark;
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/vo/OrderReasinDto.java
New file
@@ -0,0 +1,10 @@
package com.ruoyi.admin.vo;
import lombok.Data;
import java.util.List;
@Data
public class OrderReasinDto {
    Integer workerId;
    List<ReassinDto> reassinDtos;
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/vo/PageDto.java
New file
@@ -0,0 +1,9 @@
package com.ruoyi.admin.vo;
import lombok.Data;
@Data
public class PageDto {
    private Integer pageNum = 1;
    private Integer pageSize = 10;
}
ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/vo/ReassinDto.java
New file
@@ -0,0 +1,10 @@
package com.ruoyi.admin.vo;
import lombok.Data;
@Data
public class ReassinDto {
  private   String orderId;
  private Integer type;
}
ruoyi-service/ruoyi-admin/src/main/resources/bootstrap.yaml
@@ -23,6 +23,8 @@
        group: DEFAULT_GROUP
        namespace: 5b0cc96f-d058-4986-a46f-64644ff8a467
        # 线上nacos需要鉴权
#        username: nacos
#        password: nacos
        username: nacos
        password: jdhs_nacos!
      config:
@@ -31,6 +33,8 @@
        group: DEFAULT_GROUP
        namespace: 5b0cc96f-d058-4986-a46f-64644ff8a467
        # 线上nacos需要鉴权
#        username: nacos
#        password: nacos
        username: nacos
        password: jdhs_nacos!
        name: ${spring.application.name}
ruoyi-service/ruoyi-admin/src/main/resources/template/订单记录.xlsx
Binary files differ
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/ChangeDispatchController.java
@@ -18,6 +18,7 @@
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@@ -244,9 +245,9 @@
                .set(Order::getIsReinvest, Constants.ONE)
                .set(Order::getAcceptTime, new Date())
                .set(Order::getArriveTime, null)
                .set(Order::getCompleteTime, null)
                .set(Order::getCompleteTime, null).set(Order::getAcceptTime, LocalDateTime.now())
                // 原订单状态改为 1:待上门,已选择师傅
                .set(Order::getState, Constants.ONE)
                .set(Order::getState, Constants.ONE).set(Order::getServerId, workerId).set(Order::getServerName, name).set(Order::getServerPhone, phone)
                .eq(Order::getId, order.getId()).update();
        // 改派信息
        boolean update = changeDispatchService.lambdaUpdate().set(ChangeDispatch::getState, 1)
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/OrderController.java
@@ -313,6 +313,7 @@
        order.setTime(orderRequest.getTime());
        order.setAcceptTime(orderRequest.getAcceptTime());
//        order.setAcceptTime(new Date());
        // 师傅信息
        order.setServerId(orderRequest.getServerId());
        order.setServerName(orderRequest.getServerName());
@@ -420,6 +421,12 @@
        List<String> idList = Arrays.stream(ids.split(",")).collect(Collectors.toList());
        List<Order> list = orderService.lambdaQuery().in(Order::getId, idList).list();
        list.forEach(data -> data.setIsDelete(1));
        List<ChangeDispatch> list1 = changeDispatchService.lambdaQuery().in(ChangeDispatch::getOrderId, idList).list();
        if (!list1.isEmpty()) {
            list1.forEach(data -> data.setIsDelete(1));
            changeDispatchService.updateBatchById(list1);
        }
        return R.ok(orderService.updateBatchById(list));
    }
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/OrderQueryRequest.java
@@ -29,6 +29,9 @@
    @ApiModelProperty("订单状态(0:待派单;1:待上门;2:待完工;3:已完结;4:已取消;5:已改派)")
    private Integer state;
    private Integer fake;
    private String address;
    @ApiModelProperty("师傅名称")
    private String workerName;
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/OrderQueryVO.java
@@ -23,6 +23,7 @@
    @ApiModelProperty("订单数量")
    private Integer number;
    private Integer fakeNumber;
    private Integer fakeCount;
}
ruoyi-service/ruoyi-order/src/main/resources/bootstrap.yaml
@@ -23,6 +23,8 @@
        group: DEFAULT_GROUP
        namespace: 5b0cc96f-d058-4986-a46f-64644ff8a467
        # 线上nacos需要鉴权
#        username: nacos
#        password: nacos
        username: nacos
        password: jdhs_nacos!
      config:
@@ -31,6 +33,8 @@
        group: DEFAULT_GROUP
        namespace: 5b0cc96f-d058-4986-a46f-64644ff8a467
        # 线上nacos需要鉴权
#        username: nacos
#        password: nacos
        username: nacos
        password: jdhs_nacos!
        name: ${spring.application.name}
ruoyi-service/ruoyi-order/src/main/resources/mapper/order/OrderMapper.xml
@@ -5,6 +5,7 @@
    <resultMap id="BaseResultMap" type="com.ruoyi.order.entity.Order">
        <id column="id" property="id"/>
        <result column="site_id" property="siteId"/>
        <result column="accept_time" property="acceptTime"/>
        <result column="order_number" property="orderNumber"/>
        <result column="order_money" property="orderMoney"/>
        <result column="site_name" property="siteName"/>
@@ -202,7 +203,12 @@
        from t_order o
        <where>
            o.is_delete = 0
            <if test="data.fake != null ">
                and o.fake = #{data.fake}
            </if>
            <if test="data.address != null and data.address != ''">
                and o.reservation_address like concat('%', #{data.address}, '%')
            </if>
            <if test="data.orderNumber != null and data.orderNumber != ''">
                and o.order_number like concat('%', #{data.orderNumber}, '%')
            </if>
@@ -270,9 +276,23 @@
                    #{city}
                </foreach>
            </if>
            <if test="data.servIds != null and data.servIds.size() != 0">
                and o.serve_id in
                <foreach collection="data.servIds" item="c" open="(" separator="," close=")">
                    #{c}
                </foreach>
            </if>
           <if test="data.type !=null">
               and o.type = #{data.type}
           </if>
            <if test="data.fake !=null">
                and o.fake = #{data.fake}
            </if>
            <if test="data.address != null and data.address != ''">
                and o.reservation_address like concat('%', #{data.address}, '%')
            </if>
            <if test="data.orderNumber != null and data.orderNumber != ''">
                and o.order_number like concat('%', #{data.orderNumber}, '%')
            </if>
@@ -316,7 +336,7 @@
               time,
               serve_name,
               server_name,
               server_phone
               server_phone,site_name
        from t_order
        <where>
            id in
@@ -331,6 +351,21 @@
        from t_order o
        <where>
            o.is_delete = 0
            <if test="data.fake != null ">
                and o.fake = #{data.fake}
            </if>
            <if test="data.address != null and data.address != ''">
                and o.reservation_address like concat('%', #{data.address}, '%')
            </if>
            <if test="data.servIds != null and data.servIds.size() != 0">
                and o.serve_id in
                <foreach collection="data.servIds" item="c" open="(" separator="," close=")">
                    #{c}
                </foreach>
            </if>
            <if test="data.type != null">
                and o.type = #{data.type}
            </if>
            <if test="data.orderNumber != null and data.orderNumber != ''">
                and o.order_number like concat('%', #{data.orderNumber}, '%')
            </if>
@@ -353,7 +388,7 @@
                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}, '%')
                and o.site_name like concat('%', #{data.serveName}, '%')
            </if>
            <if test="data.orderTimeStart != null and data.orderTimeStart != ''">
                and DATE(o.createTime) <![CDATA[ >= ]]> #{data.orderTimeStart}
@@ -500,10 +535,11 @@
    </select>
    <select id="papercout" resultType="com.ruoyi.common.core.vo.PaperInVo">
        select count(*) as count, serve_id as serveId from t_order
                                                      where is_delete = 0
                                                      where is_delete = 0 and state = 3
                                                        and server_id = #{workId}
                                                        and `time` = #{date}
        group by serve_id
    </select>
</mapper>
ruoyi-service/ruoyi-user/src/main/resources/bootstrap.yaml
@@ -25,6 +25,8 @@
        # 线上nacos需要鉴权
        username: nacos
        password: jdhs_nacos!
#        username: nacos
#        password: nacos
      config:
        # 配置中心地址
        server-addr: 127.0.0.1:8848
@@ -33,6 +35,8 @@
        # 线上nacos需要鉴权
        username: nacos
        password: jdhs_nacos!
#        username: nacos
#        password: nacos
        name: ${spring.application.name}
        # 配置文件格式
        file-extension: yml
ruoyi-service/ruoyi-worker/pom.xml
@@ -19,6 +19,12 @@
    </properties>
    <dependencies>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.4</version>
        </dependency>
        <!-- mybatis-plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/controller/MasterWorkerController.java
@@ -1,6 +1,8 @@
package com.ruoyi.worker.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.admin.api.entity.Agreement;
import com.ruoyi.admin.api.feignClient.AdminClient;
import com.ruoyi.common.core.constant.Constants;
@@ -13,8 +15,10 @@
import com.ruoyi.order.api.entity.WorkerOrderCountVO;
import com.ruoyi.order.api.feignClient.OrderClient;
import com.ruoyi.system.api.model.LoginUserInfo;
import com.ruoyi.worker.entity.AppVersion;
import com.ruoyi.worker.entity.MasterWorker;
import com.ruoyi.worker.entity.WorkerProcess;
import com.ruoyi.worker.mapper.AppMapper;
import com.ruoyi.worker.request.LoginPasswordRequest;
import com.ruoyi.worker.request.LoginPhoneRequest;
import com.ruoyi.worker.service.MasterWorkerService;
@@ -61,7 +65,16 @@
    private AdminClient adminClient;
    @Resource
    private OrderClient orderClient;
    @Resource
    private AppMapper appMapper;
    @PostMapping("/version/check")
    @ApiOperation(value = "获取最新的版本信息", tags = {"自动更新"})
    public R<AppVersion> check() {
        AppVersion appVersion = appMapper.selectOne(new QueryWrapper<AppVersion>().orderByDesc("createTime").eq("is_delete", 0).last("limit 1"));
            return R.ok(appVersion);
    }
    /**
     * 师傅端-密码登录
     *
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/controller/OssController.java
@@ -1,12 +1,17 @@
package com.ruoyi.worker.controller;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.Result;
import com.ruoyi.common.core.utils.GaoDeMapUtil;
import com.ruoyi.order.api.feignClient.OrderClient;
import com.ruoyi.worker.utils.FileImageWatermarkUtils;
import com.ruoyi.worker.utils.TencentCosUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@@ -14,6 +19,17 @@
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
/**
 * @author HJL
@@ -23,12 +39,14 @@
@RestController
@RequestMapping("/oss")
@Api(tags = "师傅端-文件上传")
@Slf4j
public class OssController {
    @Resource
    private OrderClient orderClient;
    @Resource
    private TencentCosUtil tencentCosUtil;
    @PostMapping("/upload")
    @ApiOperation(value = "文件上传", tags = "师傅端-文件上传")
@@ -52,4 +70,40 @@
        return R.ok(tencentCosUtil.upLoadFile(file));
    }
    @PostMapping(value = "/pic", produces = "application/json;charset=UTF-8")
    @ApiOperation(value = "文件上传加水印", tags = "师傅端-文件上传")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "文件", name = "file", dataType = "MultipartFile", required = true)
    })
    public R<String> pic(@RequestParam("file") MultipartFile file,@RequestParam String longitude,@RequestParam String address,
                         @RequestParam String latitude) {
//        Result<String> address = GaoDeMapUtil.getAddress(longitude, latitude);
        // 获取当前时间
        LocalDateTime date = LocalDateTime.now();
        // 设置日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 通过format调用转换的方法
        String dateWatermark =  formatter.format(date);
//        System.err.println("==========="+LocalDateTime.now());
        log.error("==========="+LocalDateTime.now());
        MultipartFile watermarkFile = FileImageWatermarkUtils.markWithContent(file,dateWatermark,address);
//        System.err.println("==========="+LocalDateTime.now());
        log.error("==========="+LocalDateTime.now());
        String url = tencentCosUtil.upLoadFile(watermarkFile);
        log.error("==========="+LocalDateTime.now());
        return R.ok(url);
    }
}
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/entity/AppVersion.java
New file
@@ -0,0 +1,45 @@
package com.ruoyi.worker.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.ruoyi.common.core.domain.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
 * <p>
 * 菜单权限表
 * </p>
 *
 * @author hjl
 * @since 2024-06-25
 */
@Getter
@Setter
@TableName("app_version")
@ApiModel(value = "版本管理")
public class AppVersion extends BaseEntity {
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    @ApiModelProperty("版本号")
    @TableField("version")
    private String version;
    @ApiModelProperty("安卓下载地址")
    @TableField("android_url")
    private String androidUrl;
    @ApiModelProperty("二维码")
    @TableField("code")
    private String code;
    @ApiModelProperty("备注")
    @TableField("remark")
    private String remark;
}
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/entity/MultipartFileDto.java
New file
@@ -0,0 +1,189 @@
package com.ruoyi.worker.entity;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
/**
 * @author
 * file转MultipartFile的时候会用到MockMultipartFile
 * 当你导入spring-test依赖的时候 会跟某些依赖冲突(暂未找到具体是哪个冲突)
 * 解决方法 重写一个类去实现MultipartFile接口
 * 直接用MockMultipartFile的源码
 *
 */
public class MultipartFileDto implements MultipartFile {
    private final String name;
    private String originalFilename;
    private String contentType;
    private final byte[] content;
    /**
     * Create a new MultipartFileDto with the given content.
     * @param name the name of the file
     * @param content the content of the file
     */
    public MultipartFileDto(String name, byte[] content) {
        this(name, "", null, content);
    }
    /**
     * Create a new MultipartFileDto with the given content.
     * @param name the name of the file
     * @param contentStream the content of the file as stream
     * @throws IOException if reading from the stream failed
     */
    public MultipartFileDto(String name, InputStream contentStream) throws IOException {
        this(name, "", null, FileCopyUtils.copyToByteArray(contentStream));
    }
    /**
     * Create a new MultipartFileDto with the given content.
     * @param name the name of the file
     * @param originalFilename the original filename (as on the client's machine)
     * @param contentType the content type (if known)
     * @param content the content of the file
     */
    public MultipartFileDto(String name, String originalFilename, String contentType, byte[] content) {
        this.name = name;
        this.originalFilename = (originalFilename != null ? originalFilename : "");
        this.contentType = contentType;
        this.content = (content != null ? content : new byte[0]);
    }
    /**
     * Create a new MultipartFileDto with the given content.
     * @param name the name of the file
     * @param originalFilename the original filename (as on the client's machine)
     * @param contentType the content type (if known)
     * @param contentStream the content of the file as stream
     * @throws IOException if reading from the stream failed
     */
    public MultipartFileDto(String name, String originalFilename, String contentType, InputStream contentStream)
            throws IOException {
        this(name, originalFilename, contentType, FileCopyUtils.copyToByteArray(contentStream));
    }
    @Override
    public String getName() {
        return this.name;
    }
    @Override
    public String getOriginalFilename() {
        return this.originalFilename;
    }
    @Override
    public String getContentType() {
        return this.contentType;
    }
    @Override
    public boolean isEmpty() {
        return (this.content.length == 0);
    }
    @Override
    public long getSize() {
        return this.content.length;
    }
    @Override
    public byte[] getBytes() throws IOException {
        return this.content;
    }
    @Override
    public InputStream getInputStream() throws IOException {
        return new ByteArrayInputStream(this.content);
    }
    @Override
    public void transferTo(File dest) throws IOException, IllegalStateException {
        FileCopyUtils.copy(this.content, dest);
    }
}
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/mapper/AppMapper.java
New file
@@ -0,0 +1,16 @@
package com.ruoyi.worker.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.worker.entity.AppVersion;
/**
 * <p>
 * 系统通知管理 Mapper 接口
 * </p>
 *
 * @author hjl
 * @since 2024-05-29
 */
public interface AppMapper extends BaseMapper<AppVersion> {
}
ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/utils/FileImageWatermarkUtils.java
New file
@@ -0,0 +1,276 @@
package com.ruoyi.worker.utils;
import com.ruoyi.worker.entity.MultipartFileDto;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.*;
/**
 * @author inspur
 * 定义文字加水印
 */
public class FileImageWatermarkUtils {
    /**
     * 水印字体
     */
    private static final Font FONT = new Font("宋体", Font.PLAIN, 40);
    /**
     * 透明度
     */
    private static final AlphaComposite COMPOSITE = AlphaComposite
            .getInstance(AlphaComposite.SRC_OVER, 0.9f);
    /**
     * 水印之间的间隔
     */
    private static final int X_MOVE = 150;
    /**
     * 水印之间的间隔
     */
    private static final int Y_MOVE = 200;
    /**
     * 打水印(文字)
     *
     * @param file       MultipartFile
     * @return MultipartFile
     */
    public static MultipartFile markWithContent(MultipartFile file,String keyword,String address) {
        FileOutputStream fos = null;
        try {
            BufferedImage srcImg = ImageIO.read(file.getInputStream());
            // 图片宽、高
            int imgWidth = srcImg.getWidth();
            int imgHeight = srcImg.getHeight();
            // 图片缓存
            BufferedImage bufImg = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);
            // 创建绘图工具
            Graphics2D graphics = bufImg.createGraphics();
            // 画入原始图像
            graphics.drawImage(srcImg, 0, 0, imgWidth, imgHeight, null);
            // 设置水印颜色
            graphics.setColor(Color.RED);
            // 设置水印透明度
            graphics.setComposite(COMPOSITE);
            // 设置倾斜角度
/*            graphics.rotate(Math.toRadians(-35), (double) bufImg.getWidth() / 2,
                    (double) bufImg.getHeight() / 2);*/
            // 设置水印字体
            graphics.setFont(FONT);
            // 消除java.awt.Font字体的锯齿
//            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            int xCoordinate , yCoordinate;
            int xCoordinate1 , yCoordinate1;
            int xCoordinate2 , yCoordinate2;
            String mark = "ls65535";
            // 字体长度
            int markWidth = FONT.getSize() * getTextLength(keyword);
            // 字体高度
            int markHeight = FONT.getSize();
            //位置控制 水印位于图片 下方右下角
            if (address.length()<=23){
                xCoordinate = (int) ((imgWidth - getWatermarkLength(keyword, graphics)) * 0.05);
                yCoordinate = (int) (imgHeight * 0.91);
                xCoordinate1 = (int) ((imgWidth - getWatermarkLength(keyword, graphics)) * 0.05);
                yCoordinate1 = (int) (imgHeight * 0.96);
                graphics.drawString("地址:" + address, xCoordinate, yCoordinate);
                graphics.drawString("时间:" + keyword, xCoordinate1, yCoordinate1);
                InputStream inputStream = buffToInputStream(bufImg);
                // 释放画图工具
                graphics.dispose();
                return new MultipartFileDto(file.getName(),file.getOriginalFilename(),file.getContentType(),inputStream);
            }else {
                xCoordinate2 = (int) ((imgWidth - getWatermarkLength(keyword, graphics)) * 0.05);
                yCoordinate2 = (int) (imgHeight * 0.91);
                xCoordinate = (int) ((imgWidth - getWatermarkLength(keyword, graphics)) * 0.05);
                yCoordinate = (int) (imgHeight * 0.88);
                xCoordinate1 = (int) ((imgWidth - getWatermarkLength(keyword, graphics)) * 0.05);
                yCoordinate1 = (int) (imgHeight * 0.96);
                graphics.drawString("地址:" + address.substring(0,20), xCoordinate, yCoordinate);
                graphics.drawString(address.substring(20), xCoordinate2, yCoordinate2);
                graphics.drawString("时间:" + keyword, xCoordinate1, yCoordinate1);
                InputStream inputStream = buffToInputStream(bufImg);
            // 释放画图工具
            graphics.dispose();
            return new MultipartFileDto(file.getName(),file.getOriginalFilename(),file.getContentType(),inputStream);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.flush();
                    fos.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
    /**
     * 计算水印文本长度
     * 1、中文长度即文本长度 2、英文长度为文本长度二分之一
     * @param text
     * @return
     */
    public static int getTextLength(String text) {
        //水印文字长度
        int length = text.length();
        for (int i = 0; i < text.length(); i++) {
            String s = String.valueOf(text.charAt(i));
            if (s.getBytes().length > 1) {
                length++;
            }
        }
        length = length % 2 == 0 ? length / 2 : length / 2 + 1;
        return length;
    }
    public static InputStream buffToInputStream(BufferedImage buffer) throws IOException {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        ImageIO.write(buffer, "png", os);
        return new ByteArrayInputStream(os.toByteArray());
    }
    public static int getWatermarkLength(String waterMarkContent, Graphics2D g) {
        return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
    }
}
ruoyi-service/ruoyi-worker/src/main/resources/bootstrap.yaml
@@ -25,6 +25,8 @@
        # 线上nacos需要鉴权
        username: nacos
        password: jdhs_nacos!
#        username: nacos
#        password: nacos
      config:
        # 配置中心地址
        server-addr: 127.0.0.1:8848
@@ -33,6 +35,8 @@
        # 线上nacos需要鉴权
        username: nacos
        password: jdhs_nacos!
#        username: nacos
#        password: nacos
        name: ${spring.application.name}
        # 配置文件格式
        file-extension: yml