Sfoglia il codice sorgente

feat:移除redis缓存,定时获取文件变更时间去更新excel

Roc 1 anno fa
parent
commit
f48d4d6423

+ 41 - 44
cache/index_cache.go

@@ -1,54 +1,51 @@
 package cache
 
 import (
-	"fmt"
-	"hongze/hongtao3_watch/global"
-	"hongze/hongtao3_watch/utils"
+	"container/list"
+	"sync"
 )
 
-// record more information
-func IndexAutoRefresh(filePath string) bool {
-	if global.Re == nil {
-		if global.Rc != nil {
-			if global.Rc.SetNX(filePath, filePath, utils.GetTodayLastSecond()) {
-				err := global.Rc.LPush(utils.REFRESH_INDEX, filePath)
-				if err != nil {
-					fmt.Println("RecordNewLogs LPush Err:" + err.Error())
-				}
-				return true
-			}
-		}
-		return true
-	}
-	return false
-}
+//// AddIndexRefreshExcel 添加刷新excel队列
+//func AddIndexRefreshExcel(filePath string) bool {
+//	if global.Re == nil {
+//		if global.Rc != nil {
+//			err := global.Rc.LPush(utils.REFRESH_HONGTAO_EXCEL, filePath)
+//			if err != nil {
+//				fmt.Println("Add Index Reresh Excel LPush Err:" + err.Error())
+//			}
+//			return true
+//		}
+//		return true
+//	}
+//	return false
+//}
 
-// AddIndexHandleExcel 添加处理excel变更队列
-func AddIndexHandleExcel(filePath string) bool {
-	if global.Re == nil {
-		if global.Rc != nil {
-			err := global.Rc.LPush(utils.HANDLE_HONGTAO_EXCEL, filePath)
-			if err != nil {
-				fmt.Println("Add Index Handle Excel LPush Err:" + err.Error())
-			}
-			return true
-		}
-		return true
-	}
-	return false
+// RefreshList 刷新的列表
+var RefreshList *list.List
+
+func init() {
+	RefreshList = list.New()
 }
 
-// AddIndexRefreshExcel 添加刷新excel队列
-func AddIndexRefreshExcel(filePath string) bool {
-	if global.Re == nil {
-		if global.Rc != nil {
-			err := global.Rc.LPush(utils.REFRESH_HONGTAO_EXCEL, filePath)
-			if err != nil {
-				fmt.Println("Add Index Reresh Excel LPush Err:" + err.Error())
-			}
-			return true
-		}
-		return true
+var FilePathMap = make(map[string]int)
+
+// FilePathMutex 创建一个互斥锁
+var FilePathMutex sync.Mutex
+
+// AddIndexRefreshExcel
+// @Description: 添加刷新excel队列
+// @author: Roc
+// @datetime2023-10-31 09:40:30
+// @param filePath string
+func AddIndexRefreshExcel(filePath string) {
+	FilePathMutex.Lock()
+	defer FilePathMutex.Unlock()
+	// 如果存在该路径,那么就不记录入list
+	if _, ok := FilePathMap[filePath]; ok {
+		return
 	}
-	return false
+	RefreshList.PushBack(filePath)
+	FilePathMap[filePath] = 1
+
+	return
 }

+ 51 - 0
cache/index_handle_excel_cache.go

@@ -0,0 +1,51 @@
+package cache
+
+import (
+	"container/list"
+	"sync"
+)
+
+//// AddIndexHandleExcel 添加处理excel变更队列
+//func AddIndexHandleExcel(filePath string) bool {
+//	if global.Re == nil {
+//		if global.Rc != nil {
+//			err := global.Rc.LPush(utils.HANDLE_HONGTAO_EXCEL, filePath)
+//			if err != nil {
+//				fmt.Println("Add Index Handle Excel LPush Err:" + err.Error())
+//			}
+//			return true
+//		}
+//		return true
+//	}
+//	return false
+//}
+
+// HandleExcelList 刷新的列表
+var HandleExcelList *list.List
+
+func init() {
+	HandleExcelList = list.New()
+}
+
+var HandleExcelFilePathMap = make(map[string]int)
+
+// HandleExcelFilePathMutex 创建一个互斥锁
+var HandleExcelFilePathMutex sync.Mutex
+
+// AddIndexHandleExcel
+// @Description: 添加处理excel变更队列
+// @author: Roc
+// @datetime2023-10-31 09:40:30
+// @param filePath string
+func AddIndexHandleExcel(filePath string) {
+	HandleExcelFilePathMutex.Lock()
+	defer HandleExcelFilePathMutex.Unlock()
+	// 如果存在该路径,那么就不记录入list
+	if _, ok := HandleExcelFilePathMap[filePath]; ok {
+		return
+	}
+	HandleExcelList.PushBack(filePath)
+	HandleExcelFilePathMap[filePath] = 1
+
+	return
+}

+ 3 - 0
config/config.go

@@ -20,6 +20,9 @@ type Serve struct {
 	StaticDir       string `mapstructure:"static-dir" json:"static-dir" yaml:"static-dir" description:"上传的文件存储目录地址"`
 	EdbLibUrl       string `mapstructure:"edb-lib-url" json:"edb-lib-url" yaml:"edb-lib-url" description:"公共指标库的地址"`
 	ListenExcelPath string `mapstructure:"listen-excel-path" json:"listen-excel-path" yaml:"listen-excel-path" description:"监听文件夹的路径"`
+	AppEdbLibNameEn string `mapstructure:"app_edb_lib_name_en" json:"app_edb_lib_name_en" yaml:"app_edb_lib_name_en" description:"指标库的英文名称"`
+	EdbLibMd5Key    string `mapstructure:"edb_lib_md5_key" json:"edb_lib_md5_key" yaml:"edb_lib_md5_key" description:"指标库服务秘钥"`
+	TerminalCode    string `mapstructure:"terminal_code" json:"terminal_code" yaml:"terminal_code" description:"终端编码"`
 }
 
 // Log 日志配置

+ 1 - 1
core/run_server.go

@@ -16,7 +16,7 @@ func RunServe() {
 	fmt.Println(global.CONFIG.Serve.UseRedis)
 	if global.CONFIG.Serve.UseRedis {
 		//初始化redis
-		init_serve.RedisTool()
+		init_serve.Redis()
 	}
 	//初始化验证器
 	//if err := global.InitTrans("zh"); err != nil {

+ 37 - 7
global/global.go

@@ -4,15 +4,18 @@ import (
 	"fmt"
 	"github.com/fsnotify/fsnotify"
 	"github.com/go-redis/redis/v8"
-	"github.com/olivere/elastic/v7"
 	oplogging "github.com/op/go-logging"
+	"github.com/patrickmn/go-cache"
 	"github.com/spf13/viper"
 	"gorm.io/gorm"
 	"hongze/hongtao3_watch/config"
 	"hongze/hongtao3_watch/utils"
 	"io"
-
-	"github.com/rdlucklib/rdluck_tools/cache"
+	"io/fs"
+	"os"
+	"path/filepath"
+	"syscall"
+	"time"
 )
 
 var (
@@ -22,10 +25,7 @@ var (
 	MYSQL_LOG     io.Writer
 	DEFAULT_MYSQL *gorm.DB      //默认数据库连接配置
 	Redis         *redis.Client //redis链接
-	EsClient      *elastic.Client
-
-	Rc *cache.Cache //redis缓存
-	Re error        //redis错误
+	CacheClient   *cache.Cache
 )
 
 const ConfigFile = "config/config_debug.yaml" //本地(测试)环境下的配置文件地址
@@ -63,4 +63,34 @@ func init() {
 	if err := v.Unmarshal(&CONFIG); err != nil {
 		fmt.Println("配置初始化赋值失败,Err:", err)
 	}
+
+	cache.New(365*24*time.Hour, 365*24*time.Hour)
+	ReadDefaultFileModifyTime()
+}
+
+func ReadDefaultFileModifyTime() {
+	CacheClient = cache.New(365*24*time.Hour, 365*24*time.Hour)
+	err := filepath.Walk(CONFIG.Serve.ListenExcelPath, func(path string, info fs.FileInfo, err error) error {
+		if err != nil {
+			return err
+		}
+		if !info.IsDir() {
+			fmt.Println(path)
+			fileInfo, err := os.Stat(path)
+			if err != nil {
+				fmt.Println("os.Stat:", err.Error())
+			}
+			winFileAttr := fileInfo.Sys().(*syscall.Win32FileAttributeData)
+			modifyTime := SecondToTime(winFileAttr.LastWriteTime.Nanoseconds() / 1e9).Format(utils.FormatDateTime)
+			fmt.Println("最后修改时间:", modifyTime)
+			CacheClient.Set(path, modifyTime, 24*time.Hour)
+		}
+		return nil
+	})
+	fmt.Println("Read err:", err)
+}
+
+// 把秒级的时间戳转为time格式
+func SecondToTime(sec int64) time.Time {
+	return time.Unix(sec, 0)
 }

+ 1 - 0
go.mod

@@ -55,6 +55,7 @@ require (
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
 	github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
+	github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
 	github.com/pelletier/go-toml/v2 v2.0.6 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
 	github.com/richardlehane/mscfb v1.0.4 // indirect

+ 0 - 16
init_serve/redis.go

@@ -2,11 +2,8 @@ package init_serve
 
 import (
 	"context"
-	"fmt"
 	"github.com/go-redis/redis/v8"
 	"hongze/hongtao3_watch/global"
-
-	"github.com/rdlucklib/rdluck_tools/cache"
 )
 
 func Redis() {
@@ -26,16 +23,3 @@ func Redis() {
 	//全局赋值redis链接
 	global.Redis = client
 }
-
-func RedisTool() {
-	fmt.Println("init RedisTool")
-	redisConf := global.CONFIG.Redis
-	fmt.Println(redisConf)
-	REDIS_CACHE := fmt.Sprintf(`{"key":"redis","conn":"%s","password":"%s"}`, redisConf.Address, redisConf.Password)
-	fmt.Println("REDIS_CACHE:"+REDIS_CACHE)
-	global.Rc, global.Re = cache.NewCache(REDIS_CACHE) //初始化缓存
-	if global.Re != nil {
-		fmt.Println(global.Re)
-		panic(global.Re)
-	}
-}

+ 7 - 2
init_serve/task.go

@@ -13,14 +13,19 @@ func InitTask() {
 
 	// 每天下午5点开始刷新excel表格
 	_, err := c.AddFunc("0 0 17 * * *", services.RefreshExcel)
-	//_, err := c.AddFunc("0 01 15 * * *", services.RefreshExcel)
+	//_, err := c.AddFunc("0 55 13 * * *", services.RefreshExcel)
 	if err != nil {
 		global.LOG.Info("RefreshExcel err" + err.Error())
 	}
+
+	//每2分钟检测一次指标文件是否更新
+	_, err = c.AddFunc("0 */1 * * * *", watch.ReadWatchIndexFile)
+	//_, err = c.AddFunc("*/30 * * * * *", watch.ReadWatchIndexFile)
+
 	c.Start()
 
 	// 监听文件
-	go watch.ListenFolderNew()
+	//go watch.ListenFolderNew()
 
 	// 处理excel
 	go services.HandleFileUpdate()

+ 9 - 1
services/index.go

@@ -22,7 +22,7 @@ func ReadExcel(filePath string) {
 		fmt.Println("OpenFile excel err:" + err.Error())
 		return
 	}
-	fmt.Println("开始读取EXCEL了")
+	fmt.Println("开始读取EXCEL了", filePath)
 
 	defer func() {
 		excelInfo.Close()
@@ -131,6 +131,14 @@ func ReadExcel(filePath string) {
 				if col == `` {
 					continue
 				}
+
+				// 校验数据长度
+				lenSheetThirdIndexIdList := len(sheetThirdIndexIdList)
+				if lenSheetThirdIndexIdList != colIndex {
+					fmt.Println("长度不一致,sheetThirdIndexIdList:", lenSheetThirdIndexIdList, ";colIndex:", colIndex)
+					continue
+				}
+
 				thirdIndexId := sheetThirdIndexIdList[colIndex-1]
 				if _, ok := dataMap[thirdIndexId]; !ok {
 					tmpDataMap := make(map[string]string)

+ 109 - 41
services/index_queue.go

@@ -2,60 +2,128 @@ package services
 
 import (
 	"fmt"
-	"hongze/hongtao3_watch/global"
-	"hongze/hongtao3_watch/utils"
+	"hongze/hongtao3_watch/cache"
 	"path/filepath"
-	"strings"
+	"time"
 )
 
 // HandleFileUpdate 处理文件变化
-func HandleFileUpdate() {
-	defer func() {
-		if err := recover(); err != nil {
-			fmt.Println("[AutoHandle]", err)
-		}
-	}()
+//func HandleFileUpdate() {
+//	defer func() {
+//		if err := recover(); err != nil {
+//			fmt.Println("[AutoHandle]", err)
+//		}
+//	}()
+//	for {
+//		global.Rc.Brpop(utils.HANDLE_HONGTAO_EXCEL, func(b []byte) {
+//			updateFilePath := string(b)
+//			// 移除多余的双引号
+//			updateFilePath = strings.Replace(updateFilePath, `"`, "", -1)
+//			fileExt := filepath.Ext(updateFilePath)
+//			//fmt.Println("fileExt:", fileExt)
+//
+//			if fileExt != ".xlsx" && fileExt != ".xls" {
+//				//fmt.Println("不是excel文件")
+//				return
+//			}
+//			// 读取excel内容并操作入库
+//			ReadExcel(updateFilePath)
+//		})
+//	}
+//
+//}
+
+//// HandleRefreshExcel 处理excel刷新(实际去调用刷新)
+//func HandleRefreshExcel() {
+//	defer func() {
+//		if err := recover(); err != nil {
+//			fmt.Println("[AutoRefresh]", err)
+//		}
+//	}()
+//	for {
+//		global.Rc.Brpop(utils.REFRESH_HONGTAO_EXCEL, func(b []byte) {
+//			updateFilePath := string(b)
+//			// 移除多余的双引号
+//			updateFilePath = strings.Replace(updateFilePath, `"`, "", -1)
+//			fileExt := filepath.Ext(updateFilePath)
+//			//fmt.Println("fileExt:", fileExt)
+//
+//			if fileExt != ".xlsx" && fileExt != ".xls" {
+//				//fmt.Println("不是excel文件")
+//				return
+//			}
+//			// 读取excel内容并操作入库
+//			InvokeRefreshServer(updateFilePath)
+//		})
+//	}
+//
+//}
+
+// HandleRefreshExcel
+// @Description: 处理excel刷新(实际去调用刷新)
+// @author: Roc
+// @datetime2023-10-31 09:44:36
+// @param filePath string
+func HandleRefreshExcel() {
 	for {
-		global.Rc.Brpop(utils.HANDLE_HONGTAO_EXCEL, func(b []byte) {
-			updateFilePath := string(b)
-			// 移除多余的双引号
-			updateFilePath = strings.Replace(updateFilePath, `"`, "", -1)
-			fileExt := filepath.Ext(updateFilePath)
-			//fmt.Println("fileExt:", fileExt)
-
-			if fileExt != ".xlsx" && fileExt != ".xls" {
-				//fmt.Println("不是excel文件")
-				return
-			}
-			// 读取excel内容并操作入库
-			ReadExcel(updateFilePath)
-		})
-	}
+		el := cache.RefreshList.Front()
+		// 如果没取到,那么就睡眠1s
+		if el == nil {
+			time.Sleep(1 * time.Second)
+			continue
+		}
+		filePath := el.Value.(string)
+
+		fileExt := filepath.Ext(filePath)
+		if fileExt != ".xlsx" && fileExt != ".xls" {
+			//fmt.Println("不是excel文件")
+			return
+		}
+		InvokeRefreshServer(filePath)
+
+		// 处理完后就移除该list
+		cache.RefreshList.Remove(el)
 
+		cache.FilePathMutex.Lock()
+		delete(cache.FilePathMap, filePath)
+		cache.FilePathMutex.Unlock()
+	}
 }
 
-// HandleRefreshExcel 处理excel刷新(实际去调用刷新)
-func HandleRefreshExcel() {
+// HandleFileUpdate
+// @Description: 处理文件变化
+// @author: Roc
+// @datetime2023-10-31 09:52:23
+func HandleFileUpdate() {
 	defer func() {
 		if err := recover(); err != nil {
-			fmt.Println("[AutoRefresh]", err)
+			fmt.Println("[AutoHandle]", err)
 		}
 	}()
+
 	for {
-		global.Rc.Brpop(utils.REFRESH_HONGTAO_EXCEL, func(b []byte) {
-			updateFilePath := string(b)
-			// 移除多余的双引号
-			updateFilePath = strings.Replace(updateFilePath, `"`, "", -1)
-			fileExt := filepath.Ext(updateFilePath)
-			//fmt.Println("fileExt:", fileExt)
-
-			if fileExt != ".xlsx" && fileExt != ".xls" {
-				//fmt.Println("不是excel文件")
-				return
-			}
-			// 读取excel内容并操作入库
-			InvokeRefreshServer(updateFilePath)
-		})
+		el := cache.HandleExcelList.Front()
+		// 如果没取到,那么就睡眠1s
+		if el == nil {
+			time.Sleep(1 * time.Second)
+			continue
+		}
+		filePath := el.Value.(string)
+
+		fileExt := filepath.Ext(filePath)
+		if fileExt != ".xlsx" && fileExt != ".xls" {
+			//fmt.Println("不是excel文件")
+			return
+		}
+		// 读取excel内容并操作入库
+		ReadExcel(filePath)
+
+		// 处理完后就移除该list
+		cache.HandleExcelList.Remove(el)
+
+		cache.HandleExcelFilePathMutex.Lock()
+		delete(cache.HandleExcelFilePathMap, filePath)
+		cache.HandleExcelFilePathMutex.Unlock()
 	}
 
 }

+ 2 - 1
services/sync_edb_lib.go

@@ -27,6 +27,7 @@ func HandleExcelDataByEdbLib(dataMap map[string]map[string]string, indexNameList
 	param["ThirdIndexIdList"] = thirdIndexIdList
 	param["FrequencyList"] = frequencyList
 	param["UnitList"] = unitList
+	param["TerminalCode"] = global.CONFIG.Serve.TerminalCode
 
 	// 指标处理的路由地址
 	urlStr := "sci/handle/excel_data"
@@ -81,7 +82,7 @@ func HttpPost(url, postData string, params ...string) ([]byte, error) {
 		contentType = params[0]
 	}
 	req.Header.Set("Content-Type", contentType)
-	req.Header.Set("authorization", utils.MD5(utils.APP_EDB_LIB_NAME_EN+utils.EDB_LIB_Md5_KEY))
+	req.Header.Set("authorization", utils.MD5(global.CONFIG.Serve.AppEdbLibNameEn+global.CONFIG.Serve.EdbLibMd5Key))
 	resp, err := client.Do(req)
 	if resp != nil {
 		defer resp.Body.Close()

+ 10 - 5
utils/common.go

@@ -47,7 +47,7 @@ func GenToken(account string) (accessToken string, err error) {
 	return
 }
 
-//随机数种子
+// 随机数种子
 var rnd = rand.New(rand.NewSource(time.Now().UnixNano()))
 
 // GetRandString 获取随机字符串
@@ -405,8 +405,8 @@ func TrimHtml(src string) string {
 	return strings.TrimSpace(src)
 }
 
-//1556164246  ->  2019-04-25 03:50:46 +0000
-//timestamp
+// 1556164246  ->  2019-04-25 03:50:46 +0000
+// timestamp
 // TimeToTimestamp
 func TimeToTimestamp() {
 	fmt.Println(time.Unix(1556164246, 0).Format("2006-01-02 15:04:05"))
@@ -466,7 +466,7 @@ func GetWilsonScore(p, n float64) float64 {
 	return toFixed(((p+1.9208)/(p+n)-1.96*math.Sqrt(p*n/(p+n)+0.9604)/(p+n))/(1+3.8416/(p+n)), 2)
 }
 
-//将中文数字转化成数字,比如 第三百四十五章,返回第345章 不支持一亿及以上
+// 将中文数字转化成数字,比如 第三百四十五章,返回第345章 不支持一亿及以上
 func ChangeWordsToNum(str string) (numStr string) {
 	words := ([]rune)(str)
 	num := 0
@@ -642,7 +642,7 @@ func GetMonthStartAndEnd(myYear string, myMonth string) (startDate, endDate stri
 	return t1, t2
 }
 
-//TrimStr 移除字符串中的空格
+// TrimStr 移除字符串中的空格
 func TrimStr(str string) (str2 string) {
 	return strings.Replace(str, " ", "", -1)
 }
@@ -1068,3 +1068,8 @@ func GetWeekDay() (string, string) {
 	l := lastOfWeeK.Unix()
 	return time.Unix(f, 0).Format("2006-01-02") + " 00:00:00", time.Unix(l, 0).Format("2006-01-02") + " 23:59:59"
 }
+
+// SecondToTime 把秒级的时间戳转为time格式
+func SecondToTime(sec int64) time.Time {
+	return time.Unix(sec, 0)
+}

+ 173 - 134
watch/watch.go

@@ -2,13 +2,13 @@ package watch
 
 import (
 	"fmt"
-	"github.com/fsnotify/fsnotify"
-	"hongze/hongtao3_watch/cache"
+	localCache "hongze/hongtao3_watch/cache"
 	"hongze/hongtao3_watch/global"
-	"hongze/hongtao3_watch/services"
+	"hongze/hongtao3_watch/utils"
+	"io/fs"
 	"os"
 	"path/filepath"
-	"strings"
+	"syscall"
 	"time"
 )
 
@@ -19,143 +19,182 @@ CHMOD修改文件属性
 REMOVE删除临时文件。
 */
 
-func ListenFolderNew() {
-	// 如果没有配置就不监听了
-	if global.CONFIG.Serve.ListenExcelPath == `` {
+//func ListenFolderNew() {
+//	// 如果没有配置就不监听了
+//	if global.CONFIG.Serve.ListenExcelPath == `` {
+//		return
+//	}
+//
+//	fmt.Println("-----文件夹监听-------")
+//	watcher, err := fsnotify.NewWatcher()
+//	if err != nil {
+//		fmt.Println("fsnotify.NewWatcher err:" + err.Error())
+//		//log.Fatal(err)
+//	}
+//	defer watcher.Close()
+//
+//	done2 := make(chan bool)
+//	go func() {
+//		for {
+//			select {
+//			case event, ok := <-watcher.Events:
+//				//fmt.Println("event.Name", event.Name)
+//				//fmt.Println(event.Op)
+//				//if ok && event.Op == fsnotify.Create &&
+//				//	!strings.Contains(event.Name, "tmp") &&
+//				//	!strings.Contains(event.Name, ".TMP") &&
+//				//	!strings.Contains(event.Name, "~") &&
+//				//	(strings.Contains(event.Name, "xlsx") || strings.Contains(event.Name, "xls")) {
+//				//	WatchIndexFileRelease(event.Name)
+//				//	fmt.Println("op:event.Name", event.Name)
+//				//}
+//
+//				// 如果是临时文件,那么就忽略
+//				if strings.Contains(event.Name, "tmp") ||
+//					strings.Contains(event.Name, ".TMP") ||
+//					strings.Contains(event.Name, "~") {
+//					continue
+//				}
+//
+//				if ok && event.Op&fsnotify.Create == fsnotify.Create {
+//					//fmt.Println("新增文件 : ", event.Name)
+//
+//					// 判断是否属于文件夹,如果是文件夹,那么就加上该文件夹的监听权限
+//					fi, err := os.Stat(event.Name)
+//					if err == nil {
+//						if fi.IsDir() {
+//							watcherDir(watcher, event.Name)
+//							fmt.Println("添加文件夹,添加监控 : ", event.Name)
+//						} else {
+//							// 读取文件
+//							cache.AddIndexHandleExcel(event.Name)
+//						}
+//					}
+//
+//				}
+//				if ok && event.Op&fsnotify.Write == fsnotify.Write {
+//					//fmt.Println("写入文件 : ", event.Name)
+//					// 读取文件
+//
+//					cache.AddIndexHandleExcel(event.Name)
+//				}
+//				if ok && event.Op&fsnotify.Remove == fsnotify.Remove {
+//					//fmt.Println("删除文件 : ", event.Name)
+//					//如果删除文件是目录,则移除监控
+//					fi, err := os.Stat(event.Name)
+//					if err == nil && fi.IsDir() {
+//						_ = watcher.Remove(event.Name)
+//						fmt.Println("删除文件夹,删除监控 : ", event.Name)
+//					}
+//				}
+//				if ok && event.Op&fsnotify.Rename == fsnotify.Rename {
+//					//fmt.Println("重命名文件 : ", event.Name)
+//					//如果重命名文件是目录,则移除监控
+//					//注意这里无法使用os.Stat来判断是否是目录了
+//					//因为重命名后,go已经无法找到原文件来获取信息了
+//					//所以这里就简单粗爆的直接remove好了
+//					_ = watcher.Remove(event.Name)
+//					//fmt.Println("更改文件夹名称,删除监控 : ", event.Name)
+//				}
+//				if ok && event.Op&fsnotify.Chmod == fsnotify.Chmod {
+//					fmt.Println("修改权限 : ", event.Name)
+//				}
+//			case err := <-watcher.Errors:
+//				if err != nil {
+//					fmt.Println("watcher.Errors:", err)
+//					//log.Println("error:", err)
+//				}
+//			case <-time.After(60 * time.Second):
+//				continue
+//			}
+//		}
+//	}()
+//
+//	// 开始监听
+//	watcherDir(watcher, global.CONFIG.Serve.ListenExcelPath)
+//
+//	<-done2
+//}
+
+//var watcherDirMap map[string]string
+//
+//// 添加监听目录
+//func watcherDir(watcher *fsnotify.Watcher, dirPath string) {
+//	err := filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error {
+//		//这里判断是否为目录,只需监控目录即可
+//		//目录下的文件也在监控范围内,不需要我们一个一个加
+//		if info.IsDir() {
+//			subpath, e := filepath.Abs(path)
+//			if e != nil {
+//				return e
+//			}
+//			err = watcher.Add(subpath)
+//			if err != nil {
+//				return err
+//			}
+//			// 入库
+//			if watcherDirMap == nil {
+//				watcherDirMap = make(map[string]string)
+//			}
+//			watcherDirMap[subpath] = subpath
+//			fmt.Println("监控 : ", subpath)
+//		}
+//		return nil
+//	})
+//	if err != nil {
+//		fmt.Println("watcher.Add:" + err.Error())
+//		//log.Fatal(err)
+//	}
+//}
+//
+//// HandleFileUpdate 处理文件变化
+//func HandleFileUpdate(updateFilePath string) {
+//	fileExt := filepath.Ext(updateFilePath)
+//
+//	if fileExt != ".xlsx" && fileExt != ".xls" {
+//		fmt.Println("不是excel文件")
+//		return
+//	}
+//
+//	// 读取excel内容并操作入库
+//	services.ReadExcel(updateFilePath)
+//}
+
+func ReadWatchIndexFile() {
+	var err error
+	defer func() {
+		if err != nil {
+			fmt.Println("ReadWatchIndexFile Err:" + err.Error())
+		}
+	}()
+	if global.CacheClient == nil {
+		fmt.Println("CacheClient 未导入")
 		return
 	}
-
-	fmt.Println("-----文件夹监听-------")
-	watcher, err := fsnotify.NewWatcher()
-	if err != nil {
-		fmt.Println("fsnotify.NewWatcher err:" + err.Error())
-		//log.Fatal(err)
-	}
-	defer watcher.Close()
-
-	done2 := make(chan bool)
-	go func() {
-		for {
-			select {
-			case event, ok := <-watcher.Events:
-				//fmt.Println("event.Name", event.Name)
-				//fmt.Println(event.Op)
-				//if ok && event.Op == fsnotify.Create &&
-				//	!strings.Contains(event.Name, "tmp") &&
-				//	!strings.Contains(event.Name, ".TMP") &&
-				//	!strings.Contains(event.Name, "~") &&
-				//	(strings.Contains(event.Name, "xlsx") || strings.Contains(event.Name, "xls")) {
-				//	WatchIndexFileRelease(event.Name)
-				//	fmt.Println("op:event.Name", event.Name)
-				//}
-
-				// 如果是临时文件,那么就忽略
-				if strings.Contains(event.Name, "tmp") ||
-					strings.Contains(event.Name, ".TMP") ||
-					strings.Contains(event.Name, "~") {
-					continue
-				}
-
-				if ok && event.Op&fsnotify.Create == fsnotify.Create {
-					//fmt.Println("新增文件 : ", event.Name)
-
-					// 判断是否属于文件夹,如果是文件夹,那么就加上该文件夹的监听权限
-					fi, err := os.Stat(event.Name)
-					if err == nil {
-						if fi.IsDir() {
-							watcherDir(watcher, event.Name)
-							fmt.Println("添加文件夹,添加监控 : ", event.Name)
-						} else {
-							// 读取文件
-							cache.AddIndexHandleExcel(event.Name)
-						}
-					}
-
-				}
-				if ok && event.Op&fsnotify.Write == fsnotify.Write {
-					//fmt.Println("写入文件 : ", event.Name)
-					// 读取文件
-
-					cache.AddIndexHandleExcel(event.Name)
-				}
-				if ok && event.Op&fsnotify.Remove == fsnotify.Remove {
-					//fmt.Println("删除文件 : ", event.Name)
-					//如果删除文件是目录,则移除监控
-					fi, err := os.Stat(event.Name)
-					if err == nil && fi.IsDir() {
-						_ = watcher.Remove(event.Name)
-						fmt.Println("删除文件夹,删除监控 : ", event.Name)
-					}
-				}
-				if ok && event.Op&fsnotify.Rename == fsnotify.Rename {
-					//fmt.Println("重命名文件 : ", event.Name)
-					//如果重命名文件是目录,则移除监控
-					//注意这里无法使用os.Stat来判断是否是目录了
-					//因为重命名后,go已经无法找到原文件来获取信息了
-					//所以这里就简单粗爆的直接remove好了
-					_ = watcher.Remove(event.Name)
-					//fmt.Println("更改文件夹名称,删除监控 : ", event.Name)
-				}
-				if ok && event.Op&fsnotify.Chmod == fsnotify.Chmod {
-					fmt.Println("修改权限 : ", event.Name)
-				}
-			case err := <-watcher.Errors:
-				if err != nil {
-					fmt.Println("watcher.Errors:", err)
-					//log.Println("error:", err)
-				}
-			case <-time.After(60 * time.Second):
-				continue
-			}
+	err = filepath.Walk(global.CONFIG.Serve.ListenExcelPath, func(path string, info fs.FileInfo, err error) error {
+		if err != nil {
+			return err
 		}
-	}()
-
-	// 开始监听
-	watcherDir(watcher, global.CONFIG.Serve.ListenExcelPath)
-
-	<-done2
-}
-
-var watcherDirMap map[string]string
-
-// 添加监听目录
-func watcherDir(watcher *fsnotify.Watcher, dirPath string) {
-	err := filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error {
-		//这里判断是否为目录,只需监控目录即可
-		//目录下的文件也在监控范围内,不需要我们一个一个加
-		if info.IsDir() {
-			subpath, e := filepath.Abs(path)
-			if e != nil {
-				return e
-			}
-			err = watcher.Add(subpath)
+		if !info.IsDir() {
+			fileInfo, err := os.Stat(path)
 			if err != nil {
-				return err
+				fmt.Println("os.Stat:", err.Error())
 			}
-			// 入库
-			if watcherDirMap == nil {
-				watcherDirMap = make(map[string]string)
+			winFileAttr := fileInfo.Sys().(*syscall.Win32FileAttributeData)
+			modifyTimeStr := utils.SecondToTime(winFileAttr.LastWriteTime.Nanoseconds() / 1e9).Format(utils.FormatDateTime)
+
+			existModifyTime, ok := global.CacheClient.Get(path)
+			if ok {
+				existModifyTimeStr := existModifyTime.(string)
+				if existModifyTimeStr != modifyTimeStr {
+					localCache.AddIndexHandleExcel(path)
+				}
+			} else {
+				localCache.AddIndexHandleExcel(path)
 			}
-			watcherDirMap[subpath] = subpath
-			fmt.Println("监控 : ", subpath)
+			global.CacheClient.Delete(path)
+			global.CacheClient.Set(path, modifyTimeStr, 24*time.Hour)
 		}
 		return nil
 	})
-	if err != nil {
-		fmt.Println("watcher.Add:" + err.Error())
-		//log.Fatal(err)
-	}
-}
-
-// HandleFileUpdate 处理文件变化
-func HandleFileUpdate(updateFilePath string) {
-	fileExt := filepath.Ext(updateFilePath)
-
-	if fileExt != ".xlsx" && fileExt != ".xls" {
-		fmt.Println("不是excel文件")
-		return
-	}
-
-	// 读取excel内容并操作入库
-	services.ReadExcel(updateFilePath)
 }