package services
import (
"crypto/sha1"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"math/rand"
"net/http"
"sort"
"strconv"
"time"
)
var appid string
var appsecret string
type wxconfig struct {
appId string
appSecret string
url string
}
type json1 struct {
Expire_time int64
Jsapi_ticket string
}
type json2 struct {
Expire_time int64
Access_token string
}
type token struct {
Access_token string
Expires_in int64
}
type ticket struct {
Errcode int
Errmsg string
Ticket string
Expires_in int64
}
const jssdkKey = "go:act:jssdk"
const accessTokenKey = "go:act:access_token"
type signPackage struct {
AppId string `json:"appId"`
NonceStr string `json:"nonceStr"`
Timestamp int64 `json:"timestamp"`
Url string `json:"url"`
Signature string `json:"signature"`
//JsApiList []string `json:"jsApiList"`
}
func New(appId string, appSecret string, url string) wxconfig {
wx := wxconfig{appId, appSecret, url}
return wx
}
// 创建类方法获取jssdk配置项目 返回json串
func (wx wxconfig) GetWechatConfig() *signPackage {
appid = wx.appId
appsecret = wx.appSecret
//fmt.Printf("running appid: %s appsecret: %s\n", wx.appId, wx.appSecret)
ticket := getJsApiTicket()
timestamp := GetCurrTs()
ts := strconv.FormatInt(timestamp, 10)
nonceStr := getRandomString(16)
url := wx.url
my_string := fmt.Sprintf("jsapi_ticket=%s&noncestr=%s×tamp=%s&url=%s", ticket, nonceStr, ts, url)
//fmt.Println("mys_string==============", my_string)
signature := Signature(my_string)
signPackage := signPackage{wx.appId, nonceStr, timestamp, url, signature}
return &signPackage
}
// 函数首字母小写 表示私有
func getJsApiTicket() string {
redisConn := RedisConn
//fmt.Printf("获取getJsApiTicket\n")
// 获取ticket内容
//json_str := readFile("./jssdk/ticket.txt")
json_str, er := redisConn.Get(jssdkKey).Result()
fmt.Println("===========errrrrrr==========", er)
//fmt.Println("json_str*****************", json_str)
// 解析json串
if json_str != "" {
j := json1{}
err := json.Unmarshal([]byte(json_str), &j)
if err != nil {
fmt.Println("111 ", err.Error())
return ""
}
expire_time := j.Expire_time
jsapi_ticket := j.Jsapi_ticket
if expire_time < GetCurrTs() {
// ticket过期需要从新获取
// 获取access_token生成ticket
access_token := getAccessToken()
//fmt.Println("2222222 ", access_token)
if access_token == "" {
return ""
}
url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=%s", access_token)
resp, _ := http.Get(url)
if resp != nil {
defer func() {
resp.Body.Close()
}()
}
body, _ := ioutil.ReadAll(resp.Body)
//fmt.Println(string(body))
// 解析body
ticket := ticket{}
err := json.Unmarshal([]byte(body), &ticket)
if err != nil {
fmt.Println("3333333333 ", err.Error())
return ""
}
if ticket.Errcode == 0 {
jj := json1{GetCurrTs() + 7000, ticket.Ticket}
data, err := json.Marshal(jj)
if err != nil {
fmt.Println(err)
}
//setFile(string(data), "./jssdk/ticket.txt")
redisConn.Set(jssdkKey, string(data), 86400*365*time.Second)
return ticket.Ticket
} else {
return ""
}
}
return jsapi_ticket
} else {
access_token := getAccessToken()
//fmt.Println("2222222 ", access_token)
if access_token == "" {
return ""
}
url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=%s", access_token)
resp, _ := http.Get(url)
if resp != nil {
defer func() {
resp.Body.Close()
}()
}
body, _ := ioutil.ReadAll(resp.Body)
//fmt.Println(string(body))
// 解析body
ticket := ticket{}
err := json.Unmarshal([]byte(body), &ticket)
if err != nil {
fmt.Println("3333333333 ", err.Error())
return ""
}
if ticket.Errcode == 0 {
jj := json1{GetCurrTs() + 7000, ticket.Ticket}
data, err := json.Marshal(jj)
if err != nil {
fmt.Println(err)
}
//setFile(string(data), "./jssdk/ticket.txt")
redisConn.Set(jssdkKey, string(data), 86400*365*time.Second)
return ticket.Ticket
} else {
return ""
}
}
}
// 获取access token
func getAccessToken() string {
redisConn := RedisConn
// 获取ticket内容
//json_str := readFile("./jssdk/token.txt")
json_str, er := redisConn.Get(accessTokenKey).Result()
fmt.Println("accesstoken er,,,,,,,,,,,", er)
//fmt.Println("accesstoken json_str,,,,,,,,,,,", json_str)
if json_str != "" {
// 解析json串
j := json2{}
err := json.Unmarshal([]byte(json_str), &j)
if err != nil {
fmt.Println(" 333333333 ", err.Error())
return ""
}
expire_time := j.Expire_time
access_token := j.Access_token
if expire_time < GetCurrTs() {
// 获取新token
url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", appid, appsecret)
resp, _ := http.Get(url)
if resp != nil {
defer func() {
resp.Body.Close()
}()
}
body, _ := ioutil.ReadAll(resp.Body)
//fmt.Println(string(body))
// 解析body
token := token{}
err := json.Unmarshal([]byte(body), &token)
if err != nil {
fmt.Println(err.Error())
return ""
}
if len(token.Access_token) > 0 {
jj := json2{GetCurrTs() + 7000, token.Access_token}
data, err := json.Marshal(jj)
if err != nil {
fmt.Println(err)
}
//setFile(string(data), "./jssdk/token.txt")
redisConn.Set(accessTokenKey, string(data), 86400*365*time.Second)
return token.Access_token
} else {
return ""
}
}
return access_token
} else {
url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", appid, appsecret)
resp, _ := http.Get(url)
//fmt.Println("req...........",resp)
//fmt.Println("req.....err......",er)
if resp != nil {
defer func() {
resp.Body.Close()
}()
}
body, _ := ioutil.ReadAll(resp.Body)
//fmt.Println(string(body))
// 解析body
token := token{}
err := json.Unmarshal([]byte(body), &token)
if err != nil {
fmt.Println(err.Error())
return ""
}
if len(token.Access_token) > 0 {
jj := json2{GetCurrTs() + 7000, token.Access_token}
data, err := json.Marshal(jj)
if err != nil {
fmt.Println(err)
}
//setFile(string(data), "./jssdk/token.txt")
redisConn.Set(accessTokenKey, string(data), 86400*365*time.Second)
return token.Access_token
} else {
return ""
}
}
}
func timestamp() int {
timestamp := strconv.FormatInt(time.Now().UTC().Unix(), 10)
my_timestamp, _ := strconv.Atoi(timestamp)
return my_timestamp
}
// 获取随机字符串
func getRandomString(l int) string {
str := "0123456789abcdefghijklmnopqrstuvwxyz"
bytes := []byte(str)
result := []byte{}
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := 0; i < l; i++ {
result = append(result, bytes[r.Intn(len(bytes))])
}
return string(result)
}
// sha1加密
func my_sha1(data string) string {
t := sha1.New()
io.WriteString(t, data)
return fmt.Sprintf("%x", t.Sum(nil))
}
//Signature sha1签名
func Signature(params ...string) string {
sort.Strings(params)
h := sha1.New()
for _, s := range params {
io.WriteString(h, s)
}
return fmt.Sprintf("%x", h.Sum(nil))
}
func GetCurrTs() int64 {
return time.Now().Unix()
}