This commit is contained in:
Max 2021-10-01 14:50:48 +08:00
parent 274c22d2db
commit 91ca7476a1
19 changed files with 277 additions and 52 deletions

5
app/app.json Normal file
View file

@ -0,0 +1,5 @@
{
"name": "象传应用",
"short": "象传",
"description": "象传应用后台"
}

BIN
app/xiang/icons/icon.icns Normal file

Binary file not shown.

BIN
app/xiang/icons/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
app/xiang/icons/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View file

@ -16,7 +16,7 @@ var startCmd = &cobra.Command{
Long: `启动象传应用引擎`,
Run: func(cmd *cobra.Command, args []string) {
defer global.ServiceStop(func() { log.Println("服务已关闭") })
log.Printf("启动象传应用引擎 mode=%s", global.Conf.Mode)
log.Printf("启动象传应用引擎 v%s mode=%s", global.VERSION, global.Conf.Mode)
// 应用目录
if startAppPath != "" {

View file

@ -30,6 +30,7 @@ type XiangConfig struct {
Source string `json:"source,omitempty" env:"XIANG_SOURCE" envDefault:"fs://."` // 源码路径(用于单元测试载入数据)
Path string `json:"path,omitempty" env:"XIANG_PATH" envDefault:"bin://xiang"` // 引擎文件目录
Root string `json:"root,omitempty" env:"XIANG_ROOT" envDefault:"fs://."` // 应用文件目录
RootData string `json:"root_data,omitempty" env:"XIANG_ROOT_DATA"` // 应用数据文件目录
RootAPI string `json:"root_api,omitempty" env:"XIANG_ROOT_API"` // 应用API文件目录
RootModel string `json:"root_model,omitempty" env:"XIANG_ROOT_MODEL"` // 应用模型文件目录
RootFLow string `json:"root_flow,omitempty" env:"XIANG_ROOT_FLOW"` // 应用工作流文件目录
@ -134,6 +135,10 @@ func (cfg *Config) SetDefaults() {
if cfg.RootScreen == "" {
cfg.RootScreen = cfg.Root + "/screens"
}
if cfg.RootData == "" {
cfg.RootData = cfg.Root + "/data"
}
}
// IsDebug 是否为调试模式

File diff suppressed because one or more lines are too long

View file

@ -8,11 +8,13 @@ import (
"path/filepath"
"strings"
jsoniter "github.com/json-iterator/go"
"github.com/yaoapp/gou"
"github.com/yaoapp/kun/exception"
"github.com/yaoapp/xiang/config"
"github.com/yaoapp/xiang/data"
"github.com/yaoapp/xiang/table"
"github.com/yaoapp/xiang/xfs"
)
// Script 脚本文件类型
@ -32,10 +34,24 @@ type AppRoot struct {
Tables string
Charts string
Screens string
Data string
}
// AppInfo 应用信息
type AppInfo struct {
Name string `json:"name,omitempty"`
Short string `json:"short,omitempty"`
Version string `json:"version,omitempty"`
Description string `json:"description,omitempty"`
Icons map[string]string `json:"icons,omitempty"`
}
// App 应用信息
var App AppInfo
// Load 根据配置加载 API, FLow, Model, Plugin
func Load(cfg config.Config) {
LoadAppInfo(cfg.Root)
LoadEngine(cfg.Path)
LoadApp(AppRoot{
APIs: cfg.RootAPI,
@ -45,6 +61,7 @@ func Load(cfg config.Config) {
Tables: cfg.RootTable,
Charts: cfg.RootChart,
Screens: cfg.RootScreen,
Data: cfg.RootData,
})
}
@ -57,6 +74,47 @@ func Reload(cfg config.Config) {
Load(cfg)
}
// LoadAppInfo 读取应用信息
func LoadAppInfo(root string) {
info := defaultAppInfo()
fs := xfs.New(root)
if fs.MustExists("/app.json") {
err := jsoniter.Unmarshal(fs.MustReadFile("/app.json"), &info)
if err != nil {
exception.New("解析应用失败 %s", 500, err).Throw()
}
}
if fs.MustExists("/xiang/icons/icon.icns") {
info.Icons["icns"] = xfs.Encode(fs.MustReadFile("/xiang/icons/icon.icns"))
}
if fs.MustExists("/xiang/icons/icon.ico") {
info.Icons["ico"] = xfs.Encode(fs.MustReadFile("/xiang/icons/icon.ico"))
}
if fs.MustExists("/xiang/icons/icon.png") {
info.Icons["png"] = xfs.Encode(fs.MustReadFile("/xiang/icons/icon.png"))
}
App = info
}
// defaultAppInfo 读取默认应用信息
func defaultAppInfo() AppInfo {
info := AppInfo{}
err := jsoniter.Unmarshal(data.MustAsset("xiang/data/app.json"), &info)
if err != nil {
exception.New("解析默认应用失败 %s", 500, err).Throw()
}
info.Version = VERSION
info.Icons["icns"] = xfs.Encode(data.MustAsset("xiang/data/icons/icon.icns"))
info.Icons["ico"] = xfs.Encode(data.MustAsset("xiang/data/icons/icon.ico"))
info.Icons["png"] = xfs.Encode(data.MustAsset("xiang/data/icons/icon.png"))
return info
}
// LoadEngine 加载引擎的 API, Flow, Model 配置
func LoadEngine(from string) {
@ -107,7 +165,7 @@ func LoadApp(app AppRoot) {
// api string, flow string, model string, plugin string
// 创建应用目录
paths := []string{app.APIs, app.Flows, app.Models, app.Plugins, app.Charts, app.Screens}
paths := []string{app.APIs, app.Flows, app.Models, app.Plugins, app.Charts, app.Screens, app.Data}
for _, p := range paths {
if !strings.HasPrefix(p, "fs://") && strings.Contains(p, "://") {
continue

View file

@ -2,11 +2,15 @@ package global
import (
"github.com/yaoapp/gou"
"github.com/yaoapp/xiang/xfs"
)
func init() {
// 注册处理器
gou.RegisterProcessHandler("xiang.global.ping", processPing)
gou.RegisterProcessHandler("xiang.global.Ping", processPing)
gou.RegisterProcessHandler("xiang.global.FileContent", processFileContent)
gou.RegisterProcessHandler("xiang.global.AppFileContent", processAppFileContent)
gou.RegisterProcessHandler("xiang.global.Inspect", processInspect)
}
// processCreate 运行模型 MustCreate
@ -21,7 +25,32 @@ func processPing(process *gou.Process) interface{} {
return res
}
// processFile 返回文件内容
func processFile(process *gou.Process) interface{} {
return nil
// processCreate 运行模型 MustCreate
func processInspect(process *gou.Process) interface{} {
return App
}
// processFileContent 返回文件内容
func processFileContent(process *gou.Process) interface{} {
process.ValidateArgNums(2)
filename := process.ArgsString(0)
encode := process.ArgsBool(1, true)
content := xfs.Stor.MustReadFile(filename)
if encode {
return xfs.Encode(content)
}
return string(content)
}
// processAppFileContent 返回应用文件内容
func processAppFileContent(process *gou.Process) interface{} {
process.ValidateArgNums(2)
fs := xfs.New(Conf.RootData)
filename := process.ArgsString(0)
encode := process.ArgsBool(1, true)
content := fs.MustReadFile(filename)
if encode {
return xfs.Encode(content)
}
return string(content)
}

View file

@ -12,7 +12,7 @@ import (
)
// VERSION 版本号
const VERSION = "0.6.4"
const VERSION = "0.6.5"
// DOMAIN 许可域
const DOMAIN = "*.iqka.com"

10
go.mod
View file

@ -17,7 +17,7 @@ require (
github.com/joho/godotenv v1.3.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/lib/pq v1.10.3 // indirect
github.com/mattn/go-colorable v0.1.10 // indirect
github.com/mattn/go-colorable v0.1.11 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mattn/go-sqlite3 v1.14.8 // indirect
github.com/mojocn/base64Captcha v1.3.5 // indirect
@ -25,14 +25,14 @@ require (
github.com/spf13/afero v1.6.0 // indirect
github.com/spf13/cobra v1.2.1 // indirect
github.com/stretchr/testify v1.7.0
github.com/yaoapp/gou v0.0.0-20210929143406-112eed6cdfd9 // indirect
github.com/yaoapp/gou v0.0.0-20211001062655-04dd63da82aa // indirect
github.com/yaoapp/kun v0.6.5
github.com/yaoapp/xun v0.5.2 // indirect
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d // indirect
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b // indirect
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 // indirect
google.golang.org/genproto v0.0.0-20210928142010-c7af6a1a74c9 // indirect
golang.org/x/net v0.0.0-20210929193557-e81a3d93ecf6 // indirect
golang.org/x/sys v0.0.0-20210930212924-f542c8878de8 // indirect
google.golang.org/genproto v0.0.0-20210930144712-2e2e1008e8a3 // indirect
google.golang.org/grpc v1.41.0 // indirect
)

10
go.sum
View file

@ -264,6 +264,8 @@ github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.10 h1:KWqbp83oZ6YOEgIbNW3BM1Jbe2tz4jgmWA9FOuAF8bw=
github.com/mattn/go-colorable v0.1.10/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs=
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
@ -378,6 +380,8 @@ github.com/yaoapp/gou v0.0.0-20210929134711-2a520a964087 h1:h4EUeoFAS/eRyonMBzS4
github.com/yaoapp/gou v0.0.0-20210929134711-2a520a964087/go.mod h1:vcNZXFRgGuZWzjtYH65ck1o6nzWYDpToQ09zHC9xNDE=
github.com/yaoapp/gou v0.0.0-20210929143406-112eed6cdfd9 h1:rsZXATrMRQzlEraTB7JorT7i29J5RBkK1zGFd6Fw/No=
github.com/yaoapp/gou v0.0.0-20210929143406-112eed6cdfd9/go.mod h1:vcNZXFRgGuZWzjtYH65ck1o6nzWYDpToQ09zHC9xNDE=
github.com/yaoapp/gou v0.0.0-20211001062655-04dd63da82aa h1:+FCfvC/JPDSpxLQ5rcNi5fClITeYO2p736rSLxKKhqQ=
github.com/yaoapp/gou v0.0.0-20211001062655-04dd63da82aa/go.mod h1:vcNZXFRgGuZWzjtYH65ck1o6nzWYDpToQ09zHC9xNDE=
github.com/yaoapp/kun v0.6.1 h1:gbjP5wmAuJLe1RGZ2evH4rPCVWykf0iqbksaHikF/GI=
github.com/yaoapp/kun v0.6.1/go.mod h1:igsTcWDnzpp0HtRN7sBP+XOEN2tzoC5hk2MyoPFs3xA=
github.com/yaoapp/kun v0.6.2 h1:QbtdZpVIklRDGEvL5YYRf/eR05YFZVFk/8rX2vy2K0Q=
@ -505,6 +509,8 @@ golang.org/x/net v0.0.0-20210927181540-4e4d966f7476 h1:s5hu7bTnLKswvidgtqc4GwsW8
golang.org/x/net v0.0.0-20210927181540-4e4d966f7476/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b h1:eB48h3HiRycXNy8E0Gf5e0hv7YT6Kt14L/D73G1fuwo=
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210929193557-e81a3d93ecf6 h1:Z04ewVs7JhXaYkmDhBERPi41gnltfQpMWDnTnQbaCqk=
golang.org/x/net v0.0.0-20210929193557-e81a3d93ecf6/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -586,6 +592,8 @@ golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0 h1:xrCZDmdtoloIiooiA9q0OQb9r
golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 h1:foEbQz/B0Oz6YIqu/69kfXPYeFQAuuMYFkjaqXzl5Wo=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210930212924-f542c8878de8 h1:g54bVHzt/eKaj59LDwiDyLRXbOdJSfwRxA1WYEJx/Yo=
golang.org/x/sys v0.0.0-20210930212924-f542c8878de8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -735,6 +743,8 @@ google.golang.org/genproto v0.0.0-20210927142257-433400c27d05 h1:6/1QShroBaS9sY9
google.golang.org/genproto v0.0.0-20210927142257-433400c27d05/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20210928142010-c7af6a1a74c9 h1:XTH066D35LyHehRwlYhoK3qA+Hcgvg5xREG4kFQEW1Y=
google.golang.org/genproto v0.0.0-20210928142010-c7af6a1a74c9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20210930144712-2e2e1008e8a3 h1:+F3FcO6LTrzNq5wp1Z6JtoBvnJzX6euyN70FoyMDXy4=
google.golang.org/genproto v0.0.0-20210930144712-2e2e1008e8a3/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=

View file

@ -3,6 +3,7 @@ package main
import (
"github.com/yaoapp/xiang/cmd"
_ "github.com/yaoapp/xiang/user"
_ "github.com/yaoapp/xiang/xfs"
)
// 主程序

View file

@ -4,6 +4,7 @@ import (
"archive/tar"
"archive/zip"
"bytes"
"encoding/base64"
"fmt"
"io"
"io/fs"
@ -15,8 +16,12 @@ import (
"github.com/spf13/afero/tarfs"
"github.com/spf13/afero/zipfs"
"github.com/yaoapp/kun/exception"
"github.com/yaoapp/xiang/config"
)
// Stor 文件系统实例
var Stor Xfs
// Xfs 文件系统
type Xfs struct {
Root string // Root
@ -33,6 +38,10 @@ type File interface {
afero.File
}
func init() {
Stor = New(config.Conf.Storage.Path)
}
// New 创建文件系统
func New(path string) Xfs {
pinfo := strings.Split(path, "://")
@ -91,6 +100,11 @@ func NewTar(tarfile string) Xfs {
}
}
// Encode Base64编码
func Encode(content []byte) string {
return base64.StdEncoding.EncodeToString(content)
}
// MustOpen 打开文件
func (xfs *Xfs) MustOpen(filename string) File {
file, err := xfs.Open(filename)
@ -104,7 +118,7 @@ func (xfs *Xfs) MustOpen(filename string) File {
func (xfs *Xfs) MustReadFile(filename string) []byte {
bytes, err := xfs.ReadFile(filename)
if err != nil {
exception.New("阅读文件内容失败 %s 失败 ", 500, filename).Throw()
exception.New("阅读文件内容失败 %s 失败 %s ", 500, filename, err).Throw()
}
return bytes
}

View file

@ -17,10 +17,10 @@
}
},
{
"path": "/info",
"path": "/inspect",
"method": "GET",
"guard": "-",
"process": "xiang.global.Info",
"process": "xiang.global.inspect",
"in": [],
"out": {
"status": 200,

7
xiang/data/app.json Normal file
View file

@ -0,0 +1,7 @@
{
"name": "象传应用引擎",
"short": "象传",
"version": "0.6.5",
"description": "象传应用引擎管理后台",
"icons": {}
}

BIN
xiang/data/icons/icon.icns Normal file

Binary file not shown.

BIN
xiang/data/icons/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
xiang/data/icons/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB