Initial commit

This commit is contained in:
Donny
2019-04-22 20:46:32 +08:00
commit 49ab8aadd1
25441 changed files with 4055000 additions and 0 deletions

View File

@@ -0,0 +1,93 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"academy_test.go",
"whiteList_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/admin/main/creative/conf:go_default_library",
"//app/admin/main/creative/service:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"academy_archive.go",
"academy_occupation.go",
"academy_tag.go",
"app.go",
"csv.go",
"export.go",
"http.go",
"index.go",
"local.go",
"material.go",
"material_category.go",
"music.go",
"music_category.go",
"music_material.go",
"music_with_category.go",
"music_with_material.go",
"operCollectArc.go",
"task.go",
"upload.go",
"whitelist.go",
],
importpath = "go-common/app/admin/main/creative/http",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/creative/conf:go_default_library",
"//app/admin/main/creative/model/academy:go_default_library",
"//app/admin/main/creative/model/app:go_default_library",
"//app/admin/main/creative/model/logcli:go_default_library",
"//app/admin/main/creative/model/material:go_default_library",
"//app/admin/main/creative/model/music:go_default_library",
"//app/admin/main/creative/model/operation:go_default_library",
"//app/admin/main/creative/model/task:go_default_library",
"//app/admin/main/creative/model/whitelist:go_default_library",
"//app/admin/main/creative/service:go_default_library",
"//app/interface/openplatform/article/model:go_default_library",
"//app/service/main/account/api:go_default_library",
"//app/service/main/archive/api:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/binding:go_default_library",
"//library/net/http/blademaster/middleware/permit:go_default_library",
"//library/net/http/blademaster/render:go_default_library",
"//library/net/metadata:go_default_library",
"//library/sync/errgroup:go_default_library",
"//library/xstr:go_default_library",
"//vendor/github.com/davecgh/go-spew/spew:go_default_library",
"//vendor/github.com/jinzhu/gorm:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,977 @@
package http
import (
"context"
"fmt"
"math"
"net/http"
"strings"
"time"
"go-common/app/admin/main/creative/model/academy"
"go-common/app/interface/openplatform/article/model"
"go-common/app/service/main/archive/api"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/render"
"go-common/library/sync/errgroup"
"go-common/library/xstr"
"go-common/library/net/metadata"
"github.com/davecgh/go-spew/spew"
"github.com/jinzhu/gorm"
)
func addArc(c *bm.Context) {
var err error
v := new(struct {
OID int64 `form:"oid" validate:"required"`
Business int8 `form:"business"`
Comment string `form:"comment"`
CourseTID int64 `form:"course_tid" validate:"required"`
OperTID int64 `form:"oper_tid" validate:"required"`
ClassTID string `form:"class_tid" validate:"required"`
ArticleTID int64 `form:"article_tid"`
RecommendTID int64 `form:"recommend_tid" validate:"required"`
})
ip := metadata.String(c, metadata.RemoteIP)
if err = c.Bind(v); err != nil {
return
}
if v.OID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
if arc, err := checkExist(v.OID); err == nil && arc.OID != 0 {
c.JSON(nil, ecode.CreativeAcademyOIDExistErr)
return
}
uid, uname := getUIDName(c)
action := ""
if v.Business == academy.BusinessForArchvie {
action = "添加单个视频稿件"
} else if v.Business == academy.BusinessForArticle {
action = "添加单个专栏稿件"
}
svc.SendAcademyLog(c, &academy.LogParam{UID: uid, UName: uname, Action: action, OIDs: xstr.JoinInts([]int64{v.OID})})
c.JSON(nil, bulkInsertArcs(c, []int64{v.OID}, v.Business, v.CourseTID, v.OperTID, v.ArticleTID, v.RecommendTID, v.ClassTID, v.Comment, ip))
}
func upArcTag(c *bm.Context) {
var err error
v := new(struct {
OID int64 `form:"oid" validate:"required"`
Business int8 `form:"business"`
Comment string `form:"comment"`
CourseTID int64 `form:"course_tid" validate:"required"`
OperTID int64 `form:"oper_tid" validate:"required"`
ClassTID string `form:"class_tid" validate:"required"`
ArticleTID int64 `form:"article_tid"`
RecommendTID int64 `form:"recommend_tid" validate:"required"`
})
if err = c.Bind(v); err != nil {
return
}
if v.OID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
if _, err = checkExist(v.OID); err != nil {
c.JSON(nil, err)
return
}
uid, uname := getUIDName(c)
action := ""
if v.Business == academy.BusinessForArchvie {
action = "更新单个视频稿件"
} else if v.Business == academy.BusinessForArticle {
action = "更新单个专栏稿件"
}
svc.SendAcademyLog(c, &academy.LogParam{UID: uid, UName: uname, Action: action, OIDs: xstr.JoinInts([]int64{v.OID})})
c.JSON(nil, bulkUpdateArcs([]int64{v.OID}, v.Business, v.CourseTID, v.OperTID, v.ArticleTID, v.RecommendTID, v.ClassTID, v.Comment))
}
func removeArcTag(c *bm.Context) {
var err error
v := new(struct {
OID int64 `form:"oid" validate:"required"`
Business int8 `form:"business"`
})
if err = c.Bind(v); err != nil {
return
}
if v.OID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
if _, err = checkExist(v.OID); err != nil {
c.JSON(nil, err)
return
}
uid, uname := getUIDName(c)
action := ""
if v.Business == academy.BusinessForArchvie {
action = "移除单个视频稿件"
} else if v.Business == academy.BusinessForArticle {
action = "移除单个专栏稿件"
}
svc.SendAcademyLog(c, &academy.LogParam{UID: uid, UName: uname, Action: action, OIDs: xstr.JoinInts([]int64{v.OID})})
c.JSON(nil, bulkRemoveArcs([]int64{v.OID}, v.Business))
}
func viewArc(c *bm.Context) {
var err error
v := new(struct {
OID int64 `form:"oid"`
Business int8 `form:"business"`
})
if err = c.Bind(v); err != nil {
return
}
if v.OID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
if _, err = checkExist(v.OID); err != nil {
c.JSON(nil, err)
return
}
ap := &academy.EsParam{
OID: v.OID,
Business: v.Business,
State: academy.DefaultState,
Pn: 1,
Ps: 1,
IP: metadata.String(c, metadata.RemoteIP),
}
res, err := search(c, ap)
if err != nil {
c.JSON(nil, err)
return
}
if res == nil || len(res.Items) == 0 {
c.JSON(nil, ecode.NothingFound)
return
}
c.JSON(res.Items, nil)
}
func listArc(c *bm.Context) {
var (
err error
tids []int64
tidsMap map[int][]int64
)
v := new(struct {
OID int64 `form:"oid"`
Keyword string `form:"keyword"`
Uname string `form:"uname"`
Business int8 `form:"business"`
TID string `form:"tids"`
State int `form:"state" default:"2018"`
Copyright int `form:"copyright"`
Pn int `form:"pn" validate:"required,min=1"`
Ps int `form:"ps" validate:"required,min=1"`
})
if err = c.Bind(v); err != nil {
return
}
if v.Pn == 0 {
v.Pn = 1
}
if v.Ps > 20 {
v.Ps = 20
}
if v.TID != "" {
if tids, err = xstr.SplitInts(v.TID); err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", v.TID, err)
c.JSON(nil, ecode.RequestErr)
return
}
if len(tids) >= 0 {
tags, getMapErr := getTagParentChildMap()
if getMapErr != nil {
c.JSON(nil, getMapErr)
return
}
tidsMap = filterTIDs(tids, tags)
}
}
ap := &academy.EsParam{
OID: v.OID,
Keyword: v.Keyword,
Business: v.Business,
Uname: v.Uname,
TID: tids,
Copyright: v.Copyright,
State: v.State,
Pn: v.Pn,
Ps: v.Ps,
IP: metadata.String(c, metadata.RemoteIP),
TidsMap: tidsMap,
}
res, err := search(c, ap)
if err != nil {
c.JSON(nil, err)
return
}
c.Render(http.StatusOK, render.MapJSON(map[string]interface{}{
"code": 0,
"message": "0",
"data": res,
}))
}
func bindArcInfo(c context.Context, oids []int64, bs int8, ip string) (res map[int64]*academy.ArchiveMeta, err error) {
res = make(map[int64]*academy.ArchiveMeta)
if bs == academy.BusinessForArchvie {
arcs, err := svc.Archives(c, oids)
if err != nil {
return nil, err
}
stat, err := svc.Stats(c, oids, ip)
if err != nil {
log.Error("s.arc.Stats oids(%+v)|business(%d)|error(%v)", oids, bs, err)
return nil, err
}
for _, oid := range oids {
a := &academy.ArchiveMeta{}
if v, ok := arcs[oid]; ok && v != nil {
a.OID = oid
a.Title = v.Title
a.State = v.State
a.Type = v.TypeName
a.Cover = v.Pic
a.UName = v.Author.Name
if t, ok := stat[oid]; ok && t != nil {
a.Hot = countArcHot(t, int64(v.PubDate))
}
res[oid] = a
}
}
} else if bs == academy.BusinessForArticle {
arts, err := svc.Articles(c, oids)
if err != nil {
return nil, err
}
for _, oid := range oids {
if v, ok := arts[oid]; ok && v != nil {
a := &academy.ArchiveMeta{
OID: oid,
Title: v.Title,
State: v.State,
}
if v.Category != nil {
a.Type = v.Category.Name
}
if len(v.ImageURLs) > 0 {
a.Cover = v.ImageURLs[0]
}
if v.Author != nil {
a.UName = v.Author.Name
}
a.Hot = countArtHot(v)
res[oid] = a
}
}
}
return
}
func bindTags(oidTIDsMap map[int64][]int64) (res map[int64]map[int][]*academy.TagMeta, err error) {
res = make(map[int64]map[int][]*academy.TagMeta)
for oid, tids := range oidTIDsMap {
var tags []*academy.Tag
if err = svc.DB.Model(&academy.Tag{}).Where("id in (?)", tids).Find(&tags).Error; err != nil {
log.Error("creative-admin bindTags error(%v)", err)
return
}
oidTIDs := make(map[int][]*academy.TagMeta)
ctgs := make(map[int64][]*academy.TagMeta)
for _, v := range tags {
tg := renderTag(v)
switch tg.Type {
case academy.Course:
oidTIDs[academy.Course] = append(oidTIDs[academy.Course], tg)
case academy.Operation:
oidTIDs[academy.Operation] = append(oidTIDs[academy.Operation], tg)
case academy.Classify:
ctgs[tg.ParentID] = append(ctgs[tg.ParentID], tg)
case academy.ArticleClass:
oidTIDs[academy.ArticleClass] = append(oidTIDs[academy.ArticleClass], tg)
case academy.Recommend:
oidTIDs[academy.Recommend] = append(oidTIDs[academy.Recommend], tg)
}
}
for pid, tgs := range ctgs {
parent := &academy.Tag{}
if err = svc.DB.Model(&academy.Tag{}).Where("id = ?", pid).Find(parent).Error; err != nil {
log.Error("creative-admin bindTags get parent tag error(%v)", err)
continue
}
p := renderTag(parent)
p.Children = tgs
oidTIDs[academy.Classify] = append(oidTIDs[academy.Classify], p)
}
res[oid] = oidTIDs
}
return
}
func batchAddArc(c *bm.Context) {
var (
err error
oids, newOIDs, oldOIDs []int64
)
v := new(struct {
OIDs string `form:"oids" validate:"required"`
Business int8 `form:"business"`
Comment string `form:"comment"`
CourseTID int64 `form:"course_tid" validate:"required"`
OperTID int64 `form:"oper_tid" validate:"required"`
ClassTID string `form:"class_tid" validate:"required"`
ArticleTID int64 `form:"article_tid"`
RecommendTID int64 `form:"recommend_tid" validate:"required"`
})
ip := metadata.String(c, metadata.RemoteIP)
if err = c.Bind(v); err != nil {
return
}
if v.OIDs != "" {
if oids, err = xstr.SplitInts(v.OIDs); err != nil {
log.Error("batchAddArc xstr.SplitInts OIDs(%+v)|error(%v)", v.OIDs, err)
c.JSON(nil, ecode.RequestErr)
return
}
}
for _, oid := range oids {
if arc, err := checkExist(oid); err == nil && arc.OID != 0 { //表里已存在该稿件
oldOIDs = append(oldOIDs, oid)
} else {
newOIDs = append(newOIDs, oid)
}
}
if len(newOIDs) == 0 {
log.Error("batchAddArc oldOIDs(%+v)", oldOIDs)
c.JSON(nil, ecode.CreativeAcademyOIDExistErr)
return
}
uid, uname := getUIDName(c)
action := ""
if v.Business == academy.BusinessForArchvie {
action = "批量添加视频稿件"
} else if v.Business == academy.BusinessForArticle {
action = "批量添加专栏稿件"
}
svc.SendAcademyLog(c, &academy.LogParam{UID: uid, UName: uname, Action: action, OIDs: xstr.JoinInts(newOIDs)})
c.JSON(nil, bulkInsertArcs(c, newOIDs, v.Business, v.CourseTID, v.OperTID, v.ArticleTID, v.RecommendTID, v.ClassTID, v.Comment, ip))
}
//批量插入稿件表
func bulkInsertArcs(c *bm.Context, oids []int64, bs int8, courseTID, operTID, articleTID, recommendTID int64, classTID, comment, ip string) (err error) {
arcInfo, err := bindArcInfo(c, oids, bs, ip)
if err != nil {
return err
}
arcs := make([]*academy.Archive, 0, len(oids))
for _, oid := range oids {
a, ok := arcInfo[oid]
if !ok || a == nil { //校验oid是否有效
if bs == academy.BusinessForArchvie {
err = ecode.CreativeArcServiceErr
} else if bs == academy.BusinessForArticle {
err = ecode.CreativeArticleRPCErr
}
log.Error("bulkInsertArcs add archive with invalid oid(%d)|business(%d)", oid, bs)
return
}
arcs = append(arcs, setArcParam(oid, a.Hot, bs, comment))
}
valArcs := make([]string, 0, len(arcs))
valArcArgs := make([]interface{}, 0)
for _, v := range arcs {
valArcs = append(valArcs, "(?, ?, ?, ?, ?, ?, ?)")
valArcArgs = append(valArcArgs, v.OID, v.Hot, v.Business, v.State, v.Comment, v.CTime, v.MTime)
}
//批量插入稿件标签关联表
ctids, err := xstr.SplitInts(classTID)
if err != nil {
return
}
tags := make([]*academy.ArchiveTag, 0)
for _, oid := range oids {
tags = append(tags, setTagParam(oid, courseTID, bs), setTagParam(oid, operTID, bs), setTagParam(oid, recommendTID, bs))
for _, cid := range ctids { //分类标签支持绑定多个二级标签
tags = append(tags, setTagParam(oid, cid, bs))
}
if bs == academy.BusinessForArticle && articleTID > 0 { //专栏特殊分类
tags = append(tags, setTagParam(oid, articleTID, bs))
}
}
valTags := make([]string, 0)
valTagArgs := make([]interface{}, 0)
for _, v := range tags {
valTags = append(valTags, "(?, ?, ?, ?, ?, ?)")
valTagArgs = append(valTagArgs, v.OID, v.TID, v.State, v.CTime, v.MTime, v.Business)
}
sqlArcStr := fmt.Sprintf("INSERT INTO academy_archive (oid, hot, business, state, comment, ctime, mtime) VALUES %s ON DUPLICATE KEY UPDATE state=0, comment=VALUES(comment), mtime=VALUES(mtime)", strings.Join(valArcs, ","))
sqlTagStr := fmt.Sprintf("INSERT INTO academy_archive_tag (oid, tid, state, ctime, mtime, business) VALUES %s ON DUPLICATE KEY UPDATE state=0, mtime=VALUES(mtime)", strings.Join(valTags, ","))
tx := svc.DB.Begin()
if err = tx.Exec(sqlArcStr, valArcArgs...).Error; err != nil {
log.Error("creative-admin bulkInsertArcs error(%v)", err)
tx.Rollback()
return
}
if err = tx.Exec(sqlTagStr, valTagArgs...).Error; err != nil {
log.Error("creative-admin bulkInsertArcs error(%v)", err)
tx.Rollback()
return
}
tx.Commit()
return nil
}
func setArcParam(oid, hot int64, bs int8, comment string) (arc *academy.Archive) {
now := time.Now().Format("2006-01-02 15:04:05")
arc = &academy.Archive{
OID: oid,
Business: bs,
CTime: now,
MTime: now,
Comment: comment,
Hot: hot,
State: academy.StateNormal,
}
return
}
func setTagParam(oid, tid int64, bs int8) (res *academy.ArchiveTag) {
now := time.Now().Format("2006-01-02 15:04:05")
res = &academy.ArchiveTag{
OID: oid,
TID: tid,
CTime: now,
MTime: now,
Business: bs,
State: academy.StateNormal,
}
return
}
func batchUpArc(c *bm.Context) {
var (
err error
oids []int64
)
v := new(struct {
OIDs string `form:"oids" validate:"required"`
Business int8 `form:"business"`
Comment string `form:"comment"`
CourseTID int64 `form:"course_tid" validate:"required"`
OperTID int64 `form:"oper_tid" validate:"required"`
ClassTID string `form:"class_tid" validate:"required"`
ArticleTID int64 `form:"article_tid"`
RecommendTID int64 `form:"recommend_tid" validate:"required"`
})
if err = c.Bind(v); err != nil {
return
}
if v.OIDs != "" {
if oids, err = xstr.SplitInts(v.OIDs); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
}
for _, oid := range oids {
if _, err = checkExist(oid); err != nil {
c.JSON(nil, err)
return
}
}
uid, uname := getUIDName(c)
action := ""
if v.Business == academy.BusinessForArchvie {
action = "批量更新视频稿件"
} else if v.Business == academy.BusinessForArticle {
action = "批量更新专栏稿件"
}
svc.SendAcademyLog(c, &academy.LogParam{UID: uid, UName: uname, Action: action, OIDs: xstr.JoinInts(oids)})
c.JSON(nil, bulkUpdateArcs(oids, v.Business, v.CourseTID, v.OperTID, v.ArticleTID, v.RecommendTID, v.ClassTID, v.Comment))
}
func bulkUpdateArcs(oids []int64, bs int8, courseTID, operTID, articleTID, recommendTID int64, classTID, comment string) (err error) {
var (
tids []int64
arcTags []*academy.ArchiveTags
arcMapTids map[int64][]int64
delOIDTidsMap, newOIDTidsMap map[int64][]int64
)
//更新其他类别标签
var (
ats []*academy.ArchiveTags
ids []int64
)
if err = svc.DB.Raw("SELECT b.*, c.type FROM (SELECT t.id,t.tid,a.oid FROM academy_archive AS a LEFT JOIN academy_archive_tag AS t ON t.oid = a.oid WHERE a.oid IN (?) AND a.business=? AND a.state=0 AND t.state=0) b LEFT JOIN academy_tag AS c ON c.id=b.tid WHERE c.type!=?", oids, bs, academy.Classify).Find(&ats).Error; err != nil {
log.Error("creative-admin bulkUpdateArcs get all archive tags error(%v)", err)
return
}
if len(ats) == 0 {
return
}
ids = make([]int64, 0, len(ats))
for _, a := range ats {
if a == nil {
log.Error("creative-admin bulkUpdateArcs update other tags get nil a(%+v)", a)
return
}
ids = append(ids, a.ID)
}
tx := svc.DB.Begin()
// 对于提交上来的其他标签先统一删除再统一插入
if err = tx.Model(&academy.ArchiveTag{}).Where("id IN (?)", ids).
Updates(map[string]interface{}{
"state": academy.StateRemove,
}).Error; err != nil {
log.Error("bulkUpdateArcs first delete other tags by ids(%v)|error(%v)", ids, err)
tx.Rollback()
return
}
tags := make([]*academy.ArchiveTag, 0)
for _, oid := range oids {
tags = append(tags, setTagParam(oid, courseTID, bs), setTagParam(oid, operTID, bs), setTagParam(oid, recommendTID, bs))
if bs == academy.BusinessForArticle && articleTID > 0 { //专栏特殊分类
tags = append(tags, setTagParam(oid, articleTID, bs))
}
}
valTags := make([]string, 0)
valTagArgs := make([]interface{}, 0)
for _, v := range tags {
valTags = append(valTags, "(?, ?, ?, ?, ?, ?)")
valTagArgs = append(valTagArgs, v.OID, v.TID, v.State, v.CTime, v.MTime, v.Business)
}
sqlTagStr := fmt.Sprintf("INSERT INTO academy_archive_tag (oid, tid, state, ctime, mtime, business) VALUES %s ON DUPLICATE KEY UPDATE state=0,oid=VALUES(oid),tid=VALUES(tid),business=VALUES(business)", strings.Join(valTags, ","))
if err = tx.Exec(sqlTagStr, valTagArgs...).Error; err != nil {
log.Error("bulkUpdateArcs update other tags valTagArgs(%+v)", valTagArgs...)
tx.Rollback()
return
}
//处理分类标签
tids, err = xstr.SplitInts(classTID)
if err != nil {
return err
}
if err = svc.DB.Raw("SELECT b.*, c.type FROM (SELECT t.id,t.tid,a.oid FROM academy_archive AS a LEFT JOIN academy_archive_tag AS t ON t.oid = a.oid WHERE a.oid IN (?) AND a.business=? AND a.state=0 AND t.state=0) b LEFT JOIN academy_tag AS c ON c.id=b.tid WHERE c.type=?", oids, bs, academy.Classify).Find(&arcTags).Error; err != nil {
log.Error("creative-admin bulkUpdateArcs archive class tags error(%v)", err)
return
}
arcMapTids = make(map[int64][]int64)
for _, v := range arcTags {
arcMapTids[v.OID] = append(arcMapTids[v.OID], v.TID)
}
newOIDTidsMap = make(map[int64][]int64)
delOIDTidsMap = make(map[int64][]int64)
for oid, ids := range arcMapTids {
isInDB := make(map[int64]int64)
for _, id := range ids {
isInDB[id] = id
}
log.Info("creative-admin bulkUpdateArcs oid(%d)|isInDB(%+v)", oid, isInDB)
isInSub := make(map[int64]int64)
for _, tid := range tids {
isInSub[tid] = tid
if _, ok := isInDB[tid]; !ok {
newOIDTidsMap[oid] = append(newOIDTidsMap[oid], tid)
}
}
log.Info("creative-admin bulkUpdateArcs oid(%d)|isInSubmit(%+v)", oid, isInSub)
for _, id := range ids {
if _, ok := isInSub[id]; !ok {
delOIDTidsMap[oid] = append(delOIDTidsMap[oid], id)
}
}
}
if len(newOIDTidsMap) > 0 { //insert on update
tags := make([]*academy.ArchiveTag, 0)
for oid, tgs := range newOIDTidsMap { //分类标签支持绑定多个二级标签
for _, cid := range tgs {
tags = append(tags, setTagParam(oid, cid, bs))
}
}
valTags := make([]string, 0)
valTagArgs := make([]interface{}, 0)
for _, v := range tags {
valTags = append(valTags, "(?, ?, ?, ?, ?, ?)")
valTagArgs = append(valTagArgs, v.OID, v.TID, v.State, v.CTime, v.MTime, v.Business)
}
sqlTagStr := fmt.Sprintf("INSERT INTO academy_archive_tag (oid, tid, state, ctime, mtime, business) VALUES %s ON DUPLICATE KEY UPDATE state=0, oid=VALUES(oid), tid=VALUES(tid), business=VALUES(business), mtime=VALUES(mtime)", strings.Join(valTags, ","))
if err = tx.Exec(sqlTagStr, valTagArgs...).Error; err != nil {
log.Error("creative-admin bulkUpdateArcs insert new class tags error(%v)", err)
tx.Rollback()
return
}
}
if len(delOIDTidsMap) > 0 { //delete
delMapID := make(map[int64]int64)
for _, tgs := range delOIDTidsMap {
for _, tid := range tgs {
delMapID[tid] = tid
}
}
delIDs := make([]int64, 0)
for _, a := range arcTags {
if _, ok := delMapID[a.TID]; ok {
delIDs = append(delIDs, a.ID)
}
}
if err = tx.Model(&academy.ArchiveTag{}).Where("id IN (?)", delIDs).
Updates(map[string]interface{}{
"state": academy.StateRemove,
"mtime": time.Now().Format("2006-01-02 15:04:05"),
}).Error; err != nil {
log.Error("creative-admin bulkUpdateArcs delete class tags by ids(%v)|error(%v)", delIDs, err)
tx.Rollback()
return
}
}
// 统一更新comment
if err = tx.Model(&academy.Archive{}).Where("business = ?", bs).Where("oid IN (?)", oids).
Updates(map[string]interface{}{
"comment": comment,
"mtime": time.Now().Format("2006-01-02 15:04:05"),
}).Error; err != nil {
log.Error("creative-admin bulkUpdateArcs update all comment error(%v)", err)
tx.Rollback()
return
}
tx.Commit()
return
}
func batchRemoveArc(c *bm.Context) {
var (
err error
oids []int64
)
v := new(struct {
OIDs string `form:"oids" validate:"required"`
Business int8 `form:"business"`
})
if err = c.Bind(v); err != nil {
return
}
if v.OIDs != "" {
if oids, err = xstr.SplitInts(v.OIDs); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
}
for _, oid := range oids {
if _, err = checkExist(oid); err != nil {
c.JSON(nil, err)
return
}
}
uid, uname := getUIDName(c)
action := ""
if v.Business == academy.BusinessForArchvie {
action = "批量移除视频稿件"
} else if v.Business == academy.BusinessForArticle {
action = "批量移除专栏稿件"
}
svc.SendAcademyLog(c, &academy.LogParam{UID: uid, UName: uname, Action: action, OIDs: xstr.JoinInts(oids)})
c.JSON(nil, bulkRemoveArcs(oids, v.Business))
}
func bulkRemoveArcs(oids []int64, bs int8) (err error) {
var (
db *gorm.DB
now = time.Now().Format("2006-01-02 15:04:05")
ats []*academy.ArchiveTags
IDs []int64
)
db = svc.DB.Raw("SELECT t.id,t.tid,a.oid,a.business FROM academy_archive AS a LEFT JOIN academy_archive_tag AS t ON t.oid = a.oid WHERE a.oid IN (?) AND a.business=?", oids, bs)
if err = db.Find(&ats).Error; err != nil {
log.Error("creative-admin bulkRemoveArcs error(%v)", err)
return
}
if len(ats) == 0 {
return
}
for _, a := range ats {
IDs = append(IDs, a.ID)
}
tx := svc.DB.Begin()
if err = tx.Model(&academy.Archive{}).Where("oid IN (?) AND business=?", oids, bs).Updates(map[string]interface{}{
"mtime": now,
"state": academy.StateRemove,
}).Error; err != nil {
log.Error("creative-admin bulkRemoveArcs error(%v)", err)
tx.Rollback()
return
}
if err = tx.Model(&academy.ArchiveTag{}).Where("id IN (?)", IDs).Updates(map[string]interface{}{
"mtime": now,
"state": academy.StateRemove,
}).Error; err != nil {
tx.Rollback()
log.Error("creative-admin bulkRemoveArcs error(%v)", err)
return
}
tx.Commit()
return
}
func arcCountByTids(tids []int64) (res map[int64]int, err error) {
var (
countSQL = "SELECT tid, count(DISTINCT oid) AS count FROM academy_archive_tag WHERE state=0 AND tid IN (?) GROUP BY tid"
ats []*academy.ArchiveCount
)
if err = svc.DB.Raw(countSQL, tids).Find(&ats).Error; err != nil {
log.Error("creative-admin get arcCountByTids error(%v)", err)
return
}
if len(ats) == 0 {
return
}
res = make(map[int64]int)
for _, a := range ats {
res[a.TID] = a.Count
}
return
}
func checkExist(oid int64) (arc *academy.Archive, err error) {
arc = &academy.Archive{}
err = svc.DB.Model(&academy.Archive{}).Where("state=?", academy.StateNormal).Where("oid=?", oid).Find(arc).Error
if err != nil {
if err != gorm.ErrRecordNotFound {
log.Error("creative-admin checkExist oid(%d)|error(%v)", oid, err)
}
}
return
}
func fixArchive(c *bm.Context) {
var err error
v := new(struct {
ID int64 `form:"id"`
OID int64 `form:"oid"`
Business int8 `form:"business"`
State int8 `form:"state"`
})
if err = c.Bind(v); err != nil {
return
}
if err = svc.DB.Model(&academy.Archive{}).Where("id=?", v.ID).Updates(map[string]interface{}{
"oid": v.OID,
"business": v.Business,
"state": v.State,
"mtime": time.Now().Format("2006-01-02 15:04:05"),
}).Error; err != nil {
log.Error("creative-admin fixArchive error(%v)", err)
}
c.JSON(nil, err)
}
func search(c *bm.Context, ap *academy.EsParam) (res *academy.Archives, err error) {
var (
oids []int64
tempMapTIDs map[int64][]int64
arcs []*academy.ArchiveOrigin
items []*academy.ArchiveMeta
com = make(map[int64]string)
)
res = &academy.Archives{
Items: []*academy.ArchiveMeta{},
Pager: &academy.Pager{},
}
sear, err := svc.ArchivesWithES(c, ap)
if err != nil {
log.Error("search svc.ArchivesWithES error(%v)", err)
return
}
arcs = make([]*academy.ArchiveOrigin, 0)
if sear == nil || len(sear.Result) == 0 {
return
}
tempMapTIDs = make(map[int64][]int64)
for _, v := range sear.Result {
oids = append(oids, v.OID)
tempMapTIDs[v.OID] = v.TID
}
res.Pager.Total = sear.Page.Total
res.Pager.Num = sear.Page.Num
res.Pager.Size = sear.Page.Size
g, _ := errgroup.WithContext(c)
var (
arcInfo map[int64]*academy.ArchiveMeta
tagInfo map[int64]map[int][]*academy.TagMeta
bindMapTIDs map[int64][]int64
)
bindMapTIDs = make(map[int64][]int64)
for _, oid := range oids {
if v, ok := tempMapTIDs[oid]; ok {
bindMapTIDs[oid] = v
}
}
g.Go(func() error {
arcInfo, err = bindArcInfo(c, oids, ap.Business, metadata.String(c, metadata.RemoteIP))
return err
})
g.Go(func() error {
com, err = bindArcComment(oids, ap.Business)
return err
})
g.Go(func() error {
tagInfo, err = bindTags(bindMapTIDs)
return err
})
if err = g.Wait(); err != nil {
return
}
log.Info("search arcInfo(%s)", spew.Sdump(arcInfo))
items = make([]*academy.ArchiveMeta, 0, len(arcs))
for _, oid := range oids {
a, ok := arcInfo[oid]
if !ok || a == nil {
log.Error("search get archive info error by oid(%d)", oid)
return
}
if v, ok := tagInfo[oid]; ok {
a.Tags = v
}
if co, ok := com[oid]; ok {
a.Comment = co
}
items = append(items, a)
}
res.Items = items
return
}
func bindArcComment(oids []int64, bs int8) (res map[int64]string, err error) {
var arcs []*academy.Archive
if err = svc.DB.Model(&academy.Archive{}).Where("oid in(?)", oids).Where("business=?", bs).Group("oid").Find(&arcs).Error; err != nil {
log.Error("bindArcComment d.DB.Model oids(%+v)|business(%d)|error(%v)", oids, bs, err)
return
}
res = make(map[int64]string)
for _, v := range arcs {
res[v.OID] = v.Comment
}
return
}
//countArcHot 视频=硬币*0.4+收藏*0.3+弹幕*0.4+评论*0.4+播放*0.25+点赞*0.4+分享*0.6 最新视频(一天内发布)提权[总值*1.5]
func countArcHot(t *api.Stat, ptime int64) int64 {
if t == nil {
return 0
}
hot := float64(t.Coin)*0.4 +
float64(t.Fav)*0.3 +
float64(t.Danmaku)*0.4 +
float64(t.Reply)*0.4 +
float64(t.View)*0.25 +
float64(t.Like)*0.4 +
float64(t.Share)*0.6
if ptime >= time.Now().AddDate(0, 0, -1).Unix() && ptime <= time.Now().Unix() {
hot *= 1.5
}
return int64(math.Floor(hot))
}
// countArtHot 专栏=硬币*0.4+收藏*0.3+评论*0.4+阅读*0.25+点赞*0.4+分享*0.6 最新专栏(一天内发布)提权[总值*1.5]
func countArtHot(t *model.Meta) int64 {
if t.Stats == nil {
return 0
}
hot := float64(t.Stats.Coin)*0.4 +
float64(t.Stats.Favorite)*0.3 +
float64(t.Stats.Reply)*0.4 +
float64(t.Stats.View)*0.25 +
float64(t.Stats.Like)*0.4 +
float64(t.Stats.Share)*0.6
if int64(t.PublishTime) >= time.Now().AddDate(0, 0, -1).Unix() && int64(t.PublishTime) <= time.Now().Unix() {
hot *= 1.5
}
return int64(math.Floor(hot))
}
// getParentChildMap
func getTagParentChildMap() (res map[int64]*academy.Tag, err error) {
var (
db *gorm.DB
tags []*academy.Tag
)
db = svc.DB.Order("rank ASC").Find(&tags)
if err = db.Error; err != nil {
log.Error("creative-admin getTagParentChildMap error(%v)", err)
return
}
res = make(map[int64]*academy.Tag)
for _, t := range tags {
res[t.ID] = t
}
for _, v := range res {
if v == nil {
continue
}
if v.ParentID == 0 {
for _, t := range tags {
if t == nil {
continue
}
if t.ParentID == v.ID {
v.Children = append(v.Children, t)
}
}
}
}
return
}
// filterTIDs
func filterTIDs(tids []int64, parentChildMap map[int64]*academy.Tag) (res map[int][]int64) {
if len(tids) == 0 {
return
}
log.Info("s.filterTIDs origin tids(%+v)", tids)
res = make(map[int][]int64)
ochs := make([]int64, 0) //原始提交的二级标签
ops := make([]int64, 0) //原始提交的一级标签
qchs := make([]int64, 0) //通过一级标签查询出来的二级标签
for _, id := range tids {
t, ok := parentChildMap[id]
if !ok || t == nil {
continue
}
if t.Type == academy.Classify {
if t.ParentID != 0 { //原始提交的二级标签
ochs = append(ochs, id)
} else if t.ParentID == 0 && len(t.Children) > 0 { //通过一级标签查询出来的二级标签
for _, v := range t.Children {
qchs = append(qchs, v.ID)
}
} else if t.ParentID == 0 && len(t.Children) == 0 {
ops = append(ops, id)
}
} else {
res[int(t.Type)] = append(res[int(t.Type)], id)
}
}
if len(ochs) > 0 { //如果分类标签中提交了原始的二级标签则认为按该二级标签进行筛选,如果可以查询到二级标签认为筛选全部二级,否则一级参与查询.
res[academy.Classify] = ochs
} else if len(qchs) > 0 {
res[academy.Classify] = qchs
} else if len(ops) > 0 {
res[academy.Classify] = ops
}
log.Info("s.filterTIDs res(%s)", spew.Sdump(res))
return
}

View File

@@ -0,0 +1,775 @@
package http
import (
"encoding/json"
"io/ioutil"
"net/http"
"time"
"go-common/app/admin/main/creative/model/academy"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/binding"
"go-common/library/net/http/blademaster/render"
"go-common/library/sync/errgroup"
"go-common/library/xstr"
"github.com/jinzhu/gorm"
)
func addOccupation(c *bm.Context) {
var (
err error
now = time.Now().Format("2006-01-02 15:04:05")
)
v := new(academy.Occupation)
if err = c.Bind(v); err != nil {
log.Error("addOccupation c.Bind error(%v)", err)
return
}
m := &academy.Occupation{
State: academy.StateNormal,
Name: v.Name,
Desc: v.Desc,
Logo: v.Logo,
MainStep: v.MainStep,
MainSoftware: v.MainSoftware,
CTime: now,
MTime: now,
}
tx := svc.DB.Begin()
if err = tx.Create(m).Error; err != nil {
log.Error("academy addOccupation error(%v)", err)
c.JSON(nil, err)
tx.Rollback()
return
}
if err = tx.Model(&academy.Occupation{}).Where("id=?", m.ID).Updates(map[string]interface{}{
"rank": m.ID,
}).Error; err != nil {
log.Error("academy addOccupation error(%v)", err)
tx.Rollback()
}
tx.Commit()
uid, uname := getUIDName(c)
svc.SendAcademyLog(c, &academy.LogParam{UID: uid, UName: uname, Action: "添加职业", TID: m.ID, OName: m.Name})
c.JSON(map[string]interface{}{
"id": m.ID,
}, nil)
}
func upOccupation(c *bm.Context) {
var (
oc = &academy.Occupation{}
err error
)
v := new(academy.Occupation)
if err = c.Bind(v); err != nil {
return
}
if v.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
if err = svc.DB.Where("id=?", v.ID).Find(oc).Error; err != nil {
c.JSON(nil, err)
return
}
if oc == nil {
c.JSON(nil, ecode.NothingFound)
return
}
if err = svc.DB.Model(&academy.Occupation{}).Where("id=?", v.ID).Updates(map[string]interface{}{
"name": v.Name,
"desc": v.Desc,
"logo": v.Logo,
"main_step": v.MainStep,
"main_software": v.MainSoftware,
}).Error; err != nil {
log.Error("academy bindOccupation error(%v)", err)
}
uid, uname := getUIDName(c)
svc.SendAcademyLog(c, &academy.LogParam{UID: uid, UName: uname, Action: "更新职业", TID: v.ID, OName: v.Name})
c.JSON(nil, err)
}
func bindOccupation(c *bm.Context) {
var (
oc = &academy.Occupation{}
err error
)
v := new(academy.Occupation)
if err = c.Bind(v); err != nil {
return
}
if v.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
if err = svc.DB.Where("id=?", v.ID).Find(oc).Error; err != nil {
c.JSON(nil, err)
return
}
if oc == nil {
c.JSON(nil, ecode.NothingFound)
return
}
if err = svc.DB.Model(&academy.Occupation{}).Where("id=?", v.ID).Updates(map[string]interface{}{
"state": v.State,
}).Error; err != nil {
log.Error("academy upOccupation error(%v)", err)
}
uid, uname := getUIDName(c)
svc.SendAcademyLog(c, &academy.LogParam{UID: uid, UName: uname, Action: "更新职业", TID: v.ID, OName: v.Name})
c.JSON(nil, err)
}
func addSkill(c *bm.Context) {
var (
err error
now = time.Now().Format("2006-01-02 15:04:05")
)
v := new(academy.Skill)
if err = c.Bind(v); err != nil {
log.Error("addSkill c.Bind error(%v)", err)
return
}
m := &academy.Skill{
State: academy.StateNormal,
OID: v.OID,
Name: v.Name,
Desc: v.Desc,
CTime: now,
MTime: now,
}
if err = svc.DB.Create(m).Error; err != nil {
log.Error("academy addSkill error(%v)", err)
c.JSON(nil, err)
return
}
uid, uname := getUIDName(c)
svc.SendAcademyLog(c, &academy.LogParam{UID: uid, UName: uname, Action: "添加步骤", TID: m.ID, OName: m.Name})
c.JSON(map[string]interface{}{
"id": m.ID,
}, nil)
}
func upSkill(c *bm.Context) {
var (
sk = &academy.Skill{}
err error
)
v := new(academy.Skill)
if err = c.Bind(v); err != nil {
return
}
if v.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
if err = svc.DB.Where("id=?", v.ID).Find(sk).Error; err != nil {
c.JSON(nil, err)
return
}
if sk == nil {
c.JSON(nil, ecode.NothingFound)
return
}
if err = svc.DB.Model(&academy.Skill{}).Where("id=?", v.ID).Updates(map[string]interface{}{
"name": v.Name,
"desc": v.Desc,
}).Error; err != nil {
log.Error("academy upSkill error(%v)", err)
}
uid, uname := getUIDName(c)
svc.SendAcademyLog(c, &academy.LogParam{UID: uid, UName: uname, Action: "更新步骤", TID: v.ID, OName: v.Name})
c.JSON(nil, err)
}
func bindSkill(c *bm.Context) {
var (
oc = &academy.Skill{}
err error
)
v := new(academy.Skill)
if err = c.Bind(v); err != nil {
return
}
if v.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
if err = svc.DB.Where("id=?", v.ID).Find(oc).Error; err != nil {
c.JSON(nil, err)
return
}
if oc == nil {
c.JSON(nil, ecode.NothingFound)
return
}
if err = svc.DB.Model(&academy.Skill{}).Where("id=?", v.ID).Updates(map[string]interface{}{
"state": v.State,
}).Error; err != nil {
log.Error("academy bindSkill error(%v)", err)
}
uid, uname := getUIDName(c)
svc.SendAcademyLog(c, &academy.LogParam{UID: uid, UName: uname, Action: "更新职业", TID: v.ID, OName: v.Name})
c.JSON(nil, err)
}
func addSoftware(c *bm.Context) {
var (
err error
now = time.Now().Format("2006-01-02 15:04:05")
)
v := new(academy.Software)
if err = c.Bind(v); err != nil {
return
}
m := &academy.Software{
State: academy.StateNormal,
SkID: v.SkID,
Name: v.Name,
Desc: v.Desc,
CTime: now,
MTime: now,
}
if err = svc.DB.Create(m).Error; err != nil {
log.Error("academy addSoftware error(%v)", err)
c.JSON(nil, err)
return
}
uid, uname := getUIDName(c)
svc.SendAcademyLog(c, &academy.LogParam{UID: uid, UName: uname, Action: "添加步骤", TID: m.ID, OName: m.Name})
c.JSON(map[string]interface{}{
"id": m.ID,
}, nil)
}
func upSoftware(c *bm.Context) {
var (
oc = &academy.Software{}
err error
)
v := new(academy.Software)
if err = c.Bind(v); err != nil {
return
}
if v.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
if err = svc.DB.Where("id=?", v.ID).Find(oc).Error; err != nil {
c.JSON(nil, err)
return
}
if oc == nil {
c.JSON(nil, ecode.NothingFound)
return
}
if err = svc.DB.Model(&academy.Software{}).Where("id=?", v.ID).Updates(map[string]interface{}{
"name": v.Name,
"desc": v.Desc,
}).Error; err != nil {
log.Error("academy upSoftware error(%v)", err)
}
uid, uname := getUIDName(c)
svc.SendAcademyLog(c, &academy.LogParam{UID: uid, UName: uname, Action: "更新步骤", TID: v.ID, OName: v.Name})
c.JSON(nil, err)
}
func bindSoftware(c *bm.Context) {
var (
oc = &academy.Software{}
err error
)
v := new(academy.Software)
if err = c.Bind(v); err != nil {
return
}
if v.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
if err = svc.DB.Where("id=?", v.ID).Find(oc).Error; err != nil {
c.JSON(nil, err)
return
}
if oc == nil {
c.JSON(nil, ecode.NothingFound)
return
}
if err = svc.DB.Model(&academy.Software{}).Where("id=?", v.ID).Updates(map[string]interface{}{
"state": v.State,
}).Error; err != nil {
log.Error("academy bindSoftware error(%v)", err)
}
uid, uname := getUIDName(c)
svc.SendAcademyLog(c, &academy.LogParam{UID: uid, UName: uname, Action: "更新职业", TID: v.ID, OName: v.Name})
c.JSON(nil, err)
}
func listOccupation(c *bm.Context) {
var (
ocs []*academy.Occupation
sks []*academy.Skill
sfs []*academy.Software
sfMap map[int64][]*academy.Software
skMap map[int64][]*academy.Skill
sfIDs, skIDs, oIDs []int64
softMap, skillMap, occMap map[int64]int
g, _ = errgroup.WithContext(c)
err error
)
g.Go(func() error { //软件
if err = svc.DB.Find(&sfs).Error; err != nil {
log.Error("listSoftware error(%v)", err)
return err
}
if len(sfs) == 0 {
return nil
}
sfMap = make(map[int64][]*academy.Software)
sfIDs = make([]int64, 0, len(sfs))
for _, v := range sfs {
sfMap[v.SkID] = append(sfMap[v.SkID], v) //按技能聚合软件
sfIDs = append(sfIDs, v.ID)
}
softMap, _ = arcCountBySids(sfIDs) //获取软件对应稿件数量
if len(softMap) == 0 {
return nil
}
for _, v := range sfs {
if n, ok := softMap[v.ID]; ok { //映射软件对应稿件数量
v.Count = n
}
}
return nil
})
g.Go(func() error { //技能
if err = svc.DB.Find(&sks).Error; err != nil {
log.Error("listSkill error(%v)", err)
return err
}
if len(sks) == 0 {
return nil
}
skMap = make(map[int64][]*academy.Skill)
skIDs = make([]int64, 0, len(sks))
for _, v := range sks {
skMap[v.OID] = append(skMap[v.OID], v) //按职业聚合技能
skIDs = append(skIDs, v.ID)
}
skillMap, _ = arcCountBySkids(skIDs) //获取技能对应稿件数量
return nil
})
g.Go(func() error { //职业
if err = svc.DB.Order("rank ASC").Find(&ocs).Error; err != nil {
log.Error("listOccupation error(%v)", err)
return err
}
if len(ocs) == 0 {
return nil
}
oIDs = make([]int64, 0, len(ocs))
for _, v := range ocs {
oIDs = append(oIDs, v.ID)
}
occMap, _ = arcCountByPids(oIDs) //获取职业对应稿件数量
return nil
})
if err = g.Wait(); err != nil {
c.JSON(nil, err)
return
}
for _, v := range sks {
if sf, ok := sfMap[v.ID]; ok { //添加软件节点
v.Software = sf
}
if n, ok := skillMap[v.ID]; ok { //映射技能对应稿件数量
v.Count = n
}
}
for _, v := range ocs {
if sk, ok := skMap[v.ID]; ok { //添加技能节点
v.Skill = sk
}
if n, ok := occMap[v.ID]; ok { //映射职业对应稿件数量
v.Count = n
}
}
c.Render(http.StatusOK, render.MapJSON(map[string]interface{}{
"code": 0,
"message": "0",
"data": ocs,
}))
}
func arcCountByPids(tids []int64) (res map[int64]int, err error) {
var (
countSQL = "SELECT pid AS tid, count(DISTINCT aid) AS count FROM academy_arc_skill WHERE state=0 AND pid IN (?) GROUP BY pid"
ats []*academy.ArchiveCount
)
if err = svc.DB.Raw(countSQL, tids).Find(&ats).Error; err != nil {
log.Error("occupation arcCountByPids error(%v)", err)
return
}
if len(ats) == 0 {
return
}
res = make(map[int64]int)
for _, a := range ats {
res[a.TID] = a.Count
}
return
}
func arcCountBySkids(tids []int64) (res map[int64]int, err error) {
var (
countSQL = "SELECT skid AS tid, count(DISTINCT aid) AS count FROM academy_arc_skill WHERE state=0 AND skid IN (?) GROUP BY skid"
ats []*academy.ArchiveCount
)
if err = svc.DB.Raw(countSQL, tids).Find(&ats).Error; err != nil {
log.Error("skill arcCountByPids error(%v)", err)
return
}
if len(ats) == 0 {
return
}
res = make(map[int64]int)
for _, a := range ats {
res[a.TID] = a.Count
}
return
}
func arcCountBySids(tids []int64) (res map[int64]int, err error) {
var (
countSQL = "SELECT sid AS tid, count(DISTINCT aid) AS count FROM academy_arc_skill WHERE state=0 AND sid IN (?) GROUP BY sid"
ats []*academy.ArchiveCount
)
if err = svc.DB.Raw(countSQL, tids).Find(&ats).Error; err != nil {
log.Error("software arcCountBySids error(%v)", err)
return
}
if len(ats) == 0 {
return
}
res = make(map[int64]int)
for _, a := range ats {
res[a.TID] = a.Count
}
return
}
func orderOccupation(c *bm.Context) {
var err error
v := new(struct {
ID int64 `form:"id" validate:"required"`
Rank int64 `form:"rank" validate:"required"`
SwitchID int64 `form:"switch_id" validate:"required"`
SwitchRank int64 `form:"switch_rank" validate:"required"`
})
if err = c.BindWith(v, binding.Form); err != nil {
return
}
tx := svc.DB.Begin()
var oc academy.Occupation
if err = tx.Where("id=?", v.ID).First(&oc).Error; err != nil {
log.Error("academy orderOccupation error(%v)", err)
c.JSON(nil, err)
tx.Rollback()
return
}
var soc academy.Occupation
if err = tx.Where("id=?", v.SwitchID).First(&soc).Error; err != nil {
log.Error("academy orderOccupation error(%v)", err)
c.JSON(nil, err)
tx.Rollback()
return
}
if err = tx.Model(&academy.Occupation{}).Where("id=?", v.ID).Updates(
map[string]interface{}{
"rank": v.SwitchRank,
},
).Error; err != nil {
log.Error("academy orderOccupation error(%v)", err)
c.JSON(nil, err)
tx.Rollback()
return
}
if err = tx.Model(&academy.Occupation{}).Where("id=?", v.SwitchID).Updates(
map[string]interface{}{
"rank": v.Rank,
},
).Error; err != nil {
log.Error("academy orderOccupation error(%v)", err)
c.JSON(nil, err)
tx.Rollback()
return
}
tx.Commit()
uid, uname := getUIDName(c)
svc.SendAcademyLog(c, &academy.LogParam{UID: uid, UName: uname, Action: "更新职业排序", TID: v.ID, OName: ""})
c.JSON(nil, err)
}
func checkSkillArcExist(aid, sid int64) (res *academy.ArcSkill, err error) {
var as academy.ArcSkill
err = svc.DB.Where("aid=?", aid).Where("sid=?", sid).Find(&as).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
err = nil
}
log.Error("academy checkSkillArcExist aid(%d)|sid(%d)|error(%v)", aid, sid, err)
}
res = &as
return
}
func viewSkillArc(c *bm.Context) {
var (
err error
as = &academy.ArcSkill{}
)
v := new(academy.ArcSkill)
if err = c.Bind(v); err != nil {
return
}
if v.AID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
arc, err := svc.Archive(c, v.AID)
if err != nil {
c.JSON(nil, err)
return
}
if arc != nil {
as.AID = v.AID
as.Title = arc.Title
as.Pic = arc.Pic
}
c.Render(http.StatusOK, render.MapJSON(map[string]interface{}{
"code": 0,
"message": "0",
"data": as,
}))
}
func addSkillArc(c *bm.Context) {
var (
err error
now = time.Now().Format("2006-01-02 15:04:05")
)
v := new(academy.ArcSkill)
if err = c.Bind(v); err != nil {
return
}
if v.AID == 0 || v.PID == 0 || v.SkID == 0 || v.SID == 0 || v.Type == 0 {
log.Error("academy addSkillArc v(%+v)", v)
c.JSON(nil, ecode.RequestErr)
return
}
res, err := checkSkillArcExist(v.AID, v.SID)
if err != nil {
c.JSON(nil, err)
return
}
if res != nil && res.ID != 0 {
c.JSON(nil, ecode.CreativeAcademyDuplicateSoftIDErr)
return
}
m := &academy.ArcSkill{
State: academy.StateNormal,
AID: v.AID,
Type: v.Type,
PID: v.PID,
SkID: v.SkID,
SID: v.SID,
CTime: now,
MTime: now,
}
if err = svc.DB.Create(m).Error; err != nil {
log.Error("academy addSoftware error(%v)", err)
c.JSON(nil, err)
return
}
uid, uname := getUIDName(c)
svc.SendAcademyLog(c, &academy.LogParam{UID: uid, UName: uname, Action: "添加技能稿件", OIDs: xstr.JoinInts([]int64{v.AID})})
c.JSON(nil, err)
}
func upSkillArc(c *bm.Context) {
var err error
v := new(academy.ArcSkill)
if err = c.Bind(v); err != nil {
return
}
if v.ID == 0 || v.AID == 0 || v.PID == 0 || v.SkID == 0 || v.SID == 0 || v.Type == 0 {
log.Error("academy upSkillArc v(%+v)", v)
c.JSON(nil, ecode.RequestErr)
return
}
if err = svc.DB.Model(&academy.ArcSkill{}).Where("id=?", v.ID).Updates(map[string]interface{}{
"aid": v.AID,
"type": v.Type,
"pid": v.PID,
"skid": v.SkID,
"sid": v.SID,
}).Error; err != nil {
log.Error("academy upSkillArc error(%v)", err)
}
uid, uname := getUIDName(c)
svc.SendAcademyLog(c, &academy.LogParam{UID: uid, UName: uname, Action: "更新技能稿件", OIDs: xstr.JoinInts([]int64{v.AID})})
c.JSON(nil, err)
}
func bindSkillArc(c *bm.Context) {
var err error
v := new(academy.ArcSkill)
if err = c.Bind(v); err != nil {
return
}
if v.AID == 0 || v.SID == 0 {
log.Error("academy bindSkillArc v(%+v)", v)
c.JSON(nil, ecode.RequestErr)
return
}
res, err := checkSkillArcExist(v.AID, v.SID)
if err != nil {
c.JSON(nil, err)
return
}
if res != nil && res.ID == 0 {
c.JSON(nil, ecode.NothingFound)
return
}
if err = svc.DB.Model(&academy.ArcSkill{}).Where("aid=?", v.AID).Where("sid=?", v.SID).Updates(map[string]interface{}{
"state": v.State,
}).Error; err != nil {
log.Error("academy bindSkillArc error(%v)", err)
}
uid, uname := getUIDName(c)
svc.SendAcademyLog(c, &academy.LogParam{UID: uid, UName: uname, Action: "更新技能稿件状态", TID: v.ID, OName: v.Title})
c.JSON(nil, err)
}
func skillArcList(c *bm.Context) {
var (
items []*academy.ArcSkill
aids []int64
total int
err error
)
v := new(academy.ArcSkill)
if err = c.Bind(v); err != nil {
return
}
if v.Pn < 1 {
v.Pn = 1
}
if v.Ps > 20 {
v.Ps = 20
}
db := svc.DB.Model(&academy.ArcSkill{})
if v.PID != 0 {
db = db.Where("pid=?", v.PID)
}
if v.SkID != 0 {
db = db.Where("skid=?", v.SkID)
}
db.Count(&total)
if err = db.Order("ctime DESC").Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&items).Error; err != nil {
log.Error("academy skillArcList error(%v)", err)
c.JSON(nil, err)
return
}
for _, v := range items {
aids = append(aids, v.AID)
}
arcs, err := svc.Archives(c, aids)
if err != nil {
log.Error("academy skillArcList error(%v)", err)
}
for _, v := range items {
if a, ok := arcs[v.AID]; ok {
v.Pic = a.Pic
v.Title = a.Title
}
}
data := &academy.ArcSkills{
Items: items,
Pager: &academy.Pager{
Num: v.Pn,
Size: v.Ps,
Total: total,
},
}
c.Render(http.StatusOK, render.MapJSON(map[string]interface{}{
"code": 0,
"message": "0",
"data": data,
}))
}
func subSearchKeywords(c *bm.Context) {
var err error
bs, err := ioutil.ReadAll(c.Request.Body)
if err != nil {
log.Error("subSearchKeywords ioutil.ReadAll error(%v)", err)
c.JSON(nil, ecode.RequestErr)
return
}
c.Request.Body.Close()
var v []*academy.SearchKeywords
err = json.Unmarshal(bs, &v)
if err != nil {
log.Error("subSearchKeywords json.Unmarshal v(%+v) error(%v)", v, err)
c.JSON(nil, ecode.RequestErr)
return
}
if err = svc.SubSearchKeywords(v); err != nil {
c.JSON(nil, err)
return
}
c.JSON(nil, nil)
}
func searchKeywords(c *bm.Context) {
res, err := svc.SearchKeywords()
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(res, nil)
}

View File

@@ -0,0 +1,477 @@
package http
import (
"fmt"
"net/http"
"strings"
"time"
"go-common/app/admin/main/creative/model/academy"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/binding"
"go-common/library/net/http/blademaster/render"
"go-common/library/xstr"
"github.com/jinzhu/gorm"
)
func addTag(c *bm.Context) {
var (
err error
linkIDs []int64
now = time.Now().Format("2006-01-02 15:04:05")
)
v := new(struct {
ParentID int64 `form:"parent_id"`
Business int8 `form:"business"`
Type int8 `form:"type"`
Desc string `form:"desc"`
Name string `form:"name"`
LinkID string `form:"link_id"`
})
if err = c.Bind(v); err != nil {
return
}
if v.LinkID != "" {
if linkIDs, err = xstr.SplitInts(v.LinkID); err != nil {
log.Error("addTag xstr.SplitInts h5 linkid(%+v)|error(%v)", v.LinkID, err)
c.JSON(nil, ecode.RequestErr)
return
}
}
m := &academy.Tag{
ParentID: v.ParentID,
State: academy.StateUnBlock,
Type: v.Type,
Business: v.Business,
Name: v.Name,
Desc: v.Desc,
CTime: now,
MTime: now,
}
tx := svc.DB.Begin()
if err = tx.Create(m).Error; err != nil {
log.Error("creative-admin academy addTag error(%v)", err)
c.JSON(nil, err)
tx.Rollback()
return
}
if err = tx.Model(&academy.Tag{}).Where("id=?", m.ID).Updates(map[string]interface{}{
"rank": m.ID,
}).Error; err != nil {
log.Error("creative-admin academy addTag update rank error(%v)", err)
c.JSON(nil, err)
tx.Rollback()
return
}
if len(linkIDs) > 0 { //插入h5标签关联的web标签
valLink := make([]string, 0, len(linkIDs))
valLinkArgs := make([]interface{}, 0)
for _, lid := range linkIDs {
valLink = append(valLink, "(?, ?, ?, ?)")
valLinkArgs = append(valLinkArgs, m.ID, lid, now, now)
}
sqlLinkStr := fmt.Sprintf("INSERT INTO academy_tag_link (tid, link_id, ctime, mtime) VALUES %s", strings.Join(valLink, ","))
if err = tx.Exec(sqlLinkStr, valLinkArgs...).Error; err != nil {
log.Error("academy bulk insert h5 link tag error(%v)", err)
tx.Rollback()
return
}
}
tx.Commit()
tid := m.ID
uid, uname := getUIDName(c)
svc.SendAcademyLog(c, &academy.LogParam{UID: uid, UName: uname, Action: "添加标签", TID: tid, OName: m.Name})
c.JSON(map[string]interface{}{
"id": tid,
}, nil)
}
func upTag(c *bm.Context) {
var (
tg = &academy.Tag{}
linkIDs []int64
err error
now = time.Now().Format("2006-01-02 15:04:05")
tid int64
)
v := new(struct {
ID int64 `form:"id"`
Desc string `form:"desc"`
Name string `form:"name"`
LinkID string `form:"link_id"`
})
if err = c.Bind(v); err != nil {
return
}
if v.LinkID != "" {
if linkIDs, err = xstr.SplitInts(v.LinkID); err != nil {
log.Error("upTag xstr.SplitInts h5 linkid(%+v)|error(%v)", v.LinkID, err)
c.JSON(nil, ecode.RequestErr)
return
}
}
if v.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
tid = v.ID
if err = svc.DB.Model(&academy.Tag{}).Where("id=?", tid).Find(tg).Error; err != nil {
c.JSON(nil, err)
return
}
if tg == nil {
c.JSON(nil, ecode.NothingFound)
return
}
tx := svc.DB.Begin()
if err = tx.Model(&academy.Tag{}).Where("id=?", tid).Updates(map[string]interface{}{
"name": v.Name,
"desc": v.Desc,
}).Error; err != nil {
log.Error("academy upTag error(%v)", err)
tx.Rollback()
return
}
if len(linkIDs) > 0 { //插入h5标签关联的web标签
// 对于提交上来的其他标签先统一删除再统一插入
var tl academy.TagLink
if err = tx.Where("tid =?", tid).Delete(&tl).Error; err != nil {
log.Error("upTag TagLink delete by tid(%v)|error(%v)", tid, err)
tx.Rollback()
return
}
valLink := make([]string, 0, len(linkIDs))
valLinkArgs := make([]interface{}, 0)
for _, lid := range linkIDs {
valLink = append(valLink, "(?, ?, ?, ?)")
valLinkArgs = append(valLinkArgs, tid, lid, now, now)
}
sqlLinkStr := fmt.Sprintf("INSERT INTO academy_tag_link (tid, link_id, ctime, mtime) VALUES %s ON DUPLICATE KEY UPDATE tid=VALUES(tid),link_id=VALUES(link_id)", strings.Join(valLink, ","))
if err = tx.Exec(sqlLinkStr, valLinkArgs...).Error; err != nil {
log.Error("upTag TagLink valLinkArgs(%+v)", valLinkArgs...)
tx.Rollback()
return
}
}
tx.Commit()
uid, uname := getUIDName(c)
svc.SendAcademyLog(c, &academy.LogParam{UID: uid, UName: uname, Action: "更新标签", TID: tid, OName: v.Name})
c.JSON(nil, err)
}
func bindTag(c *bm.Context) {
var (
tg = &academy.Tag{}
err error
)
v := new(struct {
ID int64 `form:"id"`
State int8 `form:"state"`
})
if err = c.Bind(v); err != nil {
return
}
if v.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
if err = svc.DB.Model(&academy.Tag{}).Where("id=?", v.ID).Find(tg, v.ID).Error; err != nil {
c.JSON(nil, err)
return
}
if tg == nil {
c.JSON(nil, ecode.NothingFound)
return
}
if err = svc.DB.Model(&academy.Tag{ID: v.ID}).Updates(map[string]interface{}{
"state": v.State,
"mtime": time.Now().Format("2006-01-02 15:04:05"),
}).Error; err != nil {
log.Error("creative-admin academy delTag error(%v)", err)
}
uid, uname := getUIDName(c)
svc.SendAcademyLog(c, &academy.LogParam{UID: uid, UName: uname, Action: "更新标签状态", TID: v.ID, OState: v.State})
c.JSON(nil, err)
}
func viewTag(c *bm.Context) {
var (
err error
tg = &academy.Tag{}
)
v := new(struct {
ID int64 `form:"id"`
Type int8 `form:"type"`
Business int8 `form:"business"`
})
if err = c.Bind(v); err != nil {
return
}
if v.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
if err = svc.DB.Where("type = ?", v.Type).Where("business = ?", v.Business).Find(tg, v.ID).Error; err != nil {
c.JSON(nil, err)
return
}
if tg == nil {
c.JSON(nil, ecode.NothingFound)
return
}
c.JSON(renderTag(tg), nil)
}
func listTag(c *bm.Context) {
var (
err error
db *gorm.DB
tags []*academy.Tag
)
v := new(struct {
Type int8 `form:"type"`
})
if err = c.Bind(v); err != nil {
return
}
if v.Type != 0 {
db = svc.DB.Where("type = ?", v.Type).Order("rank ASC").Find(&tags)
} else {
db = svc.DB.Order("rank ASC").Find(&tags)
}
if err = db.Error; err != nil {
log.Error("creative-admin academy listTag error(%v)", err)
c.JSON(nil, err)
return
}
tgs, _ := tagTree(tags, v.Type)
c.Render(http.StatusOK, render.MapJSON(map[string]interface{}{
"code": 0,
"message": "0",
"data": map[string]interface{}{
"classify": academy.TagClass(),
"list": tgs,
},
}))
}
func tagTree(tags []*academy.Tag, ty int8) (res map[int8][]*academy.TagMeta, err error) {
all := make(map[int8]map[int64]*academy.TagMeta)
top := make(map[int64]*academy.TagMeta)
res = make(map[int8][]*academy.TagMeta)
tids := make([]int64, 0, len(tags))
linkMap, _ := h5RelatedWebTIDsMap() //获取h5标签关联的web标签
if ty == academy.H5 {
for _, lids := range linkMap {
tids = append(tids, lids...) //取所有关联的web标签id
}
} else {
for _, v := range tags {
if v.Type != academy.H5 {
tids = append(tids, v.ID) //取所有web标签id
}
}
}
arcCountMap, err := arcCountByTids(tids) //获取web标签下面的稿件数量
if err != nil {
return
}
h5ArcCountMap := make(map[int64]int)
for id, lids := range linkMap {
count := 0
for _, lid := range lids {
if c, ok := arcCountMap[lid]; ok {
count += c
}
}
h5ArcCountMap[id] = count
}
for _, v := range tags { //获取父级节点
if v == nil {
continue
}
t := renderTag(v)
if t.ParentID == 0 {
if c, ok := arcCountMap[t.ID]; ok { //获取除分类标签和h5标签之外的标签关联稿件数量
t.Count = c
}
top[t.ID] = t
all[t.Type] = top //存储一级标签对象id map
res[t.Type] = append(res[t.Type], t) //存储一级标签对象
}
}
for _, v := range tags { //获取子节点并获取关联稿件数量
if v == nil {
continue
}
t := renderTag(v)
p, ok := all[t.Type][t.ParentID] //获取一级标签对象
if ok && p != nil && p.Type == t.Type {
if c, ok := arcCountMap[t.ID]; ok { //获取分类标签的二级关联稿件数量
t.Count = c
}
if c, ok := h5ArcCountMap[t.ID]; ok { //获取h5标签二级关联稿件数量
t.Count = c
}
if l, ok := linkMap[v.ID]; ok && v.Type == academy.H5 {
t.LinkID = l
}
p.Children = append(p.Children, t)
}
}
for _, v := range res {
for _, t := range v { //计算分类标签或者h5标签一级关联稿件数量
if t != nil && t.ParentID == 0 && (t.Type == academy.H5 || t.Type == academy.Classify) {
for _, v := range t.Children {
t.Count += v.Count
}
}
}
}
return
}
func renderTag(v *academy.Tag) (tg *academy.TagMeta) {
tg = &academy.TagMeta{
ID: v.ID,
Type: v.Type,
State: v.State,
Business: v.Business,
ParentID: v.ParentID,
Name: v.Name,
Desc: v.Desc,
Rank: v.Rank,
}
return
}
func fixTag(c *bm.Context) {
var err error
v := new(struct {
ID int64 `form:"id"`
ParentID int64 `form:"parent_id"`
Business int8 `form:"business"`
State int8 `form:"state"`
Type int8 `form:"type"`
Name string `form:"name"`
Desc string `form:"desc"`
Rank int64 `form:"rank"`
})
if err = c.Bind(v); err != nil {
return
}
if v.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
if err = svc.DB.Model(&academy.Tag{}).Where("id=?", v.ID).Updates(map[string]interface{}{
"parent_id": v.ParentID,
"business": v.Business,
"type": v.Type,
"state": v.State,
"name": v.Name,
"desc": v.Desc,
"mtime": time.Now().Format("2006-01-02 15:04:05"),
"rank": v.Rank,
}).Error; err != nil {
log.Error("creative-admin academy upTag error(%v)", err)
}
c.JSON(nil, err)
}
func orderTag(c *bm.Context) {
var err error
v := new(struct {
ID int64 `form:"id" validate:"required"`
Rank int64 `form:"rank" validate:"required"`
SwitchID int64 `form:"switch_id" validate:"required"`
SwitchRank int64 `form:"switch_rank" validate:"required"`
})
if err = c.BindWith(v, binding.Form); err != nil {
return
}
tx := svc.DB.Begin()
tg := &academy.Tag{}
if err = tx.Where("id=?", v.ID).First(&tg).Error; err != nil {
log.Error("creative-admin academy orderTag error(%v)", err)
c.JSON(nil, err)
tx.Rollback()
return
}
stg := &academy.Tag{}
if err = tx.Where("id=?", v.SwitchID).First(&stg).Error; err != nil {
log.Error("creative-admin academy orderTag error(%v)", err)
c.JSON(nil, err)
tx.Rollback()
return
}
if err = tx.Table("academy_tag").Where("id=?", v.ID).Updates(
map[string]interface{}{
"rank": v.SwitchRank,
"mtime": time.Now().Format("2006-01-02 15:04:05")},
).Error; err != nil {
log.Error("creative-admin academy orderTag error(%v)", err)
c.JSON(nil, err)
tx.Rollback()
return
}
if err = tx.Table("academy_tag").Where("id=?", v.SwitchID).Updates(
map[string]interface{}{
"rank": v.Rank,
"mtime": time.Now().Format("2006-01-02 15:04:05")},
).Error; err != nil {
log.Error("creative-admin academy orderTag error(%v)", err)
c.JSON(nil, err)
tx.Rollback()
return
}
tx.Commit()
uid, uname := getUIDName(c)
svc.SendAcademyLog(c, &academy.LogParam{UID: uid, UName: uname, Action: "更新标签", TID: v.ID, OName: ""})
c.JSON(nil, err)
}
func h5RelatedWebTIDsMap() (res map[int64][]int64, err error) {
var tls []*academy.TagLink
if err = svc.DB.Find(&tls).Error; err != nil {
log.Error("academy h5TIDsMap error(%v)", err)
return
}
if len(tls) == 0 {
return
}
res = make(map[int64][]int64)
for _, t := range tls {
res[t.TID] = append(res[t.TID], t.LinkID)
}
return
}

View File

@@ -0,0 +1,32 @@
package http
import (
"flag"
"path/filepath"
"testing"
"go-common/app/admin/main/creative/conf"
"go-common/app/admin/main/creative/service"
. "github.com/smartystreets/goconvey/convey"
)
func init() {
dir, _ := filepath.Abs("../cmd/creative-admin.toml")
flag.Set("conf", dir)
conf.Init()
svc = service.New(conf.Conf)
}
func Test_bindTags(t *testing.T) {
var (
oidTIDsMap = map[int64][]int64{
838: {6, 8, 16, 17, 18, 19},
}
)
Convey("bindTags", t, func() {
res, err := bindTags(oidTIDsMap)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}

View File

@@ -0,0 +1,295 @@
package http
import (
"encoding/json"
"go-common/app/admin/main/creative/model/app"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/render"
"net/http"
"sort"
"time"
)
func viewPortal(c *bm.Context) {
var (
err error
info = &app.Portal{}
)
v := new(struct {
ID int64 `form:"id"`
})
if err = c.Bind(v); err != nil {
return
}
if v.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
if err = svc.DB.Debug().Model(&app.Portal{}).First(info, v.ID).Error; err != nil {
c.JSON(nil, err)
return
}
if info.ID == 0 {
c.JSON(nil, ecode.NothingFound)
} else {
layout := "2006-01-02 15:04:05"
mtime, _ := time.Parse(time.RFC3339, info.MTime)
info.MTime = mtime.Format(layout)
ptime, _ := time.Parse(time.RFC3339, info.PTime)
info.PTime = ptime.Format(layout)
ctime, _ := time.Parse(time.RFC3339, info.CTime)
info.CTime = ctime.Format(layout)
c.JSON(info, nil)
}
}
func addPortal(c *bm.Context) {
var (
err error
)
v := new(struct {
Build int64 `form:"build"`
BuildExp string `form:"buildexp"`
Platform int8 `form:"platform"`
Compare int8 `form:"compare"`
Pos int16 `form:"pos"`
Mark int8 `form:"mark"`
More int8 `form:"more"`
Type int8 `form:"type"`
Title string `form:"title" validate:"required"`
Icon string `form:"icon" validate:"required"`
URL string `form:"url" validate:"required"`
Whiteexp string `form:"whiteexp"`
SubTitle string `form:"subtitle"`
})
if err = c.Bind(v); err != nil {
return
}
if !checkBuild(v.BuildExp) {
httpCode(c, "buildexp is wrong", ecode.RequestErr)
return
}
if !checkWhite(v.Whiteexp) {
httpCode(c, "whiteexp is wrong", ecode.RequestErr)
return
}
m := &app.Portal{
Build: v.Build,
BuildExp: v.BuildExp,
Platform: v.Platform,
Compare: v.Compare,
State: 1,
Pos: v.Pos,
Mark: v.Mark,
More: v.More,
Type: v.Type,
Title: v.Title,
Icon: v.Icon,
URL: v.URL,
CTime: time.Now().Format("2006-01-02 15:04:05"),
MTime: time.Now().Format("2006-01-02 15:04:05"),
PTime: time.Now().Format("2006-01-02 15:04:05"),
SubTitle: v.SubTitle,
WhiteExp: v.Whiteexp,
}
db := svc.DB.Create(m)
if err = db.Error; err != nil {
log.Error("creativeSvc.addPortal error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(map[string]interface{}{
"id": db.Value.(*app.Portal).ID,
}, nil)
}
func upPortal(c *bm.Context) {
var (
err error
ap = &app.Portal{}
)
v := new(struct {
ID int64 `form:"id"`
Build int64 `form:"build"`
BuildExp string `form:"buildexp"`
Platform int8 `form:"platform"`
Compare int8 `form:"compare"`
Pos int16 `form:"pos"`
Mark int8 `form:"mark"`
More int8 `form:"more"`
Type int8 `form:"type"`
Title string `form:"title" validate:"required"`
Icon string `form:"icon" validate:"required"`
URL string `form:"url" validate:"required"`
Whiteexp string `form:"whiteexp"`
SubTitle string `form:"subtitle"`
})
if err = c.Bind(v); err != nil {
return
}
if !checkBuild(v.BuildExp) {
httpCode(c, "buildexp is wrong", ecode.RequestErr)
return
}
if !checkWhite(v.Whiteexp) {
httpCode(c, "whiteexp is wrong", ecode.RequestErr)
return
}
if err = svc.DB.Model(ap).Find(ap, v.ID).Error; err != nil {
c.JSON(nil, err)
return
}
if err = svc.DB.Model(&app.Portal{}).Update(map[string]interface{}{
"id": v.ID,
"build": v.Build,
"buildexp": v.BuildExp,
"platform": v.Platform,
"compare": v.Compare,
"state": 1,
"pos": v.Pos,
"mark": v.Mark,
"more": v.More,
"type": v.Type,
"title": v.Title,
"icon": v.Icon,
"url": v.URL,
"mtime": time.Now().Format("2006-01-02 15:04:05"),
"subtitle": v.SubTitle,
"whiteexp": v.Whiteexp,
}).Error; err != nil {
log.Error("creativeSvc.addPortal error(%v)", err)
}
c.JSON(nil, err)
}
func downPortal(c *bm.Context) {
var (
err error
ap = &app.Portal{}
)
v := new(struct {
ID int64 `form:"id"`
})
if err = c.Bind(v); err != nil {
return
}
if v.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
if err = svc.DB.Model(ap).Find(ap, v.ID).Error; err != nil {
c.JSON(nil, err)
return
}
if err = svc.DB.Model(&app.Portal{ID: v.ID}).Update(map[string]interface{}{
"id": v.ID,
"state": 0,
"mtime": time.Now().Format("2006-01-02 15:04:05"),
}).Error; err != nil {
log.Error("creativeSvc.addPortal error(%v)", err)
}
c.JSON(nil, err)
}
// 入口列表查询增加subtitle和whiteexp字段
func portalList(c *bm.Context) {
var (
pts []*app.Portal
items []*app.Item
total int64
err error
)
v := new(struct {
Pn int `form:"pn" validate:"required,min=1"`
Ps int `form:"ps" validate:"required,min=1"`
State int8 `form:"state"`
Type int8 `form:"type"`
Platform string `form:"platform"`
})
if err = c.Bind(v); err != nil {
return
}
if v.Pn < 1 {
v.Pn = 1
}
if v.Ps < 20 {
v.Ps = 20
}
if v.Type < 0 {
v.Type = 0
}
db := svc.DB.Model(&app.Portal{}).Where("type=?", v.Type)
if v.Platform != "" {
db = db.Where("platform=?", atoi(v.Platform))
}
if v.State != 2 {
db = db.Where("state=?", v.State)
}
db.Count(&total)
if err = db.Order("ctime DESC").Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&pts).Error; err != nil {
log.Error("portalList error(%v)", err)
c.JSON(nil, err)
return
}
if len(pts) > 0 {
items = make([]*app.Item, 0, len(pts))
for _, v := range pts {
i := &app.Item{}
if v == nil {
continue
}
i.ID = v.ID
i.Build = v.Build
i.BuildExp = v.BuildExp
i.Platform = v.Platform
i.Compare = v.Compare
i.State = v.State
i.Pos = v.Pos
i.Mark = v.Mark
i.More = v.More
i.Type = v.Type
i.Title = v.Title
i.Icon = v.Icon
i.URL = v.URL
i.SubTitle = v.SubTitle
if len(v.WhiteExp) > 0 {
if err = json.Unmarshal([]byte(v.WhiteExp), &i.WhiteExps); err != nil {
log.Error("json.Unmarshal buildComps failed error(%v)", err)
}
sort.Slice(i.WhiteExps, func(m, n int) bool {
return i.WhiteExps[m].TP <= i.WhiteExps[n].TP
})
}
ct, err := time.Parse(time.RFC3339, v.CTime)
if err != nil {
log.Error("ctime time.Parse error(%v)", err)
}
mt, err := time.Parse(time.RFC3339, v.MTime)
if err != nil {
log.Error("mtime time.Parse error(%v)", err)
}
pt, err := time.Parse(time.RFC3339, v.PTime)
if err != nil {
log.Error("ptime time.Parse error(%v)", err)
}
i.CTime = ct.Unix()
i.MTime = mt.Unix()
i.PTime = pt.Unix()
items = append(items, i)
}
} else {
items = []*app.Item{}
}
data := &app.PortalPager{
Pn: v.Pn,
Ps: v.Ps,
Items: items,
Total: total,
}
c.Render(http.StatusOK, render.MapJSON(map[string]interface{}{
"code": 0,
"message": "0",
"data": data,
}))
}

View File

@@ -0,0 +1,47 @@
package http
import (
"fmt"
"net/http"
"github.com/pkg/errors"
)
// CSVContentType
var (
CSVContentType = []string{"application/csv"}
_ Render = CSV{}
)
// Render http reponse render.
type Render interface {
Render(http.ResponseWriter) error
WriteContentType(w http.ResponseWriter)
}
// CSV str.
type CSV struct {
Content []byte
Title string
}
// WriteContentType fn
func (j CSV) WriteContentType(w http.ResponseWriter) {
writeContentType(w, CSVContentType, j.Title)
}
func writeContentType(w http.ResponseWriter, value []string, title string) {
header := w.Header()
if val := header["Content-Type"]; len(val) == 0 {
header["Content-Type"] = value
}
header["Content-Disposition"] = append(header["Content-Disposition"], fmt.Sprintf("attachment; filename=%s.csv", title))
}
// Render (JSON) writes data with json ContentType.
func (j CSV) Render(w http.ResponseWriter) (err error) {
if _, err = w.Write(j.Content); err != nil {
err = errors.WithStack(err)
}
return
}

View File

@@ -0,0 +1,44 @@
package http
import (
"bytes"
"encoding/csv"
"strconv"
"go-common/app/admin/main/creative/model/whitelist"
"go-common/library/log"
)
// FormatCSV format csv data.
func FormatCSV(records [][]string) (res []byte) {
buf := new(bytes.Buffer)
w := csv.NewWriter(buf)
for _, record := range records {
if err := w.Write(record); err != nil {
log.Error("error writing record to csv:", err)
return
}
}
w.Flush()
res = buf.Bytes()
return
}
func formatWhilteList(wl []*whitelist.Whitelist) (data [][]string, err error) {
if len(wl) < 0 {
return
}
data = append(data, []string{"MID", "昵称", "AdminMID", "备注", "粉丝数", "等级", "创建时间"})
for _, v := range wl {
var fields []string
fields = append(fields, strconv.FormatInt(int64(v.MID), 10))
fields = append(fields, v.Name)
fields = append(fields, strconv.FormatInt(int64(v.AdminMID), 10))
fields = append(fields, v.Comment)
fields = append(fields, strconv.FormatInt(int64(v.Fans), 10))
fields = append(fields, strconv.FormatInt(int64(v.CurrentLevel), 10))
fields = append(fields, v.Ctime)
data = append(data, fields)
}
return
}

View File

@@ -0,0 +1,221 @@
package http
import (
"go-common/app/admin/main/creative/conf"
"go-common/app/admin/main/creative/service"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/permit"
)
var (
svc *service.Service
authSrc *permit.Permit
)
// Init http server
func Init(c *conf.Config) {
svc = service.New(c)
authSrc = permit.New(c.Auth)
engine := bm.DefaultServer(c.BM)
innerRouter(engine)
if err := engine.Start(); err != nil {
log.Error("engine.Start error(%v)", err)
panic(err)
}
}
func innerRouter(e *bm.Engine) {
e.GET("/monitor/ping", moPing)
b := e.Group("/x/admin/creative")
{
innerMusicRouter(e, b)
innerMaterialRouter(e, b)
app := b.Group("/app")
{
app.GET("/portal", viewPortal)
app.POST("/portal/add", addPortal)
app.POST("/portal/update", upPortal)
app.POST("/portal/down", downPortal)
app.GET("/portal/list", portalList)
}
notice := b.Group("/notice")
{
notice.GET("/view", viewNotice)
notice.GET("/list", listNotice)
notice.POST("/add", addNotice)
notice.POST("/update", upNotice)
notice.POST("/delete", delNotice)
}
arc := b.Group("/oper/col_arc", authSrc.Verify())
{
arc.GET("/list", listCollectArcOper)
arc.POST("/add", addCollectArcOper)
// blew is copy from notice for support
arc.GET("/view", viewNotice)
arc.POST("/update", upNotice)
arc.POST("/delete", delNotice)
}
whitelist := b.Group("/whitelist")
{
whitelist.GET("/view", viewWhiteList)
whitelist.GET("/list", listWhiteList)
whitelist.GET("/export.so", exportWhiteList)
whitelist.POST("/add", addWhiteList)
whitelist.POST("/add/batch", addBatchWhiteList)
whitelist.POST("/update", upWhiteList)
whitelist.POST("/delete", delWhiteList)
}
academy := b.Group("/academy", authSrc.Verify(), authSrc.Permit("ACADEMY_MANAGER")) //创作学院
// academy := b.Group("/academy") //创作学院
{
academy.POST("/tag/update/fix", fixTag) //清理脏数据
academy.POST("/archive/update/fix", fixArchive) //清理脏数据
//tag
academy.POST("/tag/add", addTag)
academy.POST("/tag/update", upTag)
academy.POST("/tag/bind", bindTag)
academy.GET("/tag/view", viewTag)
academy.GET("/tag/list", listTag)
academy.POST("/tag/order", orderTag)
//archive
academy.POST("/archive/add", addArc)
academy.POST("/archive/update", upArcTag)
academy.POST("/archive/remove", removeArcTag)
academy.POST("/archive/batch/add", batchAddArc)
academy.POST("/archive/batch/update", batchUpArc)
academy.POST("/archive/batch/remove", batchRemoveArc)
academy.GET("/archive/view", viewArc)
academy.GET("/archive/list", listArc)
//occupation & skill
academy.POST("/occupation/add", addOccupation)
academy.POST("/occupation/update", upOccupation)
academy.POST("/occupation/bind", bindOccupation)
academy.POST("/occupation/order", orderOccupation)
academy.GET("/occupation/list", listOccupation)
academy.POST("/skill/add", addSkill)
academy.POST("/skill/update", upSkill)
academy.POST("/skill/bind", bindSkill)
academy.POST("/software/add", addSoftware)
academy.POST("/software/update", upSoftware)
academy.POST("/software/bind", bindSoftware)
//arc & skill
academy.GET("/skill/archive/view", viewSkillArc)
academy.GET("/skill/archive/list", skillArcList)
academy.POST("/skill/archive/add", addSkillArc)
academy.POST("/skill/archive/update", upSkillArc)
academy.POST("/skill/archive/bind", bindSkillArc)
//search keywords
academy.GET("/search/keywords", searchKeywords)
academy.POST("/search/keywords/sub", subSearchKeywords)
}
task := b.Group("/task", authSrc.Verify(), authSrc.Permit("CREATIVE_TASK_MANAGER")) //任务系统
// task := b.Group("/task") //任务系统
{
//task list
task.GET("/pre", taskPre)
task.GET("/list", taskList)
task.POST("/online", batchOnline)
//group
task.GET("/group/view", viewGroup)
task.POST("/group/add", addGroup)
task.POST("/group/edit", editGroup)
task.POST("/group/order", orderGroup)
task.POST("/group/upstate", upStateGroup)
//sub
task.GET("/sub/view", viewSubtask)
task.POST("/sub/add", addSubtask)
task.POST("/sub/edit", editSubtask)
task.POST("/sub/order", orderSubtask)
task.POST("/sub/upstate", upStateSubtask)
task.POST("/sub/transfer", transferSubtask)
//reward
task.GET("/reward/list", rewardTree)
task.GET("/reward/view", viewReward)
task.POST("/reward/add", addReward)
task.POST("/reward/edit", editReward)
task.POST("/reward/upstate", upStateReward)
//gift
task.GET("/gift/list", listGiftReward)
task.GET("/gift/view", viewGiftReward)
task.POST("/gift/add", addGiftReward)
task.POST("/gift/edit", editGiftReward)
task.POST("/gift/upstate", upStateGiftReward)
}
}
}
//素材库 db creative
func innerMaterialRouter(e *bm.Engine, group *bm.RouterGroup) {
if group == nil {
return
}
//字幕库 字体库 滤镜库
material := group.Group("/material", authSrc.Verify())
{
material.GET("", authSrc.Permit("MATERIAL_READ"), infoMaterial)
material.GET("/search", authSrc.Permit("MATERIAL_READ"), searchMaterialDb)
//支持新增和修改
material.POST("/add", authSrc.Permit("MATERIAL_WRITE"), syncMaterial)
//支持批量修改
material.POST("/state", authSrc.Permit("MATERIAL_WRITE"), stateMaterial)
//仅支持 image/ zip 上传
material.POST("/upload", upload)
//素材库分类
material.GET("/category", authSrc.Permit("MATERIAL_READ"), category)
material.POST("/category/add", authSrc.Permit("MATERIAL_WRITE"), addMCategory)
material.POST("/category/edit", authSrc.Permit("MATERIAL_WRITE"), editMCategory)
material.POST("/category/index", authSrc.Permit("MATERIAL_WRITE"), indexMCategory)
material.POST("/category/delete", authSrc.Permit("MATERIAL_WRITE"), delMCategory)
material.GET("/category/search", authSrc.Permit("MATERIAL_READ"), searchMCategory)
}
}
//音频库 db archive
func innerMusicRouter(e *bm.Engine, group *bm.RouterGroup) {
if group == nil {
return
}
groupMusic := group.Group("/music")
{
//音乐管理及同步
groupMusic.POST("/add", authSrc.Permit("MUSIC_UPDATE"), syncMusic)
groupMusic.POST("/up/frontname", authSrc.Permit("MUSIC_UPDATE"), editMusicFrontName)
groupMusic.POST("/up/tags", authSrc.Permit("MUSIC_UPDATE"), editMusicTags)
groupMusic.POST("/edit", authSrc.Permit("MUSIC_UPDATE"), editMusic)
groupMusic.POST("/batch/tags", authSrc.Permit("MUSIC_UPDATE"), batchEditMusicTags)
groupMusic.POST("/up/timeline", authSrc.Permit("MUSIC_UPDATE"), editMusicTimeline)
groupMusic.GET("/search", authSrc.Permit("MUSIC_READ"), searchMusic)
//音乐分类
groupMusic.GET("/category", authSrc.Permit("MUSIC_CATEGORY_READ"), categoryInfo)
groupMusic.POST("/category/add", authSrc.Permit("MUSIC_CATEGORY_UPDATE"), addCategory)
groupMusic.POST("/category/edit", authSrc.Permit("MUSIC_CATEGORY_UPDATE"), editCategory)
groupMusic.POST("/category/index", authSrc.Permit("MUSIC_CATEGORY_UPDATE"), indexCategory)
groupMusic.POST("/category/delete", authSrc.Permit("MUSIC_CATEGORY_UPDATE"), delCategory)
groupMusic.GET("/category/search", authSrc.Permit("MUSIC_CATEGORY_READ"), searchCategory)
//素材分类
groupMusic.GET("/material", authSrc.Permit("MUSIC_MATERIAL_READ"), materialInfo)
groupMusic.POST("/material/add", authSrc.Permit("MUSIC_MATERIAL_UPDATE"), addMaterial)
groupMusic.POST("/material/edit", authSrc.Permit("MUSIC_MATERIAL_UPDATE"), editMaterial)
groupMusic.POST("/material/delete", authSrc.Permit("MUSIC_MATERIAL_UPDATE"), delMaterial)
groupMusic.POST("/material/batch/delete", authSrc.Permit("MUSIC_MATERIAL_UPDATE"), batchDeleteMaterial)
groupMusic.GET("/material/search", authSrc.Permit("MUSIC_MATERIAL_READ"), searchMaterial)
//音乐及素材 管理端
groupMusic.GET("/material/relation", authSrc.Permit("MUSIC_WITH_MATERIAL_READ"), musicMaterialRelationInfo)
groupMusic.POST("/material/relation/add", authSrc.Permit("MUSIC_WITH_MATERIAL_UPDATE"), addMaterialRelation)
groupMusic.POST("/material/relation/batch/add", authSrc.Permit("MUSIC_WITH_MATERIAL_UPDATE"), batchAddMaterialRelation)
groupMusic.POST("/material/relation/edit", authSrc.Permit("MUSIC_WITH_MATERIAL_UPDATE"), editMaterialRelation)
//音乐及分类 app端
groupMusic.GET("/category/relation", authSrc.Permit("MUSIC_WITH_CATEGORY_READ"), musicCategoryRelationInfo)
groupMusic.POST("/category/relation/add", authSrc.Permit("MUSIC_WITH_CATEGORY_UPDATE"), addCategoryRelation)
groupMusic.POST("/category/relation/batch/add", authSrc.Permit("MUSIC_WITH_CATEGORY_UPDATE"), batchAddCategoryRelation)
groupMusic.POST("/category/relation/index", authSrc.Permit("MUSIC_WITH_CATEGORY_UPDATE"), indexCategoryRelation)
groupMusic.POST("/category/relation/edit", authSrc.Permit("MUSIC_WITH_CATEGORY_UPDATE"), editCategoryRelation)
groupMusic.POST("/category/relation/batch/delete", authSrc.Permit("MUSIC_WITH_CATEGORY_UPDATE"), batchDeleteCategoryRelation)
groupMusic.POST("/category/relation/delete", authSrc.Permit("MUSIC_WITH_CATEGORY_UPDATE"), delCategoryRelation)
groupMusic.GET("/category/relation/search", authSrc.Permit("MUSIC_WITH_CATEGORY_READ"), searchCategoryRelation)
}
}

View File

@@ -0,0 +1,309 @@
package http
import (
"go-common/app/admin/main/creative/model/operation"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/render"
"net/http"
"time"
)
var (
typesMap = map[int8]int8{
0: 0, // 显示
1: 1, // 隐藏
2: 2, // 全部
}
platformMap = map[int8]int8{
0: 0, // web+app
1: 1, // app
2: 2, // web
100: 100, // 全平台
}
)
func viewNotice(c *bm.Context) {
var (
err error
info = &operation.Operation{}
)
v := new(struct {
ID int64 `form:"id"`
})
if err = c.Bind(v); err != nil {
return
}
if v.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
if err = svc.DB.Debug().Model(&operation.Operation{}).First(info, v.ID).Error; err != nil {
c.JSON(nil, err)
return
}
if info.ID == 0 {
c.JSON(nil, ecode.NothingFound)
} else {
layout := "2006-01-02 15:04:05"
ftime, _ := time.Parse(time.RFC3339, info.Stime)
info.Stime = ftime.Format(layout)
ftime, _ = time.Parse(time.RFC3339, info.Etime)
info.Etime = ftime.Format(layout)
ftime, _ = time.Parse(time.RFC3339, info.Ctime)
info.Ctime = ftime.Format(layout)
ftime, _ = time.Parse(time.RFC3339, info.Mtime)
info.Mtime = ftime.Format(layout)
ftime, _ = time.Parse(time.RFC3339, info.Dtime)
info.Dtime = ftime.Format(layout)
c.JSON(info, nil)
}
}
func listNotice(c *bm.Context) {
var (
err error
ops []*operation.Operation
total int
)
v := new(struct {
Type int8 `form:"type"`
Platform int8 `form:"platform"`
Page int `form:"page" validate:"min=1"`
PageSize int `form:"pagesize" validate:"min=1"`
})
if err = c.Bind(v); err != nil {
return
}
if v.Page < 1 {
v.Page = 1
}
if v.PageSize < 20 {
v.PageSize = 20
}
if _, ok := typesMap[v.Type]; !ok {
data := map[string]interface{}{
"code": ecode.RequestErr,
"message": "forbid request with wrong type enum value",
}
c.Render(http.StatusOK, render.MapJSON(data))
return
}
if _, ok := platformMap[v.Platform]; !ok {
data := map[string]interface{}{
"code": ecode.RequestErr,
"message": "forbid request with wrong platform enum value",
}
c.Render(http.StatusOK, render.MapJSON(data))
return
}
now := time.Now().Format("2006-01-02 15:04:05")
where := " dtime = '0000-00-00 00:00:00' AND type = 'play' AND platform = ?"
if v.Platform == 100 {
where = " dtime = '0000-00-00 00:00:00' AND type = 'play' "
}
if v.Type == 0 {
where += " AND (stime < ? AND etime > ?) "
} else if v.Type == 1 {
where += " AND (stime > ? OR etime < ?) "
} else if v.Type == 2 {
where += " AND 1=1 "
}
if v.Type == 2 {
if v.Platform == 100 {
if err = svc.DB.Debug().Model(&operation.Operation{}).Order("rank ASC").Offset((v.Page-1)*v.PageSize).Limit(v.PageSize).Find(&ops, where).Error; err != nil {
c.JSON(nil, err)
return
}
svc.DB.Debug().Model(&operation.Operation{}).Where(where).Count(&total)
} else {
if err = svc.DB.Debug().Model(&operation.Operation{}).Order("rank ASC").Offset((v.Page-1)*v.PageSize).Limit(v.PageSize).Find(&ops, where, v.Platform).Error; err != nil {
c.JSON(nil, err)
return
}
svc.DB.Debug().Model(&operation.Operation{}).Where(where, v.Platform).Count(&total)
}
} else {
if v.Platform == 100 {
if err = svc.DB.Debug().Model(&operation.Operation{}).Order("rank ASC").Offset((v.Page-1)*v.PageSize).Limit(v.PageSize).Find(&ops, where, now, now).Error; err != nil {
c.JSON(nil, err)
return
}
svc.DB.Debug().Model(&operation.Operation{}).Where(where, now, now).Count(&total)
} else {
if err = svc.DB.Debug().Model(&operation.Operation{}).Order("rank ASC").Offset((v.Page-1)*v.PageSize).Limit(v.PageSize).Find(&ops, where, v.Platform, now, now).Error; err != nil {
c.JSON(nil, err)
return
}
svc.DB.Debug().Model(&operation.Operation{}).Where(where, v.Platform, now, now).Count(&total)
}
}
var opsView []*operation.ViewOperation
for _, v := range ops {
var (
status string
timeNow = time.Now()
stime, _ = time.Parse(time.RFC3339, v.Stime)
etime, _ = time.Parse(time.RFC3339, v.Etime)
)
if time.Now().Before(etime) && timeNow.After(stime) {
status = "显示"
} else {
status = "隐藏"
}
opsView = append(opsView, &operation.ViewOperation{
ID: v.ID,
Type: v.Type,
Ads: v.Ads,
Platform: v.Platform,
Rank: v.Rank,
Pic: v.Pic,
Link: v.Link,
Content: v.Content,
Username: v.Username,
Remark: v.Remark,
Note: v.Note,
AppPic: v.AppPic,
Stime: v.Stime,
Etime: v.Etime,
Ctime: v.Ctime,
Mtime: v.Mtime,
Dtime: v.Dtime,
Status: status,
})
}
c.Render(http.StatusOK, render.MapJSON(map[string]interface{}{
"code": 0,
"message": "0",
"data": opsView,
"pager": map[string]int{
"page": v.Page,
"pagesize": v.PageSize,
"total": total,
},
}))
}
func addNotice(c *bm.Context) {
var (
err error
)
v := new(struct {
Ads int8 `form:"ads" `
Rank int8 `form:"rank"`
Pic string `form:"pic" validate:"required"`
Link string `form:"link" validate:"required"`
Content string `form:"content" validate:"required"`
Username string `form:"username" validate:"required"`
Remark string `form:"remark"`
Note string `form:"note"`
AppPic string `form:"app_pic" validate:"required"`
Platform int8 `form:"platform"`
Stime string `form:"stime" validate:"required"`
Etime string `form:"etime" validate:"required"`
})
if err = c.Bind(v); err != nil {
return
}
m := &operation.Operation{
Type: "play",
Ads: v.Ads,
Rank: v.Rank,
Pic: v.Pic,
Link: v.Link,
Content: v.Content,
Username: v.Username,
Remark: v.Remark,
Note: v.Note,
AppPic: v.AppPic,
Platform: v.Platform,
Ctime: time.Now().Format("2006-01-02 15:04:05"),
Stime: v.Stime,
Etime: v.Etime,
}
db := svc.DB.Debug().Model(&operation.Operation{}).Create(m)
if err = db.Error; err != nil {
log.Error("creativeSvc.Operation error(%v)", err)
c.JSON(nil, ecode.RequestErr)
return
}
c.JSON(map[string]interface{}{
"id": db.Value.(*operation.Operation).ID,
}, nil)
}
func upNotice(c *bm.Context) {
var (
op = &operation.Operation{}
err error
)
v := new(struct {
ID int64 `form:"id"`
Ads int8 `form:"ads"`
Platform int8 `form:"platform"`
Rank int8 `form:"rank"`
Pic string `form:"pic"`
Link string `form:"link"`
Content string `form:"content"`
Username string `form:"username"`
Remark string `form:"remark"`
Note string `form:"note"`
AppPic string `form:"app_pic"`
Stime string `form:"stime"`
Etime string `form:"etime"`
})
if err = c.Bind(v); err != nil {
return
}
if v.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
if err = svc.DB.Debug().Model(&operation.Operation{}).Find(op, v.ID).Error; err != nil {
c.JSON(nil, err)
return
}
if err = svc.DB.Debug().Model(&operation.Operation{ID: v.ID}).Update(map[string]interface {
}{
"id": v.ID,
"ads": v.Ads,
"rank": v.Rank,
"pic": v.Pic,
"link": v.Link,
"content": v.Content,
"username": v.Username,
"remark": v.Remark,
"note": v.Note,
"app_pic": v.AppPic,
"platform": v.Platform,
"mtime": time.Now().Format("2006-01-02 15:04:05"),
"stime": v.Stime,
"etime": v.Etime,
}).Error; err != nil {
log.Error("svc.save error(%v)", err)
}
c.JSON(nil, err)
}
func delNotice(c *bm.Context) {
var (
op = &operation.Operation{}
err error
)
if err = c.Bind(op); err != nil {
return
}
if op.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
if err = svc.DB.Debug().Model(&operation.Operation{}).Find(op, op.ID).Error; err != nil {
c.JSON(nil, err)
return
}
if err = svc.DB.Debug().Model(&operation.Operation{ID: op.ID}).Update("dtime", time.Now().Format("2006-01-02 15:04:05")).Error; err != nil {
log.Error("svc.del Notice error(%v)", err)
}
c.JSON(nil, err)
}

View File

@@ -0,0 +1,16 @@
package http
import (
"net/http"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
func moPing(c *bm.Context) {
var err error
if err = svc.Ping(c); err != nil {
log.Error("creative-admin ping error(%v)", err)
c.AbortWithStatus(http.StatusServiceUnavailable)
}
}

View File

@@ -0,0 +1,407 @@
package http
import (
"strconv"
"encoding/json"
"fmt"
"go-common/app/admin/main/creative/model/app"
"go-common/app/admin/main/creative/model/logcli"
Mamdl "go-common/app/admin/main/creative/model/material"
"go-common/app/admin/main/creative/model/music"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/binding"
"go-common/library/xstr"
"strings"
"github.com/jinzhu/gorm"
"github.com/pkg/errors"
)
//素材库
func searchMaterialDb(c *bm.Context) {
var (
req = c.Request.Form
err error
items, dItems []*Mamdl.Material
count int64
typeID = req.Get("type")
Platform = atoi(req.Get("platform"))
categoryID = req.Get("category_id")
id = atoi(req.Get("id"))
name = req.Get("name")
page = atoi(req.Get("page"))
size = 20
)
if page == 0 {
page = 1
}
db := svc.DB.Model(&Mamdl.Material{}).Where("material.state!=?", Mamdl.StateDelete).
Joins("left join material_with_category on material_with_category.material_id=material.id and material_with_category.state !=?", Mamdl.StateOff).
Joins("left join material_category on material_with_category.category_id=material_category.id and material_category.state !=?", Mamdl.StateOff).
Select("material.*,material_category.name as category_name,material_with_category.category_id,material_with_category.index as category_index")
if id != 0 {
//id查询时需要提供type参数否则可能导致搜索为空
db = db.Where("material.id=?", id)
}
if Platform != -1 {
db = db.Where("material.platform=?", Platform)
}
//类型filter
if categoryID != "" {
db = db.Where("material_with_category.category_id=?", atoi(categoryID))
}
if typeID != "" {
db = db.Where("material.type=?", atoi(typeID))
}
if name != "" {
db = db.Where("material.name=?", name)
}
db.Count(&count)
if categoryID != "" {
db = db.Order("material_with_category.index")
} else {
db = db.Order("material.rank")
}
if err = db.Offset((page - 1) * size).Limit(size).Find(&dItems).Error; err != nil {
log.Error("%v\n", err)
c.JSON(nil, err)
return
}
if len(dItems) > 0 {
items = make([]*Mamdl.Material, 0, len(dItems))
for _, v := range dItems {
i := &Mamdl.Material{}
if v == nil {
continue
}
i.ID = v.ID
i.UID = v.UID
i.Name = v.Name
i.Extra = v.Extra
i.Rank = v.Rank
i.Type = v.Type
i.Platform = v.Platform
i.Build = v.Build
i.State = v.State
i.CategoryID = v.CategoryID
i.CategoryIndex = v.CategoryIndex
i.CategoryName = v.CategoryName
if i.CategoryName == "" {
i.CategoryID = 0
i.CategoryIndex = 0
}
i.CTime = v.CTime
i.MTime = v.MTime
items = append(items, i)
}
} else {
items = []*Mamdl.Material{}
}
pager := &Mamdl.Result{
Items: items,
Pager: &Mamdl.Pager{Num: page, Size: size, Total: count},
}
c.JSON(pager, nil)
}
func infoMaterial(c *bm.Context) {
var (
req = c.Request.Form
id = parseInt(req.Get("id"))
err error
)
m := &Mamdl.Material{}
if err = svc.DB.Where("id=?", id).First(&m).Error; err != nil {
c.JSON(nil, err)
return
}
c.JSON(map[string]*Mamdl.Material{
"data": m,
}, nil)
}
func getUIDName(c *bm.Context) (uid int64, uname string) {
unamei, ok := c.Get("username")
if ok {
uname = unamei.(string)
}
uidi, ok := c.Get("uid")
if ok {
uid = uidi.(int64)
}
return
}
func syncMaterial(c *bm.Context) {
var (
err error
m *Mamdl.Material
action string
)
mp := &Mamdl.Param{}
if err = c.BindWith(mp, binding.Form); err != nil {
log.Error("syncMaterial bind error trace(%+v)", errors.Wrap(err, "sync bind error"))
httpCode(c, fmt.Sprintf("bind error(%v)", err), ecode.RequestErr)
return
}
m, err = transferDB(c, mp)
if err != nil {
log.Error("transferDB find error(%+v)", err)
httpCode(c, fmt.Sprintf("transferDB validate error(%v)", err), ecode.RequestErr)
return
}
uid, uname := getUIDName(c)
m.UID = uid
if m.ID == 0 {
action = "add"
if err = svc.DB.Create(m).Error; err != nil {
log.Error("syncMaterial Create error(%+v)", err)
httpCode(c, fmt.Sprintf("syncMaterial Create error(%v)", err), ecode.RequestErr)
return
}
} else {
action = "edit"
exist := &Mamdl.Material{}
if err = svc.DB.Where("id=?", mp.ID).First(&exist).Error; err != nil && err != gorm.ErrRecordNotFound {
log.Error("syncMaterial find error(%+v)", err)
httpCode(c, fmt.Sprintf("syncMaterial find error(%v)", err), ecode.RequestErr)
return
}
if exist.ID > 0 {
m.ID = exist.ID
if err = svc.DB.Model(&Mamdl.Material{}).Where("id=?", mp.ID).Update(m).Update(map[string]int8{"type": m.Type}).Error; err != nil {
log.Error("syncMaterial update error(%+v)", err)
httpCode(c, fmt.Sprintf("syncMaterial update error(%v)", err), ecode.RequestErr)
return
}
}
}
logMaterial, _ := json.Marshal(mp)
svc.SendMusicLog(c, logcli.LogClientArchiveMaterialType, &music.LogParam{ID: m.ID, UID: uid, UName: uname, Action: action, Name: string(logMaterial)})
//不做事务允许分类绑定异常
if mp.Type == Mamdl.TypeFilter || mp.Type == Mamdl.TypeCreativeSticks {
_, err = svc.BindWithCategory(c, m.ID, mp.CategoryID, mp.CategoryIndex)
if err != nil {
httpCode(c, fmt.Sprintf("BindWithCategory update error(%v)", err), ecode.RequestErr)
return
}
}
c.JSON(map[string]int64{
"id": m.ID,
}, nil)
}
func transferDB(c *bm.Context, form *Mamdl.Param) (material *Mamdl.Material, err error) {
var extraBytes []byte
material = &Mamdl.Material{}
if form == nil {
return material, fmt.Errorf("params is wrong")
}
if form.Type != Mamdl.TypeCreativeSticks && (form.Name == "") {
return material, fmt.Errorf("name is need")
}
if form.Type == Mamdl.TypeSubTitle && (form.Max == 0) {
return material, fmt.Errorf("max is need")
}
if form.Type != Mamdl.TypeSticksIcon && (form.Rank == 0) {
return material, fmt.Errorf("rank is need")
}
//不需要cover
if form.Type != Mamdl.TypeHotWord && form.Type != Mamdl.TypeSticksIcon && form.Type != Mamdl.TypeCooperate && (form.Cover == "" || form.DownloadURL == "") {
return material, fmt.Errorf("cover and download_url is need")
}
if form.Cover != "" && (!strings.HasPrefix(form.Cover, "http") || !strings.Contains(form.Cover, "/bfs/")) {
return material, fmt.Errorf("cover is wrong")
}
if form.Type == Mamdl.TypeCooperate && form.DownloadURL != "" && !strings.Contains(form.DownloadURL, "acgvideo.com/") {
//acg
return material, fmt.Errorf("download_url is wrong")
}
if form.Type != Mamdl.TypeCooperate && form.DownloadURL != "" && (!strings.HasSuffix(form.DownloadURL, ".zip") || !strings.HasPrefix(form.DownloadURL, "http") || !strings.Contains(form.DownloadURL, "/bfs/creative/")) {
//bfs creative
return material, fmt.Errorf("download_url is wrong")
}
if !Mamdl.InMaterialType(form.Type) || form.Type == Mamdl.TypeBGM {
//Mamdl.TypeBGM 为迁入bgm预留
return material, fmt.Errorf("type is wrong")
}
if !checkBuild(form.Build) {
return material, fmt.Errorf("build is wrong")
}
switch form.Type {
case Mamdl.TypeSubTitle:
//字幕库
extraBytes, err = json.Marshal(map[string]interface{}{
"download_url": form.DownloadURL,
"max": form.Max,
"cover": form.Cover,
})
case Mamdl.TypeFont, Mamdl.TypeHotWord, Mamdl.TypeSticksIcon:
//字体库,贴纸,热词,贴纸Icon
extraBytes, err = json.Marshal(map[string]interface{}{
"download_url": form.DownloadURL,
"cover": form.Cover,
})
case Mamdl.TypeSticks:
//贴纸
extraBytes, err = json.Marshal(map[string]interface{}{
"download_url": form.DownloadURL,
"cover": form.Cover,
"sub_type": form.SubType,
"white_list": form.WhilteList,
"tip": form.Tip,
})
case Mamdl.TypeFilter:
//滤镜库
if len(form.ExtraURL) > 0 && (!strings.HasSuffix(form.ExtraURL, ".zip") || !strings.HasPrefix(form.ExtraURL, "http") || !strings.Contains(form.ExtraURL, "/bfs/creative/")) {
return material, fmt.Errorf("extra_url is wrong")
}
extraBytes, err = json.Marshal(map[string]interface{}{
"download_url": form.DownloadURL,
"cover": form.Cover,
"extra_url": form.ExtraURL,
"extra_field": form.ExtraField,
"filter_type": form.FilterType,
})
case Mamdl.TypeCooperate:
//合拍库
if form.MaterialAID*form.MaterialCID*form.DemoAID == 0 || form.SubType == 0 {
return material, fmt.Errorf("参数错误")
}
extraBytes, err = json.Marshal(map[string]interface{}{
"download_url": form.DownloadURL,
"cover": form.Cover,
"sub_type": form.SubType,
"style": form.Style,
"material_aid": form.MaterialAID,
"material_cid": form.MaterialCID,
"demo_aid": form.DemoAID,
"demo_cid": form.DemoCID,
"mission_id": form.MissionID,
})
case Mamdl.TypeTheme:
//主题库
extraBytes, err = json.Marshal(map[string]interface{}{
"download_url": form.DownloadURL,
"cover": form.Cover,
})
default:
extraBytes, err = json.Marshal(map[string]interface{}{
"download_url": form.DownloadURL,
"cover": form.Cover,
})
}
if err != nil {
return material, err
}
material.ID = form.ID
material.Name = form.Name
material.Extra = string(extraBytes)
material.Type = form.Type
material.Rank = form.Rank
material.Platform = form.Platform
material.Build = form.Build
if form.CategoryID > 0 {
if form.CategoryIndex < 1 {
return material, fmt.Errorf("category_index is wrong")
}
cate, _ := svc.CategoryByID(c, form.CategoryID)
if cate == nil || cate.State == Mamdl.StateOff {
return material, fmt.Errorf("category_id is wrong")
}
}
return
}
func stateMaterial(c *bm.Context) {
var (
req = c.Request.PostForm
ids []int64
state = parseInt(req.Get("state"))
err error
)
idStr := req.Get("id")
if ids, err = xstr.SplitInts(idStr); err != nil {
log.Error("stateMaterial strconv.ParseInt(%s) error(%v)", idStr, err)
httpCode(c, fmt.Sprintf("stateMaterial strconv.ParseInt error(%v)", err), ecode.RequestErr)
return
}
if state > 2 {
httpCode(c, "state参数可选值为 0 上架1下架2 删除", ecode.RequestErr)
return
}
//删除时保护上架状态的
if state == 2 {
if err = svc.DB.Model(Mamdl.Material{}).Where("id IN (?)", ids).Where("state !=?", 0).Update(map[string]int64{"state": state}).Error; err != nil {
log.Error("svc.stateMaterial error(%v)", err)
httpCode(c, fmt.Sprintf("stateMaterial update state error(%v)", err), ecode.RequestErr)
return
}
} else {
if err = svc.DB.Model(Mamdl.Material{}).Where("id IN (?)", ids).Update(map[string]int64{"state": state}).Error; err != nil {
log.Error("svc.stateMaterial error(%v)", err)
httpCode(c, fmt.Sprintf("stateMaterial update state error(%v)", err), ecode.RequestErr)
return
}
}
c.JSON(map[string]int{
"code": 0,
}, nil)
}
func parseInt(value string) int64 {
intval, err := strconv.ParseInt(value, 10, 64)
if err != nil {
intval = 0
}
return intval
}
func atoi(value string) (intval int) {
intval, err := strconv.Atoi(value)
if err != nil {
intval = 0
}
return intval
}
func httpCode(c *bm.Context, message string, err error) {
c.JSON(map[string]interface{}{
"message": message,
}, err)
}
func checkBuild(build string) bool {
var err error
if len(build) > 0 {
type buildItem struct {
Build int64 `json:"build"`
Conditions int8 `json:"conditions"`
}
//比较版本号符号类型,0-等于,1-小于,2-大于,3-不等于,4-小于等于,5-大于等于
//[{"conditions":0,"build":5290000},{"conditions":0,"build":5290000}]
var buildExp []*buildItem
if err = json.Unmarshal([]byte(build), &buildExp); err != nil {
return false
}
}
return true
}
func checkWhite(white string) bool {
var err error
if len(white) > 0 {
var whiteExp []*app.WhiteExp
if err = json.Unmarshal([]byte(white), &whiteExp); err != nil {
return false
}
}
return true
}

View File

@@ -0,0 +1,188 @@
package http
import (
"go-common/app/admin/main/creative/model/logcli"
"go-common/app/admin/main/creative/model/material"
"go-common/app/admin/main/creative/model/music"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/binding"
"github.com/jinzhu/gorm"
)
func searchMCategory(c *bm.Context) {
var (
req = c.Request.Form
err error
items []*material.Category
count int64
name = req.Get("name")
page = atoi(req.Get("page"))
typeStr = req.Get("type")
size = 20
)
if page == 0 {
page = 1
}
db := svc.DB.Where("state!=?", material.StateOff)
if typeStr != "" {
db = db.Where("type=?", atoi(typeStr))
}
if name != "" {
db = db.Where("name=?", name)
}
db.Model(&material.Category{}).Count(&count)
if err = db.Model(&material.Category{}).Order("rank ASC").Offset((page - 1) * size).Limit(size).Find(&items).Error; err != nil {
log.Error("%v\n", err)
c.JSON(nil, err)
return
}
pager := &material.CategoryPager{
Items: items,
Pager: &material.Pager{Num: page, Size: size, Total: count},
}
c.JSON(pager, nil)
}
func category(c *bm.Context) {
var (
req = c.Request.Form
id = parseInt(req.Get("id"))
err error
)
m := &material.CategoryParam{}
if err = svc.DB.Where("id=?", id).First(&m).Error; err != nil {
c.JSON(nil, ecode.NothingFound)
return
}
c.JSON(map[string]*material.CategoryParam{
"data": m,
}, nil)
}
func editMCategory(c *bm.Context) {
var (
req = c.Request.PostForm
id = parseInt(req.Get("id"))
err error
)
uid, uname := getUIDName(c)
m := &material.CategoryParam{}
if err = c.BindWith(m, binding.Form); err != nil {
return
}
exist := material.Category{}
if err = svc.DB.Where("id=?", id).Where("state!=?", material.StateOff).First(&exist).Error; err != nil {
c.JSON(nil, ecode.NothingFound)
return
}
m.UID = uid
if err := svc.DB.Model(&material.Category{}).Where("id=?", id).Update(m).Update(map[string]interface{}{"type": m.Type}).Update(map[string]interface{}{"new": m.New}).Error; err != nil {
log.Error("svc.editMCategory error(%v)", err)
c.JSON(nil, err)
return
}
svc.SendMusicLog(c, logcli.LogClientArchiveMaterialTypeCategory, &music.LogParam{ID: m.ID, UID: uid, UName: uname, Action: "edit", Name: exist.Name})
c.JSON(map[string]int{
"code": 0,
}, nil)
}
func indexMCategory(c *bm.Context) {
var (
err error
)
uid, uname := getUIDName(c)
m := &music.IndexParam{}
if err = c.BindWith(m, binding.Form); err != nil {
return
}
exist := material.Category{}
if err = svc.DB.Where("id=?", m.ID).Where("state!=?", material.StateOff).First(&exist).Error; err != nil {
log.Error("svc.indexMCategory error(%v)", err)
c.JSON(nil, err)
return
}
exist1 := material.Category{}
if err = svc.DB.Where("id=?", m.SwitchID).Where("state!=?", material.StateOff).First(&exist1).Error; err != nil {
log.Error("svc.indexMCategory error(%v)", err)
c.JSON(nil, err)
return
}
m.UID = uid
if err := svc.DB.Model(&material.Category{}).Where("id=?", m.ID).Update(map[string]int64{"rank": m.SwitchIndex}).Update(map[string]int64{"uid": uid}).Error; err != nil {
log.Error("svc.indexMCategory error(%v)", err)
c.JSON(nil, err)
return
}
if err := svc.DB.Model(&material.Category{}).Where("id=?", m.SwitchID).Update(map[string]int64{"rank": m.Index}).Update(map[string]int64{"uid": uid}).Error; err != nil {
log.Error("svc.indexMCategory error(%v)", err)
c.JSON(nil, err)
return
}
svc.SendMusicLog(c, logcli.LogClientArchiveMaterialTypeCategory, &music.LogParam{ID: m.ID, UID: uid, UName: uname, Action: "index", Name: exist.Name})
c.JSON(map[string]int{
"code": 0,
}, nil)
}
func addMCategory(c *bm.Context) {
var (
err error
)
uid, uname := getUIDName(c)
m := &material.CategoryParam{}
if err = c.BindWith(m, binding.Form); err != nil {
log.Error("svc.addCategory bind error(%v)", err)
return
}
m.UID = uid
//Category.type 跟素材type一致
exist := &material.Category{}
if err = svc.DB.Where("state!=?", material.StateOff).Where("name=?", m.Name).Where("type=?", m.Type).First(&exist).Error; err != nil && err != gorm.ErrRecordNotFound {
c.JSON(nil, err)
return
}
if exist.ID > 0 {
c.JSON(map[string]int64{
"id": exist.ID,
}, nil)
return
}
if err = svc.DB.Create(m).Error; err != nil {
log.Error("svc.addMCategory Create error(%v)", err)
c.JSON(nil, err)
return
}
svc.SendMusicLog(c, logcli.LogClientArchiveMaterialTypeCategory, &music.LogParam{ID: m.ID, UID: uid, UName: uname, Action: "add", Name: m.Name})
c.JSON(map[string]int64{
"id": m.ID,
}, nil)
}
func delMCategory(c *bm.Context) {
var (
req = c.Request.PostForm
id = parseInt(req.Get("id"))
err error
)
exist := material.Category{}
if err = svc.DB.Where("id=?", id).Where("state!=?", material.StateOff).First(&exist).Error; err != nil {
c.JSON(nil, err)
return
}
uid, uname := getUIDName(c)
if err := svc.DB.Model(material.Category{}).Where("id=?", id).Update(map[string]int{"state": material.StateOff}).Update(map[string]int64{"uid": uid}).Error; err != nil {
log.Error("svc.delMCategory error(%v)", err)
c.JSON(nil, err)
return
}
svc.SendMusicLog(c, logcli.LogClientArchiveMaterialTypeCategory, &music.LogParam{ID: id, UID: uid, UName: uname, Action: "del", Name: exist.Name})
c.JSON(map[string]int{
"code": 0,
}, nil)
}

View File

@@ -0,0 +1,247 @@
package http
import (
"encoding/json"
"fmt"
"go-common/app/admin/main/creative/model/logcli"
"go-common/app/admin/main/creative/model/music"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/binding"
"go-common/library/xstr"
"github.com/jinzhu/gorm"
"github.com/pkg/errors"
)
func searchMusic(c *bm.Context) {
var (
req = c.Request.Form
err error
items []*music.Music
count int64
mid = atoi(req.Get("mid"))
sid = atoi(req.Get("sid"))
tid = req.Get("tid")
musicans = req.Get("musicans")
name = req.Get("name")
page = atoi(req.Get("page"))
size = 20
)
if page == 0 {
page = 1
}
db := svc.DBArchive.Model(&music.Music{}).Where("music.state!=?", music.MusicDelete).
Joins("left join music_with_material on music.sid=music_with_material.sid and music_with_material.state !=? ", music.MusicDelete).
Joins("left join music_material on music_with_material.tid=music_material.id").
Select("music.*,music_material.name as material_name,music_material.pid as pid,music_material.id as tid,music_with_material.id as rid")
if mid != 0 {
db = db.Where("music.mid=?", mid)
}
if sid != 0 {
db = db.Where("music.sid=?", sid)
}
//未添加分类的BGM filter tid=0 filter
if tid != "" {
if atoi(tid) == 0 {
db = db.Where("music_with_material.tid is null")
} else {
db = db.Where("music_with_material.tid=?", atoi(tid))
}
}
if name != "" {
db = db.Where("music.name=?", name)
}
if musicans != "" {
db = db.Where("music.musicians=?", musicans)
}
db.Count(&count)
//投稿时间ctime 倒序排列
if err = db.Order("music.ctime DESC").Offset((page - 1) * size).Limit(size).Find(&items).Error; err != nil {
log.Error("%v\n", err)
c.JSON(nil, err)
return
}
pager := &music.ResultPager{
Items: items,
Pager: &music.Pager{Num: page, Size: size, Total: count},
}
c.JSON(pager, nil)
}
func editMusicTimeline(c *bm.Context) {
var (
req = c.Request.PostForm
sid = parseInt(req.Get("sid"))
timeline = req.Get("timeline")
err error
)
if len(timeline) > 0 {
type timelineItem struct {
//转换成毫秒存储
Point int64 `json:"point"`
Comment string `json:"comment"`
Recommend int8 `json:"recommend"`
}
var timelineExp []*timelineItem
if err = json.Unmarshal([]byte(timeline), &timelineExp); err != nil {
httpCode(c, "timeline json is wrong", ecode.RequestErr)
return
}
}
exist := music.Music{}
if err = svc.DBArchive.Where("sid=?", sid).Where("state!=?", music.MusicDelete).First(&exist).Error; err != nil {
httpCode(c, "sid不存在", ecode.RequestErr)
return
}
if err := svc.DBArchive.Model(&music.Music{}).Where("sid=?", sid).Update(map[string]string{"timeline": timeline}).Error; err != nil {
log.Error("vdaSvc.editMusicTimeline error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(map[string]int{
"code": 0,
}, nil)
}
//开放来修改一些不复杂的数据
func editMusic(c *bm.Context) {
var (
req = c.Request.PostForm
sid = parseInt(req.Get("sid"))
cooperate = req.Get("cooperate")
err error
)
exist := music.Music{}
if err = svc.DBArchive.Where("sid=?", sid).Where("state!=?", music.MusicDelete).First(&exist).Error; err != nil {
httpCode(c, "sid不存在", ecode.RequestErr)
return
}
if err := svc.DBArchive.Model(&music.Music{}).Where("sid=?", sid).Update(map[string]int{"cooperate": atoi(cooperate)}).Error; err != nil {
log.Error("vdaSvc.editMusic error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(map[string]int{
"code": 0,
}, nil)
}
func editMusicTags(c *bm.Context) {
var (
req = c.Request.PostForm
sid = parseInt(req.Get("sid"))
tags = req.Get("tags")
err error
)
exist := music.Music{}
if err = svc.DBArchive.Where("sid=?", sid).Where("state!=?", music.MusicDelete).First(&exist).Error; err != nil {
httpCode(c, "sid不存在", ecode.RequestErr)
return
}
if err := svc.DBArchive.Model(&music.Music{}).Where("sid=?", sid).Update(map[string]string{"tags": tags}).Error; err != nil {
log.Error("vdaSvc.editMusicTags error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(map[string]int{
"code": 0,
}, nil)
}
func batchEditMusicTags(c *bm.Context) {
var (
req = c.Request.PostForm
sids = req.Get("sids")
tags = req.Get("tags")
arrids []int64
err error
)
if arrids, err = xstr.SplitInts(sids); err != nil {
log.Error("svc.batchEditMusicTags SplitInts error(%v)", err)
c.JSON(nil, err)
return
}
if len(arrids) < 2 {
c.JSON(nil, fmt.Errorf("sids参数错误"))
}
if err = svc.DBArchive.Model(&music.Music{}).Where("sid IN (?)", arrids).Update(map[string]string{"tags": tags}).Error; err != nil {
log.Error("vdaSvc.batchEditMusicTags error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(map[string]int{
"code": 0,
}, nil)
}
//用户侧BGM名称 front_name
func editMusicFrontName(c *bm.Context) {
var (
req = c.Request.PostForm
sid = parseInt(req.Get("sid"))
frontname = req.Get("frontname")
err error
)
exist := music.Music{}
if err = svc.DBArchive.Where("sid=?", sid).Where("state!=?", music.MusicDelete).First(&exist).Error; err != nil {
httpCode(c, "sid不存在", ecode.RequestErr)
return
}
if err := svc.DBArchive.Model(&music.Music{}).Where("sid=?", sid).Update(map[string]string{"frontname": frontname}).Error; err != nil {
log.Error("vdaSvc.editMusicName error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(map[string]int{
"code": 0,
}, nil)
}
func syncMusic(c *bm.Context) {
var (
err error
)
mp := &music.Param{}
if err = c.BindWith(mp, binding.Form); err != nil {
log.Error("svc.syncMusic bind error(%+v)", err)
log.Error("svc.syncMusic bind error trace(%+v)", errors.Wrap(err, "sync bind error"))
return
}
m := &music.Music{Sid: mp.Sid, Name: mp.Name, Cover: mp.Cover, Stat: mp.Stat, Mid: mp.Mid, Musicians: mp.Musicians, Categorys: mp.Categorys, Playurl: mp.Playurl, PubTime: mp.PubTime, Duration: mp.Duration, Filesize: mp.Filesize, State: mp.State}
if m.State != music.MusicDelete {
m.State = music.MusicOpen
}
exist := music.Music{}
if err = svc.DBArchive.Where("sid=?", mp.Sid).First(&exist).Error; err != nil && err != gorm.ErrRecordNotFound {
log.Error("svc.syncMusic find error(%+v)", err)
c.JSON(nil, errors.Wrap(err, "sync find sid error"))
return
}
uid, uname := getUIDName(c)
if exist.ID > 0 {
m.ID = exist.ID
if err = svc.DBArchive.Model(&music.Music{}).Where("sid=?", mp.Sid).Update(m).Update(map[string]int8{"state": m.State}).Error; err != nil {
log.Error("svc.syncMusic update error(%+v)", err)
c.JSON(nil, errors.Wrap(err, "sync update error"))
return
}
if m.State == music.MusicDelete {
svc.SendMusicLog(c, logcli.LogClientArchiveMusicTypeMusic, &music.LogParam{ID: m.ID, UID: uid, UName: uname, Action: "del", Name: m.Name})
} else {
svc.SendMusicLog(c, logcli.LogClientArchiveMusicTypeMusic, &music.LogParam{ID: m.ID, UID: uid, UName: uname, Action: "update", Name: m.Name})
}
} else {
if err = svc.DBArchive.Create(m).Error; err != nil {
log.Error("svc.syncMusic Create error(%+v)", err)
c.JSON(nil, errors.Wrap(err, "sync add error"))
return
}
svc.SendMusicLog(c, logcli.LogClientArchiveMusicTypeMusic, &music.LogParam{ID: m.ID, UID: uid, UName: uname, Action: "add", Name: m.Name})
}
c.JSON(map[string]int64{
"id": m.ID,
}, nil)
}

View File

@@ -0,0 +1,201 @@
package http
import (
"go-common/app/admin/main/creative/model/logcli"
"go-common/app/admin/main/creative/model/music"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/binding"
"github.com/jinzhu/gorm"
)
func searchCategory(c *bm.Context) {
var (
req = c.Request.Form
err error
items []*music.Category
count int64
pid = atoi(req.Get("pid"))
name = req.Get("name")
page = atoi(req.Get("page"))
sort = atoi(req.Get("sort"))
size = 20
order string
)
if page == 0 {
page = 1
}
db := svc.DBArchive.Where("state!=?", music.MusicDelete)
if pid != 0 {
db = db.Where("pid=?", pid)
}
//pid 目前不做分级 pid=0
if name != "" {
db = db.Where("name=?", name)
}
db.Model(&music.Category{}).Count(&count)
if sort == 1 {
order = "camera_index"
} else {
order = "index"
}
if err = db.Model(&music.Category{}).Order(order).Offset((page - 1) * size).Limit(size).Find(&items).Error; err != nil {
log.Error("%v\n", err)
c.JSON(nil, err)
return
}
pager := &music.CategoryPager{
Items: items,
Pager: &music.Pager{Num: page, Size: size, Total: count},
}
c.JSON(pager, nil)
}
func categoryInfo(c *bm.Context) {
var (
req = c.Request.Form
id = parseInt(req.Get("id"))
err error
)
m := &music.CategoryParam{}
if err = svc.DBArchive.Where("id=?", id).First(&m).Error; err != nil {
c.JSON(nil, ecode.NothingFound)
return
}
c.JSON(map[string]*music.CategoryParam{
"data": m,
}, nil)
}
func editCategory(c *bm.Context) {
var (
req = c.Request.PostForm
id = parseInt(req.Get("id"))
err error
)
uid, uname := getUIDName(c)
m := &music.CategoryParam{}
if err = c.BindWith(m, binding.Form); err != nil {
return
}
exist := music.Category{}
if err = svc.DBArchive.Where("id=?", id).Where("state!=?", music.MusicDelete).First(&exist).Error; err != nil {
c.JSON(nil, ecode.NothingFound)
return
}
m.UID = uid
if err := svc.DBArchive.Model(&music.Category{}).Where("id=?", id).Update(m).Error; err != nil {
log.Error("svc.editCategory error(%v)", err)
c.JSON(nil, err)
return
}
svc.SendMusicLog(c, logcli.LogClientArchiveMusicTypeCategory, &music.LogParam{ID: m.ID, UID: uid, UName: uname, Action: "index", Name: exist.Name})
c.JSON(map[string]int{
"code": 0,
}, nil)
}
func indexCategory(c *bm.Context) {
var (
req = c.Request.PostForm
err error
cate = atoi(req.Get("type"))
column string
)
uid, uname := getUIDName(c)
m := &music.IndexParam{}
if err = c.BindWith(m, binding.Form); err != nil {
return
}
exist := music.Category{}
if err = svc.DBArchive.Where("id=?", m.ID).Where("state!=?", music.MusicDelete).First(&exist).Error; err != nil {
log.Error("svc.indexCategory error(%v)", err)
c.JSON(nil, err)
return
}
exist1 := music.Category{}
if err = svc.DBArchive.Where("id=?", m.SwitchID).Where("state!=?", music.MusicDelete).First(&exist1).Error; err != nil {
log.Error("svc.indexCategory error(%v)", err)
c.JSON(nil, err)
return
}
if cate == 1 {
column = "camera_index"
} else {
column = "index"
}
m.UID = uid
if err := svc.DBArchive.Model(&music.Category{}).Where("id=?", m.ID).Update(map[string]int64{column: m.SwitchIndex}).Update(map[string]int64{"uid": uid}).Error; err != nil {
log.Error("svc.indexCategory error(%v)", err)
c.JSON(nil, err)
return
}
if err := svc.DBArchive.Model(&music.Category{}).Where("id=?", m.SwitchID).Update(map[string]int64{column: m.Index}).Update(map[string]int64{"uid": uid}).Error; err != nil {
log.Error("svc.indexCategory error(%v)", err)
c.JSON(nil, err)
return
}
svc.SendMusicLog(c, logcli.LogClientArchiveMusicTypeCategory, &music.LogParam{ID: m.ID, UID: uid, UName: uname, Action: "index", Name: exist.Name})
c.JSON(map[string]int{
"code": 0,
}, nil)
}
func addCategory(c *bm.Context) {
var (
err error
)
uid, uname := getUIDName(c)
m := &music.CategoryParam{}
if err = c.BindWith(m, binding.Form); err != nil {
log.Error("svc.addCategory bind error(%v)", err)
return
}
m.UID = uid
exist := &music.Category{}
if err = svc.DBArchive.Where("state!=?", music.MusicDelete).Where("name=?", m.Name).First(&exist).Error; err != nil && err != gorm.ErrRecordNotFound {
c.JSON(nil, err)
return
}
if exist.ID > 0 {
c.JSON(map[string]int64{
"id": exist.ID,
}, nil)
return
}
if err = svc.DBArchive.Create(m).Error; err != nil {
log.Error("svc.addCategory Create error(%v)", err)
c.JSON(nil, err)
return
}
svc.SendMusicLog(c, logcli.LogClientArchiveMusicTypeCategory, &music.LogParam{ID: m.ID, UID: uid, UName: uname, Action: "add", Name: m.Name})
c.JSON(map[string]int64{
"id": m.ID,
}, nil)
}
func delCategory(c *bm.Context) {
var (
req = c.Request.PostForm
id = parseInt(req.Get("id"))
err error
)
exist := music.Category{}
if err = svc.DBArchive.Where("id=?", id).Where("state!=?", music.MusicDelete).First(&exist).Error; err != nil {
c.JSON(nil, err)
return
}
uid, uname := getUIDName(c)
if err := svc.DBArchive.Model(music.Category{}).Where("id=?", id).Update(map[string]int{"state": music.MusicDelete}).Update(map[string]int64{"uid": uid}).Error; err != nil {
log.Error("svc.delCategory error(%v)", err)
c.JSON(nil, err)
return
}
svc.SendMusicLog(c, logcli.LogClientArchiveMusicTypeCategory, &music.LogParam{ID: id, UID: uid, UName: uname, Action: "del", Name: exist.Name})
c.JSON(map[string]int{
"code": 0,
}, nil)
}

View File

@@ -0,0 +1,178 @@
package http
import (
"go-common/app/admin/main/creative/model/logcli"
"go-common/app/admin/main/creative/model/music"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/binding"
"go-common/library/xstr"
"github.com/jinzhu/gorm"
)
func searchMaterial(c *bm.Context) {
var (
req = c.Request.Form
err error
items []*music.MaterialMixParent
count int64
pid = atoi(req.Get("pid"))
name = req.Get("name")
)
db := svc.DBArchive.Where("music_material.state!=?", music.MusicDelete)
if pid != 0 {
db = db.Where("music_material.pid=?", pid)
}
if name != "" {
db = db.Where("music_material.name=?", name)
}
db.Model(&music.Material{}).Count(&count)
if err = db.Model(&music.Material{}).
Joins("left join music_material p on p.id=music_material.pid").
Select("music_material.*,p.name as p_name").
Order("music_material.index").Find(&items).Error; err != nil {
log.Error("%v\n", err)
c.JSON(nil, err)
return
}
pager := &music.MaterialMixParentPager{
Pager: &music.Pager{Num: 1, Size: int(count), Total: count},
Items: items,
}
c.JSON(pager, nil)
}
func materialInfo(c *bm.Context) {
var (
req = c.Request.Form
id = parseInt(req.Get("id"))
err error
)
m := &music.MaterialParam{}
if err = svc.DBArchive.Where("id=?", id).Where("state!=?", music.MusicDelete).First(&m).Error; err != nil {
c.JSON(nil, ecode.NothingFound)
return
}
c.JSON(map[string]*music.MaterialParam{
"data": m,
}, nil)
}
func editMaterial(c *bm.Context) {
var (
req = c.Request.PostForm
id = parseInt(req.Get("id"))
err error
)
m := &music.MaterialParam{}
if err = c.BindWith(m, binding.Form); err != nil {
return
}
exist := music.Material{}
if err = svc.DBArchive.Where("id=?", id).Where("state!=?", music.MusicDelete).First(&exist).Error; err != nil {
c.JSON(nil, ecode.NothingFound)
return
}
uid, uname := getUIDName(c)
m.UID = uid
if err = svc.DBArchive.Model(&music.Material{}).Where("id=?", id).Update(m).Error; err != nil {
log.Error("svc.editMaterial error(%v)", err)
c.JSON(nil, err)
return
}
svc.SendMusicLog(c, logcli.LogClientArchiveMusicTypeMaterial, &music.LogParam{ID: m.ID, UID: uid, UName: uname, Action: "update", Name: m.Name})
c.JSON(map[string]int{
"code": 0,
}, nil)
}
func addMaterial(c *bm.Context) {
var (
err error
)
m := &music.MaterialParam{}
if err = c.BindWith(m, binding.Form); err != nil {
return
}
uid, uname := getUIDName(c)
m.UID = uid
exist := &music.Material{}
if err = svc.DBArchive.Where("state!=?", music.MusicDelete).Where("name=?", m.Name).First(&exist).Error; err != nil && err != gorm.ErrRecordNotFound {
c.JSON(nil, err)
return
}
if exist.ID > 0 {
c.JSON(map[string]int64{
"id": exist.ID,
}, nil)
return
}
if err = svc.DBArchive.Create(m).Error; err != nil {
log.Error("svc.addMaterial error(%v)", err)
c.JSON(nil, err)
return
}
svc.SendMusicLog(c, logcli.LogClientArchiveMusicTypeMaterial, &music.LogParam{ID: m.ID, UID: uid, UName: uname, Action: "add", Name: m.Name})
c.JSON(map[string]int64{
"id": m.ID,
}, nil)
}
func delMaterial(c *bm.Context) {
var (
req = c.Request.PostForm
id = parseInt(req.Get("id"))
err error
)
exist := music.Material{}
if err = svc.DBArchive.Where("id=?", id).Where("state!=?", music.MusicDelete).First(&exist).Error; err != nil {
c.JSON(nil, ecode.NothingFound)
return
}
uid, uname := getUIDName(c)
if err = svc.DBArchive.Model(music.Material{}).Where("id=?", id).Update(map[string]int{"state": music.MusicDelete}).Update(map[string]int64{"uid": uid}).Error; err != nil {
log.Error("svc.delMaterial error(%v)", err)
c.JSON(nil, err)
return
}
svc.SendMusicLog(c, logcli.LogClientArchiveMusicTypeMaterial, &music.LogParam{ID: id, UID: uid, UName: uname, Action: "del", Name: exist.Name})
c.JSON(map[string]int{
"code": 0,
}, nil)
}
func batchDeleteMaterial(c *bm.Context) {
var (
err error
req = c.Request.PostForm
ids = req.Get("ids")
arrids []int64
)
uid, uname := getUIDName(c)
if arrids, err = xstr.SplitInts(ids); err != nil {
log.Error("svc.batchDeleteCategoryRelation SplitInts error(%v)", err)
c.JSON(nil, err)
return
}
for _, id := range arrids {
if err = svc.DBArchive.Model(music.Material{}).Where("id=?", id).Update(map[string]int{"state": music.MusicDelete}).Error; err != nil {
log.Error("svc.batchDeleteMaterial error(%v)", err)
err = nil
continue
}
//for log
exist := music.Material{}
if err = svc.DBArchive.Where("id=?", id).First(&exist).Error; err != nil {
err = nil
continue
}
svc.SendMusicLog(c, logcli.LogClientArchiveMusicTypeMaterial, &music.LogParam{ID: id, UID: uid, UName: uname, Action: "del", Name: exist.Name})
}
c.JSON(map[string]int64{
"code": 0,
}, nil)
}

View File

@@ -0,0 +1,315 @@
package http
import (
"go-common/app/admin/main/creative/model/logcli"
"go-common/app/admin/main/creative/model/music"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/binding"
"go-common/library/xstr"
"github.com/jinzhu/gorm"
)
func searchCategoryRelation(c *bm.Context) {
var (
req = c.Request.Form
err error
items []*music.CategoryList
count int64
mid = atoi(req.Get("mid"))
tid = atoi(req.Get("tid"))
sid = atoi(req.Get("sid"))
name = req.Get("name")
page = atoi(req.Get("page"))
size = 20
)
if page == 0 {
page = 1
}
//init sql
db := svc.DBArchive.Model(&music.CategoryList{}).
Joins("left join music on music.sid=music_with_category.sid").
Joins("left join music_category on music_category.id=music_with_category.tid").
Where("music_with_category.state !=?", music.MusicDelete).
Where("music.state !=?", music.MusicDelete).
Select("music_with_category.*,music_category.name as category_name,music.name,music.cover,music.playurl,music.duration,music.mid,music.musicians,music.state as music_state,music.tags,music.timeline,music.frontname,music.cooperate")
if mid != 0 {
db = db.Where("mid=?", mid)
}
if sid != 0 {
db = db.Where("music_with_category.sid=?", sid)
}
if name != "" {
db = db.Where("music_category.name=?", name)
}
if tid != 0 {
db = db.Where("music_with_category.tid=?", tid)
}
//count total
db.Model(&music.CategoryList{}).Count(&count)
if err = db.Order("music_with_category.index").Offset((page - 1) * size).Limit(size).Find(&items).Error; err != nil {
log.Error("%v\n", err)
c.JSON(nil, err)
return
}
pager := &music.CategoryListPager{
Pager: &music.Pager{Num: page, Size: size, Total: count},
Items: items,
}
c.JSON(pager, nil)
}
func musicCategoryRelationInfo(c *bm.Context) {
var (
req = c.Request.Form
id = parseInt(req.Get("id"))
err error
)
m := &music.WithCategoryParam{}
if err = svc.DBArchive.Where("id=?", id).Where("state!=?", music.MusicDelete).First(&m).Error; err != nil {
c.JSON(nil, ecode.NothingFound)
return
}
c.JSON(map[string]*music.WithCategoryParam{
"data": m,
}, nil)
}
func editCategoryRelation(c *bm.Context) {
var (
req = c.Request.PostForm
id = parseInt(req.Get("id"))
err error
)
uid, uname := getUIDName(c)
m := &music.WithCategoryParam{}
if err = c.BindWith(m, binding.Form); err != nil {
httpCode(c, "参数错误", ecode.RequestErr)
return
}
exist := music.WithCategory{}
if err = svc.DBArchive.Where("id=?", id).Where("state!=?", music.MusicDelete).First(&exist).Error; err != nil {
c.JSON(nil, ecode.NothingFound)
return
}
if err = svc.DBArchive.Model(&music.WithCategory{}).Where("id=?", id).Update(m).Error; err != nil {
log.Error("svc.editCategoryRelation error(%v)", err)
c.JSON(nil, err)
return
}
svc.SendMusicLog(c, logcli.LogClientArchiveMusicTypeCategoryRelation, &music.LogParam{ID: m.ID, UID: uid, UName: uname, Action: "update", Name: string(m.ID)})
c.JSON(map[string]int{
"code": 0,
}, nil)
}
func indexCategoryRelation(c *bm.Context) {
var (
err error
)
uid, uname := getUIDName(c)
m := &music.IndexParam{}
if err = c.BindWith(m, binding.Form); err != nil {
return
}
exist := music.WithCategory{}
if err = svc.DBArchive.Where("id=?", m.ID).Where("state!=?", music.MusicDelete).First(&exist).Error; err != nil {
c.JSON(nil, ecode.NothingFound)
return
}
exist1 := music.WithCategory{}
if err = svc.DBArchive.Where("id=?", m.SwitchID).Where("state!=?", music.MusicDelete).First(&exist1).Error; err != nil {
c.JSON(nil, ecode.NothingFound)
return
}
if err = svc.DBArchive.Model(&music.WithCategory{}).Where("id=?", m.ID).Update(map[string]int64{"index": m.SwitchIndex}).Update(map[string]int64{"uid": uid}).Error; err != nil {
log.Error("svc.indexCategoryRelation error(%v)", err)
c.JSON(nil, err)
return
}
if err = svc.DBArchive.Model(&music.WithCategory{}).Where("id=?", m.SwitchID).Update(map[string]int64{"index": m.Index}).Update(map[string]int64{"uid": uid}).Error; err != nil {
log.Error("svc.indexCategoryRelation error(%v)", err)
c.JSON(nil, err)
return
}
svc.SendMusicLog(c, logcli.LogClientArchiveMusicTypeCategoryRelation, &music.LogParam{ID: m.ID, UID: uid, UName: uname, Action: "index", Name: string(m.ID)})
c.JSON(map[string]int{
"code": 0,
}, nil)
}
func addCategoryRelation(c *bm.Context) {
var (
err error
)
uid, uname := getUIDName(c)
m := &music.WithCategoryParam{}
if err = c.BindWith(m, binding.Form); err != nil {
log.Error("svc.addCategoryRelation bind error(%v)", err)
return
}
exist := &music.WithCategory{}
if err = svc.DBArchive.Where("state!=?", music.MusicDelete).Where("sid=?", m.Sid).Where("tid=?", m.Tid).First(&exist).Error; err != nil && err != gorm.ErrRecordNotFound {
c.JSON(nil, err)
return
}
if exist.ID > 0 {
c.JSON(map[string]int64{
"id": exist.ID,
}, nil)
return
}
if err = svc.DBArchive.Create(m).Error; err != nil {
log.Error("svc.addCategoryRelation error(%v)", err)
c.JSON(nil, err)
return
}
svc.SendMusicLog(c, logcli.LogClientArchiveMusicTypeCategoryRelation, &music.LogParam{ID: m.ID, UID: uid, UName: uname, Action: "add", Name: string(m.ID)})
c.JSON(map[string]int64{
"id": m.ID,
}, nil)
}
func batchAddCategoryRelation(c *bm.Context) {
var (
err error
sids, sendIds []int64
sidsNotify = make(map[int64]*music.SidNotify)
)
uid, uname := getUIDName(c)
m := &music.BatchMusicWithCategoryParam{}
if err = c.BindWith(m, binding.Form); err != nil {
log.Error("svc.batchAddCategoryRelation bind error(%v)", err)
return
}
//todo tid 必须是二级分类
if sids, err = xstr.SplitInts(m.SidList); err != nil {
log.Error("svc.batchAddCategoryRelation SplitInts error(%v)", err)
c.JSON(nil, err)
return
}
max := music.WithCategory{}
if err = svc.DBArchive.Model(&music.WithCategory{}).Where("tid=?", m.Tid).Where("state!=?", music.MusicDelete).Order("music_with_category.index desc").First(&max).Error; err != nil && err != gorm.ErrRecordNotFound {
log.Error("svc.batchAddMaterialRelation max error(%v)", err)
c.JSON(nil, err)
return
}
thisIndex := max.Index
i := int64(1)
for _, sid := range sids {
sidnotify := music.SidNotify{Sid: sid}
//find mid
musicExist := music.Music{}
if err = svc.DBArchive.Model(&music.Music{}).Where("sid=?", sid).First(&musicExist).Error; err != nil {
log.Error("svc.batchAddMaterialRelation check exist sid (%d) error(%v)", sid, err)
continue
}
//check mid first bind
midExists := music.WithCategory{}
if err = svc.DBArchive.Model(&music.WithCategory{}).Joins("left join music on music.sid=music_with_category.sid").Where("music.mid=?", musicExist.Mid).First(&midExists).Error; err != nil && err != gorm.ErrRecordNotFound {
log.Error("svc.batchAddMaterialRelation check mid exist sid mid (%d,%d) error(%v)", sid, musicExist.Mid, err)
c.JSON(nil, err)
return
}
if err == gorm.ErrRecordNotFound {
sidnotify.MidFirst = true
}
//check sid bind
sidExists := music.WithCategory{}
if err = svc.DBArchive.Model(&music.WithCategory{}).Where("sid=?", sid).First(&sidExists).Error; err != nil && err != gorm.ErrRecordNotFound {
log.Error("svc.batchAddMaterialRelation check sid exist sid mid (%d,%d) error(%v)", sid, musicExist.Mid, err)
c.JSON(nil, err)
return
}
if err == gorm.ErrRecordNotFound {
sidnotify.SidFirst = true
}
//check sid-tid bind exists
exists := music.WithCategory{}
if err = svc.DBArchive.Model(&music.WithCategory{}).Where("sid=?", sid).Where("tid=?", m.Tid).Where("state!=?", music.MusicDelete).First(&exists).Error; err != nil && err != gorm.ErrRecordNotFound {
log.Error("svc.batchAddMaterialRelation check exist sid tid (%d,%d) error(%v)", sid, m.Tid, err)
c.JSON(nil, err)
return
}
if exists.ID > 0 {
//pass
continue
}
//should create bind
mp := &music.WithCategoryParam{Sid: sid, Tid: m.Tid, Index: thisIndex + i}
if err = svc.DBArchive.Create(mp).Error; err != nil {
log.Error("svc.batchAddMaterialRelation Create error(%v)", err)
continue
}
sidsNotify[sid] = &sidnotify
i++
svc.SendMusicLog(c, logcli.LogClientArchiveMusicTypeCategoryRelation, &music.LogParam{ID: mp.Sid, UID: uid, UName: uname, Action: "add", Name: string(mp.Sid)})
}
log.Info("svc.SendNotify param SendList(%+v) sidsNotify(%+v)", m.SendList, sidsNotify)
if m.SendList != "" {
if sendIds, err = xstr.SplitInts(m.SendList); err != nil {
log.Error("svc.batchAddCategoryRelation SplitInts SendList error(%v)", err)
c.JSON(nil, err)
return
}
log.Info("svc.SendNotify param sendIds(%+v) sidsNotify(%+v)", sendIds, sidsNotify)
svc.SendNotify(c, sendIds, sidsNotify)
}
c.JSON(map[string]int64{
"code": 0,
}, nil)
}
func batchDeleteCategoryRelation(c *bm.Context) {
var (
err error
req = c.Request.PostForm
ids = req.Get("ids")
arrids []int64
)
uid, uname := getUIDName(c)
if arrids, err = xstr.SplitInts(ids); err != nil {
log.Error("svc.batchDeleteCategoryRelation SplitInts error(%v)", err)
c.JSON(nil, err)
return
}
for _, id := range arrids {
if err = svc.DBArchive.Model(music.WithCategory{}).Where("id=?", id).Update(map[string]int{"state": music.MusicDelete}).Error; err != nil {
log.Error("svc.batchDeleteCategoryRelation error(%v)", err)
err = nil
continue
}
svc.SendMusicLog(c, logcli.LogClientArchiveMusicTypeCategoryRelation, &music.LogParam{ID: id, UID: uid, UName: uname, Action: "delete", Name: string(id)})
}
c.JSON(map[string]int64{
"code": 0,
}, nil)
}
func delCategoryRelation(c *bm.Context) {
var (
req = c.Request.PostForm
id = parseInt(req.Get("id"))
err error
)
uid, uname := getUIDName(c)
exist := music.WithCategory{}
if err = svc.DBArchive.Where("id=?", id).Where("state!=?", music.MusicDelete).First(&exist).Error; err != nil {
c.JSON(nil, err)
return
}
if err = svc.DBArchive.Model(music.WithCategory{}).Where("id=?", id).Update(map[string]int{"state": music.MusicDelete}).Error; err != nil {
log.Error("svc.delCategoryRelation error(%v)", err)
c.JSON(nil, err)
return
}
svc.SendMusicLog(c, logcli.LogClientArchiveMusicTypeCategoryRelation, &music.LogParam{ID: id, UID: uid, UName: uname, Action: "del", Name: string(exist.ID)})
c.JSON(map[string]int{
"code": 0,
}, nil)
}

View File

@@ -0,0 +1,145 @@
package http
import (
"go-common/app/admin/main/creative/model/logcli"
"go-common/app/admin/main/creative/model/music"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/binding"
"go-common/library/xstr"
"github.com/jinzhu/gorm"
)
func musicMaterialRelationInfo(c *bm.Context) {
var (
req = c.Request.Form
id = parseInt(req.Get("id"))
err error
)
m := &music.WithMaterialParam{}
if err = svc.DBArchive.Where("id=?", id).First(&m).Error; err != nil {
c.JSON(nil, ecode.NothingFound)
return
}
c.JSON(map[string]*music.WithMaterialParam{
"data": m,
}, nil)
}
func editMaterialRelation(c *bm.Context) {
var (
err error
)
uid, uname := getUIDName(c)
m := &music.WithMaterialParam{}
if err = c.BindWith(m, binding.Form); err != nil {
return
}
exist := music.WithMaterial{}
if err = svc.DBArchive.Where("sid=?", m.Sid).Where("state!=?", music.MusicDelete).First(&exist).Error; err != nil {
c.JSON(nil, ecode.NothingFound)
return
}
m.ID = exist.ID
m.UID = uid
m.Index = exist.Index
if err = svc.DBArchive.Model(&music.WithMaterial{}).Where("id=?", exist.ID).Update(m).Error; err != nil {
log.Error("svc.editMaterialRelation error(%v)", err)
c.JSON(nil, err)
return
}
svc.SendMusicLog(c, logcli.LogClientArchiveMusicTypeMaterialRelation, &music.LogParam{ID: m.ID, UID: uid, UName: uname, Action: "update", Name: string(m.ID)})
c.JSON(map[string]int{
"code": 0,
}, nil)
}
func addMaterialRelation(c *bm.Context) {
var (
err error
)
m := &music.WithMaterialParam{}
if err = c.BindWith(m, binding.Form); err != nil {
return
}
exist := &music.WithMaterial{}
//一期 sid tid 是 一一对应的关系
//check sid bind
if err = svc.DBArchive.Where("state!=?", music.MusicDelete).Where("sid=?", m.Sid).First(&exist).Error; err != nil && err != gorm.ErrRecordNotFound {
c.JSON(nil, err)
return
}
if exist.ID > 0 {
c.JSON(map[string]int64{
"id": exist.ID,
}, nil)
return
}
if err = svc.DBArchive.Create(m).Error; err != nil {
log.Error("svc.addMaterialRelation error(%v)", err)
c.JSON(nil, err)
return
}
uid, uname := getUIDName(c)
svc.SendMusicLog(c, logcli.LogClientArchiveMusicTypeMaterialRelation, &music.LogParam{ID: m.ID, UID: uid, UName: uname, Action: "add", Name: string(m.ID)})
c.JSON(map[string]int64{
"id": m.ID,
}, nil)
}
func batchAddMaterialRelation(c *bm.Context) {
var (
err error
sids []int64
)
uid, uname := getUIDName(c)
m := &music.BatchMusicWithMaterialParam{}
if err = c.BindWith(m, binding.Form); err != nil {
log.Error("svc.batchAddMaterialRelation bind error(%v)", err)
return
}
//todo tid 必须是二级分类
if sids, err = xstr.SplitInts(m.SidList); err != nil {
log.Error("svc.batchAddMaterialRelation SplitInts error(%v)", err)
c.JSON(nil, err)
return
}
max := music.WithMaterial{}
if err = svc.DBArchive.Model(&music.WithMaterial{}).Where("tid=?", m.Tid).Where("state!=?", music.MusicDelete).Order("music_with_material.index desc").First(&max).Error; err != nil && err != gorm.ErrRecordNotFound {
//sql err
log.Error("svc.batchAddMaterialRelation max index error(%v)", err)
return
}
thisIndex := max.Index
i := int64(1)
for _, sid := range sids {
//check exists
exists := music.WithMaterial{}
if err = svc.DBArchive.Model(&music.WithMaterial{}).Where("sid=?", sid).Where("state!=?", music.MusicDelete).First(&exists).Error; err != nil && err != gorm.ErrRecordNotFound {
log.Error("svc.batchAddMaterialRelation check exist sid tid (%d,%d) error(%v)", sid, m.Tid, err)
c.JSON(nil, err)
return
}
if exists.ID > 0 {
//覆盖
if err = svc.DBArchive.Model(&music.WithMaterial{}).Where("sid=?", sid).Where("state!=?", music.MusicDelete).Update("tid", m.Tid).Error; err != nil && err != gorm.ErrRecordNotFound {
log.Error("svc.batchAddMaterialRelation Update error(%v)", err)
continue
}
svc.SendMusicLog(c, logcli.LogClientArchiveMusicTypeMaterialRelation, &music.LogParam{ID: exists.Sid, UID: uid, UName: uname, Action: "update", Name: string(exists.Sid)})
} else {
mp := &music.WithMaterialParam{Sid: sid, Tid: m.Tid, Index: thisIndex + i}
if err = svc.DBArchive.Create(mp).Error; err != nil {
log.Error("svc.batchAddMaterialRelation Create error(%v)", err)
continue
}
i++
svc.SendMusicLog(c, logcli.LogClientArchiveMusicTypeMaterialRelation, &music.LogParam{ID: mp.Sid, UID: uid, UName: uname, Action: "add", Name: string(mp.Sid)})
}
}
c.JSON(map[string]int64{
"code": 0,
}, nil)
}

View File

@@ -0,0 +1,192 @@
package http
import (
"go-common/app/admin/main/creative/model/operation"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/render"
"net/http"
"time"
)
func listCollectArcOper(c *bm.Context) {
var (
err error
ops []*operation.Operation
total int
)
v := new(struct {
Type int8 `form:"type"`
Platform int8 `form:"platform"`
Pn int `form:"pn" validate:"min=1"`
Ps int `form:"ps" validate:"min=1"`
})
if err = c.Bind(v); err != nil {
return
}
if v.Pn < 1 {
v.Pn = 1
}
if v.Ps < 20 {
v.Ps = 20
}
if _, ok := typesMap[v.Type]; !ok {
data := map[string]interface{}{
"code": ecode.RequestErr,
"message": "forbid request with wrong type enum value",
}
c.Render(http.StatusOK, render.MapJSON(data))
return
}
if _, ok := platformMap[v.Platform]; !ok {
data := map[string]interface{}{
"code": ecode.RequestErr,
"message": "forbid request with wrong platform enum value",
}
c.Render(http.StatusOK, render.MapJSON(data))
return
}
now := time.Now().Format("2006-01-02 15:04:05")
where := " dtime = '0000-00-00 00:00:00' AND type = 'collect_arc' AND platform = ?"
if v.Platform == 100 {
where = " dtime = '0000-00-00 00:00:00' AND type = 'collect_arc' "
}
if v.Type == 0 {
where += " AND (stime < ? AND etime > ?) "
} else if v.Type == 1 {
where += " AND (stime > ? OR etime < ?) "
} else if v.Type == 2 {
where += " AND 1=1 "
}
if v.Type == 2 {
if v.Platform == 100 {
if err = svc.DB.Debug().Model(&operation.Operation{}).Order("rank ASC").Offset((v.Pn-1)*v.Ps).Limit(v.Ps).Find(&ops, where).Error; err != nil {
c.JSON(nil, err)
return
}
svc.DB.Debug().Model(&operation.Operation{}).Where(where).Count(&total)
} else {
if err = svc.DB.Debug().Model(&operation.Operation{}).Order("rank ASC").Offset((v.Pn-1)*v.Ps).Limit(v.Ps).Find(&ops, where, v.Platform).Error; err != nil {
c.JSON(nil, err)
return
}
svc.DB.Debug().Model(&operation.Operation{}).Where(where, v.Platform).Count(&total)
}
} else {
if v.Platform == 100 {
if err = svc.DB.Debug().Model(&operation.Operation{}).Order("rank ASC").Offset((v.Pn-1)*v.Ps).Limit(v.Ps).Find(&ops, where, now, now).Error; err != nil {
c.JSON(nil, err)
return
}
svc.DB.Debug().Model(&operation.Operation{}).Where(where, now, now).Count(&total)
} else {
if err = svc.DB.Debug().Model(&operation.Operation{}).Order("rank ASC").Offset((v.Pn-1)*v.Ps).Limit(v.Ps).Find(&ops, where, v.Platform, now, now).Error; err != nil {
c.JSON(nil, err)
return
}
svc.DB.Debug().Model(&operation.Operation{}).Where(where, v.Platform, now, now).Count(&total)
}
}
var opsView []*operation.ViewOperation
layout := "2006-01-02 15:04:05"
for _, v := range ops {
var (
status string
timeNow = time.Now()
stime, _ = time.Parse(time.RFC3339, v.Stime)
etime, _ = time.Parse(time.RFC3339, v.Etime)
ctime, _ = time.Parse(time.RFC3339, v.Ctime)
mtime, _ = time.Parse(time.RFC3339, v.Mtime)
dtime, _ = time.Parse(time.RFC3339, v.Dtime)
)
if time.Now().Before(etime) && timeNow.After(stime) {
status = "显示"
} else {
status = "隐藏"
}
opsView = append(opsView, &operation.ViewOperation{
ID: v.ID,
Type: v.Type,
Ads: v.Ads,
Platform: v.Platform,
Rank: v.Rank,
Pic: v.Pic,
Link: v.Link,
Content: v.Content,
Username: v.Username,
Remark: v.Remark,
Note: v.Note,
AppPic: v.AppPic,
Stime: stime.Format(layout),
Etime: etime.Format(layout),
Ctime: ctime.Format(layout),
Dtime: dtime.Format(layout),
Mtime: mtime.Format(layout),
Status: status,
})
}
c.Render(http.StatusOK, render.MapJSON(map[string]interface{}{
"code": 0,
"message": "0",
"data": opsView,
"pager": map[string]int{
"page": v.Pn,
"pagesize": v.Ps,
"total": total,
},
}))
}
func addCollectArcOper(c *bm.Context) {
var (
err error
)
username, _ := c.Get("username")
uname, ok := username.(string)
if !ok || len(uname) == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
v := new(struct {
Ads int8 `form:"ads" `
Rank int8 `form:"rank"`
Pic string `form:"pic" validate:"required"`
Link string `form:"link" validate:"required"`
Content string `form:"content" validate:"required"`
Remark string `form:"remark"`
Note string `form:"note"`
AppPic string `form:"app_pic" validate:"required"`
Platform int8 `form:"platform"`
Stime string `form:"stime" validate:"required"`
Etime string `form:"etime" validate:"required"`
})
if err = c.Bind(v); err != nil {
return
}
m := &operation.Operation{
Type: "collect_arc",
Ads: v.Ads,
Rank: v.Rank,
Pic: v.Pic,
Link: v.Link,
Content: v.Content,
Username: uname,
Remark: v.Remark,
Note: v.Note,
AppPic: v.AppPic,
Platform: v.Platform,
Ctime: time.Now().Format("2006-01-02 15:04:05"),
Stime: v.Stime,
Etime: v.Etime,
}
db := svc.DB.Debug().Model(&operation.Operation{}).Create(m)
if err = db.Error; err != nil {
log.Error("creativeSvc.Operation error(%v)", err)
c.JSON(nil, ecode.RequestErr)
return
}
c.JSON(map[string]interface{}{
"id": db.Value.(*operation.Operation).ID,
}, nil)
}

View File

@@ -0,0 +1,522 @@
package http
import (
"encoding/json"
"io/ioutil"
"net/http"
"go-common/app/admin/main/creative/model/task"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/render"
"go-common/library/xstr"
)
func taskList(c *bm.Context) {
var err error
v := new(struct {
Type int8 `form:"type"`
})
if err = c.Bind(v); err != nil {
return
}
res, err := svc.TaskList(v.Type)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(res, nil)
}
func taskPre(c *bm.Context) {
c.Render(http.StatusOK, render.MapJSON(map[string]interface{}{
"code": 0,
"message": "0",
"data": map[string]interface{}{
"target": task.TargetMap,
"root_type": task.TaskRootNameMap,
"group_type": task.TaskGroupNameMap,
},
}))
}
func viewGroup(c *bm.Context) {
var err error
v := new(struct {
ID int64 `form:"id"`
})
if err = c.Bind(v); err != nil {
return
}
if v.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
res, err := svc.TaskGroup(v.ID)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(res, nil)
}
func addGroup(c *bm.Context) {
var err error
v := new(task.TaskGroup)
if err = c.Bind(v); err != nil {
log.Error("addGroup c.Bind v(%+v) error(%v)", v, err)
return
}
var rewardsIDs []int64
if v.RewardIDs != "" {
if rewardsIDs, err = xstr.SplitInts(v.RewardIDs); err != nil {
log.Error("addGroup xstr.SplitInts task v.RewardIDs(%s) rewardsIDs(%+v)|error(%v)", v.RewardIDs, rewardsIDs, err)
c.JSON(nil, ecode.RequestErr)
return
}
}
id, err := svc.AddTaskGroup(v, rewardsIDs)
if err != nil {
c.JSON(nil, err)
return
}
uid, uname := getUIDName(c)
svc.SendTaskLog(c, &task.LogParam{UID: uid, UName: uname, Action: "添加任务组", OID: id, Content: v})
c.JSON(map[string]interface{}{
"id": id,
}, nil)
}
func editGroup(c *bm.Context) {
var err error
v := new(task.TaskGroup)
if err = c.Bind(v); err != nil {
log.Error("editGroup c.Bind v(%+v) error(%v)", v, err)
return
}
if v.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
var rewardsIDs []int64
if v.RewardIDs != "" {
if rewardsIDs, err = xstr.SplitInts(v.RewardIDs); err != nil {
log.Error("editGroup xstr.SplitInts task v.RewardIDs(%s) rewardsIDs(%+v)|error(%v)", v.RewardIDs, rewardsIDs, err)
c.JSON(nil, ecode.RequestErr)
return
}
}
id, err := svc.EditTaskGroup(v, rewardsIDs)
if err != nil {
c.JSON(nil, err)
return
}
uid, uname := getUIDName(c)
svc.SendTaskLog(c, &task.LogParam{UID: uid, UName: uname, Action: "编辑任务组", OID: id, Content: v})
c.JSON(map[string]interface{}{
"id": id,
}, nil)
}
func orderGroup(c *bm.Context) {
var err error
v := new(task.OrderTask)
if err = c.Bind(v); err != nil {
log.Error("orderGroup c.Bind v(%+v) error(%v)", v, err)
return
}
uid, uname := getUIDName(c)
svc.SendTaskLog(c, &task.LogParam{UID: uid, UName: uname, Action: "移动任务组顺序", OID: v.ID, Content: v})
c.JSON(nil, svc.OrderTaskGroup(v))
}
func upStateGroup(c *bm.Context) {
var err error
v := new(struct {
ID int64 `form:"id" validate:"required"`
State int8 `form:"state"`
})
if err = c.Bind(v); err != nil {
log.Error("upStateGroup c.Bind v(%+v) error(%v)", v, err)
return
}
if v.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
uid, uname := getUIDName(c)
svc.SendTaskLog(c, &task.LogParam{UID: uid, UName: uname, Action: "更新任务组状态", OID: v.ID, Content: v})
c.JSON(nil, svc.UpStateGroup(v.ID, v.State))
}
func viewSubtask(c *bm.Context) {
var err error
v := new(struct {
ID int64 `form:"id"`
})
if err = c.Bind(v); err != nil {
return
}
if v.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
res, err := svc.Task(v.ID)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(res, nil)
}
func addSubtask(c *bm.Context) {
var err error
v := new(task.Task)
if err = c.Bind(v); err != nil {
log.Error("addSubtask c.Bind v(%+v) error(%v)", v, err)
return
}
var rewardsIDs []int64
if v.RewardIDs != "" {
if rewardsIDs, err = xstr.SplitInts(v.RewardIDs); err != nil {
log.Error("addSubtask xstr.SplitInts task v.RewardIDs(%s) rewardsIDs(%+v)|error(%v)", v.RewardIDs, rewardsIDs, err)
c.JSON(nil, ecode.RequestErr)
return
}
}
id, err := svc.AddSubtask(v, rewardsIDs)
if err != nil {
c.JSON(nil, err)
return
}
uid, uname := getUIDName(c)
svc.SendTaskLog(c, &task.LogParam{UID: uid, UName: uname, Action: "添加子任务", OID: id, Content: v})
c.JSON(map[string]interface{}{
"id": id,
}, nil)
}
func editSubtask(c *bm.Context) {
var err error
v := new(task.Task)
if err = c.Bind(v); err != nil {
log.Error("editSubtask c.Bind v(%+v) error(%v)", v, err)
return
}
if v.ID == 0 {
log.Error("editSubtask v.ID(%d)", v.ID)
c.JSON(nil, ecode.RequestErr)
return
}
var rewardsIDs []int64
if v.RewardIDs != "" {
if rewardsIDs, err = xstr.SplitInts(v.RewardIDs); err != nil {
log.Error("addSubtask xstr.SplitInts task v.RewardIDs(%s) rewardsIDs(%+v)|error(%v)", v.RewardIDs, rewardsIDs, err)
c.JSON(nil, ecode.RequestErr)
return
}
}
id, err := svc.EditSubtask(v, rewardsIDs)
if err != nil {
c.JSON(nil, err)
return
}
uid, uname := getUIDName(c)
svc.SendTaskLog(c, &task.LogParam{UID: uid, UName: uname, Action: "编辑子任务", OID: id, Content: v})
c.JSON(map[string]interface{}{
"id": id,
}, nil)
}
func orderSubtask(c *bm.Context) {
var err error
v := new(task.OrderTask)
if err = c.Bind(v); err != nil {
log.Error("orderSubtask c.Bind v(%+v) error(%v)", v, err)
return
}
uid, uname := getUIDName(c)
svc.SendTaskLog(c, &task.LogParam{UID: uid, UName: uname, Action: "移动子任务顺序", OID: v.ID, Content: v})
c.JSON(nil, svc.OrderSubTask(v))
}
func upStateSubtask(c *bm.Context) {
var err error
v := new(struct {
ID int64 `form:"id" validate:"required"`
State int8 `form:"state"`
})
if err = c.Bind(v); err != nil {
log.Error("upStateSubtask c.Bind v(%+v) error(%v)", v, err)
return
}
if v.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
uid, uname := getUIDName(c)
svc.SendTaskLog(c, &task.LogParam{UID: uid, UName: uname, Action: "更新子任务状态", OID: v.ID, Content: v})
c.JSON(nil, svc.UpStateSubTask(v.ID, v.State))
}
func transferSubtask(c *bm.Context) {
var err error
v := new(struct {
ID int64 `form:"id" validate:"required"`
GroupID int64 `form:"group_id" validate:"required"`
})
if err = c.Bind(v); err != nil {
log.Error("transferSubtask c.Bind v(%+v) error(%v)", v, err)
return
}
if v.ID == 0 || v.GroupID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
uid, uname := getUIDName(c)
svc.SendTaskLog(c, &task.LogParam{UID: uid, UName: uname, Action: "转移子任务到别的组", OID: v.ID, Content: v})
c.JSON(nil, svc.TransferSubtask(v.ID, v.GroupID))
}
func rewardTree(c *bm.Context) {
c.JSON(svc.RewardTree(), nil)
}
func viewReward(c *bm.Context) {
var err error
v := new(struct {
ID int64 `form:"id"`
})
if err = c.Bind(v); err != nil {
return
}
if v.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
rd, err := svc.ViewReward(v.ID)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(rd, nil)
}
func addReward(c *bm.Context) {
var err error
v := new(task.Reward)
if err = c.Bind(v); err != nil {
log.Error("addReward c.Bind v(%+v) error(%v)", v, err)
return
}
id, err := svc.AddReward(v)
if err != nil {
c.JSON(nil, err)
return
}
uid, uname := getUIDName(c)
svc.SendTaskLog(c, &task.LogParam{UID: uid, UName: uname, Action: "添加奖励", OID: id, Content: v})
c.JSON(map[string]interface{}{
"id": id,
}, nil)
}
func editReward(c *bm.Context) {
var err error
v := new(task.Reward)
if err = c.Bind(v); err != nil {
log.Error("editReward c.Bind v(%+v) error(%v)", v, err)
return
}
if v.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
id, err := svc.EditReward(v)
if err != nil {
c.JSON(nil, err)
return
}
uid, uname := getUIDName(c)
svc.SendTaskLog(c, &task.LogParam{UID: uid, UName: uname, Action: "编辑奖励", OID: id, Content: v})
c.JSON(map[string]interface{}{
"id": id,
}, nil)
}
func upStateReward(c *bm.Context) {
var err error
v := new(struct {
ID int64 `form:"id" validate:"required"`
State int8 `form:"state"`
})
if err = c.Bind(v); err != nil {
log.Error("upStateReward c.Bind v(%+v) error(%v)", v, err)
return
}
if v.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
uid, uname := getUIDName(c)
svc.SendTaskLog(c, &task.LogParam{UID: uid, UName: uname, Action: "更新奖励状态", OID: v.ID, Content: v})
c.JSON(nil, svc.UpStateReward(v.ID, v.State))
}
func listGiftReward(c *bm.Context) {
res, err := svc.ListGiftReward()
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(res, nil)
}
func viewGiftReward(c *bm.Context) {
var err error
v := new(task.GiftReward)
if err = c.Bind(v); err != nil {
return
}
if v.RootType == 0 || v.TaskType == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
res, err := svc.ViewGiftReward(v)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(res, nil)
}
func addGiftReward(c *bm.Context) {
var err error
v := new(task.GiftReward)
if err = c.Bind(v); err != nil {
log.Error("addGiftReward c.Bind v(%+v) error(%v)", v, err)
return
}
var rewardsIDs []int64
if v.RewardIDs == "" {
c.JSON(nil, ecode.RequestErr)
return
}
if rewardsIDs, err = xstr.SplitInts(v.RewardIDs); err != nil || len(rewardsIDs) == 0 { //注意礼包配置,奖励必传
log.Error("addGiftReward xstr.SplitInts task v.RewardIDs(%s) rewardsIDs(%+v)|error(%v)", v.RewardIDs, rewardsIDs, err)
c.JSON(nil, ecode.RequestErr)
return
}
rows, err := svc.AddGiftReward(v, rewardsIDs)
if err != nil {
c.JSON(nil, err)
return
}
uid, uname := getUIDName(c)
svc.SendTaskLog(c, &task.LogParam{UID: uid, UName: uname, Action: "添加礼包", OID: 0, Content: v})
c.JSON(map[string]interface{}{
"rows": rows,
}, nil)
}
func editGiftReward(c *bm.Context) {
var err error
v := new(task.GiftReward)
if err = c.Bind(v); err != nil {
log.Error("editGiftReward c.Bind v(%+v) error(%v)", v, err)
return
}
if v.RootType == 0 || v.TaskType == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
var rewardsIDs []int64
if v.RewardIDs == "" {
c.JSON(nil, ecode.RequestErr)
return
}
if rewardsIDs, err = xstr.SplitInts(v.RewardIDs); err != nil || len(rewardsIDs) == 0 { //注意礼包配置,奖励必传
log.Error("editGiftReward xstr.SplitInts task v.RewardIDs(%s) rewardsIDs(%+v)|error(%v)", v.RewardIDs, rewardsIDs, err)
c.JSON(nil, ecode.RequestErr)
return
}
rows, err := svc.EditGiftReward(v, rewardsIDs)
if err != nil {
c.JSON(nil, err)
return
}
uid, uname := getUIDName(c)
svc.SendTaskLog(c, &task.LogParam{UID: uid, UName: uname, Action: "编辑礼包", OID: 0, Content: v})
c.JSON(map[string]interface{}{
"rows": rows,
}, nil)
}
func upStateGiftReward(c *bm.Context) {
var err error
v := new(task.GiftReward)
if err = c.Bind(v); err != nil {
log.Error("upStateGiftReward c.Bind v(%+v) error(%v)", v, err)
return
}
if v.RootType == 0 || v.TaskType == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
rows, err := svc.UpGiftReward(v)
if err != nil {
c.JSON(nil, err)
return
}
uid, uname := getUIDName(c)
svc.SendTaskLog(c, &task.LogParam{UID: uid, UName: uname, Action: "更新礼包状态", OID: 0, Content: v})
c.JSON(map[string]interface{}{
"rows": rows,
}, nil)
}
func batchOnline(c *bm.Context) {
var err error
bs, err := ioutil.ReadAll(c.Request.Body)
if err != nil {
log.Error("batchOnline ioutil.ReadAll error(%v)", err)
c.JSON(nil, ecode.RequestErr)
return
}
c.Request.Body.Close()
var v []*task.TaskGroup
err = json.Unmarshal(bs, &v)
if err != nil {
log.Error("batchOnline json.Unmarshal v(%+v) error(%v)", v, err)
c.JSON(nil, ecode.RequestErr)
return
}
err = svc.BatchOnline(v)
if err != nil {
c.JSON(nil, err)
return
}
uid, uname := getUIDName(c)
svc.SendTaskLog(c, &task.LogParam{UID: uid, UName: uname, Action: "批量刷新上线", OID: 0, Content: v})
c.JSON(nil, nil)
}

View File

@@ -0,0 +1,46 @@
package http
import (
"fmt"
"io/ioutil"
"net/http"
"time"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
func upload(c *bm.Context) {
file, _, err := c.Request.FormFile("file")
if err != nil {
log.Error("FormFile err(%v)", err)
httpCode(c, fmt.Sprintf("File Upload FormFile Error:(%v)", err), ecode.RequestErr)
return
}
defer file.Close()
content, err := ioutil.ReadAll(file)
if err != nil {
log.Error(" uploadFile.ReadAll error(%v)", err)
httpCode(c, fmt.Sprintf("File ioutil.ReadAll Error:(%v)", err), ecode.RequestErr)
return
}
filetype := http.DetectContentType(content)
switch filetype {
case "image/jpeg", "image/jpg":
case "image/gif":
case "image/png":
case "application/zip":
default:
httpCode(c, fmt.Sprintf("not allow filetype(%s)", filetype), ecode.RequestErr)
log.Warn("not allow filetype(%s) ", filetype)
return
}
local, err := svc.Upload(c, "", filetype, time.Now().Unix(), content)
if err != nil {
log.Error("svc.Upload error(%v)", err)
httpCode(c, fmt.Sprintf("svc.Upload error:(%v)", err), ecode.RequestErr)
return
}
c.JSON(local, nil)
}

View File

@@ -0,0 +1,93 @@
package http
import (
"crypto/md5"
"encoding/hex"
"flag"
"fmt"
"go-common/app/admin/main/creative/conf"
"io/ioutil"
"net/http"
"net/url"
"path/filepath"
"strconv"
"strings"
"testing"
"time"
. "github.com/smartystreets/goconvey/convey"
)
const (
_host = "http://0.0.0.0:6344"
)
var (
_view = _host + "/x/admin/creative/whitelist/view"
)
func init() {
dir, _ := filepath.Abs("../cmd/creative-admin.toml")
flag.Set("conf", dir)
conf.Init()
}
// Sign fn
func Sign(params url.Values) (query string, err error) {
if len(params) == 0 {
return
}
if params.Get("appkey") == "" {
err = fmt.Errorf("utils http get must have parameter appkey")
return
}
if params.Get("appsecret") == "" {
err = fmt.Errorf("utils http get must have parameter appsecret")
return
}
if params.Get("sign") != "" {
err = fmt.Errorf("utils http get must have not parameter sign")
return
}
// sign
secret := params.Get("appsecret")
params.Del("appsecret")
tmp := params.Encode()
if strings.IndexByte(tmp, '+') > -1 {
tmp = strings.Replace(tmp, "+", "%20", -1)
}
mh := md5.Sum([]byte(tmp + secret))
params.Set("sign", hex.EncodeToString(mh[:]))
query = params.Encode()
return
}
func Test_View(t *testing.T) {
Convey("View", t, func() {
params := url.Values{}
params.Set("id", "7")
params.Set("appkey", conf.Conf.App.Key)
params.Set("appsecret", conf.Conf.App.Secret)
params.Set("ts", strconv.FormatInt(time.Now().Unix(), 10))
var (
query, _ = Sign(params)
url string
)
url = _view + "?" + query
body, err := oget(url)
So(err, ShouldBeNil)
So(body, ShouldNotBeNil)
So(err, ShouldBeNil)
})
}
// oget http get request
func oget(url string) (body []byte, err error) {
resp, err := http.Get(url)
if err != nil {
return
}
defer resp.Body.Close()
body, err = ioutil.ReadAll(resp.Body)
return
}

View File

@@ -0,0 +1,348 @@
package http
import (
"encoding/json"
"fmt"
"go-common/app/admin/main/creative/model/whitelist"
accapi "go-common/app/service/main/account/api"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/render"
"net/http"
"time"
)
var maxMid = int64(2147483647)
func viewWhiteList(c *bm.Context) {
var (
err error
info = &whitelist.Whitelist{}
)
if err = c.Bind(info); err != nil {
return
}
if info.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
if err = svc.DB.Debug().Model(&whitelist.Whitelist{}).First(info, info.ID).Error; err != nil {
c.JSON(nil, err)
return
}
if info.ID == 0 {
c.JSON(nil, ecode.NothingFound)
} else {
pfl, _ := svc.ProfileStat(c, info.MID)
if pfl.Profile != nil {
info.Name = pfl.Profile.Name
}
info.Fans = pfl.Follower
info.CurrentLevel = pfl.LevelInfo.Cur
c.JSON(info, nil)
}
}
func listWhiteList(c *bm.Context) {
var (
err error
wls []*whitelist.Whitelist
total int
)
v := new(struct {
MID int64 `form:"mid"`
AdminMID int64 `form:"admin_mid"`
State int8 `form:"state"`
Type int8 `form:"type"`
Page int `form:"pn"`
PageSize int `form:"ps"`
})
if err = c.Bind(v); err != nil {
return
}
if v.Page < 1 {
v.Page = 1
}
if v.PageSize < 20 {
v.PageSize = 20
}
where := " state = ? AND type = ? "
if v.MID != 0 {
where += " AND mid = ?"
if v.AdminMID != 0 {
where += " AND admin_id = ?"
if err = svc.DB.Debug().Model(&whitelist.Whitelist{}).Order("ctime DESC").Offset((v.Page-1)*v.PageSize).Limit(v.PageSize).Find(&wls, where, v.State, v.Type, v.MID, v.AdminMID).Error; err != nil {
c.JSON(nil, err)
}
svc.DB.Debug().Model(&whitelist.Whitelist{}).Where(where, v.State, v.Type, v.MID, v.AdminMID).Count(&total)
} else {
if err = svc.DB.Debug().Model(&whitelist.Whitelist{}).Order("ctime DESC").Offset((v.Page-1)*v.PageSize).Limit(v.PageSize).Find(&wls, where, v.State, v.Type, v.MID).Error; err != nil {
c.JSON(nil, err)
}
svc.DB.Debug().Model(&whitelist.Whitelist{}).Where(where, v.State, v.Type, v.MID).Count(&total)
}
} else {
if v.AdminMID != 0 {
where += " AND admin_id = ?"
if err = svc.DB.Debug().Model(&whitelist.Whitelist{}).Order("ctime DESC").Offset((v.Page-1)*v.PageSize).Limit(v.PageSize).Find(&wls, where, v.State, v.Type, v.AdminMID).Error; err != nil {
c.JSON(nil, err)
}
svc.DB.Debug().Model(&whitelist.Whitelist{}).Where(where, v.State, v.Type, v.AdminMID).Count(&total)
} else {
if err = svc.DB.Debug().Model(&whitelist.Whitelist{}).Order("ctime DESC").Offset((v.Page-1)*v.PageSize).Limit(v.PageSize).Find(&wls, where, v.State, v.Type).Error; err != nil {
c.JSON(nil, err)
}
svc.DB.Debug().Model(&whitelist.Whitelist{}).Where(where, v.State, v.Type).Count(&total)
}
}
wls, err = svc.Cards(c, wls)
if err != nil {
log.Error("svc.Cards error(%v)", err)
c.JSON(nil, err)
return
}
c.Render(http.StatusOK, render.MapJSON(map[string]interface{}{
"code": 0,
"message": "0",
"data": wls,
"pager": map[string]int{
"page": v.Page,
"pagesize": v.PageSize,
"total": total,
},
}))
}
func exportWhiteList(c *bm.Context) {
var (
err error
wls []*whitelist.Whitelist
total int
)
v := new(struct {
MID int64 `form:"mid;" `
AdminMID int64 `form:"admin_mid;" `
State int8 `form:"state"`
Type int8 `form:"type"`
Page int `form:"pn"`
PageSize int `form:"ps"`
})
if err = c.Bind(v); err != nil {
return
}
if v.Page < 1 {
v.Page = 1
}
if v.PageSize < 20 {
v.PageSize = 20
}
where := " state = ? AND type = ? "
if v.MID != 0 {
where += " AND mid = ?"
if v.AdminMID != 0 {
where += " AND admin_id = ?"
if err = svc.DB.Debug().Model(&whitelist.Whitelist{}).Order("ctime DESC").Offset((v.Page-1)*v.PageSize).Limit(v.PageSize).Find(&wls, where, v.State, v.Type, v.MID, v.AdminMID).Error; err != nil {
c.JSON(nil, err)
}
svc.DB.Debug().Model(&whitelist.Whitelist{}).Where(where, v.State, v.Type, v.MID, v.AdminMID).Count(&total)
} else {
if err = svc.DB.Debug().Model(&whitelist.Whitelist{}).Order("ctime DESC").Offset((v.Page-1)*v.PageSize).Limit(v.PageSize).Find(&wls, where, v.State, v.Type, v.MID).Error; err != nil {
c.JSON(nil, err)
}
svc.DB.Debug().Model(&whitelist.Whitelist{}).Where(where, v.State, v.Type, v.MID).Count(&total)
}
} else {
if v.AdminMID != 0 {
where += " AND admin_id = ?"
if err = svc.DB.Debug().Model(&whitelist.Whitelist{}).Order("ctime DESC").Offset((v.Page-1)*v.PageSize).Limit(v.PageSize).Find(&wls, where, v.State, v.Type, v.AdminMID).Error; err != nil {
c.JSON(nil, err)
}
svc.DB.Debug().Model(&whitelist.Whitelist{}).Where(where, v.State, v.Type, v.AdminMID).Count(&total)
} else {
if err = svc.DB.Debug().Model(&whitelist.Whitelist{}).Order("ctime DESC").Offset((v.Page-1)*v.PageSize).Limit(v.PageSize).Find(&wls, where, v.State, v.Type).Error; err != nil {
c.JSON(nil, err)
}
svc.DB.Debug().Model(&whitelist.Whitelist{}).Where(where, v.State, v.Type).Count(&total)
}
}
wls, err = svc.Cards(c, wls)
if err != nil {
log.Error("svc.Cards error(%v)", err)
c.JSON(nil, err)
return
}
fWLS, err := formatWhilteList(wls)
if err != nil {
log.Error("formatWhilteList error(%v)", err)
c.JSON(nil, err)
return
}
c.Render(http.StatusOK, CSV{
Content: FormatCSV(fWLS),
Title: fmt.Sprintf("%s-%d-%d-%s", time.Now().Format("2006-01-02"), v.Type, v.State, "white_list"),
})
}
func addWhiteList(c *bm.Context) {
var (
err error
pfl *accapi.ProfileStatReply
)
v := new(struct {
MID int64 `form:"mid" validate:"required,min=1,gte=1"`
AdminMID int64 `form:"admin_mid" validate:"required,min=1,gte=1"`
Comment string `form:"comment"`
State int8 `form:"state"`
Type int8 `form:"type"`
})
if err = c.Bind(v); err != nil {
return
}
if v.MID > maxMid || v.AdminMID > maxMid {
c.JSON(nil, ecode.RequestErr)
return
}
pfl, err = svc.ProfileStat(c, v.MID)
if err != nil || pfl == nil || pfl.Profile == nil || pfl.Profile.Mid == 0 {
log.Error("svc.Card zero result error(%v)", err)
c.JSON(nil, ecode.UserNotExist)
return
}
m := &whitelist.Whitelist{
State: v.State,
Type: v.Type,
Ctime: time.Now().Format("2006-01-02 15:04:05"),
MID: v.MID,
AdminMID: v.AdminMID,
Comment: v.Comment,
}
db := svc.DB.Debug().Model(&whitelist.Whitelist{}).Create(m)
if err = db.Error; err != nil {
log.Error("creativeSvc.whitelist error(%v)", err)
c.JSON(nil, err)
}
c.JSON(map[string]interface{}{
"id": db.Value.(*whitelist.Whitelist).ID,
}, nil)
}
func addBatchWhiteList(c *bm.Context) {
var (
err error
)
v := new(struct {
Params string `form:"params" validate:"required"`
})
if err = c.Bind(v); err != nil {
return
}
filterJSON := v.Params
if len(filterJSON) == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
type Filter struct {
MID int64 `json:"mid"`
AdminMID int64 `json:"admin_mid"`
Comment string `json:"comment"`
State int8 `json:"state"`
Type int8 `json:"type"`
}
var filtersJSONData []*Filter
if err = json.Unmarshal([]byte(filterJSON), &filtersJSONData); err != nil {
err = ecode.RequestErr
return
}
if len(filtersJSONData) == 0 {
err = ecode.RequestErr
return
}
db := svc.DB.Debug().Model(&whitelist.Whitelist{})
for _, v := range filtersJSONData {
m := &whitelist.Whitelist{
State: v.State,
Type: v.Type,
Ctime: time.Now().Format("2006-01-02 15:04:05"),
MID: v.MID,
AdminMID: v.AdminMID,
Comment: v.Comment,
}
db.Create(m)
if err = db.Error; err != nil {
log.Error("creativeSvc.batchWhitelist error(%v)", err)
c.JSON(nil, err)
return
}
}
c.JSON(nil, err)
}
func upWhiteList(c *bm.Context) {
var (
wl = &whitelist.Whitelist{}
pfl *accapi.ProfileStatReply
err error
)
v := new(struct {
ID int64 `form:"id"`
MID int64 `form:"mid" validate:"required,min=1,gte=1"`
AdminMID int64 `form:"admin_mid" validate:"required,min=1,gte=1"`
Comment string `form:"comment"`
})
if err = c.Bind(v); err != nil {
return
}
if v.ID == 0 || v.MID > maxMid || v.AdminMID > maxMid {
c.JSON(nil, ecode.RequestErr)
return
}
pfl, err = svc.ProfileStat(c, v.MID)
if err != nil || pfl == nil || pfl.Profile == nil || pfl.Profile.Mid == 0 {
log.Error("svc.Card zero result error(%v)", err)
c.JSON(nil, ecode.UserNotExist)
return
}
if err = svc.DB.Debug().Model(&whitelist.Whitelist{}).Find(wl, v.ID).Error; err != nil {
c.JSON(nil, err)
return
}
if err = svc.DB.Debug().Model(&whitelist.Whitelist{ID: v.ID}).Update(map[string]interface {
}{
"id": v.ID,
"mid": v.MID,
"admin_mid": v.AdminMID,
"comment": v.Comment,
"mtime": time.Now().Format("2006-01-02 15:04:05"),
}).Error; err != nil {
log.Error("svc.save error(%v)", err)
}
c.JSON(nil, err)
}
func delWhiteList(c *bm.Context) {
var (
wl = &whitelist.Whitelist{}
err error
)
if err = c.Bind(wl); err != nil {
return
}
if wl.ID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
if err = svc.DB.Debug().Model(&whitelist.Whitelist{}).Find(wl, wl.ID).Error; err != nil {
c.JSON(nil, err)
return
}
if err = svc.DB.Debug().Model(&whitelist.Whitelist{ID: wl.ID}).Update(map[string]interface {
}{
"id": wl.ID,
"State": 0,
"mtime": time.Now().Format("2006-01-02 15:04:05"),
}).Error; err != nil {
log.Error("svc.del WhiteList error(%v)", err)
}
c.JSON(nil, err)
}