Merge branch 'main' of http://gitea.tools.fontree.cn:3000/fiee/fonchain-fiee
This commit is contained in:
commit
9731c02a63
File diff suppressed because it is too large
Load Diff
@ -483,6 +483,22 @@ func (this *ConfirmWorkReq) Validate() error {
|
|||||||
func (this *ConfirmWorkResp) Validate() error {
|
func (this *ConfirmWorkResp) Validate() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
func (this *ConfirmWorkItem) Validate() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (this *GetWaitConfirmWorkListReq) Validate() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (this *GetWaitConfirmWorkListResp) Validate() error {
|
||||||
|
for _, item := range this.Data {
|
||||||
|
if item != nil {
|
||||||
|
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
|
||||||
|
return github_com_mwitkow_go_proto_validators.FieldError("Data", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
func (this *AutoCreateUserAndOrderRequest) Validate() error {
|
func (this *AutoCreateUserAndOrderRequest) Validate() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// Code generated by protoc-gen-go-triple. DO NOT EDIT.
|
// Code generated by protoc-gen-go-triple. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// - protoc-gen-go-triple v1.0.8
|
// - protoc-gen-go-triple v1.0.5
|
||||||
// - protoc v3.21.1
|
// - protoc v5.26.0
|
||||||
// source: pb/bundle.proto
|
// source: pb/bundle.proto
|
||||||
|
|
||||||
package bundle
|
package bundle
|
||||||
@ -79,6 +79,7 @@ type BundleClient interface {
|
|||||||
GetVedioWorkDetail(ctx context.Context, in *GetVedioWorkDetailReq, opts ...grpc_go.CallOption) (*GetVedioeWorkDetailResp, common.ErrorWithAttachment)
|
GetVedioWorkDetail(ctx context.Context, in *GetVedioWorkDetailReq, opts ...grpc_go.CallOption) (*GetVedioeWorkDetailResp, common.ErrorWithAttachment)
|
||||||
ToBeComfirmedWorks(ctx context.Context, in *ToBeComfirmedWorksReq, opts ...grpc_go.CallOption) (*ToBeComfirmedWorksResp, common.ErrorWithAttachment)
|
ToBeComfirmedWorks(ctx context.Context, in *ToBeComfirmedWorksReq, opts ...grpc_go.CallOption) (*ToBeComfirmedWorksResp, common.ErrorWithAttachment)
|
||||||
ConfirmWork(ctx context.Context, in *ConfirmWorkReq, opts ...grpc_go.CallOption) (*ConfirmWorkResp, common.ErrorWithAttachment)
|
ConfirmWork(ctx context.Context, in *ConfirmWorkReq, opts ...grpc_go.CallOption) (*ConfirmWorkResp, common.ErrorWithAttachment)
|
||||||
|
GetWaitConfirmWorkList(ctx context.Context, in *GetWaitConfirmWorkListReq, opts ...grpc_go.CallOption) (*GetWaitConfirmWorkListResp, common.ErrorWithAttachment)
|
||||||
// 对账单
|
// 对账单
|
||||||
GetReconciliationList(ctx context.Context, in *GetReconciliationListReq, opts ...grpc_go.CallOption) (*GetReconciliationListResp, common.ErrorWithAttachment)
|
GetReconciliationList(ctx context.Context, in *GetReconciliationListReq, opts ...grpc_go.CallOption) (*GetReconciliationListResp, common.ErrorWithAttachment)
|
||||||
CreateReconciliation(ctx context.Context, in *ReconciliationInfo, opts ...grpc_go.CallOption) (*CommonResponse, common.ErrorWithAttachment)
|
CreateReconciliation(ctx context.Context, in *ReconciliationInfo, opts ...grpc_go.CallOption) (*CommonResponse, common.ErrorWithAttachment)
|
||||||
@ -169,6 +170,7 @@ type BundleClientImpl struct {
|
|||||||
GetVedioWorkDetail func(ctx context.Context, in *GetVedioWorkDetailReq) (*GetVedioeWorkDetailResp, error)
|
GetVedioWorkDetail func(ctx context.Context, in *GetVedioWorkDetailReq) (*GetVedioeWorkDetailResp, error)
|
||||||
ToBeComfirmedWorks func(ctx context.Context, in *ToBeComfirmedWorksReq) (*ToBeComfirmedWorksResp, error)
|
ToBeComfirmedWorks func(ctx context.Context, in *ToBeComfirmedWorksReq) (*ToBeComfirmedWorksResp, error)
|
||||||
ConfirmWork func(ctx context.Context, in *ConfirmWorkReq) (*ConfirmWorkResp, error)
|
ConfirmWork func(ctx context.Context, in *ConfirmWorkReq) (*ConfirmWorkResp, error)
|
||||||
|
GetWaitConfirmWorkList func(ctx context.Context, in *GetWaitConfirmWorkListReq) (*GetWaitConfirmWorkListResp, error)
|
||||||
GetReconciliationList func(ctx context.Context, in *GetReconciliationListReq) (*GetReconciliationListResp, error)
|
GetReconciliationList func(ctx context.Context, in *GetReconciliationListReq) (*GetReconciliationListResp, error)
|
||||||
CreateReconciliation func(ctx context.Context, in *ReconciliationInfo) (*CommonResponse, error)
|
CreateReconciliation func(ctx context.Context, in *ReconciliationInfo) (*CommonResponse, error)
|
||||||
UpdateReconciliation func(ctx context.Context, in *ReconciliationInfo) (*CommonResponse, error)
|
UpdateReconciliation func(ctx context.Context, in *ReconciliationInfo) (*CommonResponse, error)
|
||||||
@ -497,6 +499,12 @@ func (c *bundleClient) ConfirmWork(ctx context.Context, in *ConfirmWorkReq, opts
|
|||||||
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/ConfirmWork", in, out)
|
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/ConfirmWork", in, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *bundleClient) GetWaitConfirmWorkList(ctx context.Context, in *GetWaitConfirmWorkListReq, opts ...grpc_go.CallOption) (*GetWaitConfirmWorkListResp, common.ErrorWithAttachment) {
|
||||||
|
out := new(GetWaitConfirmWorkListResp)
|
||||||
|
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
|
||||||
|
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GetWaitConfirmWorkList", in, out)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *bundleClient) GetReconciliationList(ctx context.Context, in *GetReconciliationListReq, opts ...grpc_go.CallOption) (*GetReconciliationListResp, common.ErrorWithAttachment) {
|
func (c *bundleClient) GetReconciliationList(ctx context.Context, in *GetReconciliationListReq, opts ...grpc_go.CallOption) (*GetReconciliationListResp, common.ErrorWithAttachment) {
|
||||||
out := new(GetReconciliationListResp)
|
out := new(GetReconciliationListResp)
|
||||||
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
|
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
|
||||||
@ -744,6 +752,7 @@ type BundleServer interface {
|
|||||||
GetVedioWorkDetail(context.Context, *GetVedioWorkDetailReq) (*GetVedioeWorkDetailResp, error)
|
GetVedioWorkDetail(context.Context, *GetVedioWorkDetailReq) (*GetVedioeWorkDetailResp, error)
|
||||||
ToBeComfirmedWorks(context.Context, *ToBeComfirmedWorksReq) (*ToBeComfirmedWorksResp, error)
|
ToBeComfirmedWorks(context.Context, *ToBeComfirmedWorksReq) (*ToBeComfirmedWorksResp, error)
|
||||||
ConfirmWork(context.Context, *ConfirmWorkReq) (*ConfirmWorkResp, error)
|
ConfirmWork(context.Context, *ConfirmWorkReq) (*ConfirmWorkResp, error)
|
||||||
|
GetWaitConfirmWorkList(context.Context, *GetWaitConfirmWorkListReq) (*GetWaitConfirmWorkListResp, error)
|
||||||
// 对账单
|
// 对账单
|
||||||
GetReconciliationList(context.Context, *GetReconciliationListReq) (*GetReconciliationListResp, error)
|
GetReconciliationList(context.Context, *GetReconciliationListReq) (*GetReconciliationListResp, error)
|
||||||
CreateReconciliation(context.Context, *ReconciliationInfo) (*CommonResponse, error)
|
CreateReconciliation(context.Context, *ReconciliationInfo) (*CommonResponse, error)
|
||||||
@ -929,6 +938,9 @@ func (UnimplementedBundleServer) ToBeComfirmedWorks(context.Context, *ToBeComfir
|
|||||||
func (UnimplementedBundleServer) ConfirmWork(context.Context, *ConfirmWorkReq) (*ConfirmWorkResp, error) {
|
func (UnimplementedBundleServer) ConfirmWork(context.Context, *ConfirmWorkReq) (*ConfirmWorkResp, error) {
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method ConfirmWork not implemented")
|
return nil, status.Errorf(codes.Unimplemented, "method ConfirmWork not implemented")
|
||||||
}
|
}
|
||||||
|
func (UnimplementedBundleServer) GetWaitConfirmWorkList(context.Context, *GetWaitConfirmWorkListReq) (*GetWaitConfirmWorkListResp, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method GetWaitConfirmWorkList not implemented")
|
||||||
|
}
|
||||||
func (UnimplementedBundleServer) GetReconciliationList(context.Context, *GetReconciliationListReq) (*GetReconciliationListResp, error) {
|
func (UnimplementedBundleServer) GetReconciliationList(context.Context, *GetReconciliationListReq) (*GetReconciliationListResp, error) {
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method GetReconciliationList not implemented")
|
return nil, status.Errorf(codes.Unimplemented, "method GetReconciliationList not implemented")
|
||||||
}
|
}
|
||||||
@ -2416,6 +2428,35 @@ func _Bundle_ConfirmWork_Handler(srv interface{}, ctx context.Context, dec func(
|
|||||||
return interceptor(ctx, in, info, handler)
|
return interceptor(ctx, in, info, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func _Bundle_GetWaitConfirmWorkList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(GetWaitConfirmWorkListReq)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
base := srv.(dubbo3.Dubbo3GrpcService)
|
||||||
|
args := []interface{}{}
|
||||||
|
args = append(args, in)
|
||||||
|
md, _ := metadata.FromIncomingContext(ctx)
|
||||||
|
invAttachment := make(map[string]interface{}, len(md))
|
||||||
|
for k, v := range md {
|
||||||
|
invAttachment[k] = v
|
||||||
|
}
|
||||||
|
invo := invocation.NewRPCInvocation("GetWaitConfirmWorkList", args, invAttachment)
|
||||||
|
if interceptor == nil {
|
||||||
|
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||||
|
return result, result.Error()
|
||||||
|
}
|
||||||
|
info := &grpc_go.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||||
|
return result, result.Error()
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
func _Bundle_GetReconciliationList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
|
func _Bundle_GetReconciliationList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
|
||||||
in := new(GetReconciliationListReq)
|
in := new(GetReconciliationListReq)
|
||||||
if err := dec(in); err != nil {
|
if err := dec(in); err != nil {
|
||||||
@ -3539,6 +3580,10 @@ var Bundle_ServiceDesc = grpc_go.ServiceDesc{
|
|||||||
MethodName: "ConfirmWork",
|
MethodName: "ConfirmWork",
|
||||||
Handler: _Bundle_ConfirmWork_Handler,
|
Handler: _Bundle_ConfirmWork_Handler,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
MethodName: "GetWaitConfirmWorkList",
|
||||||
|
Handler: _Bundle_GetWaitConfirmWorkList_Handler,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
MethodName: "GetReconciliationList",
|
MethodName: "GetReconciliationList",
|
||||||
Handler: _Bundle_GetReconciliationList_Handler,
|
Handler: _Bundle_GetReconciliationList_Handler,
|
||||||
|
|||||||
128
pkg/cron/task.go
128
pkg/cron/task.go
@ -5,12 +5,16 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"fonchain-fiee/api/bundle"
|
||||||
"fonchain-fiee/api/cast"
|
"fonchain-fiee/api/cast"
|
||||||
"fonchain-fiee/pkg/cache"
|
"fonchain-fiee/pkg/cache"
|
||||||
|
bundleModel "fonchain-fiee/pkg/model/bundle"
|
||||||
modelCast "fonchain-fiee/pkg/model/cast"
|
modelCast "fonchain-fiee/pkg/model/cast"
|
||||||
"fonchain-fiee/pkg/service"
|
"fonchain-fiee/pkg/service"
|
||||||
serverCast "fonchain-fiee/pkg/service/cast"
|
serverCast "fonchain-fiee/pkg/service/cast"
|
||||||
"log"
|
"log"
|
||||||
|
"math/rand"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-redis/redis"
|
"github.com/go-redis/redis"
|
||||||
@ -32,6 +36,9 @@ func InitTasks() error {
|
|||||||
// 启动队列消费者
|
// 启动队列消费者
|
||||||
go WorkPublishQueueConsumer()
|
go WorkPublishQueueConsumer()
|
||||||
|
|
||||||
|
// 启动随机间隔的自动确认任务
|
||||||
|
go AutoManuallyConfirmWorkTaskWithRandomInterval()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,6 +58,127 @@ func RefreshWorkApprovalStatusTask() {
|
|||||||
serverCast.RefreshWorkApproval(nil, resp.Data)
|
serverCast.RefreshWorkApproval(nil, resp.Data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AutoManuallyConfirmWorkTaskWithRandomInterval 以随机间隔(3-7分钟)执行自动确认任务
|
||||||
|
func AutoManuallyConfirmWorkTaskWithRandomInterval() {
|
||||||
|
|
||||||
|
for {
|
||||||
|
// 执行任务
|
||||||
|
AutoManuallyConfirmWorkTask()
|
||||||
|
|
||||||
|
// 生成3-7分钟之间的随机间隔(单位:分钟)
|
||||||
|
randomMinutes := rand.Intn(5) + 3 // 3-7分钟
|
||||||
|
randomDuration := time.Duration(randomMinutes) * time.Minute
|
||||||
|
|
||||||
|
// 等待随机时间
|
||||||
|
time.Sleep(randomDuration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func AutoManuallyConfirmWorkTask() {
|
||||||
|
var req bundle.GetWaitConfirmWorkListReq
|
||||||
|
res, err := service.BundleProvider.GetWaitConfirmWorkList(context.Background(), &req)
|
||||||
|
if err != nil {
|
||||||
|
zap.L().Error("获取待确认作品列表失败", zap.Error(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if res.Data == nil || len(res.Data) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, work := range res.Data {
|
||||||
|
var req bundleModel.UserWorkConfirmReq
|
||||||
|
req.WorkUuid = work.WorkUuid
|
||||||
|
req.ConfirmStatus = 1
|
||||||
|
artistId, err := strconv.ParseInt(work.ArtistUuid, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
zap.L().Error("解析艺术家ID失败", zap.Error(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if req.ConfirmStatus == 2 { // 驳回完直接结束
|
||||||
|
_, err := service.CastProvider.UpdateStatus(context.Background(), &cast.UpdateStatusReq{
|
||||||
|
WorkAction: cast.WorkActionENUM_CONFIRM,
|
||||||
|
WorkUuid: req.WorkUuid,
|
||||||
|
ConfirmRemark: req.ConfirmRemark,
|
||||||
|
ConfirmStatus: 2,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
zap.L().Error("确认作品失败", zap.Error(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
balanceInfoRes, err := service.BundleProvider.GetBundleBalanceByUserId(context.Background(), &bundle.GetBundleBalanceByUserIdReq{
|
||||||
|
UserId: int32(artistId),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
wordInfoRes, err := service.CastProvider.WorkDetail(context.Background(), &cast.WorkDetailReq{
|
||||||
|
WorkUuid: req.WorkUuid,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if wordInfoRes.WorkStatus != 4 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var workCategory = wordInfoRes.WorkCategory
|
||||||
|
|
||||||
|
var addBalanceReq bundle.AddBundleBalanceReq
|
||||||
|
addBalanceReq.UserId = int32(artistId)
|
||||||
|
log.Printf("开始确认作品uuid:" + req.WorkUuid)
|
||||||
|
switch workCategory {
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
if balanceInfoRes.ImageConsumptionNumber >= balanceInfoRes.ImageExtendNumber { // 图文余量不足
|
||||||
|
_, err = service.CastProvider.UpdateStatus(context.Background(), &cast.UpdateStatusReq{
|
||||||
|
WorkAction: cast.WorkActionENUM_CONFIRM,
|
||||||
|
WorkUuid: req.WorkUuid,
|
||||||
|
ConfirmRemark: req.ConfirmRemark,
|
||||||
|
ConfirmStatus: 3,
|
||||||
|
})
|
||||||
|
log.Printf("图文余量不足,作品uuid:"+req.WorkUuid, zap.Error(err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
addBalanceReq.ImageConsumptionNumber = 1
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
if balanceInfoRes.VideoConsumptionNumber >= balanceInfoRes.VideoExtendNumber { // 视频余量不足
|
||||||
|
_, err = service.CastProvider.UpdateStatus(context.Background(), &cast.UpdateStatusReq{
|
||||||
|
WorkAction: cast.WorkActionENUM_CONFIRM,
|
||||||
|
WorkUuid: req.WorkUuid,
|
||||||
|
ConfirmRemark: req.ConfirmRemark,
|
||||||
|
ConfirmStatus: 3,
|
||||||
|
})
|
||||||
|
log.Printf("视频余量不足,作品uuid:"+req.WorkUuid, zap.Error(err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
addBalanceReq.VideoConsumptionNumber = 1
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
resp, err := service.BundleProvider.AddBundleBalance(context.Background(), &addBalanceReq)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("扣除余额失败,作品uuid:"+req.WorkUuid, zap.Error(err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
log.Printf("扣除余额成功,作品uuid:" + req.WorkUuid)
|
||||||
|
_, err = service.CastProvider.UpdateStatus(context.Background(), &cast.UpdateStatusReq{
|
||||||
|
WorkAction: cast.WorkActionENUM_CONFIRM,
|
||||||
|
WorkUuid: req.WorkUuid,
|
||||||
|
ConfirmRemark: req.ConfirmRemark,
|
||||||
|
CostType: resp.UsedType,
|
||||||
|
ConfirmStatus: 1,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("更新作品状态失败,作品uuid:"+req.WorkUuid, zap.Error(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func ArtistAutoConfirmTask() {
|
func ArtistAutoConfirmTask() {
|
||||||
now := float64(time.Now().Unix())
|
now := float64(time.Now().Unix())
|
||||||
opt := redis.ZRangeBy{
|
opt := redis.ZRangeBy{
|
||||||
|
|||||||
@ -155,6 +155,11 @@ const (
|
|||||||
ErrorBalanceInsufficient = "余额不足"
|
ErrorBalanceInsufficient = "余额不足"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
BundlePurchaseExport = 1
|
||||||
|
BundleDetailExport = 2
|
||||||
|
)
|
||||||
|
|
||||||
// GetMsg 获取状态码对应信息
|
// GetMsg 获取状态码对应信息
|
||||||
func GetMsg(code int) string {
|
func GetMsg(code int) string {
|
||||||
msg, ok := MsgFlags[code]
|
msg, ok := MsgFlags[code]
|
||||||
|
|||||||
@ -208,7 +208,7 @@ func WorkConfirm(c *gin.Context) { // 确认作品并扣除余量
|
|||||||
switch workCategory {
|
switch workCategory {
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
if balanceInfoRes.ImageConsumptionNumber >= balanceInfoRes.ImageNumber { // 图文余量不足
|
if balanceInfoRes.ImageConsumptionNumber >= balanceInfoRes.ImageExtendNumber { // 图文余量不足
|
||||||
service.Error(c, errors.New("图文余量不足"))
|
service.Error(c, errors.New("图文余量不足"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -216,7 +216,7 @@ func WorkConfirm(c *gin.Context) { // 确认作品并扣除余量
|
|||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
if balanceInfoRes.VideoConsumptionNumber >= balanceInfoRes.VideoNumber { // 视频余量不足
|
if balanceInfoRes.VideoConsumptionNumber >= balanceInfoRes.VideoExtendNumber { // 视频余量不足
|
||||||
service.Error(c, errors.New("视频余量不足"))
|
service.Error(c, errors.New("视频余量不足"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"fonchain-fiee/api/bundle"
|
"fonchain-fiee/api/bundle"
|
||||||
"fonchain-fiee/api/cast"
|
"fonchain-fiee/api/cast"
|
||||||
|
"fonchain-fiee/pkg/e"
|
||||||
logicCast "fonchain-fiee/pkg/logic/cast"
|
logicCast "fonchain-fiee/pkg/logic/cast"
|
||||||
"fonchain-fiee/pkg/model/login"
|
"fonchain-fiee/pkg/model/login"
|
||||||
"fonchain-fiee/pkg/service"
|
"fonchain-fiee/pkg/service"
|
||||||
@ -97,13 +98,13 @@ func MetricsBundlePurchaseExport(ctx *gin.Context) {
|
|||||||
sumFee = sumFee.Add(decimal.NewFromFloat(float64(i.FeeAmount)))
|
sumFee = sumFee.Add(decimal.NewFromFloat(float64(i.FeeAmount)))
|
||||||
}
|
}
|
||||||
|
|
||||||
f.SetCellValue(sheet, fmt.Sprintf("A%d", endRow), "合计支付金额(美元)")
|
f.SetCellValue(sheet, fmt.Sprintf("A%d", endRow+1), "合计支付金额(美元)")
|
||||||
f.SetCellValue(sheet, fmt.Sprintf("B%d", endRow), "合计结算金额(美元)")
|
f.SetCellValue(sheet, fmt.Sprintf("B%d", endRow+1), "合计结算金额(美元)")
|
||||||
f.SetCellValue(sheet, fmt.Sprintf("C%d", endRow), "合计手续费金额(美元)")
|
f.SetCellValue(sheet, fmt.Sprintf("C%d", endRow+1), "合计手续费金额(美元)")
|
||||||
|
|
||||||
f.SetCellValue(sheet, fmt.Sprintf("A%d", endRow+1), "$"+sumPayment.StringFixed(2))
|
f.SetCellValue(sheet, fmt.Sprintf("A%d", endRow+2), "$"+sumPayment.StringFixed(2))
|
||||||
f.SetCellValue(sheet, fmt.Sprintf("B%d", endRow+1), "$"+sumFinal.StringFixed(2))
|
f.SetCellValue(sheet, fmt.Sprintf("B%d", endRow+2), "$"+sumFinal.StringFixed(2))
|
||||||
f.SetCellValue(sheet, fmt.Sprintf("C%d", endRow+1), "$"+sumFee.StringFixed(2))
|
f.SetCellValue(sheet, fmt.Sprintf("C%d", endRow+2), "$"+sumFee.StringFixed(2))
|
||||||
|
|
||||||
// 创建黑色边框样式
|
// 创建黑色边框样式
|
||||||
borderStyle, err := f.NewStyle(&excelize.Style{
|
borderStyle, err := f.NewStyle(&excelize.Style{
|
||||||
@ -124,8 +125,8 @@ func MetricsBundlePurchaseExport(ctx *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 应用样式到合计区域(包括标题行和数值行)
|
// 应用样式到合计区域(包括标题行和数值行)
|
||||||
startCell := fmt.Sprintf("A%d", endRow)
|
startCell := fmt.Sprintf("A%d", endRow+1)
|
||||||
endCell := fmt.Sprintf("C%d", endRow+1)
|
endCell := fmt.Sprintf("C%d", endRow+2)
|
||||||
if err := f.SetCellStyle(sheet, startCell, endCell, borderStyle); err != nil {
|
if err := f.SetCellStyle(sheet, startCell, endCell, borderStyle); err != nil {
|
||||||
fmt.Println("设置边框样式失败:", err)
|
fmt.Println("设置边框样式失败:", err)
|
||||||
}
|
}
|
||||||
@ -133,8 +134,8 @@ func MetricsBundlePurchaseExport(ctx *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := exportStructToExcel(resp.Data, []string{
|
if err := exportStructToExcel(resp.Data, []string{
|
||||||
"订单编号", "套餐", "用户编号", "客户姓名", "手机号", "支付时间", "套餐视频数", "增值视频数", "套餐金额", "增值金额", "支付金额", "结算金额", "手续费", "汇率(%)",
|
"订单编号", "套餐", "用户编号", "客户姓名", "手机号", "支付时间", "增值视频数", "套餐金额", "增值金额", "支付金额", "结算金额", "手续费", "汇率(%)",
|
||||||
}, filePath, statistic); err != nil {
|
}, filePath, e.BundlePurchaseExport, req.EndTime, statistic); err != nil {
|
||||||
service.Error(ctx, errors.New(common.MetricsBundlePurchaseExportFailed))
|
service.Error(ctx, errors.New(common.MetricsBundlePurchaseExportFailed))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -441,7 +442,7 @@ func MetricsBalanceDetailExport(ctx *gin.Context) {
|
|||||||
"所属月份", "用户编号", "姓名", "手机号", "购买套餐时间", "套餐金额", "增值金额", "支付金额", "币种", "手续费", "套餐视频总数",
|
"所属月份", "用户编号", "姓名", "手机号", "购买套餐时间", "套餐金额", "增值金额", "支付金额", "币种", "手续费", "套餐视频总数",
|
||||||
"增值视频总数", "套餐视频单价", "增值视频单价", "当前需要上传套餐视频数", "当前需要上传增值视频数",
|
"增值视频总数", "套餐视频单价", "增值视频单价", "当前需要上传套餐视频数", "当前需要上传增值视频数",
|
||||||
"当前已上传套餐视频数", "当前已上传增值视频数", "当前套餐视频已消费总金额", "当前增值视频已消费总金额",
|
"当前已上传套餐视频数", "当前已上传增值视频数", "当前套餐视频已消费总金额", "当前增值视频已消费总金额",
|
||||||
}, filePath, yelloStyle, statistic); err != nil {
|
}, filePath, e.BundleDetailExport, "", statistic); err != nil {
|
||||||
service.Error(ctx, errors.New(common.MetricsBalanceDetailExportFailed))
|
service.Error(ctx, errors.New(common.MetricsBalanceDetailExportFailed))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -518,11 +519,28 @@ func BalanceMetricsExport(ctx *gin.Context) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func exportStructToExcel[T any](data []T, headers []string, filename string, fns ...func(data []T, headers []string, f *excelize.File)) error {
|
func exportStructToExcel[T any](data []T, headers []string, filename string, exportType int, endTime string, fns ...func(data []T, headers []string, f *excelize.File)) error {
|
||||||
|
|
||||||
f := excelize.NewFile()
|
f := excelize.NewFile()
|
||||||
sheet := f.GetSheetName(f.GetActiveSheetIndex())
|
sheet := f.GetSheetName(f.GetActiveSheetIndex())
|
||||||
|
|
||||||
|
// 创建黄色背景样式(用于截止行)
|
||||||
|
yellowStyle, err := f.NewStyle(&excelize.Style{
|
||||||
|
Fill: excelize.Fill{
|
||||||
|
Type: "pattern",
|
||||||
|
Color: []string{"#FFFF00"}, // 黄色
|
||||||
|
Pattern: 1, // 实心填充
|
||||||
|
},
|
||||||
|
Alignment: &excelize.Alignment{
|
||||||
|
Horizontal: "left",
|
||||||
|
Vertical: "center",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
// 如果创建样式失败,继续执行但不应用样式
|
||||||
|
yellowStyle = 0
|
||||||
|
}
|
||||||
|
|
||||||
// 写入表头
|
// 写入表头
|
||||||
for i, h := range headers {
|
for i, h := range headers {
|
||||||
cell, _ := excelize.CoordinatesToCellName(i+1, 1)
|
cell, _ := excelize.CoordinatesToCellName(i+1, 1)
|
||||||
@ -546,12 +564,52 @@ func exportStructToExcel[T any](data []T, headers []string, filename string, fns
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 写入数据
|
// 写入数据
|
||||||
for rowIdx, item := range data {
|
actualRowIdx := 0
|
||||||
|
flag := 0
|
||||||
|
for _, item := range data {
|
||||||
val := reflect.ValueOf(item)
|
val := reflect.ValueOf(item)
|
||||||
if val.Kind() == reflect.Ptr {
|
if val.Kind() == reflect.Ptr {
|
||||||
val = val.Elem()
|
val = val.Elem()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if exportType == e.BundlePurchaseExport {
|
||||||
|
if endTime != "" {
|
||||||
|
// 通过反射获取 PayTime 字段
|
||||||
|
payTimeField := val.FieldByName("PayTime")
|
||||||
|
if payTimeField.IsValid() && payTimeField.Kind() == reflect.String {
|
||||||
|
payTimeStr := payTimeField.String()
|
||||||
|
if payTimeStr != "" {
|
||||||
|
// 解析时间
|
||||||
|
endTimeParsed, err1 := time.Parse(time.DateTime, endTime)
|
||||||
|
payTimeParsed, err2 := time.Parse(time.DateTime, payTimeStr)
|
||||||
|
|
||||||
|
if err1 == nil && err2 == nil {
|
||||||
|
// 如果 endTime <= PayTime,需要插入截止行
|
||||||
|
if !endTimeParsed.After(payTimeParsed) && flag == 0 {
|
||||||
|
flag = 1
|
||||||
|
// 格式化截止时间显示
|
||||||
|
endTimeFormatted := endTimeParsed.Format("2006年01月02日15点04分")
|
||||||
|
// 在当前行写入"截止xxxx年xx月xx点"
|
||||||
|
cell, _ := excelize.CoordinatesToCellName(1, actualRowIdx+2)
|
||||||
|
f.SetCellValue(sheet, cell, fmt.Sprintf("截止%s", endTimeFormatted))
|
||||||
|
// 应用黄色背景样式
|
||||||
|
if yellowStyle > 0 {
|
||||||
|
// 合并整行的单元格以显示截止信息
|
||||||
|
lastCol, _ := excelize.ColumnNumberToName(len(headers))
|
||||||
|
startCell := cell
|
||||||
|
endCell := fmt.Sprintf("%s%d", lastCol, actualRowIdx+2)
|
||||||
|
f.MergeCell(sheet, startCell, endCell)
|
||||||
|
f.SetCellStyle(sheet, startCell, endCell, yellowStyle)
|
||||||
|
}
|
||||||
|
// 移动到下一行
|
||||||
|
actualRowIdx++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for colIdx, fieldIdx := range exportedFields {
|
for colIdx, fieldIdx := range exportedFields {
|
||||||
field := val.Field(fieldIdx)
|
field := val.Field(fieldIdx)
|
||||||
|
|
||||||
@ -563,9 +621,10 @@ func exportStructToExcel[T any](data []T, headers []string, filename string, fns
|
|||||||
cellValue = field.Interface()
|
cellValue = field.Interface()
|
||||||
}
|
}
|
||||||
|
|
||||||
cell, _ := excelize.CoordinatesToCellName(colIdx+1, rowIdx+2)
|
cell, _ := excelize.CoordinatesToCellName(colIdx+1, actualRowIdx+2)
|
||||||
f.SetCellValue(sheet, cell, cellValue)
|
f.SetCellValue(sheet, cell, cellValue)
|
||||||
}
|
}
|
||||||
|
actualRowIdx++
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user