wangkaiyue 1 anno fa
parent
commit
af8c1747c9

+ 7 - 0
config.yaml

@@ -38,3 +38,10 @@ company:
 # 登录相关配置
 loginType: 0 # 税务系统登录方式【0 短信登录 1 扫码登录】
 qwxRobotUrl: "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=e7792e7a-159d-4419-b1ed-27ea19b6ea54" #扫码登录企业微信消息机器人接口
+
+jyPayNotice: "http://192.168.20.241:86/jypay/invoice/callback"
+
+
+pdfFilePathRootDir: "./out"
+pdfFilePathPrefix: "jyInvoice" #即请求路径前缀
+

+ 5 - 56
internal/controller/callback.go

@@ -2,24 +2,11 @@ package controller
 
 import (
 	"ElectronicInvoice/internal/service"
-	"encoding/base64"
-	"fmt"
-	"github.com/gogf/gf/v2/errors/gerror"
 	"github.com/gogf/gf/v2/frame/g"
 	"github.com/gogf/gf/v2/net/ghttp"
-	"net/url"
-	"os"
 	"strings"
-	"time"
 )
 
-type callBackParam struct {
-	CallType  string `json:"calltype"`  // 回调信息类型
-	TaxNum    string `json:"taxNum"`    //税号
-	Tel       string `json:"tel"`       //税号
-	Parameter string `json:"parameter"` //校验
-}
-
 // CallBack 回调
 func CallBack(r *ghttp.Request) {
 	err := func() error {
@@ -30,15 +17,15 @@ func CallBack(r *ghttp.Request) {
 
 		switch callType {
 		case "userQuit": //用户退出登录
-			g.Log().Infof(r.Context(), "长在线退出登录:%s", "string(bb)")
+			g.Log().Info(r.Context(), "长在线退出登录")
 		case "Invoicing": //开发票回调
-			return InvoicingCallBackLogic(r)
+			return service.InvoicingCallBackLogic(r)
 		case "InvoicingAll": //批量开票
-			g.Log().Infof(r.Context(), "用户退出登录:%s", "string(bb)")
+			g.Log().Info(r.Context(), "用户退出登录")
 		case "Offset":
-			g.Log().Infof(r.Context(), "开红票:%s", "string(bb)")
+			g.Log().Info(r.Context(), "开红票:%s")
 		case "livenessDetection":
-			g.Log().Infof(r.Context(), "活体认证:%s", "string(bb)")
+			g.Log().Info(r.Context(), "活体认证:%s")
 		default:
 			g.Log().Infof(r.Context(), "未设置消息回调:%s", callType)
 		}
@@ -52,41 +39,3 @@ func CallBack(r *ghttp.Request) {
 }
 
 //callbak = logging
-
-// InvoicingCallBackLogic 开票回调逻辑
-func InvoicingCallBackLogic(r *ghttp.Request) error {
-	tType := r.Get("type").Int() //type [0 需要活体检测;1 成功 返回base64]
-	switch tType {
-	case 0: //需要活体检测
-		imgVal, err := url.QueryUnescape(r.Get("img").String())
-		if err != nil {
-			return gerror.Wrap(err, "活体检测二维码解析失败")
-		}
-		if err := service.SendQrImage2ChatBot(imgVal); err != nil {
-			return gerror.Wrap(err, "发送活体检测消息出错")
-		}
-	case 1: //开票成功
-		pdfBase64 := r.Get("pdf").String()
-		orderCode := r.Get("id").String()
-		fmt.Println("orderCode")
-		data, err := base64.StdEncoding.DecodeString(pdfBase64)
-		if err != nil {
-			return gerror.Wrap(err, "解析文件base64编码失败")
-		}
-		if err := os.WriteFile(fmt.Sprintf("./%s_%d.pdf", orderCode, time.Now().Unix()), data, 0644); err != nil {
-			return gerror.Wrap(err, "解析文件base64编码失败")
-		}
-		g.Log().Infof(r.Context(), "pdf保存成功")
-	case 3:
-		g.Log().Info(r.Context(), "活体验证已过期,未完成活体验证")
-	case 4:
-		g.Log().Info(r.Context(), "系统错误")
-	case 6:
-		g.Log().Info(r.Context(), "税率不存在")
-	case 7:
-		g.Log().Info(r.Context(), "非数电票试点纳税人,未核定数电票票种,不允许开票或其他原因")
-	default:
-		g.Log().Infof(r.Context(), "InvoicingCallBackLogic tType:%s", tType)
-	}
-	return nil
-}

+ 87 - 1
internal/controller/invoiceAdd.go

@@ -1,8 +1,94 @@
 package controller
 
-import "github.com/gogf/gf/v2/net/ghttp"
+import (
+	"ElectronicInvoice/internal/service/tripartite"
+	"github.com/gogf/gf/v2/errors/gerror"
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/gogf/gf/v2/net/ghttp"
+	"github.com/gogf/gf/v2/util/gconv"
+)
+
+type (
+	addInvoiceAddParam struct {
+		OrderCode string    `json:"Swno"`      //orderCode订单号
+		CustType  string    `json:"custType"`  //购货方企业类型 01:企业 02:机关执业单位 03:个人 04:其他
+		CustTaxNo string    `json:"custTaxNo"` //纳税人税号
+		Phone     string    `json:"phone"`     //手机号
+		BillDate  string    `json:"billDate"`  //单据日期  格式:yyyy-MM-dd HH:mm:ss
+		CustName  string    `json:"custName"`  //购方名称
+		Orders    []*orders `json:"orders"`    //发票内容
+	}
+
+	orders struct {
+		BillNo string   `json:"billNo"` //订单号
+		Items  []*items `json:"items"`
+	}
+
+	items struct {
+		Name        string `json:"name"`        //商品名称
+		Code        string `json:"code"`        //商品编号(税收分类编码)
+		Yhzcbs      string `json:"yhzcbs"`      //享受税收优惠政策内容
+		LineType    string `json:"lineType"`    //发票行性质 0:正常行1:折扣行2:被折扣行
+		TaxRate     string `json:"taxRate"`     //税率
+		TaxPrice    string `json:"taxPrice"`    //单价
+		TotalAmount string `json:"totalAmount"` //含税金额
+		Quantity    string `json:"quantity"`    //数量
+	}
+
+	addInvoiceAddResp struct {
+		Code int               `json:"code"` //0 开票成功;2 开票中 ;其他开票失败
+		Msg  interface{}       `json:"msg,omitempty"`
+		Data addInvoiceAddData `json:"data,omitempty"` //异步开票,通过回调通知
+	}
+	addInvoiceAddData struct {
+		Swno string `json:"swno"` //流水号  invoice_serialnum
+		Fpdm string `json:"fpdm"` //发票代码  invoice_code
+		Fphm string `json:"fphm"` //发票号码  invoice_number
+		Path string `json:"path"` //pdf地址  url
+	}
+)
 
 // InvoiceAdd 开票
 func InvoiceAdd(r *ghttp.Request) {
+	var param *addInvoiceAddParam
+	err := func() error {
+		err := gconv.Struct(r.GetBody(), param)
+		if err != nil {
+			return gerror.Wrap(err, "获取参数异常")
+		}
+		// 存入开票记录表
 
+		// 调用第三方开票接口
+		if err := tripartite.MakeSingleInvoice(tripartite.MakeInvoiceData{
+			Type:      "2",
+			Gmfmc:     param.CustName,
+			Gmfnsrsbh: param.CustTaxNo,
+			Id:        param.OrderCode,
+			//Gmfdz:     "北京市朝阳区安定路5号院13号楼B座12层1201室",
+			Lxdh: param.Phone,
+			//Yhyywdmc:  "郑州交通银行总行",
+			//Yhzh:      "6320123123000121",
+			InvoiceArr: []tripartite.MakeInvoiceItems{{
+				Xmmc:     "0fccdac71c36a8552ba662e7a2f42726",
+				WhStatus: 1,
+				Je:       param.Orders[0].Items[0].TaxPrice,
+				Sl:       "1",
+			}},
+		}); err != nil {
+			return gerror.Wrapf(err, "调用开票接口异常%v", err)
+		}
+		return nil
+	}()
+	if err != nil {
+		g.Log().Errorf(r.Context(), "处理开票业务异常")
+		r.Response.Write(addInvoiceAddResp{
+			Code: -1,
+			Msg:  err.Error(),
+		})
+		return
+	}
+	r.Response.Write(addInvoiceAddResp{
+		Code: 0,
+		Msg:  "开票中",
+	})
 }

+ 68 - 0
internal/service/invoiceCallback.go

@@ -0,0 +1,68 @@
+package service
+
+import (
+	"ElectronicInvoice/util"
+	"encoding/base64"
+	"fmt"
+	"github.com/gogf/gf/v2/errors/gerror"
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/gogf/gf/v2/net/ghttp"
+	"github.com/gogf/gf/v2/os/gfile"
+	"net/url"
+	"time"
+)
+
+// InvoicingCallBackLogic 开票回调逻辑
+func InvoicingCallBackLogic(r *ghttp.Request) error {
+	tType := r.Get("type").Int() //type [0 需要活体检测;1 成功 返回base64]
+	switch tType {
+	case 0: //需要活体检测
+		imgVal, err := url.QueryUnescape(r.Get("img").String())
+		if err != nil {
+			return gerror.Wrap(err, "活体检测二维码解析失败")
+		}
+		if err := util.SendQrImage2ChatBot(imgVal); err != nil {
+			return gerror.Wrap(err, "发送活体检测消息出错")
+		}
+	case 1: //开票成功
+		pdfBase64 := r.Get("pdf").String()
+		orderCode := r.Get("id").String()
+		data, err := base64.StdEncoding.DecodeString(pdfBase64)
+		if err != nil {
+			return gerror.Wrap(err, "解析文件base64编码失败")
+		}
+		var (
+			rootDir      = g.Cfg().MustGet(r.Context(), "pdfFilePathRootDir", "/out").String()
+			pathPrefix   = g.Cfg().MustGet(r.Context(), "pdfFilePathPrefix", "/invoice").String()
+			now          = time.Now()
+			requestPath  = fmt.Sprintf("/%s/%s/file_%d.pdf", pathPrefix, now.Format("2006-01-02"), now.Unix())
+			fileFullPath = fmt.Sprintf("%s%s", rootDir, requestPath)
+		)
+		pdfFile, err := gfile.Create(fileFullPath)
+		if err != nil {
+			return gerror.Wrap(err, "创建pdf文件异常")
+		}
+		if _, err = pdfFile.Write(data); err != nil {
+			return gerror.Wrap(err, "pdf文件写入异常")
+		}
+		g.Log().Infof(r.Context(), "pdf保存成功 orderCode:%s filePath:%s ", orderCode, fileFullPath)
+		JyPayNotice()
+		return nil
+	case 3:
+		g.Log().Error(r.Context(), "活体验证已过期,未完成活体验证")
+	case 4:
+		g.Log().Error(r.Context(), "系统错误")
+	case 6:
+		g.Log().Error(r.Context(), "税率不存在")
+	case 7:
+		g.Log().Error(r.Context(), "非数电票试点纳税人,未核定数电票票种,不允许开票或其他原因")
+	default:
+		g.Log().Infof(r.Context(), "InvoicingCallBackLogic tType:%s", tType)
+	}
+	return nil
+}
+
+// makeInvoiceSuccess  开票成功
+func makeInvoiceSuccess() error {
+	return nil
+}

+ 6 - 0
internal/service/invoiceNotice.go

@@ -0,0 +1,6 @@
+package service
+
+// JyPayNotice 发送开发票结果给支付程序
+func JyPayNotice() {
+
+}

+ 1 - 1
internal/service/callback.go → internal/service/tripartite/callback.go

@@ -1,4 +1,4 @@
-package service
+package tripartite
 
 import (
 	"context"

+ 1 - 1
internal/service/common.go → internal/service/tripartite/common.go

@@ -1,4 +1,4 @@
-package service
+package tripartite
 
 import (
 	"ElectronicInvoice/internal/consts"

+ 14 - 26
internal/service/invoice.go → internal/service/tripartite/invoice.go

@@ -1,4 +1,4 @@
-package service
+package tripartite
 
 import (
 	"context"
@@ -11,10 +11,10 @@ type (
 	makeInvoiceAllParam struct {
 		TaxNum string            `json:"taxNum"` //企业税号*
 		Tel    string            `json:"tel"`    //登录电子税局手机号或身份证号*
-		Data   []makeInvoiceData `json:"data"`
+		Data   []MakeInvoiceData `json:"data"`
 	}
 
-	makeInvoiceData struct {
+	MakeInvoiceData struct {
 		Type       string             `json:"type"`      //票类* 1 增值税专用发票;2 普通发票
 		Gmfmc      string             `json:"gmfmc"`     //购买方名称*
 		Gmfnsrsbh  string             `json:"gmfnsrsbh"` //购买方纳税人识别号*
@@ -23,9 +23,10 @@ type (
 		Lxdh       string             `json:"lxdh"`      //购买方联系方式
 		Yhyywdmc   string             `json:"yhyywdmc"`  //购买方开户行
 		Yhzh       string             `json:"yhzh"`      //购买方银行账号
-		InvoiceArr []makeInvoiceItems `json:"invoiceArr"`
+		Notes      string             `json:"notes"`     //发票备注
+		InvoiceArr []MakeInvoiceItems `json:"invoiceArr"`
 	}
-	makeInvoiceItems struct {
+	MakeInvoiceItems struct {
 		Xmmc     string `json:"xmmc"`      //项目名称*
 		Je       string `json:"je"`        //开票金额*
 		WhStatus int    `json:"wh_status"` //该开票项是否已调用接口进行维护: 1 已维护;0 未维护
@@ -33,35 +34,22 @@ type (
 		Dw       string `json:"dw"`        //单位
 		Sl       string `json:"sl"`        //数量
 		Tsaxrate string `json:"taxrate"`   //税率
-
 	}
 )
 
-func MakeInvoice() (err error) {
+// MakeSingleInvoice 开单张发票
+func MakeSingleInvoice(param MakeInvoiceData) (err error) {
+	return MakeInvoices([]MakeInvoiceData{param})
+}
+
+// MakeInvoices 开多张发票
+func MakeInvoices(invoices []MakeInvoiceData) (err error) {
 	var (
 		ctx   = context.Background()
 		param = makeInvoiceAllParam{
 			TaxNum: g.Cfg().MustGet(ctx, "company.taxNum").String(),
 			Tel:    g.Cfg().MustGet(ctx, "company.tel").String(),
-			Data: []makeInvoiceData{{
-				Type:      "2",
-				Gmfmc:     "北京拓普丰联信息科技股份有限公司",
-				Gmfnsrsbh: "91110105756025873C",
-				Id:        "123321",
-				Gmfdz:     "北京市朝阳区安定路5号院13号楼B座12层1201室",
-				Lxdh:      "010-58772571",
-				Yhyywdmc:  "郑州交通银行总行",
-				Yhzh:      "6320123123000121",
-				InvoiceArr: []makeInvoiceItems{{
-					Xmmc:     "0fccdac71c36a8552ba662e7a2f42726",
-					WhStatus: 1,
-					Je:       "2",
-					//Xhgg:     "",
-					//Dw:       "",
-					//Sl:       "1",
-					//Tsaxrate: "6",
-				}},
-			}},
+			Data:   invoices,
 		}
 	)
 	err = CommonDoPost("/index_index/makeInvoiceC",

+ 1 - 1
internal/service/login.go → internal/service/tripartite/login.go

@@ -1,4 +1,4 @@
-package service
+package tripartite
 
 import (
 	"context"

+ 1 - 1
internal/service/taxCode.go → internal/service/tripartite/taxCode.go

@@ -1,4 +1,4 @@
-package service
+package tripartite
 
 import (
 	"context"

+ 1 - 1
internal/service/token.go → internal/service/tripartite/token.go

@@ -1,4 +1,4 @@
-package service
+package tripartite
 
 import (
 	"context"

+ 21 - 6
run_test.go

@@ -1,7 +1,7 @@
 package main
 
 import (
-	"ElectronicInvoice/internal/service"
+	"ElectronicInvoice/internal/service/tripartite"
 	"context"
 	"fmt"
 	"github.com/gogf/gf/v2/frame/g"
@@ -25,19 +25,34 @@ func Test_Config(t *testing.T) {
 
 // Test_MakeInvoice 测试开发票
 func Test_MakeInvoice(t *testing.T) {
-	service.MakeInvoice()
+	tripartite.MakeInvoices([]tripartite.MakeInvoiceData{{
+		Type:      "2",
+		Gmfmc:     "北京拓普丰联信息科技股份有限公司",
+		Gmfnsrsbh: "91110105756025873C",
+		Id:        "123321",
+		Gmfdz:     "北京市朝阳区安定路5号院13号楼B座12层1201室",
+		Lxdh:      "010-58772571",
+		Yhyywdmc:  "郑州交通银行总行",
+		Yhzh:      "6320123123000121",
+		InvoiceArr: []tripartite.MakeInvoiceItems{{
+			Xmmc:     "0fccdac71c36a8552ba662e7a2f42726",
+			WhStatus: 1,
+			Je:       "2",
+			Sl:       "1",
+		}},
+	}})
 }
 
 // Test_LoginDemo 登录
 func Test_LoginDemo(t *testing.T) {
 	//登录
-	err := service.Login()
+	err := tripartite.Login()
 	if err != nil {
 		panic(err)
 	}
 	return
 	//2.验证登录
-	service.VerifyLogin()
+	tripartite.VerifyLogin()
 }
 
 // Test_TaxCode 开票项
@@ -56,13 +71,13 @@ func Test_TaxCode(t *testing.T) {
 	//	panic(err)
 	//}
 
-	list, err := service.GetSuccessTaxCodeList()
+	list, err := tripartite.GetSuccessTaxCodeList()
 	if err != nil {
 		panic(err)
 	}
 	g.Dump(list)
 	return
-	err = service.AddTaxCode([]service.Billitem{{
+	err = tripartite.AddTaxCode([]tripartite.Billitem{{
 		Name:    "信息系统增值服务",
 		Ssflbm:  "3040205000000000000",
 		Thirdid: "6f2e6a7a-18a7-4f21-b52e-a47437f817cc",

+ 1 - 1
internal/service/qr.go → util/qywx.go

@@ -1,4 +1,4 @@
-package service
+package util
 
 import (
 	"context"