Browse Source

wip:提交模拟开票程序

wangkaiyue 1 year ago
parent
commit
abaf426f8b

+ 14 - 0
docs/mockService/config.yaml

@@ -0,0 +1,14 @@
+server:
+  address: ":4041"
+  dumpRouterMap: false # 是否在Server启动时打印所有的路由列表。默认为true
+  graceful: true # 是否开启平滑重启特性,开启时将会在本地增加10000的本地TCP端口用于进程间通信。默认false
+  gracefulTimeout: 10 # 平滑重启父进程最大存活时间。默认2秒
+
+logger:
+  level: "all"
+  path: "logs" # 日志文件路径。默认为空,表示关闭,仅输出到终端
+  file: "{Y-m-d}.log" # 日志文件格式。默认为"{Y-m-d}.log"
+
+ #回调地址接口
+callBackAction: "https://www.jianyu360.cn/Invoice/callback"
+

+ 195 - 0
docs/mockService/main.go

@@ -0,0 +1,195 @@
+package main
+
+import (
+	"ElectronicInvoice/util"
+	"context"
+	"encoding/json"
+	"fmt"
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/gogf/gf/v2/net/ghttp"
+	"github.com/gogf/gf/v2/util/gconv"
+	"github.com/gogf/gf/v2/util/grand"
+	"github.com/gogf/gf/v2/util/guid"
+	"time"
+)
+
+type (
+	// 开发票
+	makeInvoiceAllParam struct {
+		TaxNum string            `json:"taxNum"` //企业税号*
+		Tel    string            `json:"tel"`    //登录电子税局手机号或身份证号*
+		Data   []MakeInvoiceData `json:"data"`
+	}
+
+	MakeInvoiceData struct {
+		Type       string             `json:"type"`      //票类* 1 增值税专用发票;2 普通发票
+		Gmfmc      string             `json:"gmfmc"`     //购买方名称* 人名
+		Gmfnsrsbh  string             `json:"gmfnsrsbh"` //购买方纳税人识别号* 身份证号
+		Id         string             `json:"id"`        //发票流水号* 合作商开具的发票流水号,涉及到回调通知
+		Gmfdz      string             `json:"gmfdz"`     //购买方地址
+		Lxdh       string             `json:"lxdh"`      //购买方联系方式
+		Yhyywdmc   string             `json:"yhyywdmc"`  //购买方开户行
+		Yhzh       string             `json:"yhzh"`      //购买方银行账号
+		Fhr        string             `json:"fhr"`       //复核人
+		Notes      string             `json:"notes"`     //发票备注
+		InvoiceArr []MakeInvoiceItems `json:"invoiceArr"`
+	}
+
+	MakeInvoiceItems struct {
+		Xmmc     string `json:"xmmc"`      //项目名称*
+		Je       string `json:"je"`        //开票金额*
+		WhStatus int    `json:"wh_status"` //该开票项是否已调用接口进行维护: 1 已维护;0 未维护
+		Xhgg     string `json:"xhgg"`      //型号规格
+		Dw       string `json:"dw"`        //单位
+		Sl       string `json:"sl"`        //数量
+		Tsaxrate string `json:"taxrate"`   //税率
+	}
+
+	//红冲
+	makeRedInvoiceAllParam struct {
+		TaxNum string               `json:"taxNum"` //企业税号*
+		Tel    string               `json:"tel"`    //登录电子税局手机号或身份证号*
+		Data   []MakeRedInvoiceData `json:"data"`
+	}
+
+	MakeRedInvoiceData struct {
+		Num  string `json:"num"`  //蓝票号码
+		Date string `json:"date"` //购买方名称* 人名
+	}
+
+	CommonRes struct {
+		Code int         `json:"code"`
+		Msg  string      `json:"msg"`
+		Data interface{} `json:"data"`
+	}
+)
+
+func main() {
+	s := g.Server()
+	s.Group("/", func(group *ghttp.RouterGroup) {
+		group.POST("/authority_token/getToken", getToken) //获取token
+		group.Group("/index_index", func(group2 *ghttp.RouterGroup) {
+			group2.POST("/makeInvoiceC", makeInvoiceC) //开票
+			group2.POST("/makeRedC", makeRedC)         //红票
+		})
+	})
+	s.Run()
+}
+
+var (
+	getToken = func(r *ghttp.Request) {
+		resp := struct {
+			Token     string `json:"token"`
+			ExpiresIn int    `json:"expiresIn"` //一天有效期
+		}{
+			Token:     "mockToken",
+			ExpiresIn: 60 * 60 * 24,
+		}
+		r.Response.Write(resp)
+	}
+
+	makeInvoiceC = func(r *ghttp.Request) {
+		var (
+			ctx   = r.Context()
+			param = makeInvoiceAllParam{}
+		)
+
+		err := json.Unmarshal(r.GetBody(), &param)
+		if err != nil {
+			g.Log().Errorf(ctx, "开票任务-接收参数异常 err:%v", err)
+			return
+		}
+		g.Log().Infof(ctx, "开票任务-接收到开票信息:%s", gconv.String(param))
+		time.Sleep(time.Second * time.Duration(grand.Intn(3))) //模拟处理
+		go func() {
+			callBackParam := g.Map{
+				"calltype": "Invoicing",
+				"pdf":      util.GetPdfBase64(fmt.Sprintf("./pdfDir/invoice_Blue_%s.pdf", param.Data[0].Type)), //pdf文件
+				"num":      fmt.Sprintf("MOCKBLUE_%s", guid.S()),
+				"id":       param.Data[0].Id,
+				"kptime":   time.Now().Format("2006-01-02 15:04:05"),
+			}
+			//TODO 回调开票成功
+			for {
+				if checkCallBackOk(ctx, callBackParam) {
+					g.Log().Infof(ctx, "开票任务-开票成功")
+					break
+				}
+				time.Sleep(time.Second * 3)
+			}
+
+			//TODO 任务完成通知
+			for {
+				if checkCallBackOk(ctx, g.Map{"calltype": "quit", "data": g.Map{"taskType": "2"}}) {
+					g.Log().Infof(ctx, "开票任务-通知完成")
+					break
+				}
+				time.Sleep(time.Second * 3)
+			}
+		}()
+		r.Response.WriteJson(CommonRes{
+			Code: 200,
+			Msg:  "",
+		})
+	}
+
+	makeRedC = func(r *ghttp.Request) {
+		var (
+			ctx   = r.Context()
+			param = makeRedInvoiceAllParam{}
+		)
+
+		err := json.Unmarshal(r.GetBody(), &param)
+		if err != nil {
+			g.Log().Errorf(ctx, "红冲任务-接收参数异常 err:%v", err)
+			return
+		}
+		g.Log().Infof(ctx, "红冲任务-接收到红冲信息:%s", gconv.String(param))
+		time.Sleep(time.Second * time.Duration(grand.Intn(3))) //模拟处理
+		go func() {
+			callBackParam := g.Map{
+				"calltype":  "offset",
+				"pdf":       util.GetPdfBase64("./pdfDir/invoice_Red.pdf"), //pdf文件
+				"num":       param.Data[0].Num,
+				"offsetNum": fmt.Sprintf("MOCKRED_%s", guid.S()),
+				"kptime":    time.Now().Format("2006-01-02 15:04:05"),
+			}
+
+			//TODO 回调红冲成功
+			for {
+				if checkCallBackOk(ctx, callBackParam) {
+					g.Log().Infof(ctx, "红冲任务-红冲成功")
+					break
+				}
+				time.Sleep(time.Second * 3)
+			}
+
+			//TODO 任务完成通知
+			for {
+				if checkCallBackOk(ctx, g.Map{"calltype": "quit", "data": g.Map{"taskType": "9"}}) {
+					g.Log().Infof(ctx, "红冲任务-通知完成")
+					break
+				}
+				time.Sleep(time.Second * 3)
+			}
+		}()
+		r.Response.WriteJson(CommonRes{
+			Code: 200,
+			Msg:  "",
+		})
+	}
+)
+
+func checkCallBackOk(ctx context.Context, param map[string]interface{}) bool {
+	res, err := g.Client().Header(g.MapStrStr{"Content-Type": "application/x-www-form-urlencoded"}).Post(ctx, g.Cfg().MustGet(ctx, "callBackAction").String(), param)
+	if err != nil {
+		g.Log().Errorf(ctx, "模拟请求异常 %v", err)
+		return false
+	}
+	defer res.Close()
+	rData := gconv.MapStrStr(res.ReadAll())
+	if rData["code"] == "200" {
+		return true
+	}
+	return false
+}

BIN
docs/mockService/pdfDir/invoice_Blue_1.pdf


BIN
docs/mockService/pdfDir/invoice_Blue_2.pdf


BIN
docs/mockService/pdfDir/invoice_Red.pdf


+ 1 - 1
internal/service/tripartiteInvoice.go

@@ -47,7 +47,7 @@ type (
 	}
 
 	MakeRedInvoiceData struct {
-		Num  string `json:"num"`  //票类* 1 增值税专用发票;2 普通发票
+		Num  string `json:"num"`  //蓝票号码
 		Date string `json:"date"` //购买方名称* 人名
 	}
 )

+ 8 - 0
util/pdf.go

@@ -34,3 +34,11 @@ func SavePdfFile(ctx context.Context, num, pdfBase64 string) (filePath string, e
 	}
 	return fmt.Sprintf("%s%s", webDoMain, requestPath), nil
 }
+
+func GetPdfBase64(filePath string) (base64Str string, err error) {
+	fileBytes := gfile.GetBytes(filePath)
+	if len(fileBytes) == 0 {
+		return "", gerror.New("文件内容为空")
+	}
+	return base64.StdEncoding.EncodeToString(fileBytes), nil
+}