| | |
| | | package com.ruoyi.order.service.impl; |
| | | |
| | | import cn.hutool.core.util.IdUtil; |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import cn.hutool.json.JSONObject; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.account.api.feignClient.AppUserClient; |
| | | import com.ruoyi.account.api.feignClient.UserPointClient; |
| | | import com.ruoyi.account.api.model.AppUser; |
| | | import com.ruoyi.account.api.model.UserPoint; |
| | | import com.ruoyi.chargingPile.api.feignClient.SiteClient; |
| | | import com.ruoyi.chargingPile.api.model.Site; |
| | | import com.ruoyi.common.core.constant.ExpressCompanyMap; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.dto.ChargingOrderGroup; |
| | | import com.ruoyi.common.core.dto.ChargingPercentProvinceDto; |
| | | import com.ruoyi.common.core.exception.ServiceException; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.core.web.page.PageInfo; |
| | | import com.ruoyi.common.security.service.TokenService; |
| | | import com.ruoyi.order.dto.GetImportOrderDTO; |
| | | import com.ruoyi.order.mapper.ChargeOrderMapper; |
| | | import com.ruoyi.order.mapper.OrderMapper; |
| | |
| | | import com.ruoyi.order.service.ChargeOrderService; |
| | | import com.ruoyi.order.service.OrderService; |
| | | import com.ruoyi.order.vo.ConfirmDelivery; |
| | | import com.ruoyi.other.api.domain.IntegralRecord; |
| | | import com.ruoyi.other.api.domain.Region; |
| | | import com.ruoyi.other.api.domain.TIntegralRule; |
| | | import com.ruoyi.other.api.feignClient.OtherClient; |
| | | import com.ruoyi.system.api.domain.SysConfig; |
| | | import com.ruoyi.system.api.domain.SysUser; |
| | | import com.ruoyi.system.api.feignClient.SysConfigClient; |
| | | import com.ruoyi.system.api.feignClient.SysUserClient; |
| | | import io.swagger.models.auth.In; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.poi.hssf.usermodel.HSSFWorkbook; |
| | | import org.apache.poi.ss.usermodel.*; |
| | | import org.apache.poi.xssf.usermodel.XSSFWorkbook; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | |
| | | import java.net.URI; |
| | | import java.net.URISyntaxException; |
| | | import java.net.URL; |
| | | import java.text.ParseException; |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.LocalDateTime; |
| | | import java.time.LocalTime; |
| | | import java.time.ZoneId; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.UUID; |
| | | import java.util.*; |
| | | |
| | | @Slf4j |
| | | @Service |
| | |
| | | private OrderService orderService; |
| | | @Resource |
| | | private SysConfigClient sysConfigClient; |
| | | |
| | | @Resource |
| | | private OtherClient otherClient; |
| | | @Resource |
| | | private AppUserClient appUserClient; |
| | | @Resource |
| | | private UserPointClient userPointClient; |
| | | @Resource |
| | | private ChargeOrderService chargeOrderService; |
| | | @Resource |
| | | private SiteClient siteClient; |
| | | |
| | | @Resource |
| | | private SysUserClient sysUserClient; |
| | | private static final String DEFAULT_AVATAR_URL = "http://qijishenghuiyuan.obs.cn-southwest-2.myhuaweicloud.com/admin/58084a0ce8c34dc79f9d8b4c0bc3774a.png"; |
| | | |
| | | |
| | | @Override |
| | | public void importExpress(MultipartFile file) { |
| | | public R<JSONObject> importExpress(MultipartFile file) { |
| | | /* System.out.println("导入订单url:"+url); |
| | | URL url1 = null; |
| | | try { |
| | |
| | | throw new RuntimeException(e); |
| | | }*/ |
| | | List<String> orderNumberList=new ArrayList<>(); |
| | | JSONObject result = new JSONObject(); |
| | | try (InputStream inputStream = file.getInputStream()) { |
| | | Workbook workbook; |
| | | |
| | | try (InputStream inputStream = file.getInputStream(); |
| | | Workbook workbook = new XSSFWorkbook(inputStream)) { |
| | | // Workbook workbook = new XSSFWorkbook(fileInputStream); |
| | | // 判断文件类型并创建相应的Workbook对象 |
| | | if (file.getOriginalFilename() != null && file.getOriginalFilename().toLowerCase().endsWith(".xlsx")) { |
| | | workbook = new XSSFWorkbook(inputStream); // 处理 .xlsx 文件 |
| | | } else if (file.getOriginalFilename() != null && file.getOriginalFilename().toLowerCase().endsWith(".xls")) { |
| | | workbook = new HSSFWorkbook(inputStream); // 处理 .xls 文件 |
| | | } else { |
| | | throw new ServiceException("不支持的文件格式,请上传 .xls 或 .xlsx 格式的文件", 500); |
| | | } |
| | | Sheet sheet = workbook.getSheetAt(0); // 获取第一个Sheet |
| | | int lastRowNum = sheet.getLastRowNum(); |
| | | for (int i = 1; i <= lastRowNum; i++) {//第二行开始 |
| | |
| | | |
| | | |
| | | // 开始时间 |
| | | Cell beginTimeCell = row.getCell(6); |
| | | Cell beginTimeCell = row.getCell(4); |
| | | if (beginTimeCell == null) { |
| | | throw new ServiceException("第" + (i + 1) + "行开始时间为空", 500); |
| | | } |
| | | |
| | | SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | LocalDateTime beginTime; |
| | | if (beginTimeCell.getCellType() == CellType.NUMERIC || DateUtil.isCellDateFormatted(beginTimeCell)) { |
| | | // 处理数值型日期(包括Excel内置日期格式) |
| | | beginTime = beginTimeCell.getDateCellValue().toInstant() |
| | | .atZone(ZoneId.systemDefault()) |
| | | .toLocalDateTime(); |
| | | } else { |
| | | // 处理文本型日期(如 "2025/4/3 23:25:38") |
| | | String dateStr = beginTimeCell.getStringCellValue().trim(); |
| | | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/M/d H:mm:ss"); |
| | | beginTime = LocalDateTime.parse(dateStr, formatter); |
| | | try { |
| | | Date startDate = format.parse(beginTimeCell.getStringCellValue()); |
| | | beginTime = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); |
| | | } catch (ParseException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | |
| | | // LocalDateTime beginTime; |
| | | // if (beginTimeCell.getCellType() == CellType.NUMERIC || DateUtil.isCellDateFormatted(beginTimeCell)) { |
| | | // // 处理数值型日期(包括Excel内置日期格式) |
| | | // beginTime = beginTimeCell.getDateCellValue().toInstant() |
| | | // .atZone(ZoneId.systemDefault()) |
| | | // .toLocalDateTime(); |
| | | // } else { |
| | | // // 处理文本型日期(如 "2025/4/3 23:25:38") |
| | | // String dateStr = beginTimeCell.getStringCellValue().trim(); |
| | | // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/M/d H:mm:ss"); |
| | | // beginTime = LocalDateTime.parse(dateStr, formatter); |
| | | // } |
| | | |
| | | // 结束时间 |
| | | Cell endTimeCell = row.getCell(7); |
| | | Cell endTimeCell = row.getCell(5); |
| | | if (endTimeCell == null) { |
| | | throw new ServiceException("第" + (i + 1) + "行开始时间为空", 500); |
| | | } |
| | | |
| | | LocalDateTime endTime; |
| | | if (endTimeCell.getCellType() == CellType.NUMERIC || DateUtil.isCellDateFormatted(endTimeCell)) { |
| | | // 处理数值型日期(包括Excel内置日期格式) |
| | | endTime = endTimeCell.getDateCellValue().toInstant() |
| | | .atZone(ZoneId.systemDefault()) |
| | | .toLocalDateTime(); |
| | | } else { |
| | | // 处理文本型日期(如 "2025/4/3 23:25:38") |
| | | String dateStr = beginTimeCell.getStringCellValue().trim(); |
| | | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/M/d H:mm:ss"); |
| | | endTime = LocalDateTime.parse(dateStr, formatter); |
| | | try { |
| | | Date startDate = format.parse(endTimeCell.getStringCellValue()); |
| | | endTime = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); |
| | | } catch (ParseException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | |
| | | |
| | | // 充电时长 |
| | | if (row.getCell(8 )== null){ |
| | | if (row.getCell(6 )== null){ |
| | | throw new ServiceException("第" + i + "行充电时长为空", 500); |
| | | } |
| | | row.getCell(8).setCellType(CellType.STRING); |
| | | String chargingDuration = row.getCell(8).getStringCellValue(); |
| | | row.getCell(6).setCellType(CellType.STRING); |
| | | String chargingDuration = row.getCell(6).getStringCellValue(); |
| | | |
| | | |
| | | // 充电电量 |
| | | if (row.getCell(9 )== null){ |
| | | if (row.getCell(7 )== null){ |
| | | throw new ServiceException("第" + i + "行充电电量为空", 500); |
| | | } |
| | | row.getCell(9).setCellType(CellType.STRING); |
| | | String chargingCapacity = row.getCell(9).getStringCellValue(); |
| | | row.getCell(7).setCellType(CellType.STRING); |
| | | String chargingCapacity = row.getCell(7).getStringCellValue(); |
| | | |
| | | // 电站运营商 |
| | | if (row.getCell(15 )== null){ |
| | | if (row.getCell(8 )== null){ |
| | | throw new ServiceException("第" + i + "行电站运营商为空", 500); |
| | | } |
| | | row.getCell(15).setCellType(CellType.STRING); |
| | | String powerStationOperator = row.getCell(15).getStringCellValue(); |
| | | row.getCell(8).setCellType(CellType.STRING); |
| | | String powerStationOperator = row.getCell(8).getStringCellValue(); |
| | | |
| | | // 城市名称 |
| | | if (row.getCell(16 )== null){ |
| | | if (row.getCell(9 )== null){ |
| | | throw new ServiceException("第" + i + "行城市名称为空", 500); |
| | | } |
| | | row.getCell(16).setCellType(CellType.STRING); |
| | | String city = row.getCell(16).getStringCellValue(); |
| | | row.getCell(9).setCellType(CellType.STRING); |
| | | String city = row.getCell(9).getStringCellValue(); |
| | | |
| | | // 充电场站 |
| | | if (row.getCell(17 )== null){ |
| | | if (row.getCell(10 )== null){ |
| | | throw new ServiceException("第" + i + "行充电场站为空", 500); |
| | | } |
| | | row.getCell(17).setCellType(CellType.STRING); |
| | | String chargingStation = row.getCell(17).getStringCellValue(); |
| | | row.getCell(10).setCellType(CellType.STRING); |
| | | String chargingStation = row.getCell(10).getStringCellValue(); |
| | | |
| | | // 电站id |
| | | if (row.getCell(18 )== null){ |
| | | if (row.getCell(11 )== null){ |
| | | throw new ServiceException("第" + i + "行电站id为空", 500); |
| | | } |
| | | row.getCell(18).setCellType(CellType.STRING); |
| | | String powerStationId = row.getCell(18).getStringCellValue(); |
| | | row.getCell(11).setCellType(CellType.STRING); |
| | | String powerStationId = row.getCell(11).getStringCellValue(); |
| | | |
| | | // 终端编码 |
| | | if (row.getCell(20 )== null){ |
| | | throw new ServiceException("第" + i + "行电站id为空", 500); |
| | | if (row.getCell(12 )== null){ |
| | | throw new ServiceException("第" + i + "行终端编码为空", 500); |
| | | } |
| | | row.getCell(20).setCellType(CellType.STRING); |
| | | String terminalCode = row.getCell(20).getStringCellValue(); |
| | | row.getCell(12).setCellType(CellType.STRING); |
| | | String terminalCode = row.getCell(12).getStringCellValue(); |
| | | |
| | | // 车牌号 |
| | | if (row.getCell(26 )== null){ |
| | | if (row.getCell(13 )== null){ |
| | | throw new ServiceException("第" + i + "行车牌号为空", 500); |
| | | } |
| | | row.getCell(26).setCellType(CellType.STRING); |
| | | String plateNumber = row.getCell(26).getStringCellValue(); |
| | | row.getCell(13).setCellType(CellType.STRING); |
| | | String plateNumber = row.getCell(13).getStringCellValue(); |
| | | |
| | | // 电站价电费金额 |
| | | if (row.getCell(73 )== null){ |
| | | if (row.getCell(14 )== null){ |
| | | throw new ServiceException("第" + i + "行电站价电费金额为空", 500); |
| | | } |
| | | row.getCell(73).setCellType(CellType.STRING); |
| | | String electricityAmount = row.getCell(73).getStringCellValue(); |
| | | row.getCell(14).setCellType(CellType.STRING); |
| | | String electricityAmount = row.getCell(14).getStringCellValue(); |
| | | |
| | | // 电站价服务费金额 |
| | | if (row.getCell(74 )== null){ |
| | | if (row.getCell(15 )== null){ |
| | | throw new ServiceException("第" + i + "行电站价服务费金额为空", 500); |
| | | } |
| | | row.getCell(74).setCellType(CellType.STRING); |
| | | String serviceAmount = row.getCell(74).getStringCellValue(); |
| | | row.getCell(15).setCellType(CellType.STRING); |
| | | String serviceAmount = row.getCell(15).getStringCellValue(); |
| | | |
| | | // 电站价总金额 |
| | | if (row.getCell(75 )== null){ |
| | | throw new ServiceException("第" + i + "行电站价服务费金额为空", 500); |
| | | if (row.getCell(16 )== null){ |
| | | throw new ServiceException("第" + i + "行电站价总金额为空", 500); |
| | | } |
| | | row.getCell(75).setCellType(CellType.STRING); |
| | | String totalAmount = row.getCell(75).getStringCellValue(); |
| | | row.getCell(16).setCellType(CellType.STRING); |
| | | String totalAmount = row.getCell(16).getStringCellValue(); |
| | | // 绿电分 |
| | | if (row.getCell(17 )== null){ |
| | | throw new ServiceException("第" + i + "行绿电分为空", 500); |
| | | } |
| | | row.getCell(17).setCellType(CellType.STRING); |
| | | String point = row.getCell(17).getStringCellValue(); |
| | | |
| | | |
| | | //检查订单号是否重复 |
| | | if (orderNumberList.contains(orderNum)) { |
| | | throw new ServiceException("订单号重复:" + orderNum, 500); |
| | | // throw new ServiceException("订单号重复:" + orderNum, 500); |
| | | result.append("订单号:[", orderNum+"]重复"); |
| | | continue; |
| | | } |
| | | //数据库中是否存在 |
| | | ChargeOrder order = chargeOrderService.getOne(new LambdaQueryWrapper<ChargeOrder>() |
| | | .eq(ChargeOrder::getOrderNumber, orderNum) |
| | | ); |
| | | if (order != null) { |
| | | throw new ServiceException("数据库中订单已存在:" + orderNum, 500); |
| | | // throw new ServiceException("数据库中订单已存在:" + orderNum, 500); |
| | | result.append("订单号:[", orderNum+"]数据库中订单已存在"); |
| | | continue; |
| | | } |
| | | orderNumberList.add(orderNum);//添加到订单集合中 |
| | | |
| | |
| | | chargeOrder.setElectricityAmount(new BigDecimal(electricityAmount)); |
| | | chargeOrder.setServiceAmount(new BigDecimal(serviceAmount)); |
| | | chargeOrder.setTotalAmount(new BigDecimal(totalAmount)); |
| | | chargeOrder.setPoint(Integer.valueOf(point)); |
| | | |
| | | R r = importData(chargeOrder); |
| | | if (R.isError(r)) { |
| | |
| | | e.printStackTrace(); |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | if(!result.isEmpty()){ |
| | | return R.fail(result.toString()); |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | | @Override |
| | |
| | | pageInfo.setRecords(list); |
| | | return pageInfo; |
| | | } |
| | | |
| | | @Override |
| | | public List<ChargingOrderGroup> chargingOrderGroup(ChargingPercentProvinceDto chargingPercentProvinceDto) { |
| | | |
| | | return this.baseMapper.chargingOrderGroup(chargingPercentProvinceDto); |
| | | } |
| | | |
| | | @Transactional |
| | | public R importData(ChargeOrder chargeOrder) { |
| | | //先计算出积分数 |
| | | Integer point = getPoint(chargeOrder.getTotalAmount()); |
| | | //获取用户,更改积分数 |
| | | Site site = siteClient.getSiteAll().getData().stream().filter(e -> e.getId() |
| | | .equals(chargeOrder.getPowerStationId())).findFirst().orElse(null); |
| | | Integer point=0; |
| | | AppUser appuser = appUserClient.getAppUserByPhone1(chargeOrder.getPhone()).getData(); |
| | | //获取用户,更改积分数 |
| | | if (null==appuser){ |
| | | //创建用户 |
| | | appuser = new AppUser(); |
| | |
| | | appuser.setDelFlag(false); |
| | | appuser.setName(appuser.getPhone().substring(0, 3) + "****" + appuser.getPhone().substring(7)); |
| | | } |
| | | if (site==null){ |
| | | //先计算出积分数 |
| | | point = getPoint(chargeOrder.getTotalAmount()); |
| | | }else{ |
| | | point = getPointSite(chargeOrder.getTotalAmount(),site.getId()); |
| | | } |
| | | // 扣除站点系统用户的积分数 |
| | | SysUser sysUser=null; |
| | | if(Objects.nonNull(site)){ |
| | | List<SysUser> data = sysUserClient.getSysUserAll().getData(); |
| | | sysUser = data.stream().filter(e -> site.getId().equals(e.getSiteId())).findFirst().orElse(null); |
| | | if (sysUser != null) { |
| | | if (sysUser.getIntegral()< point){ |
| | | return R.fail("站点积分不足"); |
| | | } |
| | | }else { |
| | | return R.fail("站点用户不存在"); |
| | | } |
| | | } |
| | | |
| | | Integer chargePoint=appuser.getRechargePoint()==null?0:appuser.getRechargePoint();//充值积分 |
| | | Integer availablePoint=appuser.getAvailablePoint()==null?0:appuser.getAvailablePoint();//可用积分 |
| | | Integer totalPoint=appuser.getTotalPoint()==null?0:appuser.getTotalPoint();//总积分 |
| | |
| | | if (userId==null){ |
| | | return R.fail("导入订单-保存用户失败"); |
| | | } |
| | | |
| | | if (site!=null){ |
| | | point = getPointSite(chargeOrder.getTotalAmount(),site.getId()); |
| | | // 增加站点端积分明细 |
| | | IntegralRecord integralRecord = new IntegralRecord(); |
| | | integralRecord.setSiteId(chargeOrder.getPowerStationId()); |
| | | integralRecord.setAppUserId(appuser.getId()); |
| | | integralRecord.setIntegralType(2); |
| | | integralRecord.setIntegralCount(point); |
| | | integralRecord.setDelFlag(0); |
| | | integralRecord.setCreateTime(LocalDateTime.now()); |
| | | otherClient.saveIntegralRecord(integralRecord); |
| | | // 扣除站点系统用户的积分数 |
| | | if (sysUser.getIntegral()==null){ |
| | | sysUser.setIntegral(0); |
| | | } |
| | | sysUser.setIntegral(sysUser.getIntegral()==null?0:sysUser.getIntegral()-point); |
| | | sysUserClient.updateSysUser(sysUser); |
| | | } |
| | | //保存到数据库 |
| | | chargeOrder.setPoint(point); |
| | | chargeOrderService.save(chargeOrder); |
| | | //添加用户积分流水 |
| | | //转入用户 |
| | | UserPoint userPoint = new UserPoint(); |
| | |
| | | if (r.isError(r)) { |
| | | return R.fail("导入订单-保存用户积分流水失败"); |
| | | } |
| | | //保存到数据库 |
| | | chargeOrder.setPoint(point); |
| | | chargeOrderService.save(chargeOrder); |
| | | |
| | | |
| | | return R.ok(); |
| | | } |
| | |
| | | } |
| | | |
| | | } |
| | | /** |
| | | * 获取现金兑换的积分数 |
| | | * @param cash |
| | | * @return |
| | | */ |
| | | public Integer getPointSite(BigDecimal cash,Integer siteId){ |
| | | if (cash == null || cash.compareTo(BigDecimal.ZERO) < 0) { |
| | | throw new IllegalArgumentException("金额不能为null或负数"); |
| | | } |
| | | // 获取积分兑换比例配置 |
| | | TIntegralRule data = otherClient.getSetBySiteId(siteId).getData(); |
| | | if (data == null) { |
| | | throw new RuntimeException("获取积分兑换比例配置失败"); |
| | | |
| | | } |
| | | if (!org.springframework.util.StringUtils.hasLength(data.getChargeCredit())) { |
| | | throw new RuntimeException("获取积分兑换比例配置失败"); |
| | | } |
| | | String chargeCredit = data.getChargeCredit(); |
| | | if (StringUtils.isBlank(chargeCredit)) { |
| | | throw new RuntimeException("积分兑换比例配置值为空"); |
| | | } |
| | | try { |
| | | com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(chargeCredit); |
| | | Integer num1 = jsonObject.getInteger("num1"); |
| | | |
| | | if (num1 <= 0) { |
| | | throw new RuntimeException("积分兑换比例必须大于0"); |
| | | } |
| | | // 计算积分并向下取整(Floor) |
| | | int cashInt = cash.intValue(); |
| | | return cashInt * num1; |
| | | |
| | | } catch (NumberFormatException e) { |
| | | throw new RuntimeException("积分兑换比例配置值格式错误", e); |
| | | } catch (ArithmeticException e) { |
| | | throw new RuntimeException("积分计算结果溢出", e); |
| | | } |
| | | |
| | | } |
| | | |
| | | } |