You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

438 lines
13 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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(&notBillData, "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)
}