bot 类型 添加 删除 校验

This commit is contained in:
Shikong 2023-02-28 00:03:02 +08:00
parent a509d108d4
commit e53ca6a47f
15 changed files with 558 additions and 83 deletions

View File

@ -1,48 +1,42 @@
# 工作目录
# 使用 . 或绝对路径,请注意 `tmp_dir` 目录必须在 `root` 目录下
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"
[build]
# 只需要写你平常编译使用的shell命令。你也可以使用 `make`
# Windows平台示例: cmd = "go build -o tmp\main.exe ."
cmd = "go build -o ./tmp/main ."
# 由`cmd`命令得到的二进制文件名
# Windows平台示例bin = "tmp\main.exe"
bin = "tmp/main"
# 自定义执行程序的命令,可以添加额外的编译标识例如添加 GIN_MODE=release
# Windows平台示例full_bin = "tmp\main.exe"
#full_bin = "APP_ENV=dev APP_USER=air ./tmp/main"
full_bin = "tmp/main
# 监听以下文件扩展名的文件.
include_ext = ["go", "tpl", "tmpl", "html"]
# 忽略这些文件扩展名或目录
exclude_dir = ["assets", "tmp", "vendor", "frontend/node_modules"]
# 监听以下指定目录的文件
include_dir = []
# 排除以下文件
exclude_file = []
# 如果文件更改过于频繁,则没有必要在每次更改时都触发构建。可以设置触发构建的延迟时间
delay = 1000 # ms
# 发生构建错误时,停止运行旧的二进制文件。
stop_on_error = true
# air的日志文件名该日志文件放置在你的`tmp_dir`中
log = "air_errors.log"
[log]
# 显示日志时间
time = true
args_bin = []
bin = "tmp\\main.exe"
cmd = "go build -o ./tmp/main.exe ."
delay = 1500
exclude_dir = ["assets", "tmp", "vendor", "testdata"]
exclude_file = []
exclude_regex = ["_test.go"]
exclude_unchanged = false
follow_symlink = false
full_bin = ""
include_dir = []
include_ext = ["go", "tpl", "tmpl", "html"]
include_file = []
kill_delay = "0s"
log = "build-errors.log"
rerun = false
rerun_delay = 500
send_interrupt = true
stop_on_error = false
[color]
# 自定义每个部分显示的颜色。如果找不到颜色,使用原始的应用程序日志。
main = "magenta"
watcher = "cyan"
build = "yellow"
runner = "green"
app = ""
build = "yellow"
main = "magenta"
runner = "green"
watcher = "cyan"
[log]
main_only = false
time = false
[misc]
# 退出时删除tmp目录
clean_on_exit = true
clean_on_exit = false
[screen]
clear_on_rebuild = false
keep_scroll = true

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CodeStream">
<option name="webViewContext" value="{&quot;chatProviderAccess&quot;:&quot;strict&quot;,&quot;currentTeamId&quot;:&quot;&quot;,&quot;currentStreamId&quot;:&quot;&quot;,&quot;pullRequestCheckoutBranch&quot;:false,&quot;isRepositioning&quot;:false,&quot;onboardStep&quot;:0,&quot;panelStack&quot;:[&quot;landing-redirect&quot;],&quot;hasFocus&quot;:false,&quot;channelFilter&quot;:&quot;all&quot;,&quot;channelsMuteAll&quot;:false,&quot;codemarkFileFilter&quot;:&quot;all&quot;,&quot;codemarkTypeFilter&quot;:&quot;all&quot;,&quot;codemarkTagFilter&quot;:&quot;all&quot;,&quot;codemarkBranchFilter&quot;:&quot;all&quot;,&quot;codemarkAuthorFilter&quot;:&quot;all&quot;,&quot;codemarksFileViewStyle&quot;:&quot;inline&quot;,&quot;codemarksShowArchived&quot;:false,&quot;codemarksShowResolved&quot;:false,&quot;codemarksWrapComments&quot;:false,&quot;showFeedbackSmiley&quot;:true,&quot;route&quot;:{&quot;name&quot;:&quot;newUserEntry&quot;,&quot;params&quot;:{}},&quot;spatialViewShowPRComments&quot;:false,&quot;currentPullRequestNeedsRefresh&quot;:{&quot;needsRefresh&quot;:false,&quot;providerId&quot;:&quot;&quot;,&quot;pullRequestId&quot;:&quot;&quot;},&quot;__teamless__&quot;:{&quot;selectedRegion&quot;:&quot;us&quot;},&quot;sessionStart&quot;:1677477984122}" />
<option name="webViewContext" value="{&quot;chatProviderAccess&quot;:&quot;strict&quot;,&quot;currentTeamId&quot;:&quot;&quot;,&quot;currentStreamId&quot;:&quot;&quot;,&quot;pullRequestCheckoutBranch&quot;:false,&quot;isRepositioning&quot;:false,&quot;onboardStep&quot;:0,&quot;panelStack&quot;:[&quot;landing-redirect&quot;],&quot;hasFocus&quot;:false,&quot;channelFilter&quot;:&quot;all&quot;,&quot;channelsMuteAll&quot;:false,&quot;codemarkFileFilter&quot;:&quot;all&quot;,&quot;codemarkTypeFilter&quot;:&quot;all&quot;,&quot;codemarkTagFilter&quot;:&quot;all&quot;,&quot;codemarkBranchFilter&quot;:&quot;all&quot;,&quot;codemarkAuthorFilter&quot;:&quot;all&quot;,&quot;codemarksFileViewStyle&quot;:&quot;inline&quot;,&quot;codemarksShowArchived&quot;:false,&quot;codemarksShowResolved&quot;:false,&quot;codemarksWrapComments&quot;:false,&quot;showFeedbackSmiley&quot;:true,&quot;route&quot;:{&quot;name&quot;:&quot;newUserEntry&quot;,&quot;params&quot;:{}},&quot;spatialViewShowPRComments&quot;:false,&quot;currentPullRequestNeedsRefresh&quot;:{&quot;needsRefresh&quot;:false,&quot;providerId&quot;:&quot;&quot;,&quot;pullRequestId&quot;:&quot;&quot;},&quot;__teamless__&quot;:{&quot;selectedRegion&quot;:&quot;us&quot;},&quot;sessionStart&quot;:1677493609591}" />
</component>
</project>

View File

@ -23,6 +23,108 @@ const docTemplate = `{
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {
"/bot/type/add": {
"post": {
"description": "添加 bot 类型",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"BotType"
],
"summary": "添加 bot 类型",
"parameters": [
{
"description": "bot 类型",
"name": "vo",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/bottype.AddBotTypeDto"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/resp.Response"
},
{
"type": "object",
"properties": {
"data": {
"type": "boolean"
}
}
}
]
}
},
"default": {
"description": "",
"schema": {
"$ref": "#/definitions/errorx.CodeErrorResponse"
}
}
}
}
},
"/bot/type/del": {
"delete": {
"description": "根据 id 删除 bot 类型",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"BotType"
],
"summary": "删除 bot 类型",
"parameters": [
{
"type": "string",
"description": "bot 类型id",
"name": "id",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/resp.Response"
},
{
"type": "object",
"properties": {
"data": {
"type": "boolean"
}
}
}
]
}
},
"default": {
"description": "",
"schema": {
"$ref": "#/definitions/errorx.CodeErrorResponse"
}
}
}
}
},
"/bot/type/list": {
"get": {
"description": "获取 bot 类型列表",
@ -69,15 +171,36 @@ const docTemplate = `{
}
},
"definitions": {
"bottype.AddBotTypeDto": {
"type": "object",
"required": [
"active",
"name"
],
"properties": {
"active": {
"description": "是否启用",
"type": "boolean"
},
"name": {
"description": "名称",
"type": "string"
}
}
},
"errorx.CodeErrorResponse": {
"type": "object",
"properties": {
"code": {
"description": "状态码",
"type": "integer",
"example": 200
},
"data": {},
"data": {
"description": "数据"
},
"msg": {
"description": "信息",
"type": "string",
"example": "OK"
}
@ -104,11 +227,15 @@ const docTemplate = `{
"type": "object",
"properties": {
"code": {
"description": "状态码",
"type": "integer",
"example": 200
},
"data": {},
"data": {
"description": "数据"
},
"msg": {
"description": "信息",
"type": "string",
"example": "OK"
}

View File

@ -16,6 +16,108 @@
},
"basePath": "/",
"paths": {
"/bot/type/add": {
"post": {
"description": "添加 bot 类型",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"BotType"
],
"summary": "添加 bot 类型",
"parameters": [
{
"description": "bot 类型",
"name": "vo",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/bottype.AddBotTypeDto"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/resp.Response"
},
{
"type": "object",
"properties": {
"data": {
"type": "boolean"
}
}
}
]
}
},
"default": {
"description": "",
"schema": {
"$ref": "#/definitions/errorx.CodeErrorResponse"
}
}
}
}
},
"/bot/type/del": {
"delete": {
"description": "根据 id 删除 bot 类型",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"BotType"
],
"summary": "删除 bot 类型",
"parameters": [
{
"type": "string",
"description": "bot 类型id",
"name": "id",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/resp.Response"
},
{
"type": "object",
"properties": {
"data": {
"type": "boolean"
}
}
}
]
}
},
"default": {
"description": "",
"schema": {
"$ref": "#/definitions/errorx.CodeErrorResponse"
}
}
}
}
},
"/bot/type/list": {
"get": {
"description": "获取 bot 类型列表",
@ -62,15 +164,36 @@
}
},
"definitions": {
"bottype.AddBotTypeDto": {
"type": "object",
"required": [
"active",
"name"
],
"properties": {
"active": {
"description": "是否启用",
"type": "boolean"
},
"name": {
"description": "名称",
"type": "string"
}
}
},
"errorx.CodeErrorResponse": {
"type": "object",
"properties": {
"code": {
"description": "状态码",
"type": "integer",
"example": 200
},
"data": {},
"data": {
"description": "数据"
},
"msg": {
"description": "信息",
"type": "string",
"example": "OK"
}
@ -97,11 +220,15 @@
"type": "object",
"properties": {
"code": {
"description": "状态码",
"type": "integer",
"example": 200
},
"data": {},
"data": {
"description": "数据"
},
"msg": {
"description": "信息",
"type": "string",
"example": "OK"
}

View File

@ -1,12 +1,27 @@
basePath: /
definitions:
bottype.AddBotTypeDto:
properties:
active:
description: 是否启用
type: boolean
name:
description: 名称
type: string
required:
- active
- name
type: object
errorx.CodeErrorResponse:
properties:
code:
description: 状态码
example: 200
type: integer
data: {}
data:
description: 数据
msg:
description: 信息
example: OK
type: string
type: object
@ -25,10 +40,13 @@ definitions:
resp.Response:
properties:
code:
description: 状态码
example: 200
type: integer
data: {}
data:
description: 数据
msg:
description: 信息
example: OK
type: string
type: object
@ -44,6 +62,67 @@ info:
title: matrix-middle-service API
version: "1.0"
paths:
/bot/type/add:
post:
consumes:
- application/json
description: 添加 bot 类型
parameters:
- description: bot 类型
in: body
name: vo
required: true
schema:
$ref: '#/definitions/bottype.AddBotTypeDto'
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/resp.Response'
- properties:
data:
type: boolean
type: object
default:
description: ""
schema:
$ref: '#/definitions/errorx.CodeErrorResponse'
summary: 添加 bot 类型
tags:
- BotType
/bot/type/del:
delete:
consumes:
- application/json
description: 根据 id 删除 bot 类型
parameters:
- description: bot 类型id
in: query
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/resp.Response'
- properties:
data:
type: boolean
type: object
default:
description: ""
schema:
$ref: '#/definitions/errorx.CodeErrorResponse'
summary: 删除 bot 类型
tags:
- BotType
/bot/type/list:
get:
consumes:

View File

@ -34,6 +34,7 @@ require (
github.com/goccy/go-json v0.8.1 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gookit/goutil v0.6.6 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
@ -64,6 +65,7 @@ require (
go.uber.org/multierr v1.8.0 // indirect
golang.org/x/crypto v0.5.0 // indirect
golang.org/x/net v0.5.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/text v0.7.0 // indirect
golang.org/x/tools v0.1.12 // indirect

View File

@ -234,6 +234,8 @@ github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
github.com/gookit/goutil v0.6.6 h1:XdvnPocHpKDXA+eykfc/F846Y1V2Vyo3+cV8rfliG90=
github.com/gookit/goutil v0.6.6/go.mod h1:D++7kbQd/6vECyYTxB5tq6AKDIG9ZYwZNhubWJvN9dw=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
@ -715,6 +717,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=

View File

@ -1,32 +0,0 @@
package controller
import (
"github.com/gofiber/fiber/v2"
"matrix-middle-service/pkg/database"
response "matrix-middle-service/pkg/resp"
"matrix-middle-service/pkg/resp/errorx"
)
func SetupBotController(r fiber.Router) {
api := r.Group("/bot")
api.Get("/type/list", GetBotTypeList)
}
// GetBotTypeList
// @Summary 获取 bot 类型列表
// @Description 获取 bot 类型列表
// @Tags BotType
// @Accept json
// @Produce json
// @Success 200 {object} response.Response{data=[]model.BotType}
// @Failure default {object} errorx.CodeErrorResponse
// @Router /bot/type/list [get]
func GetBotTypeList(ctx *fiber.Ctx) error {
return database.Exec(func(db database.DataBase) error {
list, err := db.GetAllBotTypes()
if err = errorx.ParseError(err); err != nil {
return ctx.JSON(err)
}
return ctx.JSON(response.NewResponse(list))
})
}

View File

@ -0,0 +1,11 @@
package bot
import (
"github.com/gofiber/fiber/v2"
"matrix-middle-service/internel/controller/bot/bottype"
)
func SetupBotController(r fiber.Router) {
api := r.Group("/bot")
bottype.SetupBotType(api)
}

View File

@ -0,0 +1,108 @@
package bottype
import (
"github.com/gofiber/fiber/v2"
"matrix-middle-service/pkg/database"
"matrix-middle-service/pkg/database/model"
response "matrix-middle-service/pkg/resp"
"matrix-middle-service/pkg/resp/errorx"
"matrix-middle-service/pkg/utils/sonyflake"
"matrix-middle-service/pkg/utils/validator"
)
func SetupBotType(r fiber.Router) {
api := r.Group("/type")
getBotTypeList(api)
addBotType(api)
DeleteBotTypeById(api)
}
// GetBotTypeList
// @Summary 获取 bot 类型列表
// @Description 获取 bot 类型列表
// @Tags BotType
// @Accept json
// @Produce json
// @Success 200 {object} response.Response{data=[]model.BotType}
// @Failure default {object} errorx.CodeErrorResponse
// @Router /bot/type/list [get]
func getBotTypeList(api fiber.Router) {
api.Get("/list", func(ctx *fiber.Ctx) error {
return database.Exec(func(db database.DataBase) error {
list, err := db.GetAllBotTypes()
if err = errorx.ParseError(err); err != nil {
return ctx.JSON(err)
}
return ctx.JSON(response.NewResponse(list))
})
})
}
type AddBotTypeDto struct {
// 名称
Name string `json:"name" validate:"required"`
// 是否启用
Active bool `json:"active" validate:"required"`
}
// AddBotType
// @Summary 添加 bot 类型
// @Description 添加 bot 类型
// @Tags BotType
// @Accept json
// @Produce json
// @Param vo body AddBotTypeDto true "bot 类型"
// @Success 200 {object} response.Response{data=bool}
// @Failure default {object} errorx.CodeErrorResponse
// @Router /bot/type/add [post]
func addBotType(api fiber.Router) {
api.Post("/add", func(ctx *fiber.Ctx) error {
dto := &AddBotTypeDto{}
err := ctx.BodyParser(dto)
if err = errorx.ParseError(err); err != nil {
return ctx.JSON(err)
}
err = validator.ValidateStruct(dto)
if err = errorx.ParseError(err); err != nil {
return ctx.JSON(err)
}
return database.Exec(func(db database.DataBase) error {
bt := &model.BotType{
Id: sonyflake.NextStrId(),
Name: dto.Name,
Active: dto.Active,
}
err = db.AddBotType(bt)
if err = errorx.ParseError(err); err != nil {
return ctx.JSON(err)
}
return ctx.JSON(response.NewResponse(true))
})
})
}
// DeleteBotTypeById
// @Summary 删除 bot 类型
// @Description 根据 id 删除 bot 类型
// @Tags BotType
// @Accept json
// @Produce json
// @Param id query string true "bot 类型id"
// @Success 200 {object} response.Response{data=bool}
// @Failure default {object} errorx.CodeErrorResponse
// @Router /bot/type/del [delete]
func DeleteBotTypeById(api fiber.Router) {
api.Delete("/del", func(ctx *fiber.Ctx) error {
id := ctx.Query("id")
return database.Exec(func(db database.DataBase) error {
err := db.DeleteBotTypeById(id)
if err = errorx.ParseError(err); err != nil {
return ctx.JSON(err)
}
return ctx.JSON(response.NewResponse(true))
})
})
}

View File

@ -2,7 +2,7 @@ package route
import (
"github.com/gofiber/fiber/v2"
"matrix-middle-service/internel/controller"
"matrix-middle-service/internel/controller/bot"
"matrix-middle-service/pkg/config"
)
@ -11,5 +11,5 @@ func SetupRoute(app *fiber.App, conf *config.Conf) {
SwaggerHandler(app)
}
controller.SetupBotController(app)
bot.SetupBotController(app)
}

View File

@ -17,6 +17,8 @@ type DataBase interface {
Close() error
GetAllBotTypes() ([]*model.BotType, error)
AddBotType(bt *model.BotType) error
DeleteBotTypeById(id string) error
}
func Init(conf []interface{}) {

View File

@ -2,8 +2,10 @@ package mysql
import (
"database/sql"
"errors"
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/gookit/goutil/strutil"
"github.com/mitchellh/mapstructure"
database2 "matrix-middle-service/pkg/config/database"
"matrix-middle-service/pkg/database"
@ -53,6 +55,44 @@ type db struct {
config *conf.Config
}
func (d *db) DeleteBotTypeById(id string) error {
if strutil.IsBlank(id) {
return errors.New(fmt.Sprintf("id 不能为空"))
}
exist, err := d.db.Exist(&model.BotType{Id: id})
if err != nil {
return err
}
if !exist {
return errors.New(fmt.Sprintf("类型id %s 不存在", id))
}
_, err = d.db.Limit(1).Delete(&model.BotType{Id: id})
return err
}
func (d *db) AddBotType(bt *model.BotType) error {
if strutil.IsBlank(bt.Id) {
return errors.New(fmt.Sprintf("id 不能为空"))
}
if strutil.IsBlank(bt.Name) {
return errors.New(fmt.Sprintf("类型名称 不能为空"))
}
exist, err := d.db.Exist(&model.BotType{Name: bt.Name})
if err != nil {
return err
}
if exist {
return errors.New(fmt.Sprintf("类型 %s 已存在", bt.Name))
}
_, err = d.db.UseBool("active").Insert(bt)
return err
}
func (d *db) GetAllBotTypes() ([]*model.BotType, error) {
list := make([]*model.BotType, 0)
err := d.db.Find(&list)

View File

@ -1,9 +1,12 @@
package resp
type Response struct {
Code Code `json:"code" example:"200"`
// 状态码
Code Code `json:"code" example:"200"`
// 数据
Data interface{} `json:"data"`
Msg string `json:"msg" example:"OK"`
// 信息
Msg string `json:"msg" example:"OK"`
}
type Code = int

View File

@ -1,6 +1,7 @@
package sonyflake
import (
"fmt"
"github.com/sony/sonyflake"
sf "matrix-middle-service/pkg/config/sonyflake"
"matrix-middle-service/pkg/logger"
@ -19,3 +20,12 @@ func Init(config *sf.Config) {
func SonyFlake() *sonyflake.Sonyflake {
return generator
}
func NextId() uint64 {
id, _ := generator.NextID()
return id
}
func NextStrId() string {
return fmt.Sprintf("%d", NextId())
}