package com.supersavedriving.driver.modular.system.service.impl;
|
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONObject;
|
import com.baomidou.mybatisplus.mapper.EntityWrapper;
|
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
|
import com.supersavedriving.driver.core.common.constant.JwtConstants;
|
import com.supersavedriving.driver.core.shiro.ShiroKit;
|
import com.supersavedriving.driver.core.shiro.ShiroUser;
|
import com.supersavedriving.driver.core.util.JwtTokenUtil;
|
import com.supersavedriving.driver.core.util.ToolUtil;
|
import com.supersavedriving.driver.modular.system.dao.DriverMapper;
|
import com.supersavedriving.driver.modular.system.model.BranchOffice;
|
import com.supersavedriving.driver.modular.system.model.Driver;
|
import com.supersavedriving.driver.modular.system.model.DriverWork;
|
import com.supersavedriving.driver.modular.system.service.IBranchOfficeService;
|
import com.supersavedriving.driver.modular.system.service.IDriverService;
|
import com.supersavedriving.driver.modular.system.service.IDriverWorkService;
|
import com.supersavedriving.driver.modular.system.service.IOrderPositionService;
|
import com.supersavedriving.driver.modular.system.util.RedisUtil;
|
import com.supersavedriving.driver.modular.system.util.ResultUtil;
|
import com.supersavedriving.driver.modular.system.util.UUIDUtil;
|
import com.supersavedriving.driver.modular.system.util.mongodb.model.Location;
|
import com.supersavedriving.driver.modular.system.warpper.DriverPositionWarpper;
|
import com.supersavedriving.driver.modular.system.warpper.DriverRegisterWarpper;
|
import com.supersavedriving.driver.modular.system.warpper.TokenWarpper;
|
import org.apache.shiro.authc.SimpleAuthenticationInfo;
|
import org.apache.shiro.authc.UsernamePasswordToken;
|
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
|
import org.apache.shiro.crypto.hash.Md5Hash;
|
import org.apache.shiro.util.ByteSource;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Value;
|
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.data.mongodb.core.query.Update;
|
import org.springframework.stereotype.Service;
|
|
import javax.servlet.http.HttpServletRequest;
|
import java.io.File;
|
import java.io.FileWriter;
|
import java.io.PrintWriter;
|
import java.util.ArrayList;
|
import java.util.Date;
|
import java.util.List;
|
import java.util.Objects;
|
|
import static org.bouncycastle.asn1.x500.style.RFC4519Style.c;
|
|
/**
|
* 司机
|
* @author pzb
|
* @Date 2023/2/8 18:52
|
*/
|
@Service
|
public class DriverServiceImpl extends ServiceImpl<DriverMapper, Driver> implements IDriverService {
|
|
private final String salt = "i#sm4";
|
|
@Autowired
|
private IBranchOfficeService branchOfficeService;
|
|
@Autowired
|
private RedisUtil redisUtil;
|
|
@Autowired
|
private MongoTemplate mongoTemplate;
|
|
@Autowired
|
private IOrderPositionService orderPositionService;
|
|
@Autowired
|
private IDriverWorkService driverWorkService;
|
|
@Value("${filePath}")
|
private String filePath;
|
|
|
/**
|
* 司机注册
|
* @param driverRegisterWarpper
|
* @return
|
* @throws Exception
|
*/
|
@Override
|
public ResultUtil driverRegister(DriverRegisterWarpper driverRegisterWarpper) throws Exception {
|
Driver driver = this.selectOne(new EntityWrapper<Driver>().eq("phone", driverRegisterWarpper.getPhone()).ne("status", 3));
|
if(null != driver && driver.getStatus() == 2){
|
return ResultUtil.error("该手机账号已被冻结,请联系管理员。");
|
}
|
if(null != driver && driver.getApprovalStatus() == 1){
|
return ResultUtil.error("该手机账号正在审核中。");
|
}
|
if(null != driver && driver.getApprovalStatus() == 2){
|
return ResultUtil.error("该手机账号已审核通过,请直接登录。");
|
}
|
|
//账号审核拒绝后的处理
|
if(null != driver && driver.getApprovalStatus() == 3){
|
try {
|
driver = setDriverParamete(driver, driverRegisterWarpper);
|
}catch (Exception e){
|
return ResultUtil.error(e.getMessage());
|
}
|
this.updateAllColumnById(driver);
|
}
|
//新账号
|
if(null == driver){
|
driver = new Driver();
|
driver.setCode(UUIDUtil.getNumberRandom(16));
|
try {
|
driver = setDriverParamete(driver, driverRegisterWarpper);
|
}catch (Exception e){
|
return ResultUtil.error(e.getMessage());
|
}
|
driver.setCreateTime(new Date());
|
this.insert(driver);
|
}
|
return ResultUtil.success();
|
}
|
|
|
/**
|
* 组装个人信息
|
* @param driver
|
* @param driverRegisterWarpper
|
* @return
|
*/
|
public Driver setDriverParamete(Driver driver, DriverRegisterWarpper driverRegisterWarpper) throws Exception{
|
driver.setAvatar(driverRegisterWarpper.getAvatar());
|
driver.setPhone(driverRegisterWarpper.getPhone());
|
driver.setEmergencyContact(driverRegisterWarpper.getEmergencyContact());
|
driver.setEmergencyPhone(driverRegisterWarpper.getEmergencyPhone());
|
driver.setIdcardBack(driverRegisterWarpper.getIdcardBack());
|
driver.setIdcardFront(driverRegisterWarpper.getIdcardFront());
|
driver.setDriverLicense(driverRegisterWarpper.getDriverLicense());
|
//注册地
|
String code = driverRegisterWarpper.getCode();
|
BranchOffice branchOffice = branchOfficeService.selectOne(new EntityWrapper<BranchOffice>().eq("districtCode", code).eq("status", 1));
|
if(null == branchOffice){
|
throw new Exception("该区域无服务商");
|
}
|
driver.setBranchOfficeId(branchOffice.getId());
|
driver.setAgentId(branchOffice.getAgentId());
|
driver.setInviterType(driverRegisterWarpper.getInviterType());
|
driver.setInviterId(driverRegisterWarpper.getInviterId());
|
driver.setApprovalStatus(1);
|
driver.setApprovalNotes("");
|
driver.setApprovalTime(null);
|
driver.setApprovalUserId(null);
|
driver.setStatus(1);
|
return driver;
|
}
|
|
|
/**
|
* 司机登录逻辑
|
* @param receiver 国家代码+86
|
* @param phone 登录手机号
|
* @param code 短信验证码
|
* @return
|
* @throws Exception
|
*/
|
@Override
|
public ResultUtil<TokenWarpper> driverLogin(String receiver, String phone, String code) throws Exception {
|
String value = redisUtil.getValue(receiver + phone);
|
if(ToolUtil.isEmpty(value)){
|
return ResultUtil.error("短信验证码无效");
|
}
|
if(!value.equals(code)){
|
return ResultUtil.error("短信验证码无效");
|
}
|
Driver driver = this.selectOne(new EntityWrapper<Driver>().eq("phone", phone).ne("status", 3));
|
if(null == driver){
|
return ResultUtil.error("请先进行注册");
|
}
|
if(driver.getStatus() == 2){
|
return ResultUtil.error("账号已被冻结,请联系管理员。");
|
}
|
if(driver.getApprovalStatus() == 1){
|
return ResultUtil.error("账号正在审核中。");
|
}
|
if(driver.getApprovalStatus() == 3){
|
return ResultUtil.error("账号审核不通过,请重新申请。");
|
}
|
String token = getToken(phone, code);
|
if(ToolUtil.isEmpty(token)){
|
return ResultUtil.error("登录异常,请联系管理员。");
|
}
|
TokenWarpper tokenWarpper = new TokenWarpper();
|
tokenWarpper.setToken(token);
|
tokenWarpper.setValidTime(7200L);
|
tokenWarpper.setIsSetPassword(ToolUtil.isEmpty(driver.getPassword()) ? 0 : 1);
|
return ResultUtil.success(tokenWarpper);
|
}
|
|
|
/**
|
* 司机密码登录
|
* @param receiver 国家代码+86
|
* @param phone 手机号
|
* @param password 密码
|
* @return
|
* @throws Exception
|
*/
|
@Override
|
public ResultUtil<TokenWarpper> driverPassLogin(String receiver, String phone, String password) throws Exception {
|
Driver driver = this.selectOne(new EntityWrapper<Driver>().eq("phone", phone).ne("status", 3));
|
if(null == driver){
|
return ResultUtil.error("请先进行注册");
|
}
|
if(driver.getStatus() == 2){
|
return ResultUtil.error("账号已被冻结,请联系管理员。");
|
}
|
if(driver.getApprovalStatus() == 1){
|
return ResultUtil.error("账号正在审核中。");
|
}
|
if(driver.getApprovalStatus() == 3){
|
return ResultUtil.error("账号审核不通过,请重新申请。");
|
}
|
if(!driver.getPassword().equals(ShiroKit.md5(password, salt))){
|
return ResultUtil.error("账号密码错误。");
|
}
|
String token = getToken(phone, password);
|
if(ToolUtil.isEmpty(token)){
|
return ResultUtil.error("登录异常,请联系管理员。");
|
}
|
TokenWarpper tokenWarpper = new TokenWarpper();
|
tokenWarpper.setToken(token);
|
tokenWarpper.setValidTime(7200L);
|
tokenWarpper.setIsSetPassword(ToolUtil.isEmpty(driver.getPassword()) ? 0 : 1);
|
return ResultUtil.success(tokenWarpper);
|
}
|
|
/**
|
* 获取身份凭证
|
* @param phone
|
* @param password
|
* @return
|
* @throws Exception
|
*/
|
private String getToken(String phone, String password) throws Exception{
|
//封装请求账号密码为shiro可验证的token
|
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(phone, password.toCharArray());
|
|
//获取数据库中的账号密码,准备比对
|
String credentials = ShiroKit.md5(password, salt);
|
Driver driver = this.selectOne(new EntityWrapper<Driver>().eq("phone", phone).eq("status", 1));
|
ByteSource credentialsSalt = new Md5Hash(salt);
|
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
|
new ShiroUser(), credentials, credentialsSalt, "");
|
|
//校验用户账号密码
|
HashedCredentialsMatcher md5CredentialsMatcher = new HashedCredentialsMatcher();
|
md5CredentialsMatcher.setHashAlgorithmName(ShiroKit.hashAlgorithmName);
|
md5CredentialsMatcher.setHashIterations(ShiroKit.hashIterations);
|
boolean passwordTrueFlag = md5CredentialsMatcher.doCredentialsMatch(
|
usernamePasswordToken, simpleAuthenticationInfo);
|
|
if (passwordTrueFlag) {
|
String token = JwtTokenUtil.generateToken(phone);
|
String key = token;
|
if(token.length() > 16){
|
key = token.substring(token.length() - 16);
|
}
|
redisUtil.setStrValue(key, driver.getId().toString(), 7200);//2小时
|
return token;
|
}
|
return "";
|
}
|
|
|
/**
|
* 刷新token
|
* @param uid
|
* @return
|
* @throws Exception
|
*/
|
@Override
|
public ResultUtil<TokenWarpper> flushedToken(Integer uid) throws Exception {
|
Driver driver = this.selectById(uid);
|
String token = getToken(driver.getPhone(), driver.getPhone());
|
if(ToolUtil.isEmpty(token)){
|
return ResultUtil.error("刷新token异常,请联系管理员。");
|
}
|
TokenWarpper tokenWarpper = new TokenWarpper();
|
tokenWarpper.setToken(token);
|
tokenWarpper.setValidTime(7200L);
|
tokenWarpper.setIsSetPassword(ToolUtil.isEmpty(driver.getPassword()) ? 0 : 1);
|
return ResultUtil.success(tokenWarpper);
|
}
|
|
/**
|
* 校验token获取用户信息
|
* @param request
|
* @return
|
* @throws Exception
|
*/
|
@Override
|
public Integer getUserByRequset(HttpServletRequest request) throws Exception {
|
String requestHeader = request.getHeader(JwtConstants.AUTH_HEADER);
|
if (ToolUtil.isNotEmpty(requestHeader) && requestHeader.startsWith("Bearer ")) {
|
requestHeader = requestHeader.substring(requestHeader.indexOf(" ") + 1);
|
String key = null;
|
int length = requestHeader.length();
|
if(length > 16){
|
key = requestHeader.substring(length - 16);
|
}else{
|
key = requestHeader;
|
}
|
String value = redisUtil.getValue(key);
|
return null != value ? Integer.valueOf(value) : null;
|
}else{
|
return null;
|
}
|
}
|
|
|
/**
|
* 设置司机密码
|
* @param uid
|
* @param password
|
* @throws Exception
|
*/
|
@Override
|
public void setPassword(Integer uid, String password) throws Exception {
|
Driver driver = this.selectById(uid);
|
driver.setPassword(ShiroKit.md5(password, salt));
|
this.updateById(driver);
|
}
|
|
|
@Override
|
public ResultUtil<List<String>> queryDriverPosition(Integer uid) throws Exception {
|
DriverWork driverWork = driverWorkService.selectOne(new EntityWrapper<DriverWork>().eq("driverId", uid).eq("status", 1));
|
if(null == driverWork){
|
return ResultUtil.error("请先上班");
|
}
|
String value = redisUtil.getValue("DRIVER" + uid);
|
List<String> list = new ArrayList<>();
|
if(ToolUtil.isNotEmpty(value)){
|
String[] split = value.split(",");
|
String lon = split[0];
|
String lat = split[1];
|
//找到中心点
|
GeoJsonPoint geoJsonPoint = new GeoJsonPoint(Double.valueOf(lon), Double.valueOf(lat));
|
//构造半径
|
Distance distanceR = new Distance(5D, 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);
|
locations.forEach(s -> {
|
list.add(s.getLocation().getX() + "," + s.getLocation().getY());
|
});
|
}
|
return ResultUtil.success(list);
|
}
|
|
|
|
@Override
|
public void addDriverPosition(DriverPositionWarpper driverPositionWarpper) throws Exception {
|
//实时位置存入redis中
|
Double lon = driverPositionWarpper.getLon();
|
Double lat = driverPositionWarpper.getLat();
|
Integer driverId = driverPositionWarpper.getDriverId();
|
Integer orderId = driverPositionWarpper.getOrderId();
|
redisUtil.setStrValue("DRIVER" + driverId, lon + "," + lat, 30);
|
Query query = Query.query(Criteria.where("driverId").is(driverId));
|
Location old = this.mongoTemplate.findOne(query, Location.class);
|
if (Objects.isNull(old)) {
|
old = new Location();
|
old.setDriverId(driverId);
|
old.setLocation(new GeoJsonPoint(lon, lat));
|
old.setUpdated(System.currentTimeMillis());
|
old.setLastUpdated(System.currentTimeMillis());
|
this.mongoTemplate.save(old);
|
} else {
|
//更新
|
Update update = Update
|
.update("location", new GeoJsonPoint(lon, lat))
|
.set("updated", System.currentTimeMillis())
|
.set("lastUpdated", System.currentTimeMillis());
|
this.mongoTemplate.updateFirst(query, update, Location.class);
|
}
|
|
//存储订单轨迹
|
if(null != orderId){
|
orderPositionService.saveOrderPosition(driverPositionWarpper);
|
}
|
|
}
|
|
|
|
}
|