init
This commit is contained in:
commit
4dba9b162c
|
@ -0,0 +1,11 @@
|
|||
*.iml
|
||||
.idea/
|
||||
output/
|
||||
dockerfiles/
|
||||
log
|
||||
.DS_Store
|
||||
doc
|
||||
cmd/test
|
||||
go.sum
|
||||
pkg
|
||||
test.go
|
|
@ -0,0 +1,249 @@
|
|||
package adapi
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/smbrave/gosdk/util"
|
||||
"github.com/spf13/cast"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Sdk struct {
|
||||
address string
|
||||
token string
|
||||
}
|
||||
|
||||
func NewSdk(address string, token string) *Sdk {
|
||||
if address == "" {
|
||||
address = "http://127.0.0.1:9281"
|
||||
}
|
||||
|
||||
return &Sdk{
|
||||
address: address,
|
||||
token: token,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Sdk) httpGet(url string) error {
|
||||
|
||||
body, err := util.HttpGet(url, map[string]string{
|
||||
"x-token": s.token,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
type rsp_t struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
var rsp rsp_t
|
||||
if err := json.Unmarshal(body, &rsp); err != nil {
|
||||
return err
|
||||
}
|
||||
if rsp.Code != 0 {
|
||||
return fmt.Errorf("%d:%s", rsp.Code, rsp.Message)
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func (s *Sdk) httpMatchGet(url string) (*Result, error) {
|
||||
body, err := util.HttpGet(url, map[string]string{
|
||||
"x-token": s.token,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
type rsp_t struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data *Result `json:"data"`
|
||||
}
|
||||
|
||||
var rsp rsp_t
|
||||
if err := json.Unmarshal(body, &rsp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if rsp.Code != 0 {
|
||||
return nil, fmt.Errorf("%d:%s", rsp.Code, rsp.Message)
|
||||
}
|
||||
return rsp.Data, nil
|
||||
}
|
||||
|
||||
func (s *Sdk) httpDataGet(url string) (map[string]interface{}, error) {
|
||||
body, err := util.HttpGet(url, map[string]string{
|
||||
"x-token": s.token,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
type rsp_t struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data map[string]interface{} `json:"data"`
|
||||
}
|
||||
|
||||
var rsp rsp_t
|
||||
if err := json.Unmarshal(body, &rsp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if rsp.Code != 0 {
|
||||
return nil, fmt.Errorf("%d:%s", rsp.Code, rsp.Message)
|
||||
}
|
||||
return rsp.Data, nil
|
||||
}
|
||||
|
||||
func (s *Sdk) Match(c *Request) (*Result, error) {
|
||||
if err := c.Check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
params := url.Values{}
|
||||
|
||||
params.Add("os", strings.ToLower(c.Os))
|
||||
params.Add("ip", c.Ip)
|
||||
params.Add("ua", c.Ua)
|
||||
params.Add("model", c.Model)
|
||||
params.Add("brand", c.Brand)
|
||||
params.Add("idfa", c.Idfa)
|
||||
params.Add("oaid", c.Oaid)
|
||||
params.Add("imei", c.Imei)
|
||||
params.Add("channel", c.Channel)
|
||||
params.Add("version", c.Version)
|
||||
params.Add("active", strconv.FormatBool(c.Active))
|
||||
if c.Extra != nil {
|
||||
extra, _ := json.Marshal(c.Extra)
|
||||
params.Add("extra", string(extra))
|
||||
}
|
||||
|
||||
u := fmt.Sprintf("%s/api/ad/client/match?%s", s.address, params.Encode())
|
||||
return s.httpMatchGet(u)
|
||||
}
|
||||
|
||||
func (s *Sdk) Active(adId int64, extra map[string]string) error {
|
||||
params := url.Values{}
|
||||
params.Add("adId", strconv.FormatInt(adId, 10))
|
||||
if extra != nil {
|
||||
ex, _ := json.Marshal(extra)
|
||||
params.Add("extra", string(ex))
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s/api/ad/client/active?%s",
|
||||
s.address, params.Encode())
|
||||
|
||||
return s.httpGet(url)
|
||||
}
|
||||
|
||||
/*
|
||||
extra存放扩展数据,注册相关信息都填上
|
||||
unionid、phone、openid、nickname
|
||||
*/
|
||||
|
||||
func (s *Sdk) Register(adId int64, extra map[string]string) error {
|
||||
params := url.Values{}
|
||||
params.Add("adId", strconv.FormatInt(adId, 10))
|
||||
if extra != nil {
|
||||
ex, _ := json.Marshal(extra)
|
||||
params.Add("extra", string(ex))
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s/api/ad/client/register?%s",
|
||||
s.address, params.Encode())
|
||||
|
||||
return s.httpGet(url)
|
||||
}
|
||||
|
||||
/*
|
||||
extra存放扩展数据,支付相关信息都填上
|
||||
支付金额:payFee (单位分)
|
||||
支付方式:payType(weixin、alipay、apple)
|
||||
支付位置:payLocation (内容自定义)
|
||||
支付商品:goodsId、goodsName
|
||||
*/
|
||||
|
||||
func (s *Sdk) Pay(adId int64, extra map[string]string) error {
|
||||
params := url.Values{}
|
||||
params.Add("adId", strconv.FormatInt(adId, 10))
|
||||
if extra != nil {
|
||||
ex, _ := json.Marshal(extra)
|
||||
params.Add("extra", string(ex))
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s/api/ad/client/pay?%s",
|
||||
s.address, params.Encode())
|
||||
|
||||
return s.httpGet(url)
|
||||
}
|
||||
|
||||
func (s *Sdk) Relation(adId int64) (*AdRelation, error) {
|
||||
params := url.Values{}
|
||||
params.Add("adId", strconv.FormatInt(adId, 10))
|
||||
|
||||
url := fmt.Sprintf("%s/api/ad/client/relation?%s",
|
||||
s.address, params.Encode())
|
||||
|
||||
var relation AdRelation
|
||||
data, err := s.httpDataGet(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res, _ := json.Marshal(data)
|
||||
json.Unmarshal(res, &relation)
|
||||
return &relation, nil
|
||||
}
|
||||
|
||||
func (s *Sdk) GetAccountReport(startDay, endDay string, accountType string) ([]*AccountReport, error) {
|
||||
if startDay == "" && endDay == "" {
|
||||
startDay = time.Now().Format("2006-01-02")
|
||||
endDay = startDay
|
||||
}
|
||||
|
||||
reqUrl := fmt.Sprintf("%s/api/ad/account/report?startDay=%s&endDay=%s&accountType=%s",
|
||||
s.address, startDay, endDay, accountType)
|
||||
|
||||
body, err := util.HttpGet(reqUrl, map[string]string{
|
||||
"x-token": s.token,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
type rsp_t struct {
|
||||
BaseResponse
|
||||
Data []map[string]interface{} `json:"data"`
|
||||
}
|
||||
|
||||
var rsp rsp_t
|
||||
if err := json.Unmarshal(body, &rsp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if rsp.Code != 0 {
|
||||
return nil, fmt.Errorf("%d:%s", rsp.Code, rsp.Message)
|
||||
}
|
||||
results := make([]*AccountReport, 0)
|
||||
for _, data := range rsp.Data {
|
||||
r := new(AccountReport)
|
||||
r.Id = cast.ToString(data["accounId"])
|
||||
r.Name = cast.ToString(data["accounName"])
|
||||
r.Type = cast.ToString(data["accounType"])
|
||||
r.Day = cast.ToString(data["day"])
|
||||
r.Cost = cast.ToFloat64(data["cost"])
|
||||
r.Show = cast.ToInt64(data["show"])
|
||||
r.Click = cast.ToInt64(data["click"])
|
||||
r.Download = cast.ToInt64(data["download"])
|
||||
r.Active = cast.ToInt64(data["active"])
|
||||
r.Register = cast.ToInt64(data["register"])
|
||||
r.Pay = cast.ToInt64(data["pay"])
|
||||
r.PayAmount = cast.ToFloat64(data["payAmount"])
|
||||
r.Balance = cast.ToFloat64(data["balance"])
|
||||
results = append(results, r)
|
||||
}
|
||||
return results, nil
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package adapi
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSdk(t1 *testing.T) {
|
||||
fmt.Println("ok1")
|
||||
sdk := NewSdk("http://localhost:9281", "10020", "")
|
||||
res, err := sdk.GetAccountReport("", "", "")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("ok2")
|
||||
fmt.Println(len(res))
|
||||
fmt.Printf("%+v", res)
|
||||
for i, r := range res {
|
||||
fmt.Println(i, r.Name)
|
||||
}
|
||||
|
||||
fmt.Println("ok3")
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
package adapi
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type BaseResponse struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type Request struct {
|
||||
Channel string //安装包的渠道
|
||||
Version string //安装包版本
|
||||
Os string //手机系统类别 android、ioss
|
||||
Ip string //客户端的外网ip
|
||||
Ua string //客户端的user-agent
|
||||
Brand string // 客户端手机品牌
|
||||
Model string //客户端的手机型号,如:NOH-AN00
|
||||
Idfa string //客户端的广告id,ios时候有效
|
||||
Oaid string //客户端的广告id,android时有效
|
||||
Imei string //设备唯一识别码
|
||||
Extra map[string]string //其他额外数据
|
||||
Active bool // 是否直接激活
|
||||
}
|
||||
|
||||
type Result struct {
|
||||
AdId int64 `json:"adId"`
|
||||
Source string `json:"source"`
|
||||
Extra map[string]string `json:"extra"`
|
||||
}
|
||||
|
||||
func (c *Request) Check() error {
|
||||
if strings.ToLower(c.Os) != "ios" && c.Channel == "" {
|
||||
return errors.New("channel must set")
|
||||
}
|
||||
if c.Version == "" {
|
||||
return errors.New("version must set")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AccountReport struct {
|
||||
Id string `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Day string `json:"day"`
|
||||
Cost float64 `json:"cost"`
|
||||
Show int64 `json:"show"`
|
||||
Click int64 `json:"click"`
|
||||
Download int64 `json:"download"`
|
||||
Active int64 `json:"active"`
|
||||
Register int64 `json:"register"`
|
||||
Pay int64 `json:"pay"`
|
||||
PayAmount float64 `json:"payAmount"`
|
||||
Balance float64 `json:"balance"`
|
||||
}
|
||||
|
||||
type Relation struct {
|
||||
MatchType string `json:"matchType"`
|
||||
CreateTime int64 `json:"createTime"`
|
||||
ActiveTime int64 `json:"activeTime"`
|
||||
RegisterTime int64 `json:"registerTime"`
|
||||
PayTime int64 `json:"payTime"`
|
||||
Source string `json:"source"`
|
||||
}
|
||||
|
||||
type Click struct {
|
||||
Action string `json:"action"`
|
||||
AccountId int64 `json:"accountId"`
|
||||
AccountName string `json:"accountName"`
|
||||
PlanId int64 `json:"planId"`
|
||||
PlanName string `json:"planName"`
|
||||
GroupId int64 `json:"groupId"`
|
||||
GroupName string `json:"groupName"`
|
||||
CreativeId int64 `json:"creativeId"`
|
||||
CreativeName string `json:"creativeName"`
|
||||
ClickTime int64 `json:"clickTime"`
|
||||
Ip string `json:"ip"`
|
||||
Ua string `json:"ua"`
|
||||
Idfa string `json:"idfa"`
|
||||
Oaid string `json:"oaid"`
|
||||
}
|
||||
|
||||
type AdRelation struct {
|
||||
Relation *Relation `json:"relation"`
|
||||
Click *Click `json:"click"`
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package adminapi
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/smbrave/gosdk/util"
|
||||
)
|
||||
|
||||
type Application struct {
|
||||
token string
|
||||
address string
|
||||
}
|
||||
|
||||
func NewApplication(addreess string, token string) *Application {
|
||||
if addreess == "" {
|
||||
addreess = "http://127.0.0.1:9281"
|
||||
}
|
||||
return &Application{
|
||||
address: addreess,
|
||||
token: token,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Application) Login(username, password, appid string) (interface{}, error) {
|
||||
reqUrl := fmt.Sprintf("%s/admin/app/login", m.address)
|
||||
params := make(map[string]interface{})
|
||||
params["username"] = username
|
||||
params["password"] = password
|
||||
params["appid"] = appid
|
||||
reqBody, _ := json.Marshal(params)
|
||||
body, err := util.HttpPostJson(reqUrl, map[string]string{
|
||||
"x-token": m.token,
|
||||
}, reqBody)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var rsp util.DataResponse
|
||||
if err := json.Unmarshal(body, &rsp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if rsp.Code != 0 {
|
||||
return nil, fmt.Errorf("%d:%s", rsp.Code, rsp.Message)
|
||||
}
|
||||
return rsp.Data, nil
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package adminapi
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/smbrave/gosdk/util"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
token string
|
||||
sender string
|
||||
address string
|
||||
}
|
||||
|
||||
func NewMessage(addreess string, token string, sender string) *Message {
|
||||
if addreess == "" {
|
||||
addreess = "http://127.0.0.1:9281"
|
||||
}
|
||||
return &Message{
|
||||
address: addreess,
|
||||
token: token,
|
||||
sender: sender,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Message) Send(receiver, content string) error {
|
||||
reqUrl := fmt.Sprintf("%s/admin/message/send?sender=%s&receiver=%s&content=%s", m.address, m.sender, receiver, url.QueryEscape(content))
|
||||
body, err := util.HttpGet(reqUrl, map[string]string{
|
||||
"x-token": m.token,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var rsp util.Response
|
||||
if err := json.Unmarshal(body, &rsp); err != nil {
|
||||
return err
|
||||
}
|
||||
if rsp.Code != 0 {
|
||||
return fmt.Errorf("%d:%s", rsp.Code, rsp.Message)
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package adminapi
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMessage_Send(t *testing.T) {
|
||||
|
||||
s := NewMessage("http://u.batiao8.com", "", "alarm")
|
||||
|
||||
mess := make([]string, 0)
|
||||
mess = append(mess, "加发到")
|
||||
mess = append(mess, "asdfasdfadfa")
|
||||
mess = append(mess, "@3q452345~!@@#$$%^&*())")
|
||||
err := s.Send("jiangyong", strings.Join(mess, "\n"))
|
||||
fmt.Println(err)
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
module github.com/smbrave/gosdk
|
||||
|
||||
go 1.18
|
||||
|
||||
require github.com/spf13/cast v1.5.0
|
|
@ -0,0 +1,34 @@
|
|||
package metric
|
||||
|
||||
import "os"
|
||||
|
||||
var (
|
||||
serv *service
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Address string
|
||||
Interval int
|
||||
}
|
||||
|
||||
func NewConfg() *Config {
|
||||
return &Config{
|
||||
Address: "10.0.1.15:17000",
|
||||
Interval: 10,
|
||||
}
|
||||
}
|
||||
|
||||
func Init(c *Config) error {
|
||||
if serv != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
hostname, _ := os.Hostname()
|
||||
serv = &service{
|
||||
config: c,
|
||||
hostname: hostname,
|
||||
metrics: make(chan *metric, 100000),
|
||||
}
|
||||
go serv.run()
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package metric
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func Metric(name string, value float64, tag map[string]string) {
|
||||
if serv == nil {
|
||||
return
|
||||
}
|
||||
|
||||
serv.add(&metric{
|
||||
Metric: name,
|
||||
Value: value,
|
||||
Tags: tag,
|
||||
Timestamp: time.Now().Unix(),
|
||||
})
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package metric
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestName(t *testing.T) {
|
||||
c := NewConfg()
|
||||
c.Address = "https://monitor.batiao8.com"
|
||||
Init(c)
|
||||
for i := 0; i < 100; i++ {
|
||||
Metric("test", float64(rand.Int()%100), map[string]string{
|
||||
"a": "b",
|
||||
"c": "d",
|
||||
})
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetric(t *testing.T) {
|
||||
c := NewConfg()
|
||||
c.Address = "https://monitor.batiao8.com"
|
||||
Init(c)
|
||||
|
||||
Metric("test.test1.test2", 12, map[string]string{
|
||||
"a": "b",
|
||||
"c": "d",
|
||||
})
|
||||
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
package metric
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/spf13/cast"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type metric struct {
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
Metric string `json:"metric"`
|
||||
Value float64 `json:"value"`
|
||||
Tags map[string]string `json:"tags"`
|
||||
}
|
||||
|
||||
type service struct {
|
||||
hostname string
|
||||
metrics chan *metric
|
||||
megers map[string]*metric
|
||||
config *Config
|
||||
}
|
||||
|
||||
func (s *service) run() {
|
||||
timer := time.NewTicker(time.Duration(s.config.Interval) * time.Second)
|
||||
for {
|
||||
select {
|
||||
case m := <-s.metrics:
|
||||
s.process(m)
|
||||
|
||||
case <-timer.C:
|
||||
s.report()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *service) sortMap(tag map[string]string) string {
|
||||
arr := make([]string, 0)
|
||||
for k, v := range tag {
|
||||
arr = append(arr, fmt.Sprintf("%s=%s", k, v))
|
||||
}
|
||||
sort.Strings(arr)
|
||||
return strings.Join(arr, ":")
|
||||
}
|
||||
|
||||
func (s *service) process(m *metric) {
|
||||
if s.megers == nil {
|
||||
s.megers = make(map[string]*metric)
|
||||
}
|
||||
key := m.Metric
|
||||
if m.Tags != nil {
|
||||
key += "_" + s.sortMap(m.Tags)
|
||||
}
|
||||
|
||||
if v, ok := s.megers[key]; ok {
|
||||
v.Value += m.Value
|
||||
v.Timestamp = m.Timestamp
|
||||
return
|
||||
}
|
||||
s.megers[key] = m
|
||||
}
|
||||
|
||||
func (s *service) defaultTags(tags map[string]string) map[string]string {
|
||||
if tags == nil {
|
||||
tags = map[string]string{
|
||||
"hostname": s.hostname,
|
||||
}
|
||||
} else {
|
||||
tags["hostname"] = s.hostname
|
||||
}
|
||||
return tags
|
||||
}
|
||||
|
||||
func (s *service) report() {
|
||||
if s.megers == nil {
|
||||
return
|
||||
}
|
||||
metrics := make([]*metric, 0)
|
||||
for _, v := range s.megers {
|
||||
v.Tags = s.defaultTags(v.Tags)
|
||||
metrics = append(metrics, v)
|
||||
}
|
||||
reqUrl := fmt.Sprintf("%s/opentsdb/put", serv.config.Address)
|
||||
|
||||
reqBody, _ := json.Marshal(metrics)
|
||||
resp, err := http.Post(reqUrl, "application/json", bytes.NewBuffer(reqBody))
|
||||
if err != nil {
|
||||
log.Printf("http.Post error :%s", err.Error())
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
rspBody, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
log.Printf(" ioutil.ReadAll error :%s", err.Error())
|
||||
return
|
||||
}
|
||||
result := make(map[string]interface{})
|
||||
if err := json.Unmarshal(rspBody, &result); err != nil {
|
||||
log.Printf("json result : %s", string(rspBody))
|
||||
return
|
||||
}
|
||||
|
||||
fail := cast.ToInt(result["fail"])
|
||||
if fail != 0 {
|
||||
log.Printf("http result : %s", string(rspBody))
|
||||
return
|
||||
}
|
||||
s.megers = nil
|
||||
}
|
||||
|
||||
func (s *service) add(m *metric) {
|
||||
select {
|
||||
case s.metrics <- m:
|
||||
default:
|
||||
fmt.Println("chan is full")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
package payapi
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/smbrave/gosdk/util"
|
||||
)
|
||||
|
||||
var (
|
||||
PayTypeWeixin = "weixin"
|
||||
PayTypeAlipay = "alipay"
|
||||
)
|
||||
|
||||
type Pay struct {
|
||||
address string
|
||||
token string
|
||||
}
|
||||
|
||||
func NewPay(address string, token string) *Pay {
|
||||
if address == "" {
|
||||
address = "http://127.0.0.1:9281"
|
||||
}
|
||||
return &Pay{
|
||||
address: address,
|
||||
token: token,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Pay) CreateOrder(order *CreateOrderReq) (map[string]interface{}, error) {
|
||||
if order.PayType == "" {
|
||||
errors.New("payType is nil")
|
||||
}
|
||||
if order.PayPrice <= 0 {
|
||||
return nil, errors.New("payPrice is nil")
|
||||
}
|
||||
reqBody, _ := json.Marshal(order)
|
||||
|
||||
result, err := util.HttpPostJson(p.address+"/api/pay/order", map[string]string{
|
||||
"x-token": p.token,
|
||||
}, reqBody)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var rsp CommonResponse
|
||||
if err := json.Unmarshal([]byte(result), &rsp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if rsp.Code != 0 {
|
||||
return nil, fmt.Errorf("%d:%s", rsp.Code, rsp.Message)
|
||||
}
|
||||
|
||||
return rsp.Data, nil
|
||||
}
|
||||
|
||||
func (p *Pay) UpdateOrder(data map[string]interface{}) error {
|
||||
reqBody, _ := json.Marshal(data)
|
||||
|
||||
result, err := util.HttpPutJson(p.address+"/api/pay/order", map[string]string{
|
||||
"x-token": p.token,
|
||||
}, reqBody)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var rsp CommonResponse
|
||||
if err := json.Unmarshal([]byte(result), &rsp); err != nil {
|
||||
return err
|
||||
}
|
||||
if rsp.Code != 0 {
|
||||
return fmt.Errorf("%d:%s", rsp.Code, rsp.Message)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Pay) GetOrder(outTradeNo string) (map[string]interface{}, error) {
|
||||
if outTradeNo == "" {
|
||||
errors.New("outTradeNo is nil")
|
||||
}
|
||||
|
||||
reqUrl := fmt.Sprintf("%s/api/pay/order?outTradeNo=%s", p.address, outTradeNo)
|
||||
result, err := util.HttpGet(reqUrl, map[string]string{
|
||||
"x-token": p.token,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var rsp CommonResponse
|
||||
if err := json.Unmarshal([]byte(result), &rsp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if rsp.Code != 0 {
|
||||
return nil, fmt.Errorf("%d:%s", rsp.Code, rsp.Message)
|
||||
}
|
||||
|
||||
return rsp.Data, nil
|
||||
}
|
||||
|
||||
func (p *Pay) RefundOrder(outTradeNo, reason string) error {
|
||||
if outTradeNo == "" {
|
||||
errors.New("outTradeNo is nil")
|
||||
}
|
||||
|
||||
reqUrl := fmt.Sprintf("%s/api/pay/order?outTradeNo=%s&reason=%s", p.address, outTradeNo, reason)
|
||||
result, err := util.HttpDelete(reqUrl, map[string]string{
|
||||
"x-token": p.token,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var rsp CommonResponse
|
||||
if err := json.Unmarshal([]byte(result), &rsp); err != nil {
|
||||
return err
|
||||
}
|
||||
if rsp.Code != 0 {
|
||||
return fmt.Errorf("%d:%s", rsp.Code, rsp.Message)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package payapi
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewPay(t *testing.T) {
|
||||
payApi := NewPay("http://u.batiao8.com", "")
|
||||
order, err := payApi.GetOrder("ZB_20230826122127_2YAxfg")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
res, _ := json.Marshal(order)
|
||||
fmt.Println(string(res))
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package payapi
|
||||
|
||||
type OrderUser struct {
|
||||
UserId string `json:"userId"`
|
||||
UserName string `json:"userName"`
|
||||
CreateTime string `json:"createTime"`
|
||||
Openid string `json:"openid"`
|
||||
Source string `json:"source"`
|
||||
SourceId string `json:"sourceId"`
|
||||
MobileBrand string `json:"brand"`
|
||||
MobileModel string `json:"model"`
|
||||
Platform string `json:"platform"`
|
||||
Channel string `json:"channel"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
type OrderGoods struct {
|
||||
GoodsId string `json:"goodsId"`
|
||||
GoodsName string `json:"goodsName"`
|
||||
Source string `json:"source"`
|
||||
Autopay string `json:"autopay"`
|
||||
}
|
||||
|
||||
type CreateOrderReq struct {
|
||||
OutTradeNo string `json:"outTradeNo"`
|
||||
PayType string `json:"payType"`
|
||||
PayChannel string `json:"payChannel"`
|
||||
PayPrice int64 `json:"payPrice"`
|
||||
PaySource string `json:"paySource"`
|
||||
NotifyUrl string `json:"notifyUrl"`
|
||||
Extra interface{} `json:"extra"`
|
||||
User *OrderUser `json:"user,omitempty"`
|
||||
Goods *OrderGoods `json:"goods,omitempty"`
|
||||
}
|
||||
|
||||
type CommonResponse struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data map[string]interface{} `json:"data"`
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// PostJson 请求
|
||||
func HttpPostJson(link string, header map[string]string, json []byte) ([]byte, error) {
|
||||
client := &http.Client{Timeout: 20 * time.Second}
|
||||
//忽略https的证书
|
||||
client.Transport = &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", link, bytes.NewBuffer(json))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if header != nil {
|
||||
for k, v := range header {
|
||||
req.Header.Add(k, v)
|
||||
}
|
||||
}
|
||||
req.Header.Add("Content-Type", "application/json")
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("%d:%s", resp.StatusCode, resp.Status)
|
||||
}
|
||||
return io.ReadAll(resp.Body)
|
||||
}
|
||||
|
||||
// PostJson 请求
|
||||
func HttpPutJson(link string, header map[string]string, json []byte) ([]byte, error) {
|
||||
client := &http.Client{Timeout: 20 * time.Second}
|
||||
//忽略https的证书
|
||||
client.Transport = &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("PUT", link, bytes.NewBuffer(json))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if header != nil {
|
||||
for k, v := range header {
|
||||
req.Header.Add(k, v)
|
||||
}
|
||||
}
|
||||
req.Header.Add("Content-Type", "application/json")
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("%d:%s", resp.StatusCode, resp.Status)
|
||||
}
|
||||
return io.ReadAll(resp.Body)
|
||||
}
|
||||
|
||||
// Get 请求 link:请求url
|
||||
func HttpGet(link string, header map[string]string) ([]byte, error) {
|
||||
client := &http.Client{Timeout: 20 * time.Second}
|
||||
//忽略https的证书
|
||||
client.Transport = &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("GET", link, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if header != nil {
|
||||
for k, v := range header {
|
||||
req.Header.Add(k, v)
|
||||
}
|
||||
}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("%d:%s", resp.StatusCode, resp.Status)
|
||||
}
|
||||
return io.ReadAll(resp.Body)
|
||||
}
|
||||
|
||||
// Get 请求 link:请求url
|
||||
func HttpDelete(link string, header map[string]string) ([]byte, error) {
|
||||
client := &http.Client{Timeout: 20 * time.Second}
|
||||
//忽略https的证书
|
||||
client.Transport = &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("DELETE", link, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if header != nil {
|
||||
for k, v := range header {
|
||||
req.Header.Add(k, v)
|
||||
}
|
||||
}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("%d:%s", resp.StatusCode, resp.Status)
|
||||
}
|
||||
return io.ReadAll(resp.Body)
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package util
|
||||
|
||||
type Response struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type DataResponse struct {
|
||||
Response
|
||||
Data interface{} `json:"data"`
|
||||
}
|
Loading…
Reference in New Issue