From 7107bb0393f811f0ff8aad14f73de2e87a92728c Mon Sep 17 00:00:00 2001 From: Leufolium Date: Wed, 15 May 2024 09:58:45 +0800 Subject: [PATCH 1/4] by Robin at 20240515 --- api/errcode/errcode.go | 8 ++ .../proto/daily_statement_zone_info_op.go | 68 ++++++++++++++++ .../daily_statement_zone_info_op.go | 37 +++++++++ app/mix/controller/init.go | 5 ++ app/mix/dao/mongo.go | 75 +++++++++++++++++- app/mix/dao/mysql_zone.go | 5 ++ .../logic/daily_statement_zone_info.go | 65 +++++++++++++++ app/mix/service/service.go | 15 ++++ app/mix/service/xxljob_tasks.go | 3 + codecreate/codecreate.go | 8 +- codecreate/resource/EntityDefine.xlsx | Bin 50923 -> 52290 bytes dbstruct/daily_statement_zone_info.go | 19 +++++ library/idgenerator/genid.go | 7 ++ 13 files changed, 309 insertions(+), 6 deletions(-) create mode 100644 api/proto/daily_statement_zone_info/proto/daily_statement_zone_info_op.go create mode 100644 app/mix/controller/daily_statement_zone_info_op.go create mode 100644 app/mix/service/logic/daily_statement_zone_info.go create mode 100644 dbstruct/daily_statement_zone_info.go diff --git a/api/errcode/errcode.go b/api/errcode/errcode.go index 16fdf437..f580c581 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 ( @@ -490,6 +493,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..4f5914cb --- /dev/null +++ b/api/proto/daily_statement_zone_info/proto/daily_statement_zone_info_op.go @@ -0,0 +1,68 @@ +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"` +} 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 280caffa..18060cf9 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" @@ -513,6 +514,10 @@ func Init(r *gin.Engine) { opZoneMomentGroup.POST("head", middleware.JSONParamValidator(zonemomentproto.OpHeadReq{}), middleware.JwtAuthenticator(), OpHeadZoneMoment) opZoneMomentGroup.POST("set_private", middleware.JSONParamValidator(zonemomentproto.OpSetPrivateReq{}), middleware.JwtAuthenticator(), OpSetPrivateZoneMoment) + // 空间相关每日报表 + 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 01bb8f5f..a8d85a84 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() @@ -5071,3 +5078,67 @@ 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 +} diff --git a/app/mix/dao/mysql_zone.go b/app/mix/dao/mysql_zone.go index fc8322a1..c8ba8904 100644 --- a/app/mix/dao/mysql_zone.go +++ b/app/mix/dao/mysql_zone.go @@ -499,3 +499,8 @@ func (m *Mysql) GetZoneRefundHisList(ctx *gin.Context, tx *sqlx.Tx, mid, zid int } return } + +// 获取时段内空间进入人数、总入账金额、各业务分入账金额、退款金额、退款人数 +func (m *MySql) GetDailyStatementZoneInfoFromVasOrder(ctx *gin.Context, tx *sqlx.Tx, st, et int64, offset, limit int) { + +} 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..0d3a0e47 --- /dev/null +++ b/app/mix/service/logic/daily_statement_zone_info.go @@ -0,0 +1,65 @@ +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 +} diff --git a/app/mix/service/service.go b/app/mix/service/service.go index a2131b30..69bf61e0 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" @@ -123,6 +124,7 @@ var ( _DefaultZoneMomentCreateTimes *logic.ZoneMomentCreateTimes _DefaultVideoModeration *logic.VideoModeration _DefaultVideoModerationTask *logic.VideoModerationTask + _DefaultDailyStatementZoneInfo *logic.DailyStatementZoneInfo ) type Service struct { @@ -211,6 +213,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) return @@ -3876,3 +3879,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/xxljob_tasks.go b/app/mix/service/xxljob_tasks.go index 78b85f7d..a1b3adc8 100644 --- a/app/mix/service/xxljob_tasks.go +++ b/app/mix/service/xxljob_tasks.go @@ -131,6 +131,7 @@ func (s *CronService) CreateDailyStatement(ctx context.Context, param *xxl.RunRe return fmt.Sprintf("_DefaultAccount OpCountLastHourNewUserSource fail : %v", err) } + //获取订单完成量 finishedOrderCount := int32(0) allOrderCount := int32(0) for _, orderCount := range orderCounts { @@ -140,6 +141,8 @@ func (s *CronService) CreateDailyStatement(ctx context.Context, param *xxl.RunRe allOrderCount += util.DerefInt32(orderCount.Count) } + //获取空间相关信息 + dailyStatement := &dbstruct.DailyStatement{ H5CallCount: goproto.Int64(int64(count)), RegisteredUserCount: goproto.Int64(accountCount), 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 e79d6702f9a1afd15f76bb3eab0260d2d2f48c2f..de6f31c59ae7484f4cd42ba3e2630123adab9241 100644 GIT binary patch delta 9871 zcmZ9SbyQqIv*3rpT{5`4TYvz;-3jgl$zTHn56K`X~mzHw~UhO$iVKoZ}c;4to*^*DW zGj;i{q|SIqMFzS)A7L%ze=AzzFK?g;_{^Jd`mvN&5ax@C4ZlGZ?AxhyIp({s&Q^Fo zZ436TJsshpi|gFKgZ@^OgUpM5u=PA?dJGp2uEFF(sPcjqgCT}97iIFED`7)epK`5w zK2N96i)V=e>u?bS;i22*V@Nd!0009f0D%4SOFis3-5s25%^e(UIXvv`Ds=4~wgqsW z{AM1*m^NnHf%aOhfdGSoKWGiEtl9B84BY(?ygfVQ5}o@Ehb-Qne%;b0ZxlST$>^MP zPs`&~zxTh>ow}pn7(}aFk8ooe_485>_}Ph85-v2@I0i%_KrQOKKV9IvT+FWJKvyZ4 zy_YoZ%>4rbWy zEXmnTt;P0x$nLNVg;+;(Wl_VOc`7Qd8;tJ6rH$fxmnyOrd7?5j($Q`=yn~QaCn>|hxxeD2nVQK2B?%Qa}E11^f(8U_#YZ?Sb5hThw&`%7? z@G-NnNK7d1e03e4FsV!SM&mB90a6u=({57#Zok@dckLt=d}AnO44?d4H)&Maq9}oy zV;2=yfH;$uXogl)4Dek~Ta`7jr-Gm4rpji+&GjQUlt}y!V|sUmI8d%0N4$Z5ze}ln z`Ad=pRn58oa}`RTnvgiPBXSiJ)^y7Ec=?z}i%&dg{2$1KS1av4@9uA zC+j>t6k+AEi;x?A?Np4Q^K?9Dp!Y99R31K?EV?a;bSz&cvZjYH`K{`|H(6$VTty{# z2ZkAi2Q|dvstu)_`*Rb`s(J~(Fm}Q&u4;aDxZCXcDTY}{-OHXO*QB!Jp>^jM5)r0IsE4fQAfwC)!J#T31>! zBnC!|C&OnYGw6x~kqPLCChBMRXh-!UO%J771Sp`}Tu!lwPX_qgTa|6B5O^8;DP3UN3`49N{_qPcI@X;{#NE49fPY$8mqfVdT+GC!r zz*=1y#PF%o)qmRH+sO~r>CVD^K-_u4CH2Vz*LBp~s-oTbdFv^pv#+4CPgNO4y5EBO zZ+$Z86q2^1{F@<(J@Rp~qhu%N1%Z~(${DS3E+P+ItC$-^S-!g|O>Zw-AG~D^$Uoy4 z+-yY$`X$7Pyv6Wye|3f?S_R1xX1qmY(7aT#Zj~zNr)#dDG`=HZ^TW@2A8nK0-1UiH zi=Ag@E-ASkVo{9wepI<|IK@ctY_1%A^Jg#GAm%U#lFd`<=-S+DX8WQQfbCrct*w$} zC^0-UmAiuQXx#4E2tzV-v)BB}w18fx4e8q2IA5>Uv^@81d=g_zQRcHeNRkWc*Uhyl zJV@dSCc3~Xg)PMiax9gay@~kd`Q6GPCADj_*0g-I85Y*)dmr~TAcI=H_k5biU-}}{ z3BIRMJ6tmG{QI0C8RpftxBZ7egt-703KpN{(#?Oj{*2b8y*X8o8CI0vG!Y2 z-kkAb_?Gig_sFwn0sY0HvT9%b1SZY!kqn8&P~9x#_DmWq#^j9NcbmaMs!_|I8~!}O zw$$)Zg<{PXD__>7%{mqg0XS&k$?|l4D)+wIk)OZ9935{%(24KAjY-$3s%o3me5G#g z1j-M8y)_8RCw+4|VA$Dpg@Ni-Z)=mwg;tUd-7Z}DHTA;>7mD0d6y0)jbw*b*2Y4g(M69Lx>wWU-5u(?fZ8Z?&NJIoxx9X)GJ7 zlzuPrfml|^LS6qo_pE(c(f+qz)+DlYGfI5dcWZ1NVU7mzk*d)u)|H@i&n2QCQ+$SF zJf}vt8tmyQ+b}VoiC_4NiPS@AZ>IkxWv|b>;vcI|M3^hENkJ-63k??8Q6gmM_^J7P-LX57`UQRgL!1P&+EK0bw^ZjI?DJ%T{iMV)w*Mu3 z{1v?EV{UWV;Q+78%&h@s>fH^vLDk?;uMjqY?XWmA2N=avjAJAD5zEFTQcERN3z|{X ztX8CD?_rN6@!|Wal^9Z>@zxPjdn`>cU{tzW@`g zD=A6E@QS&~jT$G71zmnsFjRWc@J77lMztBjvwvn!x3kCAYZLr{0IIx8dV9%zw83_} zZj_v5EQ1FPLo4ZSU1*a0eS>*M==7wX~RE!Y;(NATT4OrrXX zzQa*GO?tL%r#*C}NcjirLF029m#`HU7R$#?QkHu?1s_)n3#dc&7P8q6D;q^B>s1-c zL08YLvq-uyJKk4L9fi)Z!C^4pMB=mu@9**hlD(m4SJ86Ny5n)AK#9`bk0|y|Dhgq+Bsu@pd(-h8m&9xOOK+2xD13f?*;zb4XQfVm4iv|cfrgyHg_x=L zP$?u(Qm6DYu7EzRbe(dzO?S8}A9kjX6ANPO7}*u=Kn1?uZwc3r@7?SEZBe3EDT>?T zUHY){RwdTz-Yl76Ljx=9WaWdHYS=j#`y!RbJ~N2b(~Ylft{_4r=lGzIJ@a_x-O`q# zt8#^;`Dw(l!OR9Zc)=c*jRwIO6D0!;#AgYg_*I|o6bq=Z5>?!`50O;R0_P)1FwkKq ze3Sr7Km#+Y`aP*P&FLREyf5KqPH7d;GtQB?U^2 zMdvoksd)OFhxQ@qtXM5O+q`pY3!LX|yuc(|jA#=8_p}D~%$XHl3 z_{^xBI;y_+XO2{yg7Sch+aYml(Q&n(tKBBm8cED%`W3?0D zFgyku&ve0t&GEE7LG4;Lcwlu9^6eo#Cc%8|$ln|0@!}}xOX$+CpXEmCSu5W0ag+(< z+lfL+G5;C%_V|VmZw@tZub6G&Ur2{L=89uXP?15s^#V2MjYabcH)NSYQNX&}LpPEp zF<4KZ6)-V3n4kN|Is;bgDRPtu7~+`h&t%neSR8>W5iNb-O|)+~fg;n+9!C4jerz_f z!x9Uf>^2!;=Kvg`y_hGLuhBz^gB{N=FhjSB*Z4y!vz37LSUO=WKd&=H$zt) z8qZQmjDM16=zJP=<0C`!Wg*|y0=x^O;u~uC&l?*T-QCCKa?Ar^X{K382u!GOl9Dsx z$H7F~KW}e%zOG$rKKF|7)HM#R(=&^fiyERB!LgXVbbB@}*enZU{Q?toisRtxAq+^En-aCwX?JfG|K)>iL#$esNE6O>- zAeDWfTwC+vVw0nPMCaoe+8mEBlc9(AgY>O=8NmwUDN-zGNe)EUXI)x_SeR=jVskUX ziMdYCzfZV+p)((WzHt_Vy8i9g&Gxl&D?F{3mRq3AY`F%rxHPWp3qe;@C?h#p2HY;D zn~&CJnp+wUA43}S8PH*sr^l(~4T9TddX;$yoHpcAkTD{Z>?7gnC9~C7cvN#p7m17f z!qQqWw)o}`sx6}gw;;1c28!K#1tBr?pQir2njI?20yt)2YL3CawuGudtjobTYLY}{ z20Z1v{qI_uAhC32K~Tr;q%@~HI;6}J%BY?mu3v^sANL9n-~bh}gBo;ALDb=&t*P$R zNPVn^{JKm#eQhQ_n{FaFX{D#p{!YBTk-Bt(3z7jchV7#5e!~BfZIvH1A7HVsD|z{Qr$eV5%ab=d+xTfiTWl~iPZAlkY(Z!TJor%8Kk_e3Ag z5iwpEd-ujpoImR$3o+^(CZ-qq3bcAaK=N4E?H4m)$IubuCgRtg9DV^!DyJx#n=2cPH#~qL@X?dK>`~ainJ6pSD1KE)y^Jrw$QYo4Y zdj5$FMm+K-6-`#yphX|OXEMzT4t*ywcCS$09_!v9Q7y*<48@btp8&fDS151SBz&Ug z<=G`8*U^lM@cBjPBMBSS8avW<76)WJn(R@~v0e9H14Vf63*@r?yl{v9(wXRbQQEqjQxG{GJ?agGjdX`$o+tPI4)tv76Zq|T0Vk#&>kb&j~VY) zbsAG!Dj-iZ;eiK*JVC_Hr~?u7*}L?|Wl%pHJraZfQ~tL02<(*i{_BAMb{L=vj`dLp ziWIxEhL7dg)GBDz9r88849Ak?j*v!p^5kWkVN1y9`{z40x8dn4YrE_n+OHj*iVKG>+DhVuCq5(|L+R3UO2m+$Zinn?#Ayflyk|HlcetKhdbynO z;mGC@Oi0BBC_CQtq0a7(b@g|S8$Q+1bBYGyTmAURp&(vdDpjgbbA46fKp_z_>;h9q zE~i@372yC>O#Ja9J6ClhE;Tf~8K9RwdQXOjD><5|V2i=hI9TMoL4N;-o zkKSOa5%wlM|&RZ*lQEOW!50Yi$VIkbBR%ut^7$?^J2I{v=zArL64fm6aKd;+$ z_;cnPTkwS2SZG0-5>fnI8MJ}lzC%ej@}WO!4_grcbjl@S$3GL8yqbHvv_zx7m4oG(^8|Kd%`&p$7e_b%5c3Y>Bp$qLa z1J5AS(po_Se;qYpaxhWE*{Yv*@rNbB*V^3eTZA+S5ite^AQ2ln4vlb}(p}kj9HpnZ zk5^JXb>u$ZiCaUBJ*8~3!8o6jXX>uN#=yBak2FzW&dA{U1<;77Z@O3*W6+3jO?p$$ zOsw0WCyqVBEtty~8kU!fl)l0Uh?Wm}tGGsBD)9^Zw+Wfd4Bt3ryMq7HF&l=dmKdkw#iha;~o|}T1*jHf>+ynvV7UI5*j_4qHG`F zI{*!2Co+s;qKj|qaN7)Ue3!^Ci9SP2PD;bcOCuCttaWq-xx<>>h(Wc?7v zQRtfdqth{r#NS7s%w#Hh#-*rl`V7wTWl%~T0QrtuHuFAQVdTn z+1k^6nL2mCx=FKw=P;7~ay|N}V@@D{;rmty&*O$ft$t!?wegmk20qI(VXFOj{hn)6KX4)Ex)jl?5dOEC;SUy zI;o$--caztwO1rcML})bAf@?&dPudx=TZ%}OY>Z53*+y%@++8sEsLqS<5)e3v<^L+ znfS_5piw)jPWMN7Ww#jmt+pz8U|z1LE1`-0O9(3g-t7Yq0etDAakjOzwCSe8)zYe@ z8~E47q^g^?B7JR#5vBLCXE!_(*F*FLpx*v!0Geuig?3|A%qpZAzl7@at}J>lRf3U= zM=)|~rbtjIfI2-NIh5BXjR9?#X;>{N{}cRfyN_}HpD}})ulu|f11Asm_9I^Dcj`N# zJ?sS6faN(LKpvyERl}=0J+!@3ioLSte!(k)fi?P%b|fv1gp;t_ExASpwbF-!H#*b^ z8Bk0FP>G#Y2W!dLWL5fw4bEl#YBY1`{Ip1`=NRd5dXKV@wwJ4L1DxNRA;aH$T+CKz zW0pL%!}-M;xj(5!C1gK(ACOxo1!$F284vNFY`Qj%xZ8%9NUBMkx$r#y<96{IpKi$O zKq}7(<|ztpCZ6A(7{n*${V>iLk{Hxw`2~9Yr^(Z44qztKvG2r8Vp`Sgzh8&r@wQ6# zWbjOH8-^-Wv!V188F=?g8uNQM{r; z9|DmrFskE3{qO&P=uBY8tlpoJ7+hkLYWTPf%jc@WA;%upUp^;*EnDJx`K_TX_q+W` z*i-8c_ZngtD*oc37|hKR0fof5f;U!`9b_8H{#DpN5OQr4fytLW2|eVt$f-FNMrLHR z=)_y7?)D>|on+ya<^|}d#XopGDxQW`B5&hY28EFMT;C;q{}>@bhndZ1nar50IP|@r zJHEpov_P;aa9ijcMIiyt1_y>>b4mnV!)25J@4;6B^s%YA&_;^E6vvt6{^NI-7Jozr zkfbvtwhHi1I@S({H}$;uFD!2-r-Cusw+e2;?dW=Rr|x_;H!!(t!YjWn)J;+}?~aY> zT)llyWWwn6A^W{cEAo@LNY%ut>+QpxIIbDJg6(>q{B&GndkQ*9EL&Hz@d^Wo)Q-ck*F&H) zBwy8(YFVC23cVQ(aZnXHAEqFGwAU5uzC@|UU7~cFXz^wHgcZ(e#$pKy&9G zvcrHu1k+0_-^^a;4Gw1(U1E z30P3*I%9hVS@-C)wA}yD(h&2{#w9CEgcDR9iYC+uZ*e?0R_90sF zcnQ;5GnHD?fl8_0r|lH4J{01Qzvt`5D;}3beS&cuq+^*3l~fP$1d9RTh{BY`&Y!Lb zH^cmA(H>}Z39V0$G}ldzBAP3vYx}D4o`3wBz~6~zX27PWIy@BNWW@gmDd%WqA-oOS z^b$VSRK3wLm)OQAp`B7iSY+s(w$z^wHKEwCqUPRcWxyHV(yz?=}L8}l{|3JwFPdel>pdQPfvH`Hap!$qj_d9 z-SWvsW~1SWnlQs@CgTUuM24mu54 z;R5+m9#aNx7#5!}ePiP2v9U2*lRWuS%`ej#I{+S*uT{8W_g<1RgH{(mjw9Vi8xO?n z*g2bex6QP)zVF;SOf#xdf?&xv;R$INO|rBY%9j`nPkxXJXQsh;#nM;mwuiJvS6Tn_63W&{}NPzEK+I zXK|V{Yj^wTo|Yl@4o_Av`ESgq6h|c{#83AR?~B|=Y>q;zl51VYk*DfQMngPH+U1I) zOAVI2aY!*c1S96fm8NEw37|}+I+!v}?(E0;_W3z<;*Gh--w2~iarjqrt86)+OvOzq z9nUbwx;6fEJ>P!90^1RHZq0n?H~#0xH(uN94_DPhZ`@ly(QFb;o~5zVMK{nSXp}33 zJh=gn@1Ty$h%(WCaeu+Dqo9-?V|&c5nCAa^ius9}4{nET%-cLvvI6=>i5(+$*KY*5 zzSS_D^_fXWy8=9siaZFNZRqI~J`(#*&p$v#FW2iG0*}@H7Mb!ev~M=>XiUTh)$1%) z4^@ItQIqW2Z{}<9!xl{q3oFZ_^*iHVmP9#jWtL3c3j){t3L0vd#9sDR6>CT>5|eYi z_z~zVsqywMPe@tgVvTsuwfnywJbd2C8Xlh{I9@MC`oZ9;@nJ%PICcAVOh{<|eeDKD z(y9(e0<&wSApQTZa=gqP|EGw-3R`I?{%=kc4*($fFV*Xt90LG=abu9co?BUfXxOlG zE_|4H8z)0Kc{y?8b*Bb&~*1Y+kFFJ@~Mdm+A+5 zSdASiOuq*QM$l#?gyI_TRaW z|KG|PpZ^#FuY-9Hasn^gUXYnUO$qU(F#y2%@{qk;Q^M)` HPwjsJ>xo8g delta 8657 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 G5&s3$?hJJR diff --git a/dbstruct/daily_statement_zone_info.go b/dbstruct/daily_statement_zone_info.go new file mode 100644 index 00000000..1f5914c1 --- /dev/null +++ b/dbstruct/daily_statement_zone_info.go @@ -0,0 +1,19 @@ +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"` // 删除标记 + +} diff --git a/library/idgenerator/genid.go b/library/idgenerator/genid.go index e57940ec..0043b581 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 +} From 0e6368fc0c084d64f21bdb05e352de2b7882c12e Mon Sep 17 00:00:00 2001 From: Leufolium Date: Wed, 15 May 2024 12:13:02 +0800 Subject: [PATCH 2/4] by Robin at 20240515 --- .../proto/daily_statement_zone_info_op.go | 14 ++++++ app/mix/dao/mongo.go | 6 +++ app/mix/dao/mysql_zone.go | 38 ++++++++++++++-- .../logic/daily_statement_zone_info.go | 22 ++++++++++ app/mix/service/logic/vas_zone.go | 24 ++++++++-- app/mix/service/utilservice.go | 44 +++++++++++++++++++ app/mix/service/xxljob_tasks.go | 18 +++++++- dbstruct/daily_statement_zone_info.go | 43 +++++++++++------- dbstruct/vas_mysql.go | 44 +++++++++++++++++++ 9 files changed, 230 insertions(+), 23 deletions(-) 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 index 4f5914cb..287111ad 100644 --- 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 @@ -66,3 +66,17 @@ 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/app/mix/dao/mongo.go b/app/mix/dao/mongo.go index a8d85a84..8f3f56ff 100644 --- a/app/mix/dao/mongo.go +++ b/app/mix/dao/mongo.go @@ -5142,3 +5142,9 @@ func (m *Mongo) GetDailyStatementZoneInfoList(ctx *gin.Context, req *daily_state } 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 c8ba8904..ef413072 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" @@ -500,7 +501,38 @@ func (m *Mysql) GetZoneRefundHisList(ctx *gin.Context, tx *sqlx.Tx, mid, zid int return } -// 获取时段内空间进入人数、总入账金额、各业务分入账金额、退款金额、退款人数 -func (m *MySql) GetDailyStatementZoneInfoFromVasOrder(ctx *gin.Context, tx *sqlx.Tx, st, et int64, offset, limit int) { - +// 获取时段内空间进入人数、总入账金额、各业务分入账金额 +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 index 0d3a0e47..9f2426a6 100644 --- a/app/mix/service/logic/daily_statement_zone_info.go +++ b/app/mix/service/logic/daily_statement_zone_info.go @@ -63,3 +63,25 @@ func (p *DailyStatementZoneInfo) OpList(ctx *gin.Context, req *daily_statement_z } 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 9fd108c2..80bf904f 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" @@ -15,6 +12,10 @@ import ( "service/dbstruct" "service/library/logger" "time" + + "github.com/gin-gonic/gin" + "github.com/jmoiron/sqlx" + goproto "google.golang.org/protobuf/proto" ) // 检查mid对空间的解锁是否存在 @@ -1184,3 +1185,20 @@ func (v *Vas) ZoneExit(ctx *gin.Context, mid, zid int64) error { return nil } + +// 统计时段内空间报表信息 +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/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 a1b3adc8..c2571164 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" @@ -141,8 +142,6 @@ func (s *CronService) CreateDailyStatement(ctx context.Context, param *xxl.RunRe allOrderCount += util.DerefInt32(orderCount.Count) } - //获取空间相关信息 - dailyStatement := &dbstruct.DailyStatement{ H5CallCount: goproto.Int64(int64(count)), RegisteredUserCount: goproto.Int64(accountCount), @@ -163,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/dbstruct/daily_statement_zone_info.go b/dbstruct/daily_statement_zone_info.go index 1f5914c1..fabae2e8 100644 --- a/dbstruct/daily_statement_zone_info.go +++ b/dbstruct/daily_statement_zone_info.go @@ -1,19 +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"` // 删除标记 - + 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 +} From 5016e7b7bebf57defc7416e1ce1ff71d12643b6b Mon Sep 17 00:00:00 2001 From: Leufolium Date: Wed, 15 May 2024 16:07:33 +0800 Subject: [PATCH 3/4] by Robin at 20240515 --- api/proto/zone/proto/zone_vo_op.go | 3 +++ app/mix/service/xxljob_tasks.go | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) 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/app/mix/service/xxljob_tasks.go b/app/mix/service/xxljob_tasks.go index c2571164..f5d5c017 100644 --- a/app/mix/service/xxljob_tasks.go +++ b/app/mix/service/xxljob_tasks.go @@ -93,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) } //获取用户总量 @@ -109,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) } //获取订单总量 @@ -119,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) } //获取用户注册来源 @@ -129,7 +129,7 @@ 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) } //获取订单完成量 From 07b587475bccb8ae0fbeb3e0688ae6c6e196387d Mon Sep 17 00:00:00 2001 From: Leufolium Date: Wed, 15 May 2024 16:29:59 +0800 Subject: [PATCH 4/4] by Robin at 20240515 --- api/proto/zonemoment/proto/not_null_def_api.go | 4 ++++ api/proto/zonemoment/proto/not_null_def_op.go | 4 ++++ dbstruct/zonemoment.go | 9 +++++++++ 3 files changed, 17 insertions(+) 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/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 +}