v0.6.5
This commit is contained in:
parent
274c22d2db
commit
91ca7476a1
19 changed files with 277 additions and 52 deletions
5
app/app.json
Normal file
5
app/app.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"name": "象传应用",
|
||||
"short": "象传",
|
||||
"description": "象传应用后台"
|
||||
}
|
||||
BIN
app/xiang/icons/icon.icns
Normal file
BIN
app/xiang/icons/icon.icns
Normal file
Binary file not shown.
BIN
app/xiang/icons/icon.ico
Normal file
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
BIN
app/xiang/icons/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
|
|
@ -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 != "" {
|
||||
|
|
|
|||
|
|
@ -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 是否为调试模式
|
||||
|
|
|
|||
170
data/bindata.go
170
data/bindata.go
File diff suppressed because one or more lines are too long
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import (
|
|||
)
|
||||
|
||||
// VERSION 版本号
|
||||
const VERSION = "0.6.4"
|
||||
const VERSION = "0.6.5"
|
||||
|
||||
// DOMAIN 许可域
|
||||
const DOMAIN = "*.iqka.com"
|
||||
|
|
|
|||
10
go.mod
10
go.mod
|
|
@ -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
10
go.sum
|
|
@ -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=
|
||||
|
|
|
|||
1
main.go
1
main.go
|
|
@ -3,6 +3,7 @@ package main
|
|||
import (
|
||||
"github.com/yaoapp/xiang/cmd"
|
||||
_ "github.com/yaoapp/xiang/user"
|
||||
_ "github.com/yaoapp/xiang/xfs"
|
||||
)
|
||||
|
||||
// 主程序
|
||||
|
|
|
|||
16
xfs/xfs.go
16
xfs/xfs.go
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
7
xiang/data/app.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "象传应用引擎",
|
||||
"short": "象传",
|
||||
"version": "0.6.5",
|
||||
"description": "象传应用引擎管理后台",
|
||||
"icons": {}
|
||||
}
|
||||
BIN
xiang/data/icons/icon.icns
Normal file
BIN
xiang/data/icons/icon.icns
Normal file
Binary file not shown.
BIN
xiang/data/icons/icon.ico
Normal file
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
BIN
xiang/data/icons/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
Loading…
Add table
Reference in a new issue