diff --git a/api/errcode/errcode.go b/api/errcode/errcode.go index 49549479..07e27047 100644 --- a/api/errcode/errcode.go +++ b/api/errcode/errcode.go @@ -205,6 +205,9 @@ var ErrCodeMsgMap = map[ErrCode]string{ ErrCodeZoneMomentCreateTimesSrvFail: "空间动态创建频次表服务错误", ErrCodeZoneMomentCreateTimesNotExist: "空间动态创建频次表不存在", ErrCodeZoneMomentCreateTimesReachedDailyUpperbound: "每天仅可发布十条空间动态", + + ErrCodeDailyStatementZoneInfoSrvFail: "空间相关每日报表服务错误", + ErrCodeDailyStatementZoneInfoNotExist: "空间相关每日报表不存在", } const ( @@ -491,6 +494,11 @@ const ( ErrCodeZoneMomentCreateTimesNotExist ErrCode = -39002 // 动态创建频次表不存在 ErrCodeZoneMomentCreateTimesReachedDailyUpperbound ErrCode = -39003 // 动态创建次数已达每日上限 + // DailyStatementZoneInfo: 40xxx + ErrCodeDailyStatementZoneInfoSrvOk ErrCode = ErrCodeOk + ErrCodeDailyStatementZoneInfoSrvFail ErrCode = -40001 // 空间相关每日报表服务错误 + ErrCodeDailyStatementZoneInfoNotExist ErrCode = -40002 // 空间相关每日报表不存在 + // Media: 60xxx ErrCodeMediaSrvOk ErrCode = ErrCodeOk ErrCodeMediaSrvFail ErrCode = -60001 // 媒体服务错误 diff --git a/api/proto/daily_statement_zone_info/proto/daily_statement_zone_info_op.go b/api/proto/daily_statement_zone_info/proto/daily_statement_zone_info_op.go new file mode 100644 index 00000000..287111ad --- /dev/null +++ b/api/proto/daily_statement_zone_info/proto/daily_statement_zone_info_op.go @@ -0,0 +1,82 @@ +package proto + +import ( + "service/api/base" + "service/dbstruct" +) + +// op 创建 +type OpCreateReq struct { + base.BaseRequest + *dbstruct.DailyStatementZoneInfo +} + +type OpCreateData struct { +} + +type OpCreateResp struct { + base.BaseResponse + Data *OpCreateData `json:"data"` +} + +// op 删除 +type OpDeleteReq struct { + base.BaseRequest + Id int64 `json:"id"` +} + +type OpDeleteData struct { +} + +type OpDeleteResp struct { + base.BaseResponse + Data *OpDeleteData `json:"data"` +} + +// op 更新 +type OpUpdateReq struct { + base.BaseRequest + *dbstruct.DailyStatementZoneInfo +} + +type OpUpdateData struct { +} + +type OpUpdateResp struct { + base.BaseResponse + Data *OpUpdateData `json:"data"` +} + +// op 列表 +type OpListReq struct { + base.BaseRequest + CtUpperBound *int64 `json:"ct_upper_bound"` + CtLowerBound *int64 `json:"ct_lower_bound"` + Offset int `json:"offset"` + Limit int `json:"limit"` +} + +type OpListData struct { + List []*dbstruct.DailyStatementZoneInfo `json:"list"` + Offset int `json:"offset"` + More int `json:"more"` +} + +type OpListResp struct { + base.BaseResponse + Data *OpListData `json:"data"` +} + +// op 批量创建 +type OpCreateBatchReq struct { + base.BaseRequest + DailyStatementZoneInfos []*dbstruct.DailyStatementZoneInfo +} + +type OpCreateBatchData struct { +} + +type OpCreateBatchResp struct { + base.BaseResponse + Data *OpCreateData `json:"data"` +} diff --git a/api/proto/zone/proto/zone_vo_op.go b/api/proto/zone/proto/zone_vo_op.go index cb29e849..97f2c6c6 100644 --- a/api/proto/zone/proto/zone_vo_op.go +++ b/api/proto/zone/proto/zone_vo_op.go @@ -19,6 +19,9 @@ type OpZoneVO struct { StreamerExt *streamerproto.OpListExtVO `json:"streamer_ext"` // 主播信息 ZoneThirdPartner *zone_third_partner_proto.ZoneThirdPartnerApiVO `json:"zone_third_partner"` // 代运营 ZoneCollaboratorList []*zone_collaborator_proto.ZoneCollaboratorApiVO `json:"zone_collaborator_list"` // 协作者 + EntrantNum int64 `json:"entrant_num"` // 空间总人数 + IronfanNum int64 `json:"ironfan_num"` // 铁粉总人数 + SuperfanNum int64 `json:"superfan_num"` // 超粉总人数 } func (vo *OpZoneVO) GetMid() int64 { diff --git a/api/proto/zonemoment/proto/not_null_def_api.go b/api/proto/zonemoment/proto/not_null_def_api.go index 88385610..cccb6e46 100644 --- a/api/proto/zonemoment/proto/not_null_def_api.go +++ b/api/proto/zonemoment/proto/not_null_def_api.go @@ -19,6 +19,10 @@ func (p *ApiCreateReq) ProvideNotNullValue() (params []*validator.JsonParam) { case consts.ZoneMomentCType_Paid: params = append(params, validator.NewInt64PtrParam("请确认创建动态的文字可见范围!", p.ZoneMoment.TextVisibleRange)) params = append(params, validator.NewInt64PtrParam("请确认创建动态的价格!", p.ZoneMoment.Price)) + params = append(params, validator.NewInt64PtrParam("请确认是否添加付费文案!", p.ZoneMoment.IsCreatingPaidText)) + if p.ZoneMoment.GetIsCreatingPaidText() == 1 { + params = append(params, validator.NewStringPtrParam("请确认创建动态的付费文案!", p.PaidText)) + } switch util.DerefInt64(p.ZoneMoment.MType) { case consts.MediaTypeImg: params = append(params, validator.NewInt64PtrParam("请确认创建动态的媒体可见范围!", p.ZoneMoment.MediaVisibleRange)) diff --git a/api/proto/zonemoment/proto/not_null_def_op.go b/api/proto/zonemoment/proto/not_null_def_op.go index 5f9d6039..3dbb2a32 100644 --- a/api/proto/zonemoment/proto/not_null_def_op.go +++ b/api/proto/zonemoment/proto/not_null_def_op.go @@ -19,6 +19,10 @@ func (p *OpCreateReq) ProvideNotNullValue() (params []*validator.JsonParam) { case consts.ZoneMomentCType_Paid: params = append(params, validator.NewInt64PtrParam("请确认创建动态的文字可见范围!", p.ZoneMoment.TextVisibleRange)) params = append(params, validator.NewInt64PtrParam("请确认创建动态的价格!", p.ZoneMoment.Price)) + params = append(params, validator.NewInt64PtrParam("请确认是否添加付费文案!", p.ZoneMoment.IsCreatingPaidText)) + if p.ZoneMoment.GetIsCreatingPaidText() == 1 { + params = append(params, validator.NewStringPtrParam("请确认创建动态的付费文案!", p.PaidText)) + } switch util.DerefInt64(p.ZoneMoment.MType) { case consts.MediaTypeImg: params = append(params, validator.NewInt64PtrParam("请确认创建动态的媒体可见范围!", p.ZoneMoment.MediaVisibleRange)) diff --git a/app/mix/controller/daily_statement_zone_info_op.go b/app/mix/controller/daily_statement_zone_info_op.go new file mode 100644 index 00000000..54d21397 --- /dev/null +++ b/app/mix/controller/daily_statement_zone_info_op.go @@ -0,0 +1,37 @@ +package controller + +import ( + "service/api/consts" + "service/api/errcode" + daily_statement_zone_info_proto "service/api/proto/daily_statement_zone_info/proto" + "service/app/mix/service" + "service/bizcommon/util" + "service/library/logger" + + "github.com/gin-gonic/gin" +) + +func OpGetDailyStatementZoneInfoList(ctx *gin.Context) { + req := ctx.MustGet("client_req").(*daily_statement_zone_info_proto.OpListReq) + + //设置默认页长 + if req.Limit == 0 { + req.Limit = consts.DefaultPageSize + } + + list, ec := service.DefaultService.OpGetDailyStatementZoneInfoList(ctx, req) + if ec != errcode.ErrCodeDailyStatementZoneInfoSrvOk { + logger.Error("OpGetDailyStatementZoneInfoList fail, req: %v, ec: %v", util.ToJson(req), ec) + ReplyErrCodeMsg(ctx, ec) + return + } + + data := &daily_statement_zone_info_proto.OpListData{ + List: list, + Offset: req.Offset + len(list), + } + if len(list) >= req.Limit { + data.More = 1 + } + ReplyOk(ctx, data) +} diff --git a/app/mix/controller/init.go b/app/mix/controller/init.go index bcedc5b8..97009ab0 100644 --- a/app/mix/controller/init.go +++ b/app/mix/controller/init.go @@ -29,6 +29,7 @@ import ( contact_customer_serviceproto "service/api/proto/contact_customer_service/proto" contact_customer_service_sessionproto "service/api/proto/contact_customer_service_session/proto" daily_statementproto "service/api/proto/daily_statement/proto" + daily_statement_zone_info_proto "service/api/proto/daily_statement_zone_info/proto" feedbackproto "service/api/proto/feedback/proto" footprintproto "service/api/proto/footprint/proto" loginproto "service/api/proto/login/proto" @@ -519,6 +520,10 @@ func Init(r *gin.Engine) { opZoneThirdPartnerGroup.POST("set_is_hided", middleware.JSONParamValidator(zone_third_partner_proto.OpSetIsHidedReq{}), middleware.JwtAuthenticator(), OpSetIsHidedZoneThirdPartner) opZoneThirdPartnerGroup.POST("list", middleware.JSONParamValidator(zone_third_partner_proto.ApiListReq{}), middleware.JwtAuthenticator(), OpGetZoneThirdPartnerList) + // 空间相关每日报表 + opDailyStatementZoneInfoGroup := r.Group("/op/daily_statement_zone_info", PrepareOp()) + opDailyStatementZoneInfoGroup.POST("list", middleware.JSONParamValidator(daily_statement_zone_info_proto.OpListReq{}), middleware.JwtAuthenticator(), OpGetDailyStatementZoneInfoList) + // 视频审核callback extVideoModerationGroup := r.Group("/ext/video_moderation") extVideoModerationGroup.POST("callback", middleware.FORMParamValidator(video_moderation_proto.ExtVideoModerationReq{}), VideoModerationCallback) diff --git a/app/mix/dao/mongo.go b/app/mix/dao/mongo.go index c17076bf..eb64c4a2 100644 --- a/app/mix/dao/mongo.go +++ b/app/mix/dao/mongo.go @@ -24,6 +24,7 @@ import ( contact_customer_service_proto "service/api/proto/contact_customer_service/proto" contact_customer_service_sessionproto "service/api/proto/contact_customer_service_session/proto" daily_statementproto "service/api/proto/daily_statement/proto" + daily_statement_zone_info_proto "service/api/proto/daily_statement_zone_info/proto" feedbackproto "service/api/proto/feedback/proto" footprintproto "service/api/proto/footprint/proto" imageaudittaskproto "service/api/proto/imageaudittask/proto" @@ -162,8 +163,9 @@ const ( DBContactCustomerServiceSession = "contact_customer_service_session" COLContactCustomerServiceSession = "contact_customer_service_session" - DBDailyStatement = "daily_statement" - COLDailyStatement = "daily_statement" + DBDailyStatement = "daily_statement" + COLDailyStatement = "daily_statement" + COLDailyStatementZoneInfo = "daily_statement_zone_info" DBAppConfig = "app_config" COLAppConfig = "app_config" @@ -524,6 +526,11 @@ func (m *Mongo) getColVideoModerationTask() *qmgo.Collection { return m.clientMix.Database(DBVideoModeration).Collection(COLVideoModerationTask) } +// 空间相关每日报表表 +func (m *Mongo) getColDailyStatementZoneInfo() *qmgo.Collection { + return m.clientMix.Database(DBDailyStatement).Collection(COLDailyStatementZoneInfo) +} + // 商品相关 func (m *Mongo) CreateProduct(ctx *gin.Context, product *dbstruct.Product) error { col := m.getColProduct() @@ -5018,3 +5025,73 @@ func (m *Mongo) UpdateOverdueVideoModerationTasksStatus(ctx *gin.Context, videoM result, err := col.UpdateAll(ctx, filter, up) return result, err } + +// 空间相关每日报表相关 +func (m *Mongo) CreateDailyStatementZoneInfo(ctx *gin.Context, dlyStmtZoneInfo *dbstruct.DailyStatementZoneInfo) error { + col := m.getColDailyStatementZoneInfo() + _, err := col.InsertOne(ctx, dlyStmtZoneInfo) + return err +} + +func (m *Mongo) UpdateDailyStatementZoneInfo(ctx *gin.Context, dlyStmtZoneInfo *dbstruct.DailyStatementZoneInfo) error { + col := m.getColDailyStatementZoneInfo() + set := util.EntityToM(dlyStmtZoneInfo) + set["ut"] = time.Now().Unix() + up := qmgo.M{ + "$set": set, + } + err := col.UpdateId(ctx, dlyStmtZoneInfo.Id, up) + return err +} + +func (m *Mongo) DeleteDailyStatementZoneInfo(ctx *gin.Context, id int64) error { + col := m.getColDailyStatementZoneInfo() + update := qmgo.M{ + "$set": qmgo.M{ + "del_flag": 1, + }, + } + err := col.UpdateId(ctx, id, update) + return err +} + +func (m *Mongo) GetDailyStatementZoneInfoList(ctx *gin.Context, req *daily_statement_zone_info_proto.OpListReq) ([]*dbstruct.DailyStatementZoneInfo, error) { + list := make([]*dbstruct.DailyStatementZoneInfo, 0) + col := m.getColDailyStatementZoneInfo() + query := qmgo.M{ + "del_flag": 0, + } + + filterInClause := []qmgo.M{} + if req.CtLowerBound != nil { + filterInClause = append(filterInClause, qmgo.M{ + "start_time": qmgo.M{ + "$gte": util.DerefInt64(req.CtLowerBound), + }, + }) + } + if req.CtUpperBound != nil { + filterInClause = append(filterInClause, qmgo.M{ + "end_time": qmgo.M{ + "$lte": util.DerefInt64(req.CtUpperBound), + }, + }) + } + + if len(filterInClause) > 0 { + query["$and"] = filterInClause + } + + err := col.Find(ctx, query).Sort("-ct").Skip(int64(req.Offset)).Limit(int64(req.Limit)).All(&list) + if err == qmgo.ErrNoSuchDocuments { + err = nil + return list, err + } + return list, err +} + +func (m *Mongo) CreateBatchDailyStatementZoneInfo(ctx *gin.Context, dlyStmtZoneInfos []*dbstruct.DailyStatementZoneInfo) error { + col := m.getColDailyStatementZoneInfo() + _, err := col.InsertMany(ctx, dlyStmtZoneInfos) + return err +} diff --git a/app/mix/dao/mysql_zone.go b/app/mix/dao/mysql_zone.go index de24837d..aa2714a3 100644 --- a/app/mix/dao/mysql_zone.go +++ b/app/mix/dao/mysql_zone.go @@ -6,6 +6,7 @@ import ( "service/bizcommon/util" "service/dbstruct" "service/library/logger" + "strings" "time" "github.com/gin-gonic/gin" @@ -523,3 +524,39 @@ func (m *Mysql) GetZoneMomentUnlockList(ctx *gin.Context, tx *sqlx.Tx, momentId } return } + +// 获取时段内空间进入人数、总入账金额、各业务分入账金额 +func (m *Mysql) GetLastHourZoneProfit(ctx *gin.Context, tx *sqlx.Tx, st, et int64) (list []*dbstruct.ZoneProfit, err error) { + var sql strings.Builder + sql.WriteString(fmt.Sprintf("select uid as mid, oid1 as zid, product_id, count(1) as num, sum(pay_amount) as amount from %s", TableOrder)) + sql.WriteString(fmt.Sprintf(" where ct >=%d and ct<=%d and product_id in(%s,%s,%s,%s) and order_status = 1 group by product_id, uid, oid1", st, et, + dbstruct.ProductIdH5ZoneMoment, dbstruct.ProductIdH5ZoneAdmission, dbstruct.ProductIdH5ZoneIronfanship, dbstruct.ProductIdH5ZoneSuperfanship)) + list = make([]*dbstruct.ZoneProfit, 0) + if tx != nil { + err = tx.SelectContext(ctx, &list, sql.String()) + } else { + db := m.getDBVas() + err = db.SelectContext(ctx, &list, sql.String()) + } + if err != nil { + return + } + return +} + +func (m *Mysql) GetLastHourZoneRefund(ctx *gin.Context, tx *sqlx.Tx, st, et int64) (list []*dbstruct.ZoneProfit, err error) { + var sql strings.Builder + sql.WriteString(fmt.Sprintf("t1.uid as mid, t1.oid1 as zid, count(1) as num, sum(t1.pay_amount) as amount from %s t1 join %s t2 on t1.id = t2.order_id", TableOrder, TableVasZoneRefundHis)) + sql.WriteString(fmt.Sprintf(" where t2.ct >=%d and t2.ct<=%d and t1.ct <%d group by t1.uid, t1.oid1", st, et, st)) + list = make([]*dbstruct.ZoneProfit, 0) + if tx != nil { + err = tx.SelectContext(ctx, &list, sql.String()) + } else { + db := m.getDBVas() + err = db.SelectContext(ctx, &list, sql.String()) + } + if err != nil { + return + } + return +} diff --git a/app/mix/service/logic/daily_statement_zone_info.go b/app/mix/service/logic/daily_statement_zone_info.go new file mode 100644 index 00000000..9f2426a6 --- /dev/null +++ b/app/mix/service/logic/daily_statement_zone_info.go @@ -0,0 +1,87 @@ +package logic + +import ( + "service/api/consts" + daily_statement_zone_infoproto "service/api/proto/daily_statement_zone_info/proto" + "service/app/mix/dao" + "service/dbstruct" + "service/library/idgenerator" + "service/library/logger" + "time" + + "github.com/gin-gonic/gin" + goproto "google.golang.org/protobuf/proto" +) + +type DailyStatementZoneInfo struct { + store *dao.Store +} + +func NewDailyStatementZoneInfo(store *dao.Store) (a *DailyStatementZoneInfo) { + a = &DailyStatementZoneInfo{ + store: store, + } + return +} + +func (p *DailyStatementZoneInfo) OpCreate(ctx *gin.Context, req *daily_statement_zone_infoproto.OpCreateReq) error { + req.DailyStatementZoneInfo.Id = goproto.Int64(idgenerator.GenDailyStatementZoneInfoId()) + req.DailyStatementZoneInfo.Ct = goproto.Int64(time.Now().Unix()) + req.DailyStatementZoneInfo.Ut = goproto.Int64(time.Now().Unix()) + req.DailyStatementZoneInfo.DelFlag = goproto.Int64(consts.Exist) + err := p.store.CreateDailyStatementZoneInfo(ctx, req.DailyStatementZoneInfo) + if err != nil { + logger.Error("CreateDailyStatementZoneInfo fail, err: %v", err) + return err + } + return nil +} + +func (p *DailyStatementZoneInfo) OpUpdate(ctx *gin.Context, req *daily_statement_zone_infoproto.OpUpdateReq) error { + err := p.store.UpdateDailyStatementZoneInfo(ctx, req.DailyStatementZoneInfo) + if err != nil { + logger.Error("UpdateDailyStatementZoneInfo fail, err: %v", err) + return err + } + return nil +} + +func (p *DailyStatementZoneInfo) OpDelete(ctx *gin.Context, id int64) error { + err := p.store.DeleteDailyStatementZoneInfo(ctx, id) + if err != nil { + logger.Error("DeleteDailyStatementZoneInfo fail, err: %v", err) + return err + } + return nil +} + +func (p *DailyStatementZoneInfo) OpList(ctx *gin.Context, req *daily_statement_zone_infoproto.OpListReq) ([]*dbstruct.DailyStatementZoneInfo, error) { + list, err := p.store.GetDailyStatementZoneInfoList(ctx, req) + if err != nil { + logger.Error("GetDailyStatementZoneInfoList fail, err: %v", err) + return make([]*dbstruct.DailyStatementZoneInfo, 0), err + } + return list, nil +} + +func (p *DailyStatementZoneInfo) OpCreateBatch(ctx *gin.Context, req *daily_statement_zone_infoproto.OpCreateBatchReq) error { + lastDailyStatementZoneInfoId := idgenerator.GenDailyStatementZoneInfoId() + for _, dailyStatementZoneInfo := range req.DailyStatementZoneInfos { + //GenDailyStatementZoneInfoId()有可能发生碰撞,先记录上一次的id,如果发生碰撞,则新ID=旧ID+1,并刷新旧ID + curDailyStatementZoneInfoId := idgenerator.GenDailyStatementZoneInfoId() + if lastDailyStatementZoneInfoId >= curDailyStatementZoneInfoId { + curDailyStatementZoneInfoId = lastDailyStatementZoneInfoId + 1 + } + lastDailyStatementZoneInfoId = curDailyStatementZoneInfoId + dailyStatementZoneInfo.Id = goproto.Int64(curDailyStatementZoneInfoId) + dailyStatementZoneInfo.Ct = goproto.Int64(time.Now().Unix()) + dailyStatementZoneInfo.Ut = goproto.Int64(time.Now().Unix()) + dailyStatementZoneInfo.DelFlag = goproto.Int64(consts.Exist) + } + err := p.store.CreateBatchDailyStatementZoneInfo(ctx, req.DailyStatementZoneInfos) + if err != nil { + logger.Error("CreateDailyStatementZoneInfo fail, err: %v", err) + return err + } + return nil +} diff --git a/app/mix/service/logic/vas_zone.go b/app/mix/service/logic/vas_zone.go index 2c2d7db9..1cc584c5 100644 --- a/app/mix/service/logic/vas_zone.go +++ b/app/mix/service/logic/vas_zone.go @@ -3,9 +3,6 @@ package logic import ( "database/sql" "fmt" - "github.com/gin-gonic/gin" - "github.com/jmoiron/sqlx" - goproto "google.golang.org/protobuf/proto" "service/api/base" "service/api/errs" vasproto "service/api/proto/vas/proto" @@ -16,6 +13,10 @@ import ( "service/library/logger" "service/library/redis" "time" + + "github.com/gin-gonic/gin" + "github.com/jmoiron/sqlx" + goproto "google.golang.org/protobuf/proto" ) // 检查mid对空间的解锁是否存在 @@ -1206,3 +1207,20 @@ func (v *Vas) ZoneExit(ctx *gin.Context, mid, zid int64) error { func (v *Vas) GetZoneMomentUnlockList(ctx *gin.Context, momentId int64, offset, limit int) (list []*dbstruct.ZoneMomentUnlock, err error) { return v.store.GetZoneMomentUnlockList(ctx, nil, momentId, offset, limit) } + +// 统计时段内空间报表信息 +func (v *Vas) GetLastHourZoneProfit(ctx *gin.Context, st, et int64) ([]*dbstruct.ZoneProfit, []*dbstruct.ZoneProfit, error) { + zoneprofits, err := v.store.GetLastHourZoneProfit(ctx, nil, st, et) + if err != nil { + logger.Error("GetLastHourZoneProfit fail err: %v", err) + return make([]*dbstruct.ZoneProfit, 0), make([]*dbstruct.ZoneProfit, 0), err + } + + zonerefunds, err := v.store.GetLastHourZoneRefund(ctx, nil, st, et) + if err != nil { + logger.Error("GetLastHourZoneRefund fail err: %v", err) + return make([]*dbstruct.ZoneProfit, 0), make([]*dbstruct.ZoneProfit, 0), err + } + + return zoneprofits, zonerefunds, nil +} diff --git a/app/mix/service/service.go b/app/mix/service/service.go index 94508350..36bac0c9 100644 --- a/app/mix/service/service.go +++ b/app/mix/service/service.go @@ -18,6 +18,7 @@ import ( contact_customer_service_proto "service/api/proto/contact_customer_service/proto" contact_customer_service_sessionproto "service/api/proto/contact_customer_service_session/proto" daily_statementproto "service/api/proto/daily_statement/proto" + daily_statement_zone_info_proto "service/api/proto/daily_statement_zone_info/proto" feedbackproto "service/api/proto/feedback/proto" footprintproto "service/api/proto/footprint/proto" imageaudittaskproto "service/api/proto/imageaudittask/proto" @@ -125,6 +126,7 @@ var ( _DefaultVideoModeration *logic.VideoModeration _DefaultVideoModerationTask *logic.VideoModerationTask _DefaultStreamerAcct *logic.StreamerAcct + _DefaultDailyStatementZoneInfo *logic.DailyStatementZoneInfo ) type Service struct { @@ -213,6 +215,7 @@ func (s *Service) Init(c any) (err error) { _DefaultZoneMomentCreateTimes = logic.NewZoneMomentCreateTimes(store) _DefaultVideoModeration = logic.NewVideoModeration(store) _DefaultVideoModerationTask = logic.NewVideoModerationTask(store) + _DefaultDailyStatementZoneInfo = logic.NewDailyStatementZoneInfo(store) _DefaultVas = logic.NewVas(store, _DefaultStreamer, _DefaultAccount, _DefaultZone, _DefaultZoneThirdPartner, _DefaultZoneCollaborator) _DefaultStreamerAcct = logic.NewStreamerAcct(store) @@ -3920,3 +3923,15 @@ func (s *Service) OpZoneUnlockCollaborators(ctx *gin.Context, req *zoneproto.OpZ } return nil } + +// DailyStatementZoneInfo +func (s *Service) OpGetDailyStatementZoneInfoList(ctx *gin.Context, req *daily_statement_zone_info_proto.OpListReq) (list []*dbstruct.DailyStatementZoneInfo, ec errcode.ErrCode) { + ec = errcode.ErrCodeDailyStatementZoneInfoSrvOk + list, err := _DefaultDailyStatementZoneInfo.OpList(ctx, req) + if err != nil { + logger.Error("OpGetDailyStatementZoneInfoList fail, req: %v, err: %v", util.ToJson(req), err) + ec = errcode.ErrCodeDailyStatementZoneInfoSrvFail + return + } + return +} diff --git a/app/mix/service/utilservice.go b/app/mix/service/utilservice.go index 36dd6d3b..ba56252c 100644 --- a/app/mix/service/utilservice.go +++ b/app/mix/service/utilservice.go @@ -1961,3 +1961,47 @@ func (s *Service) utilFillZoneMomentsWithOpVOInfo(ctx *gin.Context, list []*dbst return } + +func (s *Service) utilAssembleDailyStatementZoneInfo(zoneprofits, zonerefunds []*dbstruct.ZoneProfit, st, et int64) (list []*dbstruct.DailyStatementZoneInfo) { + + list = make([]*dbstruct.DailyStatementZoneInfo, 0) + zidDlystmtMp := make(map[int64]*dbstruct.DailyStatementZoneInfo) + + // 先写入退款相关的信息 + zidZrMp := make(map[int64]*dbstruct.ZoneProfit) + for _, zonerefund := range zonerefunds { + zidZrMp[zonerefund.GetZid()] = zonerefund + dlystmt := &dbstruct.DailyStatementZoneInfo{ + Zid: zonerefund.Zid, + RefundAmount: zonerefund.Amount, + RefunderAmount: zonerefund.Num, + } + zidDlystmtMp[zonerefund.GetZid()] = dlystmt + list = append(list, dlystmt) + } + + // 再写入收入相关的信息 + for _, zoneprofit := range zoneprofits { + dlystmt, ok := zidDlystmtMp[zoneprofit.GetZid()] + if !ok { + //没有相关信息,写入一个 + dlystmt = &dbstruct.DailyStatementZoneInfo{ + Zid: zoneprofit.Zid, + } + zidDlystmtMp[zoneprofit.GetZid()] = dlystmt + list = append(list, dlystmt) + } + switch zoneprofit.GetProductId() { + case dbstruct.ProductIdH5ZoneMoment: + dlystmt.ZoneMomentAmount = zoneprofit.Amount + case dbstruct.ProductIdH5ZoneAdmission: + dlystmt.AdmissionAmount = zoneprofit.Amount + dlystmt.EntrantNum = goproto.Int64(dlystmt.GetEntrantNum() + zoneprofit.GetNum()) + case dbstruct.ProductIdH5ZoneSuperfanship: + dlystmt.SuperfanshipAmount = zoneprofit.Amount + } + dlystmt.TotalAmount = goproto.Int64(dlystmt.GetTotalAmount() + zoneprofit.GetAmount()) + } + + return +} diff --git a/app/mix/service/xxljob_tasks.go b/app/mix/service/xxljob_tasks.go index 904c7e50..6f939e70 100644 --- a/app/mix/service/xxljob_tasks.go +++ b/app/mix/service/xxljob_tasks.go @@ -8,6 +8,7 @@ import ( account_cancellationproto "service/api/proto/account_cancellation/proto" contact_customer_service_proto "service/api/proto/contact_customer_service/proto" daily_statementproto "service/api/proto/daily_statement/proto" + daily_statement_zone_infoproto "service/api/proto/daily_statement_zone_info/proto" momentproto "service/api/proto/moment/proto" streamerproto "service/api/proto/streamer/proto" vasproto "service/api/proto/vas/proto" @@ -92,14 +93,14 @@ func (s *CronService) CreateDailyStatement(ctx context.Context, param *xxl.RunRe count, err := DefaultScriptsService.QueryCallCount(consts.H5CallUrl, logpath) if err != nil { logger.Error("query h5 call count fail : %v", err) - return fmt.Sprintf("query h5 call count fail : %v", err) + //return fmt.Sprintf("query h5 call count fail : %v", err) } //获取站外user_id访问zone访问量 zoneListFromOusideCount, err := DefaultScriptsService.QueryCallCount(consts.ZoneListFromOutsideCountCallUrl, logpath) if err != nil { logger.Error("query list_by_user_id_from_outside call count fail : %v", err) - return fmt.Sprintf("query list_by_user_id_from_outside call count fail : %v", err) + //return fmt.Sprintf("query list_by_user_id_from_outside call count fail : %v", err) } //获取用户总量 @@ -108,7 +109,7 @@ func (s *CronService) CreateDailyStatement(ctx context.Context, param *xxl.RunRe }) if err != nil { logger.Error("_DefaultAccount OpCount fail : %v", err) - return fmt.Sprintf("_DefaultAccount OpCount fail : %v", err) + //return fmt.Sprintf("_DefaultAccount OpCount fail : %v", err) } //获取订单总量 @@ -118,7 +119,7 @@ func (s *CronService) CreateDailyStatement(ctx context.Context, param *xxl.RunRe }) if err != nil { logger.Error("_DefaultVas GetOrderCountByStatus fail : %v", err) - return fmt.Sprintf("_DefaultVas GetOrderCountByStatus fail : %v", err) + //return fmt.Sprintf("_DefaultVas GetOrderCountByStatus fail : %v", err) } //获取用户注册来源 @@ -128,9 +129,10 @@ func (s *CronService) CreateDailyStatement(ctx context.Context, param *xxl.RunRe }) if err != nil { logger.Error("_DefaultAccount OpCountLastHourNewUserSource fail : %v", err) - return fmt.Sprintf("_DefaultAccount OpCountLastHourNewUserSource fail : %v", err) + //return fmt.Sprintf("_DefaultAccount OpCountLastHourNewUserSource fail : %v", err) } + //获取订单完成量 finishedOrderCount := int32(0) allOrderCount := int32(0) for _, orderCount := range orderCounts { @@ -160,6 +162,21 @@ func (s *CronService) CreateDailyStatement(ctx context.Context, param *xxl.RunRe return fmt.Sprintf("_DefaultDailyStatement OpCreate fail : %v", err) } + //获取空间相关信息 + zoneprofits, zonerefunds, err := _DefaultVas.GetLastHourZoneProfit(&gin.Context{}, startTimeStamp, endTimeStamp) + if err != nil { + logger.Error("_DefaultVas GetLastHourZoneProfit fail : %v", err) + return fmt.Sprintf("_DefaultDailyStatementZoneInfo OpCreateBatch fail : %v", err) + } + dailyStatementZoneInfos := DefaultService.utilAssembleDailyStatementZoneInfo(zoneprofits, zonerefunds, startTimeStamp, endTimeStamp) + err = _DefaultDailyStatementZoneInfo.OpCreateBatch(&gin.Context{}, &daily_statement_zone_infoproto.OpCreateBatchReq{ + DailyStatementZoneInfos: dailyStatementZoneInfos, + }) + if err != nil { + logger.Error("_DefaultDailyStatementZoneInfo OpCreateBatch fail : %v", err) + return fmt.Sprintf("_DefaultDailyStatementZoneInfo OpCreateBatch fail : %v", err) + } + logger.Info("%v - %v statement data has created...", starttime, endtime) return fmt.Sprintf("%v - %v statement data has created...", starttime, endtime) } diff --git a/codecreate/codecreate.go b/codecreate/codecreate.go index 0b0dd5eb..3b7a2bd5 100644 --- a/codecreate/codecreate.go +++ b/codecreate/codecreate.go @@ -9,10 +9,10 @@ import ( func main() { genSource := &generator.GenSource{ - EntityName: "ZoneCollaborator", - ModuleName: "zone_collaborator", - EntityCNName: "空间协作者表", - ErrCodeSeq: "38", + EntityName: "DailyStatementZoneInfo", + ModuleName: "daily_statement_zone_info", + EntityCNName: "空间相关每日报表", + ErrCodeSeq: "40", } generator.CreateFileDirectory(genSource) diff --git a/codecreate/resource/EntityDefine.xlsx b/codecreate/resource/EntityDefine.xlsx index e79d6702..de6f31c5 100644 Binary files a/codecreate/resource/EntityDefine.xlsx and b/codecreate/resource/EntityDefine.xlsx differ diff --git a/dbstruct/daily_statement_zone_info.go b/dbstruct/daily_statement_zone_info.go new file mode 100644 index 00000000..fabae2e8 --- /dev/null +++ b/dbstruct/daily_statement_zone_info.go @@ -0,0 +1,32 @@ +package dbstruct + +type DailyStatementZoneInfo struct { + Id *int64 `json:"id" bson:"_id"` // 每日报表id + Zid *int64 `json:"zid" bson:"zid"` // 空间id + EntrantNum *int64 `json:"entrant_num" bson:"entrant_num"` // 上小时新增空间进入人数(不含退款) + TotalAmount *int64 `json:"total_amount" bson:"total_amount"` // 上小时总入账 + AdmissionAmount *int64 `json:"admission_amount" bson:"admission_amount"` // 成员入账 + ZoneMomentAmount *int64 `json:"zone_moment_amount" bson:"zone_moment_amount"` // 帖子入账 + SuperfanshipAmount *int64 `json:"superfanship_amount" bson:"superfanship_amount"` // 超粉入账 + RefundAmount *int64 `json:"refund_amount" bson:"refund_amount"` // 退款金额 + RefunderAmount *int64 `json:"refunder_amount" bson:"refunder_amount"` // 退款人数 + StartTime *int64 `json:"start_time" bson:"start_time"` // 起始时间 + EndTime *int64 `json:"end_time" bson:"end_time"` // 结束时间 + Ct *int64 `json:"ct" bson:"ct"` // 创建时间 + Ut *int64 `json:"ut" bson:"ut"` // 更新时间 + DelFlag *int64 `json:"del_flag" bson:"del_flag"` // 删除标记 +} + +func (p *DailyStatementZoneInfo) GetTotalAmount() int64 { + if p != nil && p.TotalAmount != nil { + return *p.TotalAmount + } + return 0 +} + +func (p *DailyStatementZoneInfo) GetEntrantNum() int64 { + if p != nil && p.EntrantNum != nil { + return *p.EntrantNum + } + return 0 +} diff --git a/dbstruct/vas_mysql.go b/dbstruct/vas_mysql.go index 984d8626..3396d907 100644 --- a/dbstruct/vas_mysql.go +++ b/dbstruct/vas_mysql.go @@ -1379,3 +1379,47 @@ func (p *ZoneRefundHis) GetProductId() string { } return "" } + +// 时段空间收入信息 +type ZoneProfit struct { + Mid *int64 `json:"mid" db:"mid"` // 用户id + Zid *int64 `json:"zid" db:"zid"` // 空间id + ProductId *string `json:"product_id" db:"product_id"` // 商品id + Amount *int64 `json:"amount" db:"amount"` // 支付总金额 + Num *int64 `json:"num" db:"num"` // 支付总人数 +} + +func (p *ZoneProfit) GetMid() int64 { + if p != nil && p.Mid != nil { + return *p.Mid + } + return 0 +} + +func (p *ZoneProfit) GetZid() int64 { + if p != nil && p.Zid != nil { + return *p.Zid + } + return 0 +} + +func (p *ZoneProfit) GetProductId() string { + if p != nil && p.ProductId != nil { + return *p.ProductId + } + return "" +} + +func (p *ZoneProfit) GetAmount() int64 { + if p != nil && p.Amount != nil { + return *p.Amount + } + return 0 +} + +func (p *ZoneProfit) GetNum() int64 { + if p != nil && p.Num != nil { + return *p.Num + } + return 0 +} diff --git a/dbstruct/zonemoment.go b/dbstruct/zonemoment.go index ffd1e3bd..3f498c39 100644 --- a/dbstruct/zonemoment.go +++ b/dbstruct/zonemoment.go @@ -14,6 +14,8 @@ type ZoneMoment struct { IsBlurringCover *int64 `json:"is_blurring_cover" bson:"is_blurring_cover"` // 是否模糊封面 TextAmount *int64 `json:"text_amount" bson:"text_amount"` // 动态文字总行 MediaAmount *int64 `json:"media_amount" bson:"media_amount"` // 媒体总个数 + IsCreatingPaidText *int64 `json:"is_creating_paid_text" bson:"is_creating_paid_text"` // 是否创建付费文案 + PaidText *string `json:"paid_text" bson:"paid_text"` // 付费文案 Price *int64 `json:"price" bson:"price"` // 单帖价格,单位人民币分 ProductId *int64 `json:"product_id" bson:"product_id"` // 商品id(单帖商品或超粉商品id) ThumbsUpNum *int64 `json:"thumbs_up_num" bson:"thumbs_up_num"` // 点赞次数 @@ -94,3 +96,10 @@ func (p *ZoneMoment) GetStatus() int64 { } return 0 } + +func (p *ZoneMoment) GetIsCreatingPaidText() int64 { + if p != nil && p.IsCreatingPaidText != nil { + return *p.IsCreatingPaidText + } + return 0 +} diff --git a/library/idgenerator/genid.go b/library/idgenerator/genid.go index a715dafe..c3aa4739 100644 --- a/library/idgenerator/genid.go +++ b/library/idgenerator/genid.go @@ -52,6 +52,7 @@ const ( NodeZoneMomentThumbsUp // node 私密圈动态点赞 NodeZoneSession // node 空间对话表 NodeZoneThirdPartner // node 空间代运营表 + NodeDailyStatementZoneInfo // node 空间相关每日报表 ) func GenIdInt64(node int64) (int64, error) { @@ -245,3 +246,9 @@ func GenZoneThirdPartnerId() int64 { id, _ := GenIdInt64(NodeZoneThirdPartner) return id } + +// daily_statement_zone_info +func GenDailyStatementZoneInfoId() int64 { + id, _ := GenIdInt64(NodeDailyStatementZoneInfo) + return id +}