标题
**一:**前期都是自己百度去查询接口,查了大概三四天,最终确认下来,本人用的接口是盟度开票接口
中间都是参数的传递,业务的梳理,用到一个xml解析,一个调用第三方的接口的工具类,这两个我都有发布,可以去我的博客查询。
package com.chenhao.orderandcart.invoice.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.chenhao.orderandcart.common.utils.IdWorker;
import com.chenhao.orderandcart.invoice.dto.*;
import com.chenhao.orderandcart.invoice.fegin.FilePdfFeign;
import com.chenhao.orderandcart.invoice.mapper.InvoiceMapper;
import com.chenhao.orderandcart.invoice.mapper.InvoiceMessageMapper;
import com.chenhao.orderandcart.invoice.pojo.Invoice;
import com.chenhao.orderandcart.invoice.pojo.PassBackInfo;
import com.chenhao.orderandcart.invoice.pojo.RefreshTokenResponse;
import com.chenhao.orderandcart.invoice.service.InvoiceService;
import com.chenhao.orderandcart.invoice.utils.*;
import com.chenhao.util.JsonUtils;
import com.chenhao.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Service
@Slf4j
public class InvoiceServiceImpl extends ServiceImpl<InvoiceMapper, Invoice> implements InvoiceService {
@Autowired
private IdWorker idWorker;
@Autowired
private InvoiceMessageMapper invoiceMessageMapper;
@Autowired
FilePdfFeign fileFeign;
@Autowired
private InvoiceMapper invoiceMapper;
@Value("${kpurl.fpUploadUrl}")
private String fp_Upload_Url;
@Value("${kpurl.fpCancelUrl}")
private String fp_Cancel_Url;
@Override
public Result requestInvoice(InvoiceEntryDTO invoiceEntryDTO) {
//扫码开票路径
String url="http://ek.caikaixin.cn/sendRequest";
String os = System.getProperty("os.name");
Long orderId = invoiceEntryDTO.getOrderId();
InvoiceEntryDTO commodity = invoiceMessageMapper.selectCommodity(orderId);
Integer integer = invoiceMapper.selectStatus(orderId);
Long invoiceOrderId=idWorker.nextId();
//如果没有开票成功,就重新生成订单号去开
int j=0;
if (integer!= null && integer!=1){
System.out.println("订单重新开票中。。。。。。。。。。。。。。。。。。");
invoiceOrderId=idWorker.nextId();
invoiceMapper.updateInvoiceOrderId(orderId,invoiceOrderId);
j=1;
}
//得到总价格
BigDecimal spdj = commodity.getSpdj();
BigDecimal a = new BigDecimal(commodity.getSpsl());
BigDecimal shopJE = a.multiply(spdj);
//税额
BigDecimal shopSE=shopJE.multiply(commodity.getSlv());
System.out.println("总价----》"+shopJE+":税额----》"+shopSE);
String spxx="<business id=\"zzsfp\" comment=\""+invoiceOrderId+"\">\n" +
" <body yylxdm=\"1\">\n" +
" <input>\n" +
" <bz>"+invoiceEntryDTO.getBz()+"</bz>\n" +
" <fpmx count=\"1\">\n" +
" <group xh=\"1\">\n" +
" <spmc>"+commodity.getSpmc()+"</spmc>\n" +
" <ggxh>"+commodity.getGgxh()+"</ggxh>\n" +
" <jldw>"+commodity.getJldw()+"</jldw>\n" +
" <spsl>"+commodity.getSpsl()+"</spsl>\n" +
" <spdj>"+commodity.getSpdj()+"</spdj>\n" +
" <je>"+shopJE+"</je>\n" +
" <slv>"+commodity.getSlv()+"</slv>\n" +
" <se>"+shopSE+"</se>\n" +
" <hsbz>"+1+"</hsbz>\n" +
" <spbm>"+commodity.getSpbm()+"</spbm>\n" +
" <SYYHZCBZ>"+0+"</SYYHZCBZ>\n" +
" <YHZCSM></YHZCSM>\n" +
" </group>\n" +
" </fpmx>\n" +
" </input>\n" +
" </body>\n" +
"</business>";
//获取供应商id
System.out.println("spxx"+spxx);
Long uid = invoiceMessageMapper.selectSuppIdByOId(invoiceEntryDTO.getOrderId());
//通过供应商id查到供应商开发票信息
InvoiceMessageDTO invoiceMessageDTO = invoiceMessageMapper.selectToken(uid);
String strEncode=null;
if (os.contains("Win")){
invoiceEntryDTO.setOsType("Windows");
strEncode = EncodeUtils.AESEncode(invoiceMessageDTO.getInvoice(), spxx);
System.out.println("Windows"+strEncode);
}
if (os.contains("Linux")){
invoiceEntryDTO.setOsType("Linux");
strEncode = AESUtilsForLinux.AESEncode(invoiceMessageDTO.getInvoice(),spxx);
System.out.println("Linux"+strEncode);
}
String ss=DncodeUtils.AESDncode(invoiceMessageDTO.getInvoice(),strEncode);
System.out.println("ss"+ss);
String invoiceApplyFor="{\n" +
"\t\"invoice\": \""+invoiceMessageDTO.getInvoice()+"\",\n" +
"\"kpjh\": \""+invoiceMessageDTO.getKpjh()+"\",\n" +
"\t\"token\": \""+invoiceMessageDTO.getJointToken()+" \",\n" +
"\t\"spxx\": \""+strEncode+"\",\n" +
"\t\"orderId\": \""+invoiceOrderId+"\",\n" +
"\t\"os_type\": \""+invoiceEntryDTO.getOsType()+"\"\n" +
"} \n";
System.out.println("invoiceApplyFor"+invoiceApplyFor);
String s = HttpUrlUtils.doPostOrGet(url, invoiceApplyFor);
System.out.println("请求开发票接口返回的参数----》"+s);
JSONObject jsonObject = JSON.parseObject(s);
Object errcode = jsonObject.get("errcode");
if (errcode.equals("3005") ){
//根据订单id查询供应商id
Long aLong = invoiceMessageMapper.selectSuppIdByOId(invoiceEntryDTO.getOrderId());
Result result = requestToken(aLong);
Object data = result.getData();
invoiceEntryDTO.setToken(data.toString());
System.out.println("token失效,正在重新获取并开票");
Result result1 = requestInvoice(invoiceEntryDTO);
return result1;
}
if (!errcode.equals("200") && !errcode.equals("3007")){
String errmsg = jsonObject.get("errmsg").toString();
return new Result(-1,errmsg,null);
}
JSONArray result = jsonObject.getJSONArray("info");
JSONObject urls = result.getJSONObject(0);
String info = urls.getString("url");
InvoiceDTO invoiceDTO1 = invoiceMapper.selectInvoiceByID(orderId);
if (!StringUtils.isEmpty(invoiceDTO1)){
if (invoiceDTO1.getStatus()!=0){
return new Result(-1,"该订单已开据发票,请勿重复提交",null);
}
}else if (j==0){
InvoiceDTO invoiceDTO=new InvoiceDTO();
invoiceDTO.setInvoiceId(idWorker.nextId());
invoiceDTO.setOrderId(invoiceEntryDTO.getOrderId());
invoiceDTO.setInvoiceAmount(shopJE);
invoiceDTO.setInvoiceTax(shopSE);
invoiceDTO.setCreatedTime(new Date());
invoiceDTO.setUrl(info);
invoiceDTO.setStatus(0);
invoiceDTO.setInvoiceOrderId(invoiceOrderId);
invoiceMapper.insertInvoice(invoiceDTO);
}
String infoNew=info.replaceAll("http://","https://api.lspowerstyle.cn/");
System.out.println("info--"+infoNew);
return new Result(0,"开票成功",infoNew);
}
/**
* 获取token,根据供应商id
*/
@Override
public Result requestToken(Long id) {
String tokenUrl="http://ek.caikaixin.cn/token";
InvoiceMessageDTO invoiceMessageDTO = invoiceMessageMapper.selectIvTokenBySupplierId(id);
String tokenParam=" {\"invoice\":\""+invoiceMessageDTO.getInvoice()+"\",\n" +
" \"kpjh\":\""+invoiceMessageDTO.getKpjh()+"\",\n" +
" \"token\":\""+invoiceMessageDTO.getIvToken()+"\"\n" +
" \t\n" +
" }";
String s = HttpUrlUtils.doPostOrGet(tokenUrl, tokenParam);
System.out.println("请求获取token接口返回的参数----》"+s);
JSONObject jsonObject = JSON.parseObject(s);
Object errcode = jsonObject.get("errcode");
Object info1 = jsonObject.get("info");
List<RefreshTokenResponse> info = JSONArray.parseArray(JSON.toJSONString(jsonObject.get("info")), RefreshTokenResponse.class);
String token=null;
Integer number=0;
/**
* 获取info里面的信息并解析
*/
for (RefreshTokenResponse refreshTokenResponse : info) {
token=refreshTokenResponse.getToken();
number= refreshTokenResponse.getCount();
}
InvoiceMessageDTO invoiceMessageDTO1=new InvoiceMessageDTO();
System.out.println(token);
if (errcode.equals("200")){
invoiceMessageDTO1.setJointToken(token);
invoiceMessageMapper.insertJoinTokenByMId(invoiceMessageDTO.getId(),token,new Date());
return new Result(0,"刷新成功",token);
}
if (errcode.equals("1001")){
return new Result(-1,"刷新频率过高,请稍后重试",null);
}
return new Result(-1,"刷新失败",null);
}
/**
* 初始化开票信息
*
* @return
*/
@Override
public Result requestInitialize(InitializeDTO initializeDTO, Long uid) {
String registerUrl="http://ek.caikaixin.cn/register";
System.out.println("开始调用");
//获取供应商信息
InvoiceMessageDTO invoiceMessageDTO1 = invoiceMessageMapper.selectToken(uid);
if (invoiceMessageDTO1 != null){
return new Result(-1,"该供应商已注册",null);
}
String para=" {\"company\":\""+initializeDTO.getCompany()+"\",\n" +
" \"invoice\":\""+initializeDTO.getInvoice()+"\",\n" +
" \"kpjh\":\""+initializeDTO.getKpjh()+"\",\n" +
" \"address\":\""+initializeDTO.getAddress()+"\",\n" +
" \"tel\":\""+initializeDTO.getTel()+"\",\n" +
" \"contact\":\""+initializeDTO.getContact()+"\",\n" +
" \"fpUploadUrl\":\""+fp_Upload_Url+"\",\n" +
" \"fpCancelUrl\":\""+fp_Cancel_Url+"\"\n" +
" \t\n" +
" }";
String s = HttpUrlUtils.doPostOrGet(registerUrl, para);
JSONObject jsonObject = JSON.parseObject(s);
Object errcode = jsonObject.get("errcode");
Object info1 = jsonObject.get("info");
if (errcode.equals("200")){
List<RefreshTokenResponse> info = JSONArray.parseArray(JSON.toJSONString(jsonObject.get("info")), RefreshTokenResponse.class);
String token=null;
/**
* 获取info里面的信息并解析
*/
for (RefreshTokenResponse refreshTokenResponse : info) {
token=refreshTokenResponse.getToken();
}
//1.1生成发票,基本信息 雪花算法(snowflake)生成全局唯一的ID
long orderAddressId = idWorker.nextId();
InvoiceMessageDTO invoiceMessageDTO=new InvoiceMessageDTO();
invoiceMessageDTO.setId(orderAddressId);
if (initializeDTO.getCompany() != null) {
invoiceMessageDTO.setCompany(initializeDTO.getCompany());
}
if (initializeDTO.getInvoice() != null){
invoiceMessageDTO.setInvoice(initializeDTO.getInvoice());
}
if (initializeDTO.getKpjh() != null){
invoiceMessageDTO.setKpjh(initializeDTO.getKpjh());
}
if (initializeDTO.getAddress() != null){
invoiceMessageDTO.setAddress(initializeDTO.getAddress());
}
if (initializeDTO.getTel() != null){
invoiceMessageDTO.setTel(initializeDTO.getTel());
}
if (token != null){
invoiceMessageDTO.setIvToken(token);
}
if (initializeDTO.getContact() != null){
invoiceMessageDTO.setContact(initializeDTO.getContact());
}
invoiceMessageDTO.setSupplierId(uid);
invoiceMessageDTO.setCreatTime(new Date());
invoiceMessageMapper.insertMessageBySupplierId(invoiceMessageDTO);
requestToken(invoiceMessageDTO.getSupplierId());
return new Result(0,"开票信息提交成功!",token);
}
return new Result(-1,"开票信息提交失败",errcode);
}
/**
* 发票回传解析
*
* @param invoicePassBackDTO
*/
@Override
public void requestPassBack(InvoicePassBackDTO invoicePassBackDTO) {
String os = System.getProperty("os.name");
String secret = invoicePassBackDTO.getSecret();
List<PassBackInfo> info1 = invoicePassBackDTO.getInfo();
String invoiceOrderId = invoicePassBackDTO.getOrderId();
long invoiceOrderId1 = Long.parseLong(invoiceOrderId);
Long lOrderId = invoiceMapper.selectOrderId(invoiceOrderId1);
Long aLong = invoiceMessageMapper.selectSuppIdByOId(lOrderId);
InvoiceMessageDTO invoiceMessageDTO = invoiceMessageMapper.selectToken(aLong);
InvoiceDTO invoiceDTO1 = new InvoiceDTO();
invoiceDTO1.setOrderId(lOrderId);
if (info1.size()>0 && !StringUtils.isEmpty(invoiceMessageDTO)) {
for (PassBackInfo passBackInfo : info1) {
String fpData = passBackInfo.getFpData();
String s = null;
//判断当前是什么系统发起的请求
if (os.contains("Win")) {
s = DncodeUtils.AESDncode(invoiceMessageDTO.getInvoice(), fpData);
System.out.println("Windows" + s);
}
if (os.contains("Linux")) {
s = AESUtilsForLinux.AESDncode(invoiceMessageDTO.getInvoice(), fpData);
System.out.println("Linux" + s);
}
System.out.println(s);
InvoiceDTO invoiceDTO = new InvoiceDTO();
//这个是解析第三方接口传回来的参数的工具类,我的博客中有解析xml那篇
Map map = XmlToMapUtils.readStringXmlOut(s);
System.out.println("解析xml格式后的数据"+map);
//发票抬头名称
invoiceDTO1.setInvoiceTitle( (String) map.get("GMF_MC"));
//发票金额
invoiceDTO1.setInvoiceAmount(new BigDecimal(String.valueOf( map.get("JE"))));
//发票税号(购方)
invoiceDTO1.setInvoiceTaxNo( (String) map.get("GMF_NSRSBH"));
//发票税金
invoiceDTO1.setInvoiceTax(new BigDecimal(String.valueOf(map.get("SE"))));
//{增值税}公司名称或个人名称
invoiceDTO1.setVatCompanyName((String) map.get("GMF_MC"));
//{增值税}公司地址
invoiceDTO1.setVatCompanyAddress((String)map.get("GMF_DZ"));
//{增值税}联系电话
invoiceDTO1.setVatTelphone((String)map.get("GMF_DH"));
//{增值税}开户银行
invoiceDTO1.setVatBankName((String)map.get("GMF_YH"));
//{增值税}银行账户
invoiceDTO1.setVatBankAccount((String)map.get("GMF_ZH"));
try {
String pdf = passBackInfo.getPdf();
// StringToPDF.base64ContentToFile(pdf, "C:\\Users\\chenh\\Desktop\\test\\" + orderId + ".pdf");
StringToPDF.base64ContentToFile(pdf, "/usr/local/service/tmpfile/" + invoiceOrderId + ".pdf");
String path1 = "/usr/local/service/tmpfile/";
System.out.println(path1);
// String path1 = "C:/Users/chenh/Desktop/test/";
Path path = FileSystems.getDefault().getPath("/usr/local/service/tmpfile/" + lOrderId + ".pdf");
System.out.println(path);
// Path path = FileSystems.getDefault().getPath("C:/Users/chenh/Desktop/test/" + lOrderId + ".pdf");
//二维码上传微软云
File pngFile = new File(path1 + invoiceOrderId + ".pdf");
System.out.println(pngFile);
Result r = fileFeign.azureFileUploadWx(pngFile);
System.out.println(r);
File del = new File(pngFile.toURI());
del.delete();
//二维码数据存数据库
Object data = r.getData();
String serialize = JsonUtils.serialize(data);
JSONObject jsonObject = JSONObject.parseObject(serialize);
String filePathNew = jsonObject.getString("url");
invoiceDTO1.setPdfUrl(filePathNew);
invoiceDTO1.setStatus(1);
invoiceDTO1.setIsVat(1);
boolean b = invoiceMapper.updateInvoice(invoiceDTO1);
System.out.println("订单-----》"+lOrderId+"数据回传成功,数据已修改");
} catch (IOException e) {
System.out.println("Could not generate QR Code, IOException :: " + e.getMessage());
}
}
}
}
}
k控制层就是传参,dao层是查询数据库的,主要就是上面的代码,不懂得欢迎留言