Initial commit

This commit is contained in:
yan.y
2024-03-27 23:25:08 +08:00
commit 0884384e91
127 changed files with 9353 additions and 0 deletions
@@ -0,0 +1,11 @@
{
"config": "charset=utf8mb4\u0026parseTime=True\u0026loc=Local",
"db-name": "iris-admin",
"log-mode": false,
"log-zap": "error",
"max-idle-conns": 0,
"max-open-conns": 0,
"password": "",
"path": "127.0.0.1:3306",
"username": "root"
}
+36
View File
@@ -0,0 +1,36 @@
{
"captcha": {
"img-height": 80,
"img-width": 240,
"key-long": 4
},
"cors": {
"access-credentials": "true",
"access-expose-headers": "Content-Length,Access-Control-Allow-Origin,Access-Control-Allow-Headers,Content-Type",
"access-headers": "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token,X-Token,X-U-Id",
"access-methods": "POST,GET",
"access-origin": "*"
},
"except": {
"method": "",
"uri": ""
},
"file-max-size": 1024,
"limit": {
"burst": 5,
"disable": true,
"limit": 0
},
"menu": {
"method": "",
"uri": ""
},
"session-timeout": 60,
"system": {
"addr": "127.0.0.1:8085",
"db-type": "mysql",
"level": "debug",
"time-format": "2006-01-02 15:04:05",
"tls": false
}
}
+11
View File
@@ -0,0 +1,11 @@
{
"director": "logs",
"encode-level": "LowercaseColorLevelEncoder",
"format": "console",
"level": "debug",
"link-name": "latest_log",
"log-in-console": false,
"prefix": "[IRIS-ADMIN]",
"show-line": true,
"stacktrace-key": "stacktrace"
}
+123
View File
@@ -0,0 +1,123 @@
package web_iris
import (
stdContext "context"
"errors"
"github.com/go-playground/validator/v10"
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/context"
"strings"
"time"
"github.com/kataras/iris/v12/middleware/recover"
"pet-house.com/core/helper/arr"
"pet-house.com/core/helper/str"
"pet-house.com/core/server/web"
"pet-house.com/core/server/web/web_iris/middleware"
)
var ErrAuthDriverEmpty = errors.New("auth driver initialize fail")
// WebServer
// - app iris application
// - idleConnsClosed
// - addr
// - timeFormat
// - staticPrefix
type WebServer struct {
app *iris.Application
idleConnsClosed chan struct{}
parties []Party
addr string
timeFormat string
}
// Party
// - perfix
// - partyFunc
type Party struct {
Perfix string
PartyFunc func(index iris.Party)
}
func Init() *WebServer {
app := iris.New()
if web.CONFIG.System.Tls {
app.Use(middleware.LoadTls())
}
app.Use(recover.New())
app.Validator = validator.New()
app.Logger().SetLevel(web.CONFIG.System.Level)
idleConnsClosed := make(chan struct{})
iris.RegisterOnInterrupt(func() {
timeout := 10 * time.Second
ctx, cancel := stdContext.WithTimeout(stdContext.Background(), timeout)
defer cancel()
app.Shutdown(ctx) // close all hosts
close(idleConnsClosed)
})
// 自定义应用程序配置
_ = iris.Configuration{
DisablePathCorrection: true,
DisableBodyConsumptionOnUnmarshal: true,
Charset: "UTF-8",
}
app.Configure(iris.WithCharset("UTF-8"), iris.WithOptimizations)
web.SetDefaultAddrAndTimeFormat()
return &WebServer{
app: app,
addr: web.CONFIG.System.Addr,
timeFormat: web.CONFIG.System.TimeFormat,
idleConnsClosed: idleConnsClosed,
}
}
func (ws *WebServer) GetEngine() *iris.Application {
return ws.app
}
func (ws *WebServer) AddModule(parties ...Party) {
ws.parties = append(ws.parties, parties...)
}
func (ws *WebServer) AddFrontFunc(f func(ctx *context.Context)) {
ws.app.Use(f)
}
func (ws *WebServer) AddWebStatic(staticAbsPath, webPrefix string, paths ...string) {
webPrefixs := strings.Split(web.CONFIG.System.WebPrefix, ",")
wp := arr.NewCheckArrayType(2)
for _, webPrefix := range webPrefixs {
wp.Add(webPrefix)
}
if wp.Check(webPrefix) {
return
}
fsOrDir := iris.Dir(staticAbsPath)
opt := iris.DirOptions{
IndexName: "index.html",
SPA: true,
}
ws.app.HandleDir(webPrefix, fsOrDir, opt)
web.CONFIG.System.WebPrefix = str.Join(web.CONFIG.System.WebPrefix, ",", webPrefix)
}
func (ws *WebServer) AddUploadStatic(webPrefix, staticAbsPath string) {
fsOrDir := iris.Dir(staticAbsPath)
ws.app.HandleDir(webPrefix, fsOrDir)
web.CONFIG.System.StaticPrefix = webPrefix
}
func (ws *WebServer) Run() {
ws.app.Listen(
ws.addr,
iris.WithoutInterruptHandler,
iris.WithoutServerError(iris.ErrServerClosed),
iris.WithOptimizations,
iris.WithTimeFormat(ws.timeFormat),
)
<-ws.idleConnsClosed
}
+39
View File
@@ -0,0 +1,39 @@
package web_iris
import (
"io/ioutil"
"net/http"
"testing"
"time"
"pet-house.com/core/server/database"
"pet-house.com/core/server/web"
"pet-house.com/core/server/zap_server"
)
func TestRun(t *testing.T) {
defer zap_server.Remove()
defer web.Remove()
defer database.Remove()
web.CONFIG.System.Addr = "127.0.0.1:18085"
go func() {
web.Start(Init())
}()
time.Sleep(3 * time.Second)
t.Run("test web run", func(t *testing.T) {
resp, err := http.Get("http://127.0.0.1:18085/v0/version")
if err != nil {
t.Errorf("test web start get %v", err)
}
defer resp.Body.Close()
s, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Errorf("test web start get %v", err)
}
if string(s) != "IRIS-ADMIN is running!!!" {
t.Errorf("test web start want %s but get %s", "Not Found", string(s))
}
})
}
@@ -0,0 +1,17 @@
package middleware
import (
"github.com/iris-contrib/middleware/cors"
"github.com/kataras/iris/v12/context"
)
// CrsAuth
func CrsAuth() context.Handler {
return cors.New(cors.Options{
AllowedOrigins: []string{"*"}, // allows everything, use that to change the hosts.
AllowedMethods: []string{"POST", "GET"},
AllowedHeaders: []string{"*"},
ExposedHeaders: []string{"Accept", "Content-Type", "Content-Length", "Accept-Encoding", "X-CSRF-Token", "Authorization"},
AllowCredentials: true,
})
}
@@ -0,0 +1,15 @@
package middleware
import (
"github.com/iris-contrib/middleware/secure"
"github.com/kataras/iris/v12"
)
// LoadTls
func LoadTls() iris.Handler {
middleware := secure.New(secure.Options{
SSLRedirect: true,
SSLHost: "127.0.0.1:443",
})
return middleware.Handler
}
+102
View File
@@ -0,0 +1,102 @@
package web_iris
import (
"github.com/kataras/iris/v12"
"net/http"
"strings"
"time"
"github.com/kataras/iris/v12/middleware/pprof"
"github.com/kataras/iris/v12/middleware/rate"
"github.com/kataras/iris/v12/middleware/recover"
"pet-house.com/core/helper/arr"
"pet-house.com/core/server/web"
"pet-house.com/core/server/web/web_iris/middleware"
)
// InitRouter
func (ws *WebServer) InitRouter() error {
app := ws.app.Party("/").AllowMethods(iris.MethodOptions)
{
app.Get("/v0/version", func(ctx iris.Context) {
ctx.WriteString("IRIS-ADMIN is running!!!")
})
app.UseRouter(middleware.CrsAuth())
app.UseRouter(recover.New())
if !web.CONFIG.Limit.Disable {
limitV1 := rate.Limit(web.CONFIG.Limit.Limit, web.CONFIG.Limit.Burst, rate.PurgeEvery(time.Minute, 5*time.Minute))
app.Use(limitV1)
}
if web.CONFIG.System.Level == "debug" {
debug := func(index iris.Party) {
index.Get("/", func(ctx iris.Context) {
ctx.HTML("<h1>请点击<a href='/debug/pprof'>这里</a>打开调试页面")
})
index.Any("/pprof", pprof.New())
index.Any("/pprof/{action:path}", pprof.New())
}
app.PartyFunc("/debug", debug)
}
for _, party := range ws.parties {
app.PartyFunc(party.Perfix, party.PartyFunc)
}
}
// http test must build
if err := ws.app.Build(); err != nil {
return err
}
return nil
}
// GetSources
// - PermRoutes
// - NoPermRoutes
func (ws *WebServer) GetSources() ([]map[string]string, []map[string]string) {
methodExcepts := strings.Split(web.CONFIG.Except.Method, ";")
uris := strings.Split(web.CONFIG.Except.Uri, ";")
methodMenus := strings.Split(web.CONFIG.Menu.Method, ";")
uriMenus := strings.Split(web.CONFIG.Menu.Uri, ";")
routeLen := len(ws.app.GetRoutes())
permRoutes := make([]map[string]string, 0, routeLen)
noPermRoutes := make([]map[string]string, 0, routeLen)
for _, r := range ws.app.GetRoutes() {
route := map[string]string{
"path": r.Path,
"name": r.Name,
"act": r.Method,
}
if len(methodMenus) > 0 && len(uriMenus) > 0 && len(methodMenus) == len(uriMenus) {
for i := 0; i < len(methodMenus); i++ {
if strings.EqualFold(r.Method, strings.ToLower(methodMenus[i])) && strings.EqualFold(r.Path, strings.ToLower(uriMenus[i])) {
route["is_menu"] = "1"
}
}
}
httpStatusType := arr.NewCheckArrayType(4)
httpStatusType.AddMutil(http.MethodGet, http.MethodPost)
if !httpStatusType.Check(r.Method) {
noPermRoutes = append(noPermRoutes, route)
continue
}
if len(methodExcepts) > 0 && len(uris) > 0 && len(methodExcepts) == len(uris) {
for i := 0; i < len(methodExcepts); i++ {
if strings.EqualFold(r.Method, strings.ToLower(methodExcepts[i])) && strings.EqualFold(r.Path, strings.ToLower(uris[i])) {
noPermRoutes = append(noPermRoutes, route)
continue
}
}
}
permRoutes = append(permRoutes, route)
}
return permRoutes, noPermRoutes
}
@@ -0,0 +1,23 @@
package validate
import (
"fmt"
"github.com/go-playground/validator/v10"
)
// ValidRequest
func ValidRequest(err interface{}) []string {
var errs []string
if err == nil {
return errs
}
if validateErrs, ok := err.(validator.ValidationErrors); ok {
for _, e := range validateErrs {
e := e
sErr := fmt.Errorf("%s param error: %v", e.Namespace(), e.Value())
errs = append(errs, sErr.Error())
}
}
return errs
}