增加发票导入功能

This commit is contained in:
Guoqs
2026-04-15 12:28:02 +08:00
parent d9d60dd677
commit 98bc86ef43
10 changed files with 174 additions and 2 deletions

View File

@@ -10,6 +10,7 @@ import com.jsowell.pile.domain.OrderInvoiceRecord;
import com.jsowell.pile.dto.GetInvoiceInfoDTO;
import com.jsowell.pile.service.OrderInvoiceRecordService;
import com.jsowell.pile.vo.web.OrderInvoiceRecordExportVO;
import com.jsowell.pile.vo.web.OrderInvoiceRecordImportVO;
import com.jsowell.pile.vo.web.OrderInvoiceRecordVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
@@ -21,6 +22,7 @@ import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
@@ -61,6 +63,22 @@ public class OrderInvoiceRecordController extends BaseController {
util.exportExcel(response, list, "申请开票数据");
}
/**
* 导入开票结果
*/
@PreAuthorize("@ss.hasPermi('order:invoice:edit')")
@Log(title = "申请开票", businessType = BusinessType.IMPORT)
@PostMapping("/importData")
public AjaxResult importData(MultipartFile file) throws Exception {
if (file == null || file.isEmpty()) {
return AjaxResult.error("上传文件不能为空");
}
ExcelUtil<OrderInvoiceRecordImportVO> util = new ExcelUtil<OrderInvoiceRecordImportVO>(OrderInvoiceRecordImportVO.class);
List<OrderInvoiceRecordImportVO> importList = util.importExcel(file.getInputStream());
String message = orderInvoiceRecordService.importInvoiceImages(importList, getUsername());
return AjaxResult.success(message);
}
/**
* 获取申请开票详细信息
*/

View File

@@ -45,6 +45,11 @@ public class OrderInvoiceRecord extends BaseEntity {
private String email;
/**
* 发票图片url
*/
private String invoiceUrl;
/**
* 申请订单编号(逗号分割)
*/
@@ -154,6 +159,7 @@ public class OrderInvoiceRecord extends BaseEntity {
.append("totalAmount", getTotalAmount())
.append("totalServiceAmount", getTotalServiceAmount())
.append("totalElecAmount", getTotalElecAmount())
.append("invoiceUrl", getInvoiceUrl())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())

View File

@@ -5,6 +5,7 @@ import com.jsowell.pile.dto.GetInvoiceInfoDTO;
import com.jsowell.pile.dto.QueryInvoiceRecordDTO;
import com.jsowell.pile.vo.web.InvoiceRecordVO;
import com.jsowell.pile.vo.web.OrderInvoiceRecordExportVO;
import com.jsowell.pile.vo.web.OrderInvoiceRecordImportVO;
import com.jsowell.pile.vo.web.OrderInvoiceRecordVO;
import java.time.LocalDateTime;
@@ -50,6 +51,15 @@ public interface OrderInvoiceRecordService {
*/
List<OrderInvoiceRecordExportVO> getInvoiceExportListWithAuth(GetInvoiceInfoDTO dto);
/**
* 导入发票图片并更新申请开票记录
*
* @param importList 导入数据
* @param operName 操作人
* @return 导入结果
*/
String importInvoiceImages(List<OrderInvoiceRecordImportVO> importList, String operName);
List<OrderInvoiceRecord> selectInvoiceRecordList(QueryInvoiceRecordDTO memberId);
List<OrderInvoiceRecordVO> selectInvoiceVOList(QueryInvoiceRecordDTO memberId);

View File

@@ -2,6 +2,10 @@ package com.jsowell.pile.service.impl;
import com.google.common.collect.Lists;
import com.jsowell.common.core.domain.vo.AuthorizedDeptVO;
import com.jsowell.common.util.StringUtils;
import com.jsowell.common.util.file.AliyunOssUploadUtils;
import com.jsowell.common.util.file.FileUtils;
import com.jsowell.common.config.JsowellConfig;
import com.jsowell.pile.domain.OrderInvoiceRecord;
import com.jsowell.pile.dto.GetInvoiceInfoDTO;
import com.jsowell.pile.dto.QueryInvoiceRecordDTO;
@@ -14,14 +18,21 @@ import com.jsowell.pile.vo.base.OrderAmountDetailVO;
import com.jsowell.pile.vo.uniapp.customer.InvoiceTitleVO;
import com.jsowell.pile.vo.web.InvoiceRecordVO;
import com.jsowell.pile.vo.web.OrderInvoiceRecordExportVO;
import com.jsowell.pile.vo.web.OrderInvoiceRecordImportVO;
import com.jsowell.pile.vo.web.OrderInvoiceRecordVO;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.File;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 申请开票Service业务层处理
@@ -70,6 +81,7 @@ public class OrderInvoiceRecordServiceImpl implements OrderInvoiceRecordService
.memberId(vo.getMemberId())
.phoneNumber(vo.getPhoneNumber())
.status(vo.getStatus())
.invoiceUrl(vo.getInvoiceUrl())
.invoiceTitle(invoiceTitleVO)
.orderList(orderAmountDetailVOS)
.createTime(vo.getCreateTime())
@@ -109,6 +121,78 @@ public class OrderInvoiceRecordServiceImpl implements OrderInvoiceRecordService
return orderInvoiceRecordMapper.getInvoiceExportListWithAuth(dto);
}
@Override
public String importInvoiceImages(List<OrderInvoiceRecordImportVO> importList, String operName) {
if (CollectionUtils.isEmpty(importList)) {
return "导入数据为空";
}
Set<Integer> requestedIds = importList.stream()
.map(OrderInvoiceRecordImportVO::getId)
.filter(id -> id != null)
.collect(Collectors.toCollection(HashSet::new));
if (CollectionUtils.isEmpty(requestedIds)) {
return "导入失败文件中缺少申请记录ID";
}
GetInvoiceInfoDTO dto = new GetInvoiceInfoDTO();
dto.setIds(requestedIds.toArray(new Integer[0]));
Set<Integer> authorizedIds = getInvoiceExportListWithAuth(dto).stream()
.map(OrderInvoiceRecordExportVO::getId)
.filter(id -> id != null)
.collect(Collectors.toCollection(HashSet::new));
int successNum = 0;
int skipNum = 0;
List<String> messages = new ArrayList<>();
for (int i = 0; i < importList.size(); i++) {
OrderInvoiceRecordImportVO item = importList.get(i);
int rowNum = i + 2;
if (item.getId() == null) {
messages.add("" + rowNum + "行缺少申请记录ID");
continue;
}
if (!authorizedIds.contains(item.getId())) {
messages.add("" + rowNum + "行申请记录无权限或不存在");
continue;
}
if (StringUtils.isEmpty(item.getInvoiceImage())) {
skipNum++;
continue;
}
String absolutePath = buildAbsoluteImportPath(item.getInvoiceImage());
try {
byte[] imageBytes = java.nio.file.Files.readAllBytes(Paths.get(absolutePath));
String url = AliyunOssUploadUtils.upload2OSS(imageBytes, new File(absolutePath).getName());
OrderInvoiceRecord updateRecord = new OrderInvoiceRecord();
updateRecord.setId(item.getId());
updateRecord.setInvoiceUrl(url);
updateRecord.setStatus("1");
updateRecord.setUpdateBy(operName);
updateRecord.setUpdateTime(new Date());
if (orderInvoiceRecordMapper.updateOrderInvoiceRecord(updateRecord) > 0) {
successNum++;
} else {
messages.add("" + rowNum + "行更新失败");
}
} catch (Exception e) {
messages.add("" + rowNum + "行导入失败:" + e.getMessage());
} finally {
FileUtils.deleteFile(absolutePath);
}
}
StringBuilder result = new StringBuilder();
result.append("成功导入").append(successNum).append("条发票数据");
if (skipNum > 0) {
result.append(",跳过未贴图记录").append(skipNum).append("");
}
if (CollectionUtils.isNotEmpty(messages)) {
result.append(",失败").append(messages.size()).append("条:<br/>")
.append(String.join("<br/>", messages));
}
return result.toString();
}
private boolean fillAuthorizedMerchantDeptIds(GetInvoiceInfoDTO dto) {
// 获取登录账号信息
AuthorizedDeptVO authorizedMap = UserUtils.getAuthorizedMap();
@@ -122,6 +206,17 @@ public class OrderInvoiceRecordServiceImpl implements OrderInvoiceRecordService
return true;
}
private String buildAbsoluteImportPath(String relativePath) {
if (StringUtils.isEmpty(relativePath)) {
return relativePath;
}
File file = new File(relativePath);
if (file.isAbsolute()) {
return relativePath;
}
return Paths.get(JsowellConfig.getProfile(), relativePath).toString();
}
@Override
public List<OrderInvoiceRecord> selectInvoiceRecordList(QueryInvoiceRecordDTO dto) {
return orderInvoiceRecordMapper.selectInvoiceRecordList(dto);

View File

@@ -44,6 +44,11 @@ public class InvoiceRecordVO {
*/
private String updateTime;
/**
* 发票图片url
*/
private String invoiceUrl;
/**
* 发票抬头信息
*/

View File

@@ -1,6 +1,7 @@
package com.jsowell.pile.vo.web;
import com.jsowell.common.annotation.Excel;
import com.jsowell.common.annotation.Excel.ColumnType;
import lombok.Data;
import java.math.BigDecimal;
@@ -10,6 +11,9 @@ import java.math.BigDecimal;
*/
@Data
public class OrderInvoiceRecordExportVO {
@Excel(name = "申请记录ID")
private Integer id;
@Excel(name = "会员ID")
private String memberId;
@@ -63,4 +67,7 @@ public class OrderInvoiceRecordExportVO {
@Excel(name = "开票时间")
private String updateTime;
@Excel(name = "发票图片", cellType = ColumnType.IMAGE, width = 30, height = 80)
private String invoiceImage;
}

View File

@@ -0,0 +1,17 @@
package com.jsowell.pile.vo.web;
import com.jsowell.common.annotation.Excel;
import com.jsowell.common.annotation.Excel.ColumnType;
import lombok.Data;
/**
* 申请开票导入对象
*/
@Data
public class OrderInvoiceRecordImportVO {
@Excel(name = "申请记录ID")
private Integer id;
@Excel(name = "发票图片", cellType = ColumnType.IMAGE)
private String invoiceImage;
}

View File

@@ -18,6 +18,7 @@ public class OrderInvoiceRecordVO {
private String merchantName;
private String titleId;
private String email;
private String invoiceUrl;
private String orderCodes;
private String status;
private String createTime;

View File

@@ -11,6 +11,7 @@
<result property="titleId" column="title_id" />
<result property="phoneNumber" column="phone_number" />
<result property="email" column="email" />
<result property="invoiceUrl" column="invoice_url" />
<result property="orderCodes" column="order_codes" />
<result property="status" column="status" />
<result property="totalAmount" column="total_amount" />
@@ -25,7 +26,7 @@
<sql id="Base_Column_List">
<!--@mbg.generated-->
id, member_id, merchant_id, title_id, phone_number, email, order_codes, status, total_amount, total_service_amount, total_elec_amount,
id, member_id, merchant_id, title_id, phone_number, email, invoice_url, order_codes, status, total_amount, total_service_amount, total_elec_amount,
create_by, create_time, update_by, update_time, del_flag
</sql>
@@ -59,6 +60,7 @@
<if test="titleId != null">title_id,</if>
<if test="phoneNumber != null">phone_number,</if>
<if test="email != null">email,</if>
<if test="invoiceUrl != null">invoice_url,</if>
<if test="orderCodes != null">order_codes,</if>
<if test="status != null">status,</if>
<if test="totalAmount != null">total_amount,</if>
@@ -76,6 +78,7 @@
<if test="titleId != null">#{titleId},</if>
<if test="phoneNumber != null">#{phoneNumber},</if>
<if test="email != null">#{email},</if>
<if test="invoiceUrl != null">#{invoiceUrl},</if>
<if test="orderCodes != null">#{orderCodes},</if>
<if test="status != null">#{status},</if>
<if test="totalAmount != null">#{totalAmount},</if>
@@ -94,6 +97,10 @@
<trim prefix="SET" suffixOverrides=",">
<if test="memberId != null">member_id = #{memberId},</if>
<if test="merchantId != null">merchant_id = #{merchantId},</if>
<if test="titleId != null">title_id = #{titleId},</if>
<if test="phoneNumber != null">phone_number = #{phoneNumber},</if>
<if test="email != null">email = #{email},</if>
<if test="invoiceUrl != null">invoice_url = #{invoiceUrl},</if>
<if test="orderCodes != null">order_codes = #{orderCodes},</if>
<if test="status != null">status = #{status},</if>
<if test="totalAmount != null">total_amount = #{totalAmount},</if>
@@ -145,6 +152,7 @@
t2.merchant_name as merchantName,
t1.title_id as titleId,
t1.email as email,
t1.invoice_url as invoiceUrl,
t1.order_codes as orderCodes,
t1.STATUS as status,
t1.create_time as createTime,
@@ -171,6 +179,7 @@
<select id="getInvoiceExportListWithAuth" resultType="com.jsowell.pile.vo.web.OrderInvoiceRecordExportVO">
SELECT
t1.id AS id,
t1.member_id AS memberId,
t4.mobile_number AS memberPhoneNumber,
t2.merchant_name AS merchantName,
@@ -188,7 +197,8 @@
t1.total_service_amount AS totalServiceAmount,
t1.total_elec_amount AS totalElecAmount,
t1.create_time AS createTime,
t1.update_time AS updateTime
t1.update_time AS updateTime,
t1.invoice_url AS invoiceImage
FROM order_invoice_record t1
LEFT JOIN pile_merchant_info t2 ON t1.merchant_id = t2.id
LEFT JOIN member_invoice_title t3 ON t1.title_id = t3.id AND t3.del_flag = '0'
@@ -248,6 +258,7 @@
t2.mobile_number AS phoneNumber,
t1.merchant_id AS merchantId,
t1.title_id AS titleId,
t1.invoice_url AS invoiceUrl,
t1.order_codes AS orderCodes,
t1.STATUS,
t1.total_amount AS totalAmount,

View File

@@ -0,0 +1,2 @@
ALTER TABLE order_invoice_record
ADD COLUMN invoice_url varchar(500) DEFAULT NULL COMMENT '发票图片url' AFTER email;