diff --git a/app.go b/app.go index fa5cf6c..6bc01e9 100644 --- a/app.go +++ b/app.go @@ -161,7 +161,7 @@ func (a *App) domReady(ctx context.Context) { a.cronEntrys["MonitorStockPrices"] = id } entryID, err := a.cron.AddFunc(fmt.Sprintf("@every %ds", interval+10), func() { - news := data.GetNewTelegraph(30) + news := data.NewMarketNewsApi().GetNewTelegraph(30) go runtime.EventsEmit(a.ctx, "newTelegraph", news) }) if err != nil { @@ -170,6 +170,15 @@ func (a *App) domReady(ctx context.Context) { a.cronEntrys["GetNewTelegraph"] = entryID } + entryIDSina, err := a.cron.AddFunc(fmt.Sprintf("@every %ds", interval+10), func() { + news := data.NewMarketNewsApi().GetSinaNews(30) + go runtime.EventsEmit(a.ctx, "newSinaNews", news) + }) + if err != nil { + logger.SugaredLogger.Errorf("AddFunc error:%s", err.Error()) + } else { + a.cronEntrys["newSinaNews"] = entryIDSina + } }() //刷新基金净值信息 @@ -1056,8 +1065,15 @@ func (a *App) RemoveGroup(groupId int) string { func (a *App) GetStockKLine(stockCode, stockName string, days int64) *[]data.KLineData { return data.NewStockDataApi().GetHK_KLineData(stockCode, "day", days) } +func (a *App) GetStockCommonKLine(stockCode, stockName string, days int64) *[]data.KLineData { + return data.NewStockDataApi().GetCommonKLineData(stockCode, "day", days) +} -func (a *App) GetTelegraphList() *[]*models.Telegraph { - telegraphs := data.NewMarketNewsApi().GetTelegraphList() +func (a *App) GetTelegraphList(source string) *[]*models.Telegraph { + telegraphs := data.NewMarketNewsApi().GetTelegraphList(source) return telegraphs } + +func (a *App) GlobalStockIndexes() map[string]any { + return data.NewMarketNewsApi().GlobalStockIndexes(30) +} diff --git a/backend/data/market_news_api.go b/backend/data/market_news_api.go index 5704c12..d493e8d 100644 --- a/backend/data/market_news_api.go +++ b/backend/data/market_news_api.go @@ -1,10 +1,19 @@ package data import ( + "encoding/json" + "fmt" + "github.com/PuerkitoBio/goquery" + "github.com/duke-git/lancet/v2/strutil" + "github.com/go-resty/resty/v2" + "github.com/robertkrimen/otto" "github.com/samber/lo" "go-stock/backend/db" "go-stock/backend/logger" "go-stock/backend/models" + "strconv" + "strings" + "time" ) // @Author spark @@ -18,9 +27,77 @@ func NewMarketNewsApi() *MarketNewsApi { return &MarketNewsApi{} } -func (m MarketNewsApi) GetTelegraphList() *[]*models.Telegraph { +func (m MarketNewsApi) GetNewTelegraph(crawlTimeOut int64) *[]models.Telegraph { + url := "https://www.cls.cn/telegraph" + response, _ := resty.New().SetTimeout(time.Duration(crawlTimeOut)*time.Second).R(). + SetHeader("Referer", "https://www.cls.cn/"). + SetHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.60"). + Get(fmt.Sprintf(url)) + var telegraphs []models.Telegraph + //logger.SugaredLogger.Info(string(response.Body())) + document, _ := goquery.NewDocumentFromReader(strings.NewReader(string(response.Body()))) + + document.Find(".telegraph-list").Each(func(i int, selection *goquery.Selection) { + //logger.SugaredLogger.Info(selection.Text()) + telegraph := models.Telegraph{Source: "财联社电报"} + spans := selection.Find("div.telegraph-content-box span") + if spans.Length() == 2 { + telegraph.Time = spans.First().Text() + telegraph.Content = spans.Last().Text() + if spans.Last().HasClass("c-de0422") { + telegraph.IsRed = true + } + } + + labels := selection.Find("div a.label-item") + labels.Each(func(i int, selection *goquery.Selection) { + if selection.HasClass("link-label-item") { + telegraph.Url = selection.AttrOr("href", "") + } else { + tag := &models.Tags{ + Name: selection.Text(), + Type: "subject", + } + db.Dao.Model(tag).Where("name=? and type=?", selection.Text(), "subject").FirstOrCreate(&tag) + telegraph.SubjectTags = append(telegraph.SubjectTags, selection.Text()) + } + }) + stocks := selection.Find("div.telegraph-stock-plate-box a") + stocks.Each(func(i int, selection *goquery.Selection) { + telegraph.StocksTags = append(telegraph.StocksTags, selection.Text()) + }) + + //telegraph = append(telegraph, ReplaceSensitiveWords(selection.Text())) + if telegraph.Content != "" { + cnt := int64(0) + db.Dao.Model(telegraph).Where("time=? and source=?", telegraph.Time, telegraph.Source).Count(&cnt) + if cnt == 0 { + db.Dao.Create(&telegraph) + telegraphs = append(telegraphs, telegraph) + for _, tag := range telegraph.SubjectTags { + tagInfo := &models.Tags{} + db.Dao.Model(models.Tags{}).Where("name=? and type=?", tag, "subject").First(&tagInfo) + if tagInfo.ID > 0 { + db.Dao.Model(models.TelegraphTags{}).Where("telegraph_id=? and tag_id=?", telegraph.ID, tagInfo.ID).FirstOrCreate(&models.TelegraphTags{ + TelegraphId: telegraph.ID, + TagId: tagInfo.ID, + }) + } + } + } + + } + }) + return &telegraphs +} + +func (m MarketNewsApi) GetTelegraphList(source string) *[]*models.Telegraph { news := &[]*models.Telegraph{} - db.Dao.Model(news).Preload("TelegraphTags").Order("id desc").Limit(20).Find(news) + if source != "" { + db.Dao.Model(news).Preload("TelegraphTags").Where("source=?", source).Order("id desc").Limit(20).Find(news) + } else { + db.Dao.Model(news).Preload("TelegraphTags").Order("id desc").Limit(20).Find(news) + } for _, item := range *news { tags := &[]models.Tags{} db.Dao.Model(&models.Tags{}).Where("id in ?", lo.Map(item.TelegraphTags, func(item models.TelegraphTags, index int) uint { @@ -34,3 +111,97 @@ func (m MarketNewsApi) GetTelegraphList() *[]*models.Telegraph { } return news } + +func (m MarketNewsApi) GetSinaNews(crawlTimeOut uint) *[]models.Telegraph { + news := &[]models.Telegraph{} + response, _ := resty.New().SetTimeout(time.Duration(crawlTimeOut)*time.Second).R(). + SetHeader("Referer", "https://finance.sina.com.cn"). + SetHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.60"). + Get("https://zhibo.sina.com.cn/api/zhibo/feed?callback=callback&page=1&page_size=20&zhibo_id=152&tag_id=0&dire=f&dpc=1&pagesize=20&id=4161089&type=0&_=" + strconv.FormatInt(time.Now().Unix(), 10)) + js := string(response.Body()) + js = strutil.ReplaceWithMap(js, + map[string]string{ + "try{callback(": "var data=", + ");}catch(e){};": ";", + }) + //logger.SugaredLogger.Info(js) + vm := otto.New() + _, err := vm.Run(js) + if err != nil { + logger.SugaredLogger.Error(err) + } + vm.Run("var result = data.result;") + //vm.Run("var resultStr =JSON.stringify(data);") + vm.Run("var resultData = result.data;") + vm.Run("var feed = resultData.feed;") + vm.Run("var feedStr = JSON.stringify(feed);") + + value, _ := vm.Get("feedStr") + //resultStr, _ := vm.Get("resultStr") + + //logger.SugaredLogger.Info(resultStr) + feed := make(map[string]any) + err = json.Unmarshal([]byte(value.String()), &feed) + if err != nil { + logger.SugaredLogger.Errorf("json.Unmarshal error:%v", err.Error()) + } + var telegraphs []models.Telegraph + + if feed["list"] != nil { + for _, item := range feed["list"].([]any) { + telegraph := models.Telegraph{Source: "新浪财经"} + data := item.(map[string]any) + //logger.SugaredLogger.Infof("%s:%s", data["create_time"], data["rich_text"]) + telegraph.Content = data["rich_text"].(string) + telegraph.Time = strings.Split(data["create_time"].(string), " ")[1] + tags := data["tag"].([]any) + telegraph.SubjectTags = lo.Map(tags, func(tagItem any, index int) string { + name := tagItem.(map[string]any)["name"].(string) + tag := &models.Tags{ + Name: name, + Type: "sina_subject", + } + db.Dao.Model(tag).Where("name=? and type=?", name, "sina_subject").FirstOrCreate(&tag) + return name + }) + if _, ok := lo.Find(telegraph.SubjectTags, func(item string) bool { return item == "焦点" }); ok { + telegraph.IsRed = true + } + logger.SugaredLogger.Infof("telegraph.SubjectTags:%v %s", telegraph.SubjectTags, telegraph.Content) + + if telegraph.Content != "" { + cnt := int64(0) + db.Dao.Model(telegraph).Where("time=? and source=?", telegraph.Time, telegraph.Source).Count(&cnt) + if cnt == 0 { + db.Dao.Create(&telegraph) + telegraphs = append(telegraphs, telegraph) + for _, tag := range telegraph.SubjectTags { + tagInfo := &models.Tags{} + db.Dao.Model(models.Tags{}).Where("name=? and type=?", tag, "sina_subject").First(&tagInfo) + if tagInfo.ID > 0 { + db.Dao.Model(models.TelegraphTags{}).Where("telegraph_id=? and tag_id=?", telegraph.ID, tagInfo.ID).FirstOrCreate(&models.TelegraphTags{ + TelegraphId: telegraph.ID, + TagId: tagInfo.ID, + }) + } + } + } + } + } + return &telegraphs + } + + return news + +} + +func (m MarketNewsApi) GlobalStockIndexes(crawlTimeOut uint) map[string]any { + response, _ := resty.New().SetTimeout(time.Duration(crawlTimeOut)*time.Second).R(). + SetHeader("Referer", "https://stockapp.finance.qq.com/mstats"). + SetHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.60"). + Get("https://proxy.finance.qq.com/ifzqgtimg/appstock/app/rank/indexRankDetail2") + js := string(response.Body()) + res := make(map[string]any) + json.Unmarshal([]byte(js), &res) + return res["data"].(map[string]any) +} diff --git a/backend/data/market_news_api_test.go b/backend/data/market_news_api_test.go new file mode 100644 index 0000000..a2f2bb1 --- /dev/null +++ b/backend/data/market_news_api_test.go @@ -0,0 +1,29 @@ +package data + +import ( + "encoding/json" + "go-stock/backend/db" + "go-stock/backend/logger" + "testing" +) + +// @Author spark +// @Date 2025/4/23 17:58 +// @Desc +//----------------------------------------------------------------------------------- + +func TestGetSinaNews(t *testing.T) { + db.Init("../../data/stock.db") + NewMarketNewsApi().GetSinaNews(30) + //NewMarketNewsApi().GetNewTelegraph(30) + +} + +func TestGlobalStockIndexes(t *testing.T) { + resp := NewMarketNewsApi().GlobalStockIndexes(30) + bytes, err := json.Marshal(resp) + if err != nil { + return + } + logger.SugaredLogger.Debugf("resp: %+v", string(bytes)) +} diff --git a/backend/data/openai_api.go b/backend/data/openai_api.go index 26e3ecc..4dcf0ba 100644 --- a/backend/data/openai_api.go +++ b/backend/data/openai_api.go @@ -716,70 +716,6 @@ func GetTelegraphList(crawlTimeOut int64) *[]string { return &telegraph } -func GetNewTelegraph(crawlTimeOut int64) *[]models.Telegraph { - url := "https://www.cls.cn/telegraph" - response, _ := resty.New().SetTimeout(time.Duration(crawlTimeOut)*time.Second).R(). - SetHeader("Referer", "https://www.cls.cn/"). - SetHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.60"). - Get(fmt.Sprintf(url)) - var telegraphs []models.Telegraph - //logger.SugaredLogger.Info(string(response.Body())) - document, _ := goquery.NewDocumentFromReader(strings.NewReader(string(response.Body()))) - - document.Find(".telegraph-list").Each(func(i int, selection *goquery.Selection) { - //logger.SugaredLogger.Info(selection.Text()) - telegraph := models.Telegraph{} - spans := selection.Find("div.telegraph-content-box span") - if spans.Length() == 2 { - telegraph.Time = spans.First().Text() - telegraph.Content = spans.Last().Text() - if spans.Last().HasClass("c-de0422") { - telegraph.IsRed = true - } - } - - labels := selection.Find("div a.label-item") - labels.Each(func(i int, selection *goquery.Selection) { - if selection.HasClass("link-label-item") { - telegraph.Url = selection.AttrOr("href", "") - } else { - tag := &models.Tags{ - Name: selection.Text(), - Type: "subject", - } - db.Dao.Model(tag).Where("name=? and type=?", selection.Text(), "subject").FirstOrCreate(&tag) - telegraph.SubjectTags = append(telegraph.SubjectTags, selection.Text()) - } - }) - stocks := selection.Find("div.telegraph-stock-plate-box a") - stocks.Each(func(i int, selection *goquery.Selection) { - telegraph.StocksTags = append(telegraph.StocksTags, selection.Text()) - }) - - //telegraph = append(telegraph, ReplaceSensitiveWords(selection.Text())) - if telegraph.Content != "" { - cnt := int64(0) - db.Dao.Model(telegraph).Where("time=?", telegraph.Time).Count(&cnt) - if cnt == 0 { - db.Dao.Create(&telegraph) - telegraphs = append(telegraphs, telegraph) - for _, tag := range telegraph.SubjectTags { - tagInfo := &models.Tags{} - db.Dao.Model(models.Tags{}).Where("name=? and type=?", tag, "subject").First(&tagInfo) - if tagInfo.ID > 0 { - db.Dao.Model(models.TelegraphTags{}).Where("telegraph_id=? and tag_id=?", telegraph.ID, tagInfo.ID).FirstOrCreate(&models.TelegraphTags{ - TelegraphId: telegraph.ID, - TagId: tagInfo.ID, - }) - } - } - } - - } - }) - return &telegraphs -} - func GetTopNewsList(crawlTimeOut int64) *[]string { url := "https://www.cls.cn" response, err := resty.New().SetTimeout(time.Duration(crawlTimeOut)*time.Second).R(). diff --git a/backend/data/stock_data_api.go b/backend/data/stock_data_api.go index 98ddd46..6bafe6f 100644 --- a/backend/data/stock_data_api.go +++ b/backend/data/stock_data_api.go @@ -1112,6 +1112,55 @@ func (receiver StockDataApi) GetHK_KLineData(stockCode string, kLineType string, stockCode = strings.Replace(stockCode, "gb_", "us", 1) + ".OQ" } + url := fmt.Sprintf("https://web.ifzq.gtimg.cn/appstock/app/fqkline/get?param=%s,%s,,,%d,qfq", stockCode, kLineType, days) + //logger.SugaredLogger.Infof("url:%s", url) + K := &[]KLineData{} + res := make(map[string]interface{}) + resp, err := receiver.client.SetTimeout(time.Duration(receiver.config.CrawlTimeOut)*time.Second).R(). + SetHeader("Host", "web.ifzq.gtimg.cn"). + SetHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0"). + Get(url) + if err != nil { + logger.SugaredLogger.Errorf("err:%s", err.Error()) + return K + } + //logger.SugaredLogger.Infof("resp:%s", resp.Body()) + json.Unmarshal(resp.Body(), &res) + code, _ := convertor.ToInt(res["code"]) + if code != 0 { + return K + } + if res["data"] != nil && code == 0 { + data := res["data"].(map[string]interface{})[stockCode].(map[string]interface{}) + if data != nil { + var day []any + if data["qfqday"] != nil { + day = data["qfqday"].([]any) + } + if data["day"] != nil { + day = data["day"].([]any) + } + for _, v := range day { + if v != nil { + vv := v.([]any) + KLine := &KLineData{ + Day: convertor.ToString(vv[0]), + Open: convertor.ToString(vv[1]), + Close: convertor.ToString(vv[2]), + High: convertor.ToString(vv[3]), + Low: convertor.ToString(vv[4]), + Volume: convertor.ToString(vv[5]), + } + *K = append(*K, *KLine) + } + } + } + } + return K +} + +func (receiver StockDataApi) GetCommonKLineData(stockCode string, kLineType string, days int64) *[]KLineData { + url := fmt.Sprintf("https://web.ifzq.gtimg.cn/appstock/app/fqkline/get?param=%s,%s,,,%d,qfq", stockCode, kLineType, days) logger.SugaredLogger.Infof("url:%s", url) K := &[]KLineData{} diff --git a/backend/data/stock_data_api_test.go b/backend/data/stock_data_api_test.go index 95f99c5..0e6ccae 100644 --- a/backend/data/stock_data_api_test.go +++ b/backend/data/stock_data_api_test.go @@ -28,7 +28,7 @@ func TestGetTelegraph(t *testing.T) { //for _, telegraph := range *telegraphs { // logger.SugaredLogger.Info(telegraph) //} - list := GetNewTelegraph(30) + list := NewMarketNewsApi().GetNewTelegraph(30) for _, telegraph := range *list { logger.SugaredLogger.Infof("telegraph:%+v", telegraph) } diff --git a/backend/models/models.go b/backend/models/models.go index 6fc685f..8e41a9f 100644 --- a/backend/models/models.go +++ b/backend/models/models.go @@ -224,6 +224,7 @@ type Telegraph struct { StocksTags []string `json:"stocks" gorm:"-:all"` IsRed bool `json:"isRed"` Url string `json:"url"` + Source string `json:"source"` TelegraphTags []TelegraphTags `json:"tags" gorm:"-:migration;foreignKey:TelegraphId"` } type TelegraphTags struct { diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 15df4c4..e24de1a 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -64,7 +64,7 @@ const menuOptions = ref([ } } }, - { default: () => '市场资讯' } + { default: () => '市场行情' } ), key: 'market', icon: renderIcon(NewspaperOutline), diff --git a/frontend/src/components/KLineChart.vue b/frontend/src/components/KLineChart.vue new file mode 100644 index 0000000..ed5c039 --- /dev/null +++ b/frontend/src/components/KLineChart.vue @@ -0,0 +1,382 @@ + + + + + \ No newline at end of file diff --git a/frontend/src/components/market.vue b/frontend/src/components/market.vue index 4d663d5..81bceaf 100644 --- a/frontend/src/components/market.vue +++ b/frontend/src/components/market.vue @@ -1,69 +1,193 @@ \ No newline at end of file diff --git a/frontend/src/components/stock.vue b/frontend/src/components/stock.vue index e528644..44d5a9a 100644 --- a/frontend/src/components/stock.vue +++ b/frontend/src/components/stock.vue @@ -784,7 +784,7 @@ function handleKLine(){ { type: 'inside', xAxisIndex: [0, 1], - start: 50, + start: 86, end: 100 }, { @@ -792,7 +792,7 @@ function handleKLine(){ xAxisIndex: [0, 1], type: 'slider', top: '85%', - start: 50, + start: 86, end: 100 } ], diff --git a/frontend/src/main.js b/frontend/src/main.js index c1b63ec..8f7f9af 100644 --- a/frontend/src/main.js +++ b/frontend/src/main.js @@ -3,6 +3,7 @@ import naive from 'naive-ui' import App from './App.vue' import router from './router/router' + const app = createApp(App) app.use(router) app.use(naive) diff --git a/frontend/wailsjs/go/main/App.d.ts b/frontend/wailsjs/go/main/App.d.ts index dec5fd7..9278ec9 100644 --- a/frontend/wailsjs/go/main/App.d.ts +++ b/frontend/wailsjs/go/main/App.d.ts @@ -35,16 +35,20 @@ export function GetGroupStockList(arg1:number):Promise>; export function GetPromptTemplates(arg1:string,arg2:string):Promise; +export function GetStockCommonKLine(arg1:string,arg2:string,arg3:number):Promise; + export function GetStockKLine(arg1:string,arg2:string,arg3:number):Promise; export function GetStockList(arg1:string):Promise>; -export function GetTelegraphList():Promise; +export function GetTelegraphList(arg1:string):Promise; export function GetVersionInfo():Promise; export function GetfundList(arg1:string):Promise>; +export function GlobalStockIndexes():Promise>; + export function Greet(arg1:string):Promise; export function NewChatStream(arg1:string,arg2:string,arg3:string,arg4:any):Promise; diff --git a/frontend/wailsjs/go/main/App.js b/frontend/wailsjs/go/main/App.js index a96de0d..55d3ca1 100644 --- a/frontend/wailsjs/go/main/App.js +++ b/frontend/wailsjs/go/main/App.js @@ -66,6 +66,10 @@ export function GetPromptTemplates(arg1, arg2) { return window['go']['main']['App']['GetPromptTemplates'](arg1, arg2); } +export function GetStockCommonKLine(arg1, arg2, arg3) { + return window['go']['main']['App']['GetStockCommonKLine'](arg1, arg2, arg3); +} + export function GetStockKLine(arg1, arg2, arg3) { return window['go']['main']['App']['GetStockKLine'](arg1, arg2, arg3); } @@ -74,8 +78,8 @@ export function GetStockList(arg1) { return window['go']['main']['App']['GetStockList'](arg1); } -export function GetTelegraphList() { - return window['go']['main']['App']['GetTelegraphList'](); +export function GetTelegraphList(arg1) { + return window['go']['main']['App']['GetTelegraphList'](arg1); } export function GetVersionInfo() { @@ -86,6 +90,10 @@ export function GetfundList(arg1) { return window['go']['main']['App']['GetfundList'](arg1); } +export function GlobalStockIndexes() { + return window['go']['main']['App']['GlobalStockIndexes'](); +} + export function Greet(arg1) { return window['go']['main']['App']['Greet'](arg1); } diff --git a/go.mod b/go.mod index 57473bb..107212d 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/glebarez/sqlite v1.11.0 github.com/go-resty/resty/v2 v2.16.2 github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4 + github.com/robertkrimen/otto v0.5.1 github.com/robfig/cron/v3 v3.0.1 github.com/samber/lo v1.49.1 github.com/stretchr/testify v1.10.0 @@ -70,6 +71,7 @@ require ( golang.org/x/crypto v0.33.0 // indirect golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect golang.org/x/net v0.35.0 // indirect + gopkg.in/sourcemap.v1 v1.0.5 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect modernc.org/libc v1.22.5 // indirect modernc.org/mathutil v1.5.0 // indirect diff --git a/go.sum b/go.sum index 02a06b5..24bad7a 100644 --- a/go.sum +++ b/go.sum @@ -107,6 +107,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qq github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/robertkrimen/otto v0.5.1 h1:avDI4ToRk8k1hppLdYFTuuzND41n37vPGJU7547dGf0= +github.com/robertkrimen/otto v0.5.1/go.mod h1:bS433I4Q9p+E5pZLu7r17vP6FkE6/wLxBdmKjoqJXF8= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/samber/lo v1.49.1 h1:4BIFyVfuQSEpluc7Fua+j1NolZHiEHEpaSEKdsH0tew= @@ -222,6 +224,8 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8X gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= +gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI= +gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo=