作者 yangfu

增加功能 消息中心,已读,全部已部

... ... @@ -14,6 +14,11 @@
|我的评论|完成|2019.11.21|/v1/chance/iComments|
|我的点赞| |2019.11.| |
|我的收藏| |2019.11.| |
|消息中心|完成|2019.11.|v1/message/messageCenter|
|标记已读|完成|2019.11.|v1/message/msgCenterRead|
|标记全部已读|完成|2019.11.|v1/message/msgCenterAllRead|
|互动消息-点赞| |2019.11.| |
|互动消息-评论| |2019.11.| |
|我提交的机会| |2019.11.| |
|我审核的机会| |2019.11.| |
|待抓住机会列表| |2019.11. |
... ...
... ... @@ -58,6 +58,10 @@ func (this *BaseController) Valid(obj interface{}) (result bool, msg *protocol.R
}
if !result {
for _, err := range valid.Errors {
if strings.HasSuffix(err.Key, ".Mobile") {
msg = protocol.BadRequestParam(2001)
return
}
log.Error(err.Key, err.Message)
}
msg = protocol.BadRequestParam(2)
... ... @@ -100,6 +104,10 @@ func GetRequestHeader(ctx *context.Context) *protocol.RequestHeader {
h.Uuid = ctx.Input.Header("x-mmm-uuid")
h.TimeStamp = ctx.Input.Header("x-mmm-timestamp")
h.Uid, _ = strconv.ParseInt(ctx.Input.Header("uid"), 10, 64) //需要uid写入到header里面
if h.Uid == 0 {
h.Uid, _ = strconv.ParseInt(ctx.Input.Header("x-mmm-uid"), 10, 64)
}
h.CompanyId, _ = strconv.ParseInt(ctx.Input.Header("x-mmm-companyid"), 10, 64)
return h
}
... ... @@ -112,7 +120,7 @@ func FilterComm(ctx *context.Context) {
//统计
MetricCounter(ctx)
if beego.BConfig.RunMode != "prod" {
if beego.BConfig.RunMode == "dev" {
return
}
... ... @@ -169,7 +177,7 @@ func CheckToken(ctx *context.Context) (result bool) {
var (
msg *protocol.ResponseMessage
)
if strings.HasSuffix(ctx.Request.RequestURI,"login"){
if strings.HasSuffix(ctx.Request.RequestURI, "login") {
return true
}
result = true
... ... @@ -187,7 +195,7 @@ func CheckToken(ctx *context.Context) (result bool) {
} else {
if rsp.UserInfo != nil {
//设置附加数据
ctx.Request.Header.Add("uid", fmt.Sprintf("%v", rsp.UserInfo.UserId))
ctx.Request.Header.Add("x-mmm-uid", fmt.Sprintf("%v", rsp.UserInfo.UserId))
}
}
return
... ...
... ... @@ -6,7 +6,6 @@ import (
"opp/protocol"
"reflect"
"testing"
"time"
)
func Test_GenMessage(t *testing.T) {
... ... @@ -41,16 +40,15 @@ func Benchmark_GenMessage(b *testing.B) {
}
}
func Test_RandTask(t *testing.T){
time :=time.Now().Unix()
num :=1
for i:=1;i<=num;i++{
r :=time%2
if r==0{
t.Log("xh","yf",time)
}
if r==1{
t.Log("yf","xh",time)
func Test_Valid(t *testing.T) {
/*修改手机号*/
type ChangePhoneRequest struct {
Phone string `json:"phone" valid:"Mobile"`
Captcha string `json:"captcha" valid:"Required"`
}
req := &ChangePhoneRequest{
"1886018",
"123",
}
DefaultController.Valid(req)
}
... ...
package v1
import (
"encoding/json"
"gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/log"
"opp/controllers"
"opp/protocol"
"opp/services/message"
)
type MessageController struct {
controllers.BaseController
}
//MessageCenter
// @router /messageCenter [post]
func (this *MessageController) MessageCenter() {
var msg *protocol.ResponseMessage
defer func() {
this.Resp(msg)
}()
var request *protocol.MessageCenterRequest
if err := json.Unmarshal(this.ByteBody, &request); err != nil {
log.Error(err)
msg = protocol.BadRequestParam(1)
return
}
if b, m := this.Valid(request); !b {
msg = m
return
}
header := controllers.GetRequestHeader(this.Ctx)
msg = protocol.NewReturnResponse(message.MessageCenter(header, request))
}
//MsgCenterRead
// @router /msgCenterRead [post]
func (this *MessageController) MsgCenterRead() {
var msg *protocol.ResponseMessage
defer func() {
this.Resp(msg)
}()
var request *protocol.MsgCenterReadRequest
if err := json.Unmarshal(this.ByteBody, &request); err != nil {
log.Error(err)
msg = protocol.BadRequestParam(1)
return
}
if b, m := this.Valid(request); !b {
msg = m
return
}
header := controllers.GetRequestHeader(this.Ctx)
msg = protocol.NewReturnResponse(message.MsgCenterRead(header, request))
}
//MsgCenterAllRead
// @router /msgCenterAllRead [post]
func (this *MessageController) MsgCenterAllRead() {
var msg *protocol.ResponseMessage
defer func() {
this.Resp(msg)
}()
var request *protocol.MsgCenterAllReadRequest
if err := json.Unmarshal(this.ByteBody, &request); err != nil {
log.Error(err)
msg = protocol.BadRequestParam(1)
return
}
if b, m := this.Valid(request); !b {
msg = m
return
}
header := controllers.GetRequestHeader(this.Ctx)
msg = protocol.NewReturnResponse(message.MsgCenterAllRead(header, request))
}
... ...
package repository
import "opp/models"
type IMessageRepository interface {
GetUserMsgTotals(userId int64, companyId int64, msgType int, v interface{}) (err error)
UpdateUserMsgSetRead(userId int64, companyId int64, msgType int, msgId int64) (err error)
}
var _ IMessageRepository = (*MessageRepository)(nil)
type MessageRepository struct{}
func (r *MessageRepository) GetUserMsgTotals(userId int64, companyId int64, msgType int, v interface{}) (err error) {
return models.GetUserMsgTotals(userId, companyId, msgType, v)
}
func (r *MessageRepository) UpdateUserMsgSetRead(userId int64, companyId int64, msgType int, msgId int64) (err error) {
return models.UpdateUserMsgSetRead(userId, companyId, msgType, msgId)
}
... ...
... ... @@ -13,6 +13,7 @@ var (
Position IPositionRepository
Chance IChanceRepository
Comment ICommentRepository
Message IMessageRepository
)
func init() {
... ... @@ -28,6 +29,7 @@ func InitRepository() {
Position = &PositionRepository{}
Chance = &ChanceRepository{}
Comment = &CommentRepository{}
Message = &MessageRepository{}
}
func InitRepositoryMock() {
... ...
package models
import (
"errors"
"fmt"
"reflect"
"strings"
"time"
"github.com/astaxie/beego/orm"
)
type ChanceFavorite struct {
Id int64 `orm:"column(id);pk" description:"点赞编号"`
UserId int64 `orm:"column(user_id)" description:"表user.id 用户编号"`
ObjectType int `orm:"column(object_type)" description:"类型 1:点赞 2:收藏"`
SourceType int `orm:"column(source_type)" description:"来源类型 1:机会 2:评论"`
SourceId int64 `orm:"column(source_id)" description:"来源id 机会编号/评论编号"`
ChanceTypeId int `orm:"column(chance_type_id)" description:"机会类型编号 - 附加 "`
EnableStatus int `orm:"column(enable_status)" description:"1:有效 0:无效"`
CreateAt time.Time `orm:"column(create_at);type(timestamp);null" description:"创建时间"`
DeleteAt time.Time `orm:"column(delete_at);type(timestamp);null" description:"删除时间"`
}
func (t *ChanceFavorite) TableName() string {
return "chance_favorite"
}
func init() {
orm.RegisterModel(new(ChanceFavorite))
}
// AddChanceFavorite insert a new ChanceFavorite into database and returns
// last inserted Id on success.
func AddChanceFavorite(m *ChanceFavorite) (id int64, err error) {
o := orm.NewOrm()
id, err = o.Insert(m)
return
}
// GetChanceFavoriteById retrieves ChanceFavorite by Id. Returns error if
// Id doesn't exist
func GetChanceFavoriteById(id int64) (v *ChanceFavorite, err error) {
o := orm.NewOrm()
v = &ChanceFavorite{Id: id}
if err = o.Read(v); err == nil {
return v, nil
}
return nil, err
}
// GetAllChanceFavorite retrieves all ChanceFavorite matches certain condition. Returns empty list if
// no records exist
func GetAllChanceFavorite(query map[string]string, fields []string, sortby []string, order []string,
offset int64, limit int64) (ml []interface{}, err error) {
o := orm.NewOrm()
qs := o.QueryTable(new(ChanceFavorite))
// query k=v
for k, v := range query {
// rewrite dot-notation to Object__Attribute
k = strings.Replace(k, ".", "__", -1)
if strings.Contains(k, "isnull") {
qs = qs.Filter(k, (v == "true" || v == "1"))
} else {
qs = qs.Filter(k, v)
}
}
// order by:
var sortFields []string
if len(sortby) != 0 {
if len(sortby) == len(order) {
// 1) for each sort field, there is an associated order
for i, v := range sortby {
orderby := ""
if order[i] == "desc" {
orderby = "-" + v
} else if order[i] == "asc" {
orderby = v
} else {
return nil, errors.New("Error: Invalid order. Must be either [asc|desc]")
}
sortFields = append(sortFields, orderby)
}
qs = qs.OrderBy(sortFields...)
} else if len(sortby) != len(order) && len(order) == 1 {
// 2) there is exactly one order, all the sorted fields will be sorted by this order
for _, v := range sortby {
orderby := ""
if order[0] == "desc" {
orderby = "-" + v
} else if order[0] == "asc" {
orderby = v
} else {
return nil, errors.New("Error: Invalid order. Must be either [asc|desc]")
}
sortFields = append(sortFields, orderby)
}
} else if len(sortby) != len(order) && len(order) != 1 {
return nil, errors.New("Error: 'sortby', 'order' sizes mismatch or 'order' size is not 1")
}
} else {
if len(order) != 0 {
return nil, errors.New("Error: unused 'order' fields")
}
}
var l []ChanceFavorite
qs = qs.OrderBy(sortFields...)
if _, err = qs.Limit(limit, offset).All(&l, fields...); err == nil {
if len(fields) == 0 {
for _, v := range l {
ml = append(ml, v)
}
} else {
// trim unused fields
for _, v := range l {
m := make(map[string]interface{})
val := reflect.ValueOf(v)
for _, fname := range fields {
m[fname] = val.FieldByName(fname).Interface()
}
ml = append(ml, m)
}
}
return ml, nil
}
return nil, err
}
// UpdateChanceFavorite updates ChanceFavorite by Id and returns error if
// the record to be updated doesn't exist
func UpdateChanceFavoriteById(m *ChanceFavorite) (err error) {
o := orm.NewOrm()
v := ChanceFavorite{Id: m.Id}
// ascertain id exists in the database
if err = o.Read(&v); err == nil {
var num int64
if num, err = o.Update(m); err == nil {
fmt.Println("Number of records updated in database:", num)
}
}
return
}
// DeleteChanceFavorite deletes ChanceFavorite by Id and returns error if
// the record to be deleted doesn't exist
func DeleteChanceFavorite(id int64) (err error) {
o := orm.NewOrm()
v := ChanceFavorite{Id: id}
// ascertain id exists in the database
if err = o.Read(&v); err == nil {
var num int64
if num, err = o.Delete(&ChanceFavorite{Id: id}); err == nil {
fmt.Println("Number of records deleted in database:", num)
}
}
return
}
... ...
package models
import (
"errors"
"fmt"
"reflect"
"strings"
"time"
"github.com/astaxie/beego/orm"
)
type UserMsg struct {
Id int64 `orm:"column(id);pk" description:"消息表id"`
CompanyId int64 `orm:"column(company_id)" description:"公司编号"`
ReceiveUserId int64 `orm:"column(receive_user_id)" description:"接收用户id"`
MsgType int `orm:"column(msg_type)" description:"消息类型 1.公司公告 2.表彰通知 4.互动消息 8.机会审核"`
Message string `orm:"column(message)" description:"消息内容"`
SourceId int64 `orm:"column(source_id)" description:"来源id (机会编号 /评论编号)"`
IsPublic int8 `orm:"column(is_public)" description:"1:公开 0:不公开"`
IsRead int8 `orm:"column(is_read)" description:"1:已读 0:未读"`
CreateAt time.Time `orm:"column(create_at);type(timestamp);auto_now" description:"创建时间"`
}
func (t *UserMsg) TableName() string {
return "user_msg"
}
func init() {
orm.RegisterModel(new(UserMsg))
}
// AddUserMsg insert a new UserMsg into database and returns
// last inserted Id on success.
func AddUserMsg(m *UserMsg) (id int64, err error) {
o := orm.NewOrm()
id, err = o.Insert(m)
return
}
// GetUserMsgById retrieves UserMsg by Id. Returns error if
// Id doesn't exist
func GetUserMsgById(id int64) (v *UserMsg, err error) {
o := orm.NewOrm()
v = &UserMsg{Id: id}
if err = o.Read(v); err == nil {
return v, nil
}
return nil, err
}
// GetAllUserMsg retrieves all UserMsg matches certain condition. Returns empty list if
// no records exist
func GetAllUserMsg(query map[string]string, fields []string, sortby []string, order []string,
offset int64, limit int64) (ml []interface{}, err error) {
o := orm.NewOrm()
qs := o.QueryTable(new(UserMsg))
// query k=v
for k, v := range query {
// rewrite dot-notation to Object__Attribute
k = strings.Replace(k, ".", "__", -1)
if strings.Contains(k, "isnull") {
qs = qs.Filter(k, (v == "true" || v == "1"))
} else {
qs = qs.Filter(k, v)
}
}
// order by:
var sortFields []string
if len(sortby) != 0 {
if len(sortby) == len(order) {
// 1) for each sort field, there is an associated order
for i, v := range sortby {
orderby := ""
if order[i] == "desc" {
orderby = "-" + v
} else if order[i] == "asc" {
orderby = v
} else {
return nil, errors.New("Error: Invalid order. Must be either [asc|desc]")
}
sortFields = append(sortFields, orderby)
}
qs = qs.OrderBy(sortFields...)
} else if len(sortby) != len(order) && len(order) == 1 {
// 2) there is exactly one order, all the sorted fields will be sorted by this order
for _, v := range sortby {
orderby := ""
if order[0] == "desc" {
orderby = "-" + v
} else if order[0] == "asc" {
orderby = v
} else {
return nil, errors.New("Error: Invalid order. Must be either [asc|desc]")
}
sortFields = append(sortFields, orderby)
}
} else if len(sortby) != len(order) && len(order) != 1 {
return nil, errors.New("Error: 'sortby', 'order' sizes mismatch or 'order' size is not 1")
}
} else {
if len(order) != 0 {
return nil, errors.New("Error: unused 'order' fields")
}
}
var l []UserMsg
qs = qs.OrderBy(sortFields...)
if _, err = qs.Limit(limit, offset).All(&l, fields...); err == nil {
if len(fields) == 0 {
for _, v := range l {
ml = append(ml, v)
}
} else {
// trim unused fields
for _, v := range l {
m := make(map[string]interface{})
val := reflect.ValueOf(v)
for _, fname := range fields {
m[fname] = val.FieldByName(fname).Interface()
}
ml = append(ml, m)
}
}
return ml, nil
}
return nil, err
}
// UpdateUserMsg updates UserMsg by Id and returns error if
// the record to be updated doesn't exist
func UpdateUserMsgById(m *UserMsg) (err error) {
o := orm.NewOrm()
v := UserMsg{Id: m.Id}
// ascertain id exists in the database
if err = o.Read(&v); err == nil {
var num int64
if num, err = o.Update(m); err == nil {
fmt.Println("Number of records updated in database:", num)
}
}
return
}
// DeleteUserMsg deletes UserMsg by Id and returns error if
// the record to be deleted doesn't exist
func DeleteUserMsg(id int64) (err error) {
o := orm.NewOrm()
v := UserMsg{Id: id}
// ascertain id exists in the database
if err = o.Read(&v); err == nil {
var num int64
if num, err = o.Delete(&UserMsg{Id: id}); err == nil {
fmt.Println("Number of records deleted in database:", num)
}
}
return
}
func GetUserMsgTotals(userId int64, companyId int64, msgType int, v interface{}) (err error) {
o := orm.NewOrm()
sql := `select COUNT(*) as total,msg_type from user_msg
where (msg_type & ?)>0 and receive_user_id = ? and is_public=1 and is_read=0 and company_id=?
GROUP BY msg_type`
if _, err = o.Raw(sql, msgType, userId, companyId).QueryRows(v); err == nil {
return
}
return
}
func UpdateUserMsgSetRead(userId int64, companyId int64, msgType int, msgId int64) (err error) {
o := orm.NewOrm()
sql := `update user_msg set is_read = 1
where receive_user_id = ? and company_id=? and is_public=1 `
if msgType > 0 {
sql += fmt.Sprintf(" and (msg_type & %v)>0", msgType)
}
if msgId > 0 {
sql += fmt.Sprintf(" and id=%v", msgId)
}
if _, err = o.Raw(sql, userId, companyId).Exec(); err != nil {
return
}
return
}
... ...
... ... @@ -19,6 +19,7 @@ type RequestHeader struct {
AppProject string
AccessToken string
Uid int64
CompanyId int64
}
/*Login */
... ...
... ... @@ -12,7 +12,7 @@ var errmessge ErrorMap = map[int]string{
2001: "请输入正确的手机号码",
2002: "后台未配置账号信息,请联系管理员配置",
2009: "上传的文件流为空",
2020: "帐号不存在,请联系管理员",
//2020: "帐号不存在,请联系管理员",
2021: "登录失败,手机号或密码错误",
2025: "短信验证码验证失败",
2026: "两次输入的密码不一致",
... ... @@ -21,3 +21,31 @@ var errmessge ErrorMap = map[int]string{
4141: "accessToken过期或无效,需要进行重新获取令牌",
4142: "Uuid已存在,请求失败",
}
/*MessageCenter */
type MessageCenterRequest struct {
MsgType int `json:"msgType" valid:"Required"`
}
type MessageCenterResponse struct {
Totals []*MessageTotal `json:"totals"`
}
type MessageTotal struct {
MsgType int `json:"msgType" orm:"column(msg_type)"`
MsgTotal int `json:"msgTotal" orm:"column(total)"`
}
/*MsgCenterRead */
type MsgCenterReadRequest struct {
MsgId int64 `json:"msgId" valid:"Required"`
MsgType int `json:"msgType" valid:"Required"`
}
type MsgCenterReadResponse struct {
}
/*MsgCenterAllRead */
type MsgCenterAllReadRequest struct {
MsgType int `json:"msgType" valid:"Required"`
}
type MsgCenterAllReadResponse struct {
}
... ...
... ... @@ -9,7 +9,7 @@ type CheckSmsCodeResponse struct {
/*修改手机号*/
type ChangePhoneRequest struct {
Phone string `json:"phone" valid:"Required"`
Phone string `json:"phone" valid:"Mobile"`
Captcha string `json:"captcha" valid:"Required"`
}
type ChangePhoneResponse struct {
... ...
... ... @@ -79,6 +79,30 @@ func init() {
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["opp/controllers/v1:MessageController"] = append(beego.GlobalControllerRouter["opp/controllers/v1:MessageController"],
beego.ControllerComments{
Method: "MessageCenter",
Router: `/messageCenter`,
AllowHTTPMethods: []string{"post"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["opp/controllers/v1:MessageController"] = append(beego.GlobalControllerRouter["opp/controllers/v1:MessageController"],
beego.ControllerComments{
Method: "MsgCenterAllRead",
Router: `/msgCenterAllRead`,
AllowHTTPMethods: []string{"post"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["opp/controllers/v1:MessageController"] = append(beego.GlobalControllerRouter["opp/controllers/v1:MessageController"],
beego.ControllerComments{
Method: "MsgCenterRead",
Router: `/msgCenterRead`,
AllowHTTPMethods: []string{"post"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["opp/controllers/v1:UploadController"] = append(beego.GlobalControllerRouter["opp/controllers/v1:UploadController"],
beego.ControllerComments{
Method: "Image",
... ...
... ... @@ -18,6 +18,7 @@ func init() {
beego.NSNamespace("commend", beego.NSInclude(&v1.CommendController{})),
beego.NSNamespace("user", beego.NSInclude(&v1.UserController{})),
beego.NSNamespace("chance", beego.NSInclude(&v1.ChanceController{})),
beego.NSNamespace("message", beego.NSInclude(&v1.MessageController{})),
)
beego.AddNamespace(nsV1)
beego.SetStaticPath("/file/ab", beego.AppConfig.String("source_path"))
... ...
... ... @@ -60,7 +60,7 @@ func (s *AuthService) Login(request *protocol.LoginRequest) (rsp *protocol.Login
user, err = repository.User.GetUsersByMobile(request.Phone)
if err != nil {
log.Error(err)
err = protocol.NewErrWithMessage(2020, err) //账号不存在
err = protocol.NewErrWithMessage(2002, err) //账号不存在
return
}
switch request.GrantType {
... ... @@ -149,8 +149,8 @@ func (s *AuthService) AccessToken(request *protocol.AccessTokenRequest) (rsp *pr
}
userAuth.AccessToken = uid.NewV1().StringNoDash()
userAuth.RefreshToken = uid.NewV1().StringNoDash()
userAuth.AccessTokenExp = time.Now().Add(protocol.TokenExpire*time.Second)
userAuth.RefreshTokenExp = time.Now().Add(protocol.TokenExpire*time.Second)
userAuth.AccessTokenExp = time.Now().Add(protocol.TokenExpire * time.Second)
userAuth.RefreshTokenExp = time.Now().Add(protocol.TokenExpire * time.Second)
if err = repository.UserAuth.UpdateUserAuthById(userAuth); err != nil {
log.Error(err)
return
... ...
package message
import (
"gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/log"
"opp/internal/repository"
"opp/protocol"
)
func MessageCenter(header *protocol.RequestHeader, request *protocol.MessageCenterRequest) (rsp *protocol.MessageCenterResponse, err error) {
var ()
rsp = &protocol.MessageCenterResponse{}
err = repository.Message.GetUserMsgTotals(header.Uid, header.CompanyId, request.MsgType, &rsp.Totals)
return
}
//标记已读
func MsgCenterRead(header *protocol.RequestHeader, request *protocol.MsgCenterReadRequest) (rsp *protocol.MsgCenterReadResponse, err error) {
var ()
//rsp =&protocol.MsgCenterReadResponse{}
err = repository.Message.UpdateUserMsgSetRead(header.Uid, header.CompanyId, request.MsgType, request.MsgId)
if err != nil {
log.Error(err)
}
return
}
//标记全部已读
func MsgCenterAllRead(header *protocol.RequestHeader, request *protocol.MsgCenterAllReadRequest) (rsp *protocol.MsgCenterAllReadResponse, err error) {
var ()
err = repository.Message.UpdateUserMsgSetRead(header.Uid, header.CompanyId, request.MsgType, 0)
if err != nil {
log.Error(err)
}
return
}
... ...