package service
|
|
import (
|
"car-service/extend/util"
|
"car-service/models"
|
"encoding/json"
|
"errors"
|
"fmt"
|
"github.com/astaxie/beego"
|
"sync"
|
"time"
|
)
|
var latestToken *TokenResult
|
var lock sync.RWMutex
|
func getCacheToken() string {
|
lock.Lock()
|
defer lock.Unlock()
|
if latestToken != nil {
|
return latestToken.Token
|
}
|
return ""
|
}
|
func updateToken(newT *TokenResult) {
|
lock.Lock()
|
defer lock.Unlock()
|
latestToken = newT
|
}
|
|
func init() {
|
newToken, err := RefreshToken()
|
if err == nil {
|
updateToken(newToken)
|
}
|
ticker := time.NewTicker(time.Hour * 20)
|
go func() {
|
for {
|
select {
|
case <-ticker.C:
|
if t,err := RefreshToken();err == nil {
|
updateToken(t)
|
}
|
default:
|
time.Sleep(time.Second * 5)
|
}
|
}
|
}()
|
}
|
|
//解绑所有与该别名绑定的cid
|
//func UnbindAlias(alias string) (bool, error) {
|
// appId := beego.AppConfig.String("pushAppId")
|
// baseUrl := beego.AppConfig.String("pushBaseUrl") + appId
|
// retryTimes := 0
|
//ReTry:
|
// token := getCacheToken()
|
// if token == "" {
|
// return false, errors.New("token is nil")
|
// }
|
// url := baseUrl + "/user/alias/"+alias
|
// header := map[string]string {
|
// "token": token,
|
// }
|
// b,err := util.DoDeleteRequest(url, util.CONTENT_TYPE_UTF8_JSON, nil, header)
|
// if err !=nil {
|
// fmt.Println("DoDelete err:", err)
|
// return false, err
|
// }
|
// var result PushResult
|
// err = json.Unmarshal(b, &result)
|
// if err != nil {
|
// fmt.Println("unmarshal err:", err)
|
// return false, err
|
// }
|
// if result.Code == 0 { //解绑成功
|
// return true, nil
|
// } else if result.Code == 10001 { //token过期
|
// if retryTimes <=3 {
|
// newToken, err := RefreshToken()
|
// if err == nil {
|
// updateToken(newToken)
|
// retryTimes++
|
// goto ReTry
|
// }
|
// }
|
// }
|
// return false, errors.New(result.Msg)
|
//}
|
|
//一个别名最多允许绑定10个cid
|
func BindAlias(cid, alias string) (bool, error) {
|
appId := beego.AppConfig.String("pushAppId")
|
baseUrl := beego.AppConfig.String("pushBaseUrl") + appId
|
retryTimes := 0
|
ReTry:
|
token := getCacheToken()
|
if token == "" {
|
return false, errors.New("token is nil")
|
}
|
url := baseUrl+"/user/alias"
|
caArr := make([]map[string]string, 0)
|
caArr = append(caArr, map[string]string{
|
"cid": cid,
|
"alias": alias,
|
})
|
reqBody := map[string]interface{} {
|
"data_list":caArr,
|
}
|
header := map[string]string {
|
"token": token,
|
}
|
b, err := util.DoPostRequest(url, util.CONTENT_TYPE_UTF8_JSON, reqBody, nil, header)
|
if err !=nil {
|
fmt.Println("DoPost err:", err)
|
return false, err
|
}
|
var result PushResult
|
err = json.Unmarshal(b, &result)
|
if err != nil {
|
fmt.Println("unmarshal err:", err)
|
return false, err
|
}
|
if result.Code == 0 { //绑定成功
|
return true, nil
|
} else if result.Code == 10001 { //token过期
|
if retryTimes <=3 {
|
newToken, err := RefreshToken()
|
if err == nil {
|
updateToken(newToken)
|
retryTimes++
|
goto ReTry
|
}
|
}
|
}
|
return false, errors.New(result.Msg)
|
}
|
|
type PushResult struct {
|
Code int `json:"code"`
|
Msg string `json:"msg"`
|
Data interface{} `json:"data"`
|
}
|
|
type TokenResult struct {
|
ExpireTime string `json:"expire_time"`
|
Token string `json:"token"`
|
}
|
|
type CreatePushMsgResult struct {
|
TaskId string `json:"taskid"`
|
}
|
|
func createPushMsg(title string, msg string) (bool,string, error) {
|
appId := beego.AppConfig.String("pushAppId")
|
baseUrl := beego.AppConfig.String("pushBaseUrl") + appId
|
retryTimes := 0
|
ReTry:
|
token := getCacheToken()
|
if token == "" {
|
return false, "", errors.New("token is nil")
|
}
|
url := baseUrl+"/push/list/message"
|
intent := "intent:#Intent;action=android.intent.action.oppopush;launchFlags=0x14000000;component=uni.UNIEDF0B5C/io.dcloud.PandoraEntry;S.UP-OL-SU=true;S.title="+title+";S.content="+msg+";S.payload=test;end"
|
reqBody := map[string]interface{} {
|
"request_id": time.Now().Format("20060102150405") + util.GenValidateCode(6),
|
"settings":map[string]int {
|
"ttl": 8 * 3600 * 1000,
|
},
|
"push_message": map[string]map[string]string {
|
"notification": {
|
"title": title,
|
"body": msg,
|
"click_type": "intent",
|
"intent": intent,
|
},
|
},
|
"push_channel": map[string]map[string]map[string]map[string]string {
|
"android": {
|
"ups": {
|
"notification": {
|
"title": title,
|
"body": msg,
|
"click_type": "intent",
|
"intent": intent,
|
},
|
},
|
},
|
},
|
}
|
header := map[string]string {
|
"token": token,
|
}
|
b, err := util.DoPostRequest(url, util.CONTENT_TYPE_UTF8_JSON, reqBody, nil, header)
|
if err !=nil {
|
fmt.Println("DoPost err:", err)
|
return false, "",err
|
}
|
var result PushResult
|
err = json.Unmarshal(b, &result)
|
if err != nil {
|
fmt.Println("unmarshal err:", err)
|
return false, "",err
|
}
|
if result.Code == 0 {
|
rb,uErr := json.Marshal(result.Data)
|
if uErr == nil {
|
var tResult CreatePushMsgResult
|
if uErr =json.Unmarshal(rb, &tResult); uErr ==nil {
|
return true, tResult.TaskId, nil
|
} else {
|
return false, "", uErr
|
}
|
} else {
|
return false, "", uErr
|
}
|
} else if result.Code == 10001 { //token过期
|
if retryTimes <=3 {
|
newToken, err := RefreshToken()
|
if err == nil {
|
updateToken(newToken)
|
retryTimes++
|
goto ReTry
|
}
|
}
|
}
|
return false, "", errors.New(result.Msg)
|
}
|
|
//对已注册的用户进行消息推送。调用此接口前需调用创建消息接口设置消息内容
|
func PushByAlias(title string, msg string) (bool, error) {
|
var aliasArr []string
|
|
pushUserM := make(map[string]string)
|
var userE models.User
|
allUsers, _ := userE.GetAllUsers()
|
if allUsers != nil {
|
for _,u := range allUsers {
|
pushUserM[u.Id] = u.PhoneNum
|
}
|
}
|
if len(pushUserM) == 0 {
|
return true,errors.New("len(pushUserM) == 0")
|
}
|
carPersonM := make(map[string]string) //以车牌号为key,value是hik的personId
|
csv := NewCarService()
|
carPersons := csv.GetVehicleListByPerson("")
|
if carPersons != nil {
|
for _, cp := range carPersons {
|
carPersonM[cp.PlateNo] = cp.PersonId
|
}
|
}
|
delPersonIdM := make(map[string]string)
|
spaceNos := csv.FindSpaceNo("")
|
for _,sn := range spaceNos {
|
if sn.State == 1 && sn.PlateNo != "" { //已经把车停到停车场的车主,不再推送消息
|
if pId,ok := carPersonM[sn.PlateNo];ok {
|
delPersonIdM[pId] = pId
|
delete(carPersonM, sn.PlateNo)
|
}
|
}
|
}
|
for _,personId := range carPersonM {
|
if phoneNum,ok := pushUserM[personId]; ok { //此人已注册到系统,并且车不在停车库内
|
if _,in := delPersonIdM[personId];!in {
|
aliasArr = append(aliasArr, phoneNum)
|
}
|
}
|
}
|
if len(aliasArr) == 0 {
|
return true, errors.New("aliasArr is empty")
|
} else {
|
fmt.Println("PushByAlias arr:", aliasArr)
|
}
|
|
cResult, taskId, ce := createPushMsg(title, msg)
|
fmt.Println("createPushMsg taskId:", taskId, "cResult:",cResult, "err:", ce)
|
if !cResult {
|
return false, errors.New("创建推送前置消息失败")
|
}
|
|
appId := beego.AppConfig.String("pushAppId")
|
baseUrl := beego.AppConfig.String("pushBaseUrl") + appId
|
retryTimes := 0
|
ReTry:
|
token := getCacheToken()
|
if token == "" {
|
return false, errors.New("token is nil")
|
}
|
url := baseUrl+"/push/list/alias"
|
reqBody := map[string]interface{} {
|
"audience":map[string]interface{}{
|
"alias": aliasArr,
|
},
|
"taskid": taskId,
|
"is_async": false,
|
}
|
header := map[string]string {
|
"token": token,
|
}
|
b, err := util.DoPostRequest(url, util.CONTENT_TYPE_UTF8_JSON, reqBody, nil, header)
|
if err !=nil {
|
fmt.Println("DoPost err:", err)
|
return false, err
|
}
|
var result PushResult
|
err = json.Unmarshal(b, &result)
|
if err != nil {
|
fmt.Println("unmarshal err:", err)
|
return false, err
|
}
|
if result.Code == 0 {
|
return true, nil
|
} else if result.Code == 10001 { //token过期
|
if retryTimes <=3 {
|
newToken, err := RefreshToken()
|
if err == nil {
|
updateToken(newToken)
|
retryTimes++
|
goto ReTry
|
}
|
}
|
} else {
|
fmt.Println("推送结果:", result)
|
}
|
|
return false, errors.New("推送失败")
|
}
|
|
func NightPush(title string, msg string) (bool, error) {
|
var aliasArr []string
|
|
pushUserM := make(map[string]string)
|
var userE models.User
|
allUsers, _ := userE.GetAllUsers()
|
if allUsers != nil {
|
for _,u := range allUsers {
|
pushUserM[u.Id] = u.PhoneNum
|
}
|
}
|
if len(pushUserM) == 0 {
|
return true,nil
|
}
|
carPersonM := make(map[string]string)
|
csv := NewCarService()
|
carPersons := csv.GetVehicleListByPerson("")
|
if carPersons != nil {
|
for _, cp := range carPersons {
|
carPersonM[cp.PlateNo] = cp.PersonId
|
}
|
}
|
spaceNos := csv.FindSpaceNo("")
|
for _,sn := range spaceNos {
|
if sn.State == 1 && sn.PlateNo != "" { //已经把车停到停车场的车主,不再推送消息
|
if personId,ok := carPersonM[sn.PlateNo];ok {
|
if phoneNum,ok := pushUserM[personId]; ok { //此人已注册到系统,并且车不在停车库内
|
aliasArr = append(aliasArr, phoneNum)
|
}
|
}
|
}
|
}
|
|
if len(aliasArr) == 0 {
|
fmt.Println("没有推送目标,aliasArr is empty")
|
return true, nil
|
}
|
|
cResult, taskId, ce := createPushMsg(title, msg)
|
if !cResult {
|
fmt.Println("createPushMsg taskId:", taskId, "err:", ce)
|
return false, errors.New("创建推送前置消息失败")
|
}
|
|
appId := beego.AppConfig.String("pushAppId")
|
baseUrl := beego.AppConfig.String("pushBaseUrl") + appId
|
retryTimes := 0
|
ReTry:
|
token := getCacheToken()
|
if token == "" {
|
return false, errors.New("token is nil")
|
}
|
url := baseUrl+"/push/list/alias"
|
reqBody := map[string]interface{} {
|
"audience":map[string]interface{}{
|
"alias": aliasArr,
|
},
|
"taskid": taskId,
|
"is_async": true,
|
}
|
header := map[string]string {
|
"token": token,
|
}
|
b, err := util.DoPostRequest(url, util.CONTENT_TYPE_UTF8_JSON, reqBody, nil, header)
|
if err !=nil {
|
fmt.Println("DoPost err:", err)
|
return false, err
|
}
|
var result PushResult
|
err = json.Unmarshal(b, &result)
|
if err != nil {
|
fmt.Println("unmarshal err:", err)
|
return false, err
|
}
|
if result.Code == 0 {
|
return true, nil
|
} else if result.Code == 10001 { //token过期
|
if retryTimes <=3 {
|
newToken, err := RefreshToken()
|
if err == nil {
|
updateToken(newToken)
|
retryTimes++
|
goto ReTry
|
}
|
}
|
} else {
|
fmt.Println("推送结果:", result)
|
}
|
|
return false, errors.New("推送失败")
|
}
|
|
func PushAll(title string, msg string) (bool,error) {
|
appId := beego.AppConfig.String("pushAppId")
|
baseUrl := beego.AppConfig.String("pushBaseUrl") + appId
|
retryTimes := 0
|
ReTry:
|
token := getCacheToken()
|
if token == "" {
|
return false, errors.New("token is nil")
|
}
|
url := baseUrl+"/push/all"
|
intent := "intent:#Intent;action=android.intent.action.oppopush;launchFlags=0x14000000;component=uni.UNIEDF0B5C/io.dcloud.PandoraEntry;S.UP-OL-SU=true;S.title="+title+";S.content="+msg+";S.payload=test;end"
|
reqBody := map[string]interface{} {
|
"request_id": time.Now().Format("20060102150405") + util.GenValidateCode(6),
|
"settings":map[string]int {
|
"ttl": 8 * 3600 * 1000,
|
},
|
"audience": "all",
|
"push_message": map[string]map[string]string {
|
"notification": {
|
"title": title,
|
"body": msg,
|
"click_type": "intent",
|
"intent": intent,
|
},
|
},
|
"push_channel": map[string]map[string]map[string]map[string]string {
|
"android": {
|
"ups": {
|
"notification": {
|
"title": title,
|
"body": msg,
|
"click_type": "intent",
|
"intent": intent,
|
},
|
},
|
},
|
},
|
}
|
header := map[string]string {
|
"token": token,
|
}
|
b, err := util.DoPostRequest(url, util.CONTENT_TYPE_UTF8_JSON, reqBody, nil, header)
|
if err !=nil {
|
fmt.Println("DoPost err:", err)
|
return false, err
|
}
|
var result PushResult
|
err = json.Unmarshal(b, &result)
|
if err != nil {
|
fmt.Println("unmarshal err:", err)
|
return false, err
|
}
|
if result.Code == 0 {
|
return true, nil
|
} else if result.Code == 10001 { //token过期
|
if retryTimes <=3 {
|
newToken, err := RefreshToken()
|
if err == nil {
|
updateToken(newToken)
|
retryTimes++
|
goto ReTry
|
}
|
}
|
} else {
|
fmt.Println("推送结果:", result)
|
}
|
|
return false, errors.New("推送失败")
|
}
|
|
func RefreshToken() (*TokenResult,error) {
|
appId := beego.AppConfig.String("pushAppId")
|
appKey := beego.AppConfig.String("pushAppKey")
|
masterSecret := beego.AppConfig.String("pushMasterSecret")
|
baseUrl := beego.AppConfig.String("pushBaseUrl") + appId
|
url := baseUrl +"/auth"
|
timestamp := fmt.Sprintf("%v", time.Now().UnixNano() / 1e6)
|
sign := util.Sha256(appKey + timestamp + masterSecret)
|
reqBody := map[string]interface{} {
|
"sign": sign,
|
"timestamp": timestamp,
|
"appkey": appKey,
|
}
|
b, err := util.DoPostRequest(url, util.CONTENT_TYPE_UTF8_JSON, reqBody, nil, nil)
|
if err !=nil {
|
fmt.Println("DoPost err:", err)
|
return nil, err
|
}
|
var result PushResult
|
err = json.Unmarshal(b, &result)
|
if err != nil {
|
fmt.Println("unmarshal err:", err)
|
return nil, err
|
}
|
if result.Code == 0 {
|
db, err := json.Marshal(result.Data)
|
if err != nil {
|
fmt.Println("marshal err:", err)
|
return nil, err
|
}
|
var t TokenResult
|
err = json.Unmarshal(db, &t)
|
if err != nil {
|
fmt.Println("unmarshal err:", err)
|
return nil, err
|
}
|
return &t, nil
|
}
|
return nil, errors.New("获取unipush平台token失败")
|
}
|