jack před 2 měsíci
rodič
revize
cd44401322

+ 65 - 1
README.MD

@@ -1,4 +1,68 @@
 # GoFrame Template For SingleRepo
 
 Quick Start: 
-- https://goframe.org/pages/viewpage.action?pageId=1114399
+- https://goframe.org/pages/viewpage.action?pageId=1114399
+
+
+# register
+curl -X POST http://127.0.0.1:8000/v1/users/register -H "Content-Type: application/json" -d "{\"username\":\"jiege66666\", \"password\":\"123456\", \"email\":\"admin@163.com\"}"
+
+# login
+curl -X POST http://127.0.0.1:8000/v1/users/login -H "Content-Type: application/json" -d "{\"username\":\"jiege66666\", \"password\":\"123456\"}"
+
+# get user info
+curl -H "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJZCI6NiwiVXNlcm5hbWUiOiJqaWVnZTY2NjY2IiwiZXhwIjoxNzYwMzQyNjkzfQ.ULS-Vy5GNnU6xjbayIr7mXJqjxqzgGqBFjrrj9kOB5w" http://127.0.0.1:8000/v1/account/info
+
+# create words
+curl -X POST http://127.0.0.1:8000/v1/words \
+     -H "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJZCI6NiwiVXNlcm5hbWUiOiJqaWVnZTY2NjY2IiwiZXhwIjoxNzYwMzQyNjkzfQ.ULS-Vy5GNnU6xjbayIr7mXJqjxqzgGqBFjrrj9kOB5w" \
+     -H "Content-Type: application/json" \
+     -d '{
+           "word": "example",
+           "definition": "A representative form or pattern.",
+           "example_sentence": "This is an example sentence.",
+           "chinese_translation": "例子",
+           "pronunciation": "ɪɡˈzɑːmp(ə)l",
+           "proficiency_level": 3
+         }'
+
+# update words
+curl -X PUT http://127.0.0.1:8000/v1/words/1 \
+     -H "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJZCI6NiwiVXNlcm5hbWUiOiJqaWVnZTY2NjY2IiwiZXhwIjoxNzYwMzQyNjkzfQ.ULS-Vy5GNnU6xjbayIr7mXJqjxqzgGqBFjrrj9kOB5w" \
+     -H "Content-Type: application/json" \
+     -d '{
+           "word": "example_update",
+           "definition": "A representative form or pattern.",
+           "example_sentence": "This is an example sentence.",
+           "chinese_translation": "例子2",
+           "pronunciation": "ɪɡˈzɑːmp(ə)l",
+           "proficiency_level": 3
+         }'
+
+# words page
+curl -X GET http://127.0.0.1:8000/v1/words \
+     -H "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJZCI6NiwiVXNlcm5hbWUiOiJqaWVnZTY2NjY2IiwiZXhwIjoxNzYwMzQyNjkzfQ.ULS-Vy5GNnU6xjbayIr7mXJqjxqzgGqBFjrrj9kOB5w" \
+     -H "Content-Type: application/json"
+
+# words detail
+curl -X GET http://127.0.0.1:8000/v1/words/1 \
+     -H "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJZCI6NiwiVXNlcm5hbWUiOiJqaWVnZTY2NjY2IiwiZXhwIjoxNzYwMzQyNjkzfQ.ULS-Vy5GNnU6xjbayIr7mXJqjxqzgGqBFjrrj9kOB5w" \
+     -H "Content-Type: application/json"
+
+# words delete
+curl -X DELETE http://127.0.0.1:8000/v1/words/1 \
+     -H "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJZCI6NiwiVXNlcm5hbWUiOiJqaWVnZTY2NjY2IiwiZXhwIjoxNzYwMzQyNjkzfQ.ULS-Vy5GNnU6xjbayIr7mXJqjxqzgGqBFjrrj9kOB5w" \
+     -H "Content-Type: application/json"
+
+# words rand
+curl -X GET http://127.0.0.1:8000/v1/words/rand \
+     -H "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJZCI6NiwiVXNlcm5hbWUiOiJqaWVnZTY2NjY2IiwiZXhwIjoxNzYwMzQyNjkzfQ.ULS-Vy5GNnU6xjbayIr7mXJqjxqzgGqBFjrrj9kOB5w" \
+     -H "Content-Type: application/json"
+
+# --
+curl -X PATCH http://127.0.0.1:8000/v1/words/1/level \
+     -H "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJZCI6NiwiVXNlcm5hbWUiOiJqaWVnZTY2NjY2IiwiZXhwIjoxNzYwMzQyNjkzfQ.ULS-Vy5GNnU6xjbayIr7mXJqjxqzgGqBFjrrj9kOB5w" \
+     -H "Content-Type: application/json" \
+     -d '{
+           "level": 5
+         }'

+ 62 - 1
api/words/v1/words.go

@@ -1,6 +1,9 @@
 package v1
 
-import "github.com/gogf/gf/v2/frame/g"
+import (
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/gogf/gf/v2/os/gtime"
+)
 
 type ProficiencyLevel uint
 
@@ -24,3 +27,61 @@ type CreateReq struct {
 
 type CreateRes struct {
 }
+
+type UpdateReq struct {
+	g.Meta             `path:"words/{id}" method:"put" sm:"更新" tags:"单词"`
+	Id                 uint             `json:"id" v:"required"`
+	Word               string           `json:"word" v:"required|length:1,100" dc:"单词"`
+	Definition         string           `json:"definition" v:"required|length:1,300" dc:"单词定义"`
+	ExampleSentence    string           `json:"example_sentence" v:"required|length:1,300" dc:"例句"`
+	ChineseTranslation string           `json:"chinese_translation" v:"required|length:1,300" dc:"中文翻译"`
+	Pronunciation      string           `json:"pronunciation" v:"required|length:1,100" dc:"发音"`
+	ProficiencyLevel   ProficiencyLevel `json:"proficiency_level" v:"required|between:1,5" dc:"熟练度,1最低,5最高"`
+}
+
+type UpdateRes struct {
+}
+
+type List struct {
+	Id               uint             `json:"id"`
+	Word             string           `json:"word"`
+	Definition       string           `json:"definition"`
+	ProficiencyLevel ProficiencyLevel `json:"proficiencyLevel"`
+}
+
+type ListReq struct {
+	g.Meta `path:"words" method:"get" sm:"列表" tags:"单词"`
+	Word   string `json:"word" v:"length:1,100" dc:"模糊查询单词"`
+	Page   int    `json:"page" v:"min:1" dc:"页码,默认1"`
+	Size   int    `json:"size" v:"between:1,100" dc:"每页数量,默认10"`
+}
+
+type ListRes struct {
+	List  []List `json:"words"`
+	Total uint   `json:"total"`
+}
+
+type DetailReq struct {
+	g.Meta `path:"words/{id}" method:"get" sm:"详情" tags:"单词"`
+	Id     uint `json:"id" v:"required"`
+}
+
+type DetailRes struct {
+	Id                 uint             `json:"id"`
+	Word               string           `json:"word"`
+	Definition         string           `json:"definition"`
+	ExampleSentence    string           `json:"exampleSentence"`
+	ChineseTranslation string           `json:"chineseTranslation"`
+	Pronunciation      string           `json:"pronunciation"`
+	ProficiencyLevel   ProficiencyLevel `json:"proficiencyLevel"`
+	CreatedAt          *gtime.Time      `json:"createdAt"`
+	UpdatedAt          *gtime.Time      `json:"updatedAt"`
+}
+
+type DeleteReq struct {
+	g.Meta `path:"words/{id}" method:"delete" sm:"删除" tags:"单词"`
+	Id     uint `json:"id" v:"required"`
+}
+
+type DeleteRes struct {
+}

+ 23 - 0
api/words/v1/words_learn.go

@@ -0,0 +1,23 @@
+package v1
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+type RandListReq struct {
+	g.Meta `path:"words/rand" method:"get" sm:"随机获取单词列表" tags:"单词"`
+	Limit  uint `json:"limit" v:"between:1,300" dc:"限制个数,默认50"`
+}
+
+type RandListRes struct {
+	List []List `json:"list"`
+}
+
+type SetLevelReq struct {  
+    g.Meta `path:"words/{id}/level" method:"patch"`  
+    Id     uint             `json:"id" v:"required"`  
+    Level  ProficiencyLevel `json:"level" v:"required|between:1,5"`  
+}  
+  
+type SetLevelRes struct {  
+}

+ 23 - 0
api/words/words.go

@@ -0,0 +1,23 @@
+// =================================================================================
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. 
+// =================================================================================
+
+package words
+
+import (
+	"context"
+	
+	"star/api/words/v1"
+)
+
+type IWordsV1 interface {
+	Create(ctx context.Context, req *v1.CreateReq) (res *v1.CreateRes, err error)
+	Update(ctx context.Context, req *v1.UpdateReq) (res *v1.UpdateRes, err error)
+	List(ctx context.Context, req *v1.ListReq) (res *v1.ListRes, err error)
+	Detail(ctx context.Context, req *v1.DetailReq) (res *v1.DetailRes, err error)
+	Delete(ctx context.Context, req *v1.DeleteReq) (res *v1.DeleteRes, err error)
+	RandList(ctx context.Context, req *v1.RandListReq) (res *v1.RandListRes, err error)
+	SetLevel(ctx context.Context, req *v1.SetLevelReq) (res *v1.SetLevelRes, err error)
+}
+
+

+ 2 - 0
internal/cmd/cmd.go

@@ -4,6 +4,7 @@ import (
 	"context"
 	"star/internal/controller/account"
 	"star/internal/controller/users"
+	"star/internal/controller/words"
 
 	"github.com/gogf/gf/v2/frame/g"
 	"github.com/gogf/gf/v2/net/ghttp"
@@ -26,6 +27,7 @@ var (
 					group.Group("/", func(group *ghttp.RouterGroup) {
 						group.Bind(
 							account.NewV1(),
+							words.NewV1(),
 						)
 					})
 				})

+ 6 - 0
internal/controller/words/words.go

@@ -0,0 +1,6 @@
+// =================================================================================
+// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// =================================================================================
+
+package words
+

+ 19 - 0
internal/controller/words/words_new.go

@@ -0,0 +1,19 @@
+package words
+
+import (
+	"star/api/words"
+	usersLogic "star/internal/logic/users"
+	wordsLogic "star/internal/logic/words"
+)
+
+type ControllerV1 struct {
+	users *usersLogic.Users
+	words *wordsLogic.Words
+}
+
+func NewV1() words.IWordsV1 {
+	return &ControllerV1{
+		users: usersLogic.New(),
+		words: wordsLogic.New(),
+	}
+}

+ 25 - 0
internal/controller/words/words_v1_create.go

@@ -0,0 +1,25 @@
+package words
+
+import (
+	"context"
+
+	v1 "star/api/words/v1"
+	"star/internal/logic/words"
+)
+
+func (c *ControllerV1) Create(ctx context.Context, req *v1.CreateReq) (res *v1.CreateRes, err error) {
+	uid, err := c.users.GetUid(ctx)
+	if err != nil {
+		return nil, err
+	}
+	err = c.words.Create(ctx, words.CreateInput{
+		Uid:                uid,
+		Word:               req.Word,
+		Definition:         req.Definition,
+		ExampleSentence:    req.ExampleSentence,
+		ChineseTranslation: req.ChineseTranslation,
+		Pronunciation:      req.Pronunciation,
+		ProficiencyLevel:   req.ProficiencyLevel,
+	})
+	return nil, err
+}

+ 17 - 0
internal/controller/words/words_v1_delete.go

@@ -0,0 +1,17 @@
+package words
+
+import (
+	"context"
+
+	v1 "star/api/words/v1"
+)
+
+func (c *ControllerV1) Delete(ctx context.Context, req *v1.DeleteReq) (res *v1.DeleteRes, err error) {
+	uid, err := c.users.GetUid(ctx)
+	if err != nil {
+		return nil, err
+	}
+
+	err = c.words.Delete(ctx, uid, req.Id)
+	return
+}

+ 31 - 0
internal/controller/words/words_v1_detail.go

@@ -0,0 +1,31 @@
+package words
+
+import (
+	"context"
+
+	v1 "star/api/words/v1"
+)
+
+func (c *ControllerV1) Detail(ctx context.Context, req *v1.DetailReq) (res *v1.DetailRes, err error) {
+	uid, err := c.users.GetUid(ctx)
+	if err != nil {
+		return nil, err
+	}
+
+	word, err := c.words.Detail(ctx, uid, req.Id)
+	if err != nil {
+		return nil, err
+	}
+
+	return &v1.DetailRes{
+		Id:                 word.Id,
+		Word:               word.Word,
+		Definition:         word.Definition,
+		ExampleSentence:    word.ExampleSentence,
+		ChineseTranslation: word.ChineseTranslation,
+		Pronunciation:      word.Pronunciation,
+		ProficiencyLevel:   v1.ProficiencyLevel(word.ProficiencyLevel),
+		CreatedAt:          word.CreatedAt,
+		UpdatedAt:          word.UpdatedAt,
+	}, nil
+}

+ 39 - 0
internal/controller/words/words_v1_list.go

@@ -0,0 +1,39 @@
+package words
+
+import (
+	"context"
+
+	v1 "star/api/words/v1"
+	"star/internal/logic/words"
+)
+
+func (c *ControllerV1) List(ctx context.Context, req *v1.ListReq) (res *v1.ListRes, err error) {
+	uid, err := c.users.GetUid(ctx)
+	if err != nil {
+		return nil, err
+	}
+	wordList, total, err := c.words.List(ctx, words.ListInput{
+		Uid:  uid,
+		Word: req.Word,
+		Page: req.Page,
+		Size: req.Size,
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	var list []v1.List
+	for _, v := range wordList {
+		list = append(list, v1.List{
+			Id:               v.Id,
+			Word:             v.Word,
+			Definition:       v.Definition,
+			ProficiencyLevel: v1.ProficiencyLevel(v.ProficiencyLevel),
+		})
+	}
+
+	return &v1.ListRes{
+		List:  list,
+		Total: uint(total),
+	}, nil
+}

+ 33 - 0
internal/controller/words/words_v1_rand_list.go

@@ -0,0 +1,33 @@
+package words
+
+import (
+	"context"
+
+	v1 "star/api/words/v1"
+)
+
+func (c *ControllerV1) RandList(ctx context.Context, req *v1.RandListReq) (res *v1.RandListRes, err error) {
+	uid, err := c.users.GetUid(ctx)
+	if err != nil {
+		return nil, err
+	}
+
+	wordList, err := c.words.Rand(ctx, uid, req.Limit)
+	if err != nil {
+		return nil, err
+	}
+
+	var list []v1.List
+	for _, v := range wordList {
+		list = append(list, v1.List{
+			Id:               v.Id,
+			Word:             v.Word,
+			Definition:       v.Definition,
+			ProficiencyLevel: v1.ProficiencyLevel(v.ProficiencyLevel),
+		})
+	}
+
+	return &v1.RandListRes{
+		List: list,
+	}, nil
+}

+ 17 - 0
internal/controller/words/words_v1_set_level.go

@@ -0,0 +1,17 @@
+package words
+
+import (
+	"context"
+
+	v1 "star/api/words/v1"
+)
+
+func (c *ControllerV1) SetLevel(ctx context.Context, req *v1.SetLevelReq) (res *v1.SetLevelRes, err error) {
+	uid, err := c.users.GetUid(ctx)
+	if err != nil {
+		return nil, err
+	}
+
+	err = c.words.SetLevel(ctx, uid, req.Id, req.Level)
+	return nil, err
+}

+ 25 - 0
internal/controller/words/words_v1_update.go

@@ -0,0 +1,25 @@
+package words
+
+import (
+	"context"
+
+	v1 "star/api/words/v1"
+	"star/internal/logic/words"
+)
+
+func (c *ControllerV1) Update(ctx context.Context, req *v1.UpdateReq) (res *v1.UpdateRes, err error) {
+	uid, err := c.users.GetUid(ctx)
+	if err != nil {
+		return nil, err
+	}
+	err = c.words.Update(ctx, req.Id, words.UpdateInput{
+		Uid:                uid,
+		Word:               req.Word,
+		Definition:         req.Definition,
+		ExampleSentence:    req.ExampleSentence,
+		ChineseTranslation: req.ChineseTranslation,
+		Pronunciation:      req.Pronunciation,
+		ProficiencyLevel:   req.ProficiencyLevel,
+	})
+	return nil, err
+}

+ 103 - 0
internal/logic/words/words.go

@@ -5,6 +5,7 @@ import (
 	v1 "star/api/words/v1"
 	"star/internal/dao"
 	"star/internal/model/do"
+	"star/internal/model/entity"
 
 	"github.com/gogf/gf/v2/errors/gerror"
 )
@@ -53,3 +54,105 @@ func (w *Words) Create(ctx context.Context, in CreateInput) error {
 	}
 	return nil
 }
+
+type UpdateInput struct {
+	Uid                uint
+	Word               string
+	Definition         string
+	ExampleSentence    string
+	ChineseTranslation string
+	Pronunciation      string
+	ProficiencyLevel   v1.ProficiencyLevel
+}
+
+func (w *Words) Update(ctx context.Context, id uint, in UpdateInput) error {
+	var cls = dao.Words.Columns()
+
+	count, err := dao.Words.Ctx(ctx).
+		Where(cls.Uid, in.Uid).
+		Where(cls.Word, in.Word).
+		WhereNot(cls.Id, id).Count()
+	if err != nil {
+		return err
+	}
+	if count > 0 {
+		return gerror.New("单词已存在")
+	}
+
+	_, err = dao.Words.Ctx(ctx).Data(do.Words{
+		Id:                 id,
+		Word:               in.Word,
+		Definition:         in.Definition,
+		ExampleSentence:    in.ExampleSentence,
+		ChineseTranslation: in.ChineseTranslation,
+		Pronunciation:      in.Pronunciation,
+		ProficiencyLevel:   in.ProficiencyLevel,
+	}).Where(cls.Id, id).Where(cls.Uid, in.Uid).Update()
+	if err != nil {
+		return err
+	}
+	return nil
+
+}
+
+type ListInput struct {
+	Uid  uint
+	Word string
+	Page int
+	Size int
+}
+
+func (w *Words) List(ctx context.Context, in ListInput) (list []entity.Words, total int, err error) {
+	// 对于查询初始值的处理
+	if in.Page == 0 {
+		in.Page = 1
+	}
+	if in.Size == 0 {
+		in.Size = 15
+	}
+
+	var (
+		cls = dao.Words.Columns()
+		orm = dao.Words.Ctx(ctx)
+	)
+	// 组成查询链
+	if in.Uid > 0 {
+		orm = orm.Where(cls.Uid, in.Uid)
+	}
+
+	// 模糊查询
+	if len(in.Word) != 0 {
+		orm = orm.WhereLike(cls.Word, "%"+in.Word+"%")
+	}
+	orm = orm.OrderDesc(cls.CreatedAt).OrderDesc(cls.Id).Page(in.Page, in.Size)
+	if err = orm.ScanAndCount(&list, &total, true); err != nil {
+		return
+	}
+	return
+}
+
+func (w *Words) Detail(ctx context.Context, uid, id uint) (word *entity.Words, err error) {
+	var (
+		cls = dao.Words.Columns()
+		orm = dao.Words.Ctx(ctx)
+	)
+	orm = orm.Where(cls.Id, id)
+	if uid > 0 {
+		orm = orm.Where(cls.Uid, uid)
+	}
+	err = orm.Scan(&word)
+	return
+}
+
+func (w *Words) Delete(ctx context.Context, uid, id uint) (err error) {  
+    var (  
+       cls = dao.Words.Columns()  
+       orm = dao.Words.Ctx(ctx)  
+    )  
+    orm = orm.Where(cls.Id, id)  
+    if uid > 0 {  
+       orm = orm.Where(cls.Uid, uid)  
+    }  
+    _, err = orm.Delete()  
+    return  
+}

+ 45 - 0
internal/logic/words/words_learn.go

@@ -0,0 +1,45 @@
+package words
+
+import (
+	"context"
+
+	v1 "star/api/words/v1"
+	"star/internal/dao"
+	"star/internal/model/entity"
+
+	"github.com/gogf/gf/v2/errors/gerror"
+)
+
+func (w *Words) Rand(ctx context.Context, uid, limit uint) ([]entity.Words, error) {
+	if limit <= 0 {
+		limit = 50
+	}
+	var (
+		err  error
+		cls  = dao.Words.Columns()
+		orm  = dao.Words.Ctx(ctx)
+		list = make([]entity.Words, limit)
+	)
+	if uid > 0 {
+		orm = orm.Where(cls.Uid, uid)
+	}
+	err = orm.Limit(int(limit)).OrderRandom().Scan(&list)
+	return list, err
+}
+
+func (w *Words) SetLevel(ctx context.Context, uid, id uint, level v1.ProficiencyLevel) error {
+	if level <= 0 || level > 5 {
+		return gerror.New("熟练度值不合法")
+	}
+
+	var (
+		cls = dao.Words.Columns()
+		orm = dao.Words.Ctx(ctx)
+	)
+	if uid > 0 {
+		orm = orm.Where(cls.Uid, uid)
+	}
+
+	_, err := orm.Data(cls.ProficiencyLevel, level).Where(cls.Id, id).Update()
+	return err
+}