diff --git a/jianshui-admin/src/main/java/com/jianshui/api/controller/http/invoice/v1/InvoiceController.java b/jianshui-admin/src/main/java/com/jianshui/api/controller/http/invoice/v1/InvoiceController.java index 73c1e2f..9e3dc7d 100644 --- a/jianshui-admin/src/main/java/com/jianshui/api/controller/http/invoice/v1/InvoiceController.java +++ b/jianshui-admin/src/main/java/com/jianshui/api/controller/http/invoice/v1/InvoiceController.java @@ -1,7 +1,10 @@ package com.jianshui.api.controller.http.invoice.v1; import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.codec.Base64Decoder; +import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSONObject; @@ -17,19 +20,17 @@ import com.jianshui.common.utils.http.HttpHelper; import com.jianshui.common.utils.uuid.IdUtils; import com.jianshui.framework.manager.AsyncManager; import com.jianshui.invoice.constant.elephant.ElephantConstants; -import com.jianshui.invoice.domain.BillInfo; -import com.jianshui.invoice.domain.FindRedInfo; -import com.jianshui.invoice.domain.InvoiceBack; +import com.jianshui.invoice.domain.*; import com.jianshui.invoice.domain.ele.EleNewMessage; import com.jianshui.invoice.domain.ele.EleOuterMessage; import com.jianshui.invoice.domain.ele.FindRedInfoDTO; import com.jianshui.invoice.domain.ele.HZSQDMessage; import com.jianshui.invoice.mapper.InvoiceBackMapper; +import com.jianshui.invoice.mapper.InvoiceFileMapper; import com.jianshui.invoice.task.AddInvoiceBatchTask; import com.jianshui.invoice.task.InvoiceBackTask; import com.jianshui.invoice.utils.elephant.ElephantUtils; import com.jianshui.platform.dto.InvoiceAdd.BillInfoPDTO; -import com.jianshui.invoice.domain.Redinfo; import com.jianshui.invoice.domain.dto.*; import com.jianshui.invoice.domain.dto.api.*; import com.jianshui.invoice.service.IInvoiceApiService; @@ -45,6 +46,7 @@ import com.jianshui.system.service.IServiceManageService; import io.swagger.annotations.*; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; import org.springframework.scheduling.annotation.Async; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -52,7 +54,9 @@ import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; -import java.io.UnsupportedEncodingException; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.net.URLEncoder; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.*; @@ -89,6 +93,9 @@ public class InvoiceController { @Autowired private InvoiceBackMapper invoiceBackMapper; + @Autowired + private InvoiceFileMapper invoiceFileMapper; + /** * 功能描述: 红字查询接口 @@ -301,6 +308,39 @@ public class InvoiceController { return invoiceResponseService.response(result, companyservice, "query"); } + @ApiImplicitParams({ + @ApiImplicitParam(name = "identity", value = "身份认证", dataType = "java.lang.Void", example = "1130", required = true), + @ApiImplicitParam(name = "order", value = "请求体", dataType = "java.lang.Void", required = true)}) + @GetMapping("/invoice/fileUrl/{id}") + public void fileUrl(@PathVariable String id, HttpServletResponse response) throws Exception { + + if (StrUtil.isEmpty(id)) { + return; + } + InvoiceFile invoiceFile = invoiceFileMapper.selectInvoiceFileById(id); + if (BeanUtil.isEmpty(invoiceFile) || StrUtil.isEmpty(invoiceFile.getFileContent())) { + return; + } + String fileName = invoiceFile.getFileName(); + String content = invoiceFile.getFileContent(); + + try { + byte[] buffer = Base64Decoder.decode(content); // 将文件流字符串转换为字节数组 + response.reset(); + response.setCharacterEncoding("UTF-8"); + response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".pdf"); + response.addHeader("Content-Length", "" + buffer.length); + response.setContentType("application/pdf"); + OutputStream outputStream = new BufferedOutputStream(response.getOutputStream()); + outputStream.write(buffer); + outputStream.flush(); + outputStream.close(); // 关闭输出流 + } catch (IOException ex) { + ex.printStackTrace(); + } + } + + /** * 开票查询接口(订单号) */ @@ -1916,5 +1956,4 @@ public class InvoiceController { } - } diff --git a/jianshui-admin/src/main/resources/application-dev.yml b/jianshui-admin/src/main/resources/application-dev.yml index 849ddab..9f6f541 100644 --- a/jianshui-admin/src/main/resources/application-dev.yml +++ b/jianshui-admin/src/main/resources/application-dev.yml @@ -89,6 +89,8 @@ spring: ele_auth_url: https://openapi.zncspt.com/api/ ele_check_url: https://openapi.zncspt.com/api/ elephant_entcode_check: 91370102MA3UD2FG21 +# 文件下载地址 +elephant_invoice_file: http://dev.goldentaxcloud.com/8081/invoice/fileUrl/ #logstash: # host: 43.138.58.64:14560 # indexname: jianshui-dev \ No newline at end of file diff --git a/jianshui-admin/src/main/resources/application-prod.yml b/jianshui-admin/src/main/resources/application-prod.yml index 26b6915..9e20d41 100644 --- a/jianshui-admin/src/main/resources/application-prod.yml +++ b/jianshui-admin/src/main/resources/application-prod.yml @@ -83,6 +83,8 @@ spring: ele_auth_url: https://openapi.ele-cloud.com/api/dxhy-open-income/v1/ ele_check_url: https://openapi.zncspt.com/api/ elephant_entcode_check: 91370102MA3UD2FG21 +# 文件下载地址 +elephant_invoice_file: http://dev.goldentaxcloud.com/8081/invoice/fileUrl/ #logstash: # host: 43.138.58.64:14560 # indexname: jianshui-prod \ No newline at end of file diff --git a/jianshui-framework/src/main/java/com/jianshui/framework/config/SecurityConfig.java b/jianshui-framework/src/main/java/com/jianshui/framework/config/SecurityConfig.java index 22e147a..02097f5 100644 --- a/jianshui-framework/src/main/java/com/jianshui/framework/config/SecurityConfig.java +++ b/jianshui-framework/src/main/java/com/jianshui/framework/config/SecurityConfig.java @@ -119,7 +119,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { "/invoice/batch_print", "/invoice/printer_list", "/invoice/deleteInvoice", - "/invoice/findRedInfo" + "/invoice/findRedInfo", + "/invoice/fileUrl/**" ) .permitAll() // 所有原有发票 .antMatchers( diff --git a/jianshui-invoice/src/main/java/com/jianshui/invoice/domain/InvoiceFile.java b/jianshui-invoice/src/main/java/com/jianshui/invoice/domain/InvoiceFile.java new file mode 100644 index 0000000..d5b29ca --- /dev/null +++ b/jianshui-invoice/src/main/java/com/jianshui/invoice/domain/InvoiceFile.java @@ -0,0 +1,108 @@ +package com.jianshui.invoice.domain; + +import com.jianshui.common.annotation.Excel; +import com.jianshui.common.core.domain.BaseEntity; +import net.logstash.logback.encoder.org.apache.commons.lang3.builder.ToStringBuilder; +import net.logstash.logback.encoder.org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 发票URL存储对象 invoice_file + * + * @author kk + * @date 2023-12-04 + */ +public class InvoiceFile extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键id */ + private String id; + + /** 文件id */ + @Excel(name = "文件id") + private String fileId; + + /** 文件名字 */ + @Excel(name = "文件名字") + private String fileName; + + /** 文件流 */ + @Excel(name = "文件流") + private String fileContent; + + /** 创建企业 */ + @Excel(name = "创建企业") + private String identity; + + /** 税号 */ + @Excel(name = "税号") + private String tax; + + public void setId(String id) + { + this.id = id; + } + + public String getId() + { + return id; + } + public void setFileId(String fileId) + { + this.fileId = fileId; + } + + public String getFileId() + { + return fileId; + } + public void setFileName(String fileName) + { + this.fileName = fileName; + } + + public String getFileName() + { + return fileName; + } + public void setFileContent(String fileContent) + { + this.fileContent = fileContent; + } + + public String getFileContent() + { + return fileContent; + } + public void setIdentity(String identity) + { + this.identity = identity; + } + + public String getIdentity() + { + return identity; + } + public void setTax(String tax) + { + this.tax = tax; + } + + public String getTax() + { + return tax; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("fileId", getFileId()) + .append("fileName", getFileName()) + .append("fileContent", getFileContent()) + .append("createTime", getCreateTime()) + .append("identity", getIdentity()) + .append("tax", getTax()) + .toString(); + } +} diff --git a/jianshui-invoice/src/main/java/com/jianshui/invoice/mapper/InvoiceFileMapper.java b/jianshui-invoice/src/main/java/com/jianshui/invoice/mapper/InvoiceFileMapper.java new file mode 100644 index 0000000..2d2b5ce --- /dev/null +++ b/jianshui-invoice/src/main/java/com/jianshui/invoice/mapper/InvoiceFileMapper.java @@ -0,0 +1,61 @@ +package com.jianshui.invoice.mapper; + +import java.util.List; +import com.jianshui.invoice.domain.InvoiceFile; + +/** + * 发票URL存储Mapper接口 + * + * @author kk + * @date 2023-12-04 + */ +public interface InvoiceFileMapper +{ + /** + * 查询发票URL存储 + * + * @param id 发票URL存储主键 + * @return 发票URL存储 + */ + public InvoiceFile selectInvoiceFileById(String id); + + /** + * 查询发票URL存储列表 + * + * @param invoiceFile 发票URL存储 + * @return 发票URL存储集合 + */ + public List selectInvoiceFileList(InvoiceFile invoiceFile); + + /** + * 新增发票URL存储 + * + * @param invoiceFile 发票URL存储 + * @return 结果 + */ + public int insertInvoiceFile(InvoiceFile invoiceFile); + + /** + * 修改发票URL存储 + * + * @param invoiceFile 发票URL存储 + * @return 结果 + */ + public int updateInvoiceFile(InvoiceFile invoiceFile); + + /** + * 删除发票URL存储 + * + * @param id 发票URL存储主键 + * @return 结果 + */ + public int deleteInvoiceFileById(String id); + + /** + * 批量删除发票URL存储 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteInvoiceFileByIds(String[] ids); +} diff --git a/jianshui-invoice/src/main/java/com/jianshui/invoice/service/IInvoiceFileService.java b/jianshui-invoice/src/main/java/com/jianshui/invoice/service/IInvoiceFileService.java new file mode 100644 index 0000000..dd7e191 --- /dev/null +++ b/jianshui-invoice/src/main/java/com/jianshui/invoice/service/IInvoiceFileService.java @@ -0,0 +1,61 @@ +package com.jianshui.invoice.service; + +import java.util.List; +import com.jianshui.invoice.domain.InvoiceFile; + +/** + * 发票URL存储Service接口 + * + * @author kk + * @date 2023-12-04 + */ +public interface IInvoiceFileService +{ + /** + * 查询发票URL存储 + * + * @param id 发票URL存储主键 + * @return 发票URL存储 + */ + public InvoiceFile selectInvoiceFileById(String id); + + /** + * 查询发票URL存储列表 + * + * @param invoiceFile 发票URL存储 + * @return 发票URL存储集合 + */ + public List selectInvoiceFileList(InvoiceFile invoiceFile); + + /** + * 新增发票URL存储 + * + * @param invoiceFile 发票URL存储 + * @return 结果 + */ + public int insertInvoiceFile(InvoiceFile invoiceFile); + + /** + * 修改发票URL存储 + * + * @param invoiceFile 发票URL存储 + * @return 结果 + */ + public int updateInvoiceFile(InvoiceFile invoiceFile); + + /** + * 批量删除发票URL存储 + * + * @param ids 需要删除的发票URL存储主键集合 + * @return 结果 + */ + public int deleteInvoiceFileByIds(String[] ids); + + /** + * 删除发票URL存储信息 + * + * @param id 发票URL存储主键 + * @return 结果 + */ + public int deleteInvoiceFileById(String id); +} diff --git a/jianshui-invoice/src/main/java/com/jianshui/invoice/service/impl/InvoiceFileServiceImpl.java b/jianshui-invoice/src/main/java/com/jianshui/invoice/service/impl/InvoiceFileServiceImpl.java new file mode 100644 index 0000000..4f0455a --- /dev/null +++ b/jianshui-invoice/src/main/java/com/jianshui/invoice/service/impl/InvoiceFileServiceImpl.java @@ -0,0 +1,95 @@ +package com.jianshui.invoice.service.impl; + +import java.util.List; +import com.jianshui.common.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.jianshui.invoice.mapper.InvoiceFileMapper; +import com.jianshui.invoice.domain.InvoiceFile; +import com.jianshui.invoice.service.IInvoiceFileService; + +/** + * 发票URL存储Service业务层处理 + * + * @author kk + * @date 2023-12-04 + */ +@Service +public class InvoiceFileServiceImpl implements IInvoiceFileService +{ + @Autowired + private InvoiceFileMapper invoiceFileMapper; + + /** + * 查询发票URL存储 + * + * @param id 发票URL存储主键 + * @return 发票URL存储 + */ + @Override + public InvoiceFile selectInvoiceFileById(String id) + { + return invoiceFileMapper.selectInvoiceFileById(id); + } + + /** + * 查询发票URL存储列表 + * + * @param invoiceFile 发票URL存储 + * @return 发票URL存储 + */ + @Override + public List selectInvoiceFileList(InvoiceFile invoiceFile) + { + return invoiceFileMapper.selectInvoiceFileList(invoiceFile); + } + + /** + * 新增发票URL存储 + * + * @param invoiceFile 发票URL存储 + * @return 结果 + */ + @Override + public int insertInvoiceFile(InvoiceFile invoiceFile) + { + invoiceFile.setCreateTime(DateUtils.getNowDate()); + return invoiceFileMapper.insertInvoiceFile(invoiceFile); + } + + /** + * 修改发票URL存储 + * + * @param invoiceFile 发票URL存储 + * @return 结果 + */ + @Override + public int updateInvoiceFile(InvoiceFile invoiceFile) + { + return invoiceFileMapper.updateInvoiceFile(invoiceFile); + } + + /** + * 批量删除发票URL存储 + * + * @param ids 需要删除的发票URL存储主键 + * @return 结果 + */ + @Override + public int deleteInvoiceFileByIds(String[] ids) + { + return invoiceFileMapper.deleteInvoiceFileByIds(ids); + } + + /** + * 删除发票URL存储信息 + * + * @param id 发票URL存储主键 + * @return 结果 + */ + @Override + public int deleteInvoiceFileById(String id) + { + return invoiceFileMapper.deleteInvoiceFileById(id); + } +} diff --git a/jianshui-invoice/src/main/java/com/jianshui/invoice/service/impl/adapter/request/AisinoInvoiceRequestAdapterImpl.java b/jianshui-invoice/src/main/java/com/jianshui/invoice/service/impl/adapter/request/AisinoInvoiceRequestAdapterImpl.java index 5665e06..a7b93f8 100644 --- a/jianshui-invoice/src/main/java/com/jianshui/invoice/service/impl/adapter/request/AisinoInvoiceRequestAdapterImpl.java +++ b/jianshui-invoice/src/main/java/com/jianshui/invoice/service/impl/adapter/request/AisinoInvoiceRequestAdapterImpl.java @@ -105,7 +105,7 @@ public class AisinoInvoiceRequestAdapterImpl implements IInvoiceRequestService { // 平台解密 try { // TODO: 2023/9/20 - order = AisinoInvoiceDecryptUtil.decrypt(order, JKey); +// order = AisinoInvoiceDecryptUtil.decrypt(order, JKey); } catch (Exception e) { e.printStackTrace(); throw new JianshuiParamErrorException(ErrorCode.DECRYPT_ERROR, companyservice, "invoice"); diff --git a/jianshui-invoice/src/main/java/com/jianshui/invoice/service/impl/api/ElephantInvoiceApiV6ServiceImpl.java b/jianshui-invoice/src/main/java/com/jianshui/invoice/service/impl/api/ElephantInvoiceApiV6ServiceImpl.java index c07d290..44226fa 100644 --- a/jianshui-invoice/src/main/java/com/jianshui/invoice/service/impl/api/ElephantInvoiceApiV6ServiceImpl.java +++ b/jianshui-invoice/src/main/java/com/jianshui/invoice/service/impl/api/ElephantInvoiceApiV6ServiceImpl.java @@ -30,6 +30,7 @@ import com.jianshui.common.utils.StringUtils; import com.jianshui.common.utils.TimeUtil; import com.jianshui.common.utils.ValidateUtils; import com.jianshui.common.utils.http.HttpHelper; +import com.jianshui.common.utils.spring.SpringUtils; import com.jianshui.common.utils.uuid.IdUtils; import com.jianshui.framework.manager.AsyncManager; import com.jianshui.invoice.constant.elephant.ElephantConstants; @@ -48,6 +49,7 @@ import com.jianshui.invoice.domain.ele.*; import com.jianshui.invoice.domain.vo.InvoiceAllQycodeResultElEVO; import com.jianshui.invoice.domain.vo.jcsk.*; import com.jianshui.invoice.mapper.BillInfoMapper; +import com.jianshui.invoice.mapper.InvoiceFileMapper; import com.jianshui.invoice.mapper.InvoiceMapper; import com.jianshui.invoice.mapper.RedinfoMapper; import com.jianshui.invoice.service.IBillInfoService; @@ -71,6 +73,7 @@ import org.apache.ibatis.annotations.Lang; import org.joda.time.format.DateTimeFormat; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; @@ -118,6 +121,16 @@ public class ElephantInvoiceApiV6ServiceImpl implements IInvoiceApiService { @Autowired private InvoiceAllApiLogMapper allApiLogMapper; + @Autowired + private InvoiceFileMapper invoiceFileMapper; + + private static String ELE_File_URL; + + static { + Environment environment = SpringUtils.getBean(Environment.class); + ELE_File_URL = environment.getProperty("elephant_invoice_file"); + } + /** * 发票开具 * v6 @@ -524,8 +537,30 @@ public class ElephantInvoiceApiV6ServiceImpl implements IInvoiceApiService { debugLog("断点12", uuid, timestamp); // 上传文件到oss String defaultStorage = configService.selectConfigByKey("default_storage"); - // 2023/11/16 kk:上传OSS转下载地址关闭,改为直接返回大象的文件流 - invoice.setInvoicePdfUrl(ddfpxx.getPDFZJL()); + + + // 2023/12/4 存储文件流至数据库,方便迁移,提供文件下载接口。 start + // invoiceFileMapper + String fileId = IdUtils.randomUUID(); + String fileName = invoice.getFphm(); + + if(ddfpxx.getPDFZJL() != null && StrUtil.isNotEmpty(ddfpxx.getPDFZJL())){ + InvoiceFile invoiceFile = new InvoiceFile(); + invoiceFile.setId(fileId); + invoiceFile.setFileContent(ddfpxx.getPDFZJL()); + invoiceFile.setFileId(fileId); + invoiceFile.setFileName(fileName); + invoiceFile.setCreateTime(new Date()); + invoiceFile.setIdentity(companyservice.getIdentity()); + invoiceFile.setTax(companyservice.getSellertax()); + invoiceFileMapper.insertInvoiceFile(invoiceFile); + + // 2023/11/16 kk:上传OSS转下载地址关闭,改为直接返回大象的文件流 + invoice.setInvoicePdfUrl(ELE_File_URL + fileId); + } + // end + + /*if (StringUtils.isNotEmpty(defaultStorage) && StringUtils.isEmpty(invoice.getInvoicePdfUrl())) { try { IStorageService service = storageFactory.getStorageInstance(defaultStorage); diff --git a/jianshui-invoice/src/main/resources/mapper/invoice/InvoiceFileMapper.xml b/jianshui-invoice/src/main/resources/mapper/invoice/InvoiceFileMapper.xml new file mode 100644 index 0000000..1b75f3a --- /dev/null +++ b/jianshui-invoice/src/main/resources/mapper/invoice/InvoiceFileMapper.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + select id, file_id, file_name, file_content, create_time, identity, tax from invoice_file + + + + + + + + insert into invoice_file + + id, + file_id, + file_name, + file_content, + create_time, + identity, + tax, + + + #{id}, + #{fileId}, + #{fileName}, + #{fileContent}, + #{createTime}, + #{identity}, + #{tax}, + + + + + update invoice_file + + file_id = #{fileId}, + file_name = #{fileName}, + file_content = #{fileContent}, + create_time = #{createTime}, + identity = #{identity}, + tax = #{tax}, + + where id = #{id} + + + + delete from invoice_file where id = #{id} + + + + delete from invoice_file where id in + + #{id} + + + \ No newline at end of file