feat: 新增gozero适配器

This commit is contained in:
tangtanglove
2023-01-30 16:09:34 +08:00
parent 2fbf003eea
commit 56c392c9b3
16 changed files with 1860 additions and 22 deletions

View File

@@ -0,0 +1,9 @@
# Config file for [Air](https://github.com/cosmtrek/air) in TOML format
# Working directory
# . or absolute path, please note that the directories following must be under root.
root = "."
tmp_dir = "tmp"
[build]
exclude_dir = ["assets", "tmp", "vendor", "website"]

View File

@@ -0,0 +1,3 @@
Name: zeroadmin-api
Host: 0.0.0.0
Port: 3000

View File

@@ -0,0 +1,7 @@
package config
import "github.com/zeromicro/go-zero/rest"
type Config struct {
rest.RestConf
}

View File

@@ -0,0 +1,22 @@
// Code generated by goctl. DO NOT EDIT.
package handler
import (
"net/http"
"github.com/quarkcms/quark-go/examples/zeroadmin/internal/svc"
"github.com/zeromicro/go-zero/rest"
)
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
server.AddRoutes(
[]rest.Route{
{
Method: http.MethodGet,
Path: "/from/:name",
Handler: ZeroadminHandler(serverCtx),
},
},
)
}

View File

@@ -0,0 +1,28 @@
package handler
import (
"net/http"
"github.com/quarkcms/quark-go/examples/zeroadmin/internal/logic"
"github.com/quarkcms/quark-go/examples/zeroadmin/internal/svc"
"github.com/quarkcms/quark-go/examples/zeroadmin/internal/types"
"github.com/zeromicro/go-zero/rest/httpx"
)
func ZeroadminHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.Request
if err := httpx.Parse(r, &req); err != nil {
httpx.Error(w, err)
return
}
l := logic.NewZeroadminLogic(r.Context(), svcCtx)
resp, err := l.Zeroadmin(&req)
if err != nil {
httpx.Error(w, err)
} else {
httpx.OkJson(w, resp)
}
}
}

View File

@@ -0,0 +1,29 @@
package logic
import (
"context"
"github.com/quarkcms/quark-go/examples/zeroadmin/internal/svc"
"github.com/quarkcms/quark-go/examples/zeroadmin/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type ZeroadminLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewZeroadminLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ZeroadminLogic {
return &ZeroadminLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *ZeroadminLogic) Zeroadmin(req *types.Request) (resp *types.Response, err error) {
// todo: add your logic here and delete this line
return
}

View File

@@ -0,0 +1,15 @@
package svc
import (
"github.com/quarkcms/quark-go/examples/zeroadmin/internal/config"
)
type ServiceContext struct {
Config config.Config
}
func NewServiceContext(c config.Config) *ServiceContext {
return &ServiceContext{
Config: c,
}
}

View File

@@ -0,0 +1,10 @@
// Code generated by goctl. DO NOT EDIT.
package types
type Request struct {
Name string `path:"name,options=you|me"`
}
type Response struct {
Message string `json:"message"`
}

View File

@@ -0,0 +1,12 @@
type Request {
Name string `path:"name,options=you|me"`
}
type Response {
Message string `json:"message"`
}
service zeroadmin-api {
@handler ZeroadminHandler
get /from/:name(Request) returns (Response)
}

View File

@@ -0,0 +1,100 @@
package main
import (
"flag"
"fmt"
"io/ioutil"
"net/http"
"os"
"github.com/quarkcms/quark-go/examples/zeroadmin/internal/config"
"github.com/quarkcms/quark-go/examples/zeroadmin/internal/handler"
"github.com/quarkcms/quark-go/examples/zeroadmin/internal/svc"
"github.com/quarkcms/quark-go/pkg/adapter/zeroadapter"
"github.com/quarkcms/quark-go/pkg/app/handler/admin"
"github.com/quarkcms/quark-go/pkg/app/install"
"github.com/quarkcms/quark-go/pkg/app/middleware"
"github.com/quarkcms/quark-go/pkg/builder"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"github.com/zeromicro/go-zero/core/conf"
"github.com/zeromicro/go-zero/rest"
)
var configFile = flag.String("f", "etc/zeroadmin-api.yaml", "the config file")
func main() {
flag.Parse()
var c config.Config
conf.MustLoad(*configFile, &c)
server := rest.MustNewServer(c.RestConf)
defer server.Stop()
// 加载静态文件
staticFile("/", "./website", server)
ctx := svc.NewServiceContext(c)
handler.RegisterHandlers(server, ctx)
// 数据库配置信息
dsn := "root:Bc5HQFJc4bLjZCcC@tcp(127.0.0.1:3306)/quarkgo?charset=utf8&parseTime=True&loc=Local"
// 配置资源
config := &builder.Config{
AppKey: "123456",
Providers: admin.Providers,
DBConfig: &builder.DBConfig{
Dialector: mysql.Open(dsn),
Opts: &gorm.Config{},
},
}
// 创建对象
b := builder.New(config)
// 初始化安装
b.Use(install.Handle)
// 中间件
b.Use(middleware.Handle)
// 适配gozero
zeroadapter.Adapter(b, server)
fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
server.Start()
}
// 加载静态文件
func staticFile(root string, dirPath string, server *rest.Server) {
rd, _ := ioutil.ReadDir(dirPath)
for _, f := range rd {
fileName := f.Name()
subPath := root + fileName + "/"
subDirPath := dirPath + "/" + fileName
if isDir(subDirPath) {
staticFile(subPath, subDirPath, server)
}
}
server.AddRoute(
rest.Route{
Method: http.MethodGet,
Path: root + ":file",
Handler: http.StripPrefix(root, http.FileServer(http.Dir(dirPath))).ServeHTTP,
},
)
}
// 判断所给路径是否为文件夹
func isDir(path string) bool {
s, err := os.Stat(path)
if err != nil {
return false
}
return s.IsDir()
}

36
go.mod
View File

@@ -10,6 +10,7 @@ require (
github.com/cloudwego/hertz v0.4.2 github.com/cloudwego/hertz v0.4.2
github.com/dchest/captcha v1.0.0 github.com/dchest/captcha v1.0.0
github.com/derekstavis/go-qs v0.0.0-20180720192143-9eef69e6c4e7 github.com/derekstavis/go-qs v0.0.0-20180720192143-9eef69e6c4e7
github.com/gin-contrib/static v0.0.1
github.com/go-basic/uuid v1.0.0 github.com/go-basic/uuid v1.0.0
github.com/go-redis/redis/v8 v8.11.5 github.com/go-redis/redis/v8 v8.11.5
github.com/gobeam/stringy v0.0.5 github.com/gobeam/stringy v0.0.5
@@ -25,16 +26,44 @@ require (
) )
require ( require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/felixge/fgprof v0.9.3 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect
github.com/gin-contrib/static v0.0.1 // indirect github.com/go-logr/logr v1.2.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-playground/locales v0.14.0 // indirect github.com/go-playground/locales v0.14.0 // indirect
github.com/go-playground/universal-translator v0.18.0 // indirect github.com/go-playground/universal-translator v0.18.0 // indirect
github.com/go-playground/validator/v10 v10.11.1 // indirect github.com/go-playground/validator/v10 v10.11.1 // indirect
github.com/goccy/go-json v0.9.11 // indirect github.com/goccy/go-json v0.9.11 // indirect
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect
github.com/leodido/go-urn v1.2.1 // indirect github.com/leodido/go-urn v1.2.1 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/openzipkin/zipkin-go v0.4.0 // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/prometheus/client_golang v1.13.0 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/ugorji/go/codec v1.2.7 // indirect github.com/ugorji/go/codec v1.2.7 // indirect
go.opentelemetry.io/otel v1.10.0 // indirect
go.opentelemetry.io/otel/exporters/jaeger v1.10.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.10.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.10.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.10.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.10.0 // indirect
go.opentelemetry.io/otel/exporters/zipkin v1.10.0 // indirect
go.opentelemetry.io/otel/sdk v1.10.0 // indirect
go.opentelemetry.io/otel/trace v1.10.0 // indirect
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
go.uber.org/automaxprocs v1.5.1 // indirect
golang.org/x/time v0.3.0 // indirect golang.org/x/time v0.3.0 // indirect
google.golang.org/genproto v0.0.0-20221111202108-142d8a6fa32e // indirect
google.golang.org/grpc v1.50.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
) )
@@ -60,7 +89,7 @@ require (
github.com/gin-gonic/gin v1.8.2 github.com/gin-gonic/gin v1.8.2
github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-sql-driver/mysql v1.7.0 // indirect github.com/go-sql-driver/mysql v1.7.0 // indirect
github.com/golang/protobuf v1.5.0 // indirect github.com/golang/protobuf v1.5.2 // indirect
github.com/henrylee2cn/ameda v1.4.10 // indirect github.com/henrylee2cn/ameda v1.4.10 // indirect
github.com/henrylee2cn/goutil v0.0.0-20210127050712-89660552f6f8 // indirect github.com/henrylee2cn/goutil v0.0.0-20210127050712-89660552f6f8 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect
@@ -71,7 +100,7 @@ require (
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.17 // indirect github.com/mattn/go-isatty v0.0.17 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // 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/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/nyaruka/phonenumbers v1.0.55 // indirect github.com/nyaruka/phonenumbers v1.0.55 // indirect
@@ -92,6 +121,7 @@ require (
github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 // indirect github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 // indirect
github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 // indirect github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect
github.com/zeromicro/go-zero v1.4.4
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
golang.org/x/net v0.5.0 // indirect golang.org/x/net v0.5.0 // indirect
golang.org/x/sys v0.4.0 // indirect golang.org/x/sys v0.4.0 // indirect

1318
go.sum

File diff suppressed because it is too large Load Diff

View File

@@ -28,10 +28,20 @@ func RequestAdapter(ctx *gin.Context) (*builder.Request, error) {
//把读过的字节流重新放到body //把读过的字节流重新放到body
ctx.Request.Body = ioutil.NopCloser(bytes.NewBuffer(data)) ctx.Request.Body = ioutil.NopCloser(bytes.NewBuffer(data))
headerString := ""
for hk, hvs := range ctx.Request.Header {
tmp := ""
for _, v := range hvs {
tmp = tmp + "," + v
}
tmp = strings.Trim(tmp, ",")
headerString = headerString + hk + ": " + tmp + "\r\n"
}
// 将框架请求转换为builder框架请求 // 将框架请求转换为builder框架请求
return &builder.Request{ return &builder.Request{
IPString: ctx.ClientIP(), IPString: ctx.ClientIP(),
HeaderString: ctx.GetHeader(""), HeaderString: headerString,
MethodString: ctx.Request.Method, MethodString: ctx.Request.Method,
FullPathString: ctx.FullPath(), FullPathString: ctx.FullPath(),
HostString: ctx.Request.Host, HostString: ctx.Request.Host,

View File

@@ -0,0 +1,262 @@
package zeroadapter
import (
"io/ioutil"
"net/http"
"strings"
"time"
"github.com/quarkcms/quark-go/pkg/builder"
"github.com/quarkcms/quark-go/pkg/msg"
"github.com/zeromicro/go-zero/rest"
"github.com/zeromicro/go-zero/rest/httpx"
)
const JSON_RESPONSE = "json" // json类型响应
const IMAGE_RESPONSE = "image" // 图片类型响应
const EXCEL_RESPONSE = "excel" // Excel文件类型响应
// 将gozero框架的Ctx转换为builder框架Request
func RequestAdapter(r *http.Request, routePath string) (*builder.Request, error) {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
return nil, err
}
headerString := ""
for hk, hvs := range r.Header {
tmp := ""
for _, v := range hvs {
tmp = tmp + "," + v
}
tmp = strings.Trim(tmp, ",")
headerString = headerString + hk + ": " + tmp + "\r\n"
}
// 将框架请求转换为builder框架请求
return &builder.Request{
IPString: r.RemoteAddr,
HeaderString: headerString,
MethodString: r.Method,
FullPathString: routePath,
HostString: r.Host,
PathString: r.URL.Path,
QueryString: r.Response.Request.URL.RawQuery,
BodyBuffer: body,
}, nil
}
// 适配gozero框架响应
func ResponseAdapter(r *builder.Resource, responseType string, w http.ResponseWriter) {
result, err := r.Run()
if err != nil {
httpx.OkJson(w, msg.Error(err.Error(), ""))
return
}
// 响应结果
switch responseType {
case JSON_RESPONSE:
httpx.OkJson(w, result)
return
case IMAGE_RESPONSE:
w.Write(result.([]byte))
return
case EXCEL_RESPONSE:
w.Header().Add("Content-Disposition", "attachment; filename=data_"+time.Now().Format("20060102150405")+".xlsx")
w.Header().Add("Content-Type", "application/octet-stream")
w.Write(result.([]byte))
return
}
}
// 适配gozero框架路由
func RouteAdapter(b *builder.Resource, routePath string, responseType string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
httpx.OkJson(w, msg.Error(err.Error(), ""))
return
}
headerString := ""
for hk, hvs := range r.Header {
tmp := ""
for _, v := range hvs {
tmp = tmp + "," + v
}
tmp = strings.Trim(tmp, ",")
headerString = headerString + hk + ": " + tmp + "\r\n"
}
// 将框架请求转换为builder框架请求
request := &builder.Request{
IPString: r.RemoteAddr,
HeaderString: headerString,
MethodString: r.Method,
FullPathString: routePath,
HostString: r.Host,
PathString: r.URL.Path,
QueryString: r.URL.RawQuery,
BodyBuffer: body,
}
// 转换Request对象
result, err := b.TransformRequest(request).Run()
if err != nil {
httpx.OkJson(w, msg.Error(err.Error(), ""))
return
}
// 响应结果
switch responseType {
case JSON_RESPONSE:
httpx.OkJson(w, result)
return
case IMAGE_RESPONSE:
w.Write(result.([]byte))
return
case EXCEL_RESPONSE:
w.Header().Add("Content-Disposition", "attachment; filename=data_"+time.Now().Format("20060102150405")+".xlsx")
w.Header().Add("Content-Type", "application/octet-stream")
w.Write(result.([]byte))
return
}
}
}
// 适配gozero框架
func Adapter(b *builder.Resource, server *rest.Server) {
server.AddRoutes(
[]rest.Route{
{
Method: http.MethodGet,
Path: "/api/admin/login/:resource/index",
Handler: RouteAdapter(b, "/api/admin/login/:resource/index", JSON_RESPONSE),
},
{
Method: http.MethodPost,
Path: "/api/admin/login/:resource/handle",
Handler: RouteAdapter(b, "/api/admin/login/:resource/handle", JSON_RESPONSE),
},
{
Method: http.MethodGet,
Path: "/api/admin/login/:resource/captchaId",
Handler: RouteAdapter(b, "/api/admin/login/:resource/captchaId", JSON_RESPONSE),
},
{
Method: http.MethodGet,
Path: "/api/admin/login/:resource/captcha/:id",
Handler: RouteAdapter(b, "/api/admin/login/:resource/captcha/:id", IMAGE_RESPONSE),
},
{
Method: http.MethodGet,
Path: "/api/admin/logout/:resource/handle",
Handler: RouteAdapter(b, "/api/admin/logout/:resource/handle", JSON_RESPONSE),
},
{
Method: http.MethodGet,
Path: "/api/admin/dashboard/:resource/index",
Handler: RouteAdapter(b, "/api/admin/dashboard/:resource/index", JSON_RESPONSE),
},
{
Method: http.MethodGet,
Path: "/api/admin/:resource/index",
Handler: RouteAdapter(b, "/api/admin/:resource/index", JSON_RESPONSE),
},
{
Method: http.MethodGet,
Path: "/api/admin/:resource/editable",
Handler: RouteAdapter(b, "/api/admin/:resource/editable", JSON_RESPONSE),
},
{
Method: http.MethodGet,
Path: "/api/admin/:resource/action/:uriKey",
Handler: RouteAdapter(b, "/api/admin/:resource/action/:uriKey", JSON_RESPONSE),
},
{
Method: http.MethodPost,
Path: "/api/admin/:resource/action/:uriKey",
Handler: RouteAdapter(b, "/api/admin/:resource/action/:uriKey", JSON_RESPONSE),
},
{
Method: http.MethodGet,
Path: "/api/admin/:resource/create",
Handler: RouteAdapter(b, "/api/admin/:resource/create", JSON_RESPONSE),
},
{
Method: http.MethodPost,
Path: "/api/admin/:resource/store",
Handler: RouteAdapter(b, "/api/admin/:resource/store", JSON_RESPONSE),
},
{
Method: http.MethodGet,
Path: "/api/admin/:resource/edit",
Handler: RouteAdapter(b, "/api/admin/:resource/edit", JSON_RESPONSE),
},
{
Method: http.MethodGet,
Path: "/api/admin/:resource/edit/values",
Handler: RouteAdapter(b, "/api/admin/:resource/edit/values", JSON_RESPONSE),
},
{
Method: http.MethodPost,
Path: "/api/admin/:resource/save",
Handler: RouteAdapter(b, "/api/admin/:resource/save", JSON_RESPONSE),
},
{
Method: http.MethodGet,
Path: "/api/admin/:resource/detail",
Handler: RouteAdapter(b, "/api/admin/:resource/detail", JSON_RESPONSE),
},
{
Method: http.MethodGet,
Path: "/api/admin/:resource/export",
Handler: RouteAdapter(b, "/api/admin/:resource/export", JSON_RESPONSE),
},
{
Method: http.MethodGet,
Path: "/api/admin/:resource/import",
Handler: RouteAdapter(b, "/api/admin/:resource/import", JSON_RESPONSE),
},
{
Method: http.MethodPost,
Path: "/api/admin/:resource/import",
Handler: RouteAdapter(b, "/api/admin/:resource/import", JSON_RESPONSE),
},
{
Method: http.MethodGet,
Path: "/api/admin/:resource/import/template",
Handler: RouteAdapter(b, "/api/admin/:resource/import/template", EXCEL_RESPONSE),
},
{
Method: http.MethodGet,
Path: "/api/admin/:resource/:uriKey/form",
Handler: RouteAdapter(b, "/api/admin/:resource/:uriKey/form", JSON_RESPONSE),
},
{
Method: http.MethodPost,
Path: "/api/admin/upload/:resource/handle",
Handler: RouteAdapter(b, "/api/admin/upload/:resource/handle", JSON_RESPONSE),
},
{
Method: http.MethodGet,
Path: "/api/admin/upload/:resource/getList",
Handler: RouteAdapter(b, "/api/admin/upload/:resource/getList", JSON_RESPONSE),
},
{
Method: http.MethodPost,
Path: "/api/admin/upload/:resource/delete",
Handler: RouteAdapter(b, "/api/admin/upload/:resource/delete", JSON_RESPONSE),
},
{
Method: http.MethodPost,
Path: "/api/admin/upload/:resource/crop",
Handler: RouteAdapter(b, "/api/admin/upload/:resource/crop", JSON_RESPONSE),
},
},
)
}

View File

@@ -104,8 +104,6 @@ func (p *Admin) Fields(request *builder.Request) []interface{} {
}, },
), ),
field.Editor("abc", "内容"),
field.Text("email", "邮箱"). field.Text("email", "邮箱").
SetRules( SetRules(
[]string{ []string{
@@ -267,7 +265,6 @@ func (p *Admin) AfterSaved(request *builder.Request, model *gorm.DB) interface{}
return msg.Success("操作成功!", strings.Replace("/index?api="+adminresource.IndexRoute, ":resource", request.Param("resource"), -1), "") return msg.Success("操作成功!", strings.Replace("/index?api="+adminresource.IndexRoute, ":resource", request.Param("resource"), -1), "")
} }
var result *gorm.DB
if request.IsCreating() { if request.IsCreating() {
last := map[string]interface{}{} last := map[string]interface{}{}
model.Order("id desc").First(&last) // hack model.Order("id desc").First(&last) // hack
@@ -282,7 +279,10 @@ func (p *Admin) AfterSaved(request *builder.Request, model *gorm.DB) interface{}
} }
if len(roleData) > 0 { if len(roleData) > 0 {
// 同步角色 // 同步角色
result = db.Client.Model(&models.ModelHasRole{}).Create(roleData) err := db.Client.Model(&models.ModelHasRole{}).Create(roleData).Error
if err != nil {
return msg.Error(err.Error(), "")
}
} }
} else { } else {
@@ -302,13 +302,12 @@ func (p *Admin) AfterSaved(request *builder.Request, model *gorm.DB) interface{}
} }
if len(roleData) > 0 { if len(roleData) > 0 {
// 同步角色 // 同步角色
result = db.Client.Model(&models.ModelHasRole{}).Create(roleData) err := db.Client.Model(&models.ModelHasRole{}).Create(roleData).Error
if err != nil {
return msg.Error(err.Error(), "")
}
} }
} }
if result.Error != nil {
return msg.Error(result.Error.Error(), "")
}
return msg.Success("操作成功!", strings.Replace("/index?api="+adminresource.IndexRoute, ":resource", request.Param("resource"), -1), "") return msg.Success("操作成功!", strings.Replace("/index?api="+adminresource.IndexRoute, ":resource", request.Param("resource"), -1), "")
} }

View File

@@ -34,7 +34,7 @@ func (p *WebConfig) Init() interface{} {
// 表单接口 // 表单接口
func (p *WebConfig) FormApi(request *builder.Request) string { func (p *WebConfig) FormApi(request *builder.Request) string {
return "admin/webConfig/action/change-web-config" return "/api/admin/webConfig/action/change-web-config"
} }
// 字段 // 字段