111
k94314517
2025-07-14 df5ab4f34d11a7e68af1124b3d1c3bc1d79e1fd6
111
已添加9个文件
已修改15个文件
1857 ■■■■■ 文件已修改
server/services/src/main/java/com/doumee/config/wx/WxMiniConfig.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/config/wx/WxMiniUtilService.java 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/config/wx/WxPayProperties.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/core/constants/Constants.java 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/core/utils/DateUtil.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/model/Category.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/model/Member.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/model/Multifile.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/model/OrderLog.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/model/Orders.java 59 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/model/WithdrawalOrders.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/dto/CateringDTO.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/dto/CommentDTO.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/dto/ConfirmUpdOrderDTO.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/dto/DoneOrderDTO.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/dto/UpdOrderDataDTO.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/dto/WayInfoDTO.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/OrdersService.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/impl/OrdersServiceImpl.java 864 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/resources/application-dev.yml 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/resources/application-pro.yml 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/resources/application-test.yml 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/web/src/main/java/com/doumee/api/web/OrdersApi.java 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/web/src/main/java/com/doumee/api/web/PaymentCallback.java 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/config/wx/WxMiniConfig.java
@@ -10,6 +10,12 @@
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.service.billdownload.BillDownloadService;
import com.wechat.pay.java.service.partnerpayments.jsapi.JsapiService;
import com.wechat.pay.java.service.partnerpayments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.refund.RefundService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
@@ -21,12 +27,18 @@
 */
@Configuration
public class WxMiniConfig {
    @Autowired
    private SystemDictDataBiz systemDictDataBiz;
    /********微信小程序服务**********/
    public static WxMaService wxMaService;
    /********微信小程序支付**********/
    public static WxPayService wxPayService;
    public static JsapiService wxPayService;
    public static WxPayService wxPayV2Service;
    public static RefundService refundService;
    public static JsapiServiceExtension jsapiExtService;
    public static BillDownloadService billDownloadService;
    public static WxPayProperties wxProperties;
    @Autowired
    private WxPayProperties wxPayProperties;
    public static WxMiniConfig me() {
        return SpringUtils.get().getBean(WxMiniConfig.class);
@@ -35,15 +47,23 @@
    @PostConstruct
    void init() {
        this.load_WxMaService();
//        this.load_wxPayService();
        this.load_wxPayService();
        this.load_wxPayV2Service();
        this.wxProperties = wxPayProperties;
    }
    /**
     * åˆå§‹åŒ–微信小程序
     */
    public void load_WxMaService() {
        WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
        config.setAppid(StringUtils.trimToNull(systemDictDataBiz.queryByCode(Constants.WX_CONFIG,Constants.APPID).getCode()));
        config.setSecret(StringUtils.trimToNull(systemDictDataBiz.queryByCode(Constants.WX_CONFIG,Constants.SECRET).getCode()));
        if(wxPayProperties.getExistsSub() ==1){
            //如果是服务商支付,取子商户信息
            config.setAppid(StringUtils.trimToNull(wxPayProperties.getSubAppId()));
            config.setSecret(StringUtils.trimToNull(wxPayProperties.getSubAppSecret()));
        }else {
            config.setAppid(StringUtils.trimToNull(wxPayProperties.getAppId()));
            config.setSecret(StringUtils.trimToNull(wxPayProperties.getAppSecret()));
        }
        config.setMsgDataFormat("JSON");
        //config.setToken("");
        //config.setAesKey("");
@@ -55,6 +75,50 @@
    /**
     * åˆå§‹åŒ–微信小程序支付
     */
    public void load_wxPayService()   {
        try {
            Config config =
                    new RSAAutoCertificateConfig.Builder()
                            .merchantId(wxPayProperties.getMchId())
                            .privateKeyFromPath(wxPayProperties.getPrivateKeyPath())
                            .merchantSerialNumber(wxPayProperties.getSerialNumer())
                            .apiV3Key(wxPayProperties.getApiV3Key())
                            .build();
            this.wxPayService =  new JsapiService.Builder().config(config).build();
            this.jsapiExtService =  new JsapiServiceExtension.Builder().config(config).build();
            this.refundService = new RefundService.Builder().config(config).build();
            this.billDownloadService = new BillDownloadService.Builder().config(config).build();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    /**
     * åˆå§‹åŒ–微信小程序支付
     */
    public void load_wxPayV2Service()
    {
        WxPayConfig payConfig = new WxPayConfig();
        payConfig.setTradeType(WxPayConstants.TradeType.JSAPI);
        payConfig.setSignType(WxPayConstants.SignType.MD5);
        payConfig.setAppId(StringUtils.trimToNull(wxPayProperties.getAppId()));
        payConfig.setSubAppId(StringUtils.trimToNull(wxPayProperties.getSubAppId()));
        payConfig.setMchId(StringUtils.trimToNull(wxPayProperties.getMchId()));
        payConfig.setSubMchId(StringUtils.trimToNull(wxPayProperties.getSubMchId()));
        payConfig.setMchKey(StringUtils.trimToNull(wxPayProperties.getMchKey()));
//        payConfig.setKeyPath(StringUtils.trimToNull(wxPayProperties.getKeyPath()));
        payConfig.setNotifyUrl(StringUtils.trimToNull(wxPayProperties.getNotifyUrl()));
        WxPayService wxPayService = new WxPayServiceImpl();
        wxPayService.setConfig(payConfig);
        this.wxPayV2Service = wxPayService;
    }
    /**
     * åˆå§‹åŒ–微信小程序支付
     */
//    public void load_wxPayService() {
//        WxPayConfig payConfig = new WxPayConfig();
//        payConfig.setTradeType(WxPayConstants.TradeType.JSAPI);
server/services/src/main/java/com/doumee/config/wx/WxMiniUtilService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,83 @@
package com.doumee.config.wx;
import com.alibaba.fastjson.JSONObject;
import com.doumee.biz.system.SystemDictDataBiz;
import com.doumee.core.constants.Constants;
import com.doumee.core.constants.ResponseStatus;
import com.doumee.core.exception.BusinessException;
import com.doumee.core.utils.DateUtil;
import com.doumee.core.utils.HttpsUtil;
import com.doumee.dao.business.WithdrawalOrdersMapper;
import com.doumee.dao.business.model.Orders;
import com.doumee.dao.business.model.WithdrawalOrders;
import com.doumee.dao.system.model.SystemDictData;
import com.wechat.pay.java.service.refund.model.AmountReq;
import com.wechat.pay.java.service.refund.model.CreateRequest;
import com.wechat.pay.java.service.refund.model.QueryByOutRefundNoRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
 * å¾®ä¿¡å°ç¨‹åº-公共方法
 */
@Service
@Slf4j
public class WxMiniUtilService {
    @Autowired
    private WithdrawalOrdersMapper withdrawalOrdersMapper;
    @Autowired
    private SystemDictDataBiz systemDictDataBiz;
    @Autowired
    private WxPayProperties wxPayProperties;
    @Transactional(rollbackFor = {BusinessException.class,Exception.class})
    public boolean wxRefund(WithdrawalOrders withdrawalOrders,Orders orders) {
        // å‘送退款请求
        withdrawalOrders.setCreateTime(new Date());
        withdrawalOrdersMapper.insert(withdrawalOrders);
        CreateRequest request = new CreateRequest();
        request.setOutTradeNo(orders.getCode());
        request.setOutRefundNo("refund_"+orders.getCode());
        request.setSubMchid(WxMiniConfig.wxProperties.getSubMchId());
        request.setNotifyUrl(WxMiniConfig.wxProperties.getRefundNotifyUrl());
        AmountReq amountReq = new AmountReq();
        amountReq.setTotal(withdrawalOrders.getAmount());
        amountReq.setRefund(withdrawalOrders.getAmount());
        amountReq.setCurrency("CNY");
        request.setAmount(amountReq);
        try {
            log.error("=============="+JSONObject.toJSONString(request));
            com.wechat.pay.java.service.refund.model.Refund response = WxMiniConfig.refundService.create(request);
            log.error("=============="+JSONObject.toJSONString(response));
            if ("SUCCESS".equals(response.getStatus().name())
                    || "PROCESSING".equals(response.getStatus().name()) ) {
                return  true;
            }else{
                throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"对不起,退款申请失败哦!");
            }
        }catch (Exception e){
            e.printStackTrace();
            throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"对不起,退款申请失败!");
        }
    }
}
server/services/src/main/java/com/doumee/config/wx/WxPayProperties.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,66 @@
package com.doumee.config.wx;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
 * Created by IntelliJ IDEA.
 *
 * @Author : Rk
 * @create 2023/3/22 18:04
 */
@Component
@ConfigurationProperties(prefix = "wx.pay")
@Data
public class WxPayProperties {
    /**
     * AppID
     */
    private String appId;
    private String apiV3Key;
    /**
     * AppSecret
     */
    private String appSecret;
    /**
     * å¾®ä¿¡å•†æˆ·å·
     */
    private String mchId;
    /**
     * æ”¯ä»˜API密钥
     */
    private String mchKey;
    /**
     * æ”¯ä»˜API密钥
     */
    private String subMchKey;
    /**
     * æ”¯ä»˜å›žè°ƒåœ°å€
     */
    private String notifyUrl;
    /**
     * é€€æ¬¾å›žè°ƒåœ°å€
     */
    private String refundNotifyUrl;
    /**
     * æ”¯ä»˜è¯ä¹¦(p12)
     */
    private String keyPath;
    private String serialNumer;
    private int existsSub;// true
    private String subAppId;//wxcd2b89fd2ff065f8
    private String subMchId;// 1229817002
    private String subAppSecret;// 1229817002
    private String typeId;// gybike
    private String privateKeyPath ;
    private String privateCertPath;// gybike
}
server/services/src/main/java/com/doumee/core/constants/Constants.java
@@ -52,6 +52,12 @@
    public static final String ABOUT_US ="ABOUT_US" ;
    public static final String RELEASE_CANCEL_TIMES ="RELEASE_CANCEL_TIMES" ;
    public static final String RECEIVE_CANCEL_TIMES ="RECEIVE_CANCEL_TIMES" ;
    public static final String RELEASE_CANCEL_TIME ="RELEASE_CANCEL_TIME" ;
    public static final String RECEIVE_CANCEL_TIME ="RECEIVE_CANCEL_TIME" ;
    public static final String AUTO_DISPATCH ="AUTO_DISPATCH" ;
    public static final String AUTO_DISPATCH_DISTANCE ="AUTO_DISPATCH_DISTANCE" ;
    public static final String QYWX = "QYWX";
    public static final  Integer ONE = 1;
@@ -388,4 +394,92 @@
    }
    public  enum OrdersLog {
        UPLOAD(0, "发单方-发布订单","{userName}发布{param}",0),
        RECEIVE(1, "接单方-已抢单","{userName}已抢单",1),
        UPD_ORDER(2, "发单方-修改订单","{userName}修改了用工时间",0),
        UPD_DISAGREE(3, "接单方-不同意修改,订单取消","{userName}不同意修改,订单取消",1),
        UPD_AGREE(4, "接单方-同意修改","{userName}同意修改",1),
        AUTO(5, "系统-自动派单","无人接单已自动派单给{userName}",1),
        CANCEL(6, "接单方-取消接单","{userName}已手动取消接单",1),
        BEGIN(7, "发单方-开始作业","{userName}已开始作业",0),
        DONE(8, "发单方-完成作业","{userName}已确认完成作业",0),
        PAY(9, "发单方-完成支付","{userName}已支付费用",0),
        COMMENT(10, "发单方-评价完成","{userName}完成评价",0),
        SYSTEM_CANCEL(11, "系统-订单取消","系统取消",2),
        RELEASE_CANCEL(12, "发单方-订单取消","{userName}已手动取消订单",0),
        ;
        // æˆå‘˜å˜é‡
        private String name;
        private String info;
        private int key;
        private int userType;
        // æž„造方法
        OrdersLog(int key, String name,String info,int userType) {
            this.name = name;
            this.info = info;
            this.key = key;
            this.userType = userType;
        }
        // æ™®é€šæ–¹æ³•
        public static String getName(int index) {
            for (OrdersLog c : OrdersLog.values()) {
                if (c.getKey() == index) {
                    return c.name;
                }
            }
            return null;
        }
        public static String getInfo(int index) {
            for (OrdersLog c : OrdersLog.values()) {
                if (c.getKey() == index) {
                    return c.info;
                }
            }
            return null;
        }
        // get set æ–¹æ³•
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getKey() {
            return key;
        }
        public void setKey(int key) {
            this.key = key;
        }
        public int getUserType() {
            return userType;
        }
        public void setUserType(int key) {
            this.userType = userType;
        }
        public String getInfo() {
            return info;
        }
        public void setInfo(String info) {
            this.info = info;
        }
    }
}
server/services/src/main/java/com/doumee/core/utils/DateUtil.java
@@ -1380,6 +1380,9 @@
        return (int) days;
    }
    public static int daysBetweenDates11(Date newDate, Date oldDate) {
        int days = 0;
        Calendar calo = Calendar.getInstance();
@@ -2944,9 +2947,9 @@
//                System.out.println(getPlusTime2(d));
//            }
//            Date startTime = DateUtil.StringToDate("2024-05-01 08:00:00" ,"yyyy-MM-dd HH:mm:ss");
//            Date endTime = DateUtil.StringToDate("2024-05-01 17:00:00" ,"yyyy-MM-dd HH:mm:ss");
//            Long intervalTime = 35L;
            Date startTime = DateUtil.StringToDate("2024-05-01" ,"yyyy-MM-dd");
            Date endTime = DateUtil.StringToDate("2024-06-02" ,"yyyy-MM-dd");
            System.out.println(DateUtil.daysBetweenDates(endTime,startTime));
//
//
//            DateUtil.checkDateInterval( startTime.toInstant()
server/services/src/main/java/com/doumee/dao/business/model/Category.java
@@ -26,7 +26,7 @@
    @ApiModelProperty(value = "是否已删除 0未删除 1已删除", example = "1")
    @ExcelColumn(name="是否已删除 0未删除 1已删除")
    private Byte deleted;
    private Integer deleted;
    @ApiModelProperty(value = "状态:0=启用;1=禁用;", example = "1")
    @ExcelColumn(name="状态:0=启用;1=禁用;")
server/services/src/main/java/com/doumee/dao/business/model/Member.java
@@ -118,6 +118,16 @@
    @ExcelColumn(name="评分")
    private BigDecimal score;
    @ApiModelProperty(value = "评分总数", example = "1")
    @ExcelColumn(name="评分总数")
    private BigDecimal totalScore;
    @ApiModelProperty(value = "被评价总订单数", example = "1")
    @ExcelColumn(name="被评价总订单数")
    private Integer scoreOrderNum;
    @ApiModelProperty(value = "定位地址")
    @ExcelColumn(name="定位地址")
    private String location;
server/services/src/main/java/com/doumee/dao/business/model/Multifile.java
@@ -52,7 +52,7 @@
//    @ApiModelProperty(value = "关联对象类型 0SHE上报 1跌绊滑上报 2跌绊滑处理 3跌绊滑分配物业主管 4跌绊滑分配处理人 5DCA风险上报 6DCA风险处理 7DCA工单图片", example = "1")
//    @ExcelExportColumn(name="关联对象类型 0SHE上报 1跌绊滑上报 2跌绊滑处理 3跌绊滑分配物业主管 4跌绊滑分配处理人 5DCA风险上报 6DCA风险处理 7DCA工单图片")
    @ApiModelProperty(value = "关联对象类型 0工单上报 1工单处理 2工单转交", example = "1")
    @ApiModelProperty(value = "关联对象类型 0身份申请资料 1订单附件", example = "1")
    private Integer objType;
    @ApiModelProperty(value = "文件地址")
server/services/src/main/java/com/doumee/dao/business/model/OrderLog.java
@@ -26,7 +26,7 @@
    @ApiModelProperty(value = "是否已删除 0未删除 1已删除", example = "1")
    @ExcelColumn(name="是否已删除 0未删除 1已删除")
    private Byte deleted;
    private Integer deleted;
    @ApiModelProperty(value = "创建人编码", example = "1")
    @ExcelColumn(name="创建人编码")
@@ -34,7 +34,6 @@
    @ApiModelProperty(value = "创建时间")
    @ExcelColumn(name="创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date createTime;
    @ApiModelProperty(value = "更新人编码", example = "1")
@@ -43,7 +42,6 @@
    @ApiModelProperty(value = "更新时间")
    @ExcelColumn(name="更新时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date updateTime;
    @ApiModelProperty(value = "备注")
@@ -82,4 +80,9 @@
    @ExcelColumn(name="订单状态:0=待接单;1=已接单;2=进行中;3=已完成;99=已取消;")
    private Integer orderStatus;
    @ApiModelProperty(value = "操作人类型:0=发单方;1=接单方;2=系统;", example = "1")
    @ExcelColumn(name="操作人类型:0=发单方;1=接单方;2=系统;")
    private Integer optUserType;
}
server/services/src/main/java/com/doumee/dao/business/model/Orders.java
@@ -2,6 +2,8 @@
import com.baomidou.mybatisplus.annotation.TableField;
import com.doumee.core.annotation.excel.ExcelColumn;
import com.doumee.dao.dto.CateringDTO;
import com.doumee.dao.dto.WayInfoDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import com.baomidou.mybatisplus.annotation.IdType;
@@ -29,7 +31,7 @@
    @ApiModelProperty(value = "是否已删除 0未删除 1已删除", example = "1")
    @ExcelColumn(name="是否已删除 0未删除 1已删除")
    private Byte deleted;
    private Integer deleted;
    @ApiModelProperty(value = "创建人编码", example = "1")
    @ExcelColumn(name="创建人编码")
@@ -107,12 +109,12 @@
    @ExcelColumn(name="用工类型:0=采摘工;1=分拣工;2=包装工;(用工订单)")
    private Integer workType;
    @ApiModelProperty(value = "计价数量1(天数/用车次数)", example = "1")
    @ExcelColumn(name="计价数量1(天数/用车次数)")
    @ApiModelProperty(value = "计价数量1(天数/用车次数/小时/斤数)", example = "1")
    @ExcelColumn(name="计价数量1(天数/用车次数/小时/斤数)")
    private Integer priceNum1;
    @ApiModelProperty(value = "计价数量2(用工数量/采摘数量/用车数量/)", example = "1")
    @ExcelColumn(name="计价数量2(用工数量/采摘数量/用车数量/)")
    @ApiModelProperty(value = "计价数量2(人数/用餐份数)", example = "1")
    @ExcelColumn(name="计价数量2(人数/用餐份数)")
    private Integer priceNum2;
    @ApiModelProperty(value = "需求补充")
@@ -135,12 +137,11 @@
    @ExcelColumn(name="实收费用")
    private Long receiveAccount;
    @ApiModelProperty(value = "费用说明")
    @ExcelColumn(name="费用说明")
    private String priceRemark;
//    @ApiModelProperty(value = "费用说明(弃用)")
//    private String priceRemark;
    @ApiModelProperty(value = "用车类型(运货使用):0=天;1=次", example = "1")
    @ExcelColumn(name="用车类型(运货使用):0=天;1=次")
    @ApiModelProperty(value = "用车类型(用工包装/运货使用):0=天;1=次/小时;2=重量", example = "1")
    @ExcelColumn(name="用车类型(用工包装/运货使用):0=天;1=次/小时;2=重量")
    private Integer carType;
    @ApiModelProperty(value = "运输品种(运货使用) å…³è”category表", example = "1")
@@ -175,9 +176,13 @@
    @ExcelColumn(name="订单编号")
    private String code;
    @ApiModelProperty(value = "订单状态:0=待接单;1=已接单;2=进行中;3=已完成;99=已取消;", example = "1")
    @ExcelColumn(name="订单状态:0=待接单;1=已接单;2=进行中;3=已完成;99=已取消;")
    @ApiModelProperty(value = "订单状态:0=待支付 1=待接单;2=已接单;3=进行中;4=已完成;99=已取消;", example = "1")
    @ExcelColumn(name="订单状态:0=待支付 1=待接单;2=已接单;3=进行中;4=已完成;99=已取消;")
    private Integer status;
    @ApiModelProperty(value = "支付状态:0=待支付 1=已支付", example = "1")
    @ExcelColumn(name="支付状态:0=待支付 1=已支付;")
    private Integer payStatus;
    @ApiModelProperty(value = "接单时间")
    @ExcelColumn(name="接单时间")
@@ -236,16 +241,40 @@
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date cancelTime;
    @ApiModelProperty(value = "是否已修改:0=否;1=是;", example = "1")
    @ExcelColumn(name="是否已修改:0=否;1=是;")
    @ApiModelProperty(value = "是否已修改:0=否;1=是;2=已确认;", example = "1")
    @ExcelColumn(name="是否已修改:0=否;1=是;2=已确认;")
    private Integer isUpdate;
    @ApiModelProperty(value = "接单方黑名单member:id å¤šä¸ªä»¥,分割")
    @ExcelColumn(name="接单方黑名单member:id å¤šä¸ªä»¥,分割")
    private String blackReceive;
    @ApiModelProperty
    @ApiModelProperty(value = "总天数", example = "1")
    @ExcelColumn(name="总天数")
    private Integer totalDays;
    @ApiModelProperty(value = "取消类型:0=发单方无责取消;1=发单方有责取消;2=系统取消;", example = "1")
    @ExcelColumn(name="取消类型:0=发单方无责取消;1=发单方有责取消;2=系统取消;")
    private Integer cancelType;
    @ApiModelProperty(value = "图片")
    @TableField(exist = false)
    private List<Multifile> multifileList;
    @ApiModelProperty(value = "途经点")
    @TableField(exist = false)
    private List<WayInfoDTO> wayInfoDTOList;
    @ApiModelProperty(value = "餐标")
    @TableField(exist = false)
    private List<CateringDTO> cateringDTOList;
    @ApiModelProperty(value = "移动端用户",hidden = true)
    @TableField(exist = false)
    private Member member;
}
server/services/src/main/java/com/doumee/dao/business/model/WithdrawalOrders.java
@@ -75,4 +75,12 @@
    @ExcelColumn(name="完成备注")
    private String doneInfo;
    @ApiModelProperty(value = "业务类型:0=提现;1=退款;", example = "1")
    @ExcelColumn(name="业务类型:0=提现;1=退款;")
    private Integer type;
    @ApiModelProperty(value = "关联订单主键 orders", example = "1")
    @ExcelColumn(name="关联订单主键 orders")
    private Integer objId;
}
server/services/src/main/java/com/doumee/dao/dto/CateringDTO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package com.doumee.dao.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import java.math.BigDecimal;
/**
 * Created by IntelliJ IDEA.
 *
 * @Author : Rk
 * @create 2023/3/23 9:50
 */
@Data
@ApiModel("餐饮标准信息")
public class CateringDTO {
    @ApiModelProperty(value = "类型:早餐、中餐、晚餐")
    private String name;
    @ApiModelProperty(value = "ä»·æ ¼ å•位:分")
    private Long price;
    @ApiModelProperty(value = "份数")
    private Integer num;
}
server/services/src/main/java/com/doumee/dao/dto/CommentDTO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,30 @@
package com.doumee.dao.dto;
import com.doumee.dao.business.model.Member;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * Created by IntelliJ IDEA.
 *
 * @Author : Rk
 * @create 2023/3/23 9:50
 */
@Data
@ApiModel("订单评价")
public class CommentDTO {
    @ApiModelProperty(value = "订单主键")
    private Integer orderId;
    @ApiModelProperty(value = "评价星级 1 - 5 ")
    private Long level;
    @ApiModelProperty(value = "评价内容")
    private String info;
    @ApiModelProperty(hidden = true)
    private Member member;
}
server/services/src/main/java/com/doumee/dao/dto/ConfirmUpdOrderDTO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package com.doumee.dao.dto;
import com.doumee.dao.business.model.Member;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
 * @author  dm
 * @since 2025/03/31 16:44
 */
@Data
@ApiModel("确认订单修改信息")
public class ConfirmUpdOrderDTO {
    @ApiModelProperty(value = "订单主键")
    private Integer orderId;
    @ApiModelProperty(value = "操作类型:0=同意;1=不同意;")
    private Integer status;
    @ApiModelProperty(hidden = true)
    private Member member;
}
server/services/src/main/java/com/doumee/dao/dto/DoneOrderDTO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
package com.doumee.dao.dto;
import com.doumee.dao.business.model.Member;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * Created by IntelliJ IDEA.
 *
 * @Author : Rk
 * @create 2023/3/23 9:50
 */
@Data
@ApiModel("完成订单")
public class DoneOrderDTO {
    @ApiModelProperty(value = "订单主键")
    private Integer orderId;
    @ApiModelProperty(value = "支付金额 å•位:分")
    private Long amount;
    @ApiModelProperty(hidden = true)
    private Member member;
}
server/services/src/main/java/com/doumee/dao/dto/UpdOrderDataDTO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
package com.doumee.dao.dto;
import com.doumee.dao.business.model.Member;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Date;
/**
 * @author  dm
 * @since 2025/03/31 16:44
 */
@Data
@ApiModel("修改订单日期")
public class UpdOrderDataDTO {
    @ApiModelProperty(value = "订单主键")
    private Integer orderId;
    @ApiModelProperty(value = "开始时间")
    private Date startDate;
    @ApiModelProperty(value = "结束时间")
    private Date endDate;
    @ApiModelProperty(value = "天数")
    private Integer totalDays;
    @ApiModelProperty(hidden = true)
    private Member member;
}
server/services/src/main/java/com/doumee/dao/dto/WayInfoDTO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,38 @@
package com.doumee.dao.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
 * Created by IntelliJ IDEA.
 *
 * @Author : Rk
 * @create 2023/3/23 9:50
 */
@Data
@ApiModel("途经点信息")
public class WayInfoDTO {
    @ApiModelProperty(value = "地点名称")
    private String location;
    @ApiModelProperty(value = "经度")
    private BigDecimal lat;
    @ApiModelProperty(value = "纬度")
    private BigDecimal lgt;
    @ApiModelProperty(value = "省")
    private String province;
    @ApiModelProperty(value = "市")
    private String city;
    @ApiModelProperty(value = "区县")
    private String area;
}
server/services/src/main/java/com/doumee/service/business/OrdersService.java
@@ -1,8 +1,15 @@
package com.doumee.service.business;
import com.doumee.core.model.LoginUserInfo;
import com.doumee.core.model.PageData;
import com.doumee.core.model.PageWrap;
import com.doumee.dao.business.model.Member;
import com.doumee.dao.business.model.Orders;
import com.doumee.dao.dto.CommentDTO;
import com.doumee.dao.dto.ConfirmUpdOrderDTO;
import com.doumee.dao.dto.DoneOrderDTO;
import com.doumee.dao.dto.UpdOrderDataDTO;
import java.util.List;
/**
@@ -18,7 +25,7 @@
     * @param orders å®žä½“对象
     * @return Integer
     */
    Integer create(Orders orders);
    Object create(Orders orders);
    /**
     * ä¸»é”®åˆ é™¤
@@ -94,4 +101,29 @@
     * @return long
     */
    long count(Orders orders);
    void accept(Integer orderId, Member member);
    void begin(Integer orderId,Member member);
    void updOrderData(UpdOrderDataDTO updOrderDataDTO);
    void confirmUpd(ConfirmUpdOrderDTO confirmUpdOrderDTO);
    void releaseCancelOrder(Integer orderId,Member member);
    void receiveCancelOrder(Integer orderId,Member member);
    Object doneOrder(DoneOrderDTO doneOrderDTO);
    void comment(CommentDTO commentDTO);
    /**
     * æ”¯ä»˜å›žè°ƒä¸šåŠ¡
     * @param preOrderId
     * @return
     */
    String payNotify(String preOrderId,String paymentNo);
    void platformCancel(Integer orderId, LoginUserInfo loginUserInfo);
}
server/services/src/main/java/com/doumee/service/business/impl/OrdersServiceImpl.java
@@ -1,26 +1,44 @@
package com.doumee.service.business.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.doumee.biz.system.SystemDictDataBiz;
import com.doumee.config.wx.WxMiniConfig;
import com.doumee.config.wx.WxMiniUtilService;
import com.doumee.core.constants.Constants;
import com.doumee.core.constants.ResponseStatus;
import com.doumee.core.exception.BusinessException;
import com.doumee.core.model.LoginUserInfo;
import com.doumee.core.model.PageData;
import com.doumee.core.model.PageWrap;
import com.doumee.core.utils.DateUtil;
import com.doumee.core.utils.Utils;
import com.doumee.dao.business.OrdersMapper;
import com.doumee.dao.business.model.Orders;
import com.doumee.dao.business.*;
import com.doumee.dao.business.model.*;
import com.doumee.dao.dto.*;
import com.doumee.service.business.OrdersService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Amount;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Payer;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.PrepayRequest;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.PrepayWithRequestPaymentResponse;
import jodd.util.StringUtil;
import org.apache.poi.sl.image.ImageHeaderEMF;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
/**
 * è®¢å•信息记录Service实现
@@ -33,13 +51,139 @@
    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private SystemDictDataBiz systemDictDataBiz;
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private MultifileMapper multifileMapper;
    @Autowired
    private OrderLogMapper orderLogMapper;
    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private MemberRevenueMapper memberRevenueMapper;
    @Autowired
    private WxMiniUtilService wxMiniUtilService;
    @Override
    public Integer create(Orders orders) {
    @Transactional(rollbackFor = {Exception.class,BusinessException.class})
    public Object create(Orders orders) {
        Object objects = null;
        this.initVerification(orders);
        orders.setCreateTime(new Date());
        orders.setPayStatus(Constants.ZERO);
        //TODO è®¢å•编号规则
        ordersMapper.insert(orders);
        return orders.getId();
        Category category = categoryMapper.selectOne(new QueryWrapper<Category>().lambda()
                .eq(Category::getDeleted,Constants.ZERO).eq(Category::getType,Constants.THREE)
                .eq(Category::getName,orders.getType())
                .last("limit 1")
        );
        if(Objects.isNull(category)){
            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(),"参数配置错误,请联系管理员");
    }
        //用餐订单
        if(Constants.equalsInteger(orders.getType(),Constants.TWO)){
            orders.setStatus(Constants.ZERO);
            //唤起支付业务
            objects = this.getWxPayResponse(orders,orders.getMember().getOpenid());
        }else{
            orders.setStatus(Constants.ONE);
        }
        ordersMapper.insert(orders);
        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(orders.getMultifileList())){
            List<Multifile> multifileList = orders.getMultifileList();
            for (Multifile multifile:multifileList) {
                if(Objects.isNull(multifile)
                || Objects.isNull(multifile.getObjType())
                || StringUtils.isEmpty(multifile.getFileurl())
                || StringUtils.isEmpty(multifile.getName())){
                    throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"附件信息错误");
                }
                multifile.setIsdeleted(Constants.ZERO);
                multifile.setCreateDate(new Date());
                multifile.setObjId(orders.getId());
                multifile.setObjType(Constants.ONE);
            }
            multifileMapper.insert(multifileList);
        }
        //更新用户发单量
        memberMapper.update(new UpdateWrapper<Member>().lambda().set(Member::getReceiveNum," (receive_num + 1 )").eq(Member::getId,orders.getMember().getId()));
        //创建操作日志
        Constants.OrdersLog ordersLog = Constants.OrdersLog.UPLOAD;
        String orderTypeInfo = "用工单";
        if(!Constants.equalsInteger(orders.getType(),Constants.ZERO)){
            orderTypeInfo =   Constants.equalsInteger(orders.getType(),Constants.ONE)?"用车单":"送餐单";
        }else{
            if(Constants.equalsInteger(orders.getWorkType(),Constants.ZERO)){
                orderTypeInfo = orderTypeInfo + "-采摘工";
            }else{
                orderTypeInfo = orderTypeInfo + (Constants.equalsInteger(orders.getWorkType(),Constants.ONE)?"-分拣工":"-包装工");
            }
        }
        String logInfo = ordersLog.getInfo()
                .replace("{param}",orderTypeInfo);
        this.saveOrderLog(orders,ordersLog,
                logInfo,orders.getReleaseMemberId(),null);
        return objects;
    }
    private Object getWxPayResponse(Orders orders,String openid){
        Object response = null;
        //调起支付
        PrepayRequest request = new PrepayRequest();
        request.setAttach("createOrder");
        request.setDescription("近快订单支付");
        request.setSpMchid(WxMiniConfig.wxProperties.getMchId());
        request.setSpAppid(WxMiniConfig.wxProperties.getAppId());
        request.setSubMchid(WxMiniConfig.wxProperties.getSubMchId());
        request.setSubAppid(WxMiniConfig.wxProperties.getSubAppId());
        Payer payer = new Payer();
        payer.setSubOpenid(openid);
        request.setPayer(payer);
        request.setOutTradeNo(orders.getCode());
        request.setNotifyUrl(WxMiniConfig.wxProperties.getNotifyUrl());//这个回调url必须是https开头的
        Amount amount = new Amount();
        amount.setTotal(orders.getEstimatedAccount().intValue());
        request.setAmount(amount);
//        PrepayResponse res = WxMiniConfig.wxPayService.prepay(request);
        // è·Ÿä¹‹å‰ä¸‹å•示例一样,填充预下单参数
        PrepayWithRequestPaymentResponse resParam =  WxMiniConfig.jsapiExtService.prepayWithRequestPayment(request,WxMiniConfig.wxProperties.getSubAppId());
        response =resParam;
        return response;
    }
    /**
     * æ—¥å¿—信息
     * @param orders è®¢å•信息
     * @param ordersLog è®¢å•支持分类
     * @param logInfo æ—¥å¿—内容
     * @param memberId ç§»åŠ¨ç«¯æ“ä½œäºº
     * @param userId ç³»ç»Ÿæ“ä½œäºº
     */
    public void saveOrderLog(Orders orders,Constants.OrdersLog ordersLog,String logInfo,Integer memberId,Integer userId){
        OrderLog orderLog = new OrderLog();
        orderLog.setCreateTime(orders.getUpdateTime());
        orderLog.setDeleted(Constants.ZERO);
        orderLog.setOrderId(orders.getId());
        orderLog.setTitle(ordersLog.getName());
        orderLog.setLogInfo(logInfo);
        orderLog.setObjType(ordersLog.getKey());
        orderLog.setOrderStatus(orders.getStatus());
        orderLog.setMemberId(memberId);
        orderLog.setCreateUser(userId);
        orderLog.setOptUserType(ordersLog.getUserType());
        orderLogMapper.insert(orderLog);
    }
@@ -53,22 +197,78 @@
                || Objects.isNull(orders.getLat())
                || Objects.isNull(orders.getLgt())
                || Objects.isNull(orders.getCategoryId())
                || Objects.isNull(orders.getTotalDays())
                || (Constants.equalsInteger(orders.getType(),Constants.ZERO) && Objects.isNull(orders.getWorkType()))
                || Objects.isNull(orders.getPriceNum1())
                || (!( Constants.equalsInteger(orders.getType(),Constants.ZERO)
                && Constants.equalsInteger(orders.getWorkType(),Constants.TWO) ) && Objects.isNull(orders.getPrice()) )
                || ( Constants.equalsInteger(orders.getType(),Constants.ONE) && Objects.isNull(orders.getTransportTypeId()) )
                || Objects.isNull(orders.getEstimatedAccount())
                || Objects.isNull(orders.getPrice())
        ){
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        if(Constants.equalsInteger(orders.getType(),Constants.ONE)){
        if((Constants.equalsInteger(orders.getType(),Constants.ZERO) && Constants.equalsInteger(orders.getWorkType(),Constants.ZERO ))
                || (Constants.equalsInteger(orders.getType(),Constants.ZERO) && Constants.equalsInteger(orders.getWorkType(),Constants.TWO)
                        &&Constants.equalsInteger(orders.getCarType(),Constants.TWO))
                || Constants.equalsInteger(orders.getType(),Constants.ONE)
        ){
            orders.setPriceNum2(Constants.ONE);
        }
        if(Objects.isNull(orders.getPriceNum2())){
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        if(Constants.equalsInteger(orders.getType(),Constants.ZERO)){
            if(Constants.equalsInteger(orders.getWorkType(),Constants.TWO)
            && Objects.isNull(orders.getCarType())){
                throw new BusinessException(ResponseStatus.BAD_REQUEST);
            }
        }else if(Constants.equalsInteger(orders.getType(),Constants.ONE)){
            if(Objects.isNull(orders.getTransportTypeId())
                    || Objects.isNull(orders.getCarType())
                    || Objects.isNull(orders.getTransportNum())
                    || StringUtils.isEmpty(orders.getTransportUnit())
                    || StringUtils.isEmpty(orders.getLocationEnd())
                    || Objects.isNull(orders.getLatEnd())
                    || Objects.isNull(orders.getLgtEnd())
                    || CollectionUtils.isEmpty(orders.getWayInfoDTOList())
            ){
                throw new BusinessException(ResponseStatus.BAD_REQUEST);
            }
            for (WayInfoDTO wayInfoDTO:orders.getWayInfoDTOList()) {
                if(Objects.isNull(wayInfoDTO)
                        ||StringUtils.isEmpty(wayInfoDTO.getLocation())
                        ||StringUtils.isEmpty(wayInfoDTO.getProvince())
                        ||StringUtils.isEmpty(wayInfoDTO.getCity())
                        ||StringUtils.isEmpty(wayInfoDTO.getArea())
                        ||Objects.isNull(wayInfoDTO.getLat())
                        ||Objects.isNull(wayInfoDTO.getLgt())
                ){
                    throw new BusinessException(ResponseStatus.BAD_REQUEST);
                }
            }
            orders.setWayInfo(JSONObject.toJSONString(orders.getWayInfoDTOList()));
        }else{
            //用餐订单
            if(CollectionUtils.isEmpty(orders.getCateringDTOList())){
                throw new BusinessException(ResponseStatus.BAD_REQUEST);
            }
            Long sumPrice = 0L;
            for (CateringDTO cateringDTO:orders.getCateringDTOList()) {
                if(Objects.isNull(cateringDTO)
                        || StringUtils.isEmpty(cateringDTO.getName())
                        || Objects.isNull(cateringDTO.getPrice())
                        || Objects.isNull(cateringDTO.getNum())
                ){
                    throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"用餐标准数据错误");
                }
                sumPrice = sumPrice + (cateringDTO.getPrice() * cateringDTO.getNum()) ;
            }
            if(!sumPrice.equals(orders.getPrice())){
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"单价计算错误");
            }
            orders.setWayInfo(JSONObject.toJSONString(orders.getCateringDTOList()));
        }
        if(!orders.getEstimatedAccount().equals(this.getTotal(orders))){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"金额计算错误!");
        }
    }
@@ -94,7 +294,47 @@
    }
    @Override
    @Transactional(rollbackFor = {BusinessException.class,Exception.class})
    public void updateById(Orders orders) {
        if(Objects.isNull(orders)
        || Objects.isNull(orders.getId())){
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        Orders model = ordersMapper.selectById(orders.getId());
        if(Constants.equalsInteger(model.getType(),Constants.TWO)){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"此类订单无法进行修改");
        }
        if(!Constants.equalsInteger(model.getStatus(),Constants.ONE)){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"订单状态已流转,无法进行该操作");
        }
        this.initVerification(orders);
        orders.setUpdateTime(new Date());
        Category category = categoryMapper.selectOne(new QueryWrapper<Category>().lambda()
                .eq(Category::getDeleted,Constants.ZERO).eq(Category::getType,Constants.THREE)
                .eq(Category::getName,orders.getType())
                .last("limit 1")
        );
        if(Objects.isNull(category)){
            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(),"参数配置错误,请联系管理员");
        }
        multifileMapper.update(new UpdateWrapper<Multifile>().lambda().set(Multifile::getIsdeleted,Constants.ONE).eq(Multifile::getObjType,Constants.ONE)
                .eq(Multifile::getObjId,orders.getId()));
        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(orders.getMultifileList())){
            List<Multifile> multifileList = orders.getMultifileList();
            for (Multifile multifile:multifileList) {
                if(Objects.isNull(multifile)
                        || Objects.isNull(multifile.getObjType())
                        || StringUtils.isEmpty(multifile.getFileurl())
                        || StringUtils.isEmpty(multifile.getName())){
                    throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"附件信息错误");
                }
                multifile.setIsdeleted(Constants.ZERO);
                multifile.setCreateDate(new Date());
                multifile.setObjId(orders.getId());
                multifile.setObjType(Constants.ONE);
            }
            multifileMapper.insert(multifileList);
        }
        ordersMapper.updateById(orders);
    }
@@ -212,9 +452,6 @@
        if (pageWrap.getModel().getPayAccount() != null) {
            queryWrapper.lambda().eq(Orders::getPayAccount, pageWrap.getModel().getPayAccount());
        }
        if (pageWrap.getModel().getPriceRemark() != null) {
            queryWrapper.lambda().eq(Orders::getPriceRemark, pageWrap.getModel().getPriceRemark());
        }
        if (pageWrap.getModel().getCarType() != null) {
            queryWrapper.lambda().eq(Orders::getCarType, pageWrap.getModel().getCarType());
        }
@@ -307,4 +544,593 @@
        QueryWrapper<Orders> wrapper = new QueryWrapper<>(orders);
        return ordersMapper.selectCount(wrapper);
    }
    /**
     * æ‰‹åŠ¨æŽ¥å•
     * @param orderId
     */
    @Override
    @Transactional(rollbackFor = {BusinessException.class,Exception.class})
    public void accept(Integer orderId,Member member){
        Orders orders = ordersMapper.selectById(orderId);
        if(Objects.isNull(orders)||Constants.equalsInteger(orders.getDeleted(),Constants.ONE)){
            throw new BusinessException(ResponseStatus.DATA_EMPTY);
        }
        if(!Constants.equalsInteger(orders.getStatus(),Constants.ONE)){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"订单状态已流转,无法进行该操作");
        }
        if(Constants.equalsInteger(orders.getReleaseMemberId(),member.getId())){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"您自己的订单无法进行该操作");
        }
        //查询用户是否有对应身份
        if(Constants.equalsInteger(orders.getType(),Constants.ZERO)){
            if(!Constants.equalsInteger(member.getWorkerIdentity(),Constants.TWO)){
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"身份信息异常,请联系管理员");
            }
        }else if(Constants.equalsInteger(orders.getType(),Constants.ONE)){
            if(!Constants.equalsInteger(member.getDriverIdentity(),Constants.TWO)){
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"身份信息异常,请联系管理员");
            }
        }else{
            if(!Constants.equalsInteger(member.getChefIdentity(),Constants.TWO)){
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"身份信息异常,请联系管理员");
            }
        }
        orders.setUpdateTime(new Date());
        orders.setAcceptType(Constants.ZERO);
        orders.setAcceptTime(new Date());
        orders.setAcceptMemberId(member.getId());
        orders.setStatus(Constants.TWO);
        ordersMapper.updateById(orders);
        //更新接单量
        memberMapper.update(new UpdateWrapper<Member>().lambda().set(Member::getPublishNum," (publish_num + 1 )").eq(Member::getId,member.getId()));
        //创建操作日志
        Constants.OrdersLog ordersLog = Constants.OrdersLog.RECEIVE;
        this.saveOrderLog(orders,ordersLog,
                ordersLog.getInfo(),member.getId(),null);
        //TODO å¾®ä¿¡å…¬ä¼—号提醒 å·²æŽ¥å•提醒
    }
    /**
     * å¼€å§‹ä½œä¸š
     * @param orderId
     * @param member
     */
    @Override
    @Transactional(rollbackFor = {BusinessException.class,Exception.class})
    public void begin(Integer orderId,Member member){
        Orders orders = ordersMapper.selectById(orderId);
        if(Objects.isNull(orders)||Constants.equalsInteger(orders.getDeleted(),Constants.ONE)){
            throw new BusinessException(ResponseStatus.DATA_EMPTY);
        }
        if(!Constants.equalsInteger(orders.getStatus(),Constants.TWO)){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"订单状态已流转,无法进行该操作");
        }
        if(Constants.equalsInteger(orders.getReleaseMemberId(),member.getId())){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"非您的订单无法进行该操作");
        }
        if(Constants.equalsInteger(orders.getIsUpdate(),Constants.ONE)){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"订单修改待确认,无法进行该操作");
        }
        orders.setUpdateTime(new Date());
        orders.setStatus(Constants.THREE);
        orders.setWorkStartTime(new Date());
        ordersMapper.updateById(orders);
        //创建操作日志
        Constants.OrdersLog ordersLog = Constants.OrdersLog.BEGIN;
        this.saveOrderLog(orders,ordersLog,
                ordersLog.getInfo(),member.getId(),null);
    }
    /**
     * å‘单方修改订单 - å·²æŽ¥å•状态
     * @param updOrderDataDTO
     */
    @Override
    @Transactional(rollbackFor = {BusinessException.class,Exception.class})
    public void updOrderData(UpdOrderDataDTO updOrderDataDTO){
        if(Objects.isNull(updOrderDataDTO)
            || Objects.isNull(updOrderDataDTO.getOrderId())
            || Objects.isNull(updOrderDataDTO.getStartDate())
            || Objects.isNull(updOrderDataDTO.getEndDate())
            || Objects.isNull(updOrderDataDTO.getTotalDays())){
            throw new BusinessException(ResponseStatus.DATA_EMPTY);
        }
        Orders orders = ordersMapper.selectById(updOrderDataDTO.getOrderId());
        if(Objects.isNull(orders)||Constants.equalsInteger(orders.getDeleted(),Constants.ONE)){
            throw new BusinessException(ResponseStatus.DATA_EMPTY);
        }
        if(!Constants.equalsInteger(orders.getStatus(),Constants.TWO)){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"订单状态已流转,无法进行该操作");
        }
        if(Constants.equalsInteger(orders.getReleaseMemberId(),updOrderDataDTO.getMember().getId())){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"非您的订单无法进行该操作");
        }
        if(Constants.equalsInteger(orders.getIsUpdate(),Constants.ONE)){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"订单已修改,待接单方确认,无法进行该操作");
        }
        orders.setStartDate(updOrderDataDTO.getStartDate());
        orders.setEndDate(updOrderDataDTO.getEndDate());
        orders.setTotalDays(updOrderDataDTO.getTotalDays());
        //用车类型
        if(Constants.equalsInteger(orders.getType(),Constants.ONE)){
            if(Constants.equalsInteger(orders.getCarType(),Constants.ZERO)) {
                orders.setPriceNum1(updOrderDataDTO.getTotalDays());
            }
        }else if(Constants.equalsInteger(orders.getType(),Constants.ZERO)){
            if(Constants.equalsInteger(orders.getWorkType(),Constants.ONE)||(Constants.equalsInteger(orders.getWorkType(),Constants.TWO)&&Constants.equalsInteger(orders.getCarType(),Constants.ZERO))){
                orders.setPriceNum1(updOrderDataDTO.getTotalDays());
            }
        }else{
            orders.setPriceNum1(updOrderDataDTO.getTotalDays());
        }
        Long total = this.getTotal(orders);
        ordersMapper.update(new UpdateWrapper<Orders>().lambda()
                .set(Orders::getStartDate,updOrderDataDTO.getStartDate())
                .set(Orders::getEndDate,updOrderDataDTO.getEndDate())
                .set(Orders::getTotalDays,updOrderDataDTO.getTotalDays())
                .set(Orders::getIsUpdate,Constants.ONE)
                .set(Orders::getUpdateTime,"now()")
                .set(Orders::getEstimatedAccount,total)
                .eq(Orders::getId,orders.getId())
        );
        //创建操作日志
        Constants.OrdersLog ordersLog = Constants.OrdersLog.UPD_ORDER;
        this.saveOrderLog(orders,ordersLog,
                ordersLog.getInfo(),updOrderDataDTO.getMember().getId(),null);
        //TODO é€šçŸ¥æŽ¥å•人 è®¢å•发生变更
    }
    public Long getTotal(Orders orders){
        if(
            (Constants.equalsInteger(orders.getType(),Constants.ZERO) && Constants.equalsInteger(orders.getWorkType(),Constants.ZERO )) ||
                    (Constants.equalsInteger(orders.getType(),Constants.ZERO) && Constants.equalsInteger(orders.getWorkType(),Constants.TWO)
                            &&Constants.equalsInteger(orders.getCarType(),Constants.TWO))
            || Constants.equalsInteger(orders.getType(),Constants.ONE)
        ){
            orders.setPriceNum2(Constants.ONE);
        }
        return orders.getPrice() * orders.getPriceNum1() * orders.getPriceNum2();
    }
    /**
     * æŽ¥å•方处理订单修改
     * @param confirmUpdOrderDTO
     */
    @Override
    @Transactional(rollbackFor = {BusinessException.class,Exception.class})
    public void confirmUpd(ConfirmUpdOrderDTO confirmUpdOrderDTO){
        if(Objects.isNull(confirmUpdOrderDTO)
                || Objects.isNull(confirmUpdOrderDTO.getOrderId())
                || Objects.isNull(confirmUpdOrderDTO.getStatus())
                || !(Constants.equalsInteger(confirmUpdOrderDTO.getStatus(),Constants.ONE)||
                Constants.equalsInteger(confirmUpdOrderDTO.getStatus(),Constants.ZERO))
        ){
            throw new BusinessException(ResponseStatus.DATA_EMPTY);
        }
        Orders orders = ordersMapper.selectById(confirmUpdOrderDTO.getOrderId());
        if(Objects.isNull(orders)||Constants.equalsInteger(orders.getDeleted(),Constants.ONE)){
            throw new BusinessException(ResponseStatus.DATA_EMPTY);
        }
        if(!Constants.equalsInteger(orders.getStatus(),Constants.TWO)){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"订单状态已流转,无法进行该操作");
        }
        if(!Constants.equalsInteger(orders.getIsUpdate(),Constants.ONE)){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"订单修改状态已流转,无法进行该操作");
        }
        if(Constants.equalsInteger(orders.getAcceptMemberId(),confirmUpdOrderDTO.getMember().getId())){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"非您的订单无法进行该操作");
        }
        if( Constants.equalsInteger(confirmUpdOrderDTO.getStatus(),Constants.ONE)){
            ordersMapper.update(new UpdateWrapper<Orders>().lambda()
                    .set(Orders::getIsUpdate,Constants.TWO)
                    .set(Orders::getUpdateTime,"now()")
                    .eq(Orders::getId,orders.getId())
            );
            //记录同意修改的日志
            Constants.OrdersLog ordersLog = Constants.OrdersLog.UPD_AGREE;
            this.saveOrderLog(orders,ordersLog,
                    ordersLog.getInfo(),confirmUpdOrderDTO.getMember().getId(),null);
        }else{
            ordersMapper.update(new UpdateWrapper<Orders>().lambda()
                    .set(Orders::getIsUpdate,Constants.TWO)
                    .set(Orders::getUpdateTime,"now()")
                    .set(Orders::getStatus,Constants.ONE)
                    .set(Orders::getAcceptMemberId,null)
                    .set(Orders::getAcceptType,null)
                    .eq(Orders::getId,orders.getId())
            );
            memberMapper.update(new UpdateWrapper<Member>().lambda().set(Member::getReceiveNum,"receive_num - 1").eq(Member::getId,confirmUpdOrderDTO.getMember().getId()));
            //记录不同意修改的日志
            Constants.OrdersLog ordersLog = Constants.OrdersLog.UPD_DISAGREE;
            this.saveOrderLog(orders,ordersLog,
                    ordersLog.getInfo(),confirmUpdOrderDTO.getMember().getId(),null);
            //TODO å‘送不同意变更通知
        }
    }
    /**
     * å‘单方取消订单
     * @param orderId
     * @param member
     */
    @Override
    @Transactional(rollbackFor = {BusinessException.class,Exception.class})
    public void releaseCancelOrder(Integer orderId,Member member){
        Orders orders = ordersMapper.selectById(orderId);
        if(Objects.isNull(orders)||Constants.equalsInteger(orders.getDeleted(),Constants.ONE)){
            throw new BusinessException(ResponseStatus.DATA_EMPTY);
        }
        if(!(Constants.equalsInteger(orders.getStatus(),Constants.ONE)
                ||Constants.equalsInteger(orders.getStatus(),Constants.ZERO)
        || Constants.equalsInteger(orders.getStatus(),Constants.TWO))){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"订单状态已流转,无法进行取消");
        }
        if(Constants.equalsInteger(orders.getReleaseMemberId(),member.getId())){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"非您的订单无法进行该操作");
        }
        //待支付用餐订单/待接单订单进行取消
        if(Constants.equalsInteger(orders.getStatus(),Constants.ONE)
                ||Constants.equalsInteger(orders.getStatus(),Constants.ZERO)){
            if(Constants.equalsInteger(orders.getType(),Constants.TWO)&&Constants.equalsInteger(orders.getStatus(),Constants.ONE)){
                //退款业务
                WithdrawalOrders  withdrawalOrders = new WithdrawalOrders();
                withdrawalOrders.setCreateTime(new Date());
                withdrawalOrders.setMemberId(orders.getReleaseMemberId());
                withdrawalOrders.setAmount(orders.getPayAccount());
                withdrawalOrders.setWxExternalNo("refund_"+orders.getCode());
                withdrawalOrders.setStatus(Constants.ONE);
                withdrawalOrders.setDoneTime(new Date());
                withdrawalOrders.setType(Constants.ONE);
                withdrawalOrders.setObjId(orders.getId());
                wxMiniUtilService.wxRefund(withdrawalOrders,orders);
            }
            ordersMapper.update(new UpdateWrapper<Orders>().lambda()
                    .set(Orders::getStatus,99)
                    .set(Orders::getUpdateTime,"now()")
                    .set(Orders::getCancelTime,"now()")
                    .set(Orders::getCancelType,Constants.ZERO)
                    .eq(Orders::getId,orders.getId())
            );
        }else{
            //判断是否可修改 å·²å–消次数 ä¸Ž æ—¶é—´é™åˆ¶
            Integer totalCancelTimes = Integer.valueOf(systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.RELEASE_CANCEL_TIMES).getCode());
            Long cancelTimes = ordersMapper.selectCount(new QueryWrapper<Orders>().lambda()
                    .apply(" DATE(cancel_time) = DATE(NOW()) ")
                    .eq(Orders::getStatus,99)
                    .eq(Orders::getReleaseMemberId,orders.getReleaseMemberId()));
            //查询取消次数
            if(totalCancelTimes<=cancelTimes){
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"今日订单主动取消次数已超出"+totalCancelTimes+"次,无法取消订单,如需处理请联系客服");
            }
            Integer cancelTimeHour = Integer.valueOf(systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.RELEASE_CANCEL_TIME).getCode());
            Long hours = DateUtil.getBetweenHours(new Date(),orders.getStartDate());
            if(hours < cancelTimeHour){
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"距离订单开始时间不足"+cancelTimeHour+"小时,无法取消订单,如需处理请联系客服");
            }
            if(Constants.equalsInteger(orders.getType(),Constants.TWO)){
                //退款业务
                WithdrawalOrders  withdrawalOrders = new WithdrawalOrders();
                withdrawalOrders.setCreateTime(new Date());
                withdrawalOrders.setMemberId(orders.getReleaseMemberId());
                withdrawalOrders.setAmount(orders.getPayAccount());
                withdrawalOrders.setWxExternalNo("refund_"+orders.getCode());
                withdrawalOrders.setStatus(Constants.ONE);
                withdrawalOrders.setDoneTime(new Date());
                withdrawalOrders.setType(Constants.ONE);
                withdrawalOrders.setObjId(orders.getId());
                wxMiniUtilService.wxRefund(withdrawalOrders,orders);
            }
            ordersMapper.update(new UpdateWrapper<Orders>().lambda()
                    .set(Orders::getStatus,99)
                    .set(Orders::getUpdateTime,"now()")
                    .set(Orders::getCancelTime,"now()")
                    .set(Orders::getCancelType,Constants.ONE)
                    .eq(Orders::getId,orders.getId())
            );
            //TODO å‘单方取消订单通知接单方
            //减少接单量
            memberMapper.update(new UpdateWrapper<Member>().lambda().set(Member::getReceiveNum,"receive_num - 1").eq(Member::getId,orders.getAcceptMemberId()));
        }
        //减少发单量
        memberMapper.update(new UpdateWrapper<Member>().lambda().set(Member::getPublishNum,"publish_num - 1").eq(Member::getId,orders.getReleaseMemberId()));
        //日志存储
        Constants.OrdersLog ordersLog = Constants.OrdersLog.RELEASE_CANCEL;
        this.saveOrderLog(orders,ordersLog,
                ordersLog.getInfo(),member.getId(),null);
    }
    /**
     * æŽ¥å•方取消接单
     * @param orderId
     * @param member
     */
    @Override
    @Transactional(rollbackFor = {BusinessException.class,Exception.class})
    public void receiveCancelOrder(Integer orderId,Member member){
        Orders orders = ordersMapper.selectById(orderId);
        if(Objects.isNull(orders)||Constants.equalsInteger(orders.getDeleted(),Constants.ONE)){
            throw new BusinessException(ResponseStatus.DATA_EMPTY);
        }
        if(!Constants.equalsInteger(orders.getStatus(),Constants.TWO)){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"订单状态已流转,无法进行取消");
        }
        if(Constants.equalsInteger(orders.getAcceptMemberId(),member.getId())){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"非您的订单无法进行该操作");
        }
        //判断是否可修改 å·²å–消次数 ä¸Ž æ—¶é—´é™åˆ¶
        Integer totalCancelTimes = Integer.valueOf(systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.RECEIVE_CANCEL_TIMES).getCode());
        Long cancelTimes = orderLogMapper.selectCount(new QueryWrapper<OrderLog>().lambda()
                .apply(" DATE(create_time) = DATE(NOW()) ")
                .eq(OrderLog::getObjType,Constants.OrdersLog.CANCEL.getKey())
                .eq(OrderLog::getMemberId,member.getId()));
        //查询取消次数
        if(totalCancelTimes<=cancelTimes){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"今日订单主动取消次数已超出"+totalCancelTimes+"次,无法取消订单,如需处理请联系客服");
        }
        Integer cancelTimeHour = Integer.valueOf(systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.RECEIVE_CANCEL_TIME).getCode());
        Long hours = DateUtil.getBetweenHours(new Date(),orders.getStartDate());
        if(hours < cancelTimeHour){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"距离订单开始时间不足"+cancelTimeHour+"小时,无法取消订单,如需处理请联系客服");
        }
        ordersMapper.update(new UpdateWrapper<Orders>().lambda()
                .set(Orders::getUpdateTime,"now()")
                .set(Orders::getStatus,Constants.ONE)
                .set(Orders::getAcceptMemberId,null)
                .set(Orders::getAcceptType,null)
                .eq(Orders::getId,orders.getId())
        );
        //减少接单量
        memberMapper.update(new UpdateWrapper<Member>().lambda().set(Member::getReceiveNum,"receive_num - 1").eq(Member::getId,orders.getAcceptMemberId()));
        //日志存储
        Constants.OrdersLog ordersLog = Constants.OrdersLog.CANCEL;
        this.saveOrderLog(orders,ordersLog,
                ordersLog.getInfo(),member.getId(),null);
        //TODO æŽ¥å•方取消订单通知
    }
    /**
     * å®Œæˆè®¢å•
     * @param doneOrderDTO
     */
    @Override
    @Transactional(rollbackFor = {BusinessException.class,Exception.class})
    public Object doneOrder(DoneOrderDTO doneOrderDTO){
        if(Objects.isNull(doneOrderDTO)||Objects.isNull(doneOrderDTO.getOrderId())){
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        Orders orders = ordersMapper.selectById(doneOrderDTO.getOrderId());
        if(!Constants.equalsInteger(orders.getType(),Constants.TWO)&&Objects.isNull(doneOrderDTO.getAmount())){
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        if(Objects.isNull(orders)||Constants.equalsInteger(orders.getDeleted(),Constants.ONE)){
            throw new BusinessException(ResponseStatus.DATA_EMPTY);
        }
        if(!Constants.equalsInteger(orders.getStatus(),Constants.THREE)){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"订单状态已流转,无法进行取消");
        }
        if(Constants.equalsInteger(orders.getReleaseMemberId(),doneOrderDTO.getMember().getId())){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"非您的订单无法进行该操作");
        }
        Object object = null;
        //用餐订单
        if(!Constants.equalsInteger(orders.getType(),Constants.TWO)){
            orders.setPayAccount(doneOrderDTO.getAmount());
            //提成金额
            Long tcje = Long.valueOf(new BigDecimal(orders.getPayAccount().toString()).multiply(orders.getPlatformRata()).intValue());
            orders.setReceiveAccount(orders.getPayAccount() - tcje);
            ordersMapper.updateById(orders);
            //唤起支付业务
            object = this.getWxPayResponse(orders,orders.getMember().getOpenid());
        }else{
            orders.setStatus(Constants.FOUR);
            //日志存储
            Constants.OrdersLog ordersLog = Constants.OrdersLog.DONE;
            this.saveOrderLog(orders,ordersLog,
                    ordersLog.getInfo(),doneOrderDTO.getMember().getId(),null);
        }
        return object;
    }
    @Override
    @Transactional(rollbackFor = {BusinessException.class,Exception.class})
    public void platformCancel(Integer orderId, LoginUserInfo loginUserInfo){
        Orders orders = ordersMapper.selectById(orderId);
        if(Objects.isNull(orders)||Constants.equalsInteger(orders.getDeleted(),Constants.ONE)){
            throw new BusinessException(ResponseStatus.DATA_EMPTY);
        }
        if(!(Constants.equalsInteger(orders.getStatus(),Constants.ONE)||Constants.equalsInteger(orders.getStatus(),Constants.TWO)
            ||Constants.equalsInteger(orders.getStatus(),Constants.THREE))){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"订单状态已流转,无法进行取消");
        }
        //如果已支付 åˆ™éœ€è¦è¿›è¡Œé€€æ¬¾
        if(Constants.equalsInteger(orders.getPayStatus(),Constants.ONE)){
            WithdrawalOrders  withdrawalOrders = new WithdrawalOrders();
            withdrawalOrders.setCreateTime(new Date());
            withdrawalOrders.setMemberId(orders.getReleaseMemberId());
            withdrawalOrders.setAmount(orders.getPayAccount());
            withdrawalOrders.setWxExternalNo("refund_"+orders.getCode());
            withdrawalOrders.setStatus(Constants.ONE);
            withdrawalOrders.setDoneTime(new Date());
            withdrawalOrders.setType(Constants.ONE);
            withdrawalOrders.setObjId(orders.getId());
            wxMiniUtilService.wxRefund(withdrawalOrders,orders);
        }
        //减少发单量
        memberMapper.update(new UpdateWrapper<Member>().lambda().set(Member::getPublishNum,"publish_num - 1").eq(Member::getId,orders.getReleaseMemberId()));
        if(Constants.equalsInteger(orders.getStatus(),Constants.TWO)||Constants.equalsInteger(orders.getStatus(),Constants.THREE)){
            //减少接单量
            memberMapper.update(new UpdateWrapper<Member>().lambda().set(Member::getReceiveNum,"receive_num - 1").eq(Member::getId,orders.getAcceptMemberId()));
        }
        ordersMapper.update(new UpdateWrapper<Orders>().lambda()
                .set(Orders::getStatus,99)
                .set(Orders::getUpdateTime,"now()")
                .set(Orders::getCancelTime,"now()")
                .set(Orders::getCancelType,Constants.TWO)
                .eq(Orders::getId,orders.getId())
        );
        //日志存储
        Constants.OrdersLog ordersLog = Constants.OrdersLog.SYSTEM_CANCEL;
        this.saveOrderLog(orders,ordersLog,
                ordersLog.getInfo(),null,loginUserInfo.getId());
    }
    @Override
    public void comment(CommentDTO commentDTO){
        if(Objects.isNull(commentDTO)
        || Objects.isNull(commentDTO.getOrderId())
        || Objects.isNull(commentDTO.getLevel())
        || commentDTO.getLevel()<1 || commentDTO.getLevel() > 5 ){
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        Orders orders = ordersMapper.selectById(commentDTO.getOrderId());
        if(Objects.isNull(orders)
                ||Constants.equalsInteger(orders.getDeleted(),Constants.ONE)){
            throw new BusinessException(ResponseStatus.DATA_EMPTY);
        }
        if(!Constants.equalsInteger(orders.getStatus(),Constants.FOUR)){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"订单状态已流转,无法进行评价");
        }
        if(Constants.equalsInteger(orders.getCommentStatus(),Constants.ONE)){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"订单已评价!");
        }
        ordersMapper.update(new UpdateWrapper<Orders>().lambda()
                .set(Orders::getCommentStatus,Constants.ONE)
                .set(Orders::getUpdateTime,"now()")
                .set(Orders::getCommentTime,"now()")
                .set(Orders::getCommentLevel,commentDTO.getLevel())
                .set(Orders::getCommentType,Constants.ZERO)
                .eq(Orders::getId,orders.getId())
        );
        memberMapper.update(new UpdateWrapper<Member>().lambda()
                .set(Member::getScore," ( total_score +" + commentDTO.getLevel() + " ) / (score_order_num + 1 )")
                .set(Member::getTotalScore," total_score +" + commentDTO.getLevel())
                .set(Member::getScoreOrderNum," score_order_num + 1 " ).eq(Member::getId,orders.getAcceptMemberId())
        );
        //日志存储
        Constants.OrdersLog ordersLog = Constants.OrdersLog.COMMENT;
        this.saveOrderLog(orders,ordersLog,
                ordersLog.getInfo(),orders.getAcceptMemberId(),null);
    }
    /**
     * æ”¯ä»˜å›žè°ƒ
     * @param preOrderId
     * @param paymentNo
     * @return
     */
    @Override
    @Transactional(rollbackFor = {BusinessException.class,Exception.class})
    public String payNotify(String preOrderId,String paymentNo){
        Orders orders = ordersMapper.selectOne(new QueryWrapper<Orders>().lambda().eq(Orders::getCode,preOrderId).last("limit 1"));
        if(Constants.equalsInteger(orders.getType(),Constants.TWO)){
            //用餐订单  å¦‚果已经流转到已支付  åˆ™ç›´æŽ¥è¿”回
            if(!Constants.equalsInteger(orders.getStatus(),Constants.ZERO)){
                return  ("处理成功!");
            }else{
                //处理支付完成逻辑
                ordersMapper.update(new UpdateWrapper<Orders>().lambda()
                        .set(Orders::getUpdateTime,"now()")
                        .set(Orders::getStatus,Constants.ONE)
                        .set(Orders::getPayStatus,Constants.ONE)
                        .set(Orders::getWxExternalNo,paymentNo)
                        .eq(Orders::getId,orders.getId())
                );
                //存储日志
                Constants.OrdersLog ordersLog = Constants.OrdersLog.PAY;
                this.saveOrderLog(orders,ordersLog,
                        ordersLog.getInfo(),orders.getReleaseMemberId(),null);
            }
        }else{
            //非用餐类订单
            if(!Constants.equalsInteger(orders.getStatus(),Constants.THREE)){
                return  ("处理成功!");
            }else{
                //处理支付完成逻辑
                ordersMapper.update(new UpdateWrapper<Orders>().lambda()
                        .set(Orders::getUpdateTime,"now()")
                        .set(Orders::getStatus,Constants.FOUR)
                        .set(Orders::getPayStatus,Constants.ONE)
                        .set(Orders::getWxExternalNo,paymentNo)
                        .set(Orders::getFinishTime,"now()")
                        .eq(Orders::getId,orders.getId())
                );
                Member member = memberMapper.selectById(orders.getAcceptMemberId());
                //存储流水记录
                MemberRevenue memberRevenue = new MemberRevenue();
                memberRevenue.setCreateTime(new Date());
                memberRevenue.setMemberId(orders.getAcceptMemberId());
                memberRevenue.setType(orders.getType());
                memberRevenue.setOptType(Constants.ONE);
                memberRevenue.setBeforeAmount(member.getAmount());
                memberRevenue.setAmount(orders.getReceiveAccount());
                memberRevenue.setAfterAmount(member.getAmount() + orders.getReceiveAccount());
                memberRevenue.setObjId(orders.getId());
                memberRevenue.setObjType(Constants.ZERO);
                memberRevenue.setStatus(Constants.ZERO);
                memberRevenueMapper.insert(memberRevenue);
                //更新接单用户的余额与历史总金额
                memberMapper.update(new UpdateWrapper<Member>().lambda()
                        .set(Member::getAmount,"amount + " + orders.getReceiveAccount() )
                        .set(Member::getTotalAmount,"amount + " + orders.getReceiveAccount() )
                        .eq(Member::getId,member.getId())
                );
                //存储日志
                Constants.OrdersLog ordersLog = Constants.OrdersLog.PAY;
                this.saveOrderLog(orders,ordersLog,
                        ordersLog.getInfo(),orders.getReleaseMemberId(),null);
                //TODO é€šçŸ¥æŽ¥å•æ–¹ æ¬¾é¡¹å·²åˆ°è´¦
            }
        }
        return  ("处理成功!");
    }
}
server/services/src/main/resources/application-dev.yml
@@ -80,6 +80,37 @@
    privateKey:  # RSA私钥
    time: 600000
########################微信支付相关配置########################
wx:
  pay:
    #服务商---------start-------
    appId: wx48fd8faa35cc8277
    mchId: 1661770902
    apiV3Key: iF3kC8pL8dZ9iU3hN5fX9zI6eF4xQ6fT
    serialNumer: 368B835A194384FD583B83B77977B84127D2F655
    mchKey: W97N53Q71326D6JZ2E9HY5M4VT4BAC8S
    #    notifyUrl: http://xiaopiqiu3.natapp1.cc/api/wxPayNotify
    #    refundNotifyUrl: http://xiaopiqiu3.natapp1.cc/api/wxRefundNotify
    notifyUrl: https://dmtest.ahapp.net/bike_h5_api/api/wxPayNotify
    refundNotifyUrl: https://dmtest.ahapp.net/bike_h5_api/api/wxRefundNotify
    #keyPath: /usr/local/aliConfig/bike/apiclient_cert.p12
    #privateCertPath: /usr/local/aliConfig/bike/apiclient_cert.pem
    #privateKeyPath: /usr/local/aliConfig/bike/apiclient_key.pem
    #    keyPath: d://apiclient_cert.p12
    #    privateCertPath: d://apiclient_cert.pem
    #    privateKeyPath: d://apiclient_key.pem
    #服务商-------------end---
    existsSub: 1
    appSecret: 1ceb7c9dff3c4330d653adc3ca55ea24
    #子商户------------start----
    subAppId: wxcd2b89fd2ff065f8 #wxcd2b89fd2ff065f8
    subAppSecret: 3462fa186da7cb06c544df8d8664b63a #3336812504c830b1c3c5243f9ece407a
    subMchId: 1661772003
    subMchKey: EVM8E15TKXE0OEMJFC0V6UFVIOZ5CSQS
    #子商户------------end----
    #      mchKey: u4TSNtv0wFP7WRfnxBgijYOtRhS9FvlM
    typeId: gybike
upload:
  type: ftp
server/services/src/main/resources/application-pro.yml
@@ -49,6 +49,36 @@
    enable: true
    username: admin
    password:
########################微信支付相关配置########################
wx:
  pay:
    #服务商---------start-------
    appId: wx48fd8faa35cc8277
    mchId: 1661770902
    apiV3Key: iF3kC8pL8dZ9iU3hN5fX9zI6eF4xQ6fT
    serialNumer: 368B835A194384FD583B83B77977B84127D2F655
    mchKey: W97N53Q71326D6JZ2E9HY5M4VT4BAC8S
    #    notifyUrl: http://xiaopiqiu3.natapp1.cc/api/wxPayNotify
    #    refundNotifyUrl: http://xiaopiqiu3.natapp1.cc/api/wxRefundNotify
    notifyUrl: https://dmtest.ahapp.net/bike_h5_api/api/wxPayNotify
    refundNotifyUrl: https://dmtest.ahapp.net/bike_h5_api/api/wxRefundNotify
    keyPath: /usr/local/aliConfig/bike/apiclient_cert.p12
    privateCertPath: /usr/local/aliConfig/bike/apiclient_cert.pem
    privateKeyPath: /usr/local/aliConfig/bike/apiclient_key.pem
    #    keyPath: d://apiclient_cert.p12
    #    privateCertPath: d://apiclient_cert.pem
    #    privateKeyPath: d://apiclient_key.pem
    #服务商-------------end---
    existsSub: 1
    appSecret: 1ceb7c9dff3c4330d653adc3ca55ea24
    #子商户------------start----
    subAppId: wxcd2b89fd2ff065f8 #wxcd2b89fd2ff065f8
    subAppSecret: 3462fa186da7cb06c544df8d8664b63a #3336812504c830b1c3c5243f9ece407a
    subMchId: 1661772003
    subMchKey: EVM8E15TKXE0OEMJFC0V6UFVIOZ5CSQS
    #子商户------------end----
    #      mchKey: u4TSNtv0wFP7WRfnxBgijYOtRhS9FvlM
    typeId: gybike
upload:
  type: blob
server/services/src/main/resources/application-test.yml
@@ -69,6 +69,36 @@
    username: admin
    password: 111111
########################微信支付相关配置########################
wx:
  pay:
    #服务商---------start-------
    appId: wx48fd8faa35cc8277
    mchId: 1661770902
    apiV3Key: iF3kC8pL8dZ9iU3hN5fX9zI6eF4xQ6fT
    serialNumer: 368B835A194384FD583B83B77977B84127D2F655
    mchKey: W97N53Q71326D6JZ2E9HY5M4VT4BAC8S
    #    notifyUrl: http://xiaopiqiu3.natapp1.cc/api/wxPayNotify
    #    refundNotifyUrl: http://xiaopiqiu3.natapp1.cc/api/wxRefundNotify
    notifyUrl: https://dmtest.ahapp.net/bike_h5_api/api/wxPayNotify
    refundNotifyUrl: https://dmtest.ahapp.net/bike_h5_api/api/wxRefundNotify
    keyPath: /usr/local/aliConfig/bike/apiclient_cert.p12
    privateCertPath: /usr/local/aliConfig/bike/apiclient_cert.pem
    privateKeyPath: /usr/local/aliConfig/bike/apiclient_key.pem
    #    keyPath: d://apiclient_cert.p12
    #    privateCertPath: d://apiclient_cert.pem
    #    privateKeyPath: d://apiclient_key.pem
    #服务商-------------end---
    existsSub: 1
    appSecret: 1ceb7c9dff3c4330d653adc3ca55ea24
    #子商户------------start----
    subAppId: wxcd2b89fd2ff065f8 #wxcd2b89fd2ff065f8
    subAppSecret: 3462fa186da7cb06c544df8d8664b63a #3336812504c830b1c3c5243f9ece407a
    subMchId: 1661772003
    subMchKey: EVM8E15TKXE0OEMJFC0V6UFVIOZ5CSQS
    #子商户------------end----
    #      mchKey: u4TSNtv0wFP7WRfnxBgijYOtRhS9FvlM
    typeId: gybike
upload:
  type: blob
server/web/src/main/java/com/doumee/api/web/OrdersApi.java
@@ -1,10 +1,15 @@
package com.doumee.api.web;
import com.azure.core.annotation.Post;
import com.doumee.core.annotation.LoginRequired;
import com.doumee.core.annotation.trace.Trace;
import com.doumee.core.model.ApiResponse;
import com.doumee.dao.business.model.IdentityInfo;
import com.doumee.dao.business.model.Member;
import com.doumee.dao.business.model.Orders;
import com.doumee.dao.dto.ConfirmUpdOrderDTO;
import com.doumee.dao.dto.DoneOrderDTO;
import com.doumee.dao.dto.UpdOrderDataDTO;
import com.doumee.service.business.IdentityInfoService;
import com.doumee.service.business.MemberService;
import com.doumee.service.business.OrdersService;
@@ -37,13 +42,107 @@
    private OrdersService ordersService;
    @LoginRequired
    @ApiOperation(value = "编辑个人信息", notes = "小程序端")
    @GetMapping("/getMemberInfo")
    @ApiOperation(value = "发布订单 - å‘单方", notes = "小程序端")
    @PostMapping("/release")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "token", value = "用户token值", required = true),
    })
    public ApiResponse<Member> getMemberInfo() {
        return  ApiResponse.success("查询成功",memberService.getMemberInfo(getMemberId()));
    public ApiResponse<Object> release(@RequestBody Orders orders) {
        orders.setMember(this.getMemberResponse());
        return  ApiResponse.success("操作成功",ordersService.create(orders));
    }
    @LoginRequired
    @ApiOperation(value = "修改订单 - å‘单方", notes = "小程序端")
    @PostMapping("/updateOrder")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "token", value = "用户token值", required = true),
    })
    public ApiResponse updateOrder(@RequestBody Orders orders) {
        orders.setMember(this.getMemberResponse());
        ordersService.updateById(orders);
        return  ApiResponse.success("操作成功");
    }
    @LoginRequired
    @ApiOperation(value = "手动接单 - æŽ¥å•æ–¹", notes = "小程序端")
    @GetMapping("/accept")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "token", value = "用户token值", required = true),
    })
    public ApiResponse accept(@RequestParam Integer orderId) {
        ordersService.accept(orderId,this.getMemberResponse());
        return  ApiResponse.success("操作成功");
    }
    @LoginRequired
    @ApiOperation(value = "开始作业 - å‘单方", notes = "小程序端")
    @GetMapping("/begin")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "token", value = "用户token值", required = true),
    })
    public ApiResponse begin(@RequestParam Integer orderId) {
        ordersService.begin(orderId,this.getMemberResponse());
        return  ApiResponse.success("操作成功");
    }
    @LoginRequired
    @ApiOperation(value = "取消订单 - å‘单方", notes = "小程序端")
    @GetMapping("/releaseCancelOrder")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "token", value = "用户token值", required = true),
    })
    public ApiResponse releaseCancelOrder(@RequestParam Integer orderId) {
        ordersService.releaseCancelOrder(orderId,this.getMemberResponse());
        return  ApiResponse.success("操作成功");
    }
    @LoginRequired
    @ApiOperation(value = "取消接单 - æŽ¥å•æ–¹", notes = "小程序端")
    @GetMapping("/receiveCancelOrder")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "token", value = "用户token值", required = true),
    })
    public ApiResponse receiveCancelOrder(@RequestParam Integer orderId) {
        ordersService.receiveCancelOrder(orderId,this.getMemberResponse());
        return  ApiResponse.success("操作成功");
    }
    @LoginRequired
    @ApiOperation(value = "修改订单日期 - å‘单方", notes = "小程序端")
    @PostMapping("/updOrderData")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "token", value = "用户token值", required = true),
    })
    public ApiResponse updOrderData(@RequestBody UpdOrderDataDTO updOrderDataDTO) {
        updOrderDataDTO.setMember(this.getMemberResponse());
        ordersService.updOrderData(updOrderDataDTO);
        return  ApiResponse.success("操作成功");
    }
    @LoginRequired
    @ApiOperation(value = "确认订单修改 - æŽ¥å•æ–¹", notes = "小程序端")
    @PostMapping("/confirmUpd")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "token", value = "用户token值", required = true),
    })
    public ApiResponse confirmUpd(@RequestBody ConfirmUpdOrderDTO confirmUpdOrderDTO) {
        confirmUpdOrderDTO.setMember(this.getMemberResponse());
        ordersService.confirmUpd(confirmUpdOrderDTO);
        return  ApiResponse.success("操作成功");
    }
    @LoginRequired
    @ApiOperation(value = "完成订单 - å‘单方", notes = "小程序端")
    @GetMapping("/doneOrder")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "token", value = "用户token值", required = true),
    })
    public ApiResponse<Object> doneOrder(@RequestBody DoneOrderDTO doneOrderDTO) {
        doneOrderDTO.setMember(getMemberResponse());
        return  ApiResponse.success("操作成功",ordersService.doneOrder(doneOrderDTO));
    }
server/web/src/main/java/com/doumee/api/web/PaymentCallback.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,159 @@
package com.doumee.api.web;
import com.doumee.config.wx.WxMiniConfig;
import com.doumee.core.model.ApiResponse;
import com.doumee.service.business.OrdersService;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction;
import com.wechat.pay.java.service.refund.model.RefundNotification;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.InputStreamReader;
/**
 * Created by IntelliJ IDEA.
 * æ”¯ä»˜å›žè°ƒ
 * @Author : Rk
 * @create 2023/2/23 13:49
 */
@Slf4j
@RestController
@CrossOrigin
public class PaymentCallback {
    @Autowired
    private OrdersService ordersService;
    /**
     * ã€å¾®ä¿¡æ”¯ä»˜ã€‘异步通知
     *
     * @return
     */
    @PostMapping("/api/wxPayNotify")
    public ApiResponse wxPay_notify(HttpServletRequest request) {
        try {
            ServletInputStream inputStream = request.getInputStream();
            StringBuffer stringBuffer = new StringBuffer();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String s;
            //读取回调请求体
            while ((s = bufferedReader.readLine()) != null) {
                stringBuffer.append(s);
            }
            String body = stringBuffer.toString();
            String timestamp = request.getHeader("Wechatpay-Timestamp");
            String nonce = request.getHeader("Wechatpay-Nonce");
            String signType = request.getHeader("Wechatpay-Signature-Type");
            String serialNo = request.getHeader("wechatpay-Serial");
            String signature = request.getHeader("Wechatpay-Signature");
            RequestParam requestParam = new RequestParam.Builder()
                    .serialNumber(serialNo)
                    .nonce(nonce)
                    .signType(signType)
                    .signature(signature)
                    .timestamp(String.valueOf(timestamp))
                    .body(body)
                    .build();
            NotificationConfig config = new RSAAutoCertificateConfig.Builder()
                    .merchantId(WxMiniConfig.wxProperties.getMchId())
                    .privateKeyFromPath(WxMiniConfig.wxProperties.getPrivateKeyPath())
                    .merchantSerialNumber(WxMiniConfig.wxProperties.getSerialNumer())
                    .apiV3Key(WxMiniConfig.wxProperties.getApiV3Key())
                    .build();
            NotificationParser parser = new NotificationParser(config);
            Transaction result = parser.parse(requestParam, Transaction.class);
            //自定义订单号
            String outTradeNo = result.getOutTradeNo();
            //微信订单号
            String paymentNo = result.getTransactionId();
            if ("SUCCESS".equals(result.getTradeState().name())) {
                // æ”¯ä»˜æˆåŠŸge
                switch (result.getAttach()) {
                    //支付订单回调
                    case "createOrder": {
                        ordersService.payNotify(outTradeNo,paymentNo);
                        break;
                    }
                }
            } else {
                // æ”¯ä»˜å¤±è´¥
                switch (result.getAttach()) {
                    case "createGoodsOrder": {
                        break;
                    }
                }
            }
            return ApiResponse.success("处理成功!");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("微信回调结果异常,异常原因{}", e.getLocalizedMessage());
            return ApiResponse.failed("");
        }
    }
    @PostMapping("/api/wxRefundNotify")
    public ApiResponse wxRefundNotify(HttpServletRequest request) {
        log.error("微信退款回调结果开始===========" );
        try {
            DefaultSecurityManager securityManager = new DefaultSecurityManager();
            SecurityUtils.setSecurityManager(securityManager);
            ServletInputStream inputStream = request.getInputStream();
            StringBuffer stringBuffer = new StringBuffer();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String s;
            //读取回调请求体
            while ((s = bufferedReader.readLine()) != null) {
                stringBuffer.append(s);
            }
            String body = stringBuffer.toString();
            String timestamp = request.getHeader("Wechatpay-Timestamp");
            String nonce = request.getHeader("Wechatpay-Nonce");
            String signType = request.getHeader("Wechatpay-Signature-Type");
            String serialNo = request.getHeader("wechatpay-Serial");
            String signature = request.getHeader("Wechatpay-Signature");
            RequestParam requestParam = new RequestParam.Builder()
                    .serialNumber(serialNo)
                    .nonce(nonce)
                    .signType(signType)
                    .signature(signature)
                    .timestamp(String.valueOf(timestamp))
                    .body(body)
                    .build();
            NotificationConfig config = new RSAAutoCertificateConfig.Builder()
                    .merchantId(WxMiniConfig.wxProperties.getMchId())
                    .privateKeyFromPath(WxMiniConfig.wxProperties.getPrivateKeyPath())
                    .merchantSerialNumber(WxMiniConfig.wxProperties.getSerialNumer())
                    .apiV3Key(WxMiniConfig.wxProperties.getApiV3Key())
                    .build();
            NotificationParser parser = new NotificationParser(config);
            RefundNotification result = parser.parse(requestParam, RefundNotification.class);
//            if ("SUCCESS".equals(result.getRefundStatus().name())) {
                // æ”¯ä»˜æˆåŠŸge
//                     goodsorderService.closeGoodsorderDone(result);
//            }
            return ApiResponse.success("处理成功");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("微信回调结果异常,异常原因{}", e.getLocalizedMessage());
            return ApiResponse.failed("");
        }
    }
}