liuxiaolong
2020-08-10 9358e5ec2d2b65fec4ef9a1be7d1a1e1e2cf9d2d
new push schedule
8个文件已修改
487 ■■■■■ 已修改文件
conf/app.conf 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
controllers/car.go 52 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
controllers/user.go 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
extend/util/httpUtil.go 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/car.go 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/carService.go 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/msgPush.go 358 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/userService.go 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
conf/app.conf
@@ -7,8 +7,6 @@
sqlconn =
gendoc = true
downdoc = true
latestVersion = 1.0.1
latestUrl = http://www.baidu.com
juheweihaokey = 8c0efc4439080ef6c6aa2c29688c9550
pushAppId = WfOtCAmf0w6jS3B59V0mb5
pushAppKey = hVBAHDe85F9ZviAUYknxb4
@@ -20,3 +18,4 @@
hikUrl = https://172.16.35.49:443
hikAppKey = 26577698
hikAppSecret = ZHhxujl06e0e5jsJLaiB
pushLowerLimit = 5
controllers/car.go
@@ -17,11 +17,17 @@
}
//实时计算剩余车位数量,达到条件就推送
//要求:
//1.停车数量小于等于5个推送,5个以下的数量变化都推送,推送给已注册手机号的用户,未注册的不推
//2.满足上一条,如果此车辆已经进入学校停车场了,就不再给这个车牌对应的手机号推送空余车位消息
//3.晚上10点到10点半,每间隔10分钟,给停车场内的车辆推送消息:请尽快驶出停车场
func ComputeSpaceLeftRealTime() {
    ticker := time.NewTicker(3 * time.Second)
    prePushLeft := 0
    sv := service.NewCarService()
    initCacheM := false
    lowerLimit,_ := beego.AppConfig.Int("pushLowerLimit") //[0,5]
    nightPushTimes := 0
    for {
        select {
            case <-ticker.C:
@@ -29,13 +35,14 @@
                if flag {
                    left := hikSta.Left
                    if !initCacheM {
                        models.SetSpaceNo(hikSta.TotalPermPlace)
                        models.SetSpaceNo(hikSta.TotalPlace)
                        initCacheM = true
                    }
                    if left <=5 && left != prePushLeft {
                    if left <=lowerLimit && left != prePushLeft {
                        go func() {
                            message := fmt.Sprintf("%s 剩余车位:%d个", time.Now().Format("2006-01-02 15:04:05"), left)
                            b, e := service.Push("育英智慧停车", message)
                            b, e := service.PushByAlias("育英智慧停车", message)
                            prePushLeft = left
@@ -44,11 +51,47 @@
                    }
                    updateSpaceLeft(left)
                }
                //判断当前是否在22:00-22:30之间
                now := time.Now()
                if now.Hour() == 21 && now.Minute()>=0 || now.Minute() <=29{
                    if now.Minute() == 0 {
                        if nightPushTimes ==0 {
                            go nightPush()
                            nightPushTimes++
                        }
                    } else if now.Minute() == 10 {
                        if nightPushTimes == 1 {
                            go nightPush()
                            nightPushTimes++
                        }
                    } else if now.Minute() == 20 {
                        if nightPushTimes == 2{
                            go nightPush()
                            nightPushTimes++
                        }
                    } else if now.Minute() == 29 {
                        if nightPushTimes == 3{
                            go nightPush()
                            nightPushTimes++
                        }
                    }
                } else {
                    nightPushTimes = 0
                }
        default:
            time.Sleep(500 * time.Millisecond)
        }
    }
}
func nightPush(){
    message := fmt.Sprintf("%s 请尽快驶出停车场", time.Now().Format("2006-01-02 15:04:05"))
    b, e := service.NightPush("育英智慧停车", message)
    fmt.Println("b:", b,"e:",e, "message:", message)
}
var cacheSpaceLeft int
@@ -70,9 +113,6 @@
// @Failure 403 {string} json ""
// @router /statistic [get]
func (c *CarController) Statistic() {
    //sv := service.NewCarService()
    //hikStc := sv.Statistic()
    //left := hikStc.Left
    left := getSpaceLeft()
    sta := models.CarStatistic{
        Left: left,
controllers/user.go
@@ -63,15 +63,16 @@
func (u *UserController) Login() {
    phoneNum := u.GetString("phoneNum")
    cod := u.GetString("code")
    cid := u.GetString("cid")  //unipush clientid
    resp := code.Code{}
    fmt.Println("phoneNum:", phoneNum, "code:", cod)
    if phoneNum == "" || cod == "" {
    if phoneNum == "" || cod == ""{
        resp.Success= false
        resp.Status= http.StatusBadRequest
        resp.Data= "参数有误"
    } else {
        var sv service.UserService
        b, info, e := sv.Login(phoneNum, cod)
        b, info, e := sv.Login(phoneNum, cod, cid)
        if b {
            resp.Success= true
extend/util/httpUtil.go
@@ -79,4 +79,39 @@
        return resultBytes, err
    }
    return resultBytes, nil
}
//构造delete请求
func DoDeleteRequest(url string, contentType string, body map[string]interface{}, headers map[string]string) ([]byte, error) {
    var resultBytes []byte
    var bodyJson []byte
    if body != nil {
        var err error
        bodyJson, err = json.Marshal(body)
        if err != nil {
            return resultBytes, err
        }
    }
    request, err := http.NewRequest("DELETE", url, bytes.NewBuffer(bodyJson))
    if err != nil {
        return resultBytes, err
    }
    request.Header.Set("Content-type", contentType)
    // add headers
    if headers != nil {
        for key, val := range headers {
            request.Header.Add(key, val)
        }
    }
    client := &http.Client{}
    resp, err := client.Do(request)
    if err != nil {
        return resultBytes, err
    }
    defer resp.Body.Close()
    resultBytes, err = ioutil.ReadAll(resp.Body)
    if err != nil {
        return resultBytes, err
    }
    return resultBytes, nil
}
models/car.go
@@ -25,8 +25,8 @@
}
type CarStatistic struct {
    TotalPermPlace         int         `json:"totalPermPlace"`
    Left                   int         `json:"left"`
    TotalPlace int `json:"totalPlace"`
    Left       int `json:"left"`
}
type PosInfo struct {
service/carService.go
@@ -25,14 +25,14 @@
func (sv *CarService) Statistic() (*models.CarStatistic, bool) {
    m := models.CarStatistic{
        TotalPermPlace: 0,
        Left:           0,
        TotalPlace: 0,
        Left:       0,
    }
    remainList := sv.getRemainSpaceNum("")
    if remainList != nil {
        for _,r:=range remainList {
            m.TotalPermPlace += r.TotalPermPlace
            m.TotalPlace += r.TotalPlace
            m.Left += r.LeftPlace
        }
        return &m, true
@@ -145,11 +145,13 @@
func (sv *CarService) FindSpaceNo(userId string) models.PosResult {
    resultList := make(models.PosResult,0)
    var myPlateNosMap = make(map[string]string)
    vehicles := sv.GetVehicleListByPerson(userId)
    if vehicles != nil {
        for _,veh := range vehicles {
            myPlateNosMap[veh.PlateNo] = veh.PlateNo
            //myPlateNos = append(myPlateNos, veh.PlateNo)
    if userId !="" {
        vehicles := sv.GetVehicleListByPerson(userId)
        if vehicles != nil {
            for _,veh := range vehicles {
                myPlateNosMap[veh.PlateNo] = veh.PlateNo
                //myPlateNos = append(myPlateNos, veh.PlateNo)
            }
        }
    }
@@ -347,7 +349,7 @@
    url := "/artemis/api/resource/v2/vehicle/advance/vehicleList"
    reqBody := map[string]interface{} {
        "pageNo": 1,
        "pageSize": 100,
        "pageSize": 1000,
        "personIds": personId,
    }
    pageResult := sv.getHikPageResult(url, reqBody)
service/msgPush.go
@@ -2,6 +2,7 @@
import (
    "car-service/extend/util"
    "car-service/models"
    "encoding/json"
    "errors"
    "fmt"
@@ -45,6 +46,94 @@
    }()
}
//解绑所有与该别名绑定的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"`
@@ -56,7 +145,274 @@
    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"
    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,nil
    }
    carPersonM := make(map[string]string)
    var csv CarService
    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 _,ok := carPersonM[sn.PlateNo];ok {
                delete(carPersonM, sn.PlateNo)
            }
        }
    }
    for _,personId := range carPersonM {
        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 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)
    var csv CarService
    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
service/userService.go
@@ -16,7 +16,7 @@
}
func (sv *UserService) Login(phoneNum, code string) (bool,*vo.UserInfo,error) {
func (sv *UserService) Login(phoneNum, code, cid string) (bool,*vo.UserInfo,error) {
    if verifyCode(phoneNum, code) {
        carSv := NewCarService()
@@ -54,6 +54,10 @@
                        plateNos = append(plateNos, up.PlateNo)
                    }
                }
                //客户端cid绑定别名
                if cid != "" {
                    go BindAlias(cid, phoneNum)
                }
                return true, &vo.UserInfo{
                    UserId: u.Id,
                    PhoneNum: phoneNum,
@@ -72,6 +76,10 @@
                    plateNos = append(plateNos, up.PlateNo)
                }
            }
            //客户端cid绑定别名
            if cid != "" {
                go BindAlias(cid, phoneNum)
            }
            return true, &vo.UserInfo{
                UserId: tmpUser.Id,
                PhoneNum: phoneNum,