Create & Init Project...
This commit is contained in:
66
app/admin/main/answer/dao/BUILD
Normal file
66
app/admin/main/answer/dao/BUILD
Normal file
@ -0,0 +1,66 @@
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"dao.go",
|
||||
"draw.go",
|
||||
"es.go",
|
||||
"mysql.go",
|
||||
"redis.go",
|
||||
],
|
||||
importpath = "go-common/app/admin/main/answer/dao",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/admin/main/answer/conf:go_default_library",
|
||||
"//app/admin/main/answer/model:go_default_library",
|
||||
"//library/cache/redis:go_default_library",
|
||||
"//library/database/elastic:go_default_library",
|
||||
"//library/database/orm:go_default_library",
|
||||
"//library/log:go_default_library",
|
||||
"//library/time:go_default_library",
|
||||
"//vendor/github.com/golang/freetype:go_default_library",
|
||||
"//vendor/github.com/jinzhu/gorm:go_default_library",
|
||||
"//vendor/golang.org/x/image/font:go_default_library",
|
||||
"//vendor/golang.org/x/image/math/fixed:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"dao_test.go",
|
||||
"draw_test.go",
|
||||
"es_test.go",
|
||||
"mysql_test.go",
|
||||
"redis_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
rundir = ".",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//app/admin/main/answer/conf:go_default_library",
|
||||
"//app/admin/main/answer/model:go_default_library",
|
||||
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
|
||||
],
|
||||
)
|
52
app/admin/main/answer/dao/dao.go
Normal file
52
app/admin/main/answer/dao/dao.go
Normal file
@ -0,0 +1,52 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"go-common/app/admin/main/answer/conf"
|
||||
"go-common/library/cache/redis"
|
||||
"go-common/library/database/elastic"
|
||||
"go-common/library/database/orm"
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
// Dao struct info of Dao.
|
||||
type Dao struct {
|
||||
c *conf.Config
|
||||
db *gorm.DB
|
||||
es *elastic.Elastic
|
||||
redis *redis.Pool
|
||||
redisExpire int32
|
||||
}
|
||||
|
||||
// TextImgConf text img conf.
|
||||
type TextImgConf struct {
|
||||
Fontsize int
|
||||
Length int
|
||||
Ansfontsize int
|
||||
Spacing float64
|
||||
Ansspacing float64
|
||||
}
|
||||
|
||||
// New new a Dao and return.
|
||||
func New(c *conf.Config) (d *Dao) {
|
||||
d = &Dao{
|
||||
c: c,
|
||||
db: orm.NewMySQL(c.Mysql),
|
||||
es: elastic.NewElastic(nil),
|
||||
redis: redis.NewPool(c.Redis.Config),
|
||||
redisExpire: int32(time.Duration(c.Redis.Expire) / time.Second),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Close close connections of mc, redis, db.
|
||||
func (d *Dao) Close() {
|
||||
if d.db != nil {
|
||||
d.db.Close()
|
||||
}
|
||||
if d.redis != nil {
|
||||
d.redis.Close()
|
||||
}
|
||||
}
|
52
app/admin/main/answer/dao/dao_test.go
Normal file
52
app/admin/main/answer/dao/dao_test.go
Normal file
@ -0,0 +1,52 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"go-common/app/admin/main/answer/conf"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
var (
|
||||
d *Dao
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
if os.Getenv("DEPLOY_ENV") != "" {
|
||||
flag.Set("app_id", "main.account-law.answer-admin")
|
||||
flag.Set("conf_appid", "main.account-law.answer-admin")
|
||||
flag.Set("conf_token", "bec0ecd7a2799a424602f9a0daea070d")
|
||||
flag.Set("tree_id", "4752")
|
||||
flag.Set("conf_version", "docker-1")
|
||||
flag.Set("deploy_env", "uat")
|
||||
flag.Set("conf_env", "10")
|
||||
flag.Set("conf_host", "config.bilibili.co")
|
||||
flag.Set("conf_path", "/tmp")
|
||||
flag.Set("region", "sh")
|
||||
flag.Set("zone", "sh001")
|
||||
} else {
|
||||
flag.Set("conf", "../cmd/answer-admin-test.toml")
|
||||
}
|
||||
flag.Parse()
|
||||
if err := conf.Init(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
d = New(conf.Conf)
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
Convey("Close", t, func() {
|
||||
New(conf.Conf)
|
||||
})
|
||||
}
|
||||
|
||||
func TestClose(t *testing.T) {
|
||||
Convey("Close", t, func() {
|
||||
d.Close()
|
||||
d = New(conf.Conf)
|
||||
})
|
||||
}
|
120
app/admin/main/answer/dao/draw.go
Normal file
120
app/admin/main/answer/dao/draw.go
Normal file
@ -0,0 +1,120 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"image"
|
||||
"image/draw"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"unicode/utf8"
|
||||
|
||||
"go-common/library/log"
|
||||
|
||||
"github.com/golang/freetype"
|
||||
"golang.org/x/image/font"
|
||||
"golang.org/x/image/math/fixed"
|
||||
)
|
||||
|
||||
// QueConf question img conf.
|
||||
func (d *Dao) QueConf(mobile bool) (c *TextImgConf) {
|
||||
if mobile {
|
||||
// Mobile
|
||||
c = &TextImgConf{
|
||||
Fontsize: 16, // mobile font size in points
|
||||
Length: 11, // mobile question length
|
||||
Ansfontsize: 12, // mobile ans font size in points
|
||||
}
|
||||
} else {
|
||||
// PC
|
||||
c = &TextImgConf{
|
||||
Fontsize: 12, //font size in points
|
||||
Length: 36, //question length
|
||||
Ansfontsize: 10, //ans font size in points
|
||||
}
|
||||
}
|
||||
c.Spacing = 2 // line spacing (e.g. 2 means double spaced)
|
||||
c.Ansspacing = 2 // line ansspacing (e.g. 2 means double spaced)
|
||||
return
|
||||
}
|
||||
|
||||
// DrawQue draw question title.
|
||||
func (d *Dao) DrawQue(c *freetype.Context, s string, conf *TextImgConf, pt *fixed.Point26_6) {
|
||||
c.SetFontSize(float64(conf.Fontsize))
|
||||
srune := []rune(s)
|
||||
var end = conf.Length
|
||||
for len(srune) > 0 {
|
||||
if conf.Length > len(srune) {
|
||||
end = len(srune)
|
||||
}
|
||||
d.text(c, string(srune[:end]), pt, conf.Fontsize, conf.Spacing)
|
||||
srune = srune[end:]
|
||||
}
|
||||
}
|
||||
|
||||
// DrawAns draw ans
|
||||
func (d *Dao) DrawAns(c *freetype.Context, conf *TextImgConf, anss [4]string, pt *fixed.Point26_6) {
|
||||
c.SetFontSize(float64(conf.Ansfontsize))
|
||||
arr := [4]string{"A.", "B.", "C.", "D."}
|
||||
for i, a := range anss {
|
||||
d.text(c, arr[i]+a, pt, conf.Ansfontsize, conf.Ansspacing)
|
||||
}
|
||||
}
|
||||
|
||||
//Height get img height
|
||||
func (d *Dao) Height(c *TextImgConf, que string, anslen int) (h int) {
|
||||
len := utf8.RuneCountInString(que)
|
||||
line := math.Ceil(float64(len) / float64(c.Length))
|
||||
h = int(math.Ceil(c.Spacing*line*float64(c.Fontsize))) + int(math.Ceil(c.Ansspacing*float64(anslen)*float64(c.Ansfontsize)))
|
||||
return
|
||||
}
|
||||
|
||||
// text Draw text.
|
||||
func (d *Dao) text(c *freetype.Context, s string, pt *fixed.Point26_6, size int, spacing float64) (err error) {
|
||||
_, err = c.DrawString(s, *pt)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
pt.Y += fixed.Int26_6(int(float64(size)*spacing) << 6)
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
dpi = float64(72) // screen resolution in Dots Per Inch
|
||||
hinting = "none" // none | full
|
||||
)
|
||||
|
||||
// Board init draw board.
|
||||
func (d *Dao) Board(h int) (r *image.Gray) {
|
||||
bg := image.White
|
||||
r = image.NewGray(image.Rect(0, 0, 600, h))
|
||||
draw.Draw(r, r.Bounds(), bg, image.ZP, draw.Src)
|
||||
return
|
||||
}
|
||||
|
||||
// Context freetype init context.
|
||||
func (d *Dao) Context(r *image.Gray, fileStr string) (c *freetype.Context) {
|
||||
fg := image.Black
|
||||
// Read the font data.
|
||||
fontBytes, err := ioutil.ReadFile(fileStr)
|
||||
if err != nil {
|
||||
log.Error("ioutil.ReadFile(),err:%+v", err)
|
||||
return
|
||||
}
|
||||
f, err := freetype.ParseFont(fontBytes)
|
||||
if err != nil {
|
||||
log.Error("freetype.ParseFont(),err:%+v", err)
|
||||
return
|
||||
}
|
||||
c = freetype.NewContext()
|
||||
c.SetDPI(dpi)
|
||||
c.SetFont(f)
|
||||
c.SetClip(r.Bounds())
|
||||
c.SetDst(r)
|
||||
c.SetSrc(fg)
|
||||
switch hinting {
|
||||
default:
|
||||
c.SetHinting(font.HintingNone)
|
||||
case "full":
|
||||
c.SetHinting(font.HintingFull)
|
||||
}
|
||||
return
|
||||
}
|
52
app/admin/main/answer/dao/draw_test.go
Normal file
52
app/admin/main/answer/dao/draw_test.go
Normal file
@ -0,0 +1,52 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestQueConf(t *testing.T) {
|
||||
Convey("QueConf true", t, func() {
|
||||
d.QueConf(true)
|
||||
})
|
||||
Convey("QueConf false", t, func() {
|
||||
d.QueConf(false)
|
||||
})
|
||||
}
|
||||
|
||||
func TestHeight(t *testing.T) {
|
||||
Convey("Height true", t, func() {
|
||||
textImgConf := d.QueConf(true)
|
||||
d.Height(textImgConf, "这里错了", 1)
|
||||
})
|
||||
Convey("Height false", t, func() {
|
||||
textImgConf := d.QueConf(false)
|
||||
d.Height(textImgConf, "这里对了", 1)
|
||||
})
|
||||
}
|
||||
func TestDaoBoard(t *testing.T) {
|
||||
Convey("Board", t, func() {
|
||||
res := d.Board(4)
|
||||
So(res, ShouldNotBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestContext(t *testing.T) {
|
||||
Convey("Context", t, func() {
|
||||
board := d.Board(4)
|
||||
d.Context(board, "/data/conf/yahei.ttf")
|
||||
})
|
||||
}
|
||||
|
||||
// func TestDrawQue(t *testing.T) {
|
||||
// Convey("DrawQue", t, func() {
|
||||
// quec := d.QueConf(true)
|
||||
// imgh := d.Height(quec, "这里对了", 1)
|
||||
// board := d.Board(imgh)
|
||||
// imgc := d.Context(board, "/data/conf/yahei.ttf")
|
||||
// pt := freetype.Pt(0, int(quec.Fontsize))
|
||||
// d.DrawQue(imgc, "这里对了", quec, &pt)
|
||||
// d.DrawAns(imgc, quec, [4]string{"A", "B", "C", "D"}, &pt)
|
||||
// })
|
||||
// }
|
151
app/admin/main/answer/dao/es.go
Normal file
151
app/admin/main/answer/dao/es.go
Normal file
@ -0,0 +1,151 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"go-common/app/admin/main/answer/model"
|
||||
"go-common/library/log"
|
||||
xtime "go-common/library/time"
|
||||
)
|
||||
|
||||
// Page search page info
|
||||
type Page struct {
|
||||
Num int64 `json:"num"`
|
||||
Size int64 `json:"size"`
|
||||
Total int64 `json:"total"`
|
||||
}
|
||||
|
||||
// SearchSubjectLog get subject logs
|
||||
type SearchSubjectLog struct {
|
||||
Page *Page
|
||||
Result []*struct {
|
||||
MID int64 `json:"mid"`
|
||||
Business string `json:"business"`
|
||||
Action string `json:"action"`
|
||||
ExtraData string `json:"extra_data"`
|
||||
Ctime string `json:"ctime"`
|
||||
}
|
||||
}
|
||||
|
||||
// const .
|
||||
const (
|
||||
answerLogID = 15
|
||||
answerUpdate = "answer_update"
|
||||
|
||||
basePass = "basePass"
|
||||
extraStartTime = "extraStartTime"
|
||||
extraCheck = "extraCheck"
|
||||
proQues = "proQues"
|
||||
proCheck = "proCheck"
|
||||
captcha = "captchaPass"
|
||||
level = "level"
|
||||
)
|
||||
|
||||
// HistoryES search archives by es.
|
||||
func (d *Dao) HistoryES(c context.Context, arg *model.ArgHistory) (reply []*model.AnswerHistoryDB, err error) {
|
||||
var index []string
|
||||
for year := time.Now().Year(); year >= 2018; year-- { // 2018.12 开始接入日志
|
||||
index = append(index, fmt.Sprintf("log_user_action_%d_%d", answerLogID, year))
|
||||
}
|
||||
r := d.es.NewRequest("log_user_action").Index(index...)
|
||||
r.Fields("mid", "action", "ctime", "extra_data")
|
||||
r.WhereEq("mid", arg.Mid)
|
||||
r.Pn(arg.Pn).Ps(arg.Ps)
|
||||
res := &SearchSubjectLog{}
|
||||
if err = r.Scan(c, &res); err != nil || res == nil {
|
||||
log.Error("HistoryES:Scan params(%s) error(%v)", r.Params(), err)
|
||||
return
|
||||
}
|
||||
log.Error("HistoryES:%+v", res)
|
||||
mmh := make(map[int64]map[string]*model.AnswerHistory)
|
||||
for _, v := range res.Result {
|
||||
mh := make(map[string]*model.AnswerHistory)
|
||||
if err = json.Unmarshal([]byte(v.ExtraData), &mh); err != nil {
|
||||
log.Error("json.Unmarshal(%s) error(%v)", v.ExtraData, err)
|
||||
return
|
||||
}
|
||||
for k, v := range mh {
|
||||
if mmh[v.Hid] == nil {
|
||||
mmh[v.Hid] = make(map[string]*model.AnswerHistory)
|
||||
}
|
||||
mmh[v.Hid][k] = v
|
||||
}
|
||||
}
|
||||
data := make([]*model.AnswerHistory, 0)
|
||||
for _, v := range mmh {
|
||||
if v == nil {
|
||||
continue
|
||||
}
|
||||
h := new(model.AnswerHistory)
|
||||
if eh, ok := v[basePass]; ok && eh != nil {
|
||||
h = eh
|
||||
}
|
||||
if eh, ok := v[extraStartTime]; ok && eh != nil {
|
||||
h.StepExtraStartTime = eh.StepExtraStartTime
|
||||
h.Mtime = eh.Mtime
|
||||
}
|
||||
if eh, ok := v[extraCheck]; ok && eh != nil {
|
||||
h.StepExtraCompleteTime = eh.StepExtraCompleteTime
|
||||
h.Score = eh.Score
|
||||
h.StepExtraScore = eh.StepExtraScore
|
||||
h.Mtime = eh.Mtime
|
||||
}
|
||||
if eh, ok := v[proQues]; ok && eh != nil {
|
||||
h.StepTwoStartTime = eh.StepTwoStartTime
|
||||
h.Mtime = eh.Mtime
|
||||
}
|
||||
if eh, ok := v[proCheck]; ok && eh != nil {
|
||||
h.CompleteResult = eh.CompleteResult
|
||||
h.CompleteTime = eh.CompleteTime
|
||||
h.Score = eh.Score
|
||||
h.IsFirstPass = eh.IsFirstPass
|
||||
h.RankID = eh.RankID
|
||||
h.Mtime = eh.Mtime
|
||||
}
|
||||
if eh, ok := v[captcha]; ok && eh != nil {
|
||||
h.IsPassCaptcha = eh.IsPassCaptcha
|
||||
h.Mtime = eh.Mtime
|
||||
}
|
||||
if eh, ok := v[level]; ok && eh != nil {
|
||||
h.IsFirstPass = eh.IsFirstPass
|
||||
h.PassedLevel = eh.PassedLevel
|
||||
h.Mtime = eh.Mtime
|
||||
}
|
||||
data = append(data, h)
|
||||
}
|
||||
sort.Sort(model.Histories(data))
|
||||
return convent(data), nil
|
||||
}
|
||||
|
||||
func convent(src []*model.AnswerHistory) []*model.AnswerHistoryDB {
|
||||
res := make([]*model.AnswerHistoryDB, 0, len(src))
|
||||
for _, s := range src {
|
||||
r := &model.AnswerHistoryDB{
|
||||
ID: s.ID,
|
||||
Hid: s.Hid,
|
||||
Mid: s.Mid,
|
||||
StartTime: xtime.Time(s.StartTime.Unix()),
|
||||
StepOneErrTimes: s.StepOneErrTimes,
|
||||
StepOneCompleteTime: s.StepOneCompleteTime,
|
||||
StepExtraStartTime: xtime.Time(s.StepExtraStartTime.Unix()),
|
||||
StepExtraCompleteTime: s.StepExtraCompleteTime,
|
||||
StepExtraScore: s.StepExtraScore,
|
||||
StepTwoStartTime: xtime.Time(s.StepTwoStartTime.Unix()),
|
||||
CompleteTime: xtime.Time(s.CompleteTime.Unix()),
|
||||
CompleteResult: s.CompleteResult,
|
||||
Score: s.Score,
|
||||
IsFirstPass: s.IsFirstPass,
|
||||
IsPassCaptcha: s.IsPassCaptcha,
|
||||
PassedLevel: s.PassedLevel,
|
||||
RankID: s.RankID,
|
||||
Ctime: xtime.Time(s.Ctime.Unix()),
|
||||
Mtime: xtime.Time(s.Mtime.Unix()),
|
||||
}
|
||||
res = append(res, r)
|
||||
}
|
||||
return res
|
||||
}
|
16
app/admin/main/answer/dao/es_test.go
Normal file
16
app/admin/main/answer/dao/es_test.go
Normal file
@ -0,0 +1,16 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"go-common/app/admin/main/answer/model"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestHistoryES(t *testing.T) {
|
||||
Convey("HistoryES", t, func() {
|
||||
d.HistoryES(context.Background(), &model.ArgHistory{Mid: 14771787, Pn: 1, Ps: 1})
|
||||
})
|
||||
}
|
203
app/admin/main/answer/dao/mysql.go
Normal file
203
app/admin/main/answer/dao/mysql.go
Normal file
@ -0,0 +1,203 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"go-common/app/admin/main/answer/model"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
const (
|
||||
_questionTable = "ans_v3_question"
|
||||
_typeTable = "ans_v3_question_type"
|
||||
_queHistory = "answer_history_%d"
|
||||
)
|
||||
|
||||
// QueByID by id.
|
||||
func (d *Dao) QueByID(c context.Context, id int64) (res *model.Question, err error) {
|
||||
que := &model.QuestionDB{}
|
||||
if err := d.db.Table(_questionTable).Where("id=?", id).First(que).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res = &model.Question{QuestionDB: que, Ans: []string{que.Ans1, que.Ans2, que.Ans3, que.Ans4}}
|
||||
return
|
||||
}
|
||||
|
||||
// ByIDs by id.
|
||||
func (d *Dao) ByIDs(c context.Context, IDs []int64) (res []*model.QuestionDB, err error) {
|
||||
if err := d.db.Table(_questionTable).Where("id in (?)", IDs).Find(&res).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// IDsByState by id.
|
||||
func (d *Dao) IDsByState(c context.Context) (res []int64, err error) {
|
||||
var (
|
||||
rows *sql.Rows
|
||||
)
|
||||
if rows, err = d.db.Table(_questionTable).Select("id").Where("state = ?", 1).Rows(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for rows.Next() {
|
||||
var qid int64
|
||||
if err = rows.Scan(&qid); err != nil {
|
||||
return
|
||||
}
|
||||
res = append(res, qid)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// QuestionAdd add register question.
|
||||
func (d *Dao) QuestionAdd(c context.Context, q *model.QuestionDB) (aff int64, err error) {
|
||||
db := d.db.Save(q)
|
||||
if err = db.Error; err != nil {
|
||||
return
|
||||
}
|
||||
aff = db.RowsAffected
|
||||
return
|
||||
}
|
||||
|
||||
// QuestionEdit edit register question.
|
||||
func (d *Dao) QuestionEdit(c context.Context, arg *model.QuestionDB) (aff int64, err error) {
|
||||
que := map[string]interface{}{
|
||||
"question": arg.Question,
|
||||
"ans1": arg.Ans1,
|
||||
"ans2": arg.Ans2,
|
||||
"ans3": arg.Ans3,
|
||||
"ans4": arg.Ans4,
|
||||
"operator": arg.Operator,
|
||||
}
|
||||
db := d.db.Table(_questionTable).Omit("ctime, operator").Where("id = ?", arg.ID).Updates(que)
|
||||
if err = db.Error; err != nil {
|
||||
log.Error("%+v", err)
|
||||
return
|
||||
}
|
||||
aff = db.RowsAffected
|
||||
return
|
||||
}
|
||||
|
||||
// QuestionList .
|
||||
func (d *Dao) QuestionList(c context.Context, arg *model.ArgQue) (res []*model.QuestionDB, err error) {
|
||||
db := d.db.Table(_questionTable)
|
||||
if arg.TypeID != 0 {
|
||||
db = db.Where("type_id=?", arg.TypeID)
|
||||
}
|
||||
if arg.State != -1 {
|
||||
db = db.Where("state=?", arg.State)
|
||||
}
|
||||
if len(arg.Question) != 0 {
|
||||
db = db.Where("question LIKE '%%" + arg.Question + "%%'")
|
||||
}
|
||||
db = db.Offset((arg.Pn - 1) * arg.Ps).Limit(arg.Ps).Order("id desc")
|
||||
if err = db.Find(&res).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// QuestionCount question page total count.
|
||||
func (d *Dao) QuestionCount(c context.Context, arg *model.ArgQue) (res int64, err error) {
|
||||
db := d.db.Table(_questionTable)
|
||||
if arg.TypeID != 0 {
|
||||
db = db.Where("type_id=?", arg.TypeID)
|
||||
}
|
||||
if arg.State != -1 {
|
||||
db = db.Where("state=?", arg.State)
|
||||
}
|
||||
if len(arg.Question) != 0 {
|
||||
db = db.Where("question LIKE '%%" + arg.Question + "%%'")
|
||||
}
|
||||
if err = db.Count(&res).Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateStatus update question state.
|
||||
func (d *Dao) UpdateStatus(c context.Context, state int8, qid int64, operator string) (aff int64, err error) {
|
||||
val := map[string]interface{}{
|
||||
"state": state,
|
||||
"operator": operator,
|
||||
}
|
||||
db := d.db.Table(_questionTable).Where("id=?", qid).Updates(val)
|
||||
if err = db.Error; err != nil {
|
||||
return
|
||||
}
|
||||
aff = db.RowsAffected
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
// Types get all types.
|
||||
func (d *Dao) Types(c context.Context) (res []*model.TypeInfo, err error) {
|
||||
db := d.db.Table(_typeTable)
|
||||
if err = db.Where("parentid != 0").Find(&res).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// TypeSave add register question type.
|
||||
func (d *Dao) TypeSave(c context.Context, t *model.TypeInfo) (aff int64, err error) {
|
||||
db := d.db.Save(t)
|
||||
if err = db.Error; err != nil {
|
||||
return
|
||||
}
|
||||
aff = db.RowsAffected
|
||||
return
|
||||
}
|
||||
|
||||
// BaseQS .
|
||||
func (d *Dao) BaseQS(c context.Context) (res []*model.QuestionDB, err error) {
|
||||
db := d.db.Table("ans_register_question")
|
||||
db = db.Where("type_id=6 AND state=1")
|
||||
if err = db.Omit("id").Find(&res).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// AllQS .
|
||||
func (d *Dao) AllQS(c context.Context) (res []*model.QuestionDB, err error) {
|
||||
db := d.db.Table("ans_v3_question")
|
||||
if err = db.Find(&res).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// InsBaseQs .
|
||||
func (d *Dao) InsBaseQs(c context.Context, qs *model.QuestionDB) (lastID int64, err error) {
|
||||
db := d.db.Table(_questionTable)
|
||||
qs.TypeID = 36
|
||||
qs.State = 1
|
||||
db = db.Create(qs)
|
||||
if err = db.Error; err != nil {
|
||||
return
|
||||
}
|
||||
lastID = qs.ID
|
||||
return
|
||||
}
|
||||
|
||||
// QueHistory .
|
||||
func (d *Dao) QueHistory(c context.Context, arg *model.ArgHistory) (res []*model.AnswerHistoryDB, err error) {
|
||||
db := d.db.Table(fmt.Sprintf(_queHistory, arg.Mid%10))
|
||||
db = db.Where("mid = ?", arg.Mid).Offset((arg.Pn - 1) * arg.Ps).Limit(arg.Ps).Order("id desc")
|
||||
if err = db.Find(&res).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// HistoryCount .
|
||||
func (d *Dao) HistoryCount(c context.Context, arg *model.ArgHistory) (res int64, err error) {
|
||||
db := d.db.Table(fmt.Sprintf(_queHistory, arg.Mid%10))
|
||||
if err = db.Where("mid = ?", arg.Mid).Count(&res).Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return
|
||||
}
|
168
app/admin/main/answer/dao/mysql_test.go
Normal file
168
app/admin/main/answer/dao/mysql_test.go
Normal file
@ -0,0 +1,168 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"go-common/app/admin/main/answer/model"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestDaoIDsByState(t *testing.T) {
|
||||
Convey("IDsByState", t, func() {
|
||||
_, err := d.IDsByState(context.TODO())
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoQuestionAll(t *testing.T) {
|
||||
var id int64 = 1
|
||||
q := &model.QuestionDB{ID: id, State: 1}
|
||||
Convey("QuestionAdd", t, func() {
|
||||
aff, err := d.QuestionAdd(context.TODO(), q)
|
||||
So(err, ShouldBeNil)
|
||||
So(aff, ShouldNotBeNil)
|
||||
})
|
||||
Convey("QueByID", t, func() {
|
||||
que, err := d.QueByID(context.TODO(), id)
|
||||
So(err, ShouldBeNil)
|
||||
So(que, ShouldNotBeNil)
|
||||
})
|
||||
Convey("QuestionEdit", t, func() {
|
||||
q.Question = "testone"
|
||||
aff, err := d.QuestionEdit(context.TODO(), q)
|
||||
So(err, ShouldBeNil)
|
||||
So(aff, ShouldNotBeNil)
|
||||
})
|
||||
Convey("ByIDs", t, func() {
|
||||
res, err := d.ByIDs(context.TODO(), []int64{id})
|
||||
So(err, ShouldBeNil)
|
||||
So(res, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestDaoQuestionPage(t *testing.T) {
|
||||
arg := &model.ArgQue{State: 1}
|
||||
Convey("QuestionList", t, func() {
|
||||
res, err := d.QuestionList(context.TODO(), arg)
|
||||
So(err, ShouldBeNil)
|
||||
So(res, ShouldNotBeNil)
|
||||
})
|
||||
Convey("QuestionCount", t, func() {
|
||||
res, err := d.QuestionCount(context.TODO(), arg)
|
||||
So(err, ShouldBeNil)
|
||||
So(res, ShouldNotBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoUpdateStatus(t *testing.T) {
|
||||
Convey("UpdateStatus", t, func() {
|
||||
aff, err := d.UpdateStatus(context.TODO(), 0, 0, "")
|
||||
So(err, ShouldBeNil)
|
||||
So(aff, ShouldNotBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoTypes(t *testing.T) {
|
||||
Convey("Types", t, func() {
|
||||
res, err := d.Types(context.TODO())
|
||||
So(err, ShouldBeNil)
|
||||
So(res, ShouldNotBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoTypeAdd(t *testing.T) {
|
||||
Convey("Types", t, func() {
|
||||
var allType = []*model.TypeInfo{
|
||||
{ID: 1, Parentid: 0, Name: "游戏"},
|
||||
{ID: 2, Parentid: 0, Name: "影视"},
|
||||
{ID: 3, Parentid: 0, Name: "科技"},
|
||||
{ID: 4, Parentid: 0, Name: "动画"},
|
||||
{ID: 5, Parentid: 0, Name: "艺术"},
|
||||
{ID: 6, Parentid: 0, Name: "流行前线"},
|
||||
{ID: 7, Parentid: 0, Name: "鬼畜"},
|
||||
{ID: 8, Parentid: 1, Name: "动作射击", LabelName: "游戏"},
|
||||
{ID: 9, Parentid: 1, Name: "冒险格斗", LabelName: "游戏"},
|
||||
{ID: 12, Parentid: 1, Name: "策略模拟 ", LabelName: "游戏"},
|
||||
{ID: 13, Parentid: 1, Name: "角色扮演 ", LabelName: "游戏"},
|
||||
{ID: 14, Parentid: 1, Name: "音乐体育 ", LabelName: "游戏"},
|
||||
{ID: 15, Parentid: 2, Name: "纪录片 ", LabelName: "影视"},
|
||||
{ID: 16, Parentid: 2, Name: "电影 ", LabelName: "影视"},
|
||||
{ID: 17, Parentid: 2, Name: "电视剧 ", LabelName: "影视"},
|
||||
{ID: 18, Parentid: 3, Name: "军事 ", LabelName: "科技"},
|
||||
{ID: 19, Parentid: 3, Name: "地理 ", LabelName: "科技"},
|
||||
{ID: 20, Parentid: 3, Name: "历史 ", LabelName: "科技"},
|
||||
{ID: 21, Parentid: 3, Name: "文学 ", LabelName: "科技"},
|
||||
{ID: 22, Parentid: 3, Name: "数学 ", LabelName: "科技"},
|
||||
{ID: 23, Parentid: 3, Name: "物理 ", LabelName: "科技"},
|
||||
{ID: 24, Parentid: 3, Name: "化学 ", LabelName: "科技"},
|
||||
{ID: 25, Parentid: 3, Name: "生物 ", LabelName: "科技"},
|
||||
{ID: 26, Parentid: 3, Name: "数码科技 ", LabelName: "科技"},
|
||||
{ID: 27, Parentid: 4, Name: "动画声优 ", LabelName: "动画"},
|
||||
{ID: 28, Parentid: 4, Name: "动漫内容 ", LabelName: "动画"},
|
||||
{ID: 29, Parentid: 5, Name: "ACG音乐 ", LabelName: "艺术"},
|
||||
{ID: 30, Parentid: 5, Name: "三次元音乐 ", LabelName: "艺术"},
|
||||
{ID: 31, Parentid: 5, Name: "绘画 ", LabelName: "艺术"},
|
||||
{ID: 32, Parentid: 6, Name: "娱乐 ", LabelName: "流行前线"},
|
||||
{ID: 33, Parentid: 6, Name: "时尚 ", LabelName: "流行前线"},
|
||||
{ID: 34, Parentid: 6, Name: "运动 ", LabelName: "流行前线"},
|
||||
{ID: 35, Parentid: 7, Name: "鬼畜 ", LabelName: "鬼畜"},
|
||||
{ID: 36, Parentid: 0, Name: "基础题", LabelName: "基础题"},
|
||||
}
|
||||
for _, v := range allType {
|
||||
res, err := d.TypeSave(context.TODO(), v)
|
||||
So(err, ShouldBeNil)
|
||||
So(res, ShouldNotBeNil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoBaseQS(t *testing.T) {
|
||||
Convey("TestBaseQS", t, func() {
|
||||
res, err := d.BaseQS(context.Background())
|
||||
for k, re := range res {
|
||||
fmt.Printf("k:%d re:%+v \n", k, re)
|
||||
}
|
||||
So(err, ShouldBeNil)
|
||||
So(res, ShouldNotBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoInsBaseQs(t *testing.T) {
|
||||
var qs = &model.QuestionDB{
|
||||
Mid: 1,
|
||||
IP: "127.0.0.1",
|
||||
Question: "qs",
|
||||
Ans1: "Ans1",
|
||||
Ans2: "Ans2",
|
||||
Ans3: "Ans3",
|
||||
Ans4: "Ans4",
|
||||
Tips: "tips",
|
||||
AvID: 1,
|
||||
MediaType: 1,
|
||||
Source: 1,
|
||||
Ctime: time.Now(),
|
||||
Mtime: time.Now(),
|
||||
Operator: "operator",
|
||||
}
|
||||
Convey("TestInsBaseQs", t, func() {
|
||||
af, err := d.InsBaseQs(context.Background(), qs)
|
||||
fmt.Printf("%+v \n", af)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestAllQS(t *testing.T) {
|
||||
Convey("TestAllQS", t, func() {
|
||||
res, err := d.AllQS(context.Background())
|
||||
for k, re := range res {
|
||||
fmt.Printf("k:%d re:%+v \n", k, re)
|
||||
}
|
||||
So(err, ShouldBeNil)
|
||||
So(res, ShouldNotBeNil)
|
||||
})
|
||||
}
|
32
app/admin/main/answer/dao/redis.go
Normal file
32
app/admin/main/answer/dao/redis.go
Normal file
@ -0,0 +1,32 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
const (
|
||||
_baseQsIdsKey = "v3_tc_bqs"
|
||||
)
|
||||
|
||||
// SetQidCache set question id into question set
|
||||
func (d *Dao) SetQidCache(c context.Context, id int64) (err error) {
|
||||
var (
|
||||
key = _baseQsIdsKey
|
||||
conn = d.redis.Get(c)
|
||||
)
|
||||
defer conn.Close()
|
||||
if err = conn.Send("SET", key, id); err != nil {
|
||||
log.Error("conn.Send(SET, %s, %d) error(%v)", key, id, err)
|
||||
return
|
||||
}
|
||||
if err = conn.Flush(); err != nil {
|
||||
log.Error("conn.Flush error(%v)", err)
|
||||
return
|
||||
}
|
||||
if _, err = conn.Receive(); err != nil {
|
||||
log.Error("conn.Receive() error(%v)", err)
|
||||
}
|
||||
return
|
||||
}
|
15
app/admin/main/answer/dao/redis_test.go
Normal file
15
app/admin/main/answer/dao/redis_test.go
Normal file
@ -0,0 +1,15 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestDaoSetQidCache(t *testing.T) {
|
||||
convey.Convey("SetQidCache", t, func() {
|
||||
err := d.SetQidCache(context.TODO(), 0)
|
||||
convey.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
}
|
Reference in New Issue
Block a user