| | |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-data-redis</artifactId> |
| | | </dependency> |
| | | <!--引入本地工行支付jar end--> |
| | | <!-- 计算两坐标间的直线距离 --> |
| | | <dependency> |
| | | <groupId>org.gavaghan</groupId> |
| | | <artifactId>geodesy</artifactId> |
| | | <version>1.1.3</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.projectlombok</groupId> |
| | | <artifactId>lombok</artifactId> |
| | | <version>1.18.20</version> |
| | | <scope>provided</scope> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-data-mongodb</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | |
| | |
| | | import com.stylefeng.guns.modular.system.service.ITAppUserService; |
| | | import com.stylefeng.guns.modular.system.service.ITCancelOrderService; |
| | | import com.stylefeng.guns.modular.system.service.ITOrderService; |
| | | import com.stylefeng.guns.modular.system.util.ResultUtil; |
| | | import io.swagger.annotations.ApiImplicitParam; |
| | | import io.swagger.annotations.ApiImplicitParams; |
| | | import io.swagger.annotations.ApiOperation; |
| | |
| | | */ |
| | | @RequestMapping(value = "/add") |
| | | @ResponseBody |
| | | public Object add(TOrder tOrder) { |
| | | |
| | | return SUCCESS_TIP; |
| | | public ResultUtil add(TOrder tOrder) { |
| | | ResultUtil add = tOrderService.add(tOrder); |
| | | return add; |
| | | } |
| | | |
| | | /** |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.dao; |
| | | |
| | | import com.baomidou.mybatisplus.mapper.BaseMapper; |
| | | import com.stylefeng.guns.modular.system.model.TYouTuiDriver; |
| | | |
| | | public interface TYouTuiDriverMapper extends BaseMapper<TYouTuiDriver> { |
| | | } |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.dao; |
| | | |
| | | import com.baomidou.mybatisplus.mapper.BaseMapper; |
| | | import com.stylefeng.guns.modular.system.model.WeatherCity; |
| | | |
| | | public interface WeatherCityMapper extends BaseMapper<WeatherCity> { |
| | | } |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.stylefeng.guns.modular.system.dao.TYouTuiDriverMapper"> |
| | | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.stylefeng.guns.modular.system.model.TYouTuiDriver"> |
| | | <id column="id" property="id" /> |
| | | <result column="driverId" property="driverId" /> |
| | | <result column="youTuiId" property="youTuiId" /> |
| | | <result column="integral" property="integral" /> |
| | | <result column="type" property="type"/> |
| | | <result column="surplusQuantity" property="surplusQuantity"/> |
| | | <result column="endTime" property="endTime"/> |
| | | <result column="state" property="state"/> |
| | | <result column="failureTime" property="failureTime" /> |
| | | <result column="createTime" property="createTime" /> |
| | | </resultMap> |
| | | |
| | | |
| | | </mapper> |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.stylefeng.guns.modular.system.dao.WeatherCityMapper"> |
| | | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.stylefeng.guns.modular.system.model.WeatherCity"> |
| | | <id column="id" property="id" /> |
| | | <result column="province" property="province" /> |
| | | <result column="city" property="city" /> |
| | | <result column="district" property="district" /> |
| | | </resultMap> |
| | | </mapper> |
| | |
| | | package com.stylefeng.guns.modular.system.model; |
| | | |
| | | import com.baomidou.mybatisplus.annotations.TableField; |
| | | import com.baomidou.mybatisplus.enums.IdType; |
| | | import java.math.BigDecimal; |
| | | import java.util.Date; |
| | |
| | | * 添加时间 |
| | | */ |
| | | private Date createTime; |
| | | |
| | | /** |
| | | * 预估里程 |
| | | */ |
| | | @TableField("estimatedMileage") |
| | | private Double estimatedMileage; |
| | | /** |
| | | * 预估时间 |
| | | */ |
| | | @TableField("estimatedTime") |
| | | private Integer estimatedTime; |
| | | /** |
| | | * 行程录音 |
| | | */ |
| | |
| | | private BigDecimal discountAmount; |
| | | @ApiModelProperty(value = "实际里程(米)") |
| | | private Integer actualMileage; |
| | | |
| | | /** |
| | | * 折扣0.01 |
| | | */ |
| | | @TableField("discount") |
| | | private Double discount; |
| | | @ApiModelProperty(value = "是否已开票 1是 0否") |
| | | private Integer isInvoice; |
| | | /** |
| | | * 大厅订单(0=否,1=是) |
| | | */ |
| | | @TableField("hallOrder") |
| | | private Integer hallOrder; |
| | | |
| | | public String getUserPhone() { |
| | | return userPhone; |
| | |
| | | this.createTime = createTime; |
| | | } |
| | | |
| | | public Double getEstimatedMileage() { |
| | | return estimatedMileage; |
| | | } |
| | | |
| | | public void setEstimatedMileage(Double estimatedMileage) { |
| | | this.estimatedMileage = estimatedMileage; |
| | | } |
| | | |
| | | public Integer getEstimatedTime() { |
| | | return estimatedTime; |
| | | } |
| | | |
| | | public void setEstimatedTime(Integer estimatedTime) { |
| | | this.estimatedTime = estimatedTime; |
| | | } |
| | | |
| | | public Double getDiscount() { |
| | | return discount; |
| | | } |
| | | |
| | | public void setDiscount(Double discount) { |
| | | this.discount = discount; |
| | | } |
| | | |
| | | public Integer getHallOrder() { |
| | | return hallOrder; |
| | | } |
| | | |
| | | public void setHallOrder(Integer hallOrder) { |
| | | this.hallOrder = hallOrder; |
| | | } |
| | | |
| | | @Override |
| | | protected Serializable pkVal() { |
| | | return this.id; |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.model; |
| | | |
| | | import com.baomidou.mybatisplus.annotations.TableField; |
| | | import com.baomidou.mybatisplus.annotations.TableId; |
| | | import com.baomidou.mybatisplus.annotations.TableName; |
| | | import com.baomidou.mybatisplus.enums.IdType; |
| | | import lombok.Data; |
| | | |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * 司机优推数据 |
| | | * @author pzb |
| | | * @Date 2023/2/22 14:01 |
| | | */ |
| | | @Data |
| | | @TableName("t_you_tui_driver") |
| | | public class TYouTuiDriver { |
| | | /** |
| | | * 主键 |
| | | */ |
| | | @TableId(value = "id", type = IdType.AUTO) |
| | | @TableField("id") |
| | | private Integer id; |
| | | /** |
| | | * 司机id |
| | | */ |
| | | @TableField("driverId") |
| | | private Integer driverId; |
| | | /** |
| | | * 优推id |
| | | */ |
| | | @TableField("youTuiId") |
| | | private Integer youTuiId; |
| | | /** |
| | | * 积分 |
| | | */ |
| | | @TableField("integral") |
| | | private Integer integral; |
| | | /** |
| | | * 优推类型(1=次数,2=小时) |
| | | */ |
| | | @TableField("type") |
| | | private Integer type; |
| | | /** |
| | | * 优推剩余数量 |
| | | */ |
| | | @TableField("surplusQuantity") |
| | | private Integer surplusQuantity; |
| | | /** |
| | | * 优推结束时间 |
| | | */ |
| | | @TableField("endTime") |
| | | private Date endTime; |
| | | /** |
| | | * 状态(1=未使用,2=使用中,3=已结束) |
| | | */ |
| | | @TableField("state") |
| | | private Integer state; |
| | | /** |
| | | * 失效时间 |
| | | */ |
| | | @TableField("failureTime") |
| | | private Date failureTime; |
| | | /** |
| | | * 添加时间 |
| | | */ |
| | | @TableField("createTime") |
| | | private Date createTime; |
| | | } |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.model; |
| | | |
| | | import com.baomidou.mybatisplus.annotations.TableField; |
| | | import com.baomidou.mybatisplus.annotations.TableId; |
| | | import com.baomidou.mybatisplus.annotations.TableName; |
| | | import com.baomidou.mybatisplus.enums.IdType; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 天气相关城市 |
| | | * @author pzb |
| | | * @Date 2023/2/25 10:56 |
| | | */ |
| | | @Data |
| | | @TableName("t_weather_city") |
| | | public class WeatherCity { |
| | | /** |
| | | * 主键 |
| | | */ |
| | | @TableId(value = "id", type = IdType.INPUT) |
| | | @TableField("id") |
| | | private Integer id; |
| | | /** |
| | | * 省 |
| | | */ |
| | | @TableField("province") |
| | | private String province; |
| | | /** |
| | | * 市 |
| | | */ |
| | | @TableField("city") |
| | | private String city; |
| | | /** |
| | | * 区 |
| | | */ |
| | | @TableField("district") |
| | | private String district; |
| | | } |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.service; |
| | | |
| | | import com.baomidou.mybatisplus.service.IService; |
| | | import com.stylefeng.guns.modular.system.model.TYouTuiDriver; |
| | | |
| | | |
| | | public interface ITYouTuiDriverService extends IService<TYouTuiDriver> { |
| | | } |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.service; |
| | | |
| | | import com.baomidou.mybatisplus.service.IService; |
| | | import com.stylefeng.guns.modular.system.model.WeatherCity; |
| | | |
| | | public interface IWeatherCityService extends IService<WeatherCity> { |
| | | } |
| | |
| | | package com.stylefeng.guns.modular.system.service.impl; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.mapper.EntityWrapper; |
| | | import com.baomidou.mybatisplus.service.impl.ServiceImpl; |
| | |
| | | import com.stylefeng.guns.modular.system.dao.TDriverMapper; |
| | | import com.stylefeng.guns.modular.system.dao.TOrderMapper; |
| | | import com.stylefeng.guns.modular.system.enums.OrderStateEnum; |
| | | import com.stylefeng.guns.modular.system.model.TAppUser; |
| | | import com.stylefeng.guns.modular.system.model.TBranchOffice; |
| | | import com.stylefeng.guns.modular.system.model.TDriver; |
| | | import com.stylefeng.guns.modular.system.model.TOrder; |
| | | import com.stylefeng.guns.modular.system.service.ITAppUserService; |
| | | import com.stylefeng.guns.modular.system.service.ITOrderService; |
| | | import com.stylefeng.guns.modular.system.util.DateUtil; |
| | | import com.stylefeng.guns.modular.system.util.ResultUtil; |
| | | import com.stylefeng.guns.modular.system.model.*; |
| | | import com.stylefeng.guns.modular.system.service.*; |
| | | import com.stylefeng.guns.modular.system.util.*; |
| | | import com.stylefeng.guns.modular.system.util.GaoDe.MapUtil; |
| | | import com.stylefeng.guns.modular.system.util.GaoDe.model.District; |
| | | import com.stylefeng.guns.modular.system.util.juhe.WeatherUtil; |
| | | import com.stylefeng.guns.modular.system.util.mongodb.model.Location; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.geo.Circle; |
| | | import org.springframework.data.geo.Distance; |
| | | import org.springframework.data.geo.Metrics; |
| | | import org.springframework.data.mongodb.core.MongoTemplate; |
| | | import org.springframework.data.mongodb.core.geo.GeoJsonPoint; |
| | | import org.springframework.data.mongodb.core.query.Criteria; |
| | | import org.springframework.data.mongodb.core.query.Query; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.ui.Model; |
| | | import org.springframework.util.CollectionUtils; |
| | |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.math.BigDecimal; |
| | | import java.math.MathContext; |
| | | import java.math.RoundingMode; |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.LocalDate; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | |
| | | @Autowired |
| | | private ITAppUserService appUserService; |
| | | |
| | | @Autowired |
| | | private RedisUtil redisUtil; |
| | | |
| | | @Autowired |
| | | private ITSystemConfigService systemConfigService; |
| | | |
| | | @Autowired |
| | | private ITYouTuiDriverService youTuiDriverService; |
| | | |
| | | @Resource |
| | | private MongoTemplate mongoTemplate; |
| | | |
| | | @Autowired |
| | | private IWeatherCityService weatherCityService; |
| | | |
| | | @Autowired |
| | | private PushUtil pushUtil; |
| | | |
| | | |
| | | |
| | | |
| | | @Override |
| | | public List<TOrderResp> getOrderList(String createTime, String code, Integer source, String userName, String userPhone, Integer state, String driverName,Integer isException) { |
| | |
| | | tOrder.setUserId(tAppUser.getId()); |
| | | } |
| | | JSONObject jsonObject = JSON.parseObject(startAddress); |
| | | tOrder.setStartAddress(jsonObject.getString("address")); |
| | | String address = jsonObject.getString("address"); |
| | | address = address.replaceAll("& #40;", "("); |
| | | address = address.replaceAll("& #41;", ")"); |
| | | tOrder.setStartAddress(address); |
| | | tOrder.setStartLat(jsonObject.getString("lat")); |
| | | tOrder.setStartLng(jsonObject.getString("lon")); |
| | | tOrder.setSource(3); |
| | | if(ToolUtil.isNotEmpty(endAddress)){ |
| | | jsonObject = JSON.parseObject(endAddress); |
| | | tOrder.setEndAddress(jsonObject.getString("address")); |
| | | String address1 = jsonObject.getString("address"); |
| | | address1 = address1.replaceAll("& #40;", "("); |
| | | address1 = address1.replaceAll("& #41;", ")"); |
| | | tOrder.setEndAddress(address1); |
| | | tOrder.setEndLat(jsonObject.getString("lat")); |
| | | tOrder.setEndLng(jsonObject.getString("lon")); |
| | | } |
| | |
| | | return ResultUtil.error("获取预估距离出错", ""); |
| | | } |
| | | d = Double.valueOf(distance.get("distance")) / 1000; |
| | | order.setEstimatedMileage(d); |
| | | order.setEstimatedTime(Integer.valueOf(distance.get("duration")) / 60); |
| | | tOrder.setEstimatedMileage(d); |
| | | tOrder.setEstimatedTime(Integer.valueOf(distance.get("duration")) / 60); |
| | | } |
| | | String city = ""; |
| | | District geocode = MapUtil.geocode(order.getStartLng(), order.getStartLat()); |
| | | District geocode = MapUtil.geocode(tOrder.getStartLng(), tOrder.getStartLat()); |
| | | if(null != geocode){ |
| | | WeatherCity weatherCity = weatherCityService.selectOne(new EntityWrapper<WeatherCity>() |
| | | .where("'" + geocode.getCity() + "' like CONCAT('%', city, '%') and '" + geocode.getDistrict() + "' like CONCAT('%', district, '%') ")); |
| | | city = null != weatherCity ? weatherCity.getId().toString() : ""; |
| | | } |
| | | order = getOrderPrice(1, d, 0, order, city); |
| | | order.setState(null == order.getDriverId() ? 101 : 102); |
| | | order.setStatus(1); |
| | | order.setCreateTime(new Date()); |
| | | this.insert(order); |
| | | driverService.updateById(driver); |
| | | tOrder = getOrderPrice(1, d, 0, tOrder, city); |
| | | tOrder.setState(101); |
| | | tOrder.setStatus(1); |
| | | tOrder.setCreateTime(new Date()); |
| | | this.insert(tOrder); |
| | | //推送状态 |
| | | if(null != order.getDriverId()){ |
| | | pushUtil.pushOrderStatus(uid, 2, order.getId(), order.getStatus()); |
| | | }else{ |
| | | //开始推单 |
| | | Order finalOrder = order; |
| | | new Thread(new Runnable() { |
| | | pushOrder(tOrder); |
| | | return ResultUtil.success(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 获取订单价格 |
| | | * @param type 计算类型(1=预估价,2=订单费) |
| | | * @param distance 行驶公里 |
| | | * @param waitTime 等待时长 |
| | | * @param order 订单数据 |
| | | * @param city 查询天气的城市 |
| | | * @return |
| | | */ |
| | | public TOrder getOrderPrice(Integer type, Double distance, Integer waitTime, TOrder order, String city){ |
| | | order = getOrderInitialPrice(order); |
| | | TSystemConfig systemConfig = systemConfigService.selectOne(new EntityWrapper<TSystemConfig>().eq("type", 5)); |
| | | if(null == systemConfig){ |
| | | if(type == 1){//预估金额 |
| | | order.setEstimatedPrice(new BigDecimal(0)); |
| | | } |
| | | if(type == 2){//订单金额 |
| | | order.setOrderMoney(new BigDecimal(0)); |
| | | } |
| | | return order; |
| | | } |
| | | JSONObject jsonObject = JSON.parseObject(systemConfig.getContent()); |
| | | JSONArray chargeStandard = jsonObject.getJSONArray("ChargeStandard"); |
| | | JSONObject extraCost = jsonObject.getJSONObject("ExtraCost"); |
| | | Date date = new Date(); |
| | | for (int i = 0; i < chargeStandard.size(); i++) { |
| | | JSONObject jsonObject1 = chargeStandard.getJSONObject(i); |
| | | String num1 = jsonObject1.getString("num1"); |
| | | String num2 = jsonObject1.getString("num2"); |
| | | Double num3 = jsonObject1.getDouble("num3");//起步里程 |
| | | Double num4 = jsonObject1.getDouble("num4");//起步价格 |
| | | Double num5 = jsonObject1.getDouble("num5");//超过公里 |
| | | Double num6 = jsonObject1.getDouble("num6");//超过num3每num5公里收取num6 |
| | | Double num7 = jsonObject1.getDouble("num7");//长途起始公里 |
| | | Double num8 = jsonObject1.getDouble("num8");//长途结束公里 |
| | | Double num9 = jsonObject1.getDouble("num9");//长途费 |
| | | Double num10 = jsonObject1.getDouble("num10");//超出长途里程每num10公里 |
| | | Double num11 = jsonObject1.getDouble("num11");//超过num8每num10公里收取num11 |
| | | |
| | | String[] split = num1.split(":"); |
| | | Calendar s = Calendar.getInstance(); |
| | | s.setTime(date); |
| | | s.set(Calendar.HOUR_OF_DAY, Integer.valueOf(split[0])); |
| | | s.set(Calendar.MINUTE, Integer.valueOf(split[1])); |
| | | s.set(Calendar.SECOND, 0); |
| | | |
| | | split = num2.split(":"); |
| | | Calendar e = Calendar.getInstance(); |
| | | e.setTime(date); |
| | | e.set(Calendar.HOUR_OF_DAY, Integer.valueOf(split[0])); |
| | | e.set(Calendar.MINUTE, Integer.valueOf(split[1])); |
| | | e.set(Calendar.SECOND, 0); |
| | | |
| | | if(date.getTime() >= s.getTimeInMillis() && date.getTime() < e.getTimeInMillis()){ |
| | | if(num3.compareTo(distance) >= 0){//起步里程内 |
| | | order.setStartDistance(distance);//起步里程 |
| | | order.setStartPrice(new BigDecimal(num4));//起步价 |
| | | }else{ |
| | | BigDecimal subtract = new BigDecimal(distance).subtract(new BigDecimal(num3));//超出起步里程 |
| | | BigDecimal divide = subtract.divide(new BigDecimal(num5), new MathContext(2, RoundingMode.HALF_EVEN)); |
| | | BigDecimal multiply = divide.multiply(new BigDecimal(num6)); |
| | | order.setStartDistance(num3);//起步里程 |
| | | order.setStartPrice(new BigDecimal(num4));//起步价 |
| | | order.setOverDriveDistance(subtract.doubleValue());//超出起步里程 |
| | | order.setOverDrivePrice(multiply);//超出起步里程费 |
| | | |
| | | //计算长途费 |
| | | if(distance.compareTo(num7) > 0){ |
| | | order.setLongDistance(num7 + "-" + num8);//长途里程 |
| | | order.setLongDistancePrice(new BigDecimal(num9));//长途费 |
| | | } |
| | | //计算长途里程超出的部分 |
| | | if(distance.compareTo(num8) > 0){ |
| | | BigDecimal subtract1 = new BigDecimal(distance).subtract(new BigDecimal(num8)); |
| | | BigDecimal divide1 = subtract1.divide(new BigDecimal(num10), new MathContext(2, RoundingMode.HALF_EVEN)); |
| | | BigDecimal multiply1 = divide1.multiply(new BigDecimal(num11)); |
| | | order.setOverLongDistance(subtract1.doubleValue());//超出长途里程 |
| | | order.setOverLongDistancePrice(multiply1);//超出长途里程费 |
| | | } |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | |
| | | //计算额外费用 |
| | | Integer num1 = extraCost.getInteger("num1");//等待时长 |
| | | Double num2 = extraCost.getDouble("num2");//等待费 |
| | | Integer num3 = extraCost.getInteger("num3");//等待超出时长 |
| | | Double num4 = extraCost.getDouble("num4");//等到超出时长费用单价 X/分钟 |
| | | Double num5 = extraCost.getDouble("num5");//恶劣天气公里 |
| | | Double num6 = extraCost.getDouble("num6");//恶劣天气费 |
| | | Double num7 = extraCost.getDouble("num7");//恶劣天气超出公里 |
| | | Double num8 = extraCost.getDouble("num8");//恶劣天气超出公里单价 X/公里 |
| | | Double num9 = extraCost.getDouble("num9");//恶劣天气最高收取金额 |
| | | |
| | | //等待费用 |
| | | if(waitTime.compareTo(num1) >= 0){ |
| | | order.setWaitTime(num1);//等待时长 |
| | | order.setWaitTimePrice(new BigDecimal(num2));//等待费用 |
| | | |
| | | Integer w = waitTime - num3; |
| | | BigDecimal multiply = new BigDecimal(w).multiply(new BigDecimal(num4)); |
| | | order.setOutWaitTime(w);//等待时长超出分钟 |
| | | order.setOutWaitTimePrice(multiply);//等待时长超出费用 |
| | | } |
| | | |
| | | //恶劣天气 |
| | | systemConfig = systemConfigService.selectOne(new EntityWrapper<TSystemConfig>().eq("type", 8)); |
| | | if(null != systemConfig) { |
| | | JSONObject jsonObject1 = JSON.parseObject(systemConfig.getContent()); |
| | | Integer num11 = jsonObject1.getInteger("num1");//开启恶劣天气计价 |
| | | if(1 == num11){ |
| | | boolean badWeather = WeatherUtil.isBadWeather(city); |
| | | if(badWeather){ |
| | | order.setBadWeatherDistance(new BigDecimal(num5));//恶劣天气公里 |
| | | order.setBadWeatherPrice(new BigDecimal(num6));//恶劣天气费 |
| | | if(distance.compareTo(num7) > 0){ |
| | | BigDecimal subtract = new BigDecimal(distance).subtract(new BigDecimal(num7)); |
| | | BigDecimal multiply = subtract.multiply(new BigDecimal(num8)); |
| | | order.setOverBadWeatherDistance(subtract.doubleValue());//恶劣天气超出公里 |
| | | order.setOverBadWeatherPrice(multiply);//恶劣天气超出公里费 |
| | | } |
| | | |
| | | double add = order.getOverBadWeatherPrice().add(order.getBadWeatherPrice()).setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue(); |
| | | if(num9.compareTo(add) < 0){//超出最高金额(重新调整金额) |
| | | if(num9.compareTo(num6) < 0){//如果恶劣天气费大于最高金额 |
| | | order.setBadWeatherPrice(new BigDecimal(num9));//恶劣天气费 |
| | | order.setOverBadWeatherPrice(new BigDecimal(0));//恶劣天气超出公里费 |
| | | }else{ |
| | | BigDecimal subtract = new BigDecimal(num9).subtract(new BigDecimal(add)); |
| | | order.setOverBadWeatherPrice(subtract);//恶劣天气超出公里费 |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | //计算折扣 |
| | | if(null != order.getUserId()){ |
| | | |
| | | } |
| | | |
| | | //计算总金额 |
| | | BigDecimal bigDecimal = order.getStartPrice().add(order.getOverDrivePrice()).add(order.getLongDistancePrice()).add(order.getOverLongDistancePrice()) |
| | | .add(order.getWaitTimePrice()).add(order.getOutWaitTimePrice()).add(order.getBadWeatherPrice()).add(order.getOverBadWeatherPrice()).subtract(order.getDiscountAmount()).setScale(2, BigDecimal.ROUND_HALF_EVEN); |
| | | |
| | | if(type == 1){//预估价 |
| | | order.setEstimatedPrice(bigDecimal); |
| | | } |
| | | if(type == 2){//订单金额 |
| | | order.setOrderMoney(bigDecimal); |
| | | } |
| | | return order; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 初始订单费用 |
| | | * @param order |
| | | * @return |
| | | */ |
| | | public TOrder getOrderInitialPrice(TOrder order){ |
| | | order.setStartDistance(0D);//起步里程 |
| | | order.setStartPrice(new BigDecimal(0));//起步价 |
| | | order.setOverDriveDistance(0D);//超出起步里程 |
| | | order.setOverDrivePrice(new BigDecimal(0));//超出起步里程费 |
| | | order.setLongDistance("");//长途里程 |
| | | order.setLongDistancePrice(new BigDecimal(0));//长途里程费 |
| | | order.setOverLongDistance(0D);//超出长途里程 |
| | | order.setOverLongDistancePrice(new BigDecimal(0));//超出长途里程费 |
| | | order.setWaitTime(0);//等待时长 |
| | | order.setWaitTimePrice(new BigDecimal(0));//等待费 |
| | | order.setOutWaitTime(0);//超出等待时长 |
| | | order.setOutWaitTimePrice(new BigDecimal(0));//超出等待时长费 |
| | | order.setBadWeatherDistance(new BigDecimal(0));//恶劣天气里程 |
| | | order.setBadWeatherPrice(new BigDecimal(0));//恶劣天气里程费 |
| | | order.setOverBadWeatherDistance(0D);//恶劣天气超出里程 |
| | | order.setOverBadWeatherPrice(new BigDecimal(0));//恶劣天气超出里程费 |
| | | order.setDiscountedPrice(new BigDecimal(0));//优惠金额 |
| | | order.setCouponId(null);//优惠券 |
| | | order.setDiscountAmount(new BigDecimal(0));//折扣优惠金额 |
| | | order.setDiscount(0D);//折扣 |
| | | return order; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * 订单推送逻辑 |
| | | * @param order |
| | | */ |
| | | public void pushOrder(TOrder order){ |
| | | /** |
| | | * 1.先找最大推单范围内的优推司机 -》 距离最近 |
| | | * 没有1 - 》 |
| | | * 2.按照后台推送配置在范围内查找合适司机 |
| | | * 合适司:积分 > 评分 > 距离 |
| | | * 3.司机没有接单直接将订单置入大厅 |
| | | */ |
| | | TSystemConfig systemConfig = systemConfigService.selectOne(new EntityWrapper<TSystemConfig>().eq("type", 1)); |
| | | if(null == systemConfig){ |
| | | return; |
| | | } |
| | | JSONObject jsonObject = JSON.parseObject(systemConfig.getContent()); |
| | | Double num3 = jsonObject.getDouble("num3");//推单最大范围 |
| | | Integer num4 = jsonObject.getInteger("num4");//接单时间 |
| | | String startLat = order.getStartLat(); |
| | | String startLng = order.getStartLng(); |
| | | |
| | | //1 |
| | | //找到中心点 |
| | | GeoJsonPoint geoJsonPoint = new GeoJsonPoint(Double.valueOf(startLng), Double.valueOf(startLat)); |
| | | Double num = num3 / 1000;//范围公里 |
| | | //构造半径 |
| | | Distance distanceR = new Distance(num, Metrics.KILOMETERS); |
| | | //画圆 |
| | | Circle circle = new Circle(geoJsonPoint, distanceR); |
| | | // 构造query对象 |
| | | Query query = Query.query(Criteria.where("location").withinSphere(circle)); |
| | | List<Location> locations = mongoTemplate.find(query, Location.class); |
| | | List<Integer> driverIds = locations.stream().map(Location::getDriverId).collect(Collectors.toList()); |
| | | Integer driver = null; |
| | | TYouTuiDriver youTuiDriver1 = null; |
| | | if(driverIds.size() > 0){ |
| | | List<TYouTuiDriver> youTuiDrivers = youTuiDriverService.selectList(new EntityWrapper<TYouTuiDriver>().in("driverId", driverIds) |
| | | .eq("state", 2).last(" and (surplusQuantity > 0 or now() < endTime) and now() < failureTime")); |
| | | Double d = null; |
| | | for (TYouTuiDriver youTuiDriver : youTuiDrivers) { |
| | | String value = redisUtil.getValue("DRIVER" + youTuiDriver.getDriverId()); |
| | | if(ToolUtil.isEmpty(value)){ |
| | | continue; |
| | | } |
| | | Map<String, Double> distance = GeodesyUtil.getDistance(value, order.getStartLng() + "," + order.getStartLat()); |
| | | Double wgs84 = distance.get("WGS84"); |
| | | if(d == null || d.compareTo(wgs84) > 0){ |
| | | d = wgs84; |
| | | driver = youTuiDriver.getDriverId(); |
| | | youTuiDriver1 = youTuiDriver; |
| | | } |
| | | } |
| | | } |
| | | |
| | | if(null != youTuiDriver1 && youTuiDriver1.getType() == 1){ |
| | | youTuiDriver1.setSurplusQuantity(youTuiDriver1.getSurplusQuantity() - 1); |
| | | youTuiDriverService.updateById(youTuiDriver1); |
| | | } |
| | | |
| | | //开始范围查找 |
| | | if(null == driver){ |
| | | for (int i = 1; i < 4; i++) { |
| | | if(null != driver){ |
| | | break; |
| | | } |
| | | num = jsonObject.getDouble("num" + i) / 1000;//范围公里 |
| | | //构造半径 |
| | | distanceR = new Distance(num, Metrics.KILOMETERS); |
| | | //画圆 |
| | | circle = new Circle(geoJsonPoint, distanceR); |
| | | // 构造query对象 |
| | | query = Query.query(Criteria.where("location").withinSphere(circle)); |
| | | locations = mongoTemplate.find(query, Location.class); |
| | | |
| | | driverIds = locations.stream().map(Location::getDriverId).collect(Collectors.toList()); |
| | | if(driverIds.size() > 0){ |
| | | List<TDriver> drivers = tDriverMapper.selectList(new EntityWrapper<TDriver>().eq("approvalStatus", 2).eq("serverStatus", 1).eq("status", 1).in("id", driverIds)); |
| | | if(drivers.size() == 0){ |
| | | continue; |
| | | } |
| | | |
| | | Integer integral = null; |
| | | Double score = null; |
| | | Double d = null; |
| | | for (TDriver driver1 : drivers) { |
| | | if(integral == null || integral.compareTo(driver1.getIntegral()) < 0){//积分大 |
| | | integral = driver1.getIntegral(); |
| | | score = driver1.getScore(); |
| | | driver = driver1.getId(); |
| | | continue; |
| | | } |
| | | if(integral.compareTo(driver1.getIntegral()) == 0 && score.compareTo(driver1.getScore()) < 0){//积分相同对比评分 |
| | | integral = driver1.getIntegral(); |
| | | score = driver1.getScore(); |
| | | driver = driver1.getId(); |
| | | continue; |
| | | } |
| | | if(integral.compareTo(driver1.getIntegral()) == 0 && score.compareTo(driver1.getScore()) == 0){//积分相同/评分相同对比距离 |
| | | String value = redisUtil.getValue("DRIVER" + driver1.getId()); |
| | | if(ToolUtil.isEmpty(value)){ |
| | | continue; |
| | | } |
| | | Map<String, Double> distance = GeodesyUtil.getDistance(value, order.getStartLng() + "," + order.getStartLat()); |
| | | Double wgs84 = distance.get("WGS84"); |
| | | if(d == null || d.compareTo(wgs84) > 0){ |
| | | d = wgs84; |
| | | driver = driver1.getId(); |
| | | continue; |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
| | | } |
| | | |
| | | if(null != driver){ |
| | | pushUtil.pushGrabOrder(driver, 2, order.getId(), num4); |
| | | //创建定时任务处理订单到大厅 |
| | | new Timer().schedule(new TimerTask() { |
| | | @Override |
| | | public void run() { |
| | | pushOrder(finalOrder); |
| | | TOrder order1 = TOrderServiceImpl.this.selectById(order.getId()); |
| | | if(order1.getState() == 101 || order1.getState() == 201){ |
| | | order1.setHallOrder(1); |
| | | TOrderServiceImpl.this.updateById(order1); |
| | | } |
| | | } |
| | | }).start(); |
| | | }, num4 * 1000); |
| | | }else{ |
| | | order.setHallOrder(1); |
| | | this.updateById(order); |
| | | } |
| | | return ResultUtil.success(order.getState() == 102 ? order.getId() : null); |
| | | } |
| | | } |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.service.impl.ServiceImpl; |
| | | import com.stylefeng.guns.modular.system.dao.TYouTuiDriverMapper; |
| | | import com.stylefeng.guns.modular.system.model.TYouTuiDriver; |
| | | import com.stylefeng.guns.modular.system.service.ITYouTuiDriverService; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | |
| | | /** |
| | | * 用户优推数据 |
| | | * @author pzb |
| | | * @Date 2023/2/22 14:06 |
| | | */ |
| | | @Service |
| | | public class TYouTuiDriverServiceImpl extends ServiceImpl<TYouTuiDriverMapper, TYouTuiDriver> implements ITYouTuiDriverService { |
| | | } |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.service.impl.ServiceImpl; |
| | | import com.stylefeng.guns.modular.system.dao.WeatherCityMapper; |
| | | import com.stylefeng.guns.modular.system.model.WeatherCity; |
| | | import com.stylefeng.guns.modular.system.service.IWeatherCityService; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | @Service |
| | | public class WeatherCityServiceImpl extends ServiceImpl<WeatherCityMapper, WeatherCity> implements IWeatherCityService { |
| | | } |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.util.GaoDe; |
| | | |
| | | /** |
| | | * 高德地图配置 |
| | | * @author pzb |
| | | * @Date 2023/2/16 18:52 |
| | | */ |
| | | public interface MapConfig { |
| | | |
| | | /** |
| | | * 高德key |
| | | */ |
| | | String key = "e0370a9a4d10739045fb0b8f4742a67e"; |
| | | } |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.util.GaoDe; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.stylefeng.guns.modular.system.util.GaoDe.model.District; |
| | | import com.stylefeng.guns.modular.system.util.httpClinet.HttpClientUtil; |
| | | import com.stylefeng.guns.modular.system.util.httpClinet.HttpResult; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 地图工具类 |
| | | * @author pzb |
| | | * @Date 2023/2/16 18:48 |
| | | */ |
| | | public class MapUtil { |
| | | |
| | | public static Logger logger = LoggerFactory.getLogger("ServiceLog"); |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * 获取两点的距离 |
| | | * @param origins 起点坐标 |
| | | * @param destination 终点坐标 |
| | | * @param type 计算类型:0:直线距离 1:驾车导航距离(仅支持国内坐标)。 |
| | | * @return |
| | | */ |
| | | public static Map<String, String> getDistance(String origins, String destination, Integer type){ |
| | | try { |
| | | String url = "https://restapi.amap.com/v3/distance?key=" + MapConfig.key + "&origins=" + origins + "&destination=" + destination + |
| | | "&type=" + type; |
| | | HttpResult httpResult = HttpClientUtil.pushHttpRequset("GET", url, null, null, "json"); |
| | | if(httpResult.getCode() != 200){ |
| | | logger.debug(httpResult.getData()); |
| | | return null; |
| | | } |
| | | String data = httpResult.getData(); |
| | | JSONObject jsonObject = JSON.parseObject(data); |
| | | String status = jsonObject.getString("status"); |
| | | if(status.equals("1")){ |
| | | JSONArray results = jsonObject.getJSONArray("results"); |
| | | JSONObject jsonObject1 = results.getJSONObject(0); |
| | | Map<String, String> map = new HashMap<>(); |
| | | map.put("distance", jsonObject1.getString("distance"));//距离(米) |
| | | map.put("duration", jsonObject1.getString("duration"));//预计时间(秒) |
| | | return map; |
| | | }else{ |
| | | logger.debug(data); |
| | | } |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 地址转换经纬度 |
| | | * @param address |
| | | * @return |
| | | */ |
| | | public static List<String> geocoding(String address){ |
| | | try { |
| | | String url = "https://restapi.amap.com/v3/geocode/geo?key=" + MapConfig.key + "&output=JSON&address=" + address; |
| | | HttpResult httpResult = HttpClientUtil.pushHttpRequset("GET", url, null, null, "json"); |
| | | if(httpResult.getCode() != 200){ |
| | | return null; |
| | | } |
| | | JSONObject jsonObject = JSON.parseObject(httpResult.getData()); |
| | | String status = jsonObject.getString("status"); |
| | | List<String> list = new ArrayList<>(); |
| | | if(status.equals("1")){ |
| | | JSONArray geocodes = jsonObject.getJSONArray("geocodes"); |
| | | for(int i = 0; i < geocodes.size(); i++){ |
| | | String location = geocodes.getJSONObject(i).getString("location"); |
| | | list.add(location); |
| | | } |
| | | } |
| | | return list; |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 根据经纬度获取行政区域信息 |
| | | * @param lon |
| | | * @param lan |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public static District geocode(String lon, String lan) { |
| | | try { |
| | | String url = "https://restapi.amap.com/v3/geocode/regeo?key=" + MapConfig.key + "&location=" + lon + "," + lan; |
| | | HttpResult httpResult = HttpClientUtil.pushHttpRequset("GET", url, null, null, "json"); |
| | | if(httpResult.getCode() != 200){ |
| | | return null; |
| | | } |
| | | JSONObject jsonObject = JSON.parseObject(httpResult.getData()); |
| | | Map<String, String> map = new HashMap<>(); |
| | | if(jsonObject.getString("status").equals("1")){ |
| | | JSONObject regeocode = jsonObject.getJSONObject("regeocode"); |
| | | JSONObject addressComponent = regeocode.getJSONObject("addressComponent"); |
| | | String address = regeocode.getString("formatted_address"); |
| | | map.put("address", address); |
| | | String code = addressComponent.getString("adcode"); |
| | | String province = addressComponent.getString("province"); |
| | | String city = addressComponent.getString("city"); |
| | | String district = addressComponent.getString("district"); |
| | | District district1 = new District(); |
| | | district1.setProvince(province); |
| | | district1.setProvinceCode(code.substring(0, 2) + "0000"); |
| | | district1.setCity(city); |
| | | district1.setCityCode(code.substring(0, 4) + "00"); |
| | | district1.setDistrict(district); |
| | | district1.setDistrictCode(code); |
| | | return district1; |
| | | } |
| | | logger.debug(httpResult.getData()); |
| | | return null; |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.util.GaoDe.model; |
| | | |
| | | |
| | | /** |
| | | * 行政区域 |
| | | * @author pzb |
| | | * @Date 2023/2/25 11:40 |
| | | */ |
| | | public class District { |
| | | /** |
| | | * 省名称 |
| | | */ |
| | | private String province; |
| | | /** |
| | | * 省编号 |
| | | */ |
| | | private String provinceCode; |
| | | /** |
| | | * 市名称 |
| | | */ |
| | | private String city; |
| | | /** |
| | | * 市编号 |
| | | */ |
| | | private String cityCode; |
| | | /** |
| | | * 区县名称 |
| | | */ |
| | | private String district; |
| | | /** |
| | | * 区县编号 |
| | | */ |
| | | private String districtCode; |
| | | |
| | | |
| | | public String getProvince() { |
| | | return province; |
| | | } |
| | | |
| | | public void setProvince(String province) { |
| | | this.province = province; |
| | | } |
| | | |
| | | public String getProvinceCode() { |
| | | return provinceCode; |
| | | } |
| | | |
| | | public void setProvinceCode(String provinceCode) { |
| | | this.provinceCode = provinceCode; |
| | | } |
| | | |
| | | public String getCity() { |
| | | return city; |
| | | } |
| | | |
| | | public void setCity(String city) { |
| | | this.city = city; |
| | | } |
| | | |
| | | public String getCityCode() { |
| | | return cityCode; |
| | | } |
| | | |
| | | public void setCityCode(String cityCode) { |
| | | this.cityCode = cityCode; |
| | | } |
| | | |
| | | public String getDistrict() { |
| | | return district; |
| | | } |
| | | |
| | | public void setDistrict(String district) { |
| | | this.district = district; |
| | | } |
| | | |
| | | public String getDistrictCode() { |
| | | return districtCode; |
| | | } |
| | | |
| | | public void setDistrictCode(String districtCode) { |
| | | this.districtCode = districtCode; |
| | | } |
| | | } |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.util; |
| | | |
| | | import org.gavaghan.geodesy.Ellipsoid; |
| | | import org.gavaghan.geodesy.GeodeticCalculator; |
| | | import org.gavaghan.geodesy.GeodeticCurve; |
| | | import org.gavaghan.geodesy.GlobalCoordinates; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 计算两个金纬度坐标之间的直线距离 |
| | | */ |
| | | public class GeodesyUtil { |
| | | |
| | | |
| | | /** |
| | | * 获取直线距离 |
| | | * @param fromLonLat |
| | | * @param toLonLat |
| | | * @return |
| | | */ |
| | | public static Map<String, Double> getDistance(String fromLonLat, String toLonLat){ |
| | | String[] from = fromLonLat.split(","); |
| | | String[] to = toLonLat.split(","); |
| | | GlobalCoordinates source = new GlobalCoordinates(Double.valueOf(from[1]), Double.valueOf(from[0])); |
| | | GlobalCoordinates target = new GlobalCoordinates(Double.valueOf(to[1]), Double.valueOf(to[0])); |
| | | double Sphere = getDistanceMeter(source, target, Ellipsoid.Sphere); |
| | | double WGS84 = getDistanceMeter(source, target, Ellipsoid.WGS84); |
| | | double GRS80 = getDistanceMeter(source, target, Ellipsoid.GRS80); |
| | | double GRS67 = getDistanceMeter(source, target, Ellipsoid.GRS67); |
| | | double ANS = getDistanceMeter(source, target, Ellipsoid.ANS); |
| | | double WGS72 = getDistanceMeter(source, target, Ellipsoid.WGS72); |
| | | double Clarke1858 = getDistanceMeter(source, target, Ellipsoid.Clarke1858); |
| | | double Clarke1880 = getDistanceMeter(source, target, Ellipsoid.Clarke1880); |
| | | // System.out.println("Sphere坐标系计算结果:"+Sphere + "米"); |
| | | // System.out.println("WGS84坐标系计算结果:"+WGS84 + "米"); |
| | | // System.out.println("GRS80坐标系计算结果:"+GRS80 + "米"); |
| | | // System.out.println("GRS67坐标系计算结果:"+GRS67 + "米"); |
| | | // System.out.println("ANS坐标系计算结果:"+ANS + "米"); |
| | | // System.out.println("WGS72坐标系计算结果:"+WGS72 + "米"); |
| | | // System.out.println("Clarke1858坐标系计算结果:"+Clarke1858 + "米"); |
| | | // System.out.println("Clarke1880坐标系计算结果:"+Clarke1880 + "米"); |
| | | Map<String, Double> map = new HashMap<>(); |
| | | map.put("Sphere", Sphere); |
| | | map.put("WGS84", WGS84); |
| | | map.put("GRS80", GRS80); |
| | | map.put("GRS67", GRS67); |
| | | map.put("ANS", ANS); |
| | | map.put("WGS72", WGS72); |
| | | map.put("Clarke1858", Clarke1858); |
| | | map.put("Clarke1880", Clarke1880); |
| | | return map; |
| | | } |
| | | |
| | | |
| | | private static double getDistanceMeter(GlobalCoordinates gpsFrom, GlobalCoordinates gpsTo, Ellipsoid ellipsoid){ |
| | | //创建GeodeticCalculator,调用计算方法,传入坐标系、经纬度用于计算距离 |
| | | GeodeticCurve geoCurve = new GeodeticCalculator().calculateGeodeticCurve(ellipsoid, gpsFrom, gpsTo); |
| | | return geoCurve.getEllipsoidalDistance(); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.util; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.http.HttpEntity; |
| | | import org.springframework.http.HttpHeaders; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.util.LinkedMultiValueMap; |
| | | import org.springframework.util.MultiValueMap; |
| | | import org.springframework.web.client.RestTemplate; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * socket推单处理类 |
| | | */ |
| | | @Component |
| | | public class PushUtil { |
| | | |
| | | Logger logger = LoggerFactory.getLogger("ServiceLog"); |
| | | |
| | | @Autowired |
| | | private RestTemplate internalRestTemplate; |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * 系统推单推送 |
| | | * @param id 接受对象id |
| | | * @param type 接受对象类型(1=用户,2=司机) |
| | | * @param orderId 订单id |
| | | * @param countdown 抢单倒计时(秒) |
| | | */ |
| | | public void pushGrabOrder(Integer id, Integer type, Integer orderId, Integer countdown){ |
| | | JSONObject msg = new JSONObject(); |
| | | msg.put("code", 200); |
| | | msg.put("msg", "SUCCESS"); |
| | | msg.put("method", "GRAB_ORDER"); |
| | | |
| | | Map<String, Object> map = new HashMap<>(); |
| | | map.put("orderId", orderId); |
| | | map.put("countdown", countdown); |
| | | |
| | | msg.put("data", map); |
| | | |
| | | //调用推送 |
| | | HttpHeaders headers = new HttpHeaders(); |
| | | // 以表单的方式提交 |
| | | headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); |
| | | //将请求头部和参数合成一个请求 |
| | | MultiValueMap<String, Object> params = new LinkedMultiValueMap<>(); |
| | | params.add("msg", msg.toJSONString()); |
| | | params.add("id", id.toString()); |
| | | params.add("type", type.toString()); |
| | | HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers); |
| | | String s = internalRestTemplate.postForObject("http://zuul-gateway/netty/sendMsgToClient",requestEntity , String.class); |
| | | JSONObject jsonObject1 = JSON.parseObject(s, JSONObject.class); |
| | | if(jsonObject1.getIntValue("code") != 200){ |
| | | logger.debug(jsonObject1.getString("msg")); |
| | | System.err.println(jsonObject1.getString("msg")); |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.util.httpClinet; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import org.apache.http.NameValuePair; |
| | | import org.apache.http.client.config.RequestConfig; |
| | | import org.apache.http.client.entity.UrlEncodedFormEntity; |
| | | import org.apache.http.client.methods.CloseableHttpResponse; |
| | | import org.apache.http.client.methods.HttpGet; |
| | | import org.apache.http.client.methods.HttpPost; |
| | | import org.apache.http.conn.ssl.SSLConnectionSocketFactory; |
| | | import org.apache.http.entity.ContentType; |
| | | import org.apache.http.entity.StringEntity; |
| | | import org.apache.http.impl.client.CloseableHttpClient; |
| | | import org.apache.http.impl.client.HttpClients; |
| | | import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; |
| | | import org.apache.http.message.BasicNameValuePair; |
| | | import org.apache.http.ssl.SSLContexts; |
| | | import org.apache.http.util.EntityUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | import javax.net.ssl.SSLContext; |
| | | import java.io.File; |
| | | import java.io.FileInputStream; |
| | | import java.io.InputStream; |
| | | import java.nio.charset.Charset; |
| | | import java.security.KeyStore; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.*; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | | * http工具类 |
| | | */ |
| | | public class HttpClientUtil { |
| | | |
| | | private static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class); |
| | | |
| | | private static PoolingHttpClientConnectionManager connectionManager; |
| | | |
| | | |
| | | { |
| | | //1.创建连接池管理器 |
| | | connectionManager = new PoolingHttpClientConnectionManager(60000, |
| | | TimeUnit.MILLISECONDS); |
| | | connectionManager.setMaxTotal(1000); |
| | | connectionManager.setDefaultMaxPerRoute(50); |
| | | } |
| | | |
| | | /** |
| | | * 创建一个httpClient对象 |
| | | */ |
| | | private static CloseableHttpClient getHttpCline(){ |
| | | return HttpClients.custom() |
| | | .setConnectionManager(connectionManager) |
| | | .disableAutomaticRetries() |
| | | .build(); |
| | | } |
| | | |
| | | private static RequestConfig getRequestConfig(){ |
| | | RequestConfig.Builder builder = RequestConfig.custom(); |
| | | builder.setSocketTimeout(60000)//3.1设置客户端等待服务端返回数据的超时时间 |
| | | .setConnectTimeout(30000)//3.2设置客户端发起TCP连接请求的超时时间 |
| | | .setExpectContinueEnabled(true) |
| | | .setConnectionRequestTimeout(30000);//3.3设置客户端从连接池获取链接的超时时间 |
| | | return builder.build(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 创建一个POST请求实例 |
| | | * @param url 请求地址 |
| | | * @param params 请求参数 |
| | | */ |
| | | private static CloseableHttpResponse setPostHttpRequset(String url, Map<String, Object> params, Map<String, String> header, String contentType) throws Exception{ |
| | | HttpPost httpPost = new HttpPost(url); |
| | | httpPost.setConfig(getRequestConfig()); |
| | | if(null != header){ |
| | | for(String key : header.keySet()){ |
| | | httpPost.setHeader(key, header.get(key)); |
| | | } |
| | | } |
| | | List<NameValuePair> list = new ArrayList<>(); |
| | | if(null != params){ |
| | | Set<String> keys = params.keySet(); |
| | | for(String key : keys){ |
| | | list.add(new BasicNameValuePair(key, null == params.get(key) ? null : params.get(key).toString())); |
| | | } |
| | | } |
| | | switch (contentType){ |
| | | case "form": |
| | | httpPost.setEntity(new UrlEncodedFormEntity(list, "UTF-8")); |
| | | break; |
| | | case "json": |
| | | ObjectMapper objectMapper = new ObjectMapper(); |
| | | String s =objectMapper.writeValueAsString(params); |
| | | httpPost.setEntity(new StringEntity(s, ContentType.create(ContentType.APPLICATION_JSON.getMimeType(), Charset.forName("UTF-8")))); |
| | | break; |
| | | } |
| | | return getHttpCline().execute(httpPost); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取get请求实例 |
| | | * @param url 请求地址 |
| | | * @param params 请求参数 |
| | | */ |
| | | private static CloseableHttpResponse setGetHttpRequset(String url, Map<String, Object> params, Map<String, String> header) throws Exception{ |
| | | StringBuffer sb = new StringBuffer(); |
| | | String p = ""; |
| | | if(null != params){ |
| | | Set<String> keys = params.keySet(); |
| | | for(String key : keys){ |
| | | sb.append(key + "=" + params.get(key) + "&"); |
| | | } |
| | | p = "?" + sb.substring(0, sb.length() - 1); |
| | | } |
| | | HttpGet httpGet = new HttpGet(url + p); |
| | | httpGet.setConfig(getRequestConfig()); |
| | | if(null != header){ |
| | | for(String key : header.keySet()){ |
| | | httpGet.setHeader(key, header.get(key)); |
| | | } |
| | | } |
| | | return getHttpCline().execute(httpGet); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 发送http请求 |
| | | * @param mothed "GET、POST、PUT、HEAD、DELETE、HEAD、OPTIONS" |
| | | * @param url 请求地址 |
| | | * @param params 请求参数 |
| | | * @param header 请求头 |
| | | * @param contentType 参数请求方式form/json |
| | | * @return |
| | | */ |
| | | public static HttpResult pushHttpRequset(String mothed, String url, Map<String, Object> params, Map<String, String> header, String contentType) throws Exception{ |
| | | String randome = UUID.randomUUID().toString(); |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S"); |
| | | logger.info(sdf.format(new Date()) + "----(" + randome + ")请求参数:" + JSON.toJSONString(params)); |
| | | CloseableHttpResponse httpResponse = null; |
| | | switch (mothed){ |
| | | case "GET": |
| | | httpResponse = setGetHttpRequset(url, params, header); |
| | | break; |
| | | case "POST": |
| | | httpResponse = setPostHttpRequset(url, params, header, contentType); |
| | | break; |
| | | } |
| | | int statusCode = httpResponse.getStatusLine().getStatusCode(); |
| | | String content = EntityUtils.toString(httpResponse.getEntity(), "UTF-8"); |
| | | logger.info(sdf.format(new Date()) + "----(" + randome + ")返回结果:" + content); |
| | | HttpResult httpResult = HttpResult.getHttpResult(statusCode, content); |
| | | close(httpResponse); |
| | | return httpResult; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 发送XML请求 |
| | | * @param url 请求地址 |
| | | * @param xml XML数据 |
| | | * @param header 自定义请求头 |
| | | * @return |
| | | */ |
| | | public static HttpResult pushHttpRequsetXml(String url, String xml, Map<String, String> header) throws Exception{ |
| | | HttpPost httpPost = new HttpPost(url); |
| | | httpPost.setConfig(getRequestConfig()); |
| | | for(String key : header.keySet()){ |
| | | httpPost.setHeader(key, header.get(key)); |
| | | } |
| | | httpPost.setHeader("Content-Type", "application/xml"); |
| | | httpPost.setEntity(new StringEntity(xml, "UTF-8")); |
| | | CloseableHttpResponse httpResponse = getHttpCline().execute(httpPost); |
| | | int statusCode = httpResponse.getStatusLine().getStatusCode(); |
| | | String content = EntityUtils.toString(httpResponse.getEntity(), "UTF-8"); |
| | | HttpResult httpResult = HttpResult.getHttpResult(statusCode, content); |
| | | close(httpResponse); |
| | | return httpResult; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 请求https发送XML请求 |
| | | * @param url 接口路径 |
| | | * @param xml 内容 |
| | | * @param header 请求头 |
| | | * @param certPassword 证书密码 |
| | | * @param certPath 证书路径 |
| | | * @param certType 证书类型 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public String pushHttpsRequsetXml(String url, String xml, Map<String, String> header, String certPassword, String certPath, String certType) throws Exception{ |
| | | HttpPost httpPost = new HttpPost(url); |
| | | for(String key : header.keySet()){ |
| | | httpPost.setHeader(key, header.get(key)); |
| | | } |
| | | httpPost.setHeader("Content-Type", "application/xml"); |
| | | httpPost.setEntity(new StringEntity(xml, "UTF-8")); |
| | | CloseableHttpClient httpCline = this.initCert(certPassword, certPath, certType); |
| | | CloseableHttpResponse httpResponse = httpCline.execute(httpPost); |
| | | String content = null; |
| | | if(httpResponse.getStatusLine().getStatusCode() == 200){ |
| | | content = EntityUtils.toString(httpResponse.getEntity(), "UTF-8"); |
| | | }else{ |
| | | content = "返回状态码:" + httpResponse.getStatusLine() + "。" + EntityUtils.toString(httpResponse.getEntity()); |
| | | } |
| | | this.close(httpResponse); |
| | | httpCline.close(); |
| | | return content; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 初始化https对象(带证书) |
| | | * @param key 证书密码 |
| | | * @param certPath 证书路径 |
| | | * @param certType 证书类型 |
| | | * @throws Exception |
| | | */ |
| | | private CloseableHttpClient initCert(String key, String certPath, String certType) throws Exception { |
| | | KeyStore keyStore = KeyStore.getInstance(certType); |
| | | InputStream inputStream = new FileInputStream(new File(certPath)); |
| | | try { |
| | | keyStore.load(inputStream, key.toCharArray()); |
| | | } finally { |
| | | inputStream.close(); |
| | | } |
| | | SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, key.toCharArray()).build(); |
| | | SSLConnectionSocketFactory sslsf = |
| | | new SSLConnectionSocketFactory(sslcontext, new String[] {"TLSv1"}, null, |
| | | SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); |
| | | return HttpClients.custom().setSSLSocketFactory(sslsf).build(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 关闭资源 |
| | | */ |
| | | private static void close(CloseableHttpResponse httpResponse){ |
| | | try { |
| | | if(null != httpResponse){ |
| | | EntityUtils.consume(httpResponse.getEntity());//此处高能,通过源码分析,由EntityUtils是否回收HttpEntity |
| | | httpResponse.close(); |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | }finally { |
| | | try { |
| | | if(null != httpResponse){ |
| | | httpResponse.close(); |
| | | } |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.util.httpClinet; |
| | | |
| | | |
| | | /** |
| | | * http请求返回封装 |
| | | */ |
| | | public class HttpResult { |
| | | /** |
| | | * 返回状态码 |
| | | */ |
| | | private Integer code; |
| | | /** |
| | | * 返回结果 |
| | | */ |
| | | private String data; |
| | | |
| | | public Integer getCode() { |
| | | return code; |
| | | } |
| | | |
| | | public void setCode(Integer code) { |
| | | this.code = code; |
| | | } |
| | | |
| | | public String getData() { |
| | | return data; |
| | | } |
| | | |
| | | public void setData(String data) { |
| | | this.data = data; |
| | | } |
| | | |
| | | /** |
| | | * 返回封装结果 |
| | | * @param code |
| | | * @param data |
| | | * @return |
| | | */ |
| | | public static HttpResult getHttpResult(Integer code, String data){ |
| | | HttpResult httpResult = new HttpResult(); |
| | | httpResult.setCode(code); |
| | | httpResult.setData(data); |
| | | return httpResult; |
| | | } |
| | | } |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.util.juhe; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.stylefeng.guns.modular.system.util.httpClinet.HttpClientUtil; |
| | | import com.stylefeng.guns.modular.system.util.httpClinet.HttpResult; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * @author zhibing.pu |
| | | * @date 2023/4/10 15:35 |
| | | */ |
| | | public class OCRUtil { |
| | | |
| | | static Logger logger = LoggerFactory.getLogger("ServiceLog"); |
| | | |
| | | private final static String key = "5cc9622f299335639dbc046f3812c52a"; |
| | | |
| | | private static HttpClientUtil httpClientUtil = new HttpClientUtil(); |
| | | |
| | | |
| | | /** |
| | | * OCR证件识别 |
| | | * @param cardType |
| | | * "1": "一代身份证", |
| | | * "2": "二代身份证正面", |
| | | * "3": "二代身份证证背面", |
| | | * "4": "临时身份证", |
| | | * "5": "驾照", |
| | | * "6": "行驶证", |
| | | * "7": "军官证1998版", |
| | | * "9": "中华人民共和国往来港澳通行证2005版", |
| | | * "10": "台湾居民往来大陆通行证1992版-照片页", |
| | | * "11": "大陆居民往来台湾通行证1992版-照片页", |
| | | * "12": "签证(护照幅面)", |
| | | * "13": "护照(护照幅面)", |
| | | * "14": "港澳居民来往内地通行证-照片页", |
| | | * "15": "港澳居民来往内地通行证-机读码页", |
| | | * "16": "户口本", |
| | | * "17": "银行卡", |
| | | * "22": "往来港澳通行证2014版-照片页(卡式港澳通行证)", |
| | | * "25": "台湾居民来往大陆通行证2015版-照片页", |
| | | * "26": "台湾居民往来大陆通行证2015版-机读码页", |
| | | * "28": "中国驾驶证副页", |
| | | * "29": "往来台湾通行证2017版-照片页", |
| | | * "30": "行驶证副页", |
| | | * "31": "港澳台居民居住证正面", |
| | | * "32": "港澳台居民居住证反面", |
| | | * "33": "外国人永久居留身份证", |
| | | * "101": "二代身份证正面背面自动分类", |
| | | * "102": "驾驶证正副页自动分类", |
| | | * "103": "行驶证正副页自动分类", |
| | | * "104": "身份证、驾驶证、行驶证自动分类", |
| | | * "1000": "居住证", |
| | | * "1001": "香港永久性居民身份证", |
| | | * "1002": "登机牌(拍照设备目前不支持登机牌的识别)", |
| | | * "1003": "边民证(A)(照片页)", |
| | | * "2008":"营业执照" |
| | | * @param file 图片文件 |
| | | * @return |
| | | */ |
| | | public static JSONObject certificate(Integer cardType, MultipartFile file){ |
| | | String url = "http://v.juhe.cn/certificates/query"; |
| | | HttpResult httpResult = null; |
| | | try { |
| | | Map<String, Object> params = new HashMap<>(); |
| | | params.put("key", key); |
| | | params.put("cardType", cardType.toString()); |
| | | params.put("pic", file); |
| | | httpResult = httpClientUtil.pushHttpRequset("POST", url, params, null, "form"); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | if(httpResult.getCode() != 200){ |
| | | logger.debug("查询证件失败:" + httpResult.getData()); |
| | | return null; |
| | | } |
| | | String data = httpResult.getData(); |
| | | JSONObject jsonObject = JSON.parseObject(data); |
| | | Integer error_code = jsonObject.getInteger("error_code"); |
| | | if(0 != error_code){ |
| | | logger.debug("查询证件失败:" + jsonObject.getString("reason")); |
| | | return null; |
| | | } |
| | | JSONObject result = jsonObject.getJSONObject("result"); |
| | | return result; |
| | | } |
| | | |
| | | |
| | | ////身份证识别返回示例 |
| | | //{ |
| | | // "error_code": 0, |
| | | // "reason": "操作成功", |
| | | // "result": { |
| | | // "住址": "武汉市江岸区永清路****", |
| | | // "保留": "", |
| | | // "公民身份号码": "42010619510609****", |
| | | // "出生": "1951-06-09", |
| | | // "头像": "",/*Base64字符串*/ |
| | | // "姓名": "彭*", |
| | | // "性别": "男", |
| | | // "民族": "汉", |
| | | // "orderid":"JH1531180126114835937669", |
| | | // "userid":"1234567" |
| | | // } |
| | | //} |
| | | // |
| | | ////车牌识别返回示例 |
| | | //{ |
| | | // "reason": "操作成功", |
| | | // "result": { |
| | | // "车牌号": "粤N0***81", |
| | | // "车牌颜色": "1", |
| | | // "车牌类型": "1", |
| | | // "整牌可信度": "86", |
| | | // "亮度评价": "215", |
| | | // "车牌运动方向": "0", |
| | | // "车牌位置(left_top_right_bottom)": "30_118_498_222", |
| | | // "orderid":"JH1531180126114835937669", |
| | | // "userid":"1234567" |
| | | // }, |
| | | // "error_code": 0 |
| | | //} |
| | | ////港澳台居民居住证正面 |
| | | //{ |
| | | // "reason": "操作成功", |
| | | // "result":{ |
| | | // "保留" : "", |
| | | // "姓名" : "", |
| | | // "性别" : "", |
| | | // "民族" : "", |
| | | // "住址" : "", |
| | | // "出生" : "", |
| | | // "公民身份号码" : "", |
| | | // "复印件判别" : "", |
| | | // "头像" : "" |
| | | // } |
| | | //} |
| | | ////港澳台居民居住证反面 |
| | | //{ |
| | | // "reason": "操作成功", |
| | | // "result":{ |
| | | // "保留" : "", |
| | | // "签发机关" : "", |
| | | // "有效期限" : "", |
| | | // "签发日期" : "", |
| | | // "有效期至" : "", |
| | | // "通行证号码" : "" |
| | | // } |
| | | //} |
| | | ////港澳居民来往内地通行证-照片页 |
| | | //{ |
| | | // "reason": "操作成功", |
| | | // "result":{ |
| | | // "保留" : "", |
| | | // "证件号码" : "", |
| | | // "中文姓名" : "", |
| | | // "英文姓名" : "", |
| | | // "性别" : "", |
| | | // "出生日期" : "", |
| | | // "本证有效期至" : "", |
| | | // "英文姓" : "", |
| | | // "英文名" : "", |
| | | // "港澳证件号码" : "", |
| | | // "签发日期" : "", |
| | | // "有效期限" : "", |
| | | // "签发机关" : "", |
| | | // "换证次数" : "", |
| | | // "其他姓名" : "", |
| | | // "归属地" : "", |
| | | // "头像" : "", |
| | | // } |
| | | //} |
| | | ////中国台湾居民来往内地通行证照片页 |
| | | //{ |
| | | // "reason": "操作成功", |
| | | // "result":{ |
| | | // "保留" : "", |
| | | // "中文姓名" : "", |
| | | // "英文姓名" : "", |
| | | // "出生日期" : "", |
| | | // "性别" : "", |
| | | // "有效期限" : "", |
| | | // "签发地点" : "", |
| | | // "证件号码" : "", |
| | | // "签发次数" : "", |
| | | // "签发机关" : "", |
| | | // "头像" : "", |
| | | // } |
| | | //} |
| | | ////针对车牌的信息: |
| | | //1.车牌颜色类型: |
| | | // 0 //未知车牌 |
| | | // 1 //蓝牌 |
| | | // 2 //黑牌 |
| | | // 3 //单排黄牌 |
| | | // 4 //双排黄牌(大车尾牌,农用车) |
| | | // 5 //警车车牌 |
| | | // 6 //武警车牌 |
| | | // 7 //个性化车牌 |
| | | // 8 //单排军车 |
| | | // 9 //双排军车 |
| | | // 10 //使馆牌 |
| | | // 11 //香港牌 |
| | | // 12 //拖拉机 |
| | | // 13 //澳门牌 |
| | | // 14 //厂内牌 |
| | | // 15 //民航牌 |
| | | // 16 //领事馆车牌 |
| | | // 17 //新能源车牌-小型车 |
| | | // 18 //新能源车牌-大型车 |
| | | // |
| | | //2.车牌可信度: |
| | | // 当前识别结果的分数,分数越高识别对的可能越大 |
| | | //3.车牌位置: |
| | | // 是指车牌在图像中的坐标值 |
| | | //4.车牌运动方向: |
| | | // 0 unknown, 1 left, 2 right, 3 up , 4 down |
| | | // |
| | | ////行驶证查询返回: |
| | | //{ |
| | | // "保留": "", |
| | | // "号牌号码": "粤A4****", |
| | | // "车辆类型": "小型轿车", |
| | | // "所有人": "黄**", |
| | | // "住址": "广东省从化市城郊街东风***********", |
| | | // "品牌型号": "别克1B*******71801S", |
| | | // "车辆识别代号": "LSGJ********44832", |
| | | // "发动机号码": "T18S********C", |
| | | // "注册日期": "2000-06-13", |
| | | // "发证日期": "2020-07-11", |
| | | // "使用性质": "非营运", |
| | | // "orderid":"JH1531180126114835937669", |
| | | // "userid":"1234567" |
| | | //} |
| | | ////VIN识别 |
| | | //{ |
| | | // "vin": "WBAFR7103BC727722", |
| | | // "orderid": "JH1531180524123006771818" |
| | | //} |
| | | ////营业执照 |
| | | //{ |
| | | //"reason": "操作成功", |
| | | //"result":{ |
| | | //"统一社会信用代码": "91110105MA01AMC6Q", |
| | | //"组织机构代码": "", |
| | | //"税务登记证号": "", |
| | | //"社保登记号": "", |
| | | //"统计证证号": "", |
| | | //"名称": "北京数字传奇网络科技有限公司", |
| | | //"类型": "有限责任公司(自然人投资或控股)", |
| | | //"住所": "北京市朝阳区将台乡驼房营路8号新华科技大厦21层2106室", |
| | | //"法定代表人": "吴发强", |
| | | //"组成形式": "", |
| | | //"注册资本": "100万元", |
| | | //"成立日期": "2018年03月21日", |
| | | //"营业期限": "2018年03月21日至长期", |
| | | //"经营范围": "技术开发、技术推广、技术咨询、技术服务。(企业依法自主\n选择经营项目,开展经营活班依法须经批准的顼目,经相关\n部门批准后依批准的内容开展经营活班不得从事本市产业政\n策禁止和限制类顼目的经营活动。)", |
| | | //"登记机关": "", |
| | | //"登记日期": "", |
| | | //"二维码": "http://qyxy.baic.gov.cn/wap/wap/creditWapAction!qr.dhtml?id=ff8080816242f1250162463d9d3168f3", |
| | | //"副本": "" |
| | | //}, |
| | | } |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.util.juhe; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 天气实况 |
| | | * @author pzb |
| | | * @Date 2023/2/20 11:38 |
| | | */ |
| | | @Data |
| | | public class Realtime { |
| | | /** |
| | | * 天气情况,如:晴、多云 |
| | | */ |
| | | private String info; |
| | | /** |
| | | * 天气标识id,可参考小接口2 |
| | | */ |
| | | private String wid; |
| | | /** |
| | | * 温度,可能为空 |
| | | */ |
| | | private String temperature; |
| | | /** |
| | | * 湿度,可能为空 |
| | | */ |
| | | private String humidity; |
| | | /** |
| | | * 风向,可能为空 |
| | | */ |
| | | private String direct; |
| | | /** |
| | | * 风力,可能为空 |
| | | */ |
| | | private String power; |
| | | /** |
| | | * 空气质量指数,可能为空 |
| | | */ |
| | | private String aqi; |
| | | } |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.util.juhe; |
| | | |
| | | import com.baomidou.mybatisplus.annotations.TableField; |
| | | import com.baomidou.mybatisplus.annotations.TableId; |
| | | import com.baomidou.mybatisplus.annotations.TableName; |
| | | import com.baomidou.mybatisplus.enums.IdType; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 天气相关城市 |
| | | * @author pzb |
| | | * @Date 2023/2/25 10:56 |
| | | */ |
| | | @Data |
| | | @TableName("t_weather_city") |
| | | public class WeatherCityInfo { |
| | | /** |
| | | * 主键 |
| | | */ |
| | | @TableId(value = "id", type = IdType.INPUT) |
| | | @TableField("id") |
| | | private Integer id; |
| | | /** |
| | | * 省 |
| | | */ |
| | | @TableField("province") |
| | | private String province; |
| | | /** |
| | | * 市 |
| | | */ |
| | | @TableField("city") |
| | | private String city; |
| | | /** |
| | | * 区 |
| | | */ |
| | | @TableField("district") |
| | | private String district; |
| | | } |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.util.juhe; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.stylefeng.guns.core.util.ToolUtil; |
| | | import com.stylefeng.guns.modular.system.util.httpClinet.HttpClientUtil; |
| | | import com.stylefeng.guns.modular.system.util.httpClinet.HttpResult; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | import java.util.List; |
| | | |
| | | |
| | | /** |
| | | * 天气工具类 |
| | | * @author pzb |
| | | * @Date 2023/2/18 16:54 |
| | | */ |
| | | public class WeatherUtil { |
| | | |
| | | static Logger logger = LoggerFactory.getLogger("ServiceLog"); |
| | | |
| | | private final static String weather_type = "[{\"wid\":\"00\",\"weather\":\"晴\"},{\"wid\":\"01\",\"weather\":\"多云\"},{\"wid\":\"02\",\"weather\":\"阴\"},{\"wid\":\"03\",\"weather\":\"阵雨\"},{\"wid\":\"04\",\"weather\":\"雷阵雨\"},{\"wid\":\"05\",\"weather\":\"雷阵雨伴有冰雹\"},{\"wid\":\"06\",\"weather\":\"雨夹雪\"},{\"wid\":\"07\",\"weather\":\"小雨\"},{\"wid\":\"08\",\"weather\":\"中雨\"},{\"wid\":\"09\",\"weather\":\"大雨\"},{\"wid\":\"10\",\"weather\":\"暴雨\"},{\"wid\":\"11\",\"weather\":\"大暴雨\"},{\"wid\":\"12\",\"weather\":\"特大暴雨\"},{\"wid\":\"13\",\"weather\":\"阵雪\"},{\"wid\":\"14\",\"weather\":\"小雪\"},{\"wid\":\"15\",\"weather\":\"中雪\"},{\"wid\":\"16\",\"weather\":\"大雪\"},{\"wid\":\"17\",\"weather\":\"暴雪\"},{\"wid\":\"18\",\"weather\":\"雾\"},{\"wid\":\"19\",\"weather\":\"冻雨\"},{\"wid\":\"20\",\"weather\":\"沙尘暴\"},{\"wid\":\"21\",\"weather\":\"小到中雨\"},{\"wid\":\"22\",\"weather\":\"中到大雨\"},{\"wid\":\"23\",\"weather\":\"大到暴雨\"},{\"wid\":\"24\",\"weather\":\"暴雨到大暴雨\"},{\"wid\":\"25\",\"weather\":\"大暴雨到特大暴雨\"},{\"wid\":\"26\",\"weather\":\"小到中雪\"},{\"wid\":\"27\",\"weather\":\"中到大雪\"},{\"wid\":\"28\",\"weather\":\"大到暴雪\"},{\"wid\":\"29\",\"weather\":\"浮尘\"},{\"wid\":\"30\",\"weather\":\"扬沙\"},{\"wid\":\"31\",\"weather\":\"强沙尘暴\"},{\"wid\":\"53\",\"weather\":\"霾\"}]"; |
| | | |
| | | private final static String bad_weather = "[{\"wid\":\"03\",\"weather\":\"阵雨\"},{\"wid\":\"04\",\"weather\":\"雷阵雨\"},{\"wid\":\"05\",\"weather\":\"雷阵雨伴有冰雹\"},{\"wid\":\"06\",\"weather\":\"雨夹雪\"},{\"wid\":\"07\",\"weather\":\"小雨\"},{\"wid\":\"08\",\"weather\":\"中雨\"},{\"wid\":\"09\",\"weather\":\"大雨\"},{\"wid\":\"10\",\"weather\":\"暴雨\"},{\"wid\":\"11\",\"weather\":\"大暴雨\"},{\"wid\":\"12\",\"weather\":\"特大暴雨\"},{\"wid\":\"13\",\"weather\":\"阵雪\"},{\"wid\":\"14\",\"weather\":\"小雪\"},{\"wid\":\"15\",\"weather\":\"中雪\"},{\"wid\":\"16\",\"weather\":\"大雪\"},{\"wid\":\"17\",\"weather\":\"暴雪\"},{\"wid\":\"19\",\"weather\":\"冻雨\"},{\"wid\":\"20\",\"weather\":\"沙尘暴\"},{\"wid\":\"21\",\"weather\":\"小到中雨\"},{\"wid\":\"22\",\"weather\":\"中到大雨\"},{\"wid\":\"23\",\"weather\":\"大到暴雨\"},{\"wid\":\"24\",\"weather\":\"暴雨到大暴雨\"},{\"wid\":\"25\",\"weather\":\"大暴雨到特大暴雨\"},{\"wid\":\"26\",\"weather\":\"小到中雪\"},{\"wid\":\"27\",\"weather\":\"中到大雪\"},{\"wid\":\"28\",\"weather\":\"大到暴雪\"},{\"wid\":\"30\",\"weather\":\"扬沙\"},{\"wid\":\"31\",\"weather\":\"强沙尘暴\"},{\"wid\":\"53\",\"weather\":\"霾\"}]"; |
| | | |
| | | private final static String key = "aaebb3e5c18fd371257a2ab6b5670efe"; |
| | | |
| | | private static HttpClientUtil httpClientUtil = new HttpClientUtil(); |
| | | |
| | | |
| | | /** |
| | | * 获取天气实况数据 |
| | | * @param city 要查询的城市名称/id,城市名称如:温州、上海、北京,需要utf8 urlencode |
| | | * @return |
| | | */ |
| | | public static Realtime queryNowWeather(String city){ |
| | | if(ToolUtil.isEmpty(city)){ |
| | | return null; |
| | | } |
| | | String url = "http://apis.juhe.cn/simpleWeather/query?city=" + city + "&key=" + key; |
| | | HttpResult httpResult = null; |
| | | try { |
| | | httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "json"); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | if(httpResult.getCode() != 200){ |
| | | logger.debug("查询天气失败:" + httpResult.getData()); |
| | | return null; |
| | | } |
| | | String data = httpResult.getData(); |
| | | JSONObject jsonObject = JSON.parseObject(data); |
| | | Integer error_code = jsonObject.getInteger("error_code"); |
| | | if(0 != error_code){ |
| | | logger.debug("查询天气失败:" + jsonObject.getString("reason")); |
| | | return null; |
| | | } |
| | | Realtime realtime = jsonObject.getObject("realtime", Realtime.class); |
| | | return realtime; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 查询是否是恶劣天气 |
| | | * @param city |
| | | * @return |
| | | */ |
| | | public static boolean isBadWeather(String city){ |
| | | if(null == city){ |
| | | return false; |
| | | } |
| | | Realtime realtime = queryNowWeather(city); |
| | | if(null == realtime){ |
| | | return false; |
| | | } |
| | | String wid = realtime.getWid(); |
| | | JSONArray badWeather = JSON.parseArray(bad_weather); |
| | | for (int i = 0; i < badWeather.size(); i++) { |
| | | JSONObject jsonObject = badWeather.getJSONObject(i); |
| | | String wid1 = jsonObject.getString("wid"); |
| | | if(wid.equals(wid1)){ |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取支持城市列表 |
| | | * @return |
| | | */ |
| | | public static List<WeatherCityInfo> queryCityList(){ |
| | | String url = "http://apis.juhe.cn/simpleWeather/cityList?key=" + key; |
| | | HttpResult httpResult = null; |
| | | try { |
| | | httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "json"); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | if(httpResult.getCode() != 200){ |
| | | logger.debug("查询支持城市失败:" + httpResult.getData()); |
| | | return null; |
| | | } |
| | | String data = httpResult.getData(); |
| | | JSONObject jsonObject = JSON.parseObject(data); |
| | | Integer error_code = jsonObject.getInteger("error_code"); |
| | | if(0 != error_code){ |
| | | logger.debug("查询支持城失败:" + jsonObject.getString("reason")); |
| | | return null; |
| | | } |
| | | JSONArray result = jsonObject.getJSONArray("result"); |
| | | List<WeatherCityInfo> weatherCities = result.toJavaList(WeatherCityInfo.class); |
| | | return weatherCities; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.util.mongodb; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.mongodb.BasicDBObject; |
| | | import com.mongodb.client.AggregateIterable; |
| | | import com.mongodb.client.MongoCursor; |
| | | import com.stylefeng.guns.modular.system.util.mongodb.model.Location; |
| | | import com.stylefeng.guns.modular.system.util.mongodb.model.LocationQuery; |
| | | import org.bson.Document; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.mongodb.core.MongoTemplate; |
| | | import org.springframework.data.mongodb.core.query.Criteria; |
| | | import org.springframework.data.mongodb.core.query.Query; |
| | | import org.springframework.data.mongodb.core.query.Update; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.*; |
| | | import java.util.Map.Entry; |
| | | import java.util.function.Supplier; |
| | | |
| | | |
| | | @Component |
| | | public class MongoUtils<T> { |
| | | |
| | | @Autowired |
| | | private MongoTemplate mongoTemplate; |
| | | |
| | | /** |
| | | * lambda |
| | | * @param data 添加数据 |
| | | * @param collectionName 表名 |
| | | */ |
| | | public void insert(Supplier<T> data,String collectionName){ |
| | | mongoTemplate.insert(data.get(),collectionName); |
| | | } |
| | | |
| | | public void insert(Object data, String collectionName){ |
| | | mongoTemplate.insert(data,collectionName); |
| | | } |
| | | |
| | | /** |
| | | * |
| | | * @param sp 查询条件lambda |
| | | * @param sets 更新的字段 |
| | | * @param collectionName 表名 |
| | | */ |
| | | public void update(Supplier<Criteria> sp, Supplier<Map<String,Object>> sets, String collectionName){ |
| | | Query query = Query.query(sp.get()); |
| | | Update update = new Update(); |
| | | |
| | | sets.get().forEach((key,value) ->{ |
| | | //System.out.println(key); |
| | | //System.out.println(value); |
| | | update.set(key,value); |
| | | }); |
| | | mongoTemplate.updateFirst(query, update, collectionName); |
| | | } |
| | | |
| | | public void update(Criteria sp, Supplier<Map<String,Object>> sets, String collectionName){ |
| | | Query query = Query.query(sp); |
| | | Update update = new Update(); |
| | | |
| | | sets.get().forEach((key,value) ->{ |
| | | //System.out.println(key); |
| | | //System.out.println(value); |
| | | update.set(key,value); |
| | | }); |
| | | mongoTemplate.updateFirst(query, update, collectionName); |
| | | } |
| | | |
| | | /**lambda |
| | | * @param sp 查询条件lambda |
| | | * @param collectionName 表名 |
| | | * @return |
| | | */ |
| | | public List<T> query(Supplier<Criteria> sp, String collectionName, Class entityClass){ |
| | | Query query = Query.query(sp.get()); |
| | | List<T> ts = mongoTemplate.find(query,entityClass,collectionName); |
| | | |
| | | return ts; |
| | | } |
| | | |
| | | public List<T> query(Criteria sp, String collectionName, Class entityClass){ |
| | | Query query = Query.query(sp); |
| | | List<T> ts = mongoTemplate.find(query,entityClass,collectionName); |
| | | |
| | | return ts; |
| | | } |
| | | |
| | | /** |
| | | * @param sp 查询条件lambda |
| | | * @param collectionName 表名 |
| | | * @return |
| | | */ |
| | | public void delete(Supplier<Criteria> sp, String collectionName){ |
| | | Query query = Query.query(sp.get()); |
| | | mongoTemplate.remove(query, collectionName); |
| | | } |
| | | |
| | | public void delete(Criteria sp, String collectionName){ |
| | | Query query = Query.query(sp); |
| | | mongoTemplate.remove(query, collectionName); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 查询符合条件总条数 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public long findLogCount(HashMap<String,Object> paras,Class entityClass,String collectionName) throws Exception { |
| | | Query query = new Query(); |
| | | Criteria criteria = new Criteria(); |
| | | if (null != paras ) { |
| | | Iterator<Entry<String, Object>> iterator = paras.entrySet().iterator(); |
| | | while(iterator.hasNext()) { |
| | | Entry<String, Object> entry = iterator.next(); |
| | | String key = entry.getKey(); |
| | | Object value = entry.getValue(); |
| | | criteria.and(key).is(value); |
| | | |
| | | } |
| | | query.addCriteria(criteria); |
| | | } |
| | | long count = mongoTemplate.count(query, entityClass,collectionName); |
| | | |
| | | return count; |
| | | } |
| | | |
| | | /** |
| | | * 查询附近的对象 |
| | | * @param model |
| | | * @return |
| | | */ |
| | | public List<Location> geoNear(LocationQuery model){ |
| | | List<Location> resultList = new ArrayList<>(); |
| | | try{ |
| | | List<BasicDBObject> pipeLine = new ArrayList<>(); |
| | | BasicDBObject aggregate = new BasicDBObject("$geoNear", |
| | | new BasicDBObject("near" |
| | | , new BasicDBObject("type", "Point") |
| | | .append("coordinates", model.getCoordinates())) |
| | | .append("distanceField", "distance") |
| | | .append("maxDistance", model.getDistance()) |
| | | .append("spherical", true) |
| | | |
| | | ); |
| | | |
| | | pipeLine.add(aggregate); |
| | | AggregateIterable<Document> location = mongoTemplate.getCollection("location").aggregate(pipeLine); |
| | | MongoCursor<Document> cursor = location.iterator(); |
| | | |
| | | //将查询的结果,封装成对象返回出去 |
| | | while (cursor.hasNext()) { |
| | | org.bson.Document document = cursor.next(); |
| | | Location node = JSONObject.parseObject(JSONObject.toJSONString(document),Location.class); |
| | | resultList.add(node); |
| | | } |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | } |
| | | return resultList; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.util.mongodb.model; |
| | | |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | public class GeoJson { |
| | | private String type; |
| | | private Double[] coordinates; |
| | | } |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.util.mongodb.model; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | import org.springframework.data.annotation.Id; |
| | | import org.springframework.data.mongodb.core.geo.GeoJsonPoint; |
| | | import org.springframework.data.mongodb.core.index.CompoundIndex; |
| | | import org.springframework.data.mongodb.core.mapping.Document; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | |
| | | @Data |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | @Document(collection = "driver_location") |
| | | @CompoundIndex(name = "location_index", def = "{'location': '2dsphere'}") |
| | | public class Location implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 4508868382007529970L; |
| | | |
| | | @Id |
| | | private String id; |
| | | /** |
| | | * 司机id |
| | | */ |
| | | private Integer driverId; |
| | | /** |
| | | * x:经度 y:纬度 |
| | | */ |
| | | private GeoJsonPoint location; |
| | | /** |
| | | * 位置名称 |
| | | **/ |
| | | private String name; |
| | | /** |
| | | * 创建时间 |
| | | */ |
| | | private Long created; |
| | | /** |
| | | * 更新时间 |
| | | */ |
| | | private Long updated; |
| | | /** |
| | | * 上次更新时间 |
| | | */ |
| | | private Long lastUpdated; |
| | | |
| | | } |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.util.mongodb.model; |
| | | |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | public class LocationQuery { |
| | | /** |
| | | * 当前经纬度[xxx,xxx] |
| | | **/ |
| | | private Double[] coordinates; |
| | | /** |
| | | * 距离,如:200,500,1,3,5,10,20 |
| | | **/ |
| | | private Double distance; |
| | | /** |
| | | * 距离单位,如:m,km |
| | | **/ |
| | | private String unit; |
| | | /** |
| | | * 位置类型:1-景点,2-加油站,3-酒店 |
| | | **/ |
| | | private Integer type; |
| | | } |
| | |
| | | - dataSourceGuns |
| | | - dataSourceBiz |
| | | |
| | | |
| | | --- |
| | | |
| | | spring: |
| | | data: |
| | | mongodb: |
| | | # uri: mongodb://root:bv@_N36o+cTe1LpS@127.0.0.1:27017/admin |
| | | uri: mongodb://127.0.0.1:27017/admin |
| | | |
| | | --- |
| | | |
| | | filePath: /usr/local/server/app/orderPostionFile/ #存储订单轨迹文件路径 |
| | |
| | | } |
| | | //提交信息 |
| | | var ajax = new $ax(Feng.ctxPath + "/tOrder/add", function(data){ |
| | | Feng.success("添加成功!"); |
| | | window.parent.TOrder.table.refresh(); |
| | | TOrderInfoDlg.close(); |
| | | if(data.code == 200){ |
| | | Feng.success("添加成功!"); |
| | | window.parent.TOrder.table.refresh(); |
| | | TOrderInfoDlg.close(); |
| | | }else{ |
| | | Feng.error(data.msg); |
| | | } |
| | | },function(data){ |
| | | Feng.error("添加失败!" + data.responseJSON.message + "!"); |
| | | }); |
| | | ajax.set(this.tOrderInfoData); |
| | | ajax.set('startAddress', JSON.stringify(TOrderInfoDlg.startAddress)); |
| | | ajax.set('endAddress', null == endAddress ? "" : JSON.stringify(TOrderInfoDlg.endAddress)); |
| | | ajax.set('endAddress', null == TOrderInfoDlg.endAddress ? "" : JSON.stringify(TOrderInfoDlg.endAddress)); |
| | | ajax.start(); |
| | | } |
| | | |