| | |
| | | |
| | | import ( |
| | | "car-service/extend/util" |
| | | "car-service/models" |
| | | "encoding/json" |
| | | "errors" |
| | | "fmt" |
| | | "github.com/astaxie/beego" |
| | | "strings" |
| | | "sync" |
| | | "time" |
| | | ) |
| | |
| | | }() |
| | | } |
| | | |
| | | //批量解绑别名 |
| | | func UnbindAlias(cid string) (bool, error) { |
| | | var uc models.UserClient |
| | | ucList := uc.GetByCid(cid) |
| | | if ucList ==nil { |
| | | return true,errors.New("ucList is nil") |
| | | } |
| | | var aliasArr []string |
| | | for _,als := range ucList { |
| | | aliasArr = append(aliasArr, als.PhoneNum) |
| | | } |
| | | 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" |
| | | header := map[string]string { |
| | | "token": token, |
| | | } |
| | | caArr := make([]map[string]string, 0) |
| | | for _,as := range aliasArr { |
| | | caArr = append(caArr, map[string]string{ |
| | | "cid": cid, |
| | | "alias": as, |
| | | }) |
| | | } |
| | | |
| | | reqBody := map[string]interface{}{ |
| | | "data_list": caArr, |
| | | } |
| | | b,err := util.DoDeleteRequest(url, util.CONTENT_TYPE_UTF8_JSON, reqBody, 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"` |
| | |
| | | Token string `json:"token"` |
| | | } |
| | | |
| | | func Push(title string, msg string) (bool,error) { |
| | | 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" |
| | | androidPush := map[string]map[string]map[string]string { |
| | | "ups": { |
| | | "notification": { |
| | | "title": title, |
| | | "body": msg, |
| | | "big_text": msg, |
| | | "click_type": "intent", |
| | | "intent": intent, |
| | | }, |
| | | }, |
| | | } |
| | | iosPush := map[string]interface{}{ |
| | | "type":"notify", |
| | | "payload":"育英中学停车", |
| | | "aps":map[string]interface{}{ |
| | | "alert":map[string]string{ |
| | | "title": title, |
| | | "body": msg, |
| | | }, |
| | | "content-available":0, |
| | | }, |
| | | } |
| | | 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]interface{} { |
| | | "android": androidPush, |
| | | "ios":iosPush, |
| | | }, |
| | | } |
| | | 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, isTest bool) (bool, error, []string) { |
| | | 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 false,errors.New("len(pushUserM) == 0"),aliasArr |
| | | } |
| | | carPersonM := make(map[string]string) //以车牌号为key,value是hik的personId |
| | | csv := NewCarService() |
| | | carPersons := csv.GetVehicleListByPerson("") |
| | | if carPersons != nil { |
| | | for _, cp := range carPersons { |
| | | ncPlateNo := preDealPlateNo(cp.PlateNo) //去掉汉字,D和0替换成* |
| | | if ncPlateNo != "" { |
| | | carPersonM[ncPlateNo] = cp.PersonId |
| | | } |
| | | } |
| | | } |
| | | delPersonIdM := make(map[string]string) |
| | | spaceNos := csv.FindSpaceNo("") |
| | | for _,sn := range spaceNos { |
| | | if sn.State == 1 && sn.PlateNo != "" { //已经把车停到停车场的车主,不再推送消息 |
| | | realPlateNo := preDealPlateNo(sn.PlateNo) |
| | | if realPlateNo != "" { |
| | | if pId,ok := carPersonM[realPlateNo];ok { |
| | | delPersonIdM[pId] = pId |
| | | delete(carPersonM, realPlateNo) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | var uc models.UserClient |
| | | for _,personId := range carPersonM { |
| | | if phoneNum,ok := pushUserM[personId]; ok { //此人已注册到系统,并且车不在停车库内 |
| | | if _,in := delPersonIdM[personId];!in { |
| | | if uc.Exist(phoneNum) { |
| | | aliasArr = append(aliasArr, phoneNum) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | lenAS := len(aliasArr) |
| | | if lenAS == 0 { |
| | | return false, errors.New("没有推送目标,aliasArr is empty"),aliasArr |
| | | } |
| | | if isTest { |
| | | //只给内部手机号推 |
| | | testPhones := beego.AppConfig.String("testPushPhones") |
| | | if testPhones == "" { |
| | | return false, errors.New("test push aliasArr is empty"),aliasArr |
| | | } |
| | | aliasArr = strings.Split(testPhones, ",") |
| | | } |
| | | |
| | | cResult, taskId, ce := createPushMsg(title, msg) |
| | | fmt.Println("createPushMsg taskId:", taskId, "cResult:",cResult, "err:", ce) |
| | | if !cResult { |
| | | return false, errors.New("创建推送前置消息失败"),aliasArr |
| | | } |
| | | |
| | | //alias 单次推送长度上限是200 |
| | | pushTime := 1 |
| | | if lenAS > 200 { |
| | | pushTime = lenAS / 200 |
| | | if lenAS % 200 >0 { |
| | | pushTime++ |
| | | } |
| | | } |
| | | |
| | | isSuccess := false |
| | | for i:=0;i<pushTime;i++ { |
| | | var curAliasArr []string |
| | | start := i*200 |
| | | end := (i+1)*200 -1 |
| | | if i<pushTime-1 { |
| | | curAliasArr = aliasArr[start:end] |
| | | } else { |
| | | //取剩余所有 |
| | | curAliasArr = aliasArr[start:] |
| | | } |
| | | if len(curAliasArr) >0 { |
| | | flag, e := doPush(taskId, curAliasArr) |
| | | if e != nil { |
| | | fmt.Println("doPush err:", e) |
| | | } |
| | | if flag { |
| | | isSuccess = true |
| | | } |
| | | } |
| | | } |
| | | if isSuccess { |
| | | return true, nil,aliasArr |
| | | } |
| | | |
| | | return false, errors.New("推送失败"),aliasArr |
| | | } |
| | | |
| | | //预处理车牌号,去除首个汉字,以及忽略D和0 |
| | | func preDealPlateNo(pn string) string { |
| | | if pn != "" { |
| | | r := []rune(pn) |
| | | ncStr := string(r[1:]) |
| | | newPlateNo := strings.ReplaceAll(ncStr, "D", "*") |
| | | newPlateNo = strings.ReplaceAll(newPlateNo, "0", "*") |
| | | return newPlateNo |
| | | } |
| | | return "" |
| | | } |
| | | |
| | | func doPush(taskId string, aliasArr []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/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, []string, []string) { |
| | | var aliasArr []string |
| | | var carOwners []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 false, errors.New("len(pushUserM) == 0"), aliasArr, carOwners |
| | | } |
| | | carPersonM := make(map[string]string) |
| | | csv := NewCarService() |
| | | carPersons := csv.GetVehicleListByPerson("") |
| | | if carPersons != nil { |
| | | for _, cp := range carPersons { |
| | | cnPlateNo := preDealPlateNo(cp.PlateNo) |
| | | if cnPlateNo != "" { |
| | | carPersonM[cnPlateNo] = cp.PersonId |
| | | } |
| | | } |
| | | } |
| | | //夜间某些领导的车可以停在车库内 |
| | | var vipPlateNoArr []string |
| | | vipArr := strings.Split(beego.AppConfig.String("nightVipPlateNos"), ",") |
| | | if vipArr != nil && len(vipArr) >0 { |
| | | for _,po := range vipArr { |
| | | if po != "" { |
| | | cnPo := preDealPlateNo(po) |
| | | if cnPo != "" { |
| | | vipPlateNoArr = append(vipPlateNoArr, cnPo) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | hikPersonMap := csv.GetHikPersonMap() |
| | | |
| | | spaceNos := csv.FindSpaceNo("") |
| | | var uc models.UserClient |
| | | for _,sn := range spaceNos { |
| | | if sn.State == 1 { //车尚在停车场的车牌 |
| | | inCnPlateNo := preDealPlateNo(sn.PlateNo) |
| | | if inCnPlateNo != "" { |
| | | if !isVipCar(inCnPlateNo, vipPlateNoArr) { |
| | | if personId,ok := carPersonM[inCnPlateNo];ok { |
| | | if phoneNum,ok := pushUserM[personId]; ok { |
| | | if uc.Exist(phoneNum) { |
| | | aliasArr = append(aliasArr, phoneNum) |
| | | } |
| | | } |
| | | |
| | | if v,ex := hikPersonMap[personId]; ex { |
| | | carOwners = append(carOwners, v.PersonName) |
| | | } |
| | | } else { //找不到车主,即视为临时车,将车牌作为车主姓名推送 |
| | | carOwners = append(carOwners, sn.PlateNo) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | if len(aliasArr) == 0 { |
| | | fmt.Println("没有推送目标,aliasArr is empty") |
| | | return false, errors.New("没有推送目标,aliasArr is empty"), aliasArr, carOwners |
| | | } |
| | | |
| | | cResult, taskId, ce := createPushMsg(title, msg) |
| | | if !cResult { |
| | | fmt.Println("createPushMsg taskId:", taskId, "err:", ce) |
| | | return false, errors.New("创建推送前置消息失败"), aliasArr, carOwners |
| | | } |
| | | |
| | | b,e := doPush(taskId, aliasArr) |
| | | return b,e, aliasArr, carOwners |
| | | } |
| | | |
| | | //vip车主,不接收请离开的通知,也不通知管理员这个车还在车库内 |
| | | func isVipCar(targetPlateNo string, vipPlateNoArr []string) bool { |
| | | b := false |
| | | if vipPlateNoArr != nil { |
| | | for _,v := range vipPlateNoArr { |
| | | if targetPlateNo == v { |
| | | b = true |
| | | break |
| | | } |
| | | } |
| | | } |
| | | return b |
| | | } |
| | | |
| | | //如果夜间有给车库内的车主推送“请尽快驶离”的消息,则告知管理员 有哪些车尚停在车库内 |
| | | func Push2Manager(title string, msg string) (bool, error, []string) { |
| | | if len(msg) > 256 { |
| | | fmt.Println("夜间停留车太多,message:", msg) |
| | | |
| | | r := []rune(msg) |
| | | msg = string(r[:125])+"..." |
| | | } |
| | | managers := beego.AppConfig.String("nightManagerPhones") |
| | | if managers == "" { |
| | | return false, errors.New("夜间推送管理员手机号未配置"), []string{} |
| | | } |
| | | managerArr := strings.Split(managers, ",") |
| | | if len(managerArr) == 0 { |
| | | fmt.Println("没有推送目标,managerArr is empty") |
| | | return false, errors.New("管理员手机号未配置"), managerArr |
| | | } |
| | | |
| | | cResult, taskId, ce := createPushMsg(title, msg) |
| | | if !cResult { |
| | | fmt.Println("createPushMsg taskId:", taskId, "err:", ce) |
| | | return false, errors.New("创建推送前置消息失败"), managerArr |
| | | } |
| | | |
| | | b,e := doPush(taskId, managerArr) |
| | | return b,e, managerArr |
| | | } |
| | | |
| | | /* |
| | | func PushAll(title string, msg string) (bool,error) { |
| | | appId := beego.AppConfig.String("pushAppId") |
| | | baseUrl := beego.AppConfig.String("pushBaseUrl") + appId |
| | | retryTimes := 0 |
| | |
| | | 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" |
| | | androidPush := map[string]map[string]map[string]string { |
| | | "ups": { |
| | | "notification": { |
| | | "title": title, |
| | | "body": msg, |
| | | "click_type": "intent", |
| | | "intent": intent, |
| | | }, |
| | | }, |
| | | } |
| | | iosPush := map[string]interface{}{ |
| | | "type":"notify", |
| | | "payload":"育英中学停车", |
| | | "aps":map[string]interface{}{ |
| | | "alert":map[string]string{ |
| | | "title": title, |
| | | "body": msg, |
| | | }, |
| | | "content-available":0, |
| | | //"sound":"com.gexin.ios.silence", |
| | | //"category":"ACTIONABLE", |
| | | }, |
| | | "auto_badge":"+1", |
| | | } |
| | | reqBody := map[string]interface{} { |
| | | "request_id": time.Now().Format("20060102150405") + util.GenValidateCode(6), |
| | | "settings":map[string]int { |
| | |
| | | "notification": { |
| | | "title": title, |
| | | "body": msg, |
| | | "click_type": "url", |
| | | "url": "http://baidu.com", |
| | | "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": "url", |
| | | "url": "http://baidu.com", |
| | | }, |
| | | }, |
| | | }, |
| | | "push_channel": map[string]interface{} { |
| | | "android": androidPush, |
| | | "ios": iosPush, |
| | | }, |
| | | } |
| | | header := map[string]string { |
| | |
| | | } |
| | | |
| | | return false, errors.New("推送失败") |
| | | } |
| | | }*/ |
| | | |
| | | func RefreshToken() (*TokenResult,error) { |
| | | appId := beego.AppConfig.String("pushAppId") |