package bill import ( "bytes" "crypto/cipher" "crypto/des" "crypto/md5" "encoding/base64" "encoding/json" "fmt" "github.com/gin-gonic/gin" "github.com/golangkit/formatime" "github.com/shopspring/decimal" "io/ioutil" "net/http" "recook/internal/back" "recook/internal/dbc" order1 "recook/internal/model/order" "recook/tools" "strconv" "strings" "time" ) var ( //加密字符串 key64 = "LmMGStGtOpF4xNyvYt54EQ==" //身份标致 identity = "9D9F9F13858908468CD41D4C5483AE2E00D1ACFF51C27DF1" //正式 //identity="2329CC5F90EDAA8208F1F3C72A0CE72A713A9D425CD50CDE"//测试 //开票url sendUrl = "https://nnfpbox.nuonuocs.cn/shop/buyer/allow/cxfKp/cxfServerKpOrderSync.action" //测试 //sendUrl = "https://nnfp.jss.com.cn/shop/buyer/allow/cxfKp/cxfServerKpOrderSync.action" //正式 //根据流水查询开票状态 getUrl = "https://nnfpbox.nuonuocs.cn/shop/buyer/allow/ecOd/queryElectricKp.action" //测试 //getUrl = "https://nnfp.jss.com.cn/shop/buyer/allow/ecOd/queryElectricKp.action" //正式 ) type actionToBillPem struct { GoodsDetailId []uint `json:"goodsDetailId"` //订单id,数组类型 Buyername string `json:"buyername"` //抬头名称 Taxnum string `json:"taxnum"` //购方税号 Address string `json:"address"` //公司地址 Telephone string `json:"telephone"` //公司电话 Phone string `json:"phone"` //购方手机 Email string `json:"email"` //推送邮箱 Account string `json:"account"` //银行账号 Message string `json:"message"` //备注 } type actionToBillResult struct { Status string `json:"status"` Message string `json:"message"` Fpqqlsh string `json:"fpqqlsh"` } func ActionToBill(c *gin.Context) { //http.Fail(c, "开票系统正在维护中") //return var p actionToBillPem err := tools.ParseParams(&p, c) if err != nil { back.Fail(c, err.Error()) return } //赋值测试效果 //p.Buyername = "阿库网络" //p.Taxnum = "312313131" //p.Address = "我的地址" //p.Telephone = "0922-28228822" //p.Phone = "18758321769" //p.Email = "709286540@qq.com" //p.Account = "42332453423142532413124343453424" //p.Message = "测试备注" //p.GoodsDetailId = []uint{865} if len(p.GoodsDetailId) <= 0 { back.Fail(c, "必须传订单明细ID") return } type PriceAndUid struct { Price decimal.Decimal `gorm:"column:price;json:"price"` UserId uint `gorm:"column:user_id;json:"userId"` } var mypriceUid PriceAndUid //从这里去开发票的金额为actual_amount+coin_amount dbc.DB.Select("sum(actual_amount+coin_amount) AS price,user_id").Model(&order1.GoodsDetail{}).Where("id in (?)", p.GoodsDetailId).Scan(&mypriceUid) //fmt.Println(mypriceUid) order := " {\"identity\":\"" + identity + "\",\"order\":" order = order + "{\"buyername\":\"" + p.Buyername + "\"," order = order + "\"" + p.Taxnum + "\":\"\"," order = order + "\"phone\":\"" + p.Phone + "\"," order = order + "\"address\":\"" + p.Address + "\"," order = order + "\"account\":\"" + p.Account + "\"," order = order + "\"telephone\":\"" + p.Telephone + "\"," //用第一个产品的id作为订单id order = order + "\"orderno\":\"0000" + strconv.Itoa(int(p.GoodsDetailId[0])) + "\"," order = order + "\"invoicedate\":\"" + time.Now().Format("2006-01-02 15:04:06") + "\"," order = order + "\"clerk\":\"张三\"," //开票员 后期要修改 order = order + "\"saleaccount\":\"94170078801500000106\"," order = order + "\"salephone\":\"\"," order = order + "\"saleaddress\":\"\"," order = order + "\"saletaxnum\":\"91330212MA2AE2QQXR\"," //销方税号,后期要修改 order = order + "\"kptype\":\"1\"," order = order + "\"message\":\"" + p.Message + "\"," order = order + "\"payee\":\"\"," order = order + "\"checker\":\"\"," order = order + "\"tsfs\":\"2\"," //推送方式,手机+邮箱 order = order + "\"email\":\"" + p.Email + "\"," order = order + "\"qdbz\":\"0\"," order = order + "\"qdxmmc\":\"\"," order = order + "\"dkbz\":\"0\"," order = order + "\"deptid\":\"\"," order = order + "\"clerkid\":\"\"," order = order + "\"invoiceLine\":\"p\"," order = order + "\"cpybz\":\"\"," order = order + "\"detail\":[{\"goodsname\":\"瑞库客购物 \"," order = order + "\"num\":\"1\"," order = order + "\"price\":\"" + mypriceUid.Price.String() + "\"," order = order + "\"hsbz\":\"1\"," order = order + "\"taxrate\":\"0.13\"," order = order + "\"spec\":\"\"," order = order + "\"unit\":\"\"," order = order + "\"spbm\":\"\"," //免责协议 order = order + "\"zsbm\":\"\"," order = order + "\"fphxz\":\"0\"," order = order + "\"yhzcbs\":\"0\"," order = order + "\"zzstsgl\":\"\"," order = order + "\"lslbs\":\"\"," order = order + "\"kce\":\"\"}]}}" order = encrypt(order) resp, err := http.Post(sendUrl, "application/x-www-form-urlencoded;charset=UTF-8", strings.NewReader("order="+order)) if err != nil { fmt.Println(err) } body, err := ioutil.ReadAll(resp.Body) resp.Body.Close() if err != nil { fmt.Println(err) } fmt.Println(string(body)) var actionToBillResultData actionToBillResult json.Unmarshal(body, &actionToBillResultData) if actionToBillResultData.Status == "0000" { //創建成功 //將這些訂單標記為已創建1处理中,并将流水号储存到数据中 dbc.DB.Model(order1.GoodsDetail{}).Where("id in (?)", p.GoodsDetailId).Updates(order1.GoodsDetail{Bill: 1, Fpqqlsh: actionToBillResultData.Fpqqlsh}) //这边将发票信息存储在数据库 billData := order1.Bill{ UID: mypriceUid.UserId, Fpqqlsh: actionToBillResultData.Fpqqlsh, Status: 20, Buyername: p.Buyername, Taxnum: p.Taxnum, Address: p.Address, Telephone: p.Telephone, Phone: p.Phone, Email: p.Email, Account: p.Account, Content: "平台消费", Message: p.Message, Ctime: formatime.NewSecondNow(), Price: mypriceUid.Price, Fail: "", } dbc.DB.Create(&billData) back.Suc(c, "", &actionToBillResultData) } else { back.Fail(c, actionToBillResultData.Message) } return /* { "code": "SUCCESS", "data": { "code": "FAIL", "msg": "订单编号或流水号不能重复" } } */ } type billGetData struct { Result string `json:"result"` List []struct { TerminalNumber interface{} `json:"terminalNumber"` CHjje float64 `json:"c_hjje"` CAddress string `json:"c_address"` CTelephone string `json:"c_telephone"` CMail string `json:"c_mail"` CYfpdm string `json:"c_yfpdm"` CBuyername string `json:"c_buyername"` CPayee string `json:"c_payee"` CTaxnum string `json:"c_taxnum"` CPhone string `json:"c_phone"` CYfphm string `json:"c_yfphm"` CSalerTel string `json:"c_salerTel"` CRemark string `json:"c_remark"` CipherText string `json:"cipherText"` QrCode string `json:"qrCode"` CInvoiceLine string `json:"c_invoice_line"` CResultmsg string `json:"c_resultmsg"` COfdURL string `json:"c_ofd_url"` CQdbz int `json:"c_qdbz"` CSalerAccount string `json:"c_salerAccount"` CStatus string `json:"c_status"` CKprq int64 `json:"c_kprq"` CChecker string `json:"c_checker"` COrderno string `json:"c_orderno"` CSaleName string `json:"c_saleName"` CSalerTaxNum string `json:"c_salerTaxNum"` CImgUrls string `json:"c_imgUrls"` MachineCode string `json:"machineCode"` CJpgURL string `json:"c_jpg_url"` CInvoiceid string `json:"c_invoiceid"` CHjse float64 `json:"c_hjse"` CClerkID string `json:"c_clerkId"` CQdxmmc string `json:"c_qdxmmc"` CSalerAddress string `json:"c_salerAddress"` CheckCode string `json:"checkCode"` CDeptID string `json:"c_deptId"` CFphm string `json:"c_fphm"` CClerk string `json:"c_clerk"` CURL string `json:"c_url"` CFpqqlsh string `json:"c_fpqqlsh"` CFpdm string `json:"c_fpdm"` ProductOilFlag string `json:"productOilFlag"` ExtensionNumber interface{} `json:"extensionNumber"` CBhsje float64 `json:"c_bhsje"` CMsg string `json:"c_msg"` CBankAccount string `json:"c_bankAccount"` CJym string `json:"c_jym"` } `json:"list"` } //这里到时候改成10分钟运行一次 func ActionGetBillTask() { for { select { case <-time.After(10 * time.Minute): ActionGetBill() } } } //根据流水号获取开票状态,这个用定时去跑 func ActionGetBill() { //这里查询状态不为2的流水记录 var notBillData []order1.Bill dbc.DB.Find(¬BillData, "status=20 OR status=21") fpqqlsh := "" for _, item := range notBillData { if len(fpqqlsh) > 0 { fpqqlsh = fpqqlsh + "," + item.Fpqqlsh } else { fpqqlsh = fpqqlsh + item.Fpqqlsh } } if len(fpqqlsh) == 0 { return } order := " {\"identity\":\"" + identity + "\"," order = order + "\"fpqqlsh\":[" + fpqqlsh + "]}" fmt.Println(order) order = encrypt(order) resp, err := http.Post(getUrl, "application/x-www-form-urlencoded;charset=UTF-8", strings.NewReader("order="+order)) if err != nil { fmt.Println(err) } body, err := ioutil.ReadAll(resp.Body) resp.Body.Close() if err != nil { fmt.Println(err) } var billData billGetData json.Unmarshal(body, &billData) fmt.Println(string(body)) fmt.Println(billData) //这里要循环返回结果并处理数据 for _, billDataOne := range billData.List { tempStatus, _ := strconv.Atoi(billDataOne.CStatus) if tempStatus != 2 { dbc.DB.Model(order1.Bill{}).Where("fpqqlsh=?", billDataOne.CFpqqlsh).Update(order1.Bill{Status: tempStatus, Fail: billDataOne.CResultmsg}) } else { dbc.DB.Model(order1.Bill{}).Where("fpqqlsh=?", billDataOne.CFpqqlsh).Update(order1.Bill{Status: tempStatus}) } } } func encrypt(content string) string { key, err := base64.StdEncoding.DecodeString(key64) if err != nil { return "" } sum := md5.Sum([]byte(content)) sourceBuf := bytes.Join([][]byte{sum[:], []byte(content)}, []byte("")) p, err := DesCBCEncrypt(sourceBuf, key) if err != nil { return "" } return base64.StdEncoding.EncodeToString(p) } func DesCBCEncrypt(origData, key []byte) ([]byte, error) { desKey := key[:8] iv := key[8:] block, err := des.NewCipher(desKey) if err != nil { return nil, err } origData = PKCS5Padding(origData, block.BlockSize()) blockMode := cipher.NewCBCEncrypter(block, iv) crypted := make([]byte, len(origData)) blockMode.CryptBlocks(crypted, origData) return crypted, nil } func PKCS5Padding(ciphertext []byte, blockSize int) []byte { padding := blockSize - len(ciphertext)%blockSize padtext := bytes.Repeat([]byte{byte(padding)}, padding) return append(ciphertext, padtext...) } type addLetterheadPem struct { ID uint `json:"id"` // UID 用户id UID uint `json:"uid"` // Type 1公司 2个人 Type uint `json:"type"` // Name 名称 Name string `json:"name"` // Taxnum 税号 Taxnum string `json:"taxnum"` // Address 地址 Address string `json:"address"` // Phone 电话 Phone string `json:"phone"` // Bank 银行账号 Bank string `json:"bank"` // Default 1默认 Default int `json:"default"` } //增加抬头 func AddLetterhead(c *gin.Context) { var p addLetterheadPem err := tools.ParseParams(&p, c) if err != nil { back.Fail(c, err.Error()) return } if p.Default == 1 { dbc.DB.Table("recook_user_letterhead").Where("uid=?", p.UID).Updates(map[string]interface{}{"default": "0"}) } letterheadData := order1.Letterhead{} letterheadData.UID = p.UID letterheadData.Type = p.Type letterheadData.Name = p.Name letterheadData.Taxnum = p.Taxnum letterheadData.Address = p.Address letterheadData.Phone = p.Phone letterheadData.Bank = p.Bank letterheadData.Default = p.Default if p.ID > 0 { dbc.DB.Table("recook_user_letterhead").Where("id=?", p.ID).Updates(map[string]interface{}{ "uid": letterheadData.UID, "type": letterheadData.Type, "name": letterheadData.Name, "taxnum": letterheadData.Taxnum, "address": letterheadData.Address, "phone": letterheadData.Phone, "bank": letterheadData.Bank, "default": letterheadData.Default, }) } else { dbc.DB.Create(&letterheadData) } back.Suc(c, "", nil) } type LetterheadListPem struct { Uid uint `json:"uid"` } type LetterheadOnePem struct { ID uint `json:"id"` } //获取抬头列表 func LetterheadList(c *gin.Context) { var p LetterheadListPem err := tools.ParseParams(&p, c) if err != nil { //http.Fail(c, err.Error()) //return } var letterheadData []order1.Letterhead dbc.DB.Find(&letterheadData, "uid=?", p.Uid) back.Suc(c, "", &letterheadData) } //获取单个抬头 func LetterheadOne(c *gin.Context) { var p LetterheadOnePem err := tools.ParseParams(&p, c) if err != nil { back.Fail(c, err.Error()) return } var letterheadData order1.Letterhead dbc.DB.Find(&letterheadData, "id=?", p.ID) back.Suc(c, "", &letterheadData) }