diff --git a/app/apis/user.http.json b/app/apis/user.http.json index c8dade36..c43f1fe9 100644 --- a/app/apis/user.http.json +++ b/app/apis/user.http.json @@ -16,6 +16,17 @@ "type": "application/json" } }, + { + "path": "/find/:id", + "method": "GET", + "guard": "-", + "process": "models.user.Find", + "in": ["$param.id", ":params"], + "out": { + "status": 200, + "type": "application/json" + } + }, { "path": "/info/:id", "method": "GET", diff --git a/global/config.go b/global/config.go index 278c7584..30890262 100644 --- a/global/config.go +++ b/global/config.go @@ -24,7 +24,7 @@ type Config struct { // XiangConfig 象传应用引擎配置 type XiangConfig struct { Mode string `json:"mode,omitempty" env:"XIANG_MODE" envDefault:"release"` // 象传引擎模式 debug/release/test - Source string `json:"source,omitempty" env:"XIANG_SOURCE" envDefault:"fs://."` // 源码路径(用于调试时载入数据) + 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://."` // 应用文件目录 RootAPI string `json:"root_api,omitempty" env:"XIANG_ROOT_API"` // 应用API文件目录 diff --git a/global/watch.go b/global/watch.go new file mode 100644 index 00000000..e6aa7009 --- /dev/null +++ b/global/watch.go @@ -0,0 +1,102 @@ +package global + +import ( + "log" + "os" + "path/filepath" + + "github.com/fsnotify/fsnotify" + "github.com/yaoapp/kun/exception" +) + +var watchDone = []chan bool{} +var watchOp = map[fsnotify.Op]string{ + fsnotify.Create: "create", + fsnotify.Write: "write", + fsnotify.Remove: "remove", + fsnotify.Rename: "rename", + fsnotify.Chmod: "chmod", +} + +// Watch 监听目录 +func Watch(root string, cb func(op string, file string)) { + watcher, err := fsnotify.NewWatcher() + if err != nil { + log.Fatal(err) + } + defer watcher.Close() + + watchDone = append(watchDone, make(chan bool)) + last := len(watchDone) - 1 + go func() { + for { + select { + case event, ok := <-watcher.Events: + if !ok { + return + } + + // 监听子目录 + if event.Op == fsnotify.Create { + file, err := os.Open(event.Name) + if err == nil { + fi, err := file.Stat() + file.Close() + if err == nil && fi.IsDir() { + Watch(event.Name, cb) + } + } + } + + cb(watchOp[event.Op], event.Name) + + case err, ok := <-watcher.Errors: + if !ok { + return + } + log.Println("error:", err) + } + } + }() + + err = watcher.Add(root) + if err != nil { + log.Fatal(err) + } + + log.Println("开始监听目录:", root) + + // 监听子目录 + filepath.Walk(root, func(subfolder string, info os.FileInfo, err error) error { + if err != nil { + exception.Err(err, 500).Throw() + return err + } + + if subfolder == root { + return nil + } + + if info.IsDir() { + go Watch(subfolder, cb) + } + return nil + }) + + select { + case v := <-watchDone[last]: + log.Println("停止监听目录:", root) + if v == true { + break + } + } +} + +// StopWatch 停止监听 +func StopWatch() { + for i := range watchDone { + log.Println("发送停止信号:", i) + watchDone[i] <- true + } + watchDone = []chan bool{} +} diff --git a/global/watch_test.go b/global/watch_test.go new file mode 100644 index 00000000..9d3e3fa8 --- /dev/null +++ b/global/watch_test.go @@ -0,0 +1,21 @@ +package global + +import ( + "log" + "path" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestWatchAddNew(t *testing.T) { + root := path.Join(Conf.Source, "/app") + assert.NotPanics(t, func() { + go Watch(root, func(op string, file string) { + log.Println(op, file) + }) + time.Sleep(time.Second * 2) + defer StopWatch() + }) +} diff --git a/go.mod b/go.mod index 68d072a2..e416bac8 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/caarlos0/env/v6 v6.7.1 // indirect github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect github.com/elazarl/go-bindata-assetfs v1.0.1 // indirect + github.com/fsnotify/fsnotify v1.5.1 // indirect github.com/gin-gonic/gin v1.7.4 // indirect github.com/joho/godotenv v1.3.0 // indirect github.com/json-iterator/go v1.1.12 // indirect diff --git a/go.sum b/go.sum index 171e84ff..2a739565 100644 --- a/go.sum +++ b/go.sum @@ -86,6 +86,8 @@ github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGE github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc= github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= +github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= diff --git a/main_test.go b/main_test.go index a76a59e8..0796bb5a 100644 --- a/main_test.go +++ b/main_test.go @@ -46,7 +46,7 @@ func TestCommandStart(t *testing.T) { // 发送请求 request := func() (maps.MapStr, error) { time.Sleep(time.Microsecond * 1000) - url := fmt.Sprintf("http://%s:%d/api/user/info/1?select=id,name", "local.iqka.com", global.Conf.Service.Port) + url := fmt.Sprintf("http://%s:%d/api/user/find/1?select=id,name", "local.iqka.com", global.Conf.Service.Port) // utils.Dump(url) resp, err := http.Get(url) if err != nil { diff --git a/xiang/apis/sys.http.json b/xiang/apis/sys.http.json index a5f9ea3d..48074be8 100644 --- a/xiang/apis/sys.http.json +++ b/xiang/apis/sys.http.json @@ -8,6 +8,17 @@ { "path": "/info/:id", "method": "GET", + "guard": "-", + "process": "models.user.Find", + "in": ["$param.id", ":params"], + "out": { + "status": 200, + "type": "application/json" + } + }, + { + "path": "/find/:id", + "method": "GET", "process": "models.user.Find", "in": ["$param.id", ":params"], "out": {