GRD支付宝,就不能不用zip来打包吗!!!!!
支付宝的对账单下载并不复杂,但他特么的就是不告诉你用GET还是用POST发送,发错了还给你甩一堆HTML过来,还都是乱码,唉卧槽他大爷坑了我2天时间。
下载及处理zip如下:
package controllers
import (
"github.com/astaxie/beego"
"time"
"monkeyServer/shopUtils/timeUtils"
"fmt"
"net/http"
"io/IoUtil"
"net/url"
"encoding/json"
"monkeyServer/shopUtils/logUtils"
"os"
"archive/zip"
"strings"
"io"
)
type AdminAliBillsController struct {
beego.Controller
}
func (c *AdminAliBillsController) Post() {
c.EnableRender = false
//checkLogin.CheckAdminLogin(c.Ctx)
date := c.GetString("alDate","")
date = "2017-07-08"
if len(date) != 10 || date == "" {
c.Ctx.WriteString("日期参数长度错误")
}
m := make(map[string]interface{})
m["app_id"] = ALI_APP_ID
m["method"] = "alipay.data.dataservice.bill.downloadurl.query"
m["charset"] = "utf-8"
m["sign_type"] = "RSA"
m["timestamp"] = time.Now().Format(timeUtils.TIMELAYOUT)
m["version"] = "1.0"
//bill_type:trade指商户基于支付宝交易收单的业务账单;signcustomer是指基于商户支付宝余额收入及支出等资金变动的帐务账单
m["biz_content"] = `{"bill_type":"trade","bill_date":"` + date + `"}`
sign := aliPaySign(m)
//签名
encodStr := ""
for k,_ := range m {
//所有一级value(biz_content作为一个value)进行encode
value := fmt.Sprintf("%v",m[k])
encodStr = encodStr + k + "=" + url.QueryEscape(value) + "&"
//encodStr = encodStr + k + "=" + value + "&"
}
encodStr = encodStr + "sign=" + url.QueryEscape(sign)
//beego.Error("组合的请求 ",encodStr)
resp,err := http.Get("https://openapi.alipay.com/gateway.do?" + encodStr)
if err != nil {
beego.Error("发起对账单get请求错误",err)
logUtils.GetLog().Error("发起对账单get请求错误",err)
} else {
defer resp.Body.Close()
body,err := IoUtil.ReadAll(resp.Body)
if err != nil {
beego.Error("解析对账单get返回错误",err)
logUtils.GetLog().Error("解析对账单get返回错误",err)
} else {
//result := string(body)
//beego.Error("解析对账单get返回ok ",result)
type alipay_bill_response struct {
Code string `json:"code"`
Msg string `json:"msg"`
BillDownloadUrl string `json:"bill_download_url"`
}
type aliBillResp struct {
Alipay_bill_response *alipay_bill_response `json:"alipay_data_dataservice_bill_downloadurl_query_response"`
Sign string `json:"sign"`
}
var ar aliBillResp
uerr := json.Unmarshal(body,&ar)
if uerr == nil {
fmt.Printf("%+v\n",ar.Alipay_bill_response)
if ar.Alipay_bill_response.Code == "10000" && ar.Alipay_bill_response.Msg == "Success" {
beego.Error("解析对账单下载地址为 ",ar.Alipay_bill_response.BillDownloadUrl)
//下载并保存csv.zip
saveAliBillZip(ar.Alipay_bill_response.BillDownloadUrl,date)
} else {
beego.Error("code及msg不正确",ar)
logUtils.GetLog().Error("code及msg不正确",ar)
}
} else {
beego.Error("解析对账单json转换错误",uerr)
logUtils.GetLog().Error("解析对账单json转换错误",uerr)
}
}
}
}
//下载对账zip文件 解压缩 删除文件
func saveAliBillZip(downUrl,billDate string) {
resp,err := http.Get(downUrl)
if err == nil {
defer resp.Body.Close()
body,err := IoUtil.ReadAll(resp.Body)
if err != nil {
beego.Error("解析下载ali对账zip结果错误",err)
logUtils.GetLog().Error("解析下载ali对账zip结果错误",err)
} else {
zipPath := createAlBillCSVZipFile(billDate)
err := IoUtil.WriteFile(zipPath,body,os.ModeAppend)
if err == nil {
beego.Error("zip文件写入成功")
unZipAliZip(zipPath)
} else {
beego.Error("ali zip文件写入失败",err)
logUtils.GetLog().Error("ali zip文件写入失败",err)
}
}
} else {
beego.Error("获取地址之后下载ali对账zip失败",err)
logUtils.GetLog().Error("获取地址之后下载ali对账zip失败",err)
}
}
//解压缩zip包
func unZipAliZip(zipPath string) {
rc,err := zip.OpenReader(zipPath)
defer rc.Close()
if err != nil {
beego.Error("打开ali zip文件失败",err)
logUtils.GetLog().Error("打开ali zip文件失败",err)
return
}
for _,_file := range rc.File {
//带括号的是汇总 不带括号的是明细
fmt.Println("未进行转换之前:",_file.Name,len(_file.Name),strings.Contains(_file.Name,"("))
f,err := _file.Open()
if err != nil {
beego.Error("读取alicsv文件失败",err)
logUtils.GetLog().Error("读取alicsv文件失败",err)
return
}
//把第一个下划线之前的字符全部去除 20887124614165740156_20170708_业务明细.csv
csvName:=_file.Name[strings.Index(_file.Name,"_") + 1:]
newCsvPath := "static/alicsv/" + csvName
desfile,err1 := os.OpenFile(newCsvPath,os.O_CREATE | os.O_WRONLY,os.ModePerm)
if err1 != nil {
beego.Error("创建alicsv文件失败",err1)
logUtils.GetLog().Error("创建alicsv文件失败",err1)
return
}
_,err = io.CopyN(desfile,f,int64(_file.UncompressedSize64))
if err != nil {
beego.Error("写入alicsv文件失败",err)
logUtils.GetLog().Error("写入alicsv文件失败",err)
return
}
desfile.Close()
}
//删除压缩文件
os.Remove(zipPath)
}
func createAlBillCSVZipFile(date string) string {
dirPath := "static/alicsv/"
if !IsFileExist(dirPath) {
os.MkdirAll(dirPath,0)
}
newPath := dirPath + date + ".csv.zip"
if IsFileExist(newPath) {
err := os.Remove(newPath)
if err != nil {
beego.Error("删除旧的csv文件错误",err)
}
}
return newPath
}