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

4 years ago
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\":\"\","
3 years ago
order = order + "\"detail\":[{\"goodsname\":\"瑞库客购物 \","
4 years ago
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)
}