Commit c32b7c05 by zhangjie

1.增加留言相关功能

parent 53919eb0
package api_we_card_operate
import (
"dc_golang_server_1/api"
"dc_golang_server_1/data_db_cache/cache"
"dc_golang_server_1/logger"
"dc_golang_server_1/util"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"net/http"
)
type qr2StudentsRes struct {
AreaID uint32 `json:"areaID"` // 区域ID 用作创建学生
AreaName string `json:"areaName"` // 区域名字 用作创建学生
CardNum string `json:"cardNum"` // 卡号 等会调绑卡接口来用
CardType uint8 `json:"cardType"` // 卡类型:1电话卡 等会调绑卡接口来用
Students []struct {
Expiry string `json:"expiry"` // 缴费的到期时间,年月日(日期当天则仍在有效期内),展示给用户看,如果过了,就要先缴费才能绑卡,如果是"0001-01-01",则表示从来未缴过费
Name string `json:"name"` // 学生昵称,另外去把头像也拉下来展示出来
Sex uint8 `json:"sex"` // 性别 0,无信息,1女,2男
CID uint32 `json:"cid"` // 学生ID 等会调绑卡接口来用
Master bool `json:"master"` // 是否为主家长,页面上展示出来
} `json:"students"` // 学生列表
}
// Qr2Students 根据二维码,返回用户状态信息及卡号
// @Tags 家长微信-卡操作
// @Summary 根据二维码,返回用户状态信息及卡号
// @Description 根据二维码,返回用户状态信息及卡号
// @Produce json
// @Param qrcode path string true "QR内容"
// @Success 0 {object} qr2StudentsRes "result"
// @Router /we/qr2students/{qrcode} [GET]
// @Security ApiKeyAuth
func Qr2Students(c *gin.Context) {
qrCode := c.Param("qrcode")
if len(qrCode) != 36 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara,
"message": api.CodeMsg[api.ErrorReqPara] + " 二维码长度错误",
})
return
}
cardID, err := util.DecryptBase64URLToBytes(qrCode, "keyQR123@dcrym01")
if err != nil {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara,
"message": api.CodeMsg[api.ErrorReqPara] + " 无效二维码",
})
return
}
for i := 0; i < 26; i++ {
cardID[i] -= uint8(i)%3 + 0x18
}
cardID[11], cardID[25], cardID[20], cardID[22], cardID[9], cardID[24], cardID[21], cardID[12], cardID[0] = cardID[0], cardID[9], cardID[11], cardID[12], cardID[20], cardID[21], cardID[22], cardID[24], cardID[25]
if cardID[20] != 0x16 || cardID[21] != 0x11 || cardID[22] != 0x03 || !util.CheckCRC(cardID) {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara,
"message": api.CodeMsg[api.ErrorReqPara] + " 无效二维码",
})
return
}
res := qr2StudentsRes{
CardNum: string(cardID[:20]),
CardType: 1,
}
// 获取sim卡信息
simInfo := cache.GetSimInfo(res.CardNum) // 根据请求的卡号,获取系统中卡的信息
if simInfo == nil {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara,
"message": "卡号错误:系统找不到该卡号",
})
return
}
if simInfo.CardUserID != 0 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara,
"message": "该卡已被绑定",
})
return
}
if simInfo.Status == 0 || simInfo.AreaServiceID == 0 { // 没绑校区的卡视为未出库的卡
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara,
"message": "无效卡",
})
return
}
areaServiceInfo := cache.GetAreaServiceInfo(simInfo.AreaServiceID)
if areaServiceInfo == nil {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorSystemErr,
"message": api.CodeMsg[api.ErrorSystemErr] + " 查询不到区域服务信息",
})
return
}
// 取微信用户
v, ok := c.Get("userID")
weUserID := v.(uint32)
if ok != true || weUserID == 0 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorSystemErr,
"message": api.CodeMsg[api.ErrorSystemErr],
})
logger.Log.Error("Qr2Students",
zap.Reflect("c.Get(\"userID\")", v))
return
}
weUserInfo := cache.GetWeUserInfoFromMapAndDB(weUserID)
if weUserInfo == nil {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorSystemErr,
"message": api.CodeMsg[api.ErrorSystemErr],
})
logger.Log.Error("Qr2Students weUserInfo == nil",
zap.Uint32("weUserID", weUserID))
return
}
res.AreaID = areaServiceInfo.AreaID
res.AreaName = cache.GetAreaMapName(areaServiceInfo.AreaID, weUserInfo.TestRole)
if len(res.AreaName) == 0 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara,
"message": "对不起,您不具备测试区域权限,请联系管理员",
})
return
}
for _, cardUserID := range weUserInfo.MasterCardUserID {
cardUserInfo := cache.GetCardUserInfo(cardUserID)
if cardUserInfo != nil && cardUserInfo.AreaID == res.AreaID && len(cardUserInfo.SimCardID) == 0 { // 在卡这个校区的,且没绑卡的
res.Students = append(res.Students, struct {
Expiry string `json:"expiry"` // 缴费的到期时间,年月日(日期当天则仍在有效期内),展示给用户看,如果过了,就要先缴费才能绑卡
Name string `json:"name"` // 学生昵称,另外去把头像也拉下来展示出来
Sex uint8 `json:"sex"` // 性别 0,无信息,1女,2男
CID uint32 `json:"cid"` // 学生ID 等会调绑卡接口来用
Master bool `json:"master"` // 是否为主家长,页面上展示出来
}{
Expiry: cardUserInfo.PhoneExpiry.Format("2006-01-02"),
Name: cardUserInfo.Name,
Sex: cardUserInfo.Sex,
CID: cardUserID,
Master: true,
})
}
}
for _, cardUserID := range weUserInfo.SlaveCardUserID {
cardUserInfo := cache.GetCardUserInfo(cardUserID)
if cardUserInfo != nil && cardUserInfo.AreaID == res.AreaID && len(cardUserInfo.SimCardID) == 0 { // 在卡这个校区的,且没绑卡的
res.Students = append(res.Students, struct {
Expiry string `json:"expiry"` // 缴费的到期时间,年月日(日期当天则仍在有效期内),展示给用户看,如果过了,就要先缴费才能绑卡
Name string `json:"name"` // 学生昵称,另外去把头像也拉下来展示出来
Sex uint8 `json:"sex"` // 性别 0,无信息,1女,2男
CID uint32 `json:"cid"` // 学生ID 等会调绑卡接口来用
Master bool `json:"master"` // 是否为主家长,页面上展示出来
}{
Expiry: cardUserInfo.PhoneExpiry.Format("2006-01-02"),
Name: cardUserInfo.Name,
Sex: cardUserInfo.Sex,
CID: cardUserID,
Master: false,
})
}
}
c.JSON(http.StatusOK, gin.H{
"code": api.Success,
"data": res,
})
}
package api_we_msg
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"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"net/http"
"strconv"
)
//type reqDeleteMsg struct {
// CardUserID uint32 `json:"cardUserID"` // 学生ID
// MsgID []uint32 `json:"msgID"` // 留言ID
//}
// DeleteMsg 家长删除未读留言,主家长可删所有留言,附家长只能删自己发起的
// @Tags 家长微信-留言
// @Summary 家长删除未读留言
// @Description 家长删除未读留言
// @Produce json
// @Param cid path integer true "学生ID"
// @Param mid path integer true "留言ID"
// @Success 0
// @Router /we/msg/{cid}/{mid} [DELETE]
// @Security ApiKeyAuth
func DeleteMsg(c *gin.Context) {
cardUserIDInt64, _ := strconv.ParseInt(c.Param("cid"), 10, 32)
msgIDInt64, _ := strconv.ParseInt(c.Param("mid"), 10, 32)
if cardUserIDInt64 == 0 || msgIDInt64 == 0 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara,
"message": api.CodeMsg[api.ErrorReqPara],
})
return
}
cardUserID := uint32(cardUserIDInt64)
msgID := uint32(msgIDInt64)
// 取微信用户
v, ok := c.Get("userID")
weUserID := v.(uint32)
if ok != true || weUserID == 0 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorSystemErr,
"message": api.CodeMsg[api.ErrorSystemErr],
})
logger.Log.Error("DeleteMsg",
zap.Reflect("c.Get(\"userID\")", v))
return
}
// 校验weUserID是否有cardUserID权限
if cache.CheckCardUserMaserAndSlaveWeID(cardUserID, weUserID) < 2 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorUserRole,
"message": api.CodeMsg[api.ErrorUserRole],
})
return
}
if dbcurd.DeleteUMsgNRead(cardUserID, msgID) {
cache.DeleteOneNReadMsg(cardUserID, msgID)
c.JSON(http.StatusOK, gin.H{
"code": api.Success,
})
} else {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorSystemBusy,
"message": api.CodeMsg[api.ErrorSystemBusy],
})
}
}
package api_we_msg
import (
"dc_golang_server_1/api"
"dc_golang_server_1/data_db_cache/cache"
"dc_golang_server_1/logger"
"dc_golang_server_1/util"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"net/http"
"strconv"
"time"
)
type resNReadMsg struct {
ID uint32 `json:"id"`
Msg string `json:"msg"`
Nickname string `json:"nickname"` // 微信昵称
AvatarURL string `json:"avatarURL"` // 头像URL
Phone string `json:"phone"` // 手机号
CreateAt string `json:"createAt"` // 创建时间
DelEnable bool `json:"delEnable"` // 是否可删除
}
type msgPayStruct struct {
Status uint8 `json:"status"` // 0 留言服务已到期 1 未开通留言服务
Amount int32 `json:"amount"` // 金额
Expiry string `json:"expiry"` // 缴费后有效期
}
// GetMsgNRead 家长获取未读留言列表,主家长删所有留言,附家长只能删自己发起的
// @Tags 家长微信-留言
// @Summary 家长获取未读留言列表,注意,这个接口有可能返回 []resNReadMsg ,也有可能返回 msgPayStruct
// @Description 家长获取未读留言列表
// @Produce json
// @Param cid path integer true "学生ID"
// @Success 0 {object} []resNReadMsg "留言列表"
// @Failure 1 {object} msgPayStruct “支付信息”
// @Router /we/msgnread/{aid}/{cid} [GET]
// @Security ApiKeyAuth
func GetMsgNRead(c *gin.Context) {
cardUserIDInt64, _ := strconv.ParseInt(c.Param("cid"), 10, 32)
areaServiceIDInt64, _ := strconv.ParseInt(c.Param("aid"), 10, 32)
if cardUserIDInt64 == 0 || areaServiceIDInt64 == 0 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara,
"message": api.CodeMsg[api.ErrorReqPara],
})
return
}
cardUserID := uint32(cardUserIDInt64)
cardUserInfo := cache.GetCardUserInfo(cardUserID)
if cardUserInfo == nil {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorSystemErr,
"message": api.CodeMsg[api.ErrorSystemErr],
})
logger.Log.Error("GetMsgNRead cardUserInfo == nil",
zap.Uint32("cardUserID", cardUserID))
return
}
if time.Now().After(cardUserInfo.PhoneExpiry.Add(23 * time.Hour)) { // 话费服务都到期了
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara,
"message": "对不起,您的公话服务已到期",
})
return
}
if time.Now().Before(cardUserInfo.MsgExpiry.Add(23 * time.Hour)) { // 留言服务费未到期
// 取微信用户
v, ok := c.Get("userID")
weUserID := v.(uint32)
if ok != true || weUserID == 0 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorSystemErr,
"message": api.CodeMsg[api.ErrorSystemErr],
})
logger.Log.Error("GetMsgNRead",
zap.Reflect("c.Get(\"userID\")", v))
return
}
// 校验weUserID是否有cardUserID权限
if cache.CheckCardUserMaserAndSlaveWeID(cardUserID, weUserID) < 2 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorUserRole,
"message": api.CodeMsg[api.ErrorUserRole],
})
return
}
cacheRes := cache.GetNReadMsgMap(cardUserID)
res := make([]resNReadMsg, len(cacheRes))
for i, v1 := range cacheRes {
weInfo := cache.GetWeUserInfoFromMapAndDB(v1.WeUserID)
if weInfo != nil {
res[i].Nickname = weInfo.Nickname
res[i].Phone = weInfo.WePhone
res[i].AvatarURL = weInfo.AvatarURL
}
res[i].Msg = v1.Msg
res[i].DelEnable = true
res[i].ID = v1.ID
res[i].CreateAt = v1.CreateAt.Format("2006-01-02 15:04:05")
}
c.JSON(http.StatusOK, gin.H{
"code": api.Success,
"data": res,
})
} else {
msgFee := cache.GetPhoneMsgFeeMap(uint32(areaServiceIDInt64))
if msgFee == nil {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorServiceStop,
"message": api.CodeMsg[api.ErrorServiceStop],
})
return
}
var res msgPayStruct
if cardUserInfo.MsgExpiry == *new(time.Time) { // 未开通留言服务
res.Status = 1
}
res.Expiry = cardUserInfo.PhoneExpiry.Format("2006-01-02")
res.Amount = msgFee.Amount * util.SubMonth(cardUserInfo.PhoneExpiry, time.Now())
if res.Amount <= 0 {
res.Amount = 1 // 先收1分钱,后面来处理 todo
if msgFee.Amount == 0 {
logger.Log.Error("费率为0居然没开留言服务 GetMsgNRead", zap.Int64("areaServiceIDInt64", areaServiceIDInt64), zap.Uint32("cardUserID", cardUserID))
}
}
c.JSON(http.StatusOK, gin.H{
"code": api.Success,
"data": res,
})
}
}
package api_we_msg
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"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"net/http"
"strconv"
)
// GetMsgRead 家长获取已读留言列表
// @Tags 家长微信-留言
// @Summary 家长获取已读留言列表
// @Description 家长获取已读留言列表
// @Produce json
// @Param cid path integer true "学生ID"
// @Success 0 {object} []dbcurd.SelectUMsgReadRecordRes "留言列表"
// @Router /we/msgread/{aid}/{cid} [GET]
// @Security ApiKeyAuth
func GetMsgRead(c *gin.Context) {
cardUserIDInt64, _ := strconv.ParseInt(c.Param("cid"), 10, 32)
areaServiceIDInt64, _ := strconv.ParseInt(c.Param("aid"), 10, 32)
if cardUserIDInt64 == 0 || areaServiceIDInt64 == 0 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara,
"message": api.CodeMsg[api.ErrorReqPara],
})
return
}
cardUserID := uint32(cardUserIDInt64)
// 取微信用户
v, ok := c.Get("userID")
weUserID := v.(uint32)
if ok != true || weUserID == 0 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorSystemErr,
"message": api.CodeMsg[api.ErrorSystemErr],
})
logger.Log.Error("GetMsgRead",
zap.Reflect("c.Get(\"userID\")", v))
return
}
// 校验weUserID是否有cardUserID权限
if cache.CheckCardUserMaserAndSlaveWeID(cardUserID, weUserID) < 2 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorUserRole,
"message": api.CodeMsg[api.ErrorUserRole],
})
return
}
res := dbcurd.SelectUMsgReadRecord(cardUserID, uint32(areaServiceIDInt64))
for i, d := range res {
weUserInfo := cache.GetWeUserInfoFromMapAndDB(d.WeUserID)
if weUserInfo != nil {
res[i].Nickname = weUserInfo.Nickname
res[i].AvatarURL = weUserInfo.AvatarURL
res[i].Phone = weUserInfo.WePhone
}
}
c.JSON(http.StatusOK, gin.H{
"code": api.Success,
"data": res,
})
}
package api_we_msg
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/data_db_cache/model"
"dc_golang_server_1/logger"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"net/http"
"time"
)
// PostMsg 家长向学生发起留言
// @Tags 家长微信-留言
// @Summary 家长向学生发起留言
// @Description 家长向学生发起留言,注意,超过10条将删除前面的留言
// @Accept json
// @Produce json
// @Param data body dbcurd.InsertTableUMsgNReadStruct true "留言信息"
// @Success 0
// @Router /we/msg [POST]
// @Security ApiKeyAuth
func PostMsg(c *gin.Context) {
var reqData dbcurd.InsertTableUMsgNReadStruct
err := c.ShouldBindJSON(&reqData)
if err != nil || reqData.CardUserID == 0 || reqData.AreaServiceID == 0 || len(reqData.Msg) == 0 || len(reqData.Msg) > 300 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqParaFormat,
"message": api.CodeMsg[api.ErrorReqParaFormat],
})
return
}
// 取微信用户
v, ok := c.Get("userID")
reqData.WeUserID = v.(uint32)
if ok != true || reqData.WeUserID == 0 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorSystemErr,
"message": api.CodeMsg[api.ErrorSystemErr],
})
logger.Log.Error("GetCallRecord",
zap.Reflect("c.Get(\"userID\")", v))
return
}
// 校验weUserID是否有cardUserID权限
if cache.CheckCardUserMaserAndSlaveWeID(reqData.CardUserID, reqData.WeUserID) < 2 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorUserRole,
"message": api.CodeMsg[api.ErrorUserRole],
})
return
}
//cardUserInfo := cache.GetCardUserInfo(reqData.CardUserID)
//if cardUserInfo == nil {
// c.JSON(http.StatusOK, gin.H{
// "code": api.ErrorSystemErr,
// "message": api.CodeMsg[api.ErrorSystemErr],
// })
// logger.Log.Error("PostMsg cardUserInfo == nil",
// zap.Reflect("reqData", reqData))
// return
//}
//CardUserID uint32 `json:"cardUserID"` // 学生ID
//AreaServiceID uint32 `json:"-"`
//WeUserID uint32 `json:"-"`
//Msg string `json:"msg"` // 留言内容
reqData.CreateAt = time.Now()
msgID := dbcurd.InsertUMsgNRead(&reqData)
if msgID == 0 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorSystemBusy,
"message": api.CodeMsg[api.ErrorSystemBusy],
})
return
}
cache.InsertNReadMsgMap(reqData.CardUserID, &model.CacheCardUserNReadMsgStruct{
ID: msgID,
CreateAt: reqData.CreateAt,
WeUserID: reqData.WeUserID,
Msg: reqData.Msg,
})
c.JSON(http.StatusOK, gin.H{
"code": api.Success,
})
}
...@@ -17,6 +17,7 @@ type getPhoneCardStatusRes struct { ...@@ -17,6 +17,7 @@ type getPhoneCardStatusRes struct {
model.CacheSimInfoStruct model.CacheSimInfoStruct
ExpiryAtString string `json:"expiryAt"` // 给前端返回年月日 ExpiryAtString string `json:"expiryAt"` // 给前端返回年月日
MaxFamily uint8 `json:"maxFamily"` // 最多可以添加几个亲情号 MaxFamily uint8 `json:"maxFamily"` // 最多可以添加几个亲情号
MsgEnable bool `json:"msgEnable"` // 是否显示留言按钮(本区域服务是否开通留言服务)
} }
// GetPhoneCardStatus 获取学生公话卡状态 // GetPhoneCardStatus 获取学生公话卡状态
...@@ -146,6 +147,7 @@ func GetPhoneCardStatus(c *gin.Context) { // 以后要改成根据区域服务 ...@@ -146,6 +147,7 @@ func GetPhoneCardStatus(c *gin.Context) { // 以后要改成根据区域服务
CacheSimInfoStruct: *res, CacheSimInfoStruct: *res,
ExpiryAtString: res.ExpiryAt.Format("2006-01-02"), ExpiryAtString: res.ExpiryAt.Format("2006-01-02"),
MaxFamily: 2, MaxFamily: 2,
MsgEnable: cache.GetPhoneMsgFeeMap(res.AreaServiceID) != nil, // 如果留言服务费缓存有该区域服务ID,则说明该区域服务开通了留言功能
}, },
}) })
} }
......
...@@ -20,6 +20,7 @@ import ( ...@@ -20,6 +20,7 @@ import (
type wePostPayReq struct { type wePostPayReq struct {
CID uint32 `json:"cid"` // 学生id CID uint32 `json:"cid"` // 学生id
LID uint32 `json:"lid"` // 选填,话费支付列表id,若不传则不充话费,只是开卡或补卡(实际应用中,补卡就不传这个) LID uint32 `json:"lid"` // 选填,话费支付列表id,若不传则不充话费,只是开卡或补卡(实际应用中,补卡就不传这个)
Msg bool `json:"msg"` // 选填,补开通留言服务或充话费时才有效,且即便是充话费的时候都可以不填,不填就默认不开通留言服务,若只填了CID和Msg则为补开通留言服务
CardFeeType uint8 `json:"cardFeeType"` // 选填 1开卡/2补卡 CardFeeType uint8 `json:"cardFeeType"` // 选填 1开卡/2补卡
} }
...@@ -46,7 +47,7 @@ func PostPay(c *gin.Context) { ...@@ -46,7 +47,7 @@ func PostPay(c *gin.Context) {
} }
aidInt64, _ := strconv.ParseInt(c.Param("aid"), 10, 32) aidInt64, _ := strconv.ParseInt(c.Param("aid"), 10, 32)
if aidInt64 == 0 || reqData.CID == 0 || (reqData.LID == 0 && reqData.CardFeeType == 0) { // 既不缴卡费又不充话 if aidInt64 == 0 || reqData.CID == 0 || (reqData.LID == 0 && reqData.CardFeeType == 0 && reqData.Msg == false) { // 既不缴卡费又不充话费还不是补交留言
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara, "code": api.ErrorReqPara,
"message": api.CodeMsg[api.ErrorReqPara], "message": api.CodeMsg[api.ErrorReqPara],
...@@ -159,6 +160,7 @@ func PostPay(c *gin.Context) { ...@@ -159,6 +160,7 @@ func PostPay(c *gin.Context) {
//orderNum := strconv.FormatUint(uint64(reqData.CID), 10) + "_" + //strconv.FormatInt(lidInt64, 10) + "_" + //orderNum := strconv.FormatUint(uint64(reqData.CID), 10) + "_" + //strconv.FormatInt(lidInt64, 10) + "_" +
// strconv.FormatUint(uint64(payInfo.Amount), 10) + "_" + productTime.Format("060102150405.000000000") + "_" + payInfo.Expiry // strconv.FormatUint(uint64(payInfo.Amount), 10) + "_" + productTime.Format("060102150405.000000000") + "_" + payInfo.Expiry
var expiry uint8
if reqData.LID > 0 { // 要缴话费 if reqData.LID > 0 { // 要缴话费
payType |= 0x10 payType |= 0x10
var payInfo model.CacheAreaServicePhonePayListStruct var payInfo model.CacheAreaServicePhonePayListStruct
...@@ -172,6 +174,7 @@ func PostPay(c *gin.Context) { ...@@ -172,6 +174,7 @@ func PostPay(c *gin.Context) {
newExpiry = util.RenewExpiry(cardUserInfo.PhoneExpiry, payInfo.Expiry) // 续费 newExpiry = util.RenewExpiry(cardUserInfo.PhoneExpiry, payInfo.Expiry) // 续费
} }
expiry = payInfo.Expiry
applyPayPara.Amount += payInfo.Amount applyPayPara.Amount += payInfo.Amount
applyPayPara.SplitAmount = payInfo.SplitAmount applyPayPara.SplitAmount = payInfo.SplitAmount
break break
...@@ -187,6 +190,42 @@ func PostPay(c *gin.Context) { ...@@ -187,6 +190,42 @@ func PostPay(c *gin.Context) {
} }
} }
if reqData.Msg { // 要缴留言服务费
msgFee := cache.GetPhoneMsgFeeMap(aid)
if msgFee == nil {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara,
"message": api.CodeMsg[api.ErrorReqPara] + "该区域未开通留言服务",
})
return
}
payType |= 0x20 // 要开通留言服务
if msgFee.Amount > 0 {
if expiry > 0 {
applyPayPara.Amount += msgFee.Amount * int32(expiry)
} else { // todo 处理下留言续费逻辑
applyPayPara.Amount += msgFee.Amount * util.SubMonth(cardUserInfo.PhoneExpiry, time.Now())
}
for v1i, v1 := range applyPayPara.SplitAmount {
for v2i, v2 := range msgFee.SplitAmount {
if v1.AdminID == v2.AdminID {
applyPayPara.SplitAmount[v1i].Amount += v2.Amount * int32(expiry)
applyPayPara.SplitAmount[v1i].Remark += "(" + strconv.FormatUint(uint64(v1.Amount), 10) + "分)+留言服务费:" + v2.Remark + "(" + strconv.FormatUint(uint64(v2.Amount), 10) + "分)"
msgFee.SplitAmount = append(msgFee.SplitAmount[:v2i], msgFee.SplitAmount[v2i+1:]...)
break
}
}
}
for _, v1 := range msgFee.SplitAmount {
applyPayPara.SplitAmount = append(applyPayPara.SplitAmount, model.PaySplitMoneyStruct{
AdminID: v1.AdminID,
Amount: v1.Amount,
Remark: "留言服务费:" + v1.Remark,
})
}
}
}
if payType == 0 { if payType == 0 {
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara, "code": api.ErrorReqPara,
...@@ -195,7 +234,15 @@ func PostPay(c *gin.Context) { ...@@ -195,7 +234,15 @@ func PostPay(c *gin.Context) {
return return
} }
// 订单号生成规则:4B cardUserID,4B到期时间,4B 金额amount,8B 时间纳秒 if applyPayPara.Amount == 0 {
c.JSON(http.StatusOK, gin.H{
"code": api.ErrorReqPara,
"message": api.CodeMsg[api.ErrorReqPara] + " 对应充值项已失效",
})
return
}
// 订单号生成规则:4B cardUserID,4B到期时间,4B 金额amount,,1B payType,8B 时间纳秒
productTime := time.Now() productTime := time.Now()
unixNano := productTime.UnixNano() unixNano := productTime.UnixNano()
ex := uint32(newExpiry.Unix()) ex := uint32(newExpiry.Unix())
...@@ -212,6 +259,7 @@ func PostPay(c *gin.Context) { ...@@ -212,6 +259,7 @@ func PostPay(c *gin.Context) {
byte(applyPayPara.Amount >> 16), byte(applyPayPara.Amount >> 16),
byte(applyPayPara.Amount >> 8), byte(applyPayPara.Amount >> 8),
byte(applyPayPara.Amount), byte(applyPayPara.Amount),
payType,
byte(unixNano >> 56), byte(unixNano >> 56),
byte(unixNano >> 48), byte(unixNano >> 48),
byte(unixNano >> 40), byte(unixNano >> 40),
...@@ -220,7 +268,6 @@ func PostPay(c *gin.Context) { ...@@ -220,7 +268,6 @@ func PostPay(c *gin.Context) {
byte(unixNano >> 16), byte(unixNano >> 16),
byte(unixNano >> 8), byte(unixNano >> 8),
byte(unixNano), byte(unixNano),
byte(0x55),
}) })
dbInsertData := dbcurd.InsertTableUPhonePayRecordAndSplit{ dbInsertData := dbcurd.InsertTableUPhonePayRecordAndSplit{
...@@ -236,8 +283,8 @@ func PostPay(c *gin.Context) { ...@@ -236,8 +283,8 @@ func PostPay(c *gin.Context) {
ProductAt: productTime, ProductAt: productTime,
PayAdminID: areaServiceInfo.PayAdminID, // 通联支付取消微信MchID增加收款主体的adminID PayAdminID: areaServiceInfo.PayAdminID, // 通联支付取消微信MchID增加收款主体的adminID
// Describe: "", // Describe: "",
ExpiryAt: newExpiry, ExpiryAt: newExpiry,
Type: payType, // // 缴费类型:1仅开卡 2仅补卡 16续费 17开卡+充值 18补卡+续费 Type: payType, // // 缴费类型:1仅开卡 2仅补卡 16续费 17开卡+充值 18补卡+续费
SplitAmount: applyPayPara.SplitAmount, SplitAmount: applyPayPara.SplitAmount,
} }
switch payType { switch payType {
...@@ -251,6 +298,15 @@ func PostPay(c *gin.Context) { ...@@ -251,6 +298,15 @@ func PostPay(c *gin.Context) {
dbInsertData.Describe = "充值(含开卡)" dbInsertData.Describe = "充值(含开卡)"
case 0x12: case 0x12:
dbInsertData.Describe = "充值(含补卡)" dbInsertData.Describe = "充值(含补卡)"
case 0x20: // 仅补缴留言服务
// todo zjzjzj 判断是否已经有家长缴费了,如果有了不允许再补交
dbInsertData.Describe = "留言服务费"
case 0x20 + 0x10:
dbInsertData.Describe = "话费充值(含留言服务)"
case 0x20 + 0x11:
dbInsertData.Describe = "充值(含开卡、留言服务)"
case 0x20 + 0x12:
dbInsertData.Describe = "充值(含补卡、留言服务)"
} }
//if dbcurd.InsertUPhonePayRecord(&dbInsertData) != dbcurd.InsertOK { //if dbcurd.InsertUPhonePayRecord(&dbInsertData) != dbcurd.InsertOK {
...@@ -282,8 +338,6 @@ func PostPay(c *gin.Context) { ...@@ -282,8 +338,6 @@ func PostPay(c *gin.Context) {
"code": api.Success, "code": api.Success,
"data": res, "data": res,
}) })
return
} }
//type wechatPostPayTest struct { //type wechatPostPayTest struct {
......
...@@ -15,6 +15,7 @@ type getPreviewCardUserStruct struct { ...@@ -15,6 +15,7 @@ type getPreviewCardUserStruct struct {
Name string `json:"name"` // 学生名字,脱敏显示 Name string `json:"name"` // 学生名字,脱敏显示
Area string `json:"area" example:"温江实验中学"` // 区域名字 Area string `json:"area" example:"温江实验中学"` // 区域名字
ID uint32 `json:"id"` // 学生ID ID uint32 `json:"id"` // 学生ID
Sex uint8 `json:"sex"` //0,无信息,1女,2男
} }
// GetPreviewCardUser 通过邀请码获取学生预览信息 // GetPreviewCardUser 通过邀请码获取学生预览信息
...@@ -147,6 +148,7 @@ func GetPreviewCardUser(c *gin.Context) { ...@@ -147,6 +148,7 @@ func GetPreviewCardUser(c *gin.Context) {
cardUserInfo.Name, cardUserInfo.Name,
cache.GetAreaMapName(cardUserInfo.AreaID, true), cache.GetAreaMapName(cardUserInfo.AreaID, true),
cardUserID, //api_we_student.GetCardUserDownSmallAvatarQiNiuURL(cardUserID), cardUserID, //api_we_student.GetCardUserDownSmallAvatarQiNiuURL(cardUserID),
cardUserInfo.Sex,
}, },
}) })
} }
...@@ -11,7 +11,7 @@ import ( ...@@ -11,7 +11,7 @@ import (
) )
type slaveWeUserRes struct { type slaveWeUserRes struct {
WeUserID uint32 `json:"weUserID"` // 微信UnionID WeUserID uint32 `json:"weUserID"` // 微信用户ID
Nickname string `json:"nickname"` // 微信昵称 Nickname string `json:"nickname"` // 微信昵称
AvatarURL string `json:"avatarURL"` // 头像URL AvatarURL string `json:"avatarURL"` // 头像URL
Phone string `json:"phone"` // 手机号 Phone string `json:"phone"` // 手机号
......
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
"dc_golang_server_1/api/api_server_ops" "dc_golang_server_1/api/api_server_ops"
"dc_golang_server_1/api/api_we/api_we_card_operate" "dc_golang_server_1/api/api_we/api_we_card_operate"
"dc_golang_server_1/api/api_we/api_we_login_we_info" "dc_golang_server_1/api/api_we/api_we_login_we_info"
"dc_golang_server_1/api/api_we/api_we_msg"
"dc_golang_server_1/api/api_we/api_we_phone_card" "dc_golang_server_1/api/api_we/api_we_phone_card"
"dc_golang_server_1/api/api_we/api_we_phone_pay" "dc_golang_server_1/api/api_we/api_we_phone_pay"
"dc_golang_server_1/api/api_we/api_we_slave" "dc_golang_server_1/api/api_we/api_we_slave"
...@@ -135,10 +136,11 @@ func InitRouter() { //*gin.Engine{ ...@@ -135,10 +136,11 @@ func InitRouter() { //*gin.Engine{
//wechat.PUT("cardusershareoff/:id", api_we.PutCardUserShareOff) //关闭邀请码开关(仅主家长有权限) //wechat.PUT("cardusershareoff/:id", api_we.PutCardUserShareOff) //关闭邀请码开关(仅主家长有权限)
wechat.DELETE("slaveweuser/:id", api_we_slave.DeleteSlaveWeUser) //删除副家长(仅主家长有权限) wechat.DELETE("slaveweuser/:id", api_we_slave.DeleteSlaveWeUser) //删除副家长(仅主家长有权限)
wechat.GET("qr2cardid/:qrcode", api_we_card_operate.Qr2CardID) // Qr2CardID 根据二维码,返回卡号信息 wechat.GET("qr2cardid/:qrcode", api_we_card_operate.Qr2CardID) // Qr2CardID 根据二维码,返回卡号信息
wechat.PUT("cardloss/:id", api_we_card_operate.CardLoss) //卡挂失/解挂 wechat.GET("qr2students/:qrcode", api_we_card_operate.Qr2Students) // Qr2CardID 根据二维码,返回用户状态信息及卡号
wechat.PUT("cardbind/:id", api_we_card_operate.CardBind) //绑定卡 wechat.PUT("cardloss/:id", api_we_card_operate.CardLoss) //卡挂失/解挂
wechat.DELETE("cardbind/:id", api_we_card_operate.DeleteCardBind) //解绑卡 wechat.PUT("cardbind/:id", api_we_card_operate.CardBind) //绑定卡
wechat.DELETE("cardbind/:id", api_we_card_operate.DeleteCardBind) //解绑卡
wechat.GET("phonecardstatus/:id", api_we_phone_card.GetPhoneCardStatus) //获取学生公话卡状态 wechat.GET("phonecardstatus/:id", api_we_phone_card.GetPhoneCardStatus) //获取学生公话卡状态
wechat.POST("familynum/:id", api_we_phone_card.AddFamilyNum) //添加亲情号 wechat.POST("familynum/:id", api_we_phone_card.AddFamilyNum) //添加亲情号
...@@ -157,8 +159,10 @@ func InitRouter() { //*gin.Engine{ ...@@ -157,8 +159,10 @@ func InitRouter() { //*gin.Engine{
// wechat.GET("replacecardfee/phone/:aid", api_we_phone_pay.GetReplaceCardFeePhone) //查询补卡费(目前仅公话卡) // wechat.GET("replacecardfee/phone/:aid", api_we_phone_pay.GetReplaceCardFeePhone) //查询补卡费(目前仅公话卡)
// wechat.POST("payreplacecard/phone/:aid/:cid", api_we_phone_pay.PostPayReplaceCard) //补卡缴费(目前仅公话卡) // wechat.POST("payreplacecard/phone/:aid/:cid", api_we_phone_pay.PostPayReplaceCard) //补卡缴费(目前仅公话卡)
//获取学生定位卡状态 wechat.GET("msgnread/:aid/:cid", api_we_msg.GetMsgNRead) // 家长获取未读留言列表
//查询通行记录 wechat.GET("msgread/:aid/:cid", api_we_msg.GetMsgRead) // 家长获取已读留言列表
wechat.POST("msg", api_we_msg.PostMsg) // 家长向学生发起留言
wechat.DELETE("msg/:cid/:mid", api_we_msg.DeleteMsg) // 家长删除未读留言,主家长删所有留言,附家长只能删自己发起的
} }
//// r.POST("ad/login", api_we.AdminLogin) //// r.POST("ad/login", api_we.AdminLogin)
...@@ -184,7 +188,7 @@ func InitRouter() { //*gin.Engine{ ...@@ -184,7 +188,7 @@ func InitRouter() { //*gin.Engine{
phone := r.Group("phone20/") phone := r.Group("phone20/")
// phone.Use(adminCors(),api.JeffWTPublic()) // phone.Use(adminCors(),api.JeffWTPublic())
dcphone20.TCP.NewDCPhone20API(phone) dcphone20.TCP.NewDCPhone20API(phone) // todo 改到admin去
fmt.Println("根路径: " + setting.HttpServerMainHost + setting.HttpServerPort) fmt.Println("根路径: " + setting.HttpServerMainHost + setting.HttpServerPort)
......
[token] [token]
KEY = `jeffWT@666%b;'~+` KEY = `dcrymk12testabcd`
[grpc_server] [grpc_server]
Grpc2AdminListenPort = :7010 Grpc2AdminListenPort = :7010
Grpc2TcpConnListenPort = :7011 Grpc2TcpConnListenPort = :7011
[grpc_client] [grpc_client]
GrpcFromDeviceConnServerIpPort = 127.0.0.1:7020 #GrpcFromDeviceConnServerIpPort = 127.0.0.1:7020
#GrpcFromDeviceConnServerIpPort = 192.168.1.43:7020
GrpcFromDeviceConnServerIpPort = k12t.shero.plus:7020
[allin_pay] [allin_pay]
#测试 K12B 正式 K12B- #测试 K12B 正式 K12B-
...@@ -57,11 +59,13 @@ AppSecret = 8e007ad30204af2a64af27ecc88b54e7 ...@@ -57,11 +59,13 @@ AppSecret = 8e007ad30204af2a64af27ecc88b54e7
[sms_captcha] [sms_captcha]
#短信验证码服务器请求地址 #短信验证码服务器请求地址
#url = http://127.0.0.1:6051 #url = http://127.0.0.1:6051
url = http://192.168.1.43:6051 url = http://k12t.shero.plus:6051
#url = http://192.168.1.43:6051
[firmware_server] [firmware_server]
#固件服务器地址 #固件服务器地址
baseUrl = http://192.168.1.41:6031 #baseUrl = http://192.168.1.41:6031
baseUrl = http://k12t.shero.plus:6031
deviceUrl = http://k12t.shero.plus:6031 deviceUrl = http://k12t.shero.plus:6031
[log] [log]
......
...@@ -14,8 +14,11 @@ func Init() { ...@@ -14,8 +14,11 @@ func Init() {
initWechatAndCardUserRelationToWechatCustomerMapAndCardUserMap() initWechatAndCardUserRelationToWechatCustomerMapAndCardUserMap()
initSimInfoMap() initSimInfoMap()
initAreaServiceMap() initAreaServiceMap()
initPhoneMsgFeeMap()
initPhone20DeviceMap() initPhone20DeviceMap()
initCardUserTrendMap() initCardUserTrendMap()
initNReadMsgMap()
initAreaServicePhonePayListMap() initAreaServicePhonePayListMap()
areaServicePhonePayListMapAddSplit() // 区域服务收款项列表添加分账列表 areaServicePhonePayListMapAddSplit() // 区域服务收款项列表添加分账列表
// initWechatMchInfoMap() // initWechatMchInfoMap()
...@@ -36,6 +39,9 @@ var areaMap sync.Map // 有列表,全局锁增删改 仅GRPC ...@@ -36,6 +39,9 @@ var areaMap sync.Map // 有列表,全局锁增删改 仅GRPC
// status不为0的所有区域服务 map[uint32_areaServiceID]model.CacheAreaServiceStruct -----OK // status不为0的所有区域服务 map[uint32_areaServiceID]model.CacheAreaServiceStruct -----OK
var areaServiceMap sync.Map // 无列表,直接增删改 仅GRPC var areaServiceMap sync.Map // 无列表,直接增删改 仅GRPC
// 话机留言服务费缓存,若没有对应的区域服务ID,则该区域服务未开通留言功能 map[uint32_areaServiceID]model.CachePhoneMsgFeeStruct
var phoneMsgFeeMap sync.Map
// 校区服务支付信息 map[uint32_areaServiceID][]model.CacheAreaServicePhonePayListStruct 仅缓存库里面status==true的项 -----OK // 校区服务支付信息 map[uint32_areaServiceID][]model.CacheAreaServicePhonePayListStruct 仅缓存库里面status==true的项 -----OK
var areaServicePhonePayListMap sync.Map // 列表,全局锁增删改 仅GRPC var areaServicePhonePayListMap sync.Map // 列表,全局锁增删改 仅GRPC
...@@ -66,5 +72,8 @@ var cardUserMap sync.Map //有列表,大并发量,channel增删改 ...@@ -66,5 +72,8 @@ var cardUserMap sync.Map //有列表,大并发量,channel增删改
// 学生最新动态 map[uint32_cardUserID][]model.CacheCardUserTrendStruct -----OK // 学生最新动态 map[uint32_cardUserID][]model.CacheCardUserTrendStruct -----OK
var cardUserTrendMap sync.Map //有列表,全局锁增删改 var cardUserTrendMap sync.Map //有列表,全局锁增删改
// 学生未读留言缓存,每个学生最多10条未读留言 map[uint32_cardUserID][]model.CacheCardUserNReadMsgStruct
var nReadMsgMap sync.Map //
// 固件升级缓存 存设备号和期望的固件版本,如果设备已经是期望版本,则删除 // 固件升级缓存 存设备号和期望的固件版本,如果设备已经是期望版本,则删除
var deviceUpdateFirmwareMapPhone20 sync.Map // map[deviceID uint32]firmwareName string var deviceUpdateFirmwareMapPhone20 sync.Map // map[deviceID uint32]firmwareName string
...@@ -17,7 +17,7 @@ func initAreaServicePhonePayListMap() { // 存入status为true且verify_result=1 ...@@ -17,7 +17,7 @@ func initAreaServicePhonePayListMap() { // 存入status为true且verify_result=1
fmt.Println(time.Now(), "cache: initAreaServicePhonePayListMap begin") fmt.Println(time.Now(), "cache: initAreaServicePhonePayListMap begin")
// rows, err := dbcurd.PgDb.Query("SELECT id,area_service_id,expiry,amount,month_min,describe FROM b_phone_pay_list WHERE status=true and verify_result=1 ORDER BY create_at") // 暂时不管审核的事情 // rows, err := dbcurd.PgDb.Query("SELECT id,area_service_id,expiry,amount,month_min,describe FROM b_phone_pay_list WHERE status=true and verify_result=1 ORDER BY create_at") // 暂时不管审核的事情
rows, err := dbcurd.PgDb.Query("SELECT id,area_service_id,expiry,amount,month_min,describe,status FROM b_phone_pay_list ORDER BY create_at") // 暂时不管审核的事情 rows, err := dbcurd.PgDb.Query("SELECT id,area_service_id,expiry,amount,month_min,describe,status,msg_enable FROM b_phone_pay_list ORDER BY create_at") // 暂时不管审核的事情
if err != nil { if err != nil {
log.Panicln("initAreaServicePhonePayListMap rows", err) log.Panicln("initAreaServicePhonePayListMap rows", err)
} }
...@@ -28,20 +28,20 @@ func initAreaServicePhonePayListMap() { // 存入status为true且verify_result=1 ...@@ -28,20 +28,20 @@ func initAreaServicePhonePayListMap() { // 存入status为true且verify_result=1
var temp model.CacheAreaServicePhonePayListStruct var temp model.CacheAreaServicePhonePayListStruct
for rows.Next() { for rows.Next() {
var list []model.CacheAreaServicePhonePayListStruct var list []model.CacheAreaServicePhonePayListStruct
err = rows.Scan(&temp.ID, &areaServiceID, &temp.Expiry, &temp.Amount, &temp.MonthMin, &temp.Describe, &temp.Status) err = rows.Scan(&temp.ID, &areaServiceID, &temp.Expiry, &temp.Amount, &temp.MonthMin, &temp.Describe, &temp.Status, &temp.MsgEnable)
if err != nil { if err != nil {
log.Panicln("initAreaServicePhonePayListMap rows.Scan", err) log.Panicln("initAreaServicePhonePayListMap rows.Scan", err)
} }
//if t.After(time.Now()) { //if t.After(time.Now()) {
if areaServiceID > 0 { if areaServiceID > 0 {
if v, ok := areaServicePhonePayListMap.Load(areaServiceID); ok { if v, ok := areaServicePhonePayListMap.Load(areaServiceID); ok {
list, _ = v.([]model.CacheAreaServicePhonePayListStruct) list, _ = v.([]model.CacheAreaServicePhonePayListStruct)
}
list = append(list, temp)
areaServicePhonePayListMap.Store(areaServiceID, list)
// fmt.Println(areaServiceID,list)
} }
list = append(list, temp)
areaServicePhonePayListMap.Store(areaServiceID, list)
// fmt.Println(areaServiceID,list)
}
//} else { //} else {
// logger.Log.Error("充值项已到期", // logger.Log.Error("充值项已到期",
// zap.String("Src", "initAreaServicePhonePayListMap"), // zap.String("Src", "initAreaServicePhonePayListMap"),
...@@ -89,20 +89,20 @@ func GetAreaServicePhonePayListMap(areaServiceID uint32) []model.CacheAreaServic ...@@ -89,20 +89,20 @@ func GetAreaServicePhonePayListMap(areaServiceID uint32) []model.CacheAreaServic
var areaServicePhonePayListMapUpdateLock sync.Mutex // 直接全局锁 var areaServicePhonePayListMapUpdateLock sync.Mutex // 直接全局锁
// AddPhonePayListMap 仅GRPC调用,给校区服务添加一项支付项 // AddPhonePayListMap 仅GRPC调用,给校区服务添加一项支付项
func AddPhonePayListMap(areaServiceID uint32,newData *model.CacheAreaServicePhonePayListStruct) error { func AddPhonePayListMap(areaServiceID uint32, newData *model.CacheAreaServicePhonePayListStruct) error {
areaServicePhonePayListMapUpdateLock.Lock() areaServicePhonePayListMapUpdateLock.Lock()
defer areaServicePhonePayListMapUpdateLock.Unlock() defer areaServicePhonePayListMapUpdateLock.Unlock()
if v, ok := areaServicePhonePayListMap.Load(areaServiceID); ok { if v, ok := areaServicePhonePayListMap.Load(areaServiceID); ok {
if list, ok := v.([]model.CacheAreaServicePhonePayListStruct); ok { if list, ok := v.([]model.CacheAreaServicePhonePayListStruct); ok {
for i,oldData := range list { for i, oldData := range list {
if oldData.ID == newData.ID{ // 如果已经有这个ID的了,先删除 if oldData.ID == newData.ID { // 如果已经有这个ID的了,先删除
list = append(list[:i], list[i+1:]...) list = append(list[:i], list[i+1:]...)
// break 等它遍历完 // break 等它遍历完
} }
} }
list = append(list,*newData) list = append(list, *newData)
areaServicePhonePayListMap.Store(areaServiceID,list) areaServicePhonePayListMap.Store(areaServiceID, list)
return nil return nil
} else { } else {
areaServicePhonePayListMap.Delete(areaServiceID) areaServicePhonePayListMap.Delete(areaServiceID)
...@@ -112,24 +112,24 @@ func AddPhonePayListMap(areaServiceID uint32,newData *model.CacheAreaServicePhon ...@@ -112,24 +112,24 @@ func AddPhonePayListMap(areaServiceID uint32,newData *model.CacheAreaServicePhon
} }
} }
areaServicePhonePayListMap.Store(areaServiceID,[]model.CacheAreaServicePhonePayListStruct{*newData}) areaServicePhonePayListMap.Store(areaServiceID, []model.CacheAreaServicePhonePayListStruct{*newData})
return nil return nil
} }
// DelPhonePayListMap 仅GRPC调用,校区服务删除一项支付项 // DelPhonePayListMap 仅GRPC调用,校区服务删除一项支付项
func DelPhonePayListMap(areaServiceID , payListID uint32) { func DelPhonePayListMap(areaServiceID, payListID uint32) {
areaServicePhonePayListMapUpdateLock.Lock() areaServicePhonePayListMapUpdateLock.Lock()
defer areaServicePhonePayListMapUpdateLock.Unlock() defer areaServicePhonePayListMapUpdateLock.Unlock()
if v, ok := areaServicePhonePayListMap.Load(areaServiceID); ok { if v, ok := areaServicePhonePayListMap.Load(areaServiceID); ok {
if list, ok := v.([]model.CacheAreaServicePhonePayListStruct); ok { if list, ok := v.([]model.CacheAreaServicePhonePayListStruct); ok {
for i,oldData := range list { for i, oldData := range list {
if oldData.ID == payListID{ if oldData.ID == payListID {
list = append(list[:i], list[i+1:]...) list = append(list[:i], list[i+1:]...)
if len(list) == 0 { if len(list) == 0 {
areaServicePhonePayListMap.Delete(areaServiceID) areaServicePhonePayListMap.Delete(areaServiceID)
} else { } else {
areaServicePhonePayListMap.Store(areaServiceID,list) areaServicePhonePayListMap.Store(areaServiceID, list)
} }
return return
} }
...@@ -144,16 +144,16 @@ func DelPhonePayListMap(areaServiceID , payListID uint32) { ...@@ -144,16 +144,16 @@ func DelPhonePayListMap(areaServiceID , payListID uint32) {
} }
// UpdatePhonePayListMap 仅GRPC调用,修改校区服务支付项 // UpdatePhonePayListMap 仅GRPC调用,修改校区服务支付项
func UpdatePhonePayListMap(areaServiceID uint32,newData *model.CacheAreaServicePhonePayListStruct) error { func UpdatePhonePayListMap(areaServiceID uint32, newData *model.CacheAreaServicePhonePayListStruct) error {
areaServicePhonePayListMapUpdateLock.Lock() areaServicePhonePayListMapUpdateLock.Lock()
defer areaServicePhonePayListMapUpdateLock.Unlock() defer areaServicePhonePayListMapUpdateLock.Unlock()
if v, ok := areaServicePhonePayListMap.Load(areaServiceID); ok { if v, ok := areaServicePhonePayListMap.Load(areaServiceID); ok {
if list, ok := v.([]model.CacheAreaServicePhonePayListStruct); ok { if list, ok := v.([]model.CacheAreaServicePhonePayListStruct); ok {
for i,oldData := range list { for i, oldData := range list {
if oldData.ID == newData.ID{ if oldData.ID == newData.ID {
list[i] = *newData list[i] = *newData
areaServicePhonePayListMap.Store(areaServiceID,list) areaServicePhonePayListMap.Store(areaServiceID, list)
return nil return nil
} }
} }
...@@ -165,5 +165,5 @@ func UpdatePhonePayListMap(areaServiceID uint32,newData *model.CacheAreaServiceP ...@@ -165,5 +165,5 @@ func UpdatePhonePayListMap(areaServiceID uint32,newData *model.CacheAreaServiceP
} }
} }
return errors.New("未找到ID为:"+ strconv.FormatUint(uint64(newData.ID),10) +"的支付项") return errors.New("未找到ID为:" + strconv.FormatUint(uint64(newData.ID), 10) + "的支付项")
} }
\ No newline at end of file
...@@ -26,17 +26,17 @@ func areaServicePhonePayListMapAddSplit() { // 区域服务收款项列表添加 ...@@ -26,17 +26,17 @@ func areaServicePhonePayListMapAddSplit() { // 区域服务收款项列表添加
return true return true
}) })
fmt.Println(time.Now(), "init areaServicePhonePayListMap SplitAmount end") fmt.Println(time.Now(), "cache: init areaServicePhonePayListMap SplitAmount end")
} }
func areaServicePhonePayListMapAddSplitByPayListID(payListID uint32) (res []model.PhonePaySplitMoneyStruct) { func areaServicePhonePayListMapAddSplitByPayListID(payListID uint32) (res []model.PaySplitMoneyStruct) {
rows, err := dbcurd.PgDb.Query("SELECT admin_id,amount FROM b_pay_split_money WHERE pay_list_id=$1", payListID) // rows, err := dbcurd.PgDb.Query("SELECT admin_id,amount FROM b_pay_split_money WHERE pay_list_id=$1", payListID) //
if err != nil { if err != nil {
log.Panicln("areaServicePhonePayListMapAddSplit rows", err) log.Panicln("areaServicePhonePayListMapAddSplit rows", err)
} }
defer rows.Close() defer rows.Close()
var temp model.PhonePaySplitMoneyStruct var temp model.PaySplitMoneyStruct
for rows.Next() { for rows.Next() {
err = rows.Scan(&temp.AdminID, &temp.Amount) err = rows.Scan(&temp.AdminID, &temp.Amount)
if err != nil { if err != nil {
......
...@@ -20,15 +20,16 @@ func initCardUserMapNoSimID() { ...@@ -20,15 +20,16 @@ func initCardUserMapNoSimID() {
var cardUserID uint32 var cardUserID uint32
var temp model.CacheCardUserStruct var temp model.CacheCardUserStruct
// rows, err := dbcurd.PgDb.Query("SELECT id,name,sex,area_id,grade,class,student_num,phone_expiry FROM u_card_user WHERE delete_at is null") // rows, err := dbcurd.PgDb.Query("SELECT id,name,sex,area_id,grade,class,student_num,phone_expiry FROM u_card_user WHERE delete_at is null")
rows, err := dbcurd.PgDb.Query("SELECT id,name,sex,area_id,phone_expiry,birthday FROM u_card_user WHERE delete_at is null") rows, err := dbcurd.PgDb.Query("SELECT id,name,sex,area_id,phone_expiry,birthday,msg_expiry FROM u_card_user WHERE delete_at is null")
if err != nil { if err != nil {
log.Panicln("Select u_card_user To Map rows", err) log.Panicln("Select u_card_user To Map rows", err)
} }
defer rows.Close() defer rows.Close()
// var simInfo model.CacheSimInfoStruct // var simInfo model.CacheSimInfoStruct
var expiry string var expiry string
var msgExpiry string
for rows.Next() { for rows.Next() {
err = rows.Scan(&cardUserID, &temp.Name, &temp.Sex, &temp.AreaID, &expiry, &temp.Birthday) err = rows.Scan(&cardUserID, &temp.Name, &temp.Sex, &temp.AreaID, &expiry, &temp.Birthday, &msgExpiry)
if err != nil { if err != nil {
log.Panicln("initCardUserMapAndSimInfoMapNoFamilyNum rows.Scan", err) log.Panicln("initCardUserMapAndSimInfoMapNoFamilyNum rows.Scan", err)
} }
...@@ -54,7 +55,9 @@ func initCardUserMapNoSimID() { ...@@ -54,7 +55,9 @@ func initCardUserMapNoSimID() {
temp.Birthday = temp.Birthday[:7] temp.Birthday = temp.Birthday[:7]
} }
temp.PhoneExpiry, _ = time.Parse("2006-01-02T00:00:00Z", expiry) temp.PhoneExpiry, _ = time.Parse("2006-01-02T00:00:00Z", expiry)
//fmt.Println("temp.PhoneExpiry",temp.PhoneExpiry,expiry) temp.MsgExpiry, _ = time.Parse("2006-01-02T00:00:00Z", msgExpiry)
// fmt.Println("temp.PhoneExpiry",temp.PhoneExpiry,expiry)
// fmt.Println("temp.MsgExpiry",temp.MsgExpiry,msgExpiry)
cardUserMap.Store(cardUserID, temp) cardUserMap.Store(cardUserID, temp)
} }
// 处理完毕后,需要判断一次遍历过程中是否有错误产生 // 处理完毕后,需要判断一次遍历过程中是否有错误产生
...@@ -178,6 +181,9 @@ func UpdateCardUserMap(cardUserID uint32, newData *model.CacheUpdateCardUserStru ...@@ -178,6 +181,9 @@ func UpdateCardUserMap(cardUserID uint32, newData *model.CacheUpdateCardUserStru
if newData.PhoneExpiry != nil { if newData.PhoneExpiry != nil {
data.PhoneExpiry = *newData.PhoneExpiry data.PhoneExpiry = *newData.PhoneExpiry
} }
if newData.MsgExpiry != nil {
data.MsgExpiry = *newData.MsgExpiry
}
if newData.SimCardID != nil { if newData.SimCardID != nil {
data.SimCardID = *newData.SimCardID data.SimCardID = *newData.SimCardID
} }
...@@ -219,6 +225,32 @@ func GetCardUserMapPhoneExpiry(cardUserID uint32) *time.Time { ...@@ -219,6 +225,32 @@ func GetCardUserMapPhoneExpiry(cardUserID uint32) *time.Time {
return nil return nil
} }
// GetCardUserMapPhoneExpiryAndMsgExpiry 查询学生电话卡和留言服务到期时间
func GetCardUserMapPhoneExpiryAndMsgExpiry(cardUserID uint32) (*time.Time, *time.Time) {
if s, ok := cardUserMap.Load(cardUserID); ok { // map有
if v, ok := s.(model.CacheCardUserStruct); ok { //类型断言正确
return &v.PhoneExpiry, &v.MsgExpiry
} else { //类型断言失败
cardUserMap.Delete(cardUserID)
logger.Log.Error("cardUserMap 类型断言错误",
zap.Uint32("cardUserID", cardUserID),
zap.String("src", "GetCardUserMapMsgExpiry"))
}
} else {
logger.Log.Error("cardUserMap 有问题,没数据",
zap.Uint32("cardUserID", cardUserID),
zap.String("src", "GetCardUserMapMsgExpiry"))
}
//if cardUserID == 0 {
// fmt.Println("GetCardUserInfo 居然传入了0")
// return nil
//}
// var temp model.CacheCardUserStruct
// todo1 再去查一盘库
return nil, nil
}
// AddOrDelSlaveWeUserIDInCardUserMap 给学生缓存增加或删除附家长 // AddOrDelSlaveWeUserIDInCardUserMap 给学生缓存增加或删除附家长
func AddOrDelSlaveWeUserIDInCardUserMap(weUserID, cardUserID uint32, del bool) { func AddOrDelSlaveWeUserIDInCardUserMap(weUserID, cardUserID uint32, del bool) {
cardUserMapUpdateLock.Lock() cardUserMapUpdateLock.Lock()
......
...@@ -3,29 +3,70 @@ package cache ...@@ -3,29 +3,70 @@ package cache
import ( import (
"dc_golang_server_1/data_db_cache/dbcurd" "dc_golang_server_1/data_db_cache/dbcurd"
"dc_golang_server_1/data_db_cache/model" "dc_golang_server_1/data_db_cache/model"
"dc_golang_server_1/logger"
"fmt" "fmt"
"log" "go.uber.org/zap"
"sync" "sync"
"time" "time"
) )
// initCardUserTrendMap 获取学生近20条动态,现在只有通话记录 // initCardUserTrendMap 获取学生近20条动态 // ,现在只有通话记录
//func initCardUserTrendMap() {
// fmt.Println(time.Now(), "cache: initCardUserTrendMap begin")
// var cardUserID uint32
// var ok bool
// cardUserMap.Range(func(k, _ interface{}) bool {
// cardUserID, ok = k.(uint32)
// if ok != true {
// log.Panicln(time.Now(), "initCardUserTrendMap k.(uint32) error", k)
// }
// trends := dbcurd.SelectCardUserTrendsLimit20FromUCallRecordByCardUserID(cardUserID)
// if trends != nil {
// cardUserTrendMap.Store(cardUserID, trends)
// }
// return true
// })
// fmt.Println(time.Now(), "cache: initCardUserTrendMap OK")
//}
func initCardUserTrendMap() { func initCardUserTrendMap() {
fmt.Println(time.Now(), "cache: initCardUserTrendMap begin") fmt.Println(time.Now(), "cache: initCardUserTrendMap begin")
rows, err := dbcurd.PgDb.Query("SELECT card_user_id,service_type,title,content,ctime FROM nlog_user_trend ORDER BY ID")
if err != nil {
fmt.Println("initCardUserTrendMap rows", err)
}
defer rows.Close()
var cardUserID uint32 var cardUserID uint32
var ok bool var temp model.CacheCardUserTrendStruct
cardUserMap.Range(func(k, _ interface{}) bool { for rows.Next() {
cardUserID, ok = k.(uint32) err = rows.Scan(&cardUserID, &temp.ServiceType, &temp.Title, &temp.Content, &temp.Time)
if ok != true { if err != nil {
log.Panicln(time.Now(), "initCardUserTrendMap k.(uint32) error", k) fmt.Println("initCardUserTrendMap rows.Scan", err)
} }
trends := dbcurd.SelectCardUserTrendsLimit20FromUCallRecordByCardUserID(cardUserID)
if trends != nil { if info, ok := cardUserTrendMap.Load(cardUserID); ok { //map有
cardUserTrendMap.Store(cardUserID, trends) if v, ok := info.([]model.CacheCardUserTrendStruct); ok { //类型断言正确
} v = append(v, temp)
return true cardUserTrendMap.Store(cardUserID, v)
}) continue
fmt.Println(time.Now(), "cache: initCardUserTrendMap OK") } else { //类型断言失败
fmt.Println("cardUserTrendMap 类型断言失败")
//cardUserTrendMap.Store(cardUserID, append([]model.CacheCardUserTrendStruct{}, temp))
}
} //else {
cardUserTrendMap.Store(cardUserID, append([]model.CacheCardUserTrendStruct{}, temp))
//}
}
// 处理完毕后,需要判断一次遍历过程中是否有错误产生
if err = rows.Err(); err != nil {
logger.Log.Error("rows.Err()",
zap.Error(err),
zap.String("src", "initCardUserTrendMap"))
fmt.Println(time.Now(), "initCardUserTrendMap rows.Err()", err)
} else {
fmt.Println(time.Now(), "cache: initCardUserTrendMap end")
}
} }
var cardUserTrendMapUpdateLock sync.Mutex // 直接全局锁 var cardUserTrendMapUpdateLock sync.Mutex // 直接全局锁
...@@ -36,8 +77,7 @@ func InsertCardUserTrendMap(cardUserID uint32, temp *model.CacheCardUserTrendStr ...@@ -36,8 +77,7 @@ func InsertCardUserTrendMap(cardUserID uint32, temp *model.CacheCardUserTrendStr
if v, ok := cardUserTrendMap.Load(cardUserID); ok { if v, ok := cardUserTrendMap.Load(cardUserID); ok {
if trends, ok := v.([]model.CacheCardUserTrendStruct); ok { if trends, ok := v.([]model.CacheCardUserTrendStruct); ok {
trends = append([]model.CacheCardUserTrendStruct{*temp}, trends...) trends = append([]model.CacheCardUserTrendStruct{*temp}, trends...)
length := len(trends) if len(trends) > 20 {
if length > 20 {
trends = trends[:20] trends = trends[:20]
} }
cardUserTrendMap.Store(cardUserID, trends) cardUserTrendMap.Store(cardUserID, trends)
...@@ -56,10 +96,10 @@ func InsertCardUserTrendMap(cardUserID uint32, temp *model.CacheCardUserTrendStr ...@@ -56,10 +96,10 @@ func InsertCardUserTrendMap(cardUserID uint32, temp *model.CacheCardUserTrendStr
func GetCardUserTrendMapByCardUserID(cardUserID uint32) (trends []model.CacheCardUserTrendStruct) { func GetCardUserTrendMapByCardUserID(cardUserID uint32) (trends []model.CacheCardUserTrendStruct) {
if v, ok := cardUserTrendMap.Load(cardUserID); ok { if v, ok := cardUserTrendMap.Load(cardUserID); ok {
if trends, ok = v.([]model.CacheCardUserTrendStruct); ok { if trends, ok = v.([]model.CacheCardUserTrendStruct); ok {
return trends return
} else { // 类型断言错误 } else { // 类型断言错误
cardUserTrendMap.Delete(cardUserID) cardUserTrendMap.Delete(cardUserID)
fmt.Println("InsertCardUserTrendMap cardUserTrendMap 类型断言错误") fmt.Println("GetCardUserTrendMapByCardUserID cardUserTrendMap 类型断言错误")
} }
} /*else { } /*else {
logger.Log.Error("cardUserTrendMap 有问题,没数据", logger.Log.Error("cardUserTrendMap 有问题,没数据",
...@@ -72,9 +112,13 @@ func GetCardUserTrendMapByCardUserID(cardUserID uint32) (trends []model.CacheCar ...@@ -72,9 +112,13 @@ func GetCardUserTrendMapByCardUserID(cardUserID uint32) (trends []model.CacheCar
// cardUserTrendMap.Store(cardUserID,trends) // cardUserTrendMap.Store(cardUserID,trends)
//} //}
return nil return
} }
func DeleteCardUserTrendMap(cardUserID uint32) { func DeleteCardUserTrendMap(cardUserID uint32) {
cardUserTrendMap.Delete(cardUserID) cardUserTrendMap.Delete(cardUserID)
} }
func SystemExitToSaveTrend() {
dbcurd.InsertNLogUserTrend(&cardUserTrendMap)
}
package cache
import (
"dc_golang_server_1/data_db_cache/dbcurd"
"dc_golang_server_1/data_db_cache/model"
"fmt"
"log"
"sync"
"time"
)
// initNReadMsgMap 获取学生留言
func initNReadMsgMap() {
fmt.Println(time.Now(), "cache: initNReadMsgMap begin")
var cardUserID uint32
var ok bool
cardUserMap.Range(func(k, _ interface{}) bool {
cardUserID, ok = k.(uint32)
if ok != true {
log.Panicln(time.Now(), "initNReadMsgMap k.(uint32) error", k)
}
msg := dbcurd.SelectUMsgNReadByCardUserID(cardUserID)
if msg != nil {
nReadMsgMap.Store(cardUserID, msg)
}
return true
})
fmt.Println(time.Now(), "cache: initNReadMsgMap OK")
}
var nReadMsgMapUpdateLock sync.Mutex // 直接全局锁
func InsertNReadMsgMap(cardUserID uint32, temp *model.CacheCardUserNReadMsgStruct) {
nReadMsgMapUpdateLock.Lock()
defer nReadMsgMapUpdateLock.Unlock()
if v, ok := nReadMsgMap.Load(cardUserID); ok {
if msg, ok := v.([]model.CacheCardUserNReadMsgStruct); ok {
msg = append([]model.CacheCardUserNReadMsgStruct{*temp}, msg...)
if len(msg) > 10 {
msg = msg[:10]
}
nReadMsgMap.Store(cardUserID, msg)
return
} else { // 类型断言错误
nReadMsgMap.Delete(cardUserID)
fmt.Println("InsertNReadMsgMap nReadMsgMap 类型断言错误")
}
}
msg := make([]model.CacheCardUserNReadMsgStruct, 1)
msg[0] = *temp
nReadMsgMap.Store(cardUserID, msg)
}
func GetNReadMsgMap(cardUserID uint32) []model.CacheCardUserNReadMsgStruct {
if v, ok := nReadMsgMap.Load(cardUserID); ok {
if temp, ok := v.([]model.CacheCardUserNReadMsgStruct); ok {
if len(temp) > 10 {
temp = temp[:10]
nReadMsgMap.Store(cardUserID, temp)
}
return temp
} else { // 类型断言错误
nReadMsgMap.Delete(cardUserID)
fmt.Println("GetNReadMsgMapByCardUserID nReadMsgMap 类型断言错误")
}
} /*else {
logger.Log.Error("cardUserTrendMap 有问题,没数据",
zap.Uint32("cardUserID", cardUserID),
zap.String("src", "GetCardUserTrendMapByCardUserID"))
}*/
//trends = dbcurd.SelectCardUserTrendsLimit20FromUCallRecordByCardUserID(cardUserID)
//if trends != nil {
// cardUserTrendMap.Store(cardUserID,trends)
//}
return []model.CacheCardUserNReadMsgStruct{}
}
func GetOneNReadMsgAndLenByCardUserID(cardUserID uint32) (*model.CacheCardUserNReadMsgStruct, uint8) {
if v, ok := nReadMsgMap.Load(cardUserID); ok {
if temp, ok := v.([]model.CacheCardUserNReadMsgStruct); ok {
totalLen := uint8(len(temp))
if totalLen > 0 {
return &temp[0], totalLen
}
} else { // 类型断言错误
nReadMsgMap.Delete(cardUserID)
fmt.Println("GetNReadMsgMapByCardUserID nReadMsgMap 类型断言错误")
}
} /*else {
logger.Log.Error("cardUserTrendMap 有问题,没数据",
zap.Uint32("cardUserID", cardUserID),
zap.String("src", "GetCardUserTrendMapByCardUserID"))
}*/
//trends = dbcurd.SelectCardUserTrendsLimit20FromUCallRecordByCardUserID(cardUserID)
//if trends != nil {
// cardUserTrendMap.Store(cardUserID,trends)
//}
return nil, 0
}
func DeleteOneNReadMsg(cardUserID, msgID uint32) { // 用于删除一条留言缓存,家长主动删除或学生查看后硬件上报删除
if v, ok := nReadMsgMap.Load(cardUserID); ok {
if temp, ok := v.([]model.CacheCardUserNReadMsgStruct); ok {
for i, msg := range temp {
if msg.ID == msgID {
temp = append(temp[:i], temp[i+1:]...)
nReadMsgMap.Store(cardUserID, temp)
return
}
}
} else { // 类型断言错误
nReadMsgMap.Delete(cardUserID)
fmt.Println("GetNReadMsgMapByCardUserID nReadMsgMap 类型断言错误")
}
}
}
func DeleteNReadMsgMap(cardUserID uint32) {
nReadMsgMap.Delete(cardUserID)
}
package cache
import (
"dc_golang_server_1/data_db_cache/dbcurd"
"dc_golang_server_1/data_db_cache/model"
"dc_golang_server_1/logger"
"fmt"
"go.uber.org/zap"
"strconv"
"time"
)
// initPhoneMsgFeeMap 缓存 b_phone_msg_fee 全表 并缓存 b_msg_split_money 的分账信息
func initPhoneMsgFeeMap() {
fmt.Println(time.Now(), "cache: initPhoneMsgFeeMap begin")
rows, err := dbcurd.PgDb.Query("SELECT area_service_id,amount FROM b_phone_msg_fee")
if err != nil {
panic("initPhoneMsgFeeMap SELECT b_phone_msg_fee rows" + err.Error())
}
defer rows.Close()
var areaServiceID uint32
var temp model.CachePhoneMsgFeeStruct
for rows.Next() {
err = rows.Scan(&areaServiceID, &temp.Amount)
if err != nil {
panic("initPhoneMsgFeeMap SELECT b_phone_msg_fee rows.Scan" + err.Error())
}
temp.SplitAmount = getMsgSplitMoney(areaServiceID)
phoneMsgFeeMap.Store(areaServiceID, temp)
}
// 处理完毕后,需要判断一次遍历过程中是否有错误产生
if err = rows.Err(); err != nil {
logger.Log.Error("rows.Err()",
zap.Error(err),
zap.String("src", "getMsgSplitMoney"))
fmt.Println(time.Now(), "initPhoneMsgFeeMap rows.Err()", err)
} else {
fmt.Println(time.Now(), "cache: initPhoneMsgFeeMap end")
}
}
func getMsgSplitMoney(areaServiceID uint32) (d []model.PaySplitMoneyStruct) {
rows, err := dbcurd.PgDb.Query("SELECT admin_id,amount,remark FROM b_msg_split_money WHERE area_service_id=$1", areaServiceID)
if err != nil {
panic("getMsgSplitMoney rows" + err.Error() + strconv.FormatUint(uint64(areaServiceID), 10))
}
defer rows.Close()
var temp model.PaySplitMoneyStruct
for rows.Next() {
err = rows.Scan(&temp.AdminID, &temp.Amount, &temp.Remark)
if err != nil {
panic("getMsgSplitMoney rows.Scan" + err.Error() + strconv.FormatUint(uint64(areaServiceID), 10))
}
d = append(d, temp)
}
// 处理完毕后,需要判断一次遍历过程中是否有错误产生
if err = rows.Err(); err != nil {
logger.Log.Error("rows.Err()",
zap.Error(err),
zap.String("src", "getMsgSplitMoney"))
fmt.Println(time.Now(), "getMsgSplitMoney rows.Err()", err, strconv.FormatUint(uint64(areaServiceID), 10))
}
return
}
// GetPhoneMsgFeeMap 根据区域服务ID获取缓存
func GetPhoneMsgFeeMap(areaServiceID uint32) *model.CachePhoneMsgFeeStruct {
if fee, ok := phoneMsgFeeMap.Load(areaServiceID); ok { //map有
if msgFee, ok := fee.(model.CachePhoneMsgFeeStruct); ok { //类型断言正确
return &msgFee
} else { //类型断言失败
phoneMsgFeeMap.Delete(areaServiceID)
logger.Log.Error("GetPhoneMsgFeeMap 类型断言错误",
zap.Uint32("areaServiceID", areaServiceID),
zap.String("src", "GetPhoneMsgFeeMap"))
}
}
return nil
}
package dbcurd package dbcurd
import (
"dc_golang_server_1/logger"
"fmt"
"go.uber.org/zap"
"time"
)
//CREATE TABLE IF NOT EXISTS public.d_hex_command_err //CREATE TABLE IF NOT EXISTS public.d_hex_command_err
//( //(
//device_id bigint NOT NULL, //device_id bigint NOT NULL,
...@@ -21,17 +14,17 @@ import ( ...@@ -21,17 +14,17 @@ import (
// createAt timestamp.Timestamp // createAt timestamp.Timestamp
//} //}
func InsertDevCommandErr(devId uint32, ciphertext string, errMsg string) { //func InsertDevCommandErr(devId uint32, ciphertext string, errMsg string) {
fmt.Println("InsertDevCommandErr", errMsg, devId, ciphertext) // fmt.Println("InsertDevCommandErr", errMsg, devId, ciphertext)
var err error // var err error
for i := 0; i < 10; i++ { // for i := 0; i < 10; i++ {
_, err = PgDb.Exec("INSERT INTO d_command_err(device_id, ciphertext, err)VALUES($1,$2,$3)", devId, ciphertext, errMsg) // _, err = PgDb.Exec("INSERT INTO d_command_err(device_id, ciphertext, err)VALUES($1,$2,$3)", devId, ciphertext, errMsg)
if err == nil { // if err == nil {
return // return
} // }
fmt.Println("硬件问题 InsertDevCommandErr:", i, err) // fmt.Println("硬件问题 InsertDevCommandErr:", i, err)
time.Sleep(3 * time.Second) // time.Sleep(3 * time.Second)
} // }
logger.Log.Error("InsertDevCommandErr Err", // logger.Log.Error("InsertDevCommandErr Err",
zap.Error(err)) // zap.Error(err))
} //}
package dbcurd package dbcurd
import (
"dc_golang_server_1/logger"
"fmt"
"go.uber.org/zap"
"time"
)
//CREATE TABLE IF NOT EXISTS public.d_hex_connect_record //CREATE TABLE IF NOT EXISTS public.d_hex_connect_record
//( //(
//dev_id bigint NOT NULL, //dev_id bigint NOT NULL,
...@@ -14,17 +7,17 @@ import ( ...@@ -14,17 +7,17 @@ import (
//create_at timestamp without time zone NOT NULL DEFAULT CURRENT_TIMESTAMP //create_at timestamp without time zone NOT NULL DEFAULT CURRENT_TIMESTAMP
//) //)
// DevConnectRecord state 0:新连接来了 1:设备正常离线 2:正常离线 3:新连接挤掉就连接 4:未知异常(连接池类型断言失败) //// DevConnectRecord state 0:新连接来了 1:设备正常离线 2:正常离线 3:新连接挤掉就连接 4:未知异常(连接池类型断言失败)
func DevConnectRecord(devId uint32, state uint8) { //func DevConnectRecord(devId uint32, state uint8) {
var err error // var err error
for i := 0; i < 100; i++ { // for i := 0; i < 100; i++ {
_, err = stmtInsertDevConnectRecord.Exec(devId, state) // _, err = stmtInsertDevConnectRecord.Exec(devId, state)
if err == nil { // if err == nil {
return // return
} // }
fmt.Println("DevConnectRecord:", i, err) // fmt.Println("DevConnectRecord:", i, err)
time.Sleep(20 * time.Millisecond) // time.Sleep(20 * time.Millisecond)
} // }
logger.Log.Error("DevConnectRecord Err", // logger.Log.Error("DevConnectRecord Err",
zap.Error(err)) // zap.Error(err))
} //}
...@@ -17,7 +17,7 @@ const ( //0 成功 1 唯一约束重复 9 系统繁忙 ...@@ -17,7 +17,7 @@ const ( //0 成功 1 唯一约束重复 9 系统繁忙
var PgDb *sql.DB var PgDb *sql.DB
var stmtInsertDevConnectRecord *sql.Stmt // 硬件联网流水 // var stmtInsertDevConnectRecord *sql.Stmt // 硬件联网流水
var stmtInsertDevCommandRecord *sql.Stmt // 硬件通讯流水 var stmtInsertDevCommandRecord *sql.Stmt // 硬件通讯流水
var stmtInsertDevCommandRecordRW *sql.Stmt // 硬件通讯流水,一收一发的情况同时记录 var stmtInsertDevCommandRecordRW *sql.Stmt // 硬件通讯流水,一收一发的情况同时记录
var stmtInsertDevResetRecord *sql.Stmt // 硬件复位流水 var stmtInsertDevResetRecord *sql.Stmt // 硬件复位流水
...@@ -49,11 +49,11 @@ func InitDb() { ...@@ -49,11 +49,11 @@ func InitDb() {
panic("stmtInsertDevCommandRecord:" + err.Error()) panic("stmtInsertDevCommandRecord:" + err.Error())
} }
// 硬件联网流水 //// 硬件联网流水
stmtInsertDevConnectRecord, err = PgDb.Prepare("INSERT INTO d_connect_record VALUES($1,$2)") //stmtInsertDevConnectRecord, err = PgDb.Prepare("INSERT INTO d_connect_record VALUES($1,$2)")
if err != nil { //if err != nil {
panic("stmtInsertDevConnectRecord:" + err.Error()) // panic("stmtInsertDevConnectRecord:" + err.Error())
} //}
// 硬件复位流水 // 硬件复位流水
stmtInsertDevResetRecord, err = PgDb.Prepare("INSERT INTO d_reset_record VALUES($1,$2,$3,$4,$5,$6,$7,$8)") stmtInsertDevResetRecord, err = PgDb.Prepare("INSERT INTO d_reset_record VALUES($1,$2,$3,$4,$5,$6,$7,$8)")
if err != nil { if err != nil {
...@@ -76,9 +76,9 @@ func CloseDb() { ...@@ -76,9 +76,9 @@ func CloseDb() {
_ = stmtInsertDevCommandRecordRW.Close() _ = stmtInsertDevCommandRecordRW.Close()
} }
if stmtInsertDevConnectRecord != nil { // 硬件联网流水 //if stmtInsertDevConnectRecord != nil { // 硬件联网流水
_ = stmtInsertDevConnectRecord.Close() // _ = stmtInsertDevConnectRecord.Close()
} //}
if stmtInsertDevResetRecord != nil { // 硬件复位流水 if stmtInsertDevResetRecord != nil { // 硬件复位流水
_ = stmtInsertDevResetRecord.Close() _ = stmtInsertDevResetRecord.Close()
......
package dbcurd
import (
"dc_golang_server_1/data_db_cache/model"
"fmt"
"strconv"
"sync"
"time"
)
func SelectNLogUserTrend(data *sync.Map) {
fmt.Println(time.Now(), "cache: SelectNLogUserTrend")
i := 0
var err error
for {
_, err = PgDb.Exec("TRUNCATE TABLE nlog_user_trend")
if err == nil {
break
}
i++
if i == 5 {
fmt.Println(time.Now(), "缓存的用户最新动态持久化 InsertNLogUserTrend 清表失败", i, err)
return
} else {
fmt.Println(err)
time.Sleep(100 * time.Millisecond)
}
}
i = 0
sql := "INSERT INTO nlog_user_trend VALUES"
data.Range(func(k, v interface{}) bool {
if values, ok := v.([]model.CacheCardUserTrendStruct); ok {
if len(values) > 20 {
values = values[:20]
}
for _, t := range values {
sql += "(" + strconv.FormatUint(uint64(k.(uint32)), 10) + "," + strconv.FormatUint(uint64(t.ServiceType), 10) + ",'" + t.Title + "','" + t.Content + "','" + t.Time.Format("2006-01-02 15:04:05") + "'),"
}
i++
if i >= 3000 {
sql = sql[:len(sql)-1]
insertNLogUserTrendOneSQL(&sql)
i = 0
sql = "INSERT INTO nlog_user_trend VALUES"
}
}
return true
})
if i > 0 {
sql = sql[:len(sql)-1]
insertNLogUserTrendOneSQL(&sql)
}
fmt.Println(time.Now(), "缓存的用户最新动态持久化 InsertNLogUserTrend 成功")
}
func InsertNLogUserTrend(data *sync.Map) {
fmt.Println(time.Now(), "缓存的用户最新动态持久化 InsertNLogUserTrend")
i := 0
var err error
for {
_, err = PgDb.Exec("TRUNCATE TABLE nlog_user_trend")
if err == nil {
break
}
i++
if i == 5 {
fmt.Println(time.Now(), "缓存的用户最新动态持久化 InsertNLogUserTrend 清表失败", i, err)
return
} else {
fmt.Println(err)
time.Sleep(100 * time.Millisecond)
}
}
i = 0
sql := "INSERT INTO nlog_user_trend VALUES"
data.Range(func(k, v interface{}) bool {
if values, ok := v.([]model.CacheCardUserTrendStruct); ok {
if len(values) > 20 {
values = values[:20]
}
for _, t := range values {
sql += "(" + strconv.FormatUint(uint64(k.(uint32)), 10) + "," + strconv.FormatUint(uint64(t.ServiceType), 10) + ",'" + t.Title + "','" + t.Content + "','" + t.Time.Format("2006-01-02 15:04:05") + "'),"
}
i++
if i >= 3000 {
sql = sql[:len(sql)-1]
insertNLogUserTrendOneSQL(&sql)
i = 0
sql = "INSERT INTO nlog_user_trend VALUES"
}
}
return true
})
if i > 0 {
sql = sql[:len(sql)-1]
insertNLogUserTrendOneSQL(&sql)
}
fmt.Println(time.Now(), "缓存的用户最新动态持久化 InsertNLogUserTrend 成功")
}
func insertNLogUserTrendOneSQL(sql *string) {
var err error
for i := 0; i < 5; i++ {
_, err = PgDb.Exec(*sql)
if err == nil {
return
}
fmt.Println(err)
time.Sleep(10 * time.Millisecond)
}
fmt.Println(err, *sql)
}
...@@ -13,7 +13,7 @@ import ( ...@@ -13,7 +13,7 @@ import (
type InsertTableUCallRecordStruct struct { type InsertTableUCallRecordStruct struct {
CardUserId uint32 CardUserId uint32
DeviceId uint32 DeviceId uint32
CallStartAt string CallStartAt time.Time //string
CardUserName string CardUserName string
SimID string SimID string
CalledNumber string CalledNumber string
...@@ -65,12 +65,13 @@ func InsertUCallRecordAndUpdateUSimInfo(insertData *InsertTableUCallRecordStruct ...@@ -65,12 +65,13 @@ func InsertUCallRecordAndUpdateUSimInfo(insertData *InsertTableUCallRecordStruct
// panic("反正是测试,先退出2") // panic("反正是测试,先退出2")
//} //}
//fmt.Println(rowAffected) //fmt.Println(rowAffected)
if insertData.TalkTime > 0 {
_, err = tx.Exec("UPDATE u_sim_info SET total_talk_minutes=total_talk_minutes+$1,month_talk_minutes=month_talk_minutes+$1 WHERE sim_id=$2", (insertData.TalkTime+59)/60, insertData.SimID) _, err = tx.Exec("UPDATE u_sim_info SET total_talk_minutes=total_talk_minutes+$1,month_talk_minutes=month_talk_minutes+$1 WHERE sim_id=$2", (insertData.TalkTime+59)/60, insertData.SimID)
if err != nil { if err != nil {
logger.Log.Error("InsertUCallRecordAndUpdateUSimInfo UPDATE u_sim_info:", logger.Log.Error("InsertUCallRecordAndUpdateUSimInfo UPDATE u_sim_info:",
zap.Error(err)) zap.Error(err))
return InsertSysErr return InsertSysErr
}
} }
//rowAffected, err = rs.RowsAffected() //rowAffected, err = rs.RowsAffected()
//if err != nil { //if err != nil {
...@@ -89,9 +90,9 @@ func InsertUCallRecordAndUpdateUSimInfo(insertData *InsertTableUCallRecordStruct ...@@ -89,9 +90,9 @@ func InsertUCallRecordAndUpdateUSimInfo(insertData *InsertTableUCallRecordStruct
} }
func SelectCardUserTrendsLimit20FromUCallRecordByCardUserID(cardUserID uint32) (trends []model.CacheCardUserTrendStruct) { func SelectCardUserTrendsLimit20FromUCallRecordByCardUserID(cardUserID uint32) (trends []model.CacheCardUserTrendStruct) {
rows, err := PgDb.Query("SELECT call_start_at, called_nickname, talk_time, place_user FROM u_call_record WHERE card_user_id=$1 ORDER BY create_at DESC LIMIT 20", cardUserID) rows, err := PgDb.Query("SELECT call_start_at,called_nickname,talk_time,place_user FROM u_call_record WHERE card_user_id=$1 ORDER BY create_at DESC LIMIT 20", cardUserID)
if err != nil { if err != nil {
fmt.Println("SELECT call_start_at, called_nickname, talk_time, place_user FROM u_call_record WHERE card_user_id=$1 ORDER BY create_at DESC LIMIT 20", err) fmt.Println("SELECT call_start_at, called_nickname, talk_time, place_user FROM u_call_record WHERE card_user_id=$1 ORDER BY create_at DESC LIMIT 20", cardUserID, err)
return return
} }
defer rows.Close() defer rows.Close()
...@@ -103,19 +104,19 @@ func SelectCardUserTrendsLimit20FromUCallRecordByCardUserID(cardUserID uint32) ( ...@@ -103,19 +104,19 @@ func SelectCardUserTrendsLimit20FromUCallRecordByCardUserID(cardUserID uint32) (
for rows.Next() { for rows.Next() {
err = rows.Scan(&startAt, &nickname, &talkTime, &place) err = rows.Scan(&startAt, &nickname, &talkTime, &place)
if err != nil { if err != nil {
fmt.Println("selectCardUserTrendsLimit20FromUCallRecordByCardUserID rows", err) fmt.Println("selectCardUserTrendsLimit20FromUCallRecordByCardUserID rows", cardUserID, err)
return return
} }
trends = append(trends, model.CacheCardUserTrendStruct{ trends = append(trends, model.CacheCardUserTrendStruct{
ServiceType: 1, ServiceType: 1,
Title: "公话机-" + place, Title: "公话机-" + place,
Content: "被叫:" + nickname + " 时长:" + strconv.Itoa((talkTime+59)/60) + "分", Content: "被叫:" + nickname + " 时长:" + strconv.Itoa((talkTime+59)/60) + "分",
Time: startAt.Format("2006-01-02 15:04:05"), Time: startAt, //.Format("2006-01-02 15:04:05"),
}) })
} }
// 处理完毕后,需要判断一次遍历过程中是否有错误产生 // 处理完毕后,需要判断一次遍历过程中是否有错误产生
if err = rows.Err(); err != nil { if err = rows.Err(); err != nil {
fmt.Println(time.Now(), "selectCardUserTrendsLimit20FromUCallRecordByCardUserID rows.Err()", err) fmt.Println(time.Now(), "selectCardUserTrendsLimit20FromUCallRecordByCardUserID rows.Err()", cardUserID, err)
} }
return return
} }
......
package dbcurd
import (
"dc_golang_server_1/data_db_cache/model"
"dc_golang_server_1/logger"
"fmt"
"go.uber.org/zap"
"time"
)
type InsertTableUMsgNReadStruct struct {
CardUserID uint32 `json:"cardUserID"` // 学生ID
AreaServiceID uint32 `json:"aid"` // 区域服务ID
WeUserID uint32 `json:"-"`
Msg string `json:"msg"` // 留言内容
CreateAt time.Time `json:"-"`
}
func InsertUMsgNRead(insertData *InsertTableUMsgNReadStruct) (msgID uint32) {
tx, err := PgDb.Begin()
if err != nil {
logger.Log.Error("InsertUMsgNRead PgDb.Begin():",
zap.Error(err))
return
}
defer clearTransaction(tx)
_, err = tx.Exec("DELETE FROM u_msg_nread WHERE id IN(SELECT id FROM u_msg_nread WHERE card_user_id=$1 ORDER BY id DESC OFFSET 9)", insertData.CardUserID)
if err != nil {
logger.Log.Error("InsertUMsgNRead DELETE",
zap.Reflect("insertData", insertData),
zap.Error(err))
return 0
}
err = tx.QueryRow("INSERT INTO u_msg_nread(card_user_id,area_service_id,we_user_id,create_at,msg)VALUES($1,$2,$3,$4,$5)RETURNING id",
insertData.CardUserID,
insertData.AreaServiceID,
insertData.WeUserID,
insertData.CreateAt,
insertData.Msg,
).Scan(&msgID)
if err != nil {
logger.Log.Error("InsertUMsgNRead INSERT",
zap.Reflect("insertData", insertData),
zap.Error(err))
return
}
if err = tx.Commit(); err != nil {
logger.Log.Error("InsertUCardUserAndUserWeCardUser Commit",
zap.Reflect("insertData", insertData),
zap.Error(err))
return 0
}
return
}
func SelectUMsgNReadByCardUserID(cardUserID uint32) (msg []model.CacheCardUserNReadMsgStruct) {
rows, err := PgDb.Query("SELECT id,we_user_id,create_at,msg FROM u_msg_nread WHERE card_user_id=$1 ORDER BY create_at DESC LIMIT 10", cardUserID)
if err != nil {
fmt.Println("SELECT id,we_user_id,create_at FROM u_msg_nread WHERE card_user_id=$1 ORDER BY create_at DESC LIMIT 10", cardUserID, err)
return
}
defer rows.Close()
var temp model.CacheCardUserNReadMsgStruct
for rows.Next() {
err = rows.Scan(&temp.ID, &temp.WeUserID, &temp.CreateAt, &temp.Msg)
if err != nil {
fmt.Println("selectCardUserTrendsLimit20FromUCallRecordByCardUserID rows", cardUserID, err)
return
}
msg = append(msg, temp)
}
// 处理完毕后,需要判断一次遍历过程中是否有错误产生
if err = rows.Err(); err != nil {
fmt.Println(time.Now(), "selectCardUserTrendsLimit20FromUCallRecordByCardUserID rows.Err()", err)
}
return
}
func DeleteUMsgNReadAndInsertReadRecord(msgID, deviceID uint32, place string) uint32 {
tx, err := PgDb.Begin()
if err != nil {
logger.Log.Error("DeleteUMsgNReadAndInsertReadRecord PgDb.Begin():",
zap.Error(err))
return 0
}
defer clearTransaction(tx)
var cardUserID, areaServiceID, weUserID uint32
var createAt, msg string
err = tx.QueryRow("DELETE FROM u_msg_nread WHERE id=$1 RETURNING card_user_id,area_service_id,we_user_id,create_at,msg",
msgID,
).Scan(&cardUserID, &areaServiceID, &weUserID, &createAt, &msg)
if err != nil {
logger.Log.Error("DeleteUMsgNReadAndInsertReadRecord DELETE:",
zap.Error(err))
return 0
}
_, err = tx.Exec("INSERT INTO u_msg_read_record(id,card_user_id,area_service_id,we_user_id,create_at,msg,device_id,device_place)VALUES($1,$2,$3,$4,$5,$6,$7,$8)",
msgID, cardUserID, areaServiceID, weUserID, createAt, msg, deviceID, place)
if err != nil {
logger.Log.Error("DeleteUMsgNReadAndInsertReadRecord INSERT:",
zap.Error(err))
return 0
}
if err = tx.Commit(); err != nil {
logger.Log.Error("DeleteUMsgNReadAndInsertReadRecord Commit:",
zap.Error(err))
return 0
}
return cardUserID
}
func DeleteUMsgNRead(cardUserID, msgID uint32) bool {
_, err := PgDb.Exec("DELETE FROM u_msg_nread WHERE id=$1 AND card_user_id=$2", msgID, cardUserID)
if err == nil {
return true
}
return false
}
// u_msg_read_record
type SelectUMsgReadRecordRes struct {
WeUserID uint32 `json:"-"`
CreateAt string `json:"createAt"` // 创建时间
Msg string `json:"msg"`
ReadAt string `json:"readAt"` // 学生读取时间
Place string `json:"place"` // 读取的设备位置
Nickname string `json:"nickname"` // 微信昵称
AvatarURL string `json:"avatarURL"` // 头像URL
Phone string `json:"phone"` // 手机号
}
func SelectUMsgReadRecord(cardUserID, areaServiceID uint32) (d []SelectUMsgReadRecordRes) {
rows, err := PgDb.Query("SELECT we_user_id,create_at,msg,read_at,device_place FROM u_msg_read_record WHERE card_user_id=$1 AND area_service_id=$2 ORDER BY read_at DESC LIMIT 100", cardUserID, areaServiceID)
if err != nil {
logger.Log.Error("SelectUMsgReadRecord SELECT", zap.Error(err), zap.Uint32("cardUserID", cardUserID), zap.Uint32("areaServiceID", areaServiceID))
return
}
defer rows.Close()
var temp SelectUMsgReadRecordRes
for rows.Next() {
err = rows.Scan(&temp.WeUserID, &temp.CreateAt, &temp.Msg, &temp.ReadAt, &temp.Place)
if err != nil {
logger.Log.Error("SelectUMsgReadRecord rows", zap.Error(err), zap.Uint32("cardUserID", cardUserID), zap.Uint32("areaServiceID", areaServiceID))
return
}
d = append(d, temp)
}
// 处理完毕后,需要判断一次遍历过程中是否有错误产生
if err = rows.Err(); err != nil {
logger.Log.Error("SelectUMsgReadRecord rows.Err()", zap.Error(err), zap.Uint32("cardUserID", cardUserID), zap.Uint32("areaServiceID", areaServiceID))
}
return
}
...@@ -71,7 +71,7 @@ type InsertTableUPhonePayRecordAndSplit struct { ...@@ -71,7 +71,7 @@ type InsertTableUPhonePayRecordAndSplit struct {
Describe string // 描述 Describe string // 描述
ExpiryAt time.Time // 本次缴费后,话费有效期 ExpiryAt time.Time // 本次缴费后,话费有效期
Type uint8 // 缴费类型:1开卡+充值 2续费 3补卡 4补卡+续费 Type uint8 // 缴费类型:1开卡+充值 2续费 3补卡 4补卡+续费
SplitAmount []model.PhonePaySplitMoneyStruct SplitAmount []model.PaySplitMoneyStruct
} }
// InsertUPhonePayRecordAndSplit 通过事务插入缴费记录和分账记录表 // InsertUPhonePayRecordAndSplit 通过事务插入缴费记录和分账记录表
...@@ -79,7 +79,7 @@ func InsertUPhonePayRecordAndSplit(values *InsertTableUPhonePayRecordAndSplit) b ...@@ -79,7 +79,7 @@ func InsertUPhonePayRecordAndSplit(values *InsertTableUPhonePayRecordAndSplit) b
splitSql := "INSERT INTO u_trade_split_record(trade_num,admin_id,amount,remark)VALUES" splitSql := "INSERT INTO u_trade_split_record(trade_num,admin_id,amount,remark)VALUES"
header := "('" + values.TradeNum + "'," header := "('" + values.TradeNum + "',"
for _, v := range values.SplitAmount { for _, v := range values.SplitAmount {
splitSql += header + strconv.FormatUint(uint64(v.AdminID), 10) + "," + strconv.FormatUint(uint64(v.Amount), 10) +",'"+v.Remark +"')," splitSql += header + strconv.FormatUint(uint64(v.AdminID), 10) + "," + strconv.FormatUint(uint64(v.Amount), 10) + ",'" + v.Remark + "'),"
} }
splitSql = splitSql[:len(splitSql)-1] splitSql = splitSql[:len(splitSql)-1]
...@@ -135,17 +135,17 @@ func InsertUPhonePayRecordAndSplit(values *InsertTableUPhonePayRecordAndSplit) b ...@@ -135,17 +135,17 @@ func InsertUPhonePayRecordAndSplit(values *InsertTableUPhonePayRecordAndSplit) b
} }
type UpdateUPhonePayRecordStruct struct { type UpdateUPhonePayRecordStruct struct {
CardUserID uint32 CardUserID uint32
Expiry *time.Time Expiry *time.Time
PayAt *time.Time PayAt *time.Time
NotifyAt time.Time NotifyAt time.Time
TradeNum string TradeNum string
ThirdNum string ThirdNum string
TencentTradeNum string TencentTradeNum string
Fee uint32 Fee uint32
} }
func UpdateUPhonePayRecordPayAtAndUCardUserPhoneExpiryTransaction(upData *UpdateUPhonePayRecordStruct) bool { func UpdateUPhonePayRecordPayAtAndUCardUserPhoneExpiryTransaction(upData *UpdateUPhonePayRecordStruct, msg bool) bool {
tx, err := PgDb.Begin() tx, err := PgDb.Begin()
if err != nil { if err != nil {
logger.Log.Error("UpdateUCardUserPhoneExpiryAndUPhonePayRecordPayAtTransaction PgDb.Begin():", logger.Log.Error("UpdateUCardUserPhoneExpiryAndUPhonePayRecordPayAtTransaction PgDb.Begin():",
...@@ -157,7 +157,7 @@ func UpdateUPhonePayRecordPayAtAndUCardUserPhoneExpiryTransaction(upData *Update ...@@ -157,7 +157,7 @@ func UpdateUPhonePayRecordPayAtAndUCardUserPhoneExpiryTransaction(upData *Update
// 先更新充值订单 // 先更新充值订单
res, err := tx.Exec("UPDATE u_phone_pay_record SET pay_at=$1,result=1,notify_at=$2,third_num=$3,tencent_trade_num=$4,fee=$5 WHERE trade_num=$6", res, err := tx.Exec("UPDATE u_phone_pay_record SET pay_at=$1,result=1,notify_at=$2,third_num=$3,tencent_trade_num=$4,fee=$5 WHERE trade_num=$6",
upData.PayAt,upData.NotifyAt,upData.ThirdNum,upData.TencentTradeNum,upData.Fee,upData.TradeNum) upData.PayAt, upData.NotifyAt, upData.ThirdNum, upData.TencentTradeNum, upData.Fee, upData.TradeNum)
if err != nil { if err != nil {
logger.Log.Error("UpdateUCardUserPhoneExpiryAndUPhonePayRecordPayAtTransaction UPDATE u_phone_pay_record", logger.Log.Error("UpdateUCardUserPhoneExpiryAndUPhonePayRecordPayAtTransaction UPDATE u_phone_pay_record",
zap.Reflect("upData", upData), zap.Reflect("upData", upData),
...@@ -178,7 +178,11 @@ func UpdateUPhonePayRecordPayAtAndUCardUserPhoneExpiryTransaction(upData *Update ...@@ -178,7 +178,11 @@ func UpdateUPhonePayRecordPayAtAndUCardUserPhoneExpiryTransaction(upData *Update
} }
// 更新UCardUserPhone // 更新UCardUserPhone
res, err = tx.Exec("UPDATE u_card_user SET phone_expiry=$1 WHERE id=$2 AND(phone_expiry<=$1 OR phone_expiry is null)AND delete_at is null", upData.Expiry, upData.CardUserID) if msg {
res, err = tx.Exec("UPDATE u_card_user SET phone_expiry=$1,msg_expiry=$1 WHERE id=$2 AND(phone_expiry<=$1 OR phone_expiry is null)AND delete_at is null", upData.Expiry, upData.CardUserID)
} else {
res, err = tx.Exec("UPDATE u_card_user SET phone_expiry=$1 WHERE id=$2 AND(phone_expiry<=$1 OR phone_expiry is null)AND delete_at is null", upData.Expiry, upData.CardUserID)
}
if err != nil { if err != nil {
logger.Log.Error("UpdateUCardUserPhoneExpiryAndUPhonePayRecordPayAtTransaction UPDATE u_card_user res.RowsAffected()", logger.Log.Error("UpdateUCardUserPhoneExpiryAndUPhonePayRecordPayAtTransaction UPDATE u_card_user res.RowsAffected()",
zap.Reflect("upData", upData), zap.Reflect("upData", upData),
......
...@@ -9,7 +9,7 @@ import ( ...@@ -9,7 +9,7 @@ import (
"time" "time"
) )
func UpdateUWeCustomerLoginTime(weUserID uint32) { //todoN 以后添加微信登录流水表 也可以先存缓存,半夜来插入 func UpdateUWeCustomerLoginTime(weUserID uint32) { //todo 考虑开个协程单独慢慢记
var err error var err error
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
_, err = stmtUpdateWechatUserLogin.Exec(time.Now().Format("2006-01-02 15:04:05.000"), weUserID) //这里格式化可加可不加 _, err = stmtUpdateWechatUserLogin.Exec(time.Now().Format("2006-01-02 15:04:05.000"), weUserID) //这里格式化可加可不加
...@@ -18,7 +18,7 @@ func UpdateUWeCustomerLoginTime(weUserID uint32) { //todoN 以后添加微信登 ...@@ -18,7 +18,7 @@ func UpdateUWeCustomerLoginTime(weUserID uint32) { //todoN 以后添加微信登
return return
} }
fmt.Println("UpdateUWeCustomerLoginTime:", i, err) fmt.Println("UpdateUWeCustomerLoginTime:", i, err)
time.Sleep(3 * time.Second) time.Sleep(30 * time.Millisecond)
} }
logger.Log.Error("UpdateUWeCustomerLoginTime Err", logger.Log.Error("UpdateUWeCustomerLoginTime Err",
zap.Error(err)) zap.Error(err))
......
...@@ -30,6 +30,11 @@ type CacheAreaServiceStruct struct { ...@@ -30,6 +30,11 @@ type CacheAreaServiceStruct struct {
ReplacementCardFee int32 // 补卡费 ReplacementCardFee int32 // 补卡费
} }
type CachePhoneMsgFeeStruct struct {
Amount int32 // 留言月服务费,单位分
SplitAmount []PaySplitMoneyStruct // 分账信息
}
type CacheWeCustomerStruct struct { type CacheWeCustomerStruct struct {
// TokenCreatTime int64 // TokenCreatTime int64
OpenID string // 微信OpenID OpenID string // 微信OpenID
...@@ -53,6 +58,7 @@ type CacheUpdateCardUserStruct struct { ...@@ -53,6 +58,7 @@ type CacheUpdateCardUserStruct struct {
// Class *int8 // Class *int8
// StuNum *string // StuNum *string
PhoneExpiry *time.Time //电话机判断有效期按这个来,电话卡充没充值按这个来 PhoneExpiry *time.Time //电话机判断有效期按这个来,电话卡充没充值按这个来
MsgExpiry *time.Time // 留言服务到期时间
SimCardID *string SimCardID *string
// LocationCardID uint32 // LocationCardID uint32
// IcCardID uint32 // IcCardID uint32
...@@ -68,17 +74,25 @@ type CacheCardUserStruct struct { ...@@ -68,17 +74,25 @@ type CacheCardUserStruct struct {
// Grade int8 // Grade int8
// Class int8 // Class int8
// StuNum string // StuNum string
PhoneExpiry time.Time //电话机判断有效期按这个来,电话卡充没充值按这个来 PhoneExpiry time.Time // 电话机判断有效期按这个来,电话卡充没充值按这个来
MsgExpiry time.Time // 留言服务到期时间
SimCardID string SimCardID string
// LocationCardID uint32 // LocationCardID uint32
// IcCardID uint32 // IcCardID uint32
} }
type CacheCardUserTrendStruct struct { type CacheCardUserTrendStruct struct {
ServiceType uint8 `json:"service" example:"1"` // 服务项目 1公话2定位3饮水4卡消费5洗浴6洗衣机 决定UI图标及颜色等 ServiceType uint8 `json:"service" example:"1"` // 服务项目 1公话2定位3饮水4卡消费5洗浴6洗衣机 决定UI图标及颜色等
Title string `json:"title" example:"公话机-教1楼3层"` // 显示在第一行 公话机-PlaceUser Title string `json:"title" example:"公话机-教1楼3层"` // 显示在第一行 公话机-PlaceUser
Content string `json:"content" example:"被叫:爸爸 时长:2分"` // 显示在第二行 nickname+talkTime Content string `json:"content" example:"被叫:爸爸 时长:2分"` // 显示在第二行 nickname+talkTime
Time string `json:"time" example:"2021-10-23 17:00:00"` // 显示在第三行,呼叫起始时间 Time time.Time `json:"time" example:"2021-10-23 17:00:00"` // 显示在第三行,呼叫起始时间
}
type CacheCardUserNReadMsgStruct struct {
ID uint32 // 留言ID
CreateAt time.Time // 留言时间
WeUserID uint32 // 留言人的微信ID
Msg string // 留言内容
} }
type CacheUpdateSimInfoStruct struct { type CacheUpdateSimInfoStruct struct {
...@@ -124,7 +138,7 @@ type CachePhone20DeviceStruct struct { // 绑定了校区的才存 ...@@ -124,7 +138,7 @@ type CachePhone20DeviceStruct struct { // 绑定了校区的才存
// //
//} //}
type PhonePaySplitMoneyStruct struct { type PaySplitMoneyStruct struct {
AdminID uint32 //`json:"adminID"` // AdminID uint32 //`json:"adminID"` //
Amount int32 //`json:"amount"` // 金额分 Amount int32 //`json:"amount"` // 金额分
Remark string Remark string
...@@ -135,14 +149,15 @@ type CacheAreaServicePhonePayBase struct { ...@@ -135,14 +149,15 @@ type CacheAreaServicePhonePayBase struct {
Amount int32 `json:"amount" example:"6000"` // 金额(单位分) Amount int32 `json:"amount" example:"6000"` // 金额(单位分)
MonthMin uint16 `json:"monthMin"` // 月套餐通话分钟数 MonthMin uint16 `json:"monthMin"` // 月套餐通话分钟数
// ExpiryAt string `json:"expiry" example:"2021-12-31 23:59:59"` // 有效期至:2021-12-31 23:59:59 // 数据库无此字段,现算出来的 // ExpiryAt string `json:"expiry" example:"2021-12-31 23:59:59"` // 有效期至:2021-12-31 23:59:59 // 数据库无此字段,现算出来的
Expiry uint8 `json:"-"` // 有效期月数,前端计算到期时间,显示有效期 Expiry uint8 `json:"-"` // 有效期月数,前端计算到期时间,显示有效期
Describe string `json:"describe" example:"完成充值后生活老师会将电话卡配发给学生"` // 描述 Describe string `json:"describe" example:"完成充值后生活老师会将电话卡配发给学生"` // 描述
MsgEnable uint8 `json:"msgEnable"` // 是否展示 0 不展示 1 必选项 2 可选项默认不勾选 3 可选项默认勾选
} }
type CacheAreaServicePhonePayListStruct struct { type CacheAreaServicePhonePayListStruct struct {
CacheAreaServicePhonePayBase CacheAreaServicePhonePayBase
SplitAmount []PhonePaySplitMoneyStruct `json:"-"` // 分账信息 不生成json,即不用传给小程序 SplitAmount []PaySplitMoneyStruct `json:"-"` // 分账信息 不生成json,即不用传给小程序
Status bool `json:"-"` // 是否有效,不传给小程序 Status bool `json:"-"` // 是否有效,不传给小程序
} }
//type CacheWechatMchInfoStruct struct { // MchID string // 商户ID //type CacheWechatMchInfoStruct struct { // MchID string // 商户ID
......
...@@ -3,23 +3,26 @@ package dcphone20 ...@@ -3,23 +3,26 @@ package dcphone20
import ( import (
"dc_golang_server_1/grpc_client/GrpcFromDeviceConn" "dc_golang_server_1/grpc_client/GrpcFromDeviceConn"
"dc_golang_server_1/grpc_server/Grpc2Phone20TcpConn" "dc_golang_server_1/grpc_server/Grpc2Phone20TcpConn"
myGRPC "dc_golang_server_1/my_grpc/grpc_k122Server" "dc_golang_server_1/my_grpc/grpc_k122Server"
"dc_golang_server_1/util/setting"
"google.golang.org/grpc" "google.golang.org/grpc"
"net" "net"
) )
var TCP DCPhone20 // http接口改到admin,这个变量放到函数里面去
func NewDCPhone20() { func NewDCPhone20() {
go func() { // todo 加下 recover go func() { // todo 加下 recover
GrpcFromDeviceConn.Init() GrpcFromDeviceConn.Init()
var tcp DCPhone20
tcp.NewDCPhone20("DCRYM-2018-pswd.", "I can't tell YOU", 0x5B) // setting TCP.NewDCPhone20("DCRYM-2018-pswd.", "I can't tell YOU", 0x5B) // setting
l, err := net.Listen("tcp", ":7011") l, err := net.Listen("tcp", setting.Grpc2TcpConnListenPort)
if err != nil { if err != nil {
panic(err) panic(err)
} }
s := grpc.NewServer() s := grpc.NewServer()
myGRPC.RegisterGrpc2TcpConnServer(s, &Grpc2Phone20TcpConn.ToTcpConnServer{ k122Server.RegisterGrpc2TcpConnServer(s, &Grpc2Phone20TcpConn.ToTcpConnServer{
ReceiveResponse: tcp.ReceiveResponse, ReceiveResponse: TCP.ReceiveResponse,
}) })
err = s.Serve(l) err = s.Serve(l)
if err != nil { if err != nil {
......
...@@ -66,6 +66,42 @@ definitions: ...@@ -66,6 +66,42 @@ definitions:
example: 1 example: 1
type: integer type: integer
type: object type: object
api_we_card_operate.qr2StudentsRes:
properties:
areaID:
description: 区域ID 用作创建学生
type: integer
areaName:
description: 区域名字 用作创建学生
type: string
cardNum:
description: 卡号 等会调绑卡接口来用
type: string
cardType:
description: 卡类型:1电话卡 等会调绑卡接口来用
type: integer
students:
description: 学生列表
items:
properties:
cid:
description: 学生ID 等会调绑卡接口来用
type: integer
expiry:
description: 缴费的到期时间,年月日(日期当天则仍在有效期内),展示给用户看,如果过了,就要先缴费才能绑卡,如果是"0001-01-01",则表示从来未缴过费
type: string
master:
description: 是否为主家长,页面上展示出来
type: boolean
name:
description: 学生昵称,另外去把头像也拉下来展示出来
type: string
sex:
description: 性别 0,无信息,1女,2男
type: integer
type: object
type: array
type: object
api_we_login_we_info.weLoginReq: api_we_login_we_info.weLoginReq:
properties: properties:
code: code:
...@@ -113,6 +149,40 @@ definitions: ...@@ -113,6 +149,40 @@ definitions:
iv: iv:
type: string type: string
type: object type: object
api_we_msg.msgPayStruct:
properties:
amount:
description: 金额
type: integer
expiry:
description: 缴费后有效期
type: string
status:
description: 0 留言服务已到期 1 未开通留言服务
type: integer
type: object
api_we_msg.resNReadMsg:
properties:
avatarURL:
description: 头像URL
type: string
createAt:
description: 创建时间
type: string
delEnable:
description: 是否可删除
type: boolean
id:
type: integer
msg:
type: string
nickname:
description: 微信昵称
type: string
phone:
description: 手机号
type: string
type: object
api_we_phone_card.apiDeleteFamilyNumStruct: api_we_phone_card.apiDeleteFamilyNumStruct:
properties: properties:
phone: phone:
...@@ -141,6 +211,9 @@ definitions: ...@@ -141,6 +211,9 @@ definitions:
monthPack: monthPack:
description: 月套餐分钟数 description: 月套餐分钟数
type: integer type: integer
msgEnable:
description: 是否显示留言按钮(本区域服务是否开通留言服务)
type: boolean
simID: simID:
description: 卡号 description: 卡号
type: string type: string
...@@ -200,6 +273,12 @@ definitions: ...@@ -200,6 +273,12 @@ definitions:
monthMin: monthMin:
description: 月套餐通话分钟数 description: 月套餐通话分钟数
type: integer type: integer
msgAmount:
description: 留言服务费
type: integer
msgEnable:
description: 是否展示 0 不展示 1 必选项 2 可选项默认不勾选 3 可选项默认勾选
type: integer
type: object type: object
type: array type: array
type: object type: object
...@@ -214,6 +293,9 @@ definitions: ...@@ -214,6 +293,9 @@ definitions:
lid: lid:
description: 选填,话费支付列表id,若不传则不充话费,只是开卡或补卡(实际应用中,补卡就不传这个) description: 选填,话费支付列表id,若不传则不充话费,只是开卡或补卡(实际应用中,补卡就不传这个)
type: integer type: integer
msg:
description: 选填,补开通留言服务或充话费时才有效,且即便是充话费的时候都可以不填,不填就默认不开通留言服务,若只填了CID和Msg则为补开通留言服务
type: boolean
type: object type: object
api_we_slave.apiDeleteSlaveWeUserStruct: api_we_slave.apiDeleteSlaveWeUserStruct:
properties: properties:
...@@ -233,6 +315,9 @@ definitions: ...@@ -233,6 +315,9 @@ definitions:
name: name:
description: 学生名字,脱敏显示 description: 学生名字,脱敏显示
type: string type: string
sex:
description: 0,无信息,1女,2男
type: integer
type: object type: object
api_we_slave.slaveWeUserRes: api_we_slave.slaveWeUserRes:
properties: properties:
...@@ -246,7 +331,7 @@ definitions: ...@@ -246,7 +331,7 @@ definitions:
description: 手机号 description: 手机号
type: string type: string
weUserID: weUserID:
description: 微信UnionID description: 微信用户ID
type: integer type: integer
type: object type: object
api_we_student.GetCardUserAndTrendRes: api_we_student.GetCardUserAndTrendRes:
...@@ -349,6 +434,41 @@ definitions: ...@@ -349,6 +434,41 @@ definitions:
description: Grade int8 `json:"grade"` // 必填,"1~9对应一年级~九年级,10~12对应高一~高三" description: Grade int8 `json:"grade"` // 必填,"1~9对应一年级~九年级,10~12对应高一~高三"
type: integer type: integer
type: object type: object
dbcurd.InsertTableUMsgNReadStruct:
properties:
aid:
description: 区域服务ID
type: integer
cardUserID:
description: 学生ID
type: integer
msg:
description: 留言内容
type: string
type: object
dbcurd.SelectUMsgReadRecordRes:
properties:
avatarURL:
description: 头像URL
type: string
createAt:
description: 创建时间
type: string
msg:
type: string
nickname:
description: 微信昵称
type: string
phone:
description: 手机号
type: string
place:
description: 读取的设备位置
type: string
readAt:
description: 学生读取时间
type: string
type: object
dbcurd.SelectUPhonePayRecordStruct: dbcurd.SelectUPhonePayRecordStruct:
properties: properties:
amount: amount:
...@@ -528,7 +648,14 @@ info: ...@@ -528,7 +648,14 @@ info:
/we/pay 接口调整 /we/pay 接口调整
/we/payrecord 接口调整 /we/payrecord 接口调整
/we/payrecord/{aid} [GET] 接口增加字段 /we/payrecord/{aid} [GET] 接口增加字段
2022-02-26 /serverops/sysstate [GET] 取消PhoneTcpSocketNo字段,在adminServer去增加,因为连接硬件的服务从本服务剥离出去了 2022-02-26 /serverops/sysstate [GET] 取消PhoneTcpSocketNo字段,在adminServer增加了本字段,因为连接硬件的服务从本服务剥离出去了
2022-02-26 /we/qr2students/{qrcode} [GET] 增加这个接口,请仔细阅读下方接口说明
2022-03-03 /we/phonecardstatus/{id} [GET] 这个接口返回的status=1时,显示留言按钮
家长点击自己的微信头像,重新问用户要昵称和头像授权并上传更新
/we/phonecardstatus/{id} [GET] 接口增加 msgEnable字段,用于表示该区域有没有留言服务
/we/paylist/{aid}/{id} [GET] 接口增加留言服务费及是否可选项字段
/we/pay/{aid} [POST] 支付接口增加msg字段,补交留言服务费也用这个接口
title: 多彩中小学一卡通系统 title: 多彩中小学一卡通系统
version: V0.0.9 version: V0.0.9
paths: paths:
...@@ -1197,6 +1324,102 @@ paths: ...@@ -1197,6 +1324,102 @@ paths:
summary: 登录(测试的假code) [complete] summary: 登录(测试的假code) [complete]
tags: tags:
- 家长微信-登录及微信信息上传 - 家长微信-登录及微信信息上传
/we/msg:
post:
consumes:
- application/json
description: 家长向学生发起留言,注意,超过10条将删除前面的留言
parameters:
- description: 留言信息
in: body
name: data
required: true
schema:
$ref: '#/definitions/dbcurd.InsertTableUMsgNReadStruct'
produces:
- application/json
responses:
"0":
description: ""
security:
- ApiKeyAuth: []
summary: 家长向学生发起留言
tags:
- 家长微信-留言
/we/msg/{cid}/{mid}:
delete:
description: 家长删除未读留言
parameters:
- description: 学生ID
in: path
name: cid
required: true
type: integer
- description: 留言ID
in: path
name: mid
required: true
type: integer
produces:
- application/json
responses:
"0":
description: ""
security:
- ApiKeyAuth: []
summary: 家长删除未读留言
tags:
- 家长微信-留言
/we/msgnread/{aid}/{cid}:
get:
description: 家长获取未读留言列表
parameters:
- description: 学生ID
in: path
name: cid
required: true
type: integer
produces:
- application/json
responses:
"0":
description: 留言列表
schema:
items:
$ref: '#/definitions/api_we_msg.resNReadMsg'
type: array
"1":
description: ""
schema:
$ref: '#/definitions/api_we_msg.msgPayStruct'
security:
- ApiKeyAuth: []
summary: 家长获取未读留言列表,注意,这个接口有可能返回 []resNReadMsg ,也有可能返回 msgPayStruct
tags:
- 家长微信-留言
/we/msgread/{aid}/{cid}:
get:
description: 家长获取已读留言列表
parameters:
- description: 学生ID
in: path
name: cid
required: true
type: integer
produces:
- application/json
responses:
"0":
description: 留言列表
schema:
items:
$ref: '#/definitions/dbcurd.SelectUMsgReadRecordRes'
type: array
security:
- ApiKeyAuth: []
summary: 家长获取已读留言列表
tags:
- 家长微信-留言
/we/pay/{aid}: /we/pay/{aid}:
post: post:
consumes: consumes:
...@@ -1347,6 +1570,27 @@ paths: ...@@ -1347,6 +1570,27 @@ paths:
summary: 根据二维码,返回卡号信息[complete] summary: 根据二维码,返回卡号信息[complete]
tags: tags:
- 家长微信-卡操作 - 家长微信-卡操作
/we/qr2students/{qrcode}:
get:
description: 根据二维码,返回用户状态信息及卡号
parameters:
- description: QR内容
in: path
name: qrcode
required: true
type: string
produces:
- application/json
responses:
"0":
description: result
schema:
$ref: '#/definitions/api_we_card_operate.qr2StudentsRes'
security:
- ApiKeyAuth: []
summary: 根据二维码,返回用户状态信息及卡号
tags:
- 家长微信-卡操作
/we/replacecardfee/phone/{aid}: /we/replacecardfee/phone/{aid}:
get: get:
description: 查询补卡费(目前仅公话卡) description: 查询补卡费(目前仅公话卡)
......
...@@ -16,9 +16,9 @@ func (s *ToAdminServer) CacheAddPhonePayList(ctx context.Context, req *myGRPC.Ca ...@@ -16,9 +16,9 @@ func (s *ToAdminServer) CacheAddPhonePayList(ctx context.Context, req *myGRPC.Ca
return new(myGRPC.Empty), errors.New("AreaServiceID err") return new(myGRPC.Empty), errors.New("AreaServiceID err")
} }
splitAmount := make([]model.PhonePaySplitMoneyStruct, len(req.SplitAmount)) splitAmount := make([]model.PaySplitMoneyStruct, len(req.SplitAmount))
for i, v := range req.SplitAmount { for i, v := range req.SplitAmount {
splitAmount[i] = model.PhonePaySplitMoneyStruct{ splitAmount[i] = model.PaySplitMoneyStruct{
AdminID: v.AdminID, AdminID: v.AdminID,
Amount: v.Amount, Amount: v.Amount,
Remark: v.Remark, Remark: v.Remark,
...@@ -46,9 +46,9 @@ func (s *ToAdminServer) CacheUpdatePhonePayList(ctx context.Context, req *myGRPC ...@@ -46,9 +46,9 @@ func (s *ToAdminServer) CacheUpdatePhonePayList(ctx context.Context, req *myGRPC
return new(myGRPC.Empty), errors.New("AreaServiceID err") return new(myGRPC.Empty), errors.New("AreaServiceID err")
} }
splitAmount := make([]model.PhonePaySplitMoneyStruct, len(req.SplitAmount)) splitAmount := make([]model.PaySplitMoneyStruct, len(req.SplitAmount))
for i, v := range req.SplitAmount { for i, v := range req.SplitAmount {
splitAmount[i] = model.PhonePaySplitMoneyStruct{ splitAmount[i] = model.PaySplitMoneyStruct{
AdminID: v.AdminID, AdminID: v.AdminID,
Amount: v.Amount, Amount: v.Amount,
Remark: v.Remark, Remark: v.Remark,
......
...@@ -5,6 +5,7 @@ import ( ...@@ -5,6 +5,7 @@ import (
"dc_golang_server_1/data_db_cache/cache" "dc_golang_server_1/data_db_cache/cache"
"dc_golang_server_1/data_db_cache/dbcurd" "dc_golang_server_1/data_db_cache/dbcurd"
"dc_golang_server_1/dev_product/dcphone20" "dc_golang_server_1/dev_product/dcphone20"
"dc_golang_server_1/grpc_client/GrpcFromDeviceConn"
"dc_golang_server_1/grpc_server/Grpc2Admin" "dc_golang_server_1/grpc_server/Grpc2Admin"
"dc_golang_server_1/logger" "dc_golang_server_1/logger"
myGRPC "dc_golang_server_1/my_grpc/grpc_k122Server" myGRPC "dc_golang_server_1/my_grpc/grpc_k122Server"
...@@ -32,7 +33,14 @@ import ( ...@@ -32,7 +33,14 @@ import (
// @Description /we/pay 接口调整 // @Description /we/pay 接口调整
// @Description /we/payrecord 接口调整 // @Description /we/payrecord 接口调整
// @Description /we/payrecord/{aid} [GET] 接口增加字段 // @Description /we/payrecord/{aid} [GET] 接口增加字段
// @Description 2022-02-26 /serverops/sysstate [GET] 取消PhoneTcpSocketNo字段,在adminServer去增加,因为连接硬件的服务从本服务剥离出去了 // @Description 2022-02-26 /serverops/sysstate [GET] 取消PhoneTcpSocketNo字段,在adminServer增加了本字段,因为连接硬件的服务从本服务剥离出去了
// @Description 2022-02-26 /we/qr2students/{qrcode} [GET] 增加这个接口,请仔细阅读下方接口说明
// @Description 2022-03-03 /we/phonecardstatus/{id} [GET] 这个接口返回的status=1时,显示留言按钮
// @Description
// @Description 家长点击自己的微信头像,重新问用户要昵称和头像授权并上传更新
// @Description /we/phonecardstatus/{id} [GET] 接口增加 msgEnable字段,用于表示该区域有没有留言服务
// @Description /we/paylist/{aid}/{id} [GET] 接口增加留言服务费及是否可选项字段
// @Description /we/pay/{aid} [POST] 支付接口增加msg字段,补交留言服务费也用这个接口
// @securityDefinitions.apikey ApiKeyAuth // @securityDefinitions.apikey ApiKeyAuth
// @in header // @in header
// @name token // @name token
...@@ -44,25 +52,27 @@ func main() { // ...@@ -44,25 +52,27 @@ func main() { //
setting.Init() setting.Init()
logger.Init() logger.Init()
dbcurd.InitDb() dbcurd.InitDb()
cache.Init()
go func() { go func() {
osc := make(chan os.Signal, 1) osc := make(chan os.Signal, 1)
signal.Notify(osc, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL) signal.Notify(osc, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL)
s := <-osc s := <-osc
cache.SystemExitToSaveTrend()
dbcurd.CloseDb() dbcurd.CloseDb()
GrpcFromDeviceConn.CloseGrpc()
fmt.Println(time.Now(), "程序退出:", s) fmt.Println(time.Now(), "程序退出:", s)
os.Exit(1) os.Exit(1)
}() }()
cache.Init()
//tencent.InitWechatPay() //tencent.InitWechatPay()
dcphone20.NewDCPhone20() dcphone20.NewDCPhone20()
GrpcFromDeviceConn.Init()
//dcdrinking60.NewDCDrinking60() //dcdrinking60.NewDCDrinking60()
go func() { go func() {
l, err := net.Listen("tcp", ":7010") l, err := net.Listen("tcp", setting.Grpc2AdminListenPort)
if err != nil { if err != nil {
panic(err) panic(err)
} }
...@@ -82,6 +92,10 @@ func main() { // ...@@ -82,6 +92,10 @@ func main() { //
router.InitRouter() router.InitRouter()
} }
// 1. 新增区域服务若选择公话,则新增开启留言服务的可选项,若选择开启留言服务,则应输入留言月服务费,若留言月服务费>0,则可添加分账项
// 2. b_phone_pay_list, 增加 msg_enable 字段
// 定时任务: // 定时任务:
// 1. 每月最后一天晚上11点半开始,统一从移动系统删除亲情号,然后更新亲情号可修改次数,然后更新套餐分钟数。 // 1. 每月最后一天晚上11点半开始,统一从移动系统删除亲情号,然后更新亲情号可修改次数,然后更新套餐分钟数。
// 2. 每晚校验缓存,同时更新用户登录次数和时间 // 2. 每晚校验缓存,同时更新用户登录次数和时间
...@@ -2,7 +2,7 @@ syntax = "proto3"; ...@@ -2,7 +2,7 @@ syntax = "proto3";
option go_package = "./k122Server"; option go_package = "./k122Server";
package my_grpc; package k122Server;
message CacheAreaReq { message CacheAreaReq {
uint32 AreaID = 1; uint32 AreaID = 1;
......
...@@ -92,7 +92,7 @@ type ConsumeApplyStruct struct { ...@@ -92,7 +92,7 @@ type ConsumeApplyStruct struct {
AreaServiceAllinPayID uint32 //收款主体的adminID AreaServiceAllinPayID uint32 //收款主体的adminID
OrderNum string // 订单号 OrderNum string // 订单号
Amount int32 Amount int32
SplitAmount []model.PhonePaySplitMoneyStruct SplitAmount []model.PaySplitMoneyStruct
} }
type WxMiniRequestPayment struct { type WxMiniRequestPayment struct {
...@@ -205,7 +205,7 @@ func Pay(req *ConsumeApplyStruct) *WxMiniRequestPayment { // ...@@ -205,7 +205,7 @@ func Pay(req *ConsumeApplyStruct) *WxMiniRequestPayment { //
//} //}
//if len(req.SplitAmount) == 0 { // 如果没有传入分账信息,则全部收入收款主体 //if len(req.SplitAmount) == 0 { // 如果没有传入分账信息,则全部收入收款主体
// req.SplitAmount = append(req.SplitAmount,model.PhonePaySplitMoneyStruct{ // req.SplitAmount = append(req.SplitAmount,model.PaySplitMoneyStruct{
// AdminID: req.AreaServiceAllinPayID, // AdminID: req.AreaServiceAllinPayID,
// Amount: req.Amount, // Amount: req.Amount,
// }) // })
...@@ -386,7 +386,7 @@ func PayCallback(c *gin.Context) { ...@@ -386,7 +386,7 @@ func PayCallback(c *gin.Context) {
c.Status(404) c.Status(404)
return // 订单号都不对,看看要不要回复它,免得它一直发 return // 订单号都不对,看看要不要回复它,免得它一直发
} }
//订单号生成规则:4B cardUserID,4B到期时间,4B 金额amount,8B 时间纳秒 //订单号生成规则:4B cardUserID,4B到期时间,4B 金额amount,1B payType,8B 时间纳秒
cardUserID := uint32(orderBytes[0])<<24 + uint32(orderBytes[1])<<16 + uint32(orderBytes[2])<<8 + uint32(orderBytes[3]) cardUserID := uint32(orderBytes[0])<<24 + uint32(orderBytes[1])<<16 + uint32(orderBytes[2])<<8 + uint32(orderBytes[3])
expiryUnix := int64(orderBytes[4])<<24 + int64(orderBytes[5])<<16 + int64(orderBytes[6])<<8 + int64(orderBytes[7]) expiryUnix := int64(orderBytes[4])<<24 + int64(orderBytes[5])<<16 + int64(orderBytes[6])<<8 + int64(orderBytes[7])
// amount := uint32(orderBytes[8])<<24 + uint32(orderBytes[9])<<16 +uint32(orderBytes[10])<<8 + uint32(orderBytes[11]) // amount := uint32(orderBytes[8])<<24 + uint32(orderBytes[9])<<16 +uint32(orderBytes[10])<<8 + uint32(orderBytes[11])
...@@ -410,6 +410,24 @@ func PayCallback(c *gin.Context) { ...@@ -410,6 +410,24 @@ func PayCallback(c *gin.Context) {
} }
expiry := time.Unix(expiryUnix, 0) expiry := time.Unix(expiryUnix, 0)
//switch orderBytes[12] { // payType
//case 0x01: // "开卡费"
//case 0x02: // "补卡费"
//case 0x10: // "话费充值"
//case 0x11: // "充值(含开卡)"
//case 0x12: // "充值(含补卡)"
//case 0x20+0x10: // "话费充值(含留言服务)"
//case 0x20+0x11: // "充值(含开卡、留言服务)"
//case 0x20+0x12: // "充值(含补卡、留言服务)"
//case 0x20: // 仅补缴留言服务
//}
//if orderBytes[12] == 0x20 {
// // todo zjzjzj 判断是否已经有家长缴费了,如果有了则这一单缴费缴重复了应该退款
//}
msgNew := orderBytes[12]&0x20 == 0x20
// 1. 更新库 用事务处理 // 1. 更新库 用事务处理
if dbcurd.UpdateUPhonePayRecordPayAtAndUCardUserPhoneExpiryTransaction(&dbcurd.UpdateUPhonePayRecordStruct{ if dbcurd.UpdateUPhonePayRecordPayAtAndUCardUserPhoneExpiryTransaction(&dbcurd.UpdateUPhonePayRecordStruct{
CardUserID: cardUserID, CardUserID: cardUserID,
...@@ -420,11 +438,16 @@ func PayCallback(c *gin.Context) { ...@@ -420,11 +438,16 @@ func PayCallback(c *gin.Context) {
ThirdNum: orderData.OrderNo, ThirdNum: orderData.OrderNo,
TencentTradeNum: orderData.PayInterfaceOutTradeNo, TencentTradeNum: orderData.PayInterfaceOutTradeNo,
Fee: uint32(fee), Fee: uint32(fee),
}) { }, msgNew) {
// 更新两个库都成功,那就写缓存回成功 2. 修改缓存的到期时间 // 更新两个库都成功,那就写缓存回成功 2. 修改缓存的到期时间
if cache.UpdateCardUserMap(cardUserID, &model.CacheUpdateCardUserStruct{ temp := model.CacheUpdateCardUserStruct{
PhoneExpiry: &expiry, PhoneExpiry: &expiry,
}) == false { }
if msgNew {
temp.MsgExpiry = &expiry
}
if cache.UpdateCardUserMap(cardUserID, &temp) == false {
fmt.Println("WechatPay 写缓存失败", cardUserID) fmt.Println("WechatPay 写缓存失败", cardUserID)
} }
c.Status(200) c.Status(200)
......
...@@ -8,14 +8,14 @@ import ( ...@@ -8,14 +8,14 @@ import (
// NewCardAddExpiry 计算新开卡充值后话费有效期 // NewCardAddExpiry 计算新开卡充值后话费有效期
// 计算逻辑:本月免费,下月开始计费 // 计算逻辑:本月免费,下月开始计费
func NewCardAddExpiry(month uint8) time.Time{ func NewCardAddExpiry(month uint8) time.Time {
return dateAddExpiryMonth(time.Now(),month) return dateAddExpiryMonth(time.Now(), month)
} }
// RenewExpiry 续费时计算新的有效期 // RenewExpiry 续费时计算新的有效期
// 计算逻辑:原有效期基础上加有效期月份,例如原有效期为2022-03-31 23:59:59 续费12个月 则为2023-03-31 23:59:59 // 计算逻辑:原有效期基础上加有效期月份,例如原有效期为2022-03-31 23:59:59 续费12个月 则为2023-03-31 23:59:59
func RenewExpiry(t time.Time,month uint8) time.Time{ func RenewExpiry(t time.Time, month uint8) time.Time {
return dateAddExpiryMonth(t,month) return dateAddExpiryMonth(t, month)
} }
// JudgeCardCancel 判断学生话费状态 返回 0 有效期内 3 服务已到期 4 未充值(即从未充过值) 5 已销号,请补卡 // JudgeCardCancel 判断学生话费状态 返回 0 有效期内 3 服务已到期 4 未充值(即从未充过值) 5 已销号,请补卡
...@@ -25,11 +25,11 @@ func JudgeCardCancel(t time.Time) uint8 { ...@@ -25,11 +25,11 @@ func JudgeCardCancel(t time.Time) uint8 {
return 4 return 4
} }
if time.Now().Before(t) { if time.Now().Before(t.Add(23 * time.Hour)) {
return 0 return 0
} }
if time.Now().Before(dateAddExpiryMonth(t,1)) { if time.Now().Before(dateAddExpiryMonth(t, 1)) {
return 3 return 3
} }
...@@ -37,17 +37,41 @@ func JudgeCardCancel(t time.Time) uint8 { ...@@ -37,17 +37,41 @@ func JudgeCardCancel(t time.Time) uint8 {
} }
// 加有效期月份,返回某年某月的最后一天的23:59:59,为0则为当月底,例如:3月10号加1个月有效期,即到4-30 23:59:59 // 加有效期月份,返回某年某月的最后一天的23:59:59,为0则为当月底,例如:3月10号加1个月有效期,即到4-30 23:59:59
func dateAddExpiryMonth(t time.Time,months uint8) time.Time { func dateAddExpiryMonth(t time.Time, months uint8) time.Time {
year, month, day := t.Date() year, month, day := t.Date()
// firstDayOfMonthAfterAddDate: years 年,months 月后的 那个月份的1号 // firstDayOfMonthAfterAddDate: years 年,months 月后的 那个月份的1号
firstDayOfMonthAfterAddDate := time.Date(year, month+time.Month(months), 1, firstDayOfMonthAfterAddDate := time.Date(year, month+time.Month(months), 1,
0, 0, 0, 0,time.Now().Location()) 0, 0, 0, 0, time.Now().Location())
// firstDayOfMonthAfterAddDate 月份的最后一天 // firstDayOfMonthAfterAddDate 月份的最后一天
day = firstDayOfMonthAfterAddDate.AddDate(0,1,-1).Day() day = firstDayOfMonthAfterAddDate.AddDate(0, 1, -1).Day()
return time.Date(year, month+time.Month(months), day, return time.Date(year, month+time.Month(months), day,
23, 59, 59, 0, time.Now().Location()) 23, 00, 00, 0, time.Now().Location())
}
// SubMonth 计算日期相差多少月,当月就是0个月
func SubMonth(t1, t2 time.Time) (month int32) {
y1 := int32(t1.Year())
y2 := int32(t2.Year())
m1 := int32(t1.Month())
m2 := int32(t2.Month())
d1 := t1.Day()
d2 := t2.Day()
yearInterval := y1 - y2
// 如果 d1的 月-日 小于 d2的 月-日 那么 yearInterval-- 这样就得到了相差的年数
if m1 < m2 || m1 == m2 && d1 < d2 {
yearInterval--
}
// 获取月数差值
monthInterval := (m1 + 12) - m2
if d1 < d2 {
monthInterval--
}
monthInterval %= 12
month = yearInterval*12 + monthInterval
return
} }
//// NowDateAddMonth 加月份,返回年月日 //// NowDateAddMonth 加月份,返回年月日
...@@ -69,4 +93,4 @@ func dateAddExpiryMonth(t time.Time,months uint8) time.Time { ...@@ -69,4 +93,4 @@ func dateAddExpiryMonth(t time.Time,months uint8) time.Time {
// //
// return time.Date(year, month+time.Month(months), day, // return time.Date(year, month+time.Month(months), day,
// 0, 0, 0, 0, time.Now().Location()) // 0, 0, 0, 0, time.Now().Location())
//} //}
\ No newline at end of file
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