From 6dd6e95781c85398e366c4d468a6de83babfa206 Mon Sep 17 00:00:00 2001
From: shinnosuke <tantao@1hoper.com>
Date: 星期四, 09 七月 2026 11:30:16 +0800
Subject: [PATCH] feat(menu): 修复工作台权限菜单并完善发票开票功能
---
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TOrderInvoiceServiceImpl.java | 193 +++++++++++++++++++++++++++++++++---------------
1 files changed, 132 insertions(+), 61 deletions(-)
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TOrderInvoiceServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TOrderInvoiceServiceImpl.java
index f4f4c98..a29e3ac 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TOrderInvoiceServiceImpl.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TOrderInvoiceServiceImpl.java
@@ -32,9 +32,11 @@
import com.ruoyi.other.api.feignClient.InvoiceTypeClient;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
+import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
@@ -102,76 +104,144 @@
* @return
*/
@Override
+ @Transactional(rollbackFor = Exception.class)
public AjaxResult addOrderInvoice(AddOrderInvoice addOrderInvoice) {
Long userId = tokenService.getLoginUserApplet().getUserId();
RLock lock = redissonClient.getLock("ADD_ORDER_INVOICE:" + userId);
+ boolean locked = false;
try {
- boolean tryLock = lock.tryLock(5, 5, TimeUnit.SECONDS);
- if(tryLock){
- String orders = addOrderInvoice.getOrders();
- if(StringUtils.isEmpty(orders)){
- return AjaxResult.error("请选择有效的订单");
+ locked = lock.tryLock(5, 5, TimeUnit.SECONDS);
+ if (!locked) {
+ return AjaxResult.error("开票申请正在处理中,请勿重复提交");
+ }
+ String orders = addOrderInvoice.getOrders();
+ if (StringUtils.isEmpty(orders)) {
+ return AjaxResult.error("请选择有效的订单");
+ }
+ JSONArray parse = JSONArray.parse(orders);
+ if (parse == null || parse.isEmpty()) {
+ return AjaxResult.error("请选择有效的订单");
+ }
+ List<Long> orderIds = new ArrayList<>();
+ Map<Long, BigDecimal> amountMap = new HashMap<>();
+ for (int i = 0; i < parse.size(); i++) {
+ JSONObject jsonObject = parse.getJSONObject(i);
+ Long id = jsonObject.getLong("id");
+ BigDecimal amount = jsonObject.getBigDecimal("amount");
+ if (id == null || amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
+ return AjaxResult.error("订单金额异常,请刷新后重试");
}
- JSONArray parse = JSONArray.parse(orders);
- List<Long> orderIds = new ArrayList<>();
- Map<Long, BigDecimal> map = new HashMap<>();
- for (int i = 0; i < parse.size(); i++) {
- JSONObject jsonObject = parse.getJSONObject(i);
- Long id = jsonObject.getLong("id");
- BigDecimal amount = jsonObject.getBigDecimal("amount");
- orderIds.add(id);
- map.put(id, amount);
- }
- long count = orderInvoiceDetailService.count(new LambdaQueryWrapper<TOrderInvoiceDetail>().eq(TOrderInvoiceDetail::getOrderType, addOrderInvoice.getOrderType())
- .in(TOrderInvoiceDetail::getOrderId, orderIds));
- if(count > 0){
+ orderIds.add(id);
+ amountMap.put(id, amount);
+ }
+ List<TOrderInvoiceDetail> existingDetails = orderInvoiceDetailService.list(new LambdaQueryWrapper<TOrderInvoiceDetail>()
+ .eq(TOrderInvoiceDetail::getOrderType, addOrderInvoice.getOrderType())
+ .in(TOrderInvoiceDetail::getOrderId, orderIds));
+ if (!CollectionUtils.isEmpty(existingDetails)) {
+ List<Long> invoiceIds = existingDetails.stream().map(TOrderInvoiceDetail::getOrderInvoiceId).distinct().collect(Collectors.toList());
+ long count = this.count(new LambdaQueryWrapper<TOrderInvoice>().in(TOrderInvoice::getId, invoiceIds).ne(TOrderInvoice::getStatus, 4));
+ if (count > 0) {
return AjaxResult.error("不能重复申请开票,请刷新数据后重试");
}
- SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
- String code = Double.valueOf(Math.random() * 1000).intValue() + sdf.format(new Date());
- //获取开票类型
- TInvoiceType invoiceType = invoiceTypeClient.getInvoiceType(addOrderInvoice.getInvoiceTypeId()).getData();
- addOrderInvoice.setInvoicingCompany(invoiceType.getInvoicingCompany());
- addOrderInvoice.setInvoiceType(invoiceType.getName());
- addOrderInvoice.setInvoiceMaterial(2);
- addOrderInvoice.setInvoicingMethod(invoiceType.getInvoicingMethod());
- addOrderInvoice.setAppUserId(userId);
- addOrderInvoice.setCode(code);
- addOrderInvoice.setStatus(1);
- addOrderInvoice.setCreateTime(LocalDateTime.now());
- fillInvoiceSite(addOrderInvoice, orderIds);
- if (Integer.valueOf(2).equals(addOrderInvoice.getInvoicingMethod())) {
- addOrderInvoice.setStatus(3);
- addOrderInvoice.setBillingTime(LocalDateTime.now());
- }
- this.save(addOrderInvoice);
- for (Long orderId : orderIds) {
- List<TChargingOrderAccountingStrategy> list = chargingOrderAccountingStrategyService.list(new LambdaQueryWrapper<TChargingOrderAccountingStrategy>()
- .eq(TChargingOrderAccountingStrategy::getChargingOrderId, orderId));
- BigDecimal electrovalence = list.stream().map(TChargingOrderAccountingStrategy::getElectrovalence).reduce(BigDecimal.ZERO, BigDecimal::add);
- BigDecimal serviceCharge = list.stream().map(TChargingOrderAccountingStrategy::getServiceCharge).reduce(BigDecimal.ZERO, BigDecimal::add);
-
- TOrderInvoiceDetail orderInvoiceDetail = new TOrderInvoiceDetail();
- orderInvoiceDetail.setOrderInvoiceId(addOrderInvoice.getId());
- orderInvoiceDetail.setInvoiceAmount(map.get(orderId));
- orderInvoiceDetail.setOrderType(addOrderInvoice.getOrderType());
- orderInvoiceDetail.setOrderId(orderId);
- orderInvoiceDetail.setElectricityTariff(invoiceType.getElectricityTariff());
- orderInvoiceDetail.setServiceTariff(invoiceType.getServiceTariff());
- orderInvoiceDetail.setAddedServiceTariff(invoiceType.getAddedServiceTariff());
- orderInvoiceDetail.setElectrovalence(electrovalence);
- orderInvoiceDetail.setServiceCharge(serviceCharge);
- orderInvoiceDetail.setAddedService(serviceCharge.multiply(null == invoiceType.getAddedServiceTariff()
- ? new BigDecimal(1) : invoiceType.getAddedServiceTariff().divide(new BigDecimal(100))));
- orderInvoiceDetailService.save(orderInvoiceDetail);
- }
}
- }catch (Exception e){
+ //获取开票类型
+ TInvoiceType invoiceType = invoiceTypeClient.getInvoiceType(addOrderInvoice.getInvoiceTypeId()).getData();
+ if (invoiceType == null) {
+ return AjaxResult.error("请选择有效的发票类型");
+ }
+ Map<Integer, List<Long>> invoiceOrderGroups = buildInvoiceOrderGroups(addOrderInvoice, orderIds);
+ for (List<Long> groupOrderIds : invoiceOrderGroups.values()) {
+ TOrderInvoice invoice = buildOrderInvoice(addOrderInvoice, userId, invoiceType, groupOrderIds, amountMap);
+ this.save(invoice);
+ saveInvoiceDetails(invoice, invoiceType, groupOrderIds, amountMap);
+ }
+ return AjaxResult.success();
+ } catch (Exception e) {
e.printStackTrace();
- }finally {
- lock.unlock();
+ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+ return AjaxResult.error("开票申请失败:" + (StringUtils.isEmpty(e.getMessage()) ? "请稍后重试" : e.getMessage()));
+ } finally {
+ if (locked && lock.isHeldByCurrentThread()) {
+ lock.unlock();
+ }
}
- return AjaxResult.success();
+ }
+
+ private Map<Integer, List<Long>> buildInvoiceOrderGroups(AddOrderInvoice addOrderInvoice, List<Long> orderIds) {
+ Map<Integer, List<Long>> groups = new LinkedHashMap<>();
+ if (!Integer.valueOf(1).equals(addOrderInvoice.getOrderType())) {
+ groups.put(0, orderIds);
+ return groups;
+ }
+ List<TChargingOrder> chargingOrders = chargingOrderService.listByIds(orderIds);
+ Map<Long, Integer> siteIdMap = chargingOrders.stream().collect(Collectors.toMap(TChargingOrder::getId, TChargingOrder::getSiteId, (a, b) -> a));
+ for (Long orderId : orderIds) {
+ Integer siteId = siteIdMap.get(orderId);
+ if (siteId == null) {
+ throw new IllegalArgumentException("订单所属电站异常,请刷新后重试");
+ }
+ groups.computeIfAbsent(siteId, key -> new ArrayList<>()).add(orderId);
+ }
+ return groups;
+ }
+
+ private TOrderInvoice buildOrderInvoice(AddOrderInvoice source, Long userId, TInvoiceType invoiceType, List<Long> orderIds, Map<Long, BigDecimal> amountMap) {
+ TOrderInvoice invoice = new TOrderInvoice();
+ BeanUtils.copyProperties(source, invoice);
+ invoice.setId(null);
+ invoice.setCode(generateInvoiceCode());
+ invoice.setAppUserId(userId);
+ invoice.setInvoicingCompany(invoiceType.getInvoicingCompany());
+ invoice.setInvoiceType(invoiceType.getName());
+ invoice.setInvoiceMaterial(2);
+ invoice.setInvoicingMethod(invoiceType.getInvoicingMethod());
+ invoice.setTotalAmount(orderIds.stream().map(amountMap::get).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add));
+ invoice.setInvoiceUrl(null);
+ invoice.setBillingUserId(null);
+ invoice.setCancelTime(null);
+ invoice.setStatus(1);
+ invoice.setCreateTime(LocalDateTime.now());
+ invoice.setBillingTime(null);
+ invoice.setSiteId(null);
+ invoice.setPartnerId(null);
+ fillInvoiceSite(invoice, orderIds);
+ if (Integer.valueOf(2).equals(invoice.getInvoicingMethod())) {
+ invoice.setStatus(3);
+ invoice.setBillingTime(LocalDateTime.now());
+ }
+ return invoice;
+ }
+
+ private void saveInvoiceDetails(TOrderInvoice invoice, TInvoiceType invoiceType, List<Long> orderIds, Map<Long, BigDecimal> amountMap) {
+ for (Long orderId : orderIds) {
+ BigDecimal electrovalence = BigDecimal.ZERO;
+ BigDecimal serviceCharge = BigDecimal.ZERO;
+ if (Integer.valueOf(1).equals(invoice.getOrderType())) {
+ List<TChargingOrderAccountingStrategy> list = chargingOrderAccountingStrategyService.list(new LambdaQueryWrapper<TChargingOrderAccountingStrategy>()
+ .eq(TChargingOrderAccountingStrategy::getChargingOrderId, orderId));
+ electrovalence = list.stream().map(TChargingOrderAccountingStrategy::getElectrovalence).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
+ serviceCharge = list.stream().map(TChargingOrderAccountingStrategy::getServiceCharge).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
+ }
+
+ TOrderInvoiceDetail orderInvoiceDetail = new TOrderInvoiceDetail();
+ orderInvoiceDetail.setOrderInvoiceId(invoice.getId());
+ orderInvoiceDetail.setInvoiceAmount(amountMap.get(orderId));
+ orderInvoiceDetail.setOrderType(invoice.getOrderType());
+ orderInvoiceDetail.setOrderId(orderId);
+ orderInvoiceDetail.setElectricityTariff(invoiceType.getElectricityTariff());
+ orderInvoiceDetail.setServiceTariff(invoiceType.getServiceTariff());
+ orderInvoiceDetail.setAddedServiceTariff(invoiceType.getAddedServiceTariff());
+ orderInvoiceDetail.setElectrovalence(electrovalence);
+ orderInvoiceDetail.setServiceCharge(serviceCharge);
+ orderInvoiceDetail.setAddedService(serviceCharge.multiply(null == invoiceType.getAddedServiceTariff()
+ ? new BigDecimal(1) : invoiceType.getAddedServiceTariff().divide(new BigDecimal(100))));
+ orderInvoiceDetailService.save(orderInvoiceDetail);
+ }
+ }
+
+ private String generateInvoiceCode() {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+ return Double.valueOf(Math.random() * 1000).intValue() + sdf.format(new Date());
}
private void fillInvoiceSite(TOrderInvoice invoice, List<Long> orderIds) {
@@ -208,7 +278,7 @@
Long userId = tokenService.getLoginUserApplet().getUserId();
Integer pageCurr = (query.getPageCurr() - 1) * query.getPageSize();
LambdaQueryWrapper<TOrderInvoice> wrapper = new LambdaQueryWrapper<TOrderInvoice>().eq(TOrderInvoice::getAppUserId, userId);
- if(query.getStatus() != 1){
+ if(query.getStatus() != null){
wrapper.eq(TOrderInvoice::getStatus, query.getStatus());
}
List<TOrderInvoice> list = this.list(wrapper.orderByDesc(TOrderInvoice::getCreateTime).last(" limit " + pageCurr + ", " + query.getPageSize()));
@@ -219,6 +289,7 @@
orderInvoiceList.setOrderType(tOrderInvoice.getOrderType());
orderInvoiceList.setTotalAmount(tOrderInvoice.getTotalAmount());
orderInvoiceList.setName(tOrderInvoice.getName());
+ orderInvoiceList.setStatus(tOrderInvoice.getStatus());
orderInvoiceList.setCreateTime(tOrderInvoice.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
pageList.add(orderInvoiceList);
}
--
Gitblit v1.7.1