package com.bohuikeji.delivery.backstage.controller.api.courier;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.bohuikeji.delivery.backstage.constants.KeyConst;
import com.bohuikeji.delivery.backstage.constants.WxAppEm;
import com.bohuikeji.delivery.backstage.controller.open.KeRuYunApi;
import com.bohuikeji.delivery.backstage.entity.*;
import com.bohuikeji.delivery.backstage.entity.socket.AdminNotice;
import com.bohuikeji.delivery.backstage.entity.vo.CourierAddressVo;
import com.bohuikeji.delivery.backstage.entity.wx.TWxUser;
import com.bohuikeji.delivery.backstage.listener.order.OrderAliCenterListener;
import com.bohuikeji.delivery.backstage.listener.order.OrderEndListener;
import com.bohuikeji.delivery.backstage.listener.order.OrderLogisticsUpdateListener;
import com.bohuikeji.delivery.backstage.listener.order.OrderStartListener;
import com.bohuikeji.delivery.backstage.service.*;
import com.bohuikeji.delivery.backstage.service.third.ThirdUtils;
import com.bohuikeji.delivery.backstage.util.WxUtils;
import com.bohuikeji.delivery.backstage.util.maiyatian.maltUtils;
import com.bohuikeji.frame.module.admin.base.ApiController;
import com.bohuikeji.frame.module.admin.component.MqTool;
import com.bohuikeji.frame.module.admin.component.RedisUtil;
import com.bohuikeji.frame.module.admin.entity.TFranchiseeInformation;
import com.bohuikeji.frame.module.admin.entity.back.APIEntity;
import com.bohuikeji.frame.module.admin.entity.back.DataPage;
import com.bohuikeji.frame.module.admin.entity.sys.SysConfig;
import com.bohuikeji.frame.module.admin.entity.vo.AddressVo;
import com.bohuikeji.frame.module.admin.service.ISysConfigService;
import com.bohuikeji.frame.module.admin.service.ITFranchiseeInformationService;
import com.bohuikeji.frame.module.admin.utils.*;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import jodd.http.HttpRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zhouliwu
 * 派送员相关接口
 * 注：所以接口类必须继承 ApiController，否则无法被接口文档识别
 */
@Slf4j
@Api(tags = {"派送员相关接口"})
@RestController
@RequestMapping("/api/courier")
public class CourierApi extends ApiController {

    @Autowired
    ITCourierService courierService;
    @Autowired
    ITCourierPayService courierPayService;
    @Autowired
    ITOrderService orderService;
    @Autowired
    ITLogisticsService logisticsService;
    @Autowired
    ITLogisticsRecordService logisticsRecordService;
    @Autowired
    ITNewsService newsService;
    @Autowired
    ISysConfigService sysConfigService;
    @Autowired
    ITCustomerService customerService;
    @Autowired
    RedisUtil redisUtil;
    @Autowired
    IGmsService gmsService;
    @Autowired
    RabbitTemplate rabbitTemplate;
    @Autowired
    ISysConfigService configService;
    @Autowired
    ITFranchiseeInformationService informationService;
    @Autowired
    ITVehicleInformationService vehicleInformationService;
    @Autowired
    ITCustomerWalletService customerWalletService;
    @Autowired
    ITPayService payService;
    @Autowired
    ITCourierrExamService courierrExamService;
    @Autowired
    ITCustomerBigService customerBigService;
    @Autowired
    ITConfigService itConfigService;
    @Autowired
    ISocketService socketService;
    @Autowired
    ITCourierSaveDetailService saveDetailService;
    @Autowired
    IWxUserService wxUserService;
    @Autowired
    MqTool mqTool;
    @Autowired
    ITMaltFieldService maltFieldService;
    @Autowired
    CourierV2Api courierV2Api;

    /**
     * 派送员查询物流列表
     * @return
     */
    @ApiOperation("派送员查询物流信息")
    @GetMapping("/getLogistics")
    @ApiOperationSupport(ignoreParameters = {"records","total","searchCount"})
    @ApiImplicitParams({
            @ApiImplicitParam(name="courierId",value="派送员id",dataType="Integer", paramType = "query",required = true)})
    public APIEntity getLogistics(Integer courierId){
        return APIEntity.success(logisticsService.list(new QueryWrapper<TLogistics>().eq("courier_id",courierId)));
    }

    /**
     * 根据id获取派送员
     * @return
     */
    @ApiOperation("根据id获取派送员")
    @GetMapping("/getId")
    @ApiOperationSupport(ignoreParameters = {"records","total","searchCount"})
    @ApiImplicitParams({
            @ApiImplicitParam(name="courierId",value="派送员id",dataType="Integer", paramType = "query",required = true)})
    public APIEntity<TCourier> getId(Integer courierId){
        TCourier courier=courierService.getById(courierId);
        if(courier==null){
            return APIEntity.fail("登陆失效，请重新登陆！",412);
        }
        return APIEntity.success(courier);
    }


    /**
     * 根据id获取派送员
     * @return
     */
    @ApiOperation("获取派送员信息")
    @GetMapping("/get/courier")

    public APIEntity<TCourier> getCourier(@RequestAttribute("JwtUserId") Integer id){
        TCourier courier=courierService.getById(id);
        if(courier==null){
            return APIEntity.fail("登陆失效，请重新登陆！",412);
        }
        return APIEntity.success(courier);
    }

    /**
     * 派送员接单周排行榜
     * @return
     */
    @ApiOperation("派送员接单周排行榜")
    @GetMapping("/getWeekPai")
    @ApiOperationSupport(ignoreParameters = {"records","total","searchCount"})
    public APIEntity<List<TCourier>> getWeekPai(){
        List<TCourier> list = courierService.getWeekRanking();
        return APIEntity.success(list);
    }


    /**
     * 派送员接单月排行榜
     * @return
     */
    @ApiOperation("派送员接单月排行榜")
    @GetMapping("/getMonthPai")
    @ApiOperationSupport(ignoreParameters = {"records","total","searchCount"})
    public APIEntity<List<TCourier>> getMonthPai(){
        List<TCourier> list = courierService.getMonthRanking();
        return APIEntity.success(list);
    }

    /**
     * 派送员接单月排行榜
     * @return
     */
    @ApiOperation("派送员更新个人推送唯一标识(cid)")
    @PostMapping("/update/cid")
    @ApiImplicitParams({
            @ApiImplicitParam(name="cid",value="个人推送唯一标识",dataType="String", paramType = "query",example="15771331234",required=true),
            @ApiImplicitParam(name="courierId",value="派送员id",dataType="int", paramType = "query",example="15",required=true)
    })
    public APIEntity updateCid(@RequestBody TCourier tCourier){
        log.info("哈哈哈：[{}]",tCourier);
        courierService.updateById(tCourier);
        return APIEntity.success(tCourier.getCid());
    }

    /**
     * 派送员今日接单量
     * @return
     */
    @ApiOperation("派送员今日接单量")
    @GetMapping("/getDateNum")
    @ApiOperationSupport(ignoreParameters = {"records","total","searchCount","id"})
    public APIEntity<Integer> getDateNum(@RequestAttribute("JwtUserId") Integer id){
        Integer coun = courierService.getTordercount(id);
        return APIEntity.success(coun);
    }


    /**
     * 派送员今日收入
     * @return
     */
    @ApiOperation("派送员今日收入")
    @GetMapping("/getTodayIncome")
    @ApiOperationSupport(ignoreParameters = {"records","total","searchCount","id"})
    public APIEntity getTodayIncome(@RequestAttribute("JwtUserId") Integer id){
        SysConfig sysConfig = sysConfigService.getOne(new QueryWrapper<SysConfig>().eq("config_key","courier"));
        System.out.println("派送员分配额度："+sysConfig.getConfigValue());
        BigDecimal bd=new BigDecimal(sysConfig.getConfigValue());
        BigDecimal dig = courierService.getTodayIncome(id);
        System.out.println("金额："+dig);
        return APIEntity.success(dig);
    }

    /**
     * 登陆模拟接口
     * @return
     */
    @ApiOperation("登陆模拟接口(发放用户token测试")
    @ApiImplicitParams({
            @ApiImplicitParam(name="courierPhone",value="派送员手机号",dataType="String", paramType = "query",example="15771331234",required=true),
            @ApiImplicitParam(name="code",value="短信验证码",dataType="String", paramType = "query",example="123456",required=true)})
    @GetMapping("/login")
    public APIEntity login(String courierPhone,String code){
        TCourier courier= courierService.getOne(new QueryWrapper<TCourier>().eq("courier_phone",courierPhone));
        if (courier==null){
            return APIEntity.fail("未找到用户");
        }
        return APIEntity.success(JwtTokenUtil.createToken("派送员",courier.getCourierId()));
    }

    /**
     * 派送员App注册/验证码登陆
     * @return
     */
    @ApiOperation("派送员App注册/验证码登陆")
    @ApiImplicitParams({
            @ApiImplicitParam(name="courierPhone",value="派送员手机号",dataType="String", paramType = "query",example="15771331234",required=true),
            @ApiImplicitParam(name="verCode",value="短信验证码",dataType="String", paramType = "query",example="",required=true)})
    @GetMapping("/login/register")
    public APIEntity loginRegister(String courierPhone,String verCode,String cid){
        Object code = redisUtil.get("gms:courier:"+courierPhone);
        if(code==null){
            return APIEntity.fail("验证码无效，请重新获取！");
        }
        if(!code.toString().equals(verCode)){
            return APIEntity.fail("验证码错误！");
        }
        TCourier courier= courierService.getOne(new QueryWrapper<TCourier>().eq("courier_phone",courierPhone));
        if(courier != null) {
            if("禁止登陆".equals(courier.getCourierStatus())){
                return APIEntity.fail("您的账号已被禁止登陆，请联系客服或者平台管理员！");
            }
            if("已注销".equals(courier.getCourierStatus())){
                return APIEntity.fail("该手机号已注销，如需重新注册，请您更换手机号码重新登录！");
            }
            return APIEntity.success(JwtTokenUtil.createToken("派送员",courier.getCourierId()));
        }else {
            courier = new TCourier();
            String num=NumberUtils.getShort();
            courier.setCourierName("派送员"+num);
            courier.setCourierNumber(num);
            courier.setCourierPhone(courierPhone);
            courier.setCourierPwd("123456");
            courier.setCid(cid);
            if (!courierService.save(courier)) {
                log.error("派送员注册失败，创建失败，派送员：" + courier);
                return APIEntity.fail("系统繁忙，请稍后重试！");
            }
            newsService.pushCourierMsg1(courier.getCourierId(),"注册成功提醒","您好，您已成功注册成为”同城急送“派送员，默认登陆密码：{0}请及时修改。",courier.getCourierPwd());
            log.info("当前注册派送员[{}],ID=[{}]",courier.getCourierPhone(),courier.getCourierId());
            return APIEntity.success(JwtTokenUtil.createToken("派送员",courier.getCourierId()));
        }
    }


    /**
     *骑手端微信小程序登陆
     * @return
     */
    @ApiOperation("骑手端微信小程序登陆")
    @ApiImplicitParams({
            @ApiImplicitParam(name="loginCode",value="登陆凭证loginCode",dataType="String", paramType = "query",example="vxxxxxxxxxxxxxxxxz",required=true),
            @ApiImplicitParam(name="phoneCode",value="获取手机号phoneCode",dataType="String", paramType = "query",example="vxxxxxxxxxxxxxxxxz",required=true)})
    @PostMapping("/courier/wxLogin")
    public APIEntity courierWxlogin(String loginCode,String phoneCode){
        log.info("骑手端微信小程序登陆loginCode---1 [{}]",loginCode);
        log.info("骑手端小程序换取手机号phoneCode---2 [{}]",phoneCode);
        WxAppEm app= WxAppEm.MP_COURIER;
        JSONObject wxUserInfoJson= WxUtils.getLoginPhone(phoneCode,app);//phoneCode换取手机号
        if(wxUserInfoJson==null){
            return APIEntity.fail("手机号获取失败，请重新登陆");
        }
        JSONObject res= WxUtils.getCodeLoginInfo(loginCode,app);//小程序Code登录获取用户信息
        if(res==null){
            return APIEntity.fail("用户登陆失败，请重新登陆");
        }
        String openId = res.get("openid").toString();
        TCourier tCourier = courierService.getOne(new QueryWrapper<TCourier>().eq("courier_phone",wxUserInfoJson.getString("phoneNumber")));
        log.info("骑手登陆注册时返回openId信息：{}",openId);
        if(tCourier != null){
            if("已注销".equals(tCourier.getCourierStatus())){
                return APIEntity.fail("该手机号已注销，如需重新注册，请您更换手机号码重新登录！");
            }
            TWxUser wxUser=wxUserService.getUserByLogin(tCourier.getCourierId(),openId,WxAppEm.WX_USER_TYPE_COURIER,app);
            if(wxUser == null){
                wxUserService.saveLoginWxUser(res,app,tCourier.getCourierId());
            }else {
                wxUserService.updateById(wxUser.setWxUserSessionkey(res.getString("session_key")));
            }
            tCourier.setCourierUpdateTime(LocalDateTime.now());
            courierService.updateById(tCourier);
        }else {
            tCourier = courierService.saveCourier(wxUserInfoJson.getString("phoneNumber"));
            wxUserService.saveLoginWxUser(res,app,tCourier.getCourierId());
        }
        return APIEntity.success(JwtTokenUtil.createToken("派送员",tCourier.getCourierId()));
    }


    /**
     * 派送员App密码登录
     * @param courierPhone
     * @param courierPwd
     * @param request
     * @returnzhang'j'ao
     */
    @ApiOperation("派送员App登录")
    @GetMapping(value="/login/app")
    @ApiImplicitParams({
            @ApiImplicitParam(name="courierPhone",value="手机号",dataType="string", paramType = "query",example="15771335697",required = true),
            @ApiImplicitParam(name="courierPwd",value="密码",dataType="string", paramType = "query",example="123456",required = true)})
    public APIEntity findByUserNameAPP(String courierPhone, String courierPwd,HttpServletRequest request){
        TCourier courier =courierService.getOne(new QueryWrapper<TCourier>().notIn("courier_status","已注销").eq("courier_phone",courierPhone).eq("courier_pwd",courierPwd));
        if (courier==null){
            return APIEntity.fail("手机号或密码错误或该用户未注册！");
        }
        if("禁止登陆".equals(courier.getCourierStatus())){
            return APIEntity.fail("您的账号已被禁止登陆，请联系客服或者平台管理员！");
        }
        return APIEntity.success(JwtTokenUtil.createToken("派送员",courier.getCourierId()));
    }

    /**
     * 转单
     * @param phone
     * @param id
     * @return
     */
    @ApiOperation("手机号查询派送员")
    @GetMapping(value="/getCourByPhone")
    public APIEntity getCourByPhone(String phone,@RequestAttribute("JwtUserId") Integer id){
        TCourier tCourier = courierService.getOne(new QueryWrapper<TCourier>().eq("courier_phone",phone));
        if (tCourier == null){
            return APIEntity.fail("未找到该手机号骑手");
        }
        if("关闭".equals(tCourier.getAssignSwitch())){
            return APIEntity.fail("该派送员未开启接受指派功能！");
        }
        /* 判断转单对象是不是自己 */
        TCourier res = courierService.getById(id);
        if (res.getCourierPhone().equals(tCourier.getCourierPhone())){
            return APIEntity.fail("被转单人不能填自己");
        }
        return APIEntity.success(tCourier);
    }

    /**
     * 派送员App设置用户名、手机号、密码
     * @return
     */
    @ApiOperation("派送员App设置用户名、手机号、密码")
    @PostMapping(value="/updateCour")
    public APIEntity updateCour(@RequestBody TCourier tmp){
        TCourier courier = courierService.getById(tmp.getCourierId());
        if(courier==null){
            //客户端需要重新登陆
            return APIEntity.fail("未找到骑手信息，请重新登录！",412);
        }
        if(StringUtils.isBlank(tmp.getCourierName())){
            return APIEntity.fail("姓名不能为空！");
        }
        if(StringUtils.isBlank(tmp.getCourierPwd())){
            return APIEntity.fail("密码不能为空！");
        }
        courier.setCourierPwd(tmp.getCourierPwd());
        if(StringUtils.isBlank(tmp.getCourierPhone())){
            return APIEntity.fail("手机号码不能为空！");
        }
        if(!courier.getCourierPhone().equals(tmp.getCourierPhone())){
            TCourier have=courierService.getOne(new QueryWrapper<TCourier>().eq("courier_phone",tmp.getCourierPhone()));
            if(have!=null){
                return APIEntity.fail("该手机号码已被其他用户注册了！");
            }
        }
        courier.setJobStatus(tmp.getJobStatus());
        courier.setAssignSwitch(tmp.getAssignSwitch());
        if(courierService.updateById(courier)){
            return APIEntity.success(courier);
        }
        return APIEntity.fail("系统繁忙，请稍后再试!");
    }

    /**
     * 消息接收开关
     * @return
     */
    @ApiOperation("消息接收开关")
    @PostMapping(value="/updateCour/whether")
    public APIEntity updateWhetherCour(@RequestAttribute("JwtUserId") Integer id,String jobStatus){
        TCourier courier = courierService.getById(id);
        if(courier==null){
            //客户端需要重新登陆
            return APIEntity.fail("未找到骑手信息，请重新登录！",412);
        }
        courier.setJobStatus(jobStatus);
        if(courierService.updateById(courier)){
            return APIEntity.success(courier);
        }
        return APIEntity.fail("系统繁忙，请稍后再试!");

    }

    /**
     * 骑手App注销
     * @param id
     * @return
     */
    @ApiOperation("骑手App注销")
    @PostMapping("/logout")
    public APIEntity logout(@RequestAttribute("JwtUserId") Integer id) {
        TCourier courier = courierService.getOne(new QueryWrapper<TCourier>().eq("courier_id",id));
        if(courier==null){
            return APIEntity.fail("无法识别用户信息").setStatus(412);
        }
        if("已注销".equals(courier.getCourierStatus())){
            return APIEntity.fail("您的账户已注销，请不要重复提交！");
        }
        if("已缴费".equals(courier.getCourierPayStatus())){
            return APIEntity.fail("您的入住缴费未退款，无法注销！");
        }
        if(orderService.list(new QueryWrapper<TOrder>().eq("courier_id",courier.getCourierId()).notIn("order_status","已完成","已取消","已退款")).size()>0){
            return APIEntity.fail("您有订单正在派送中，请完成订单后再注销！");
        }
        if(orderService.list(new QueryWrapper<TOrder>().eq("courier_id",courier.getCourierId()).eq("order_status","已完成").eq("courier_sett_status","未结算")).size()>0){
            return APIEntity.fail("您的钱包中有余额未提现，请确认余额到账后在注销！");
        }
        courier.setCourierStatus("已注销");
        courier.setCourierUpdateTime(LocalDateTime.now());
        courierService.updateById(courier);
        return APIEntity.success("注销成功");
    }


    /**
     * 派送员App抢单
     * @param orderId
     * @param id
     * @return
     */
    @ApiOperation("派送员App抢单")
    @GetMapping("/receipt")
    @ApiImplicitParams({
            @ApiImplicitParam(name="orderId",value="订单id",dataType="Integer", paramType = "query",example="1",required = true),
            @ApiImplicitParam(name="version",value="版本号",dataType="String", paramType = "query",example="1.0.3",required = true)})
    public APIEntity receipt(@RequestAttribute("JwtUserId") Integer id,Integer orderId,String location,String version){
        TCourier courier = courierService.getById(id);
        if(!"认证成功".equals(courier.getCourierAuth())){
            return APIEntity.fail("请先完成身份认证！");
        }
        if("兼职".equals(courier.getCourierType())&&"未认证".equals(courier.getCourierAuthVehicle())){
            return APIEntity.fail("您需要先认证车辆信息！");
        }
        if("审核中".equals(courier.getCourierType())){
            return APIEntity.fail("您切换的骑手类型正在审核中，请通过后再接单");
        }
        if("禁止接单".equals(courier.getCourierStatus())){
            return APIEntity.fail("您的账号已被禁止接单，请联系客服或者平台管理员！");
        }
        courier.setJobStatus("工作中");
        /*if(courier.getFranId()==null){
            courier.setFranId(informationService.checkPio(MapUtils.getAddressReGeo(location)).getFranId());
        }*/
        if(!courier.updateById()){
            return APIEntity.fail("系统繁忙，请再试一次~");
        }
        TOrder order = orderService.getOne(new QueryWrapper<TOrder>().eq("order_status","待接单").eq("order_id",orderId));
        if(order==null){
            return APIEntity.fail("您手慢了，该订单已被抢走~");
        }
        if(order.getWayName().equals("极送-平均1小时")){
            TFranchiseeInformation franchiseeInformation = informationService.getById(order.getFranId());
            if(orderService.list(new QueryWrapper<TOrder>().eq("courier_id",courier.getCourierId()).eq("way_name","极送-平均1小时").in("order_status","待取件","取件中","派送中")).size()>franchiseeInformation.getAllowNum()){
                return APIEntity.fail("极送订单最多只能接"+franchiseeInformation.getAllowNum()+"单！");
            }
        }
        JSONObject jsonObject = courierService.getType(courier,order);//判断骑手的缴费金额等级符不符合接单规则
        if(!jsonObject.getBooleanValue("type")){
            return APIEntity.fail(jsonObject.getString("message"));
        }
        if(StringUtils.isBlank(location)){
            return APIEntity.fail("抢单失败，请检查是否开启位置信息，是否为最新版本！");
        }
        long orderDis=MapUtils.getDistance(location,order.getMailingAddress().getLng()+","+order.getMailingAddress().getLat());
        if(orderDis>50000){
            return APIEntity.fail("该订单距离您超过50公里，无法接单!");
        }
        if(orderService.getOne(new QueryWrapper<TOrder>().eq("order_id",orderId).eq("order_status","待接单"))==null){
            return APIEntity.fail("您手慢了，该订单已被抢走~");
        }
        order.setOrderStatus("待取件");
        order.setCourierId(id);
        order.setCourierPhone(courier.getCourierPhone());
        order.setCourierType(courier.getCourierType());
        order.setAcceptanceTime(LocalDateTime.now());
        orderService.updateById(order);
        mqTool.sendMsg(order.getOrderNum(), OrderStartListener.class);
        return APIEntity.success(order);
    }


    /**
     * 派送员App添加物流信息
     * @param logistics
     * @return
     */
    @ApiOperation("派送员App添加物流信息")
    @PostMapping("/addLog")

    public APIEntity addLog(@RequestBody TLogistics logistics){
        List<TLogistics> list = logisticsService.list(
                new QueryWrapper<TLogistics>()
                .eq("logistics_num",logistics.getLogisticsNum())
        );
        if(list.size() != 0){
            return APIEntity.fail("物流号已存在请检查物流号是否正确");
        }
        if(!StringUtils.isNotBlank(logistics.getLogisticsNum())){
            return APIEntity.fail("物流号不能为空");
        }
        log.info("测试添加物流单号是否正确 [{}]",logistics.getLogisticsNum());
        //logistics.setLogisticsNum(NumberUtils.get("L"));
        logistics.setLogisticsNum(logistics.getLogisticsNum());
        logisticsService.addTLogistics(logistics);
        return APIEntity.success(logistics);
    }

    /**
     * 派送员App物流跟踪记录
     * @param logisticsStatus
     * @param logisticsNum
     * @return
     */
    @ApiOperation("派送员App物流跟踪记录")
    @PostMapping("/addLogRec")
    @ApiImplicitParams({
            @ApiImplicitParam(name="logisticsStatus",value="按钮传输的状态",dataType="String", paramType = "query",example="1",required = true),
            @ApiImplicitParam(name="logisticsNum",value="物流号",dataType="String", paramType = "query",example="1",required = true)})
    public APIEntity addLogRec(String logisticsStatus,String logisticsNum){
        log.info("@@@@@@@@@@@@@@@@状态:{},物流号：{}",logisticsStatus,logisticsNum);
        TLogistics  tLogistics = logisticsService.getOne(new QueryWrapper<TLogistics>().eq("logistics_num",logisticsNum));
        TLogisticsRecord tLogisticsRecord = logisticsRecordService.getOne(new QueryWrapper<TLogisticsRecord>().eq("logistics_num",tLogistics.getLogisticsNum()));
        String type = null;
       if(Constants.SEND_TO.equals(logisticsStatus)){
            type=Constants.DELIVERY_IN;
        }else if(Constants.CONFIRM_RECEIPT.equals(logisticsStatus)){
           TOrder order = orderService.getOne(new QueryWrapper<TOrder>().eq("order_num",tLogistics.getOrderNum()));
            type=Constants.COMPLETED;
           tLogistics.setLogisticsStatus(type);
        }
       log.info("测试物流状体流转 [{}]",type);
            logisticsService.updateById(tLogistics);
            tLogisticsRecord.setLogisticsStatus(type);
            logisticsRecordService.save(tLogisticsRecord);
            return APIEntity.success(tLogisticsRecord);
    }

    /**
     * 派送员App修改订单
     * @param order
     * @return
     */
    @ApiOperation("派送员App修改订单")
    @PostMapping("/updateOrder")
    public APIEntity updateOrder(@RequestBody TOrder order){
        order.setCargoName(order.getCargoName());
        order.setCargoConfigId(order.getCargoConfigId());
        order.setVehicleConfigId(order.getVehicleConfigId());
        order.setWorthConfigId(order.getWorthConfigId());
        order.setCargoWeight(order.getCargoWeight());
        order.setWayConfigId(order.getWayConfigId());
        return APIEntity.success(orderService.updateById(order));
    }

    /**
     * 派送员App订单状态流转
     * 订单状态明细流转
     * @param orderId
     * @param courierId
     * @param orderStatus
     * 原接口修改----添加了包裹图片字段（在订单状态未“待派送时”，添加包裹）
     * @return
     */
    @ApiOperation("派送员App订单状态流转")
    @GetMapping("/stateFlow")
    @ApiImplicitParams({
            @ApiImplicitParam(name="orderId",value="订单id",dataType="Integer", paramType = "query",example="1",required = true),
            @ApiImplicitParam(name="courierId",value="派送员id",dataType="Integer", paramType = "query",example="1",required = true),
            @ApiImplicitParam(name="cargoPhotos",value="包裹照片",dataType="String", paramType = "query",example="1",required = true),
            @ApiImplicitParam(name="location",value="当前派送员经纬度",dataType="String", paramType = "query",example = "111.665544,40.858289",defaultValue = "111.665544,40.858289"),
            @ApiImplicitParam(name="signMethod",value="签收方式",dataType="String", paramType = "query",example = "本人签收")})
    public APIEntity stateFlow(Integer orderId,Integer courierId,String orderStatus,String cargoPhotos,String location,String signMethod){
        log.error("@@@@@@@@@@@@@@@@状态:{},派送员：{},经纬度：{},照片路径：{},签收方式：{}",orderStatus,courierId,location,cargoPhotos,signMethod);
        TOrder order = orderService.getOne(new QueryWrapper<TOrder>().eq("order_id",orderId).eq("courier_id",courierId));
        if(order==null){
            return APIEntity.fail("未找到订单信息！");
        }
        //当前订单状态
        String tmpStatus=order.getOrderStatus();
        switch (orderStatus){
            case "去取件":
                order.setOrderStatus("取件中");break;
            case "确认取件":
                order.setOrderStatus("待派送");
                order.setConfirmPickTime(LocalDateTime.now());
                order.setPackageCount(logisticsService.count(new QueryWrapper<TLogistics>().eq("order_id",order.getOrderId())));break;
            case "去派送":
                order.setOrderStatus("派送中");
                //上报给客如云订单已接单
                KeRuYunApi.statusPush(order.getOrderNum(),3,courierService.getCacheById(order.getCourierId()));
                order.setOrderExpectTime(orderService.getExpectTime(order,0));
                gmsService.sendOrderSend(order.getReceiptPhone(),order.getOrderNum());break;
            case "确认收货":
                long orderDis;
                if(!order.getTest()){
                    if(StringUtils.isNotBlank(location)){
                        orderDis=MapUtils.getWalkDistance(location,order.getReceiptAddress().getLng()+","+order.getReceiptAddress().getLat());
                    }else {
                        return APIEntity.fail("定位异常，请刷新定位！");
                    }
                    if("本人签收".equals(signMethod)){
                        if(orderDis>1000){
                            return APIEntity.fail("签收地未定位于收件地址范围内, 请刷新");
                        }
                    }
                    if("拍照签收".equals(signMethod)){
                        if(StringUtils.isBlank(cargoPhotos)){
                            return APIEntity.fail("拍照签收需要上传签收照片！");
                        }
                        if(orderDis>1000){
                            return APIEntity.fail("签收地未定位于收件地址范围内, 请刷新");
                        }
                    }
                    if(!order.getThird()){//非第三方操作，走此接口
                        TLogistics  tLogistics = logisticsService.getOne(new QueryWrapper<TLogistics>().eq("order_num",order.getOrderNum()));
                        log.error("签收获取物流包裹信息：{}",tLogistics);
                        if(tLogistics == null){
                            tLogistics = new TLogistics();
                        }
                        tLogistics.setSignMethod(signMethod);
                        tLogistics.setSignPhotos(cargoPhotos);
                        tLogistics.setLogisticsStatus("已完成");
                        tLogistics.setSignAddress(MapUtils.getAddressReGeo(location));
                        if("定位异常".equals(signMethod)){
                            tLogistics.setSignDistance(Math.toIntExact(orderDis));
                        }
                        if(StringUtils.isBlank(signMethod)){
                            tLogistics.setSignDistance(Math.toIntExact(orderDis));
                        }
                        tLogistics.setSignDistance(Math.toIntExact(orderDis));
                        logisticsService.updateById(tLogistics);
                    }
                }
                TCourier courier = courierService.getById(courierId);
                order.setOrderStatus("已完成");
                order.setCourierType(courier.getCourierType());
                order.setOrderEndTime(LocalDateTime.now());
                //上报给客如云订单已接单
                KeRuYunApi.statusPush(order.getOrderNum(),4,courierService.getCacheById(order.getCourierId()));
            default:break;
        }
        orderService.updateById(order);
        TOrderCircu.insertCircu(order);
        //当订单有变化且更新成功则更新物流信息
        if(!tmpStatus.equals(order.getOrderStatus())){
            if("待派送".equals(order.getOrderStatus())){
                logisticsService.saveTLogistics(orderId,courierId,cargoPhotos);
            }
            //通知物流更新
            mqTool.sendMsg(order.getOrderNum(), OrderLogisticsUpdateListener.class);
            if("已完成".equals(order.getOrderStatus())){
                //已完成订单通知完成消息
                mqTool.sendMsg(order.getOrderNum(), OrderEndListener.class);
            }
        }
        if("麦芽田".equals(order.getOrderChannel())){
            if("取件中".equals(order.getOrderStatus())){
                return APIEntity.success();
            }
            TCourier courier = courierService.getById(courierId);
            TMaltField maltField = maltFieldService.getOne(new QueryWrapper<TMaltField>().eq("shop_id",order.getShopId()));
            CourierAddressVo cuv=redisUtil.get(KeyConst.REDIS_COURIER_ADDRESS +courierId, CourierAddressVo.class);
            if(cuv == null){
                maltUtils.getDeliveryChange(order,courier.getCourierName(),maltField,null,"",1);
            }else {
                maltUtils.getDeliveryChange(order,courier.getCourierName(),maltField,cuv.getAddress(),"",1);
            }
        }
        mqTool.sendMsg(order.getOrderNum(), OrderAliCenterListener.class);
        courierV2Api.reportLatlon(order.getCourierId(),location);
        return APIEntity.success();
    }
    /**
     * 派送员提交认证材料第一步
     * @return
     */
    @ApiOperation("派送员提交认证材料第一步")
    @PostMapping("/auth/submit/one")
    public APIEntity submitAuthOne(@RequestBody TCourier courier){
        log.info("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@:[{}]",courier);
        String idCard=courier.getCourierCard();
        if (StringUtils.isBlank(idCard)){
            return APIEntity.fail("身份证号码不能为空！");
        }
        String msg;
        try {
            msg=IdCardUtils.IDCardValidate(idCard);
        } catch (ParseException e) {
            return APIEntity.fail("身份证号码格式错误！");
        }
        if (!IdCardUtils.VALIDITY.equals(msg)){
            return APIEntity.fail(msg);
        }
        //根据身份证号码计算生日
        courier.setCourierBirthday(IdCardUtils.getBirthday(idCard));
        courier.setCourierAuth("未认证");
        if(courier.updateById()){
            //返回更新后的用户信息
            return APIEntity.success(courier);
        }
        return APIEntity.fail();
    }
    /**
     * 派送员提交认证材料第二步
     * @return
     */
    @ApiOperation("派送员提交认证材料第二步")
    @PostMapping("/auth/submit/two")
    public APIEntity submitAuthTwo(@RequestBody TCourier courier){
        courier.setCourierAuth("审核中");
        courier.setCourierStatus("审核中");
        if(courier.updateById()){
            socketService.sendAdminMsg(new AdminNotice("您好，有新的配送员提交认证，请及时审核！")
                    .setAudio("https://oss.bhynm.com/delivery/upload/2022/3/15/164731173175938.mp3")
                    .setFranId(courier.getFranId()));
            return APIEntity.success(courier);
        }
        return APIEntity.fail();
    }


    /**
     * 派送员完善信息
     * @return
     */
    @ApiOperation("派送员完善信息(个人信息、测量信息)")
    @PostMapping("/perfect/info")
    public APIEntity perfectInfo(@RequestAttribute("JwtUserId") Integer id,@RequestBody TCourier courier){
        TCourier tCourier = courierService.getById(id);
        if("审核中".equals(tCourier.getCourierStatus())){
            return APIEntity.fail("信息已存在，请勿重复提交！");
        }
        String idCard=courier.getCourierCard();
        if (StringUtils.isBlank(idCard)){
            return APIEntity.fail("身份证号码不能为空！");
        }
        String msg;
        try {
            msg=IdCardUtils.IDCardValidate(idCard);
        } catch (ParseException e) {
            return APIEntity.fail("身份证号码格式错误！");
        }
        if (!IdCardUtils.VALIDITY.equals(msg)){
            return APIEntity.fail(msg);
        }
        if (StringUtils.isBlank(courier.getCourierName())){
            return APIEntity.fail("姓名不能为空！");
        }
        if (StringUtils.isBlank(courier.getLocation())){
            return APIEntity.fail("配送区域不能为空！");
        }
        if (StringUtils.isBlank(courier.getCourierAddress())){
            return APIEntity.fail("居住地址不能为空！");
        }
        if (StringUtils.isBlank(courier.getCourierType())){
            return APIEntity.fail("骑手类型不能为空！");
        }
        if (StringUtils.isBlank(courier.getCourierCardUrl())){
            return APIEntity.fail("请上传完整的证件信息！");
        }
        /*if(vehicleInformationService.list(new QueryWrapper<TVehicleInformation>().eq("courier_id",tCourier.getCourierId()).eq("vehicle_name",courier.getVehicleInformation().getVehicleName())).size()>=1){
            return APIEntity.fail("您已认证过该类型车辆，请不要重复申请！");
        }*/
        if(configService.getOneByKey("car_type_ddc").getConfigName().equals(courier.getVehicleInformation().getVehicleName())){
            courier.getVehicleInformation().setVehicleNumber("无车牌");
        }
        //根据身份证号码计算生日
        courier.setCourierId(id);
        courier.setCourierBirthday(IdCardUtils.getBirthday(idCard));
        courier.setCourierStatus("审核中");
        courier.setCourierAuth("认证中");
        courier.setFranId(informationService.checkPio(MapUtils.getAddressReGeo(courier.getLocation())).getFranId());
        if(courierService.updateById(courier)){
            if(!"无".equals(courier.getVehicleInformation().getVehicleName())){
                /*if("轿车".equals(courier.getVehicleInformation().getVehicleName())){
                    return APIEntity.fail("轿车类型暂未开通，请选择其他类型！");
                }*/
                if(StringUtils.isBlank(courier.getVehicleInformation().getVehicleNumber())){
                    return APIEntity.fail("请填写车牌号！");
                }
                SysConfig carType = configService.getOne(new QueryWrapper<SysConfig>().eq("config_name",courier.getVehicleInformation().getVehicleName()));
                //根据车辆名称查找车辆类型ID
                if (carType != null){
                    courier.getVehicleInformation().setVehicleTypeId(carType.getConfigId());
                }else {
                    return APIEntity.fail("车辆类型选择错误，请刷新页面重新选择！");
                }
                courier.getVehicleInformation().setAuthStatus("待认证");
                courier.getVehicleInformation().setCourierId(courier.getCourierId());
                courier.getVehicleInformation().setFranId(courier.getFranId());
                if(vehicleInformationService.list(new QueryWrapper<TVehicleInformation>().eq("courier_id",tCourier.getCourierId()).eq("vehicle_name",courier.getVehicleInformation().getVehicleName())).size()>0){
                    TVehicleInformation vehicleInformation= vehicleInformationService.getOne(new QueryWrapper<TVehicleInformation>().eq("courier_id",tCourier.getCourierId()).eq("vehicle_name",courier.getVehicleInformation().getVehicleName()));
                    //return APIEntity.fail("您已认证过该类型车辆，请不要重复申请！");
                    vehicleInformationService.saveOrUpdate(vehicleInformation);
                }
                vehicleInformationService.saveOrUpdate(courier.getVehicleInformation());
            }

            //返回更新后的用户信息
            return APIEntity.success(courier);
        }
        return APIEntity.fail();
    }


    /**
     * 派送员App获取验证码
     * @return
     */
    @ApiOperation("派送员App获取验证码(手机号、验证码登陆）")
    @ApiImplicitParams({
            @ApiImplicitParam(name="courierPhone",value="派送员手机号",dataType="String", paramType = "query",example="15600000000",required=true)})
    @GetMapping("/getVerCode")
    public APIEntity getVerCode(String courierPhone,HttpServletRequest request){
        if(StringUtils.isBlank(courierPhone)){
            return APIEntity.fail("手机号不能为空");
        }
        String code=gmsService.sendCode(courierPhone,request);
        //10分钟有效
        redisUtil.set("gms:courier:"+courierPhone,code,60*10);
        return APIEntity.success(code);

    }

    /**
     * 根据派送员登陆信息获取入驻费用
     * @return
     */
    @ApiOperation("根据派送员登陆信息获取入驻费用")
    @GetMapping("/getCourierById")

    public APIEntity getCourierById(@RequestAttribute("JwtUserId") Integer id){
        return APIEntity.success(courierService.getCourierPrice(id).getConfigValue());
    }

    /**
     * 根据经纬度获取配送区域
     * @return
     */
    @ApiOperation("根据经纬度获取配送区域")
    @GetMapping("/get/region/address")
    @ApiOperationSupport(ignoreParameters = {"id","records","total","searchCount"})
    @ApiImplicitParams({
            @ApiImplicitParam(name="location",value="经纬度",dataType="String", paramType = "query",example = "111.665544,40.858289")})
    public APIEntity getRegionAddress(String location) {
        log.info("参数：{}",location);
        AddressVo addressVo = MapUtils.getAddressReGeo(location);
        log.info("获取骑手地址:[{}]",addressVo);
        return APIEntity.success(addressVo.getCity());
    }

    /**
     * 根据派送员所在经纬度获取地址
     * @return
     */
    @ApiOperation("根据派送员所在经纬度获取地址")
    @GetMapping("/getAddress")
    @ApiOperationSupport(ignoreParameters = {"id","records","total","searchCount"})
    @ApiImplicitParams({
            @ApiImplicitParam(name="location",value="经纬度",dataType="String", paramType = "query",example = "111.665544,40.858289")})
    public APIEntity getAddress(String location) {
        log.info("参数：{}",location);
        AddressVo addressVo = MapUtils.getAddressReGeo(location);
        log.info("获取骑手地址:[{}]",addressVo);
        if (StringUtils.isNotBlank(addressVo.getCity())) {
            JSONArray jsonArray = MapUtils.getDist(addressVo.getCity());
            if(jsonArray==null||jsonArray.size()<1){
                return APIEntity.fail("该地区没有下属区域，请开启位置信息");
            }
            return APIEntity.success(MapUtils.getDist(addressVo.getCity()));
        }else{
            return APIEntity.success(MapUtils.getDist(addressVo.getProvince()));
        }
    }

    /**
     * 派送员申请退款
     * @return
     */
    @ApiOperation("派送员申请退款")
    @GetMapping("/getrefundexam")
    @ApiOperationSupport(ignoreParameters = {"id"})
    public APIEntity<TCourier> getCourierRefundExam(@RequestAttribute("JwtUserId") Integer id){
        TCourier tCourier = courierService.getById(id);
        if("已退款".equals(tCourier.getCourierPayStatus())){
            return APIEntity.fail("您的入驻费已退款，请及时刷新");
        }
        List<TOrder> orderList=orderService.list(new QueryWrapper<TOrder>().eq("courier_id",id).eq("order_status","已完成").eq("courier_sett_status","未结算"));
        if("审核中".equals(tCourier.getCourierType())){
            return APIEntity.fail("您好，您切换的骑手类型正在审核中，请在审核成功后再进行退款操作");
        }
        TCourierExam courierExam = courierrExamService.getOne(new QueryWrapper<TCourierExam>().eq("courier_id",tCourier.getCourierId()).eq("exam_status","审核中"));
        if(courierExam != null){
            if("审核中".equals(courierExam.getExamStatus())){
                return APIEntity.fail("您申请的退款正在审核中，请勿重复提交");
            }
        }
        if(orderService.list(new QueryWrapper<TOrder>().eq("courier_id",id).in("order_status","待取件","取件中","待派送","派送中")).size()>0){
            return APIEntity.fail("您有正在进行中的订单，无法退款，请先完成订单~");
        }
        courierrExamService.saveEacem(tCourier);
        tCourier.setGrade(8);
        tCourier.setCourierPayStatus("退款中");
        courierService.updateById(tCourier);
        return APIEntity.success();
    }


    /**
     * 根据派送员选择区域获取订单
     * @return
     */
    /*@ApiOperation("根据派送员选择区域获取订单")
    @GetMapping("/getOrderByAddress")
    @ApiOperationSupport(ignoreParameters = {"id","records","total","searchCount"})
    @ApiImplicitParams({
            @ApiImplicitParam(name="abcode",value="区级行政区",dataType="String", paramType = "query")})
    public APIEntity getOrderByAddress(DataPage page,String abcode) {
        page.setDesc("order_id");
        return APIEntity.success(orderService.page(page,new QueryWrapper<TOrder>().eq("order_status","待接单").eq("json_extract(receipt_address,'$.adcode')",abcode)));
    }*/

    /**
     * 获取派送员登陆信息
     * @return
     */
    @ApiOperation("获取派送员登陆信息")
    @GetMapping("/get")

    public APIEntity<TCourier> getById(@RequestAttribute("JwtUserId") Integer id){
        return APIEntity.success(courierService.getById(id));
    }


    /**
     * 获取所有派送员列表
     * @return
     */
    @ApiOperation("获取所有派送员列表")
    @GetMapping("/list")
    public APIEntity<List<TCourier>> listAll(){
        return APIEntity.success(courierService.list());
    }

    /**
     * 分页查询派送员列表
     * @return
     */
    @ApiOperation("分页查询派送员列表")
    @GetMapping("/page/list")
    //配置忽略参数
    @ApiOperationSupport(ignoreParameters = {"records","total","searchCount"})
    public APIEntity<IPage<TCourier>> listAll(DataPage<TCourier> page){
        return APIEntity.success(courierService.page(page));
    }
}
