补充book的具体实现

This commit is contained in:
yumaojun03 2025-05-25 10:57:47 +08:00
parent 4d5b597380
commit ebfb39bade
11 changed files with 275 additions and 3 deletions

View File

@ -1,6 +1,6 @@
# Book 业务分区 # Book 业务分区
定义Book业务逻辑 ## 定义Book业务逻辑
业务功能: CRUD 业务功能: CRUD
1. 创建书籍(录入) 1. 创建书籍(录入)
@ -9,4 +9,54 @@
4. Book更新 4. Book更新
5. Book删除 5. Book删除
通过Go语言的里面的接口 来定义描述业务功能 通过Go语言的里面的接口 来定义描述业务功能
```go
// book.Service, Book的业务定义
type Service interface {
// 1. 创建书籍(录入)
CreateBook(context.Context, *CreateBookRequest) (*Book, error)
// 2. Book列表查询
QueryBook(context.Context, *QueryBookRequest) (*types.Set[*Book], error)
// 3. Book详情查询
DescribeBook(context.Context, *DescribeBookRequest) (*Book, error)
// 4. Book更新
UpdateBook(context.Context, *UpdateBookRequest) (*Book, error)
// 5. Book删除
DeleteBook(context.Context, *DeleteBookRequest) error
}
```
## 业务的具体实现(TDD Test Drive Develop)
1. BookServiceImpl
```go
// CreateBook implements book.Service.
func (b *BookServiceImpl) CreateBook(context.Context, *book.CreateBookRequest) (*book.Book, error) {
panic("unimplemented")
}
// DeleteBook implements book.Service.
func (b *BookServiceImpl) DeleteBook(context.Context, *book.DeleteBookRequest) error {
panic("unimplemented")
}
// DescribeBook implements book.Service.
func (b *BookServiceImpl) DescribeBook(context.Context, *book.DescribeBookRequest) (*book.Book, error) {
panic("unimplemented")
}
// QueryBook implements book.Service.
func (b *BookServiceImpl) QueryBook(context.Context, *book.QueryBookRequest) (*types.Set[*book.Book], error) {
panic("unimplemented")
}
// UpdateBook implements book.Service.
func (b *BookServiceImpl) UpdateBook(context.Context, *book.UpdateBookRequest) (*book.Book, error) {
panic("unimplemented")
}
```
编写单元测试

View File

@ -0,0 +1,3 @@
# 业务实现包
ServiceImpl(book.Service)

View File

@ -0,0 +1,49 @@
package impl
import (
"context"
"122.51.31.227/go-course/go18/book/v3/config"
"122.51.31.227/go-course/go18/book/v4/apps/book"
"github.com/infraboard/mcube/v2/exception"
"github.com/infraboard/mcube/v2/types"
)
// CreateBook implements book.Service.
func (b *BookServiceImpl) CreateBook(ctx context.Context, in *book.CreateBookRequest) (*book.Book, error) {
// 自定义异常改造, 放到mcube
// 自定义异常, exception 包, 统一放到一个公共库里面, mcube
if err := in.Validate(); err != nil {
return nil, exception.NewBadRequest("校验Book创建失败, %s", err)
}
bookInstance := &book.Book{CreateBookRequest: *in}
// config对象改造
// 数据入库(Grom), 补充自增Id的值
if err := config.DB().Save(bookInstance).Error; err != nil {
return nil, err
}
return bookInstance, nil
}
// DeleteBook implements book.Service.
func (b *BookServiceImpl) DeleteBook(context.Context, *book.DeleteBookRequest) error {
panic("unimplemented")
}
// DescribeBook implements book.Service.
func (b *BookServiceImpl) DescribeBook(context.Context, *book.DescribeBookRequest) (*book.Book, error) {
panic("unimplemented")
}
// QueryBook implements book.Service.
func (b *BookServiceImpl) QueryBook(context.Context, *book.QueryBookRequest) (*types.Set[*book.Book], error) {
panic("unimplemented")
}
// UpdateBook implements book.Service.
func (b *BookServiceImpl) UpdateBook(context.Context, *book.UpdateBookRequest) (*book.Book, error) {
panic("unimplemented")
}

View File

@ -0,0 +1,22 @@
package impl_test
import (
"testing"
"122.51.31.227/go-course/go18/book/v4/apps/book"
)
//
func TestCreateBook(t *testing.T) {
req := book.NewCreateBookRequest()
req.SetIsSale(true)
req.Title = "Go语言V4"
req.Author = "will"
req.Price = 10
ins, err := svc.CreateBook(ctx, req)
if err != nil {
t.Fatal(err)
}
t.Log(ins)
}

View File

@ -0,0 +1,18 @@
package impl
import (
"122.51.31.227/go-course/go18/book/v4/apps/book"
)
// 怎么知道他有没有实现该业务, 可以通过类型约束
// var _ book.Service = &BookServiceImpl{}
// &BookServiceImpl 的 nil对象
//
// int64(1) int64 1
// *BookServiceImpl(nil)
var _ book.Service = (*BookServiceImpl)(nil)
// Book业务的具体实现
type BookServiceImpl struct {
}

View File

@ -0,0 +1,10 @@
package impl_test
import (
"context"
"122.51.31.227/go-course/go18/book/v4/apps/book/impl"
)
var ctx = context.Background()
var svc = impl.BookServiceImpl{}

View File

@ -3,6 +3,8 @@ package book
import ( import (
"context" "context"
"github.com/infraboard/mcube/v2/http/request"
"github.com/infraboard/mcube/v2/ioc/config/validator"
"github.com/infraboard/mcube/v2/types" "github.com/infraboard/mcube/v2/types"
) )
@ -13,8 +15,24 @@ type Service interface {
// 2. Book列表查询 // 2. Book列表查询
QueryBook(context.Context, *QueryBookRequest) (*types.Set[*Book], error) QueryBook(context.Context, *QueryBookRequest) (*types.Set[*Book], error)
// 3. Book详情查询 // 3. Book详情查询
DescribeBook(context.Context, *DescribeBookRequest) (*Book, error)
// 4. Book更新 // 4. Book更新
UpdateBook(context.Context, *UpdateBookRequest) (*Book, error)
// 5. Book删除 // 5. Book删除
DeleteBook(context.Context, *DeleteBookRequest) error
}
type DeleteBookRequest struct {
DescribeBookRequest
}
type UpdateBookRequest struct {
DescribeBookRequest
CreateBookRequest
}
type DescribeBookRequest struct {
Id uint
} }
type BookSet struct { type BookSet struct {
@ -39,6 +57,10 @@ func (b *BookSet) Add(item *Book) {
// b.Items = append(b.Items, item) // b.Items = append(b.Items, item)
// } // }
func NewCreateBookRequest() *CreateBookRequest {
return (&CreateBookRequest{}).SetIsSale(false)
}
type CreateBookRequest struct { type CreateBookRequest struct {
// type 用于要使用gorm 来自动创建和更新表的时候 才需要定义 // type 用于要使用gorm 来自动创建和更新表的时候 才需要定义
Title string `json:"title" gorm:"column:title;type:varchar(200)" validate:"required"` Title string `json:"title" gorm:"column:title;type:varchar(200)" validate:"required"`
@ -49,5 +71,29 @@ type CreateBookRequest struct {
IsSale *bool `json:"is_sale" gorm:"column:is_sale"` IsSale *bool `json:"is_sale" gorm:"column:is_sale"`
} }
type QueryBookRequest struct { // 这个请求对象的教育
func (r *CreateBookRequest) Validate() error {
// validate := validator.New()
// validate.Struct(r)
return validator.Validate(r)
}
func (r *CreateBookRequest) SetIsSale(v bool) *CreateBookRequest {
r.IsSale = &v
return r
}
func NewQueryBookRequest() *QueryBookRequest {
return &QueryBookRequest{
// PageRequest{PageSize:20, PageNumber: 1}
PageRequest: *request.NewDefaultPageRequest(),
}
}
type QueryBookRequest struct {
// PageSize uint
// PageNumber uint
request.PageRequest
// 关键字参数
Keywords string `json:"keywords"`
} }

2
go.mod
View File

@ -14,6 +14,7 @@ require (
) )
require ( require (
github.com/BurntSushi/toml v1.5.0 // indirect
github.com/bytedance/sonic v1.13.2 // indirect github.com/bytedance/sonic v1.13.2 // indirect
github.com/bytedance/sonic/loader v0.2.4 // indirect github.com/bytedance/sonic/loader v0.2.4 // indirect
github.com/cloudwego/base64x v0.1.5 // indirect github.com/cloudwego/base64x v0.1.5 // indirect
@ -32,6 +33,7 @@ require (
github.com/leodido/go-urn v1.4.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect

4
go.sum
View File

@ -1,3 +1,5 @@
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ= github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ=
github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
@ -54,6 +56,8 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=

65
skills/mcube/README.md Normal file
View File

@ -0,0 +1,65 @@
# 配置(依赖注入)
## Config大对象
容易理解, 方便维护, 这个配置就是和项目绑定
```go
// 这歌对象就是程序配置
// yaml, toml
type Config struct {
Application *application `toml:"app" yaml:"app" json:"app"`
MySQL *mySQL `toml:"mysql" yaml:"mysql" json:"mysql"`
Log *Log `toml:"log" yaml:"log" json:"log"`
}
```
```yaml
app:
host: 127.0.0.1
port: 8080
mysql:
host: 127.0.0.1
port: 3306
database: go18
username: "root"
password: "123456"
debug: true
```
## 依赖注入
大对象,没法按照项目需求,自由组装
datasource
```toml
[datasource]
provider = "mysql"
host = "127.0.0.1"
port = 3306
database = ""
username = ""
password = ""
auto_migrate = false
debug = false
trace = true
```
```go
package main
import (
"fmt"
// 自动解析配置文件里面, 相应的部分
"github.com/infraboard/mcube/v2/ioc/config/datasource"
)
func main() {
db := datasource.DB()
// 通过db对象进行数据库操作
fmt.Println(db)
}
```

3
skills/mcube/config.go Normal file
View File

@ -0,0 +1,3 @@
package mcube
// 依赖注入