219 lines
9.8 KiB
Go
219 lines
9.8 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, pc := dao.Task.Columns(), dao.TaskHall.Columns(), dao.Product.Columns()
|
|
return s.Model(ctx).As("t").
|
|
LeftJoin(dao.TaskHall.Table()+" h", col("h", hc.Id)+"="+col("t", tc.HallId)).
|
|
LeftJoin(dao.Product.Table()+" p", col("p", pc.Id)+"="+col("t", tc.ProductId)).
|
|
Fields("t.*", fmt.Sprintf("COALESCE(%s,'') hall_name", col("h", hc.Name)), fmt.Sprintf("COALESCE(%s,'') product_name", col("p", pc.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("任务大厅不存在")
|
|
}
|
|
pc := dao.Product.Columns()
|
|
productCount, err := handler.Model(dao.Product.Ctx(ctx), &handler.Option{FilterTenant: true}).WherePri(in.ProductId).WhereIn(pc.PublishStatus, []int{consts.BizPublishPublished, consts.BizPublishOffline, consts.BizPublishDraft}).Count()
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
if productCount == 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.ProductId: in.ProductId, 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.ProductId, 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.ProductId: in.ProductId, 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, "productId": in.ProductId, "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, "删除任务失败")
|
|
})
|
|
}
|