Commit 426ff5de by zhangjiec

1

parent 5eb4784d
......@@ -11,14 +11,18 @@ import (
"strconv"
)
type apiCardBindStruct struct {
Code string `json:"code"` // 必填,卡号
Type uint8 `json:"type" example:"1"` // 必填,卡类型:1电话卡,2定位卡,3IC卡(饮水、消费、洗浴、洗衣机均为IC卡,固任何一个服务的卡挂失状态改变,其余也跟随改变)
}
// CardBind 绑定卡
// @Tags 家长微信
// @Summary 绑定卡 [complete]
// @Description 传学生id及卡类型、卡号至后台,后台返回成功失败
// @Produce json
// @Param id path integer true "学生ID"
// @Param code query string true "卡号"
// @Param type query integer true "卡类型:1电话卡,2定位卡,3IC卡(饮水、消费、洗浴、洗衣机均为IC卡,固任何一个服务的卡挂失状态改变,其余也跟随改变)"
// @Param data body apiCardBindStruct true "绑定的卡号及卡类型数据"
// @Success 0
// @Router /we/cardbind/{id} [PUT]
// @Security ApiKeyAuth
......@@ -56,7 +60,17 @@ func CardBind(c *gin.Context) {
return
}
if c.Query("type") != "1" {
var reqData apiCardBindStruct
err := c.ShouldBindJSON(&reqData)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqParaFormat,
"message": api.CodeMsg[api.ErrorReqParaFormat],
})
return
}
if reqData.Type != 1 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara,
"message": api.CodeMsg[api.ErrorReqPara] + " type暂时只支持1",
......@@ -64,8 +78,7 @@ func CardBind(c *gin.Context) {
return
}
simID := c.Query("code")
if len(simID) == 0 {
if len(reqData.Code) == 0 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara,
"message": api.CodeMsg[api.ErrorReqPara] + " code不能为空",
......@@ -73,19 +86,22 @@ func CardBind(c *gin.Context) {
return
}
//if len(cardUserInfo.SimCardID)>0{
// if cardUserInfo.SimCardID == simID {
//
// }
// c.JSON(http.StatusOK, gin.H{
// "code": api.ErrorReqPara,
// "message": "错误:已绑卡号"+cardUserInfo.SimCardID,
// })
// return
//}
if len(cardUserInfo.SimCardID) > 0 {
if cardUserInfo.SimCardID == reqData.Code {
c.JSON(http.StatusOK, gin.H{
"code": api.Success,
})
return
}
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara,
"message": "错误:已绑卡号" + cardUserInfo.SimCardID,
})
return
}
// 获取sim卡信息
simInfo := cache.GetSimInfo(simID)
simInfo := cache.GetSimInfo(reqData.Code)
if simInfo == nil {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara,
......@@ -127,12 +143,12 @@ func CardBind(c *gin.Context) {
}
// 操作数据库
if dbcurd.UpdateUSimInfoCardUserID(simID, cardUserID) {
if dbcurd.UpdateUSimInfoCardUserID(reqData.Code, cardUserID) {
// CardUserMap SimInfoMap 并发不安全
cardUserInfo.SimCardID = simID
cardUserInfo.SimCardID = reqData.Code
cache.CardUserMap.Store(cardUserID, *cardUserInfo) // todo 并发不安全 所有的store delete都封装一下
simInfo.CardUserID = cardUserID
cache.SimInfoMap.Store(simID, *simInfo)
cache.SimInfoMap.Store(reqData.Code, *simInfo)
c.JSON(http.StatusOK, gin.H{
"code": api.Success,
......
......@@ -11,14 +11,18 @@ import (
"strconv"
)
type apiCardLossStruct struct {
Loss uint8 `json:"loss" example:"2"` // 1解挂,2挂失,其他预留无意义
Type uint8 `json:"type" example:"1"` // 卡类型:1电话卡,2定位卡,3IC卡(饮水、消费、洗浴、洗衣机均为IC卡,固任何一个服务的卡挂失状态改变,其余也跟随改变)
}
// CardLoss 卡挂失/解挂
// @Tags 家长微信
// @Summary 卡挂失/解挂 [complete]
// @Description 传学生id及卡类型至后台,后台返回成功失败
// @Produce json
// @Param id path integer true "学生ID"
// @Param loss query integer true "1解挂,2挂失,其他预留无意义"
// @Param type query integer true "卡类型:1电话卡,2定位卡,3IC卡(饮水、消费、洗浴、洗衣机均为IC卡,固任何一个服务的卡挂失状态改变,其余也跟随改变)" default(1)
// @Param data body apiCardLossStruct true " "
// @Success 0
// @Router /we/cardloss/{id} [PUT]
// @Security ApiKeyAuth
......@@ -46,7 +50,17 @@ func CardLoss(c *gin.Context) {
return
}
if c.Query("type") != "1" {
var reqData apiCardLossStruct
err := c.ShouldBindJSON(&reqData)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqParaFormat,
"message": api.CodeMsg[api.ErrorReqParaFormat],
})
return
}
if reqData.Type != 1 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara,
"message": api.CodeMsg[api.ErrorReqPara] + " type暂时只支持1",
......@@ -54,8 +68,7 @@ func CardLoss(c *gin.Context) {
return
}
status, _ := strconv.ParseUint(c.Query("loss"), 10, 8)
if status == 0 || status > 2 {
if reqData.Loss == 0 || reqData.Loss > 2 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara,
"message": api.CodeMsg[api.ErrorReqPara] + " loss内容不正确",
......@@ -87,7 +100,7 @@ func CardLoss(c *gin.Context) {
return
}
if dbcurd.UpdateUSimInfoStatus(userInfo.SimCardID, uint8(status)) == false {
if dbcurd.UpdateUSimInfoStatus(userInfo.SimCardID, reqData.Loss) == false {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorSystemBusy,
"data": api.CodeMsg[api.ErrorSystemBusy],
......@@ -97,7 +110,7 @@ func CardLoss(c *gin.Context) {
simInfo := cache.GetSimInfo(userInfo.SimCardID)
if simInfo != nil { // 这里并发不安全
simInfo.Status = uint8(status)
simInfo.Status = reqData.Loss
cache.SimInfoMap.Store(userInfo.SimCardID, *simInfo)
c.JSON(http.StatusOK, gin.H{
"code": api.Success,
......
......@@ -11,10 +11,10 @@ import (
"net/http"
)
type creatCardUserRes struct {
ID uint32 `json:"id"` // 新创建的学生ID
Service [6]uint8 `json:"service" example:"1,2,2,2,2,2"` // 对应6个数字对应公话、定位、饮水、卡消费、洗浴、洗衣机图标(0不显示,1正常,2显示但提示校区暂未开通该服务)
}
//type creatCardUserRes struct {
// ID uint32 `json:"id"` // 新创建的学生ID
// // Service [6]uint8 `json:"service" example:"1,2,2,2,2,2"` // 对应6个数字对应公话、定位、饮水、卡消费、洗浴、洗衣机图标(0不显示,1正常,2显示但提示校区暂未开通该服务)
//}
// CreateCardUser 创建一个学生
// @Tags 家长微信
......@@ -22,8 +22,8 @@ type creatCardUserRes struct {
// @Description 传新建学生信息至后台,后台返回学生id,以及对应校区的service
// @Accept json
// @Produce json
// @Param data body dbcurd.InsertTableUCardUserStruct true "学生信息"
// @Success 0 {object} creatCardUserRes
// --@Param data body dbcurd.InsertTableUCardUserStruct true "学生信息"
// @Success 0
// @Router /we/carduser [POST]
// @Security ApiKeyAuth
func CreateCardUser(c *gin.Context) {
......@@ -77,9 +77,9 @@ func CreateCardUser(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": api.Success,
"data": creatCardUserRes{
newID,
[6]uint8{1, 2, 2, 2, 2, 2},
},
//"data": creatCardUserRes{
// newID,
// // [6]uint8{1, 2, 2, 2, 2, 2},
//},
})
}
......@@ -11,13 +11,17 @@ import (
"strconv"
)
type apiDeleteCardBindStruct struct {
Type uint8 `json:"type" example:"1"` //卡类型:1电话卡,2定位卡,3IC卡(饮水、消费、洗浴、洗衣机均为IC卡,固任何一个服务的卡挂失状态改变,其余也跟随改变)
}
// DeleteCardBind 解绑卡
// @Tags 家长微信
// @Summary 解绑卡 [complete]
// @Description 传学生id及卡类型至后台,后台返回成功失败
// @Produce json
// @Param id path integer true "学生ID"
// @Param type query integer true "卡类型:1电话卡,2定位卡,3IC卡(饮水、消费、洗浴、洗衣机均为IC卡,固任何一个服务的卡挂失状态改变,其余也跟随改变)"
// @Param data body apiDeleteCardBindStruct true " "
// @Success 0
// @Router /we/cardbind/{id} [DELETE]
// @Security ApiKeyAuth
......@@ -55,7 +59,17 @@ func DeleteCardBind(c *gin.Context) {
return
}
if c.Query("type") != "1" {
var reqData apiDeleteCardBindStruct
err := c.ShouldBindJSON(&reqData)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqParaFormat,
"message": api.CodeMsg[api.ErrorReqParaFormat],
})
return
}
if reqData.Type != 1 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara,
"message": api.CodeMsg[api.ErrorReqPara] + " type暂时只支持1",
......
package api_we
import (
"dc_golang_server_1/api"
"dc_golang_server_1/data_db_cache/cache"
"dc_golang_server_1/data_db_cache/dbcurd"
"dc_golang_server_1/logger"
"fmt"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"net/http"
"strconv"
)
type apiDeleteFamilyNumStruct struct {
Phone string `json:"phone"` // 必填
}
// DeleteFamilyNum 删除亲情号
// @Tags 家长微信
// @Summary 删除亲情号 [complete]
// @Description 删除亲情号接口
// @Accept json
// @Produce json
// @Param id path integer true "学生ID"
// @Param data body apiDeleteFamilyNumStruct true "电话号码"
// @Success 0
// @Router /we/familynum/{id} [DELETE]
// @Security ApiKeyAuth
func DeleteFamilyNum(c *gin.Context) {
cardUserIDInt, _ := strconv.ParseUint(c.Param("id"), 10, 32)
cardUserID := uint32(cardUserIDInt)
if cardUserID == 0 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara,
"message": api.CodeMsg[api.ErrorReqPara] + " id不正确",
})
return
}
// 取微信用户
v, ok := c.Get("userID")
weUserID := v.(uint32)
if ok != true || weUserID == 0 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorSystemErr,
"data": api.CodeMsg[api.ErrorSystemErr],
})
logger.Log.Error("AddFamilyNum",
zap.Reflect("c.Get(\"userID\")", v))
return
}
// 校验weUserID是否有cardUserID权限
cardUserInfo, r := cache.GetCardUserInfoAndCheckCardUserMaserAndSlaveWeID(cardUserID, weUserID)
if r < 2 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorUserRole,
"data": api.CodeMsg[api.ErrorUserRole],
})
return
}
if cardUserInfo.SimCardID == "" { // 学生未绑卡
c.JSON(
http.StatusOK,
gin.H{
"code": api.ErrorUserNotHavePhoneCard,
"data": api.CodeMsg[api.ErrorUserNotHavePhoneCard] + ",请先绑定共话卡",
},
)
return
}
// 查卡的信息
simInfoP := cache.GetSimInfo(cardUserInfo.SimCardID)
if simInfoP == nil {
fmt.Println("居然查不到卡信息 cardUserInfo.SimCardID:", cardUserInfo.SimCardID)
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorSystemErr,
"message": api.CodeMsg[api.ErrorSystemErr] + "查不到sim卡信息",
})
return
}
if simInfoP.FamilyDeleteCount < 1 { // 每个月修改亲情号次数不得超过2次
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorMonthDeleteFamilyNumOverrun,
"message": api.CodeMsg[api.ErrorMonthDeleteFamilyNumOverrun],
})
return
}
var reqData apiDeleteFamilyNumStruct
err := c.ShouldBindJSON(&reqData)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqParaFormat,
"message": api.CodeMsg[api.ErrorReqParaFormat],
})
return
}
for i, family := range simInfoP.FamilyNum {
if family.Phone == reqData.Phone {
// 找移动删除亲情号 todo
// 考虑这下面的操作用事务处理成功了,再去找移动删,但是这样就要单独整个任务专门找移动搞,通过channel丢过去
// 本月删除亲情号次数加1
newCount := dbcurd.UpdateUSimInfoAddFamilyDeleteCount(cardUserInfo.SimCardID)
if newCount != simInfoP.FamilyDeleteCount-1 {
logger.Log.Error("map里面simInfo.FamilyDeleteCount 跟数据库对不上",
zap.String("simID", cardUserInfo.SimCardID),
zap.Int8("simInfoP.FamilyDeleteCount", simInfoP.FamilyDeleteCount-1),
zap.Int8("db", newCount))
}
simInfoP.FamilyDeleteCount = newCount
// 删库
if dbcurd.DeleteUSimFamilyNum(cardUserInfo.SimCardID, reqData.Phone) == false {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorSystemBusy,
"message": api.CodeMsg[api.ErrorSystemBusy] + "更新删除失败",
})
return
}
simInfoP.FamilyNum = append(simInfoP.FamilyNum[:i], simInfoP.FamilyNum[i+1:]...)
cache.SimInfoMap.Store(cardUserInfo.SimCardID, *simInfoP)
c.JSON(http.StatusOK, gin.H{
"code": api.Success,
})
return
}
}
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara,
"message": api.CodeMsg[api.ErrorReqPara] + "未找到号码" + reqData.Phone,
})
}
......@@ -58,71 +58,3 @@ func DeleteSlaveBindCardUser(c *gin.Context) {
"code": api.Success,
})
}
// MasterDeleteSlaveWeUser 删除副家长(仅主家长有权限)
// @Tags 家长微信
// @Summary 删除副家长(仅主家长有权限) [complete]
// @Description 传学生ID和微信UnionID,后台返回成功失败
// @Produce json
// @Param id path integer true "学生ID"
// @Param weUserID query integer true "副家长微信weUserID"
// @Success 0
// @Router /we/slaveweuser/{id} [DELETE]
// @Security ApiKeyAuth
func MasterDeleteSlaveWeUser(c *gin.Context) {
cardUserIDInt, _ := strconv.ParseUint(c.Param("id"), 10, 32)
cardUserID := uint32(cardUserIDInt)
if cardUserID == 0 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara,
"message": api.CodeMsg[api.ErrorReqPara] + " id不正确",
})
return
}
// 取微信用户
v, ok := c.Get("userID")
masterWeUserID := v.(uint32)
if ok != true || masterWeUserID == 0 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorSystemErr,
"data": api.CodeMsg[api.ErrorSystemErr],
})
logger.Log.Error("DeleteSlaveBindCardUser",
zap.Reflect("c.Get(\"userID\")", v))
return
}
// 校验weUserID是否有cardUserID权限
if cache.CheckCardUserMaserAndSlaveWeID(cardUserID, masterWeUserID) != 2 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorUserRole,
"data": api.CodeMsg[api.ErrorUserRole],
})
return
}
weUserIDInt, _ := strconv.ParseUint(c.Query("weUserID"), 10, 32)
weUserID := uint32(weUserIDInt)
if weUserID == 0 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara,
"message": api.CodeMsg[api.ErrorReqPara] + "副家长ID不正确",
})
return
}
if dbcurd.UpdateUWeCardUserDeleteAt(weUserID, cardUserID) == false {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorSystemBusy,
"data": api.CodeMsg[api.ErrorSystemBusy],
})
}
cache.DeleteAStudentIDInWechatCustomerMap(weUserID, cardUserID, false)
cache.DeleteASlaveWeUserIDInCardUserMap(weUserID, cardUserID)
c.JSON(http.StatusOK, gin.H{
"code": api.Success,
})
}
......@@ -67,12 +67,13 @@ func GetCardUser(c *gin.Context) {
"code": api.Success,
"data": GetCardUserInfoRes{
WeResUserInfoStruct: WeResUserInfoStruct{
ID: cardUserID,
Name: cardUserInfo.Name,
Sex: cardUserInfo.Sex,
Grade: cardUserInfo.Grade,
Class: cardUserInfo.Class,
StuNum: cardUserInfo.StuNum,
cardUserID,
cardUserInfo.Name,
cardUserInfo.Sex,
cache.GetAreaMapName(cardUserInfo.AreaID, true),
cardUserInfo.Grade,
cardUserInfo.Class,
cardUserInfo.StuNum,
},
Service: [6]uint8{1, 2, 2, 2, 2, 2},
},
......
......@@ -3,7 +3,6 @@ package api_we
import (
"dc_golang_server_1/api"
"dc_golang_server_1/data_db_cache/cache"
"dc_golang_server_1/data_db_cache/dbcurd"
"dc_golang_server_1/logger"
"dc_golang_server_1/util"
"github.com/gin-gonic/gin"
......@@ -75,7 +74,7 @@ func GetCardUserShareCode(c *gin.Context) {
return
}
eTime := uint32(time.Now().Second()) + uint32(timeMin)*60
eTime := uint32(time.Now().Unix()) + uint32(timeMin)*60
r := rand.New(rand.NewSource(time.Now().UnixNano()))
var clear = make([]byte, 11)
......@@ -98,190 +97,3 @@ func GetCardUserShareCode(c *gin.Context) {
"data": util.EncryptBytesToBase64URL(clear, "Password88OhYeah"),
})
}
type BindCardUserRes struct {
GetCardUserAndTrendRes
Master bool `json:"master" example:"false"` //true:本来就是主家长,false:已成功绑定成副家长
}
// BindCardUser 通过邀请码绑定学生
// @Tags 家长微信
// @Summary 通过邀请码绑定学生 [complete]
// @Description 传学生的邀请码,后台返回学生信息
// @Produce json
// @Param share_code path string true "学生的邀请码"
// @Success 0 {object} BindCardUserRes "学生信息"
// @Failure 30 "邀请码无效"
// @Failure 31 "邀请码已过期"
// @Router /we/bindcarduser/{share_code} [POST]
// @Security ApiKeyAuth
func BindCardUser(c *gin.Context) {
str := c.Param("share_code")
if len(str) == 16 {
// todo logger 有人在非法请求
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorShareCode,
"message": api.CodeMsg[api.ErrorShareCode],
})
}
clear, err := util.DecryptBase64URLToBytes(str, "Password88OhYeah")
if err != nil {
// todo logger 有人在非法请求
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorShareCode,
"message": api.CodeMsg[api.ErrorShareCode],
})
return
}
if len(clear) != 11 {
// todo logger 有人在非法请求
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorShareCode,
"message": api.CodeMsg[api.ErrorShareCode],
})
return
}
clear[9] += clear[2]
clear[10] -= clear[2]
if util.CheckCRC(clear) == false {
// todo logger 有人在非法请求
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorShareCode,
"message": api.CodeMsg[api.ErrorShareCode],
})
return
}
//clear[5] = byte(eTime)
//clear[1] = byte(eTime >> 8)
//clear[0] = byte(eTime >> 16)
//clear[3] = byte(eTime >> 24)
//clear[7] = byte(cardUserID)
//clear[4] = byte(cardUserID >> 8)
//clear[6] = byte(cardUserID >> 16)
//clear[8] = byte(cardUserID >> 24)
eTime := uint32(clear[5]) + (uint32(clear[1]) << 8) + (uint32(clear[0]) << 16) + (uint32(clear[3]) << 24)
if eTime > uint32(time.Now().Second()) {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorShareCodeRunTime,
"message": api.CodeMsg[api.ErrorShareCodeRunTime],
})
return
}
cardUserID := uint32(clear[7]) + (uint32(clear[4]) << 8) + (uint32(clear[6]) << 16) + (uint32(clear[8]) << 24)
if cardUserID == 0 {
// todo logger 有人在非法请求
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorShareCode,
"message": api.CodeMsg[api.ErrorShareCode],
})
return
}
cardUserInfo := cache.GetCardUserInfo(cardUserID)
if cardUserInfo == nil {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorShareCode,
"message": api.CodeMsg[api.ErrorShareCode],
})
return
}
// 取微信用户
v, ok := c.Get("userID")
weUserID := v.(uint32)
if ok != true || weUserID == 0 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorSystemErr,
"data": api.CodeMsg[api.ErrorSystemErr],
})
logger.Log.Error("BindCardUser",
zap.Reflect("c.Get(\"userID\")", v))
return
}
if cardUserInfo.MasterWechatUserID == weUserID { // 本来就是主家长
c.JSON(http.StatusOK, gin.H{
"code": api.Success,
"data": BindCardUserRes{
Master: true,
GetCardUserAndTrendRes: GetCardUserAndTrendRes{
WeResUserInfoStruct: WeResUserInfoStruct{
ID: cardUserID,
Name: cardUserInfo.Name,
Sex: cardUserInfo.Sex,
Grade: cardUserInfo.Grade,
Class: cardUserInfo.Class,
StuNum: cardUserInfo.StuNum,
},
Service: [6]uint8{1, 2, 2, 2, 2, 2},
Trend: cache.GetCardUserTrendMapByCardUserID(cardUserID),
},
},
})
return
}
for _, slave := range cardUserInfo.SlaveWechatUserID {
if weUserID == slave { // 本来就是副家长
c.JSON(http.StatusOK, gin.H{
"code": api.Success,
"data": BindCardUserRes{
Master: false,
GetCardUserAndTrendRes: GetCardUserAndTrendRes{
WeResUserInfoStruct: WeResUserInfoStruct{
ID: cardUserID,
Name: cardUserInfo.Name,
Sex: cardUserInfo.Sex,
Grade: cardUserInfo.Grade,
Class: cardUserInfo.Class,
StuNum: cardUserInfo.StuNum,
},
Service: [6]uint8{1, 2, 2, 2, 2, 2},
Trend: cache.GetCardUserTrendMapByCardUserID(cardUserID),
},
},
})
return
}
}
// 存数据库
if dbcurd.InsertOrUpdateUWeCardUserSlave(weUserID, cardUserID) == false {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorSystemBusy,
"data": api.CodeMsg[api.ErrorSystemBusy],
})
}
// 存缓存
cache.InsertNewStudentIDToWechatCustomerMap(weUserID, cardUserID, false)
cache.InsertWechatAndCardUserRelationToCardUserMap(weUserID, cardUserID, false)
cardUserInfo = cache.GetCardUserInfo(cardUserID)
if cardUserInfo == nil { // 刚才都有,在就没有了呢
logger.Log.Error("BindCardUser cache.GetCardUserInfo(cardUserID) 突然没有了",
zap.Uint32("cardUserID", cardUserID),
zap.Uint32("weUserID", weUserID))
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorSystemErr,
"message": api.CodeMsg[api.ErrorSystemErr],
})
return
}
c.JSON(http.StatusOK, gin.H{
"code": api.Success,
"data": BindCardUserRes{
Master: false,
GetCardUserAndTrendRes: GetCardUserAndTrendRes{
WeResUserInfoStruct: WeResUserInfoStruct{
ID: cardUserID,
Name: cardUserInfo.Name,
Sex: cardUserInfo.Sex,
Grade: cardUserInfo.Grade,
Class: cardUserInfo.Class,
StuNum: cardUserInfo.StuNum,
},
Service: [6]uint8{1, 2, 2, 2, 2, 2},
Trend: cache.GetCardUserTrendMapByCardUserID(cardUserID),
},
},
})
}
......@@ -9,6 +9,7 @@ import (
"go.uber.org/zap"
"net/http"
"strconv"
"time"
)
//type getPhoneCardStatusRes struct {
......@@ -90,6 +91,10 @@ func GetPhoneCardStatus(c *gin.Context) {
}
res := cache.GetSimInfo(cardUserInfo.SimCardID)
// 服务已过期
if time.Now().After(res.ExpiryAt) && res.Status == 1 {
res.Status = 3
}
if res != nil {
c.JSON(
http.StatusOK,
......
......@@ -5,40 +5,26 @@ import (
"dc_golang_server_1/data_db_cache/cache"
"dc_golang_server_1/data_db_cache/dbcurd"
"dc_golang_server_1/data_db_cache/model"
"dc_golang_server_1/logger"
tencent2 "dc_golang_server_1/tencent"
"dc_golang_server_1/thirdapi/tencent"
"fmt"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"net/http"
"time"
)
type WeResUserInfoStruct struct {
ID uint32 `json:"id"` // 学生ID
Name string `json:"name"`
Sex uint8 `json:"sex"` // 0无意义 1女 2男
Area string `json:"area" example:"温江实验中学"` // 区域名字
Grade int8 `json:"grade"` // 0无意义 "1~9对应一年级~九年级,10~12对应高一~高三"
Class int8 `json:"class"` // 0无意义
StuNum string `json:"stuNum"` // ""无意义
// Service [6]uint8 `json:"service" example:"1,2,2,0,0,0"` // 对应6个数字对应公话、定位、饮水、卡消费、洗浴、洗衣机图标(0不显示,1正常,2显示但提示校区暂未开通该服务)
// TopUp bool `json:"topUp"` // 是否已充值(已充值则不能删除,未充值可以删除)
}
type weUserListStruct struct {
Master []WeResUserInfoStruct `json:"master"` // 自己创建的学生列表(主家长)
Slave []WeResUserInfoStruct `json:"slave"` // 添加的学生列表(副家长)
}
const tokenExpiryTimeS = uint32(48 * 3600)
type weLoginRes struct {
weUserListStruct
WePhone bool `json:"wePhone"` // 是否已获取到微信电话
WeInfo bool `json:"weInfo"` // 是否已获取到微信用户信息
// weUserListStruct
// WePhone bool `json:"wePhone"` // 是否已获取到微信电话
// WeInfo bool `json:"weInfo"` // 是否已获取到微信用户信息
Token string `json:"token"`
Expiry uint32 `json:"expiry"` //到期时间,10位时间戳
}
type weLoginReq struct {
Nickname string `json:"nickname"` // 选填,用户昵称
AvatarURL string `json:"avatarurl" example:""` // 选填,用户头像URL
Code string `json:"code" example:"codeTest1"` //必填,登录要用的微信code
Token string `json:"token,omitempty"` //选填,如果有旧的token,也带过来
}
......@@ -78,13 +64,13 @@ func WeLogin(c *gin.Context) {
var userInfo *model.CacheWeCustomerStruct
if userID != 0 {
userInfo = cache.GetWechatCustomerInfoAndCacheUpdateTokenTime(userID, nowTime)
if userInfo != nil {
dbcurd.UpdateUWeCustomerLoginTime(userID)
}
//if userInfo != nil {
// dbcurd.UpdateUWeCustomerLoginTime(userID) todo 改成每天半夜来记录
//}
}
if userInfo == nil { // 微信服务器登录
unionID, err := tencent2.WechatCode2Session(reqData.Code) //也不去校验reqData.Code长度了,对半是对的
unionID, err := tencent.WechatCode2Session(reqData.Code) //也不去校验reqData.Code长度了,对半是对的
if err != nil {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorTencentErr,
......@@ -121,7 +107,7 @@ func WeLogin(c *gin.Context) {
} else { // 已有用户
userInfo = cache.GetWechatCustomerInfoAndCacheUpdateTokenTime(userID, nowTime)
if userInfo != nil {
dbcurd.UpdateUWeCustomerLoginTime(userID)
// dbcurd.UpdateUWeCustomerLoginTime(userID) todo 改成每天半夜来记录
} else {
cache.WechatCustomerMap.Delete(userID)
cache.WechatCustomerUnionIDToIDMAP.Delete(unionID)
......@@ -135,135 +121,25 @@ func WeLogin(c *gin.Context) {
}
}
var res weLoginRes
res.Token = api.CreateToken(nowTime, userID, 1, 48*24*3600)
if len(userInfo.WePhone) > 0 {
res.WePhone = true
}
if len(userInfo.Nickname) > 0 { // todo 这里考虑长时间之后重新获取一盘昵称头像
res.WeInfo = true
}
// 保存昵称头像
saveNickname := len(reqData.Nickname) > 0 && reqData.Nickname != userInfo.Nickname // 要更新数据
saveURL := len(reqData.AvatarURL) > 0 && reqData.AvatarURL != userInfo.AvatarURL // 要更新数据
for _, cardUserID := range userInfo.MasterCardUserID {
cardUserInfo := cache.GetCardUserInfo(cardUserID)
if cardUserInfo != nil {
var upInfo WeResUserInfoStruct
upInfo.ID = cardUserID
upInfo.Name = cardUserInfo.Name
upInfo.Sex = cardUserInfo.Sex
upInfo.Grade = cardUserInfo.Grade
upInfo.Class = cardUserInfo.Class
upInfo.StuNum = cardUserInfo.StuNum
// upInfo.Service = [6]uint8{1, 2, 2, 2, 2, 2}
areaInfoP := cache.GetAreaMapInfo(cardUserInfo.AreaID)
if areaInfoP != nil {
if areaInfoP.Status == 1 || (areaInfoP.Status == 2 && userInfo.TestRole) {
upInfo.Area = areaInfoP.Name
if saveNickname || saveURL { // 要更新数据
if saveNickname {
userInfo.Nickname = reqData.Nickname
}
if saveURL {
userInfo.AvatarURL = reqData.AvatarURL
}
res.Master = append(res.Master, upInfo)
if dbcurd.UpdateUWeCustomerNicknameAndURL(userID, userInfo.Nickname, userInfo.AvatarURL) { // 更新数据库
cache.WechatCustomerMap.Store(userID, *userInfo) // 更新缓存
}
}
for _, cardUserID := range userInfo.SlaveCardUserID {
cardUserInfo := cache.GetCardUserInfo(cardUserID)
if cardUserInfo != nil {
var upInfo WeResUserInfoStruct
upInfo.ID = cardUserID
upInfo.Name = cardUserInfo.Name
upInfo.Sex = cardUserInfo.Sex
upInfo.Grade = cardUserInfo.Grade
upInfo.Class = cardUserInfo.Class
upInfo.StuNum = cardUserInfo.StuNum
// upInfo.Service = [6]uint8{1, 2, 2, 2, 2, 2}
areaInfoP := cache.GetAreaMapInfo(cardUserInfo.AreaID)
if areaInfoP != nil {
if areaInfoP.Status == 1 || (areaInfoP.Status == 2 && userInfo.TestRole) {
upInfo.Area = areaInfoP.Name
}
}
res.Slave = append(res.Slave, upInfo)
}
}
c.JSON(http.StatusOK, gin.H{
"code": api.Success,
"data": res,
})
}
// GetStudentList 获取学生列表
// @Tags 家长微信
// @Summary 获取学生列表 [complete]
// @Description 获取学生列表
// @Product json
// @Success 0 {object} weUserListStruct
// @Router /we/stulist [GET]
// @Security ApiKeyAuth
func GetStudentList(c *gin.Context) {
v, ok := c.Get("userID")
userID := v.(uint32)
if ok != true || userID == 0 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorSystemErr,
"data": api.CodeMsg[api.ErrorSystemErr],
})
logger.Log.Error("GetStudentList",
zap.Reflect("c.Get(\"userID\")", v))
return
}
userInfo := cache.GetWeUserInfoFromMapAndDB(userID)
if userInfo == nil { // 微信服务器登录
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorSystemErr,
"message": api.CodeMsg[api.ErrorSystemErr],
})
return
}
var res weUserListStruct
for _, cardUserID := range userInfo.MasterCardUserID {
cardUserInfo := cache.GetCardUserInfo(cardUserID)
if cardUserInfo != nil {
var upInfo WeResUserInfoStruct
upInfo.ID = cardUserID
upInfo.Name = cardUserInfo.Name
upInfo.Sex = cardUserInfo.Sex
upInfo.Grade = cardUserInfo.Grade
upInfo.Class = cardUserInfo.Class
upInfo.StuNum = cardUserInfo.StuNum
// upInfo.Service = [6]uint8{1, 2, 2, 2, 2, 2}
areaInfoP := cache.GetAreaMapInfo(cardUserInfo.AreaID)
if areaInfoP != nil {
if areaInfoP.Status == 1 || (areaInfoP.Status == 2 && userInfo.TestRole) {
upInfo.Area = areaInfoP.Name
}
}
res.Master = append(res.Master, upInfo)
}
}
for _, cardUserID := range userInfo.SlaveCardUserID {
cardUserInfo := cache.GetCardUserInfo(cardUserID)
if cardUserInfo != nil {
var upInfo WeResUserInfoStruct
upInfo.ID = cardUserID
upInfo.Name = cardUserInfo.Name
upInfo.Sex = cardUserInfo.Sex
upInfo.Grade = cardUserInfo.Grade
upInfo.Class = cardUserInfo.Class
upInfo.StuNum = cardUserInfo.StuNum
// upInfo.Service = [6]uint8{1, 2, 2, 2, 2, 2}
areaInfoP := cache.GetAreaMapInfo(cardUserInfo.AreaID)
if areaInfoP != nil {
if areaInfoP.Status == 1 || (areaInfoP.Status == 2 && userInfo.TestRole) {
upInfo.Area = areaInfoP.Name
}
}
res.Slave = append(res.Slave, upInfo)
}
}
var res weLoginRes
res.Expiry = uint32(nowTime/1000000) + tokenExpiryTimeS
res.Token = api.CreateToken(nowTime, userID, 1, res.Expiry)
c.JSON(http.StatusOK, gin.H{
"code": api.Success,
......
package api_we
import (
"dc_golang_server_1/api"
"github.com/gin-gonic/gin"
"net/http"
)
//// PutCardUserShareOn 打开邀请码开关(仅主家长有权限)
//// @Tags 家长微信
//// @Summary 打开邀请码开关(仅主家长有权限)
//// @Description 传学生ID至后台,后台返回成功失败
//// @Produce json
//// @Param id path integer true "学生ID"
//// @Success 0
//// @Router /we/cardusershareon/{id} [PUT]
//// @Security ApiKeyAuth
//func PutCardUserShareOn(c *gin.Context) {
// c.JSON(http.StatusOK, gin.H{
// "code": api.Success,
// })
//}
//// PutCardUserShareOff 关闭邀请码开关(仅主家长有权限)
//// @Tags 家长微信
//// @Summary 关闭邀请码开关(仅主家长有权限)
//// @Description 传学生ID至后台,后台返回成功失败
//// @Produce json
//// @Param id path integer true "学生ID"
//// @Success 0
//// @Router /we/cardusershareoff/{id} [PUT]
//// @Security ApiKeyAuth
//func PutCardUserShareOff(c *gin.Context) {
// c.JSON(http.StatusOK, gin.H{
// "code": api.Success,
// })
//}
//// DeleteAllSlaveWeUser 清空所有副家长(仅主家长有权限)
//// @Tags 家长微信
//// @Summary 删除副家长(仅主家长有权限)
//// @Description 传学生ID和微信UnionID,后台返回成功失败
//// @Produce json
//// @Param id path integer true "学生ID"
//// @Param unionid query string true "副家长微信UnionID"
//// @Success 0
//// @Router /we/allslaveweuser/{id} [DELETE]
//// @Security ApiKeyAuth
//func DeleteAllSlaveWeUser(c *gin.Context) {
// c.JSON(http.StatusOK, gin.H{
// "code": api.Success,
// })
//}
// AddFamilyNum 添加亲情号
// @Tags 家长微信
// @Summary 添加亲情号
// @Description 家长绑定亲情号接口
// @Accept json
// @Produce json
// @Param id path integer true "学生ID"
// @Param data body model.CacheFamilyOnePerson true "亲情号内容"
// @Success 0
// @Router /we/familynum/{id} [POST]
// @Security ApiKeyAuth
func AddFamilyNum(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": api.Success,
})
}
// PutFamilyNum 修改亲情号
// @Tags 家长微信
// @Summary 修改亲情号
// @Description 修改亲情号接口
// @Accept json
// @Produce json
// @Param id path integer true "学生ID"
// @Param phone query string true "电话号码"
// @Param data body model.CacheFamilyOnePerson true "亲情号内容"
// @Success 0
// @Router /we/familynum/{id} [PUT]
// @Security ApiKeyAuth
func PutFamilyNum(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": api.Success,
})
}
// DeleteFamilyNum 删除亲情号
// @Tags 家长微信
// @Summary 删除亲情号
// @Description 删除亲情号接口
// @Accept json
// @Produce json
// @Param id path integer true "学生ID"
// @Param phone query string true "电话号码"
// @Success 0
// @Router /we/familynum/{id} [DELETE]
// @Security ApiKeyAuth
func DeleteFamilyNum(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": api.Success,
})
}
......@@ -17,6 +17,8 @@ const (
ErrorReqInsertDuplicate = 12
ErrorDeleteCardUserHaveSimCard = 13
ErrorMonthDeleteFamilyNumOverrun = 20
ErrorShareCode = 30
ErrorShareCodeRunTime = 31
)
......@@ -37,6 +39,8 @@ var CodeMsg = map[uint16]string{
ErrorReqInsertDuplicate: "内容重复,无法创建",
ErrorDeleteCardUserHaveSimCard: "已绑定电话卡,请解绑电话卡后再删除",
ErrorMonthDeleteFamilyNumOverrun: "根据防电信诈骗相关规定,月删除亲情号次数不得超过2次,请于下月修改",
ErrorShareCode: "邀请码无效,请联系主家长微信重新分享",
ErrorShareCodeRunTime: "邀请码已过期,请联系主家长微信重新分享",
}
......@@ -25,13 +25,13 @@ type TokenResult struct {
}
// CreateToken 生成token,duration单位秒,=0表示不限时长
func CreateToken(creatTime int64, userID uint32, userType uint8, duration uint32) string {
var expireTime uint32
if duration == 0 {
expireTime = 0xffffffff
} else {
expireTime = uint32(creatTime/1000000) + duration
}
func CreateToken(creatTime int64, userID uint32, userType uint8, expireTime uint32) string {
//var expireTime uint32
//if duration == 0 {
// expireTime = 0xffffffff
//} else {
// expireTime = uint32(creatTime/1000000) + duration
//}
var clear = make([]byte, tokenClearLen) //7字节创建时间 4字节结束时间 4字节有效时长 2字节CRC 3字节随机数预留
r := rand.New(rand.NewSource(time.Now().UnixNano()))
random := byte(r.Intn(256))
......
......@@ -48,11 +48,12 @@ func InitRouter() { //*gin.Engine{
wechat.GET("cardusertrend/:id", api_we.GetCardUserAndTrend) //获取单个学生信息和最新动态
wechat.GET("bindcarduser/:id", api_we.GetSlaveBindCardUser) //获取学生副家长列表(仅主家长有权限)
wechat.GET("sharestring/:id", api_we.GetCardUserShareCode) //获取邀请码(仅主家长有权限)
wechat.POST("bindcarduser/:share_code", api_we.BindCardUser) //副家长绑定学生
wechat.GET("previewcarduser/:share_code", api_we.GetPreviewCardUser) //根据邀请码预览学生信息
wechat.POST("bindcarduser/:share_code", api_we.SlaveBindCardUser) //副家长绑定学生
wechat.DELETE("bindcarduser/:id", api_we.DeleteSlaveBindCardUser) //副家长解绑学生
//wechat.PUT("cardusershareon/:id", api_we.PutCardUserShareOn) //打开邀请码开关(仅主家长有权限)
//wechat.PUT("cardusershareoff/:id", api_we.PutCardUserShareOff) //关闭邀请码开关(仅主家长有权限)
wechat.DELETE("slaveweuser/:id", api_we.MasterDeleteSlaveWeUser) //删除副家长(仅主家长有权限)
wechat.DELETE("slaveweuser/:id", api_we.DeleteSlaveWeUser) //删除副家长(仅主家长有权限)
wechat.PUT("carduser/:id", api_we.PutCardUser) //修改学生信息
wechat.PUT("cardloss/:id", api_we.CardLoss) //卡挂失/解挂
wechat.PUT("cardbind/:id", api_we.CardBind) //绑定卡
......@@ -60,7 +61,7 @@ func InitRouter() { //*gin.Engine{
wechat.GET("phonecardstatus/:id", api_we.GetPhoneCardStatus) //获取学生公话卡状态
wechat.GET("callrecord/:id", api_we.GetCallRecord) // 查询通话记录
wechat.POST("familynum/:id", api_we.AddFamilyNum) //添加亲情号
wechat.PUT("familynum/:id", api_we.PutFamilyNum) //修改亲情号
wechat.PUT("familynickname/:id", api_we.PutFamilyNickName) //修改亲情号的昵称
wechat.DELETE("familynum/:id", api_we.DeleteFamilyNum) //删除亲情号
//缴费
//查询缴费记录
......
......@@ -10,9 +10,9 @@ func Init() {
initAreaMapAndCountyAreaMap()
initWechatCustomerMap()
initCardUserMapAndSimInfoMapNoFamilyNum()
initCardUserMapNoSimID()
initWechatAndCardUserRelationToWechatCustomerMapAndCardUserMap()
initFamilyNumToSimInfoMap()
initSimInfoMap()
initAreaServiceMap()
initPhone20DeviceMap()
// initAdminMap()
......
......@@ -7,7 +7,6 @@ import (
"fmt"
"go.uber.org/zap"
"log"
"strings"
"time"
)
......@@ -15,7 +14,7 @@ import (
//Title string `json:"title" example:"公话机-教1楼3层"` // 显示在第一行 公话机-PlaceUser
//Content string `json:"content" example:"被叫:爸爸 时长:2分"` // 显示在第二行 nickname+talkTime
//Time time.Time `json:"time" example:"2021-10-23 17:00:00"` // 显示在第三行,呼叫起始时间
func initCardUserMapAndSimInfoMapNoFamilyNum() {
func initCardUserMapNoSimID() {
fmt.Println(time.Now(), "cache: initCardUserMapAndSimInfoMapNoFamilyNum begin")
var cardUserID uint32
var temp model.CacheCardUserStruct
......@@ -24,31 +23,30 @@ func initCardUserMapAndSimInfoMapNoFamilyNum() {
log.Panicln("Select u_card_user To Map rows", err)
}
defer rows.Close()
var simInfo model.CacheSimInfoStruct
// var simInfo model.CacheSimInfoStruct
for rows.Next() {
err = rows.Scan(&cardUserID, &temp.Name, &temp.Sex, &temp.AreaID, &temp.Grade, &temp.Class, &temp.StuNum)
if err != nil {
log.Panicln("initCardUserMapAndSimInfoMapNoFamilyNum rows.Scan", err)
}
// 查对应卡用户的卡信息
err = dbcurd.PgDb.QueryRow("SELECT sim_id,area_service_id,month_talk_minutes,month_package_minutes,status,family_change_count,expiry_at FROM u_sim_info WHERE card_user_id=$1 AND area_service_id!=0 AND status!=0", cardUserID).Scan(
&temp.SimCardID,
&simInfo.AreaServiceID,
&simInfo.MonthTalkMinutes,
&simInfo.MonthPackageMinutes,
&simInfo.Status,
&simInfo.FamilyChangeCount,
&simInfo.ExpiryAt)
if err != nil {
if strings.Contains(err.Error(), "no rows in result") {
CardUserMap.Store(cardUserID, temp)
continue
}
log.Panicln("Select u_sim_info To temp.SimCardID", err)
}
// todo1 考虑校验area_service_id
simInfo.CardUserID = cardUserID
SimInfoMap.Store(temp.SimCardID, simInfo)
//// 查对应卡用户的卡信息
//err = dbcurd.PgDb.QueryRow("SELECT sim_id,area_service_id,month_talk_minutes,month_package_minutes,status,family_delete_count,expiry_at FROM u_sim_info WHERE card_user_id=$1 AND area_service_id!=0 AND status!=0", cardUserID).Scan(
// &temp.SimCardID,
// &simInfo.AreaServiceID,
// &simInfo.MonthTalkMinutes,
// &simInfo.MonthPackageMinutes,
// &simInfo.Status,
// &simInfo.FamilyDeleteCount,
// &simInfo.ExpiryAt)
//if err != nil {
// if strings.Contains(err.Error(), "no rows in result") {
// CardUserMap.Store(cardUserID, temp)
// continue
// }
// log.Panicln("Select u_sim_info To temp.SimCardID", err)
//}
//simInfo.CardUserID = cardUserID
//SimInfoMap.Store(temp.SimCardID, simInfo)
CardUserMap.Store(cardUserID, temp)
}
// 处理完毕后,需要判断一次遍历过程中是否有错误产生
......
......@@ -10,26 +10,40 @@ import (
"time"
)
func initFamilyNumToSimInfoMap() {
func initSimInfoMap() { // 查询绑定了校区的有效卡
fmt.Println(time.Now(), "cache: initFamilyNumToSimInfoMap begin")
var key string
var value model.CacheSimInfoStruct
var ok bool
SimInfoMap.Range(func(k, v interface{}) bool {
key, ok = k.(string)
if ok != true {
log.Panicln(time.Now(), "initFamilyNumToSimInfoMap k.(string) error", k, v)
var simID string
var temp model.CacheSimInfoStruct
rows, err := dbcurd.PgDb.Query("SELECT sim_id,card_user_id,area_service_id,month_talk_minutes,month_package_minutes,status,family_delete_count,expiry_at FROM u_sim_info WHERE area_service_id!=0 AND status!=0")
if err != nil {
log.Panicln("Select u_sim_info To Map rows", err)
}
value, ok = v.(model.CacheSimInfoStruct)
if ok != true {
log.Panicln(time.Now(), "initFamilyNumToSimInfoMap v.(model.CacheSimInfoStruct) error", k, v)
defer rows.Close()
for rows.Next() {
err = rows.Scan(&simID, &temp.CardUserID, &temp.AreaServiceID, &temp.MonthTalkMinutes, &temp.MonthPackageMinutes, &temp.Status, &temp.FamilyDeleteCount, &temp.ExpiryAt)
if err != nil {
log.Panicln("initCardUserMapAndSimInfoMapNoFamilyNum rows.Scan", err)
}
if temp.CardUserID != 0 { // 往CardUserMap里填入simID
cardUserInfo := GetCardUserInfo(temp.CardUserID)
if cardUserInfo == nil {
fmt.Println("simInfo里面的CardUserID,居然在CardUserMap里面查不到", simID, temp.CardUserID)
//logger.Log.Error("simInfo里面的CardUserID,居然在CardUserMap里面查不到",
// zap.String("simId", simID),
// zap.Uint32("CardUserID",temp.CardUserID),
// zap.String("src", "initSimInfoMap"))
} else {
cardUserInfo.SimCardID = simID
CardUserMap.Store(temp.CardUserID, *cardUserInfo)
}
}
temp.FamilyNum = dbcurd.SelectUSimFamilyNumBySimID(simID)
SimInfoMap.Store(simID, temp)
}
// 处理完毕后,需要判断一次遍历过程中是否有错误产生
if err = rows.Err(); err != nil {
log.Panicln(time.Now(), "initCardUserMapAndSimInfoMapNoFamilyNum rows.Err()", err)
}
value.FamilyNum = dbcurd.SelectUSimFamilyNumBySimID(key)
SimInfoMap.Store(key, value)
return true
})
fmt.Println(time.Now(), "cache: initFamilyNumToSimInfoMap end")
}
......
......@@ -4,6 +4,8 @@ import (
"dc_golang_server_1/data_db_cache/model"
"dc_golang_server_1/logger"
"go.uber.org/zap"
"strings"
"time"
)
func SelectUSimFamilyNumBySimID(simID string) (familyNumbers []model.CacheFamilyOnePerson) {
......@@ -36,3 +38,49 @@ func SelectUSimFamilyNumBySimID(simID string) (familyNumbers []model.CacheFamily
return
}
func InsertUSimFamilyNum(simID, phone, nickname string) uint8 {
var err error
for i := 0; i < 50; i++ {
_, err = PgDb.Exec("INSERT INTO u_sim_family_num(sim_id,phone,nickname)VALUES($1,$2,$3)", simID, phone, nickname)
if err == nil {
return InsertOK
}
if strings.Contains(err.Error(), "duplicate key value") {
logger.Log.Error("InsertUSimFamilyNum Err",
zap.String("simID", simID),
zap.String("phone", phone),
zap.String("nickname", nickname),
zap.Error(err))
return InsertDuplicate
}
time.Sleep(2 * time.Millisecond)
}
logger.Log.Error("InsertUSimFamilyNum Err",
zap.Error(err))
return InsertSysErr
}
func UpdateUSimFamilyNumNickname(simID, phone, nickname string) bool {
_, err := PgDb.Exec("UPDATE u_sim_family_num SET nickname=$1 WHERE sim_id=$2 AND phone=$3", nickname, simID, phone)
if err == nil {
return true
}
return false
}
func DeleteUSimFamilyNum(simID, phone string) bool {
var err error
for i := 0; i < 50; i++ {
_, err = PgDb.Exec("DELETE FROM u_sim_family_num WHERE sim_id=$1 AND phone=$2", simID, phone)
if err == nil {
return true
}
time.Sleep(2 * time.Millisecond)
}
logger.Log.Error("DeleteUSimFamilyNum Err",
zap.String("simID", simID),
zap.String("phone", phone),
zap.Error(err))
return false
}
......@@ -50,3 +50,33 @@ func UpdateUSimInfoCardUserID(simId string, cardUserID uint32) bool {
}
return false
}
func UpdateUSimInfoAddFamilyDeleteCount(simID string) (newCount int8) { //family_delete_count+1
var err error
for i := 0; i < 50; i++ {
err = PgDb.QueryRow("UPDATE u_sim_info SET family_delete_count=family_delete_count-1 WHERE sim_id=$1 RETURNING family_delete_count",
simID).Scan(&newCount)
if err == nil {
if newCount < 0 {
newCount = 0
logger.Log.Error("UpdateUSimInfoAddFamilyDeleteCount newCount < 0",
zap.String("simID", simID),
zap.Int8("newCount", newCount),
zap.Error(err))
}
return
}
if strings.Contains(err.Error(), "no rows in result") {
logger.Log.Error("UpdateUSimInfoAddFamilyDeleteCount no rows in result",
zap.String("simID", simID),
zap.Error(err))
return 0
}
fmt.Println("UpdateUSimInfoAddFamilyDeleteCount:", i, err)
time.Sleep(2 * time.Millisecond)
}
logger.Log.Error("UpdateUSimInfoAddFamilyDeleteCount 2",
zap.String("simID", simID),
zap.Error(err))
return 0
}
......@@ -146,3 +146,19 @@ func SelectUWeCustomerByUserIDToCacheModel(userID uint32) (*model.CacheWeCustome
}
return &weUserInfo, weUnionID
}
func UpdateUWeCustomerNicknameAndURL(weUserID uint32, nickname, url string) bool { // todo 看下用不用搞成 *sql.Stmt
var err error
for i := 0; i < 10; i++ {
if _, err = PgDb.Exec("UPDATE u_we_customer SET nickname=$1,avatarurl=$2 WHERE id=$3", nickname, url, weUserID); err == nil {
return true
}
time.Sleep(2 * time.Millisecond)
}
logger.Log.Error("UpdateUWeCustomerNicknameAndURL",
zap.String("nickname", nickname),
zap.String("avatarurl", url),
zap.Uint32("weUserID", weUserID),
zap.Error(err))
return false
}
......@@ -55,16 +55,16 @@ type CacheCardUserStruct struct {
type CacheSimInfoStruct struct {
CardUserID uint32 `json:"-" swaggerignore:"true"` //卡用户ID
AreaServiceID uint32 `json:"-" swaggerignore:"true"`
Status uint8 `json:"status"` //0无数据 1 正常使用 2 已挂失
Status uint8 `json:"status"` //0无数据 1 正常使用 2 已挂失 3 服务已到期(数据库无该状态,仅微信API接口该状态)
MonthTalkMinutes uint16 `json:"monthMin"` // 本月已使用分钟数
MonthPackageMinutes uint16 `json:"monthPack"` // 月套餐分钟数
ExpiryAt time.Time `json:"expiryAt"`
FamilyNum []CacheFamilyOnePerson `json:"family"` // 亲情号列表
FamilyChangeCount uint8 `json:"changeable"` // 本月可修改亲情号次数
FamilyDeleteCount int8 `json:"deleteable"` // 本月剩余可删除亲情号次数
}
type CacheFamilyOnePerson struct {
Phone string `json:"phone"`
Nickname string `json:"name"`
Phone string `json:"phone"` // 必填
Nickname string `json:"name"` // 必填
}
type CachePhone20DeviceStruct struct {
......
No preview for this file type
No preview for this file type
{"level":"INFO","ts":"2021-10-28 17:40:10.206","msg":"","HostName":"DESKTOP-2789F62","Status":200,"SpendNanoS":74277,"Ip":"127.0.0.1","Method":"POST","Path":"/we/login/%7Bcode%7D","DataSize":405,"Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3875.400 QQBrowser/10.8.4492.400"}
{"level":"INFO","ts":"2021-10-28 17:40:27.981","msg":"","HostName":"DESKTOP-2789F62","Status":200,"SpendNanoS":237,"Ip":"127.0.0.1","Method":"GET","Path":"/we/phonecardstatus/5","DataSize":276,"Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3875.400 QQBrowser/10.8.4492.400"}
{"level":"INFO","ts":"2021-10-28 17:40:37.046","msg":"","HostName":"DESKTOP-2789F62","Status":200,"SpendNanoS":37842,"Ip":"127.0.0.1","Method":"POST","Path":"/we/login/%7Bcode%7D","DataSize":116,"Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3875.400 QQBrowser/10.8.4492.400"}
{"level":"INFO","ts":"2021-10-28 17:40:44.399","msg":"","HostName":"DESKTOP-2789F62","Status":200,"SpendNanoS":998,"Ip":"127.0.0.1","Method":"POST","Path":"/we/login/%7Bcode%7D","DataSize":64,"Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3875.400 QQBrowser/10.8.4492.400"}
{"level":"INFO","ts":"2021-10-28 17:40:51.534","msg":"","HostName":"DESKTOP-2789F62","Status":200,"SpendNanoS":38383,"Ip":"127.0.0.1","Method":"POST","Path":"/we/login/%7Bcode%7D","DataSize":116,"Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3875.400 QQBrowser/10.8.4492.400"}
{"level":"INFO","ts":"2021-10-28 17:40:56.179","msg":"","HostName":"DESKTOP-2789F62","Status":200,"SpendNanoS":36648,"Ip":"127.0.0.1","Method":"POST","Path":"/we/login/%7Bcode%7D","DataSize":116,"Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3875.400 QQBrowser/10.8.4492.400"}
{"level":"INFO","ts":"2021-10-28 17:41:00.418","msg":"","HostName":"DESKTOP-2789F62","Status":200,"SpendNanoS":40236,"Ip":"127.0.0.1","Method":"POST","Path":"/we/login/%7Bcode%7D","DataSize":116,"Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3875.400 QQBrowser/10.8.4492.400"}
{"level":"INFO","ts":"2021-10-28 17:41:04.822","msg":"","HostName":"DESKTOP-2789F62","Status":200,"SpendNanoS":74008,"Ip":"127.0.0.1","Method":"POST","Path":"/we/login/%7Bcode%7D","DataSize":116,"Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3875.400 QQBrowser/10.8.4492.400"}
......@@ -6,11 +6,12 @@ import (
"github.com/natefinch/lumberjack"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"os"
"time"
)
var Log *zap.Logger
var logGin *zap.Logger
var LogHttpClient *zap.Logger
func Init() {
config := zapcore.EncoderConfig{
......@@ -72,19 +73,75 @@ func Init() {
//zapcore.NewCore(zapcore.NewJSONEncoder(encoder), zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout)), logLevel),//同时将日志输出到控制台,NewJSONEncoder 是结构化输出
)
Log = zap.New(core, zap.AddStacktrace(zap.ErrorLevel))
infoWriter = &lumberjack.Logger{
Filename: config3.LogPath + "infoGin.log",
MaxSize: config3.LogFileMaxSize, //最大M数,超过则切割
MaxBackups: config3.LogInfoMaxFileNum, //最大文件保留数,超过就删除最老的日志文件
MaxAge: config3.LogInfoMaxFileDay, //保存30天
Compress: false, //是否压缩
}
warnWriter = &lumberjack.Logger{
Filename: config3.LogPath + "warnGin.log",
MaxSize: config3.LogFileMaxSize, //最大M数,超过则切割
MaxBackups: config3.LogWarnMaxFileNum, //最大文件保留数,超过就删除最老的日志文件
MaxAge: config3.LogWarnMaxFileDay, //保存30天
Compress: false, //是否压缩
}
errorWriter = &lumberjack.Logger{
Filename: config3.LogPath + "errorGin.log",
MaxSize: config3.LogFileMaxSize, //最大M数,超过则切割
MaxBackups: config3.LogErrorMaxFileNum, //最大文件保留数,超过就删除最老的日志文件
MaxAge: config3.LogErrorMaxFileDay, //保存30天
Compress: false, //是否压缩
}
core = zapcore.NewTee(
zapcore.NewCore(zapcore.NewJSONEncoder(config), zapcore.AddSync(infoWriter), infoLevel), // zapcore.NewConsoleEncoder(encoder)
zapcore.NewCore(zapcore.NewJSONEncoder(config), zapcore.AddSync(warnWriter), warnLevel), //
zapcore.NewCore(zapcore.NewJSONEncoder(config), zapcore.AddSync(errorWriter), errorLevel), //
//zapcore.NewCore(zapcore.NewJSONEncoder(encoder), zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout)), logLevel),//同时将日志输出到控制台,NewJSONEncoder 是结构化输出
)
logGin = zap.New(core, zap.AddStacktrace(zap.ErrorLevel))
infoWriter = &lumberjack.Logger{
Filename: config3.LogPath + "infoClient.log",
MaxSize: config3.LogFileMaxSize, //最大M数,超过则切割
MaxBackups: config3.LogInfoMaxFileNum, //最大文件保留数,超过就删除最老的日志文件
MaxAge: config3.LogInfoMaxFileDay, //保存30天
Compress: false, //是否压缩
}
warnWriter = &lumberjack.Logger{
Filename: config3.LogPath + "warnClient.log",
MaxSize: config3.LogFileMaxSize, //最大M数,超过则切割
MaxBackups: config3.LogWarnMaxFileNum, //最大文件保留数,超过就删除最老的日志文件
MaxAge: config3.LogWarnMaxFileDay, //保存30天
Compress: false, //是否压缩
}
errorWriter = &lumberjack.Logger{
Filename: config3.LogPath + "errorClient.log",
MaxSize: config3.LogFileMaxSize, //最大M数,超过则切割
MaxBackups: config3.LogErrorMaxFileNum, //最大文件保留数,超过就删除最老的日志文件
MaxAge: config3.LogErrorMaxFileDay, //保存30天
Compress: false, //是否压缩
}
core = zapcore.NewTee(
zapcore.NewCore(zapcore.NewJSONEncoder(config), zapcore.AddSync(infoWriter), infoLevel), // zapcore.NewConsoleEncoder(encoder)
zapcore.NewCore(zapcore.NewJSONEncoder(config), zapcore.AddSync(warnWriter), warnLevel), //
zapcore.NewCore(zapcore.NewJSONEncoder(config), zapcore.AddSync(errorWriter), errorLevel), //
//zapcore.NewCore(zapcore.NewJSONEncoder(encoder), zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout)), logLevel),//同时将日志输出到控制台,NewJSONEncoder 是结构化输出
)
LogHttpClient = zap.New(core, zap.AddStacktrace(zap.ErrorLevel))
}
func HttpGinLog() gin.HandlerFunc { //logger *log.Log
return func(c *gin.Context) {
startTime := time.Now().UnixMicro()
startTime := time.Now().UnixMilli()
c.Next()
// stopTime := time.Since(startTime)
// spendTime := stopTime.Nanoseconds()/1000000///fmt.Sprintf("%d ms", (stopTime.Nanoseconds()+500000)/1000000)
spendTime := time.Now().UnixMicro() - startTime
hostName, err := os.Hostname()
if err != nil {
hostName = "unknown"
}
spendTime := time.Now().UnixMilli() - startTime
// hostName, err := os.Hostname()
//if err != nil {
// hostName = "unknown"
//}
statusCode := c.Writer.Status()
clientIp := c.ClientIP()
userAgent := c.Request.UserAgent()
......@@ -112,10 +169,10 @@ func HttpGinLog() gin.HandlerFunc { //logger *log.Log
if len(c.Errors) > 0 {
//entry.Error(c.Errors.ByType(gin.ErrorTypePrivate).String())
Log.Error(c.Errors.ByType(gin.ErrorTypePrivate).String(),
zap.String("HostName", hostName),
logGin.Error(c.Errors.ByType(gin.ErrorTypePrivate).String(),
// zap.String("HostName", hostName),
zap.Int("Status", statusCode),
zap.Int64("SpendNanoS", spendTime),
zap.Int64("SpendMS", spendTime),
zap.String("Ip", clientIp),
zap.String("Method", method),
zap.String("Path", path),
......@@ -123,30 +180,30 @@ func HttpGinLog() gin.HandlerFunc { //logger *log.Log
zap.String("Agent", userAgent))
}
if statusCode >= 500 {
Log.Error("",
zap.String("HostName", hostName),
logGin.Error("",
// zap.String("HostName", hostName),
zap.Int("Status", statusCode),
zap.Int64("SpendNanoS", spendTime),
zap.Int64("SpendMS", spendTime),
zap.String("Ip", clientIp),
zap.String("Method", method),
zap.String("Path", path),
zap.Int("DataSize", dataSize),
zap.String("Agent", userAgent))
} else if statusCode >= 400 {
Log.Warn("",
zap.String("HostName", hostName),
logGin.Warn("",
// zap.String("HostName", hostName),
zap.Int("Status", statusCode),
zap.Int64("SpendNanoS", spendTime),
zap.Int64("SpendMS", spendTime),
zap.String("Ip", clientIp),
zap.String("Method", method),
zap.String("Path", path),
zap.Int("DataSize", dataSize),
zap.String("Agent", userAgent))
} else {
Log.Info("",
zap.String("HostName", hostName),
logGin.Info("",
// zap.String("HostName", hostName),
zap.Int("Status", statusCode),
zap.Int64("SpendNanoS", spendTime),
zap.Int64("SpendMS", spendTime),
zap.String("Ip", clientIp),
zap.String("Method", method),
zap.String("Path", path),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment