Files
olons_admin/server/internal/logic/sys/task.go
T
2026-10-10 20:56:17 +08:00

208 lines
9.2 KiB
Go

package sys
import (
"context"
"fmt"
"hotgo/internal/consts"
"hotgo/internal/dao"
"hotgo/internal/library/contexts"
"hotgo/internal/library/hgorm/handler"
"hotgo/internal/library/hgorm/hook"
"hotgo/internal/model/entity"
"hotgo/internal/model/input/sysin"
"hotgo/internal/service"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/util/grand"
)
type sSysTask struct{}
func NewSysTask() *sSysTask { return &sSysTask{} }
func init() { service.RegisterSysTask(NewSysTask()) }
func (s *sSysTask) Model(ctx context.Context) *gdb.Model {
return handler.Model(dao.Task.Ctx(ctx), &handler.Option{FilterTenant: true})
}
func (s *sSysTask) relationModel(ctx context.Context) *gdb.Model {
return handler.Model(dao.TaskLevel.Ctx(ctx), &handler.Option{FilterTenant: true})
}
func (s *sSysTask) listModel(ctx context.Context) *gdb.Model {
tc, hc := dao.Task.Columns(), dao.TaskHall.Columns()
return s.Model(ctx).As("t").LeftJoin(dao.TaskHall.Table()+" h", col("h", hc.Id)+"="+col("t", tc.HallId)).Fields("t.*", fmt.Sprintf("COALESCE(%s,'') hall_name", col("h", hc.Name)))
}
func (s *sSysTask) List(ctx context.Context, in *sysin.TaskListInp) (list []*sysin.TaskListModel, total int, err error) {
tc := dao.Task.Columns()
mod := s.listModel(ctx)
if in.Title != "" {
mod = mod.WhereLike(col("t", tc.Title), "%"+in.Title+"%")
}
if in.HallId > 0 {
mod = mod.Where(col("t", tc.HallId), in.HallId)
}
if in.PublishStatus > 0 {
mod = mod.Where(col("t", tc.PublishStatus), in.PublishStatus)
}
if in.LevelId > 0 {
mod = mod.WhereExists(s.relationModel(ctx).As("tl").Fields("1").Where(col("tl", dao.TaskLevel.Columns().TaskId)+"="+col("t", tc.Id)).Where(col("tl", dao.TaskLevel.Columns().LevelId), in.LevelId))
}
if err = mod.Page(in.Page, in.PerPage).OrderAsc(col("t", tc.Sort)).OrderDesc(col("t", tc.Id)).ScanAndCount(&list, &total, false); err != nil {
return nil, 0, gerror.Wrap(err, "获取任务列表失败")
}
for _, row := range list {
if err = s.loadLevels(ctx, row); err != nil {
return nil, 0, err
}
count, e := handler.Model(dao.TradeOrder.Ctx(ctx), &handler.Option{FilterTenant: true}).Where(dao.TradeOrder.Columns().TaskId, row.Id).Count()
if e != nil {
return nil, 0, e
}
row.Referenced = count > 0
}
return
}
func (s *sSysTask) View(ctx context.Context, in *sysin.TaskViewInp) (res *sysin.TaskListModel, err error) {
if err = s.listModel(ctx).Where(col("t", dao.Task.Columns().Id), in.Id).Scan(&res); err != nil {
return nil, gerror.Wrap(err, "获取任务详情失败")
}
if res == nil {
return nil, gerror.New("任务不存在")
}
err = s.loadLevels(ctx, res)
return
}
func (s *sSysTask) loadLevels(ctx context.Context, row *sysin.TaskListModel) error {
rc, lc := dao.TaskLevel.Columns(), dao.AppMemberLevel.Columns()
type item struct {
Id uint64 `json:"id"`
Name string `json:"name"`
}
var rows []*item
if err := s.relationModel(ctx).As("r").LeftJoin(dao.AppMemberLevel.Table()+" l", col("l", lc.Id)+"="+col("r", rc.LevelId)).Fields(col("l", lc.Id), col("l", lc.Name)).Where(col("r", rc.TaskId), row.Id).OrderAsc(col("l", lc.Sort)).Scan(&rows); err != nil {
return gerror.Wrap(err, "获取任务等级失败")
}
row.LevelIds = []uint64{}
row.LevelNames = []string{}
for _, v := range rows {
row.LevelIds = append(row.LevelIds, v.Id)
row.LevelNames = append(row.LevelNames, v.Name)
}
return nil
}
func (s *sSysTask) Edit(ctx context.Context, in *sysin.TaskEditInp) (id uint64, err error) {
amount, err := parseCents(in.Commission)
if err != nil {
return 0, err
}
in.CommissionAmount = amount
hc := dao.TaskHall.Columns()
hallCount, err := handler.Model(dao.TaskHall.Ctx(ctx), &handler.Option{FilterTenant: true}).WherePri(in.HallId).WhereIn(hc.PublishStatus, []int{consts.BizPublishPublished, consts.BizPublishOffline, consts.BizPublishDraft}).Count()
if err != nil {
return 0, err
}
if hallCount == 0 {
return 0, gerror.New("任务大厅不存在")
}
lc := dao.AppMemberLevel.Columns()
levelCount, err := handler.Model(dao.AppMemberLevel.Ctx(ctx), &handler.Option{FilterTenant: true}).WhereIn(lc.Id, in.LevelIds).Where(lc.Status, consts.StatusEnabled).Count()
if err != nil {
return 0, err
}
if levelCount != len(in.LevelIds) {
return 0, gerror.New("所选会员等级不存在或已停用")
}
err = g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
c := dao.Task.Columns()
uid := contexts.GetUserId(ctx)
var before *entity.Task
if in.Id > 0 {
if e := s.Model(ctx).WherePri(in.Id).LockUpdate().Scan(&before); e != nil {
return e
}
if before == nil {
return gerror.New("任务不存在")
}
result, e := s.Model(ctx).WherePri(in.Id).Where(c.Version, in.Version).Fields(sysin.TaskUpdateFields{}).Data(g.Map{c.HallId: in.HallId, c.Title: in.Title, c.Description: in.Description, c.DetailHtml: in.DetailHtml, c.CoverAttachmentId: in.CoverAttachmentId, c.CoverUrl: in.CoverUrl, c.CommissionAmount: in.CommissionAmount, c.CommissionRate: in.CommissionRate, c.DailyLimit: in.DailyLimit, c.PerMemberLimit: in.PerMemberLimit, c.StartAt: in.StartAt, c.EndAt: in.EndAt, c.Sort: in.Sort, c.Remark: in.Remark, c.UpdatedBy: uid, c.Version: gdb.Raw(c.Version + "+1")}).Update()
if e != nil {
return gerror.Wrap(e, "更新任务失败")
}
rows, _ := result.RowsAffected()
if rows != 1 {
return gerror.New("任务数据已更新,请刷新后重试")
}
id = in.Id
} else {
taskNo := "TK" + gtime.Now().Format("YmdHis") + grand.S(5)
result, e := s.Model(ctx).Fields(c.TaskNo, c.HallId, c.Title, c.Description, c.DetailHtml, c.CoverAttachmentId, c.CoverUrl, c.CommissionAmount, c.CommissionRate, c.DailyLimit, c.PerMemberLimit, c.StartAt, c.EndAt, c.PublishStatus, c.Sort, c.Remark, c.CreatedBy, c.UpdatedBy).Hook(hook.SaveTenant).Data(g.Map{c.TaskNo: taskNo, c.HallId: in.HallId, c.Title: in.Title, c.Description: in.Description, c.DetailHtml: in.DetailHtml, c.CoverAttachmentId: in.CoverAttachmentId, c.CoverUrl: in.CoverUrl, c.CommissionAmount: in.CommissionAmount, c.CommissionRate: in.CommissionRate, c.DailyLimit: in.DailyLimit, c.PerMemberLimit: in.PerMemberLimit, c.StartAt: in.StartAt, c.EndAt: in.EndAt, c.PublishStatus: consts.BizPublishDraft, c.Sort: in.Sort, c.Remark: in.Remark, c.CreatedBy: uid, c.UpdatedBy: uid}).Insert()
if e != nil {
return gerror.Wrap(e, "创建任务失败")
}
last, _ := result.LastInsertId()
id = uint64(last)
}
rc := dao.TaskLevel.Columns()
if _, e := s.relationModel(ctx).Where(rc.TaskId, id).Delete(); e != nil {
return e
}
for _, levelId := range in.LevelIds {
if _, e := dao.TaskLevel.Ctx(ctx).Fields(rc.TaskId, rc.LevelId).Hook(hook.SaveTenant).Data(g.Map{rc.TaskId: id, rc.LevelId: levelId}).Insert(); e != nil {
return gerror.Wrap(e, "保存任务等级失败")
}
}
return service.SysBizAudit().Record(ctx, &sysin.BizAuditRecordInp{Module: "task", Action: "task.edit", TargetType: "task", TargetId: id, Before: before, After: g.Map{"title": in.Title, "commissionAmount": in.CommissionAmount, "levelIds": in.LevelIds}})
})
return
}
func (s *sSysTask) Status(ctx context.Context, in *sysin.TaskStatusInp) error {
c := dao.Task.Columns()
if in.PublishStatus == consts.BizPublishPublished {
count, err := s.relationModel(ctx).Where(dao.TaskLevel.Columns().TaskId, in.Id).Count()
if err != nil {
return err
}
if count == 0 {
return gerror.New("任务至少绑定一个会员等级后才能发布")
}
}
result, err := s.Model(ctx).WherePri(in.Id).Where(c.Version, in.Version).Data(g.Map{c.PublishStatus: in.PublishStatus, c.UpdatedBy: contexts.GetUserId(ctx), c.Version: gdb.Raw(c.Version + "+1")}).Update()
if err != nil {
return gerror.Wrap(err, "更新任务状态失败")
}
rows, _ := result.RowsAffected()
if rows != 1 {
return gerror.New("任务数据已更新,请刷新后重试")
}
return service.SysBizAudit().Record(ctx, &sysin.BizAuditRecordInp{Module: "task", Action: "task.status", TargetType: "task", TargetId: in.Id, After: g.Map{"publishStatus": in.PublishStatus}})
}
func (s *sSysTask) Delete(ctx context.Context, in *sysin.TaskDeleteInp) error {
c := dao.Task.Columns()
var row *entity.Task
if err := s.Model(ctx).WherePri(in.Id).Scan(&row); err != nil {
return err
}
if row == nil {
return gerror.New("任务不存在")
}
count, err := handler.Model(dao.TradeOrder.Ctx(ctx), &handler.Option{FilterTenant: true}).Where(dao.TradeOrder.Columns().TaskId, in.Id).Count()
if err != nil {
return err
}
if count > 0 {
return gerror.New("任务已被订单引用,只允许下线,不能删除")
}
if row.PublishStatus == consts.BizPublishPublished {
_, err = s.Model(ctx).WherePri(in.Id).Data(g.Map{c.PublishStatus: consts.BizPublishOffline, c.UpdatedBy: contexts.GetUserId(ctx), c.Version: gdb.Raw(c.Version + "+1")}).Update()
return err
}
return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
if _, e := s.relationModel(ctx).Where(dao.TaskLevel.Columns().TaskId, in.Id).Delete(); e != nil {
return e
}
_, e := s.Model(ctx).WherePri(in.Id).Data(g.Map{c.DeletedAt: gtime.Now(), c.DeletedBy: contexts.GetUserId(ctx), c.UpdatedBy: contexts.GetUserId(ctx)}).Update()
return gerror.Wrap(e, "删除任务失败")
})
}