ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/GaoDeMapUtil.java
@@ -189,14 +189,16 @@ public static Result<CityInfoVO> getAddressInfo(String address) { // 返回起始地startAddr与目的地endAddr之间的距离,单位:米 String queryUrl = "https://restapi.amap.com/v3/geocode/geo?address=" + address + "&key=" + GAO_DE_KEY; + "&output=json&key=" + GAO_DE_KEY; String queryResult = getResponse(queryUrl); GaoDeAddressInfoVO data = JSONObject.parseObject(queryResult, GaoDeAddressInfoVO.class); List<Geocodes> geocodes = data.getGeocodes(); Geocodes info = geocodes.get(0); String adcode = info.getAdcode(); String city = info.getCity(); return Result.succeed(new CityInfoVO(city, adcode), "距离计算成功!"); String location = info.getLocation(); String[] split = location.split(","); return Result.succeed(new CityInfoVO(city, adcode,Double.valueOf(split[0]),Double.valueOf(split[1])), "距离计算成功!"); } /** ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/vo/CityInfoVO.java
@@ -13,12 +13,16 @@ private String city; private String code; private Double longitude; private Double latitude; public CityInfoVO() { } public CityInfoVO(String city, String code) { public CityInfoVO(String city, String code,Double longitude,Double latitude) { this.city = city; this.code = code; this.longitude = longitude; this.latitude = latitude; } } ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/vo/Geocodes.java
@@ -24,4 +24,6 @@ private String adcode; private String location; } ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/OrderController.java
@@ -1,13 +1,19 @@ package com.ruoyi.admin.controller; import cn.hutool.http.HttpStatus; import com.alibaba.excel.EasyExcel; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.admin.entity.*; import com.ruoyi.admin.importExcel.DemoDataListener; import com.ruoyi.admin.importExcel.FrozenBuckleImportDTO; import com.ruoyi.admin.netty.NettyChannelMap; import com.ruoyi.admin.netty.NettyWebSocketController; import com.ruoyi.admin.service.*; import com.ruoyi.admin.utils.DescribeInstances; import com.ruoyi.admin.utils.HttpUtil; import com.ruoyi.admin.vo.OrderByServeRecordVO; import com.ruoyi.admin.vo.OrderDetailVO; import com.ruoyi.admin.vo.OrderReasinDto; @@ -16,7 +22,10 @@ import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.utils.DateUtils; import com.ruoyi.common.core.utils.GaoDeMapUtil; import com.ruoyi.common.core.utils.SnowflakeIdWorker; import com.ruoyi.common.core.utils.bean.BeanUtils; import com.ruoyi.common.core.vo.CityInfoVO; import com.ruoyi.common.core.vo.PaperInVo; import com.ruoyi.common.core.vo.PrintDto; import com.ruoyi.common.redis.service.RedisService; @@ -37,8 +46,11 @@ import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import java.io.BufferedInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; import java.nio.file.Files; import java.nio.file.Paths; @@ -47,13 +59,17 @@ import java.util.stream.Collectors; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; /** * <p> @@ -63,6 +79,7 @@ * @author hjl * @since 2024-05-29 */ @Slf4j @RestController @RequestMapping("/order") @Api(tags = {"后台-订单管理"}) @@ -745,6 +762,126 @@ // return R.ok(list); // } /** * 管理后台-订单导入 */ @ApiOperation(value = "订单导入", tags = {"管理后台"}) @PostMapping(value = "/importOrder") public R<String> importOrder(@RequestParam("file") MultipartFile file) { if (!file.isEmpty()) { //文件名称 int begin = Objects.requireNonNull(file.getOriginalFilename()).indexOf("."); //文件名称长度 int last = file.getOriginalFilename().length(); //判断文件格式是否正确 String fileName = file.getOriginalFilename().substring(begin, last); if (!fileName.endsWith(".xls") && !fileName.endsWith(".xlsx")) { throw new IllegalArgumentException("上传文件格式错误"); } } else { throw new IllegalArgumentException("文件不能为空"); } try (InputStream inputStream = file.getInputStream()) { return simpleRead(inputStream); } catch (IOException e) { System.out.println(e.getMessage()); } return R.ok(); } /** * 最简单的读的监听器 */ private R<String> simpleRead(InputStream inputStream){ //获取正确数据 ArrayList<FrozenBuckleImportDTO> successArrayList = new ArrayList<>(); //获取错误数据 EasyExcel.read(inputStream) .head(FrozenBuckleImportDTO.class) .registerReadListener(new DemoDataListener( // 监听器中doAfterAllAnalysed执行此方法;所有读取完成之后处理逻辑 successArrayList::addAll)) // 设置sheet,默认读取第一个 .sheet() // 设置标题(字段列表)所在行数 .headRowNumber(2) .doRead(); System.err.println(successArrayList); List<Site> sites = siteService.list(Wrappers.lambdaQuery(Site.class).eq(Site::getIsDelete, 0)); List<MasterWorker> masterWorkers = masterWorkerService.list(Wrappers.lambdaQuery(MasterWorker.class).eq(MasterWorker::getIsDelete, 0)); List<RecoveryServe> recoveryServes =recoveryServeService.list(Wrappers.lambdaQuery(RecoveryServe.class).eq(RecoveryServe::getIsDelete, 0)); for (FrozenBuckleImportDTO frozenBuckleImportDTO : successArrayList) { OrderRequest order = new OrderRequest(); BeanUtils.copyProperties(frozenBuckleImportDTO,order); String province = frozenBuckleImportDTO.getProvince(); String city = frozenBuckleImportDTO.getCity(); String area = frozenBuckleImportDTO.getArea(); String address = frozenBuckleImportDTO.getReservationAddress(); // 解析地址经纬度 CityInfoVO cityInfoVO = GaoDeMapUtil.getAddressInfo(province + city + area + address).getDatas(); String areaCode = cityInfoVO.getCode(); String provinceCode = areaCode.substring(0, 2) + "0000"; String cityCode = areaCode.substring(0, 4) + "00"; order.setProvinceCode(provinceCode); order.setCityCode(cityCode); order.setAreaCode(areaCode); order.setLongitude(cityInfoVO.getLongitude()); order.setLatitude(cityInfoVO.getLatitude()); // 站点信息 Site site = sites.stream().filter(e -> e.getSiteName().equals(frozenBuckleImportDTO.getSiteName())).findFirst().orElse(null); if(Objects.nonNull(site)){ order.setSiteId(site.getId()); } // 师傅信息 if (StringUtils.hasLength(order.getServerName())) { MasterWorker masterWorker = masterWorkers.stream().filter(e -> e.getRealName().equals(frozenBuckleImportDTO.getServerName())).findFirst().orElse(null); if(Objects.nonNull(masterWorker)){ order.setServerId(masterWorker.getId()); order.setServerPhone(masterWorker.getPhone()); } order.setAcceptTime(new Date()); // 待上门 order.setState(Constants.ONE); } else { // 待派单状态 order.setState(Constants.ZERO); } // 后台订单 order.setType(Constants.ONE); order.setSubsidy(BigDecimal.ZERO); order.setOrderNumber(String.valueOf(SNOW_FLAKE_ID_WORKER.nextId())); // 回收服务信息 RecoveryServe recoveryServe = recoveryServes.stream().filter(e->e.getServeName().equals(frozenBuckleImportDTO.getServeName())).findFirst().orElse(null); if(Objects.nonNull(recoveryServe)){ order.setServeId(recoveryServe.getId()); order.setServePrice(recoveryServe.getDefaultPrice()); } RecoveryServePrice one = recoveryServePriceService.lambdaQuery().eq(RecoveryServePrice::getCity, order.getCityCode()).eq(RecoveryServePrice::getRecoveryServeId, order.getServeId()).eq(BaseEntity::getIsDelete, 0).one(); if (one==null) { order.setOrderMoney(recoveryServe.getDefaultPrice()); }else { order.setOrderMoney(one.getRecoveryPrice()); } Boolean data = orderClient.save(order).getData(); if (null == data) { return R.fail(orderClient.save(order).getMsg()); } System.out.println("服务人员id:" + order.getServerId()); ChannelHandlerContext context = NettyChannelMap.getData(String.valueOf(order.getServerId())); System.out.println("socket连接信息:" + context); if (null != context) { System.out.println("服务端发送消息到: " + order.getServerId()); NettyWebSocketController.sendMsgToClient(context, "您有一条新的订单,请注意查收!"); } return data ? R.ok() : R.fail(); } return R.ok(); } } ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/importExcel/DemoDataListener.java
New file @@ -0,0 +1,39 @@ package com.ruoyi.admin.importExcel; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.google.common.collect.Lists; import org.apache.commons.collections4.CollectionUtils; import java.util.List; import java.util.function.Consumer; /** * 读取excel数据 */ public class DemoDataListener extends AnalysisEventListener<FrozenBuckleImportDTO> { /**临时存储正常数据集合,最大存储100*/ private List<FrozenBuckleImportDTO> successDataList = Lists.newArrayListWithExpectedSize(100); /**自定义消费者函数接口用于自定义监听器中数据组装*/ private final Consumer<List<FrozenBuckleImportDTO>> successConsumer; public DemoDataListener(Consumer<List<FrozenBuckleImportDTO>> successConsumer) { this.successConsumer = successConsumer; } @Override public void invoke(FrozenBuckleImportDTO goodsImportExcel, AnalysisContext analysisContext) { successDataList.add(goodsImportExcel); System.out.println("数据:"+goodsImportExcel); } @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { if (CollectionUtils.isNotEmpty(successDataList)) { successConsumer.accept(successDataList); } } } ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/importExcel/FrozenBuckleImportDTO.java
New file @@ -0,0 +1,47 @@ package com.ruoyi.admin.importExcel; import com.alibaba.excel.annotation.ExcelProperty; import lombok.Data; import java.io.Serializable; /** * 导入模板 */ @Data public class FrozenBuckleImportDTO implements Serializable { @ExcelProperty(value = "站点名称") private String siteName; @ExcelProperty(value = "服务信息") private String serveName; @ExcelProperty(value = "预约姓名") private String reservationName; @ExcelProperty(value = "预约电话") private String reservationPhone; @ExcelProperty(value = "省份") private String province; @ExcelProperty(value = "市") private String city; @ExcelProperty(value = "区") private String area; @ExcelProperty(value = "详细地址") private String reservationAddress; @ExcelProperty(value = "上门时间") private String custClass; @ExcelProperty(value = "服务人员") private String serverName; @ExcelProperty(value = "备注") private String reservationRemark; private Integer siteId; private Integer serverId; private Integer serveId; private Double longitude; private Double latitude; private String provinceCode; private String cityCode; private String areaCode; private String serverPhone; } ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/utils/HttpUtil.java
New file @@ -0,0 +1,312 @@ package com.ruoyi.admin.utils; import com.ruoyi.common.core.constant.Constants; import com.ruoyi.common.core.exception.ServiceException; import com.ruoyi.common.core.utils.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.net.ssl.*; import java.io.*; import java.net.*; import java.nio.charset.StandardCharsets; import java.security.cert.X509Certificate; /** * 通用http发送方法 * * @author ruoyi */ public class HttpUtil { private static final Logger log = LoggerFactory.getLogger(HttpUtils.class); /** * 向指定 URL 发送GET方法的请求 * * @param url 发送请求的 URL * @return 所代表远程资源的响应结果 */ public static String sendGet(String url) { return sendGet(url, StringUtils.EMPTY); } /** * 向指定 URL 发送GET方法的请求 * * @param url 发送请求的 URL * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @return 所代表远程资源的响应结果 */ public static String sendGet(String url, String param) { return sendGet(url, param, Constants.UTF8); } /** * 向指定 URL 发送GET方法的请求 * * @param url 发送请求的 URL * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @param contentType 编码类型 * @return 所代表远程资源的响应结果 */ public static String sendGet(String url, String param, String contentType) { StringBuilder result = new StringBuilder(); BufferedReader in = null; try { String urlNameString = StringUtils.isNotBlank(param) ? url + "?" + param : url; log.info("sendGet - {}", urlNameString); URL realUrl = new URL(urlNameString); URLConnection connection = realUrl.openConnection(); connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); connection.connect(); in = new BufferedReader(new InputStreamReader(connection.getInputStream(), contentType)); String line; while ((line = in.readLine()) != null) { result.append(line); } log.info("recv - {}", result); } catch (ConnectException e) { log.error("调用HttpUtils.sendGet ConnectException, url=" + url + ",param=" + param, e); } catch (SocketTimeoutException e) { log.error("调用HttpUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e); } catch (IOException e) { log.error("调用HttpUtils.sendGet IOException, url=" + url + ",param=" + param, e); } catch (Exception e) { log.error("调用HttpsUtil.sendGet Exception, url=" + url + ",param=" + param, e); } finally { try { if (in != null) { in.close(); } } catch (Exception ex) { log.error("调用in.close Exception, url=" + url + ",param=" + param, ex); } } return result.toString(); } /** * 向指定 URL 发送POST方法的请求 * * @param url 发送请求的 URL * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @return 所代表远程资源的响应结果 */ public static String sendPost(String url, String param) { PrintWriter out = null; BufferedReader in = null; StringBuilder result = new StringBuilder(); try { log.info("sendPost - {}", url); URL realUrl = new URL(url); URLConnection conn = realUrl.openConnection(); conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); conn.setRequestProperty("Accept-Charset", "utf-8"); conn.setRequestProperty("contentType", "utf-8"); conn.setDoOutput(true); conn.setDoInput(true); out = new PrintWriter(conn.getOutputStream()); out.print(param); out.flush(); in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8)); String line; while ((line = in.readLine()) != null) { result.append(line); } log.info("recv - {}", result); } catch (ConnectException e) { log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e); } catch (SocketTimeoutException e) { log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e); } catch (IOException e) { log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e); } catch (Exception e) { log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e); } finally { try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (IOException ex) { log.error("调用in.close Exception, url=" + url + ",param=" + param, ex); } } return result.toString(); } public static String sendSSLPost(String url, String param) { StringBuilder result = new StringBuilder(); String urlNameString = url + "?" + param; try { log.info("sendSSLPost - {}", urlNameString); SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom()); URL console = new URL(urlNameString); HttpsURLConnection conn = (HttpsURLConnection) console.openConnection(); conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); conn.setRequestProperty("Accept-Charset", "utf-8"); conn.setRequestProperty("contentType", "utf-8"); conn.setDoOutput(true); conn.setDoInput(true); conn.setSSLSocketFactory(sc.getSocketFactory()); conn.setHostnameVerifier(new TrustAnyHostnameVerifier()); conn.connect(); InputStream is = conn.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String ret = ""; while ((ret = br.readLine()) != null) { if (ret != null && !"".equals(ret.trim())) { result.append(new String(ret.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8)); } } log.info("recv - {}", result); conn.disconnect(); br.close(); } catch (ConnectException e) { log.error("调用HttpUtils.sendSSLPost ConnectException, url=" + url + ",param=" + param, e); } catch (SocketTimeoutException e) { log.error("调用HttpUtils.sendSSLPost SocketTimeoutException, url=" + url + ",param=" + param, e); } catch (IOException e) { log.error("调用HttpUtils.sendSSLPost IOException, url=" + url + ",param=" + param, e); } catch (Exception e) { log.error("调用HttpsUtil.sendSSLPost Exception, url=" + url + ",param=" + param, e); } return result.toString(); } public static String post(String strURL, String params) { String result = ""; BufferedReader reader = null; try { URL url = new URL(strURL);// 创建连接 HttpURLConnection connection = (HttpURLConnection) url .openConnection(); connection.setDoOutput(true); connection.setDoInput(true); connection.setUseCaches(false); connection.setInstanceFollowRedirects(true); connection.setRequestMethod("POST"); // 设置请求方式 connection.setRequestProperty("Accept", "application/json"); // 设置接收数据的格式 connection.setRequestProperty("Content-Type", "application/json"); // 设置发送数据的格式 connection.connect(); if (params != null && !StringUtils.isEmpty(params)) { byte[] writebytes = params.getBytes(); // 设置文件长度 // connection.setRequestProperty("Content-Length", String.valueOf(writebytes.length)); OutputStream outwritestream = connection.getOutputStream(); outwritestream.write(params.getBytes()); outwritestream.flush(); outwritestream.close(); // Log.d("hlhupload", "doJsonPost: conn"+connection.getResponseCode()); } if (connection.getResponseCode() == 200) { log.info("<<<<<<<<<<<<<请求响应:{}", connection.getResponseMessage()); reader = new BufferedReader( new InputStreamReader(connection.getInputStream())); result = reader.readLine(); log.info("<<<<<<<<<<<<<请求响应:{}", result); } else { throw new ServiceException(connection.getResponseMessage()); } } catch (Exception e) { throw new ServiceException("http的post请求异常!" + e.getMessage()); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } return result; } private static class TrustAnyTrustManager implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) { } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[] {}; } } private static class TrustAnyHostnameVerifier implements HostnameVerifier { @Override public boolean verify(String hostname, SSLSession session) { return true; } } }