diff --git a/.gitignore b/.gitignore index f20ecee083a5fe275de2d3d7f771e19eaea97237..61ebe7ddc8c7b50b2ae386bb2a5e05b30aa21ab6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +bin/ vendor/ .idea/ output/ diff --git a/README.md b/README.md index 1d8a19459ccdcaeec416ebfecafa862b78ffcc32..47280e11be4839d282fdbe9a154f1b63425bd65a 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,10 @@ # tg-flow简介 -tg-flow是一个专注于在线高并发场景的无状态的工作流引擎,它可以在保证高性能的前提下,为在线高并发系统提供复杂的的工作流调度能力,目前tg-flow已经广泛运用于滴滴内部多个日流量数十亿的核心在线系统。 -tg-flow包括三个主要模块: -* tg-core: tg-flow的工作流引擎核心模块,提供了对工作流的的调度执行能力。 -* tg-web: tg-flow的工作流配置管理前端页面,为用户提供工作流的创建、编辑、保存、删除、导入、导出等功能。 -* tg-service:tg-flow的工作流配置管理后台服务,为tg-web的后台API接口,同时也提供工作流配置分发的能力,可将配置分发到redis、zookeeper、文件系统(导出为文件)中。 +tg-flow是一个专注于在线高并发场景的工作流引擎,它综合运用了多种优化算法,可以在高并发场景下轻松地支持由100多个节点组成的复杂工作流的调度,目前已经广泛运用于滴滴内部多个日流量数十亿的核心在线高并发系统。 + +tg-flow 相关的开源仓库总共将包括3个部分: +* tg-flow: 工作流引擎核心模块,提供高并发场景下的复杂工作流的调度执行能力。 +* tg-example: 为便于用户快速上手而提供的一个示例项目,如果用户本地有安装golang环境,下载后直接go run main.go即可运行。[点此了解 tg-example](https://github.com/didi/tg-example) +* tg-service: 后台管理系统,辅助用户对工作流进行配置管理及发布上线,此部分非tg-flow的强依赖模块,尚在整理中,待完善后再提交。 # 我们的目标 受限于在线高并发场景的高性能要求,传统工作流引擎很难支持在线高并发系统。 我们的目标是实现一个既能够满足在线高并发场景的性能要求,又具备传统工作流引擎各种复杂功能的工作流引擎。 @@ -25,7 +26,7 @@ tg-flow包括三个主要模块: 3. 再进一步,如果需要使用tg-flow所有功能,可以在第二步的基础上,自行部署redis或zookeeper,然后在线系统中可以使用tg-core中的核心模块定期从redis或zookeeper中检测工作流新版本,并及时更新到在线系统。 # 用户手册 - 参见: [user_manual](user_manual.html) + [用户手册](https://github.com/didi/tg-example/blob/main/user_manual.md) # 欢迎加入 - 请联系:[张云锋](https://github.com/dayunzhangyunfeng), [周子纯](https://github.com/zhouzichun0315), [唐桂尧](https://github.com/tgy931) + 请联系:[张云锋](https://github.com/dayunzhangyunfeng), [周子纯](https://github.com/zhouzichun0315), [唐桂尧](https://github.com/tgy931) diff --git a/common/crontask/new_register_task.go b/common/crontask/new_register_task.go new file mode 100644 index 0000000000000000000000000000000000000000..be8b96e15e55640af7ddb019134e20c7e80acad2 --- /dev/null +++ b/common/crontask/new_register_task.go @@ -0,0 +1,41 @@ +package crontask +// +//import ( +// "context" +// "github.com/didi/tg-flow/common/tlog" +// "reflect" +// "time" +//) +// +//const( +// TagCronTask = " _cron_task" +//) +//// 定时任务接口 +//type TaskInterface interface { +// Run() +//} +// +///* +//********************参数含义*************** +// +// task:定时任务结构体 +// period:定时周期的单位:秒 +// flag:是否在系统启动前启动定时任务 +// +//****************************************** +//*/ +//func StartTask(task TaskInterface, period time.Duration, flag bool) { +// ctx := context.TODO() +// taskName := reflect.TypeOf(task).String() +// +// defer RecoverTaskRun(taskName, ctx) +// if flag { //如果是需要在系统启动前启动定时任务,那么定时任务正式开始执行时间后延一个周期 +// time.Sleep(period * time.Second) +// } +// +// for { +// tlog.Handler.Infof(ctx, TagCronTask, "taskName=%v is start.", taskName) +// task.Run() +// time.Sleep(period * time.Second) +// } +//} diff --git a/common/crontask/register_task.go b/common/crontask/register_task.go new file mode 100644 index 0000000000000000000000000000000000000000..c937e554e27c7daec11b81ffca03153914ca4047 --- /dev/null +++ b/common/crontask/register_task.go @@ -0,0 +1,96 @@ +package crontask +// +//import ( +// "context" +// "crypto/rand" +// "fmt" +// "github.com/didi/tg-flow/common/tlog" +// "github.com/robfig/cron" +// "math" +// "math/big" +// "reflect" +// "strconv" +// "strings" +//) +// +////定时任务管理实例 +//var CronTask *cron.Cron = cron.New() +// +////定时任务管道 +//var ChanMap map[string]chan interface{} = make(map[string]chan interface{}) +// +///**注册定时任务 +// taskTime:定时任务的周期 +// job:具体的定时任务对象 +// ch:job任务中的定时管道 +// flag:是否随系统启动时,执行一次该任务 +//**/ +//func RegisterTask(taskTime string, job cron.Job, flag bool) { +// //定时任务管道初始化 +// name := reflect.TypeOf(job) +// ChanMap[name.Name()] = make(chan interface{}, 1) +// +// //是否随系统启动执行 +// if flag { +// job.Run() +// } +// +// //如果是秒以上的定时周期,则给一个随机的秒,以避免同台机器并发执行任务,给相应机器造成并发压力 +// newTaskTime := "" +// tempTimes := strings.Split(taskTime, " ") +// if tempTimes[0] == "0" || tempTimes[0] == "*" { +// for i := 1; i < len(tempTimes); i++ { +// newTaskTime += " " + tempTimes[i] +// } +// newTaskTime = strconv.FormatInt(RangeRand(0, 59), 10) + newTaskTime +// // time.Sleep(1 * time.Second) +// // newTaskTime = strconv.Itoa(time.Now().Second()) + newTaskTime +// } else { +// newTaskTime = taskTime +// } +// +// //注册任务 +// CronTask.AddJob(newTaskTime, job) +//} +// +///** +// 启动定时任务 +//**/ +//func TaskStart() { +// defer recoverTaskStart() +// CronTask.Start() +//} +// +////定时任务运行异常,捕获异常后,需要释放该任务的任务管道 +//func RecoverTaskRun(taskName string, ctx context.Context) { +// if err := recover(); err != nil { +// content := fmt.Sprintf("taskName=%v||err=%v", taskName, err) +// tlog.Handler.ErrorCount(ctx, "crontask.recoverTaskRun", content) +// } +//} +// +////所有定时任务启动失败 +//func recoverTaskStart() { +// if err := recover(); err != nil { +// content := fmt.Sprintf("all task start fail||err=%v", err) +// tlog.Handler.ErrorCount(context.TODO(), "crontask.recoverTaskStart", content) +// } +//} +// +//// 生成区间[-m, n]的安全随机数 +//func RangeRand(min, max int64) int64 { +// if min > max { +// panic("the min is greater than max!") +// } +// +// if min < 0 { +// f64Min := math.Abs(float64(min)) +// i64Min := int64(f64Min) +// result, _ := rand.Int(rand.Reader, big.NewInt(max+1+i64Min)) +// +// return result.Int64() - i64Min +// } else { +// result, _ := rand.Int(rand.Reader, big.NewInt(max-min+1)) +// return min + result.Int64() +// } +//} diff --git a/tg-core/common/path/init.go b/common/path/init.go similarity index 60% rename from tg-core/common/path/init.go rename to common/path/init.go index c7ac8bcf600b6e746e0ffee9aed8caf8875ca87f..6c4c220bfcc92c8cf6a4004a01a73c9945ee5968 100644 --- a/tg-core/common/path/init.go +++ b/common/path/init.go @@ -8,20 +8,21 @@ import ( const ( TEST_MAPBASE_PATH = "TEST_MAPBASE_PATH" ) + // Root current dir var Root string func init() { - log.Println("tg-core path init start...") + log.Println("tg-flow path init start...") - if rootPath := os.Getenv(TEST_MAPBASE_PATH);rootPath != ""{ + if rootPath := os.Getenv(TEST_MAPBASE_PATH); rootPath != "" { Root = rootPath - }else { + } else { var err error Root, err = os.Getwd() if err != nil { log.Fatal("Initialize Root error: ", err) } } - log.Println("tg-core path init successful, path="+Root) -} \ No newline at end of file + log.Println("tg-flow path init successful, path=" + Root) +} diff --git a/tg-core/common/timeutils/time_coster.go b/common/timeutils/time_coster.go similarity index 49% rename from tg-core/common/timeutils/time_coster.go rename to common/timeutils/time_coster.go index df192ef17d03735413566ad03456fef109f2c125..5da9412a75cd57d6ac7c37ce802cc28ff1432721 100644 --- a/tg-core/common/timeutils/time_coster.go +++ b/common/timeutils/time_coster.go @@ -15,36 +15,68 @@ import ( ) type TimeCoster struct { - startTime time.Time - costMap *sync.Map + startTime time.Time + timeUnit string + costMap *sync.Map } const ( - totalCost = "totalCost" + TotalCost = "totalCost" + TimeUnitSecond = "s" + TimeUnitMillSecond = "ms" + TimeUnitNanoSecond = "ns" ) +// 老的,即将被下面NewTimeCosterUnit替换 func NewTimeCoster() *TimeCoster { t := new(TimeCoster) - t.costMap = &sync.Map{} + t.timeUnit = TimeUnitMillSecond + t.costMap = &sync.Map{} + t.StartCount() + return t +} + +/* +* + + timeUnit三种取值: + s : 秒 + ms:毫秒,缺省 + ns: 纳秒 +*/ +func NewTimeCosterUnit(timeUnit string) *TimeCoster { + t := new(TimeCoster) + //不想panc, 兼容一下 + if timeUnit != TimeUnitNanoSecond && timeUnit != TimeUnitMillSecond && timeUnit != TimeUnitSecond { + //todo add warning + timeUnit = TimeUnitMillSecond + } + t.timeUnit = timeUnit + t.costMap = &sync.Map{} t.StartCount() return t } func (t *TimeCoster) StartCount() { t.startTime = time.Now() - t.costMap.Store(totalCost, t.startTime.UnixNano()) + t.costMap.Store(TotalCost, t.startTime.UnixNano()) } func (t *TimeCoster) StopCount() { - st, ok := t.costMap.Load(totalCost) + st, ok := t.costMap.Load(TotalCost) if !ok { - t.costMap.Delete(totalCost) + t.costMap.Delete(TotalCost) return } startTime := st.(int64) - costTime := (time.Now().UnixNano() - startTime)/1000000 - t.costMap.Store(totalCost, costTime) + costTime := time.Now().UnixNano() - startTime + if t.timeUnit == TimeUnitMillSecond { + costTime = costTime / 1000000 + } else if t.timeUnit == TimeUnitSecond { + costTime = costTime / 1000000000 + } + t.costMap.Store(TotalCost, costTime) } func (t *TimeCoster) StartSectionCount(key string) { @@ -59,21 +91,27 @@ func (t *TimeCoster) StopSectionCount(key string) { } startTime := st.(int64) - costTime := (time.Now().UnixNano() - startTime)/1000000 + costTime := time.Now().UnixNano() - startTime + if t.timeUnit == TimeUnitMillSecond { + costTime = costTime / 1000000 + } else if t.timeUnit == TimeUnitSecond { + costTime = costTime / 1000000000 + } + t.costMap.Store(key, costTime) } func (t *TimeCoster) GetSectionCount(key string) (int64, error) { - ct,oks := t.costMap.Load(key) + ct, oks := t.costMap.Load(key) if !oks { return 0, fmt.Errorf("no time count info:%v", key) } - costTime:=ct.(int64) + costTime := ct.(int64) return costTime, nil } -func (t *TimeCoster) GetAllCounts() (map[string]int64) { +func (t *TimeCoster) GetAllCounts() map[string]int64 { kv := make(map[string]int64) t.costMap.Range(func(k, v interface{}) bool { key := fmt.Sprintf("%v", k) @@ -98,14 +136,14 @@ func (t *TimeCoster) ToCountString() string { }) strs := buffer.String() - if strings.HasSuffix(strs,"||") { - strs = strs[0:len(strs)-2] + if strings.HasSuffix(strs, "||") { + strs = strs[0 : len(strs)-2] } return strs } -func (t *TimeCoster) SetSectionCount(key string, cost int64){ +func (t *TimeCoster) SetSectionCount(key string, cost int64) { t.costMap.Store(key, cost) } @@ -113,14 +151,20 @@ func (t *TimeCoster) GetStartTime() time.Time { return t.startTime } -//目前没用,就不要了 -/*func (t *TimeCoster) Merge(t1 *TimeCoster){ +func (t *TimeCoster) Merge(t1 *TimeCoster) { if t1 == nil { return } + if t.timeUnit != t1.timeUnit { + //TODO 不允许,先忽略吧 + return + } + t1.costMap.Range(func(k, v interface{}) bool { - t.costMap.Store(k, v) + if k != TotalCost { + t.costMap.Store(k, v) + } return true }) -}*/ +} diff --git a/common/tlog/count_logger.go b/common/tlog/count_logger.go new file mode 100644 index 0000000000000000000000000000000000000000..c4062a2f9b6169ddfc53d47138304eade9162cd0 --- /dev/null +++ b/common/tlog/count_logger.go @@ -0,0 +1,140 @@ +package tlog + +import ( + "context" + "fmt" + "path/filepath" + "runtime" + "strings" +) + +// should be assigned when service init +var Handler *CountLogger + +type ICounter interface{ + Count(metricName string) + CounterByTags(metricName string, tags map[string]string) +} + +type ILogger interface { + /*Trace(tag string, args ...interface{}) + Tracef(ctx context.Context, tag string, format string, args ...interface{}) + Warn(tag string, args ...interface{}) + Warnf(ctx context.Context, tag string, format string, args ...interface{}) + Fatal(tag string, args ...interface{}) + Fatalf(ctx context.Context, tag string, format string, args ...interface{})*/ + + Debug(tag string, args ...interface{}) + Debugf(ctx context.Context, tag string, format string, args ...interface{}) + + Info(tag string, args ...interface{}) + Infof(ctx context.Context, tag string, format string, args ...interface{}) + + Error(tag string, args ...interface{}) + Errorf(ctx context.Context, tag string, format string, args ...interface{}) + //Public(ctx context.Context, key string, pairs map[string]interface{}, isPLid bool) + + // ErrorCount :print error log and send count to monitor server if exist + // ctx : context.Context + // tag: key which to be counted by + //ErrorCount(ctx context.Context, metricName string, content string) + + // ErrorCountWithTags :print error log and send count to monitor server if exist + // ctx : context.Context + // tag: keys which to be counted by + //ErrorCountWithTags(ctx context.Context, metricName string, tags map[string]string, content string) +} + +type CountLogger struct { + log ILogger + count ICounter +} + +func SetCountLogger(logger ILogger, counter ICounter){ + Handler = NewCountLogger(logger, counter) +} + +func NewCountLogger(logger ILogger, counter ICounter) *CountLogger { + return &CountLogger{ + log: logger, + count: counter, + } +} + +func (c *CountLogger) Debug(tag string, args ...interface{}) { + c.log.Debug(tag, args) +} + +func (c *CountLogger) Debugf(ctx context.Context, tag string, format string, args ...interface{}) { + c.log.Debugf(ctx, tag, format, args) +} + +func (c *CountLogger) Info(tag string, args ...interface{}) { + c.log.Info(tag, args) +} + +func (c *CountLogger) Infof(ctx context.Context, tag string, format string, args ...interface{}) { + c.log.Infof(ctx, tag, format, args) +} + +func (c *CountLogger) Error(tag string, args ...interface{}) { + c.log.Error(tag, args) +} + +func (c *CountLogger) Errorf(ctx context.Context, tag string, format string, args ...interface{}) { + c.log.Errorf(ctx, tag, format, args) +} + +func (c *CountLogger) Public(ctx context.Context, key string, pairs map[string]interface{}, isPLid bool) { + //公司内部业务日志打印专用,可根据业务需要在继承struct中自行实现,也可忽略 +} + +// ErrorCount :print error log and send count to monitor server if exist +// ctx : context.Context +// tag: key which to be counted by +func (c *CountLogger) ErrorCount(ctx context.Context, metricName string, content string) { + path := c.FormatLogPath() + c.Errorf(ctx, metricName, "etype=%v||log_path=%v||error=%v", metricName, path, strings.Replace(content, "\n", "", -1)) + //按metricName上报错误统计,如果有就加,没有就省略吧。 + if c.count != nil { + c.count.Count(metricName) + } +} + +// ErrorCountWithTags :print error log and send count to monitor server if exist +// ctx : context.Context +// tag: keys which to be counted by +func (c *CountLogger) ErrorCountWithTags(ctx context.Context, metricName string, tags map[string]string, content string) { + path := c.FormatLogPath() + c.log.Errorf(ctx, metricName, "etype=%v||log_path=%v||error=%v", metricName, path, strings.Replace(content, "\n", "", -1)) + //按metricName上报错误统计,如果有就加,没有就省略吧。 + if c.count != nil { + c.count.CounterByTags(metricName, tags) + } +} + +func (c *CountLogger) FormatLogPath() string { + filename, line, path, ok, index := "", 0, "", false, 1 + for { + if index >= 10 { + break + } + _, filename, line, ok = runtime.Caller(index) + if ok { + filename = filepath.Base(filename) + } + if filename == "" { + break + } + index++ + if strings.Contains(filename, "autogenerated") || strings.Contains(filename, "asm_amd64") { + continue + } + if len(path) > 0 { + path = filename + ":" + fmt.Sprintf("%v", line) + "/" + path + } else { + path = filename + ":" + fmt.Sprintf("%v", line) + } + } + return path +} diff --git a/common/tlog/see_count_logger.go b/common/tlog/see_count_logger.go new file mode 100644 index 0000000000000000000000000000000000000000..ced3a529bed5967074609ff5933a8089c8bfa5f4 --- /dev/null +++ b/common/tlog/see_count_logger.go @@ -0,0 +1,50 @@ +/* + This is a sample class which show you how to implement the interface ICountLogger, and you can implement it by yourself +*/ +package tlog + +import ( + "context" + "github.com/cihub/seelog" + "log" +) + +type SeeCountLogger struct { + handler seelog.LoggerInterface + counter ICounter +} + +func InitCountLoggerFromSeelog(seeLogger seelog.LoggerInterface, counter ICounter) { + log.Println("tg-flow CountLogger init start...") + seeCountLogger := &SeeCountLogger{handler:seeLogger} + Handler = NewCountLogger(seeCountLogger,counter) + log.Println("tg-flow CountLogger init finished!!!") +} + +func (d *SeeCountLogger) Debug(tag string, args ...interface{}) { + d.handler.Debug(tag, args) +} + +func (d *SeeCountLogger) Debugf(ctx context.Context, tag string, format string, args ...interface{}) { + d.handler.Debugf(format, args) +} + +func (d *SeeCountLogger) Info(tag string, args ...interface{}) { + d.handler.Info(tag, args) +} + +func (d *SeeCountLogger) Infof(ctx context.Context, tag string, format string, args ...interface{}) { + d.handler.Infof(format, args) +} + +func (d *SeeCountLogger) Error(tag string, args ...interface{}) { + d.handler.Error(args) +} + +func (d *SeeCountLogger) Errorf(ctx context.Context, tag string, format string, args ...interface{}) { + d.handler.Errorf(format, args) +} + +func (d *SeeCountLogger) Public(ctx context.Context, key string, pairs map[string]interface{}, isPLid bool) { + // you can fullfill business log printer here +} diff --git a/common/utils/recover.go b/common/utils/recover.go new file mode 100644 index 0000000000000000000000000000000000000000..c7bd065f3d7613aba15486f2ba964d6b29943a21 --- /dev/null +++ b/common/utils/recover.go @@ -0,0 +1,13 @@ +package utils + +import ( + "context" + "fmt" + "github.com/didi/tg-flow/common/tlog" +) + +func Recover(ctx context.Context, tag string) { + if err := recover(); err != nil { + tlog.Handler.ErrorCount(ctx, tag, fmt.Sprintf("Recover system panic : %v", err)) + } +} diff --git a/conf/tlog.xml b/conf/tlog.xml new file mode 100644 index 0000000000000000000000000000000000000000..8befcde2dd4e77adbe2d7b40c5e5503a8999ffa8 --- /dev/null +++ b/conf/tlog.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/consts/global_c.go b/consts/global_c.go new file mode 100644 index 0000000000000000000000000000000000000000..1e642f116fcd9a6683d2af5a2531473ecc414b3f --- /dev/null +++ b/consts/global_c.go @@ -0,0 +1,7 @@ +package consts + +const ( + FLOW_BY_ONLINE_RANDOM = 0 + FLOW_BY_CUSTOM = 1 + FLOW_BY_APOLLO = 3 +) diff --git a/docs/app_add.png b/docs/app_add.png deleted file mode 100644 index e3757cbbb1461105425d04b7962f93ace43a0cc8..0000000000000000000000000000000000000000 Binary files a/docs/app_add.png and /dev/null differ diff --git a/docs/app_manage.png b/docs/app_manage.png deleted file mode 100644 index fd8070da2952cf7447be8dd32dfe81ecf51ab238..0000000000000000000000000000000000000000 Binary files a/docs/app_manage.png and /dev/null differ diff --git a/docs/app_update.png b/docs/app_update.png deleted file mode 100644 index ce98a196a5ac232b79e7299864f696204b460161..0000000000000000000000000000000000000000 Binary files a/docs/app_update.png and /dev/null differ diff --git a/docs/code_dir.png b/docs/code_dir.png deleted file mode 100644 index 43bb2b849a03c2d8dd663f9cba23afccf04947a4..0000000000000000000000000000000000000000 Binary files a/docs/code_dir.png and /dev/null differ diff --git a/docs/flow_edit.png b/docs/flow_edit.png deleted file mode 100644 index 031a053a890a8308d2481dd24a14e622dac472eb..0000000000000000000000000000000000000000 Binary files a/docs/flow_edit.png and /dev/null differ diff --git a/docs/flow_edit2.png b/docs/flow_edit2.png deleted file mode 100644 index 8224b7aa40b57f0d8f584208acf1976d38ee60ab..0000000000000000000000000000000000000000 Binary files a/docs/flow_edit2.png and /dev/null differ diff --git a/docs/flow_import.png b/docs/flow_import.png deleted file mode 100644 index ad9f14e9c2048886f0a333afb84cdd9ac78e02fe..0000000000000000000000000000000000000000 Binary files a/docs/flow_import.png and /dev/null differ diff --git a/docs/flow_manage.png b/docs/flow_manage.png deleted file mode 100644 index c256353a8463b9b942f492c18ec4fd7977ddeee4..0000000000000000000000000000000000000000 Binary files a/docs/flow_manage.png and /dev/null differ diff --git a/docs/git_reg.png b/docs/git_reg.png deleted file mode 100644 index 7cd0d6b5bce5661b9c87ad26bf3ee45b3eae2c2d..0000000000000000000000000000000000000000 Binary files a/docs/git_reg.png and /dev/null differ diff --git a/docs/login.png b/docs/login.png deleted file mode 100644 index 20d5caf9e4d4ee4f7d7053327496efe0029dae93..0000000000000000000000000000000000000000 Binary files a/docs/login.png and /dev/null differ diff --git a/docs/scene.png b/docs/scene.png deleted file mode 100644 index a7d41baef67c0404d648a6214b6f664694de2097..0000000000000000000000000000000000000000 Binary files a/docs/scene.png and /dev/null differ diff --git a/go.mod b/go.mod new file mode 100644 index 0000000000000000000000000000000000000000..b98193962bb5711652c105b18c91887f717bbede --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module github.com/didi/tg-flow + +go 1.21.5 + +require ( + github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 + github.com/robfig/cron v1.2.0 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000000000000000000000000000000000000..83f069f65a568b975f986d60adfef11501e4d113 --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 h1:kHaBemcxl8o/pQ5VM1c8PVE1PubbNx3mjUr09OqWGCs= +github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575/go.mod h1:9d6lWj8KzO/fd/NrVaLscBKmPigpZpn5YawRPw+e3Yo= +github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= +github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= diff --git a/tg-core/main.go b/main.go similarity index 60% rename from tg-core/main.go rename to main.go index a506432bea6f6c188b624f97a727b8567830e48f..b4a8546772fb102c5e0984dbf241ebfcdc404c10 100644 --- a/tg-core/main.go +++ b/main.go @@ -1,11 +1,15 @@ package main import ( + "encoding/json" "fmt" + "github.com/didi/tg-flow/wfengine" + "github.com/didi/tg-flow/wfengine/test" + "io/ioutil" ) -/*func main(){ - path := "/Users/didi/gopath/src/github.com/didi/tg-flow/tg-core/wfengine/workflow.json" +func main() { + path := "/Users/didi/gopath/src/github.com/didi/tg-flow/wfengine/workflow.json" flowStr, err := readStrFromFile(path) if err != nil { fmt.Println("flowStr,err", flowStr, err) @@ -20,7 +24,7 @@ import ( fmt.Println("fcm===============>", fmt.Sprintf("%+v", string(fcm))) action := getAction() - params :=make([]interface{}, 2) + params := make([]interface{}, 2) params[0] = 4.4 params[1] = "4.4" ce := wfengine.GetCondExecutors() @@ -87,7 +91,7 @@ func getInAction() *wfengine.Action { return action } -func readStrFromFile(path string) (string, error){ +func readStrFromFile(path string) (string, error) { f, err := ioutil.ReadFile(path) if err != nil { return "", err @@ -95,46 +99,46 @@ func readStrFromFile(path string) (string, error){ return string(f), nil } -*/ type Action struct { - ActionType string `json:"action_type"` - ActionId string `json:"action_id"` - ActionName string `json:"action_name"` - NextActionIds []string `json:"next_action_ids"` - NextConditions []string `json:"next_conditions"` - PrevActionIds []string `json:"prev_action_ids"` - Description string `json:"description"` + ActionType string `json:"action_type"` + ActionId string `json:"action_id"` + ActionName string `json:"action_name"` + NextActionIds []string `json:"next_action_ids"` + NextConditions []string `json:"next_conditions"` + PrevActionIds []string `json:"prev_action_ids"` + Description string `json:"description"` } -func main() { - - //创建和初始化数组 - //使用简写声明 - action1 := Action{ - ActionType: "action-1", - ActionId: "", - ActionName: "", - NextActionIds: nil, - NextConditions: nil, - PrevActionIds: []string{"aaa","bbb","ccc"}, - Description: "", - } - - action2 := Action{ - ActionType: "action-2", - ActionId: "", - ActionName: "", - NextActionIds: nil, - NextConditions: nil, - PrevActionIds: action1.PrevActionIds, - Description: "", - } - - fmt.Println("action1: ", action1) - fmt.Println("action2:", action2) - - action1.PrevActionIds = nil - fmt.Println("action11: ", action1) - fmt.Println("action22:", action2) -} \ No newline at end of file +// +//func main() { +// +// //创建和初始化数组 +// //使用简写声明 +// action1 := Action{ +// ActionType: "action-1", +// ActionId: "", +// ActionName: "", +// NextActionIds: nil, +// NextConditions: nil, +// PrevActionIds: []string{"aaa", "bbb", "ccc"}, +// Description: "", +// } +// +// action2 := Action{ +// ActionType: "action-2", +// ActionId: "", +// ActionName: "", +// NextActionIds: nil, +// NextConditions: nil, +// PrevActionIds: action1.PrevActionIds, +// Description: "", +// } +// +// fmt.Println("action1: ", action1) +// fmt.Println("action2:", action2) +// +// action1.PrevActionIds = nil +// fmt.Println("action11: ", action1) +// fmt.Println("action22:", action2) +//} diff --git a/tg-core/model/experiment.go b/model/experiment.go similarity index 100% rename from tg-core/model/experiment.go rename to model/experiment.go diff --git a/tg-core/model/strategy_context.go b/model/strategy_context.go similarity index 36% rename from tg-core/model/strategy_context.go rename to model/strategy_context.go index a3e8a36bf14083511524d956ad9d1883097c257a..b9d453c48040bea920662e04c820ab93b0c2a437 100644 --- a/tg-core/model/strategy_context.go +++ b/model/strategy_context.go @@ -10,7 +10,7 @@ import ( "context" "encoding/json" "errors" - trace "git.xiaojukeji.com/lego/context-go" + "github.com/didi/tg-flow/common/timeutils" "sync" ) @@ -18,115 +18,106 @@ const ( KEY_TIMEOUT_ACTION = "timeout_action" ) -type ModuleResultInfo struct { - Id string - StrategyName string - CostTime int64 - ResultInfo interface{} -} - type StrategyContext struct { - AppId int64 - AppName string - SceneId int64 - FlowId int64 - IsLimited bool - IsDebug bool - CtxTrace *trace.DefaultTrace + AppId int64 + AppName string + SceneId int64 + FlowId int64 + IsLimited bool + IsDebug bool + //CtxTrace *trace.DefaultTrace UserId string Phone string + GroupName string ContextMap *sync.Map ActionResultMap map[string]map[string]string contextMutex sync.Mutex - - moduleResultMap *sync.Map + TC *timeutils.TimeCoster errMap *sync.Map ErrNo int32 ErrMsg string skipFlag bool skipMutex sync.Mutex - - ApolloInfo *ApolloConfig } func NewStrategyContext(ctx context.Context) *StrategyContext { strategyContext := new(StrategyContext) strategyContext.ContextMap = &sync.Map{} strategyContext.ActionResultMap = make(map[string]map[string]string) - strategyContext.moduleResultMap = &sync.Map{} strategyContext.errMap = &sync.Map{} - if ctxTrace, ok := trace.GetCtxTrace(ctx); ok { - strategyContext.CtxTrace = ctxTrace - } else { - strategyContext.CtxTrace = trace.NewDefaultTrace() - } + strategyContext.TC = timeutils.NewTimeCosterUnit(timeutils.TimeUnitMillSecond) + //if ctxTrace, ok := trace.GetCtxTrace(ctx); ok { + // strategyContext.CtxTrace = ctxTrace + //} else { + // strategyContext.CtxTrace = trace.NewDefaultTrace() + //} return strategyContext } -func (this *StrategyContext) Set(key string, value interface{}) { - this.ContextMap.Store(key,value) +func (s *StrategyContext) Set(key string, value interface{}) { + s.ContextMap.Store(key, value) } -func (this *StrategyContext) SetDebug(actionName string, key string, value interface{}) { - if !this.IsDebug { +func (s *StrategyContext) SetDebug(actionName string, key string, value interface{}) { + if !s.IsDebug { return } - this.contextMutex.Lock() + s.contextMutex.Lock() var debugStr string if resultJson, err := json.Marshal(value); err == nil { debugStr = string(resultJson) } - if _, ok := this.ActionResultMap[actionName]; !ok { - this.ActionResultMap[actionName] = make(map[string]string) + if _, ok := s.ActionResultMap[actionName]; !ok { + s.ActionResultMap[actionName] = make(map[string]string) } - this.ActionResultMap[actionName][key] = debugStr - this.contextMutex.Unlock() + s.ActionResultMap[actionName][key] = debugStr + s.contextMutex.Unlock() } -func (this *StrategyContext) Get(key string) interface{} { - value, _ := this.ContextMap.Load(key) +func (s *StrategyContext) Get(key string) interface{} { + value, _ := s.ContextMap.Load(key) return value } -func (this *StrategyContext) Skip(errNo int32, errMsg string) { - this.skipMutex.Lock() - this.ErrNo = errNo - this.ErrMsg = errMsg - this.skipFlag = true - this.skipMutex.Unlock() +func (s *StrategyContext) Skip(errNo int32, errMsg string) { + s.skipMutex.Lock() + s.ErrNo = errNo + s.ErrMsg = errMsg + s.skipFlag = true + s.skipMutex.Unlock() } -func (this *StrategyContext) IsSkip() bool { - return this.skipFlag +func (s *StrategyContext) IsSkip() bool { + return s.skipFlag } -func (this *StrategyContext) AddToArray(arrayKey string, value interface{}) { +func (s *StrategyContext) AddToArray(arrayKey string, value interface{}) { var itArray []interface{} - if itr, ok := this.ContextMap.Load(arrayKey); ok { + if itr, ok := s.ContextMap.Load(arrayKey); ok { itArray = itr.([]interface{}) itArray = append(itArray, value) } else { itArray = make([]interface{}, 0, 10) itArray = append(itArray, value) } - this.ContextMap.Store(arrayKey, itArray) + s.ContextMap.Store(arrayKey, itArray) } -func (this *StrategyContext) GetArray(arrayKey string) ([]interface{}, error) { - if itf, ok := this.ContextMap.Load(arrayKey); ok { +func (s *StrategyContext) GetArray(arrayKey string) ([]interface{}, error) { + if itf, ok := s.ContextMap.Load(arrayKey); ok { return itf.([]interface{}), nil } return nil, errors.New("No such key:" + arrayKey) } -func (this *StrategyContext) AddTimeoutAction(actionName string) { - this.AddToArray(KEY_TIMEOUT_ACTION, actionName) +func (s *StrategyContext) AddTimeoutAction(actionName string) { + s.AddToArray(KEY_TIMEOUT_ACTION, actionName) } -func (this *StrategyContext) GetTimeoutActions() []string { - itf, err := this.GetArray(KEY_TIMEOUT_ACTION) - if err != nil || len(itf)==0 { +func (s *StrategyContext) GetTimeoutActions() []string { + itf, err := s.GetArray(KEY_TIMEOUT_ACTION) + if err != nil || len(itf) == 0 { return nil } @@ -137,25 +128,10 @@ func (this *StrategyContext) GetTimeoutActions() []string { return actionNames } -func (this *StrategyContext) SetModuleResult(actionId, actionName string, costTime int64, resultInfo interface{}) { - mri := &ModuleResultInfo{ - Id: actionId, - StrategyName: actionName, - CostTime: costTime, - ResultInfo: resultInfo, - } - - this.moduleResultMap.Store(actionId, mri) -} - -func (this *StrategyContext) GetModuleResultMap() *sync.Map { - return this.moduleResultMap -} - -func (this *StrategyContext) SetError(actionId string, err error) { - this.errMap.Store(actionId, err) +func (s *StrategyContext) SetError(actionId string, err error) { + s.errMap.Store(actionId, err) } -func (this *StrategyContext) GetErrorMap() *sync.Map { - return this.errMap +func (s *StrategyContext) GetErrorMap() *sync.Map { + return s.errMap } diff --git a/tg-core/README.md b/tg-core/README.md deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/tg-core/common/cache/dicache.go b/tg-core/common/cache/dicache.go deleted file mode 100644 index ea594810b530a1252188bb1f75751a3c7292264e..0000000000000000000000000000000000000000 --- a/tg-core/common/cache/dicache.go +++ /dev/null @@ -1,107 +0,0 @@ -/** -* function: local cache based on FreeCache -* Author : dayunzhangyunfeng@didiglobal.com -* Since : 2019-05-31 17:25:26 - */ - -package cache - -import ( - "context" - "fmt" - "git.xiaojukeji.com/nuwa/golibs/redis" - "github.com/coocood/freecache" -) - -const ( - LOCALCACHE_TTL = 1800 //unit:s -) - -type DiCache struct { - RedisCache *redis.Manager - Cache *freecache.Cache - Size int - TTL int -} - -func NewDiCache(redisCache *redis.Manager, size int, ttl int) *DiCache { - var freeCache = freecache.NewCache(size) - return &DiCache{ - RedisCache: redisCache, - Cache: freeCache, - Size: size, - TTL: ttl} -} - -func (this *DiCache) Get(ctx context.Context, key string) (string, error) { - vBytes, err := this.Cache.Get([]byte(key)) - if err == nil { - return string(vBytes), nil - } - - val, err := this.RedisCache.Get(ctx, key) - if err == nil { - this.Cache.Set([]byte(key), []byte(val), this.TTL) - } - - return val, err -} - -func (this *DiCache) GetMust(ctx context.Context, key, defaultValue string) string { - vBytes, err := this.Cache.Get([]byte(key)) - if err == nil { - return string(vBytes) - } - - val, err := this.RedisCache.Get(ctx, key) - if err == nil { - this.Cache.Set([]byte(key), []byte(val), this.TTL) - return val - } - - return defaultValue -} - -func (this *DiCache) MGet(ctx context.Context, keys []string) (map[string]string, error) { - valMap := make(map[string]string) - if keys == nil || len(keys) == 0 { - return valMap, nil - } - - notHitKeys := make([]string, 0, len(keys)) - for _, key := range keys { - vBytes, err := this.Cache.Get([]byte(key)) - if err == nil { - valMap[key] = string(vBytes) - } else { - notHitKeys = append(notHitKeys, key) - } - } - - notHitCount := len(notHitKeys) - if notHitCount == 0 { - return valMap, nil - } - - //不知道err不空时tempMap还是否可能有值,兜一下 - tempMap, err := this.RedisCache.MGet(ctx, notHitKeys) - if tempMap == nil || len(tempMap) == 0 { - return valMap, fmt.Errorf("redis keys not found all keys:%v, err:%v", notHitKeys, err) - } - - tempKeys := make([]string, 0, notHitCount) - for _, notHitKey := range notHitKeys { - if notHitVal, ok := tempMap[notHitKey]; ok { - valMap[notHitKey] = notHitVal - this.Cache.Set([]byte(notHitKey), []byte(notHitVal), this.TTL) - } else { - tempKeys = append(tempKeys, notHitKey) - } - } - - if len(tempKeys) > 0 { - err = fmt.Errorf("redis keys not found keys:%v", tempKeys) - } - - return valMap, err -} diff --git a/tg-core/common/crontask/new_register_task.go b/tg-core/common/crontask/new_register_task.go deleted file mode 100644 index a04b6afa2540f3c7bbcfe62bd57330ca19ed88a9..0000000000000000000000000000000000000000 --- a/tg-core/common/crontask/new_register_task.go +++ /dev/null @@ -1,35 +0,0 @@ -package crontask - -import ( - "context" - "github.com/didi/tg-flow/tg-core/common/tlog" - "github.com/didi/tg-flow/tg-core/consts" - "reflect" - "time" -) - -//定时任务接口 -type TaskInterface interface { - Run() -} - -/*********************参数含义*************** - task:定时任务结构体 - period:定时周期的单位:秒 - flag:是否在系统启动前启动定时任务 -*******************************************/ -func StartTask(task TaskInterface, period time.Duration, flag bool) { - ctx := context.TODO() - taskName := reflect.TypeOf(task).String() - - defer RecoverTaskRun(taskName, ctx) - if flag { //如果是需要在系统启动前启动定时任务,那么定时任务正式开始执行时间后延一个周期 - time.Sleep(period * time.Second) - } - - for { - tlog.Handler.Infof(ctx, consts.DLTagCronTask, "taskName=%v is start.", taskName) - task.Run() - time.Sleep(period * time.Second) - } -} diff --git a/tg-core/common/crontask/register_task.go b/tg-core/common/crontask/register_task.go deleted file mode 100644 index da80e06a1c88b72f16a022f6e5d3a475a666b7ac..0000000000000000000000000000000000000000 --- a/tg-core/common/crontask/register_task.go +++ /dev/null @@ -1,97 +0,0 @@ -package crontask - -import ( - "context" - "crypto/rand" - "fmt" - "github.com/didi/tg-flow/tg-core/common/tlog" - "github.com/didi/tg-flow/tg-core/consts" - "github.com/robfig/cron" - "math" - "math/big" - "reflect" - "strconv" - "strings" -// "time" -) - -//定时任务管理实例 -var CronTask *cron.Cron = cron.New() - -//定时任务管道 -var ChanMap map[string]chan interface{} = make(map[string]chan interface{}) - -/**注册定时任务 - taskTime:定时任务的周期 - job:具体的定时任务对象 - ch:job任务中的定时管道 - flag:是否随系统启动时,执行一次该任务 -**/ -func RegisterTask(taskTime string, job cron.Job, flag bool) { - //定时任务管道初始化 - name := reflect.TypeOf(job) - ChanMap[name.Name()] = make(chan interface{}, 1) - - //是否随系统启动执行 - if flag { - job.Run() - } - - //如果是秒以上的定时周期,则给一个随机的秒,以避免同台机器并发执行任务,给相应机器造成并发压力 - newTaskTime := "" - tempTimes := strings.Split(taskTime, " ") - if tempTimes[0] == "0" || tempTimes[0] == "*" { - for i := 1; i < len(tempTimes); i++ { - newTaskTime += " " + tempTimes[i] - } - newTaskTime = strconv.FormatInt(RangeRand(0, 59), 10) + newTaskTime -// time.Sleep(1 * time.Second) -// newTaskTime = strconv.Itoa(time.Now().Second()) + newTaskTime - } else { - newTaskTime = taskTime - } - - //注册任务 - CronTask.AddJob(newTaskTime, job) -} - -/** - 启动定时任务 -**/ -func TaskStart() { - defer recoverTaskStart() - CronTask.Start() -} - -//定时任务运行异常,捕获异常后,需要释放该任务的任务管道 -func RecoverTaskRun(taskName string, ctx context.Context) { - if err := recover(); err != nil { - content := fmt.Sprintf("taskName=%v", taskName) - tlog.LogError(ctx, nil, consts.DLTagCronTask, "crontask.recoverTaskRun", content, fmt.Errorf("%v", err)) - } -} - -//所有定时任务启动失败 -func recoverTaskStart() { - if err := recover(); err != nil { - tlog.LogError(context.TODO(), nil, consts.DLTagCronTask, "crontask.recoverTaskStart", "all task start fail", fmt.Errorf("%v", err)) - } -} - -// 生成区间[-m, n]的安全随机数 -func RangeRand(min, max int64) int64 { - if min > max { - panic("the min is greater than max!") - } - - if min < 0 { - f64Min := math.Abs(float64(min)) - i64Min := int64(f64Min) - result, _ := rand.Int(rand.Reader, big.NewInt(max+1+i64Min)) - - return result.Int64() - i64Min - } else { - result, _ := rand.Int(rand.Reader, big.NewInt(max-min+1)) - return min + result.Int64() - } -} diff --git a/tg-core/common/httpserv/init.go b/tg-core/common/httpserv/init.go deleted file mode 100644 index 2d183bacdf3a64e9593283278c419a22b88ad85c..0000000000000000000000000000000000000000 --- a/tg-core/common/httpserv/init.go +++ /dev/null @@ -1,41 +0,0 @@ -package httpserv - -import ( - "context" - "github.com/didi/tg-flow/tg-core/common/tlog" - "github.com/didi/tg-flow/tg-core/conf" - "github.com/didi/tg-flow/tg-core/router" - "git.xiaojukeji.com/nuwa/nuwa-go-httpclient" - ngs "git.xiaojukeji.com/nuwa/nuwa-go-httpserver/v2" - "log" - "time" -) - -var Handler ngs.HTTPServer - -func init() { - log.Println("tg-core httpserv init start...") - Handler = ngs.New(conf.Handler) - Handler.SetLogger(tlog.Handler) - Handler.SetRouter(router.Handler) - - Handler.RegisterOnShutdown(func() { - }) -} - -func SendHttpRequest(url string, timeOut int64, parmasMap interface{}) ([]byte, error) { - _, resp, err := httpclient.PostJSON(context.TODO(), url, parmasMap, httpclient.SetTimeout(time.Millisecond*time.Duration(timeOut))) - if err != nil { //重试2次 - for i := 0; i < 2; i++ { - _, resp, err = httpclient.PostJSON(context.TODO(), url, parmasMap, httpclient.SetTimeout(time.Millisecond*time.Duration(timeOut))) - if err == nil { - break - } - } - } - - if err != nil { - return nil, err - } - return resp, nil -} diff --git a/tg-core/common/ipaddrs/ips.go b/tg-core/common/ipaddrs/ips.go deleted file mode 100644 index 655b3349a7a7fbe806d42c17155c5201936da4f8..0000000000000000000000000000000000000000 --- a/tg-core/common/ipaddrs/ips.go +++ /dev/null @@ -1,84 +0,0 @@ -package ipaddrs - -import ( - "context" - "fmt" - "git.xiaojukeji.com/gobiz/utils" - "net" - "net/http" - "strings" -) - -//ZYF 以下从nuwa-go-httpserver/middleware/trace.go里面拷贝过来的,便于实现GetClientIp -type ctxKey struct { - name string -} - -var ( - // RequestTimeKey ... - RequestTimeKey = ctxKey{"requestTime"} - // TraceRecordKey ... - TraceRecordKey = ctxKey{"traceRecord"} - // ExtraInfoReqOut ... - ExtraInfoReqOut = ctxKey{"extraReqOut"} -) - -// TraceRecord ... -type TraceRecord struct { - TraceId string - SpanId string - HintCode string - HintContent string - URL string - Params string - Method string - Host string - From string - FormatString string -} -//ZYF 以上从nuwa-go-httpserver/middleware/trace.go里面拷贝过来的,便于实现GetClientIp,跟nuwa/trace/trace.go中的Trace定义高度相似,field是后者的子集. - -func GetLocalIp() (string, error) { - addrs, err := net.InterfaceAddrs() - if err != nil { - return "", err - } - for _, value := range addrs { - if ipnet, ok := value.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { - if ipnet.IP.To4() != nil { - return ipnet.IP.String(), nil - } - } - } - return "", fmt.Errorf("get local ip is fail,addrs is %v", addrs) -} - -func GetClientIp(ctx context.Context) string { - rec, ok := ctx.Value(TraceRecordKey).(TraceRecord) - var clientIp string - if ok { - clientIp = formatIp(rec.From) - } else { - clientIp = "0.0.0.0" - } - return clientIp -} - -func GetClientAddr(r *http.Request) string { - remoteAddr := utils.GetClientAddr(r) - return formatIp(remoteAddr) -} - -func formatIp(remoteAddr string) string { - if remoteAddr == "::1" { - return "127.0.0.1" - } - - strs := strings.Split(remoteAddr, ":") - if strs != nil && len(strs) > 0 { - remoteAddr = strs[0] - } - - return remoteAddr -} - diff --git a/tg-core/common/lock/lease_lock.go b/tg-core/common/lock/lease_lock.go deleted file mode 100644 index f4305e17a9dee67b6c94806a3e10b49efeaad6e4..0000000000000000000000000000000000000000 --- a/tg-core/common/lock/lease_lock.go +++ /dev/null @@ -1,9 +0,0 @@ -package lock - -type LeaseLock interface { - - RegisterLock(key string, value string) - - TryLock(key string) - -} \ No newline at end of file diff --git a/tg-core/common/lock/lock_message.go b/tg-core/common/lock/lock_message.go deleted file mode 100644 index eb5a5bcc2e970bb3258d46f979c52753a159948e..0000000000000000000000000000000000000000 --- a/tg-core/common/lock/lock_message.go +++ /dev/null @@ -1,55 +0,0 @@ -package lock -/** -* function: 锁信息 -* Author : dayunzhangyunfeng@didiglobal.com -* Since : 2019-11-25 19:50:00 -*/ -import ( - "sync/atomic" -) - -type LockMessage struct { - - Key string - - Value string - - ExpireTime int64 - - LockStatus int32 - - ChangeTimes int64 -} - -func NewLockMessage(key, value string) *LockMessage { - lockMessage := &LockMessage{} - lockMessage.Key = key - lockMessage.Value = value - return lockMessage -} - -func (this *LockMessage) GetKey() string { - return this.Key; -} - -func (this *LockMessage) GetValue() string { - return this.Value; -} - -func (this *LockMessage) SetNewStatus(newStatus int32) bool { - return atomic.CompareAndSwapInt32(&this.LockStatus, 1-newStatus, newStatus) -} - -/** - * 锁过期时间 - * 如果当前节点持有锁,则expireTime和redis中的锁过期时间保持一致 - * 如果当前节点不持有锁,则expireTime是当前节点最后一次获取到锁的过期时间 - */ -func (this *LockMessage) GetExpireTime() int64 { - return atomic.LoadInt64(&this.ExpireTime) -} - -func (this *LockMessage) SetExpireTime(expireTime int64) { - atomic.StoreInt64(&this.ExpireTime, expireTime) -} - \ No newline at end of file diff --git a/tg-core/common/lock/redis_lease_lock.go b/tg-core/common/lock/redis_lease_lock.go deleted file mode 100644 index f88ec2d1e24e56b0754b6237fd8726a439bfb57c..0000000000000000000000000000000000000000 --- a/tg-core/common/lock/redis_lease_lock.go +++ /dev/null @@ -1,133 +0,0 @@ -package lock -/** -* function: 租约锁 -* Author : dayunzhangyunfeng@didiglobal.com -* Since : 2019-11-25 19:50:00 -*/ -import ( - "fmt" - "time" - "github.com/didi/tg-flow/tg-core/common/redis" - "github.com/didi/tg-flow/tg-core/common/utils" - "github.com/didi/tg-flow/tg-core/consts" - "context" -) - - -const ( - DEFAULT_LEASE_EXPIRE_TIME = 20 - DEFAULT_LEASE_PERIOD = 2 -) - -type RedisLeaseLock struct { - LeaseLock - - LockMap map[string]*LockMessage - - LeaseExpireTime int64 // 过期时长(单位秒) - - LeasePeriod int64 // 间隔(单位秒) -} - -func NewRedisLeaseLock(leasePeriod int64, leaseExpireTime int64) (*RedisLeaseLock, error) { - rll := &RedisLeaseLock{} - // 租约过期时长 至少 是续租间隔的4倍,否则抛出异常 - if (leaseExpireTime <= leasePeriod * 4) { - return nil, fmt.Errorf("leaseExpireTime is too small, it must great than %v" , leasePeriod * 4) - } - - rll.LeasePeriod = leasePeriod - rll.LeaseExpireTime = leaseExpireTime - rll.LockMap = make(map[string]*LockMessage) - return rll, nil -} - -func (this *RedisLeaseLock) RegisterLock(key, value string) error { - if _, ok := this.LockMap[key]; ok { - return fmt.Errorf("register lease lock error, key is exist! key=", key); - } - - this.LockMap[key]= &LockMessage{ - Key : key, - Value : value, - ExpireTime : 0, - LockStatus : 0, - ChangeTimes : 0} - fmt.Println("register lease lock, key=" + key + ", value=" + value) - - // 注册时需要阻塞调用一次 - this.setLeaseLocks() - - go this.initTryLock(); - - return nil -} - -func (this *RedisLeaseLock) initTryLock() { - for { - time.Sleep(time.Duration(1) * time.Second) - this.setLeaseLocks() - } -} - -func (this *RedisLeaseLock) setLeaseLocks() { - for _, lockMessage :=range this.LockMap { - this.setLeaseLock(lockMessage) - } -} - -func (this *RedisLeaseLock) setLeaseLock(lockMessage *LockMessage) { - defer utils.Recover(context.TODO(), nil, consts.DLTagCronTask, "RedisLeaseLock.setLeaseLock") - // 锁已过期,尝试nx操作获取锁 - if time.Now().Unix() >= lockMessage.GetExpireTime() { - isOk, err := redis.Handler.SetNEx(context.TODO(), lockMessage.GetKey(), int(this.LeaseExpireTime), lockMessage.GetValue()) - if isOk == "OK" && err == nil { - lockMessage.SetExpireTime(time.Now().Unix() + this.LeaseExpireTime); - } else if isOk == "" { - // 如果NX不能获取锁,需要进一步确认此锁是否还属于自己 - // 如果属于自己,则取出当前锁的TTL赋给内存对象 - serverLockMessage, err := redis.Handler.GetString(context.TODO(), lockMessage.GetKey()) - if serverLockMessage != "" && err ==nil && serverLockMessage == lockMessage.GetValue() { - ttl, err := redis.Handler.TTL(context.TODO(), lockMessage.GetKey()) - if err == nil { - ttl64 := int64(ttl) - if ttl64 > this.LeasePeriod && err == nil { - lockMessage.SetExpireTime(time.Now().Unix() + ttl64) - } - } - } - } - } else { - // 锁还未过期,尝试expire - serverLockMessage, err := redis.Handler.GetString(context.TODO(), lockMessage.GetKey()) - if serverLockMessage == "" || serverLockMessage != lockMessage.GetValue() { - return; - } - - isOk, err := redis.Handler.Expire(context.TODO(), lockMessage.GetKey(), this.LeaseExpireTime) - if isOk == 1 && err == nil { - lockMessage.SetExpireTime(time.Now().Unix() + this.LeaseExpireTime); - } - } -} - -/** - 获取任务对应的锁 - 如果key不存在,抛异常 - 如果获取成功,则返回true - 如果获取失败,则返回false -**/ -func (this *RedisLeaseLock) TryLock(key string) bool { - lockMessage, ok := this.LockMap[key] - if !ok { - panic("not registered key:"+ key) - } - - if time.Now().Unix() < lockMessage.GetExpireTime() { - lockMessage.SetNewStatus(int32(1)) - return true - } else{ - lockMessage.SetNewStatus(int32(0)) - return false - } -} diff --git a/tg-core/common/metric/metric_service.go b/tg-core/common/metric/metric_service.go deleted file mode 100644 index 5801d92b39a14b357187628b67cdbf04d3ea64c5..0000000000000000000000000000000000000000 --- a/tg-core/common/metric/metric_service.go +++ /dev/null @@ -1,123 +0,0 @@ -/** - description: 统计结构上报工具 - 后续将删除或抽象为接口供外部实现 -**/ - -package metric - -import ( - "context" - "fmt" - "github.com/didi/tg-flow/tg-core/common/timeutils" - "github.com/didi/tg-flow/tg-core/common/tlog" - "github.com/didi/tg-flow/tg-core/consts" - statsd "go.intra.xiaojukeji.com/foundation/didi-standard-lib/metric/golang-v2/statsdlib" - "time" -) - -const ( - dlTagTimeCost = " time_cost_ms" - eTag = "time_cost_ms" -) - -/** - metricName:统计的名称 - source:数据来源 - metricType:统计的类型 -**/ -func SendMetric(startTime time.Time, metricName string, source string, metricType string) { - latency := time.Now().Sub(startTime) - statsd.RpcMetric(metricName, source, metricType, latency, "ok") -} - -/** - metricName:统计的名称 - caller: 调用方 - callee: 被调用方 - startTime: 开始计时时间内 - code: 调用结果, 取值 "ok" "0" "200" "201" "203"为成功、其他均为失败 -**/ -func RpcMetric(metricName string, caller string, callee string, startTime time.Time, code interface{}) { - latency := time.Now().Sub(startTime) - statsd.RpcMetric(metricName, caller, callee, latency, code) -} - -//打印各个策略节点耗时,并上报metrics -func PrintSectionTime(startTime time.Time, traceId string, tc *timeutils.TimeCoster, metricsName string, sceneId int64) { - tlog.Handler.Infof(context.TODO(), consts.DLTagControll, "etype=%v||%v||traceid=%v", eTag, tc.ToCountString(), traceId) - - //上报系统,包含所有场景,作为一个整体耗时给metrcis,便于配置报警策略 - go SendMetric(startTime, fmt.Sprintf("%v_total", metricsName), "all", "rt") - - //上报系统,分每个场景各自的耗时给metrcis,便于配置报警策略 - go SendMetric(startTime, fmt.Sprintf("%v_%v_total", metricsName, sceneId), "all", "rt") - - //系统内部各节点分段耗时上报metrics统计服务 - for key, useTime := range tc.GetAllCounts() { - go statsd.RpcMetric(fmt.Sprintf("%v_%v", metricsName, key), "all", "rt", time.Millisecond*time.Duration(useTime), "ok") - } -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -//上面是base库中老的metric封装, metricName由自己命名,无product和hintcode,将废弃 -//下面是按点架构新出的规范做的的metric封装,用于替换上线老的metric封装。 -//点架构metric规范: http://wiki.intra.xiaojukeji.com/pages/viewpage.action?pageId=609594742 -/////////////////////////////////////////////////////////////////////////////////////////////////// -func PrintAllMetrics(caller, callee string, sceneId int64, errCode, productId, hintCode string, traceId string, tc *timeutils.TimeCoster) { - latency := time.Now().Sub(tc.GetStartTime()) - tlog.Handler.Infof(context.TODO(), dlTagTimeCost, "etype=%v||%v||traceid=%v", eTag, tc.ToCountString(), traceId) - - //接口 - tags := getTagMap(productId, hintCode) - go SendRpcMetric("rpc_outer", caller, callee, latency, errCode, tags) - - //场景 - go SendRpcMetric("rpc_outer_scene", caller, fmt.Sprintf("scene_%v", sceneId), latency, errCode, nil) - - //节点 - for key, useTime := range tc.GetAllCounts() { - go SendRpcMetric("rpc_outer_section", caller, key, time.Millisecond*time.Duration(useTime), errCode, nil) - } -} - -/** - 标签,注意返回内容必须不为空 - */ -func getTagMap(productId, hintCode string) map[string]string { - tags := make(map[string]string) - if productId == "" { - productId = "unknown" - } - if hintCode == "" { - hintCode = "unknown" - } - tags["product"] = productId - tags["hintcode"] = hintCode - return tags -} -/** - 上报服务被调用的请求量、延时、错误率指标,打印耗时日志 -*/ -func PrintOuterMetric(caller, callee string, errCode, productId, hintCode string, traceId string, tc *timeutils.TimeCoster) { - latency := time.Now().Sub(tc.GetStartTime()) - tlog.Handler.Infof(context.TODO(), dlTagTimeCost, "etype=%v||%v||traceid=%v", eTag, tc.ToCountString(), traceId) - tags := getTagMap(productId, hintCode) - SendRpcMetric("rpc_outer", caller, callee, latency, errCode, tags) -} - -func SendRpcMetric(metricsName, caller, callee string, latency time.Duration, errCode string, tags map[string]string) { - if len(tags) > 0 { - statsd.RpcMetric(metricsName, caller, callee, latency, errCode, tags) - }else{ - statsd.RpcMetric(metricsName, caller, callee, latency, errCode) - } - -} - -/** -上报服务调用下游的请求量、延时、错误率指标 -*/ -func PrintAccessMetric(fun, callee string, latency time.Duration, errCode, productId, hintCode string) { - tags := getTagMap(productId, hintCode) - SendRpcMetric("rpc_access", fun, callee, latency, errCode, tags) -} diff --git a/tg-core/common/mysql/init.go b/tg-core/common/mysql/init.go deleted file mode 100644 index 138b977eaa5bee1b1471bb5bc33c6bd14c45ca98..0000000000000000000000000000000000000000 --- a/tg-core/common/mysql/init.go +++ /dev/null @@ -1,56 +0,0 @@ -package mysql - -import ( - "database/sql" - "log" - "time" - - "github.com/didi/tg-flow/tg-core/conf" - - "github.com/didi/gendry/manager" - _ "github.com/go-sql-driver/mysql" -) - -var Handler *sql.DB - -const ( - SECTION = "mysql" -) - -func InitMySqlHandler() { - log.Println("tg-core mysql init start...") - sec, err := conf.Handler.GetSection(SECTION) - if err != nil { - log.Fatal("MySQL init error: ", err) - } - host := sec.GetStringMust("host", "localhost") - port := sec.GetIntMust("port", 3306) - user := sec.GetStringMust("user", "root") - pwd := sec.GetStringMust("password", "") - charset := sec.GetStringMust("charset", "utf8") - dbName := sec.GetStringMust("db_name", "") - timeout := sec.GetIntMust("conn_timeout", 500) - readTimeout := sec.GetIntMust("read_timeout", 500) - writeTimeout := sec.GetIntMust("write_timeout", 500) - connMaxLifetime := sec.GetIntMust("conn_max_lifetime", 0) - maxIdleConns := sec.GetIntMust("max_idle_conns", 2) - maxOpenConns := sec.GetIntMust("max_open_conns", 2) - - Handler, err = manager.New(dbName, user, pwd, host). - Set( - manager.SetCharset(charset), - manager.SetTimeout(time.Duration(timeout)*time.Millisecond), - manager.SetReadTimeout(time.Duration(readTimeout)*time.Millisecond), - manager.SetWriteTimeout(time.Duration(writeTimeout)*time.Millisecond), - manager.SetParseTime(true), - manager.SetLoc("Local"), - ).Port(int(port)).Open(true) - if err != nil { - log.Fatal("Init mysql error: ", err) - } - - Handler.SetConnMaxLifetime(time.Duration(connMaxLifetime)) - Handler.SetMaxIdleConns(int(maxIdleConns)) - Handler.SetMaxOpenConns(int(maxOpenConns)) - log.Println("tg-core mysql init successful!") -} diff --git a/tg-core/common/redis/init.go b/tg-core/common/redis/init.go deleted file mode 100644 index 53127a9062ff038cb4d57f2adf72f26c17a0a922..0000000000000000000000000000000000000000 --- a/tg-core/common/redis/init.go +++ /dev/null @@ -1,235 +0,0 @@ -package redis - -import ( - "context" - "encoding/json" - "fmt" - "git.xiaojukeji.com/gobiz/config" - "git.xiaojukeji.com/nuwa/golibs/redis" - "github.com/didi/tg-flow/tg-core/common/tlog" - "github.com/didi/tg-flow/tg-core/conf" - "github.com/didi/tg-flow/tg-core/consts" - "github.com/didi/tg-flow/tg-core/model" - "log" - "strings" - "time" -) - -var Handler *redis.Manager -var FeatureRedisHandler *redis.Manager -var Handlers map[string]*redis.Manager - -const ( - SECTION = "redis" - FEATURE_REDIS_SECTION = "feature_redis" - ErrNil = "redigo: nil returned" - //notFindKey = "can not find key" -) - -func InitRedisHandlers(sections []string) { - if len(sections) <1 { - return - } - - handlers := make(map[string]*redis.Manager) - for _, section := range sections { - redisManager, err := NewManagerFromConf(conf.Handler, section) - if err != nil || redisManager == nil { - log.Fatal("Init redis client["+ section + "] error: ", err) - } - - handlers[section] = redisManager - //为兼容内置Handler,此处先特殊处理一下 - if section == SECTION { - Handler = redisManager - }else if section == FEATURE_REDIS_SECTION { - FeatureRedisHandler = redisManager - } - log.Println("Init redis client["+ section + "] successful !!!") - } - Handlers = handlers -} - -//redis.go支持的参数太少,包一下 -func NewManagerFromConf(cfg config.Configer, sec string, opt ...redis.Option) (*redis.Manager, error) { - var opts []redis.Option - addrs, err := cfg.GetSetting(sec, "addrs") - if err != nil { - return nil, err - } - - servers := strings.Split(addrs, ",") - auth, err := cfg.GetSetting(sec, "auth") - if err != nil { - return nil, err - } - disfEnable, _ := cfg.GetBoolSetting(sec, "disf_enable") - if disfEnable { - sn, err := cfg.GetSetting(sec, "service_name") - if err != nil { - return nil, err - } - opts = append(opts, redis.EnableDisf()) - opts = append(opts, redis.DisfServiceName(sn)) - } - - poolSize, err := cfg.GetIntSetting(sec, "pool_size") - if err == nil { - opts = append(opts, redis.SetPoolSize(poolSize)) - } - - maxConn, err := cfg.GetIntSetting(sec, "max_conn") - if err == nil { - opts = append(opts, redis.SetMaxConn(maxConn)) - } - - connTimeout, err := cfg.GetIntSetting(sec, "conn_timeout") - if err == nil { - opts = append(opts, redis.SetConnectTimeout(time.Millisecond*time.Duration(connTimeout))) - } - - readTimeout, err := cfg.GetIntSetting(sec, "read_timeout") - if err == nil { - opts = append(opts, redis.SetReadTimeout(time.Millisecond*time.Duration(readTimeout))) - } - - writeTimeout, err := cfg.GetIntSetting(sec, "write_timeout") - if err == nil { - opts = append(opts, redis.SetWriteTimeout(time.Millisecond*time.Duration(writeTimeout))) - } - - maxTryTimes, err := cfg.GetIntSetting(sec, "max_try_times") - if err == nil { - opts = append(opts, redis.SetMaxTryTimes(maxTryTimes)) - } - - opts = append(opts, opt...) - - return redis.NewManager(servers, auth, opts...) -} - -//TODO:write to redis -func WriteRedis(sc *model.StrategyContext, redisKey string, info interface{}, etype string) { - infoByte, err := json.Marshal(info) - if err != nil { - tlog.LogError(context.TODO(), sc, consts.DLTagFushion, fmt.Sprintf("%v.redis.jsonMarshal", etype), fmt.Sprintf("info=%v", info), err) - return - } - if _, err := Handler.Set(context.TODO(), redisKey, infoByte); err != nil { - tlog.LogError(context.TODO(), sc, consts.DLTagFushion, fmt.Sprintf("%v.redis.WriteRedis", etype), fmt.Sprintf("info=%v", info), err) - return - } -} - -//write to fusion -func SetFusion(ctx context.Context, sc *model.StrategyContext, redisKey string, info interface{}, etype string) { - infoByte, err := json.Marshal(info) - if err != nil { - tlog.LogError(ctx, sc, consts.DLTagFushion, fmt.Sprintf("%v.redis.jsonMarshal", etype), fmt.Sprintf("info=%v", info), err) - return - } - WriteFushion(ctx, sc, redisKey, infoByte, etype) -} - -func WriteFushion(ctx context.Context, sc *model.StrategyContext, redisKey string, info []byte, etype string) { - if _, err := Handler.Set(ctx, redisKey, info); err != nil { - tlog.LogError(ctx, sc, consts.DLTagFushion, fmt.Sprintf("%v.redis.WriteFushion", etype), fmt.Sprintf("info=%v", info), err) - } -} - -//write to fusion -func WriteFushionEx(ctx context.Context, sc *model.StrategyContext, redisKey string, info []byte, expireTime int, etype string) { - if _, err := Handler.SetEx(ctx, redisKey, expireTime, info); err != nil { - tlog.LogError(ctx, sc, consts.DLTagFushion, fmt.Sprintf("%v.redis.WriteFushionEx", etype), fmt.Sprintf("info=%v", info), err) - } -} - -//get from fusion -func GetFushion(ctx context.Context, sc *model.StrategyContext, redisKey string, etype string) string { - info, err := Handler.Get(ctx, redisKey) - if err != nil && err.Error() != ErrNil { - tlog.LogError(ctx, sc, consts.DLTagFushion, fmt.Sprintf("%v.redis.GetFushion", etype), fmt.Sprintf("info=%v", info), err) - return "" - } - return info -} - -func WToFusion(ctx context.Context, sc *model.StrategyContext, redisKey string, info interface{}, etype string) { - if _, err := Handler.Set(ctx, redisKey, info); err != nil { - tlog.LogError(ctx, sc, consts.DLTagFushion, fmt.Sprintf("%v.redis.WriteFushion", etype), fmt.Sprintf("info=%v", info), err) - } -} - -//write to fusion -func WToFusionEx(ctx context.Context, sc *model.StrategyContext, redisKey string, info interface{}, expireTime int, etype string) { - if _, err := Handler.SetEx(ctx, redisKey, expireTime, info); err != nil { - tlog.LogError(ctx, sc, consts.DLTagFushion, fmt.Sprintf("%v.redis.WriteFushionEx", etype), fmt.Sprintf("info=%v", info), err) - } -} - -//复制以上方法,新增一个redis.handle参数 -func HSetRedis(ctx context.Context, sc *model.StrategyContext, fusionHandler *redis.Manager, redisKey string, subKey string, info interface{}, etype string) { - infoByte, err := json.Marshal(info) - if err != nil { - tlog.LogError(ctx, sc, consts.DLTagFushion, fmt.Sprintf("%v.redis.HSetRedisMarshal", etype), fmt.Sprintf("info=%v", info), err) - return - } - if _, err = fusionHandler.HSet(ctx, redisKey, subKey, infoByte); err != nil { - tlog.LogError(ctx, sc, consts.DLTagFushion, fmt.Sprintf("%v.redis.HSetRedis", etype), fmt.Sprintf("info=%v", info), err) - } -} - -//write to fusion -func SetRedis(ctx context.Context, sc *model.StrategyContext, fusionHandler *redis.Manager, redisKey string, info interface{}, etype string) { - infoByte, err := json.Marshal(info) - if err != nil { - tlog.LogError(ctx, sc, consts.DLTagFushion, fmt.Sprintf("%v.redis.SetRedis", etype), fmt.Sprintf("info=%v", info), err) - return - } - WriteFushionByte(ctx, sc, fusionHandler, redisKey, infoByte, etype) -} - -func WriteFushionByte(ctx context.Context, sc *model.StrategyContext, fusionHandler *redis.Manager, redisKey string, info []byte, etype string) { - if _, err := fusionHandler.Set(ctx, redisKey, info); err != nil { - tlog.LogError(ctx, sc, consts.DLTagFushion, fmt.Sprintf("%v.redis.WriteFushionByte", etype), fmt.Sprintf("info=%v", info), err) - } -} - -func WriteFushionInterface(ctx context.Context, sc *model.StrategyContext, fusionHandler *redis.Manager, redisKey string, info interface{}, etype string) { - if _, err := fusionHandler.Set(ctx, redisKey, info); err != nil { - tlog.LogError(ctx, sc, consts.DLTagFushion, fmt.Sprintf("%v.redis.WriteFushionInterface", etype), fmt.Sprintf("info=%v", info), err) - } -} - -func SetRedisEx(ctx context.Context, sc *model.StrategyContext, fusionHandler *redis.Manager, redisKey string, info interface{}, expireTime int, etype string) { - infoByte, err := json.Marshal(info) - if err != nil { - tlog.LogError(ctx, sc, consts.DLTagFushion, fmt.Sprintf("%v.redis.SetRedisEx", etype), fmt.Sprintf("info=%v", info), err) - return - } - WriteFushionByteEx(ctx, sc, fusionHandler, redisKey, infoByte, expireTime, etype) -} - -//write to fusion -func WriteFushionByteEx(ctx context.Context, sc *model.StrategyContext, fusionHandler *redis.Manager, redisKey string, info []byte, expireTime int, etype string) { - if _, err := fusionHandler.SetEx(ctx, redisKey, expireTime, info); err != nil { - tlog.LogError(ctx, sc, consts.DLTagFushion, fmt.Sprintf("%v.redis.WriteFushionByteEx", etype), fmt.Sprintf("info=%v", info), err) - } -} - -//write to fusion -func WriteFushionInterfaceEx(ctx context.Context, sc *model.StrategyContext, fusionHandler *redis.Manager, redisKey string, info interface{}, expireTime int, etype string) { - if _, err := fusionHandler.SetEx(ctx, redisKey, expireTime, info); err != nil { - tlog.LogError(ctx, sc, consts.DLTagFushion, fmt.Sprintf("%v.redis.WriteFushionInterfaceEx", etype), fmt.Sprintf("info=%v", info), err) - } -} - -//get from fusion -func GetRedis(ctx context.Context, sc *model.StrategyContext, fusionHandler *redis.Manager, redisKey string, etype string) string { - info, err := fusionHandler.Get(ctx, redisKey) - if err != nil && err.Error() != ErrNil { - tlog.LogError(ctx, sc, consts.DLTagFushion, fmt.Sprintf("%v.redis.GetRedis", etype), fmt.Sprintf("info=%v", info), err) - return "" - } - return info -} diff --git a/tg-core/common/tlog/init.go b/tg-core/common/tlog/init.go deleted file mode 100644 index 37d2ecfc6133378cb1ec6e6a2115425d5e63c601..0000000000000000000000000000000000000000 --- a/tg-core/common/tlog/init.go +++ /dev/null @@ -1,227 +0,0 @@ -package tlog - -import ( - "context" - "fmt" - "github.com/didi/tg-flow/tg-core/conf" - "github.com/didi/tg-flow/tg-core/model" - "git.xiaojukeji.com/gobiz/logger" - trace "git.xiaojukeji.com/lego/context-go" - "log" - "path/filepath" - "runtime" - "strings" - statsd "go.intra.xiaojukeji.com/foundation/didi-standard-lib/metric/golang-v2/statsdlib" -) - -var Handler logger.Tracer - -const ( - DIDI_HINT_CODE = "1" // 压测 - DIDI_HINT_CODE_TEST = "2" // 线上巡检流量 -) - -func init() { - log.Println("tg-core tlog init start...") - var err error - Handler, err = logger.NewTracerWithConfig(conf.Handler) - if err != nil { - log.Fatal("Init log error: ", err) - } - - Handler.RegisterContextFormat(trace.FormatCtx) - logger.RegisterContextFormat(trace.FormatCtx) - - - err = logger.NewLoggerWithConfig(conf.Handler) - if err != nil { - log.Fatal("NewLoggerWithConfig Init log error: ", err) - } - initHintLog() -} - -// didi 日志跟压测日志分离,注册压测日志句柄&回调函数 -func initHintLog() { - enable, err := conf.Handler.GetBoolSetting("log", "hint_log.enable") - if err != nil || !enable { - return - } - - prefix, _ := conf.Handler.GetSetting("log","hint_log.prefix") - dir, _ := conf.Handler.GetSetting("log","hint_log.dir") - formatInfo, _ := conf.Handler.GetSetting("log","hint_log.format") - levelInfo, _ := conf.Handler.GetSetting("log","hint_log.level") - levelVal := getLogLevel(levelInfo) - async, _ := conf.Handler.GetBoolSetting("log","hint_log.async") - disableLink, _ := conf.Handler.GetBoolSetting("log","hint_log.disable_link") - autoClear, _ := conf.Handler.GetBoolSetting("log","hint_log.auto_clear") - clearHour, _ := conf.Handler.GetIntSetting("log","hint_log.clear_hours") - seprated, _ := conf.Handler.GetBoolSetting("log","hint_log.seprated") - - err = logger.NewShadowWithSetting( &logger.LogSetting{ - LogT: logger.LogTypeFile, - Enable: enable, - Prefix: prefix, - AsyncWrite: async, - Dir: dir, - DisableLink: disableLink, - Format: formatInfo, - Level: levelVal, - AutoClear: autoClear, - ClearHours: int32(clearHour), - Seprated: seprated, - RMode: logger.RotateModeHour, - }) - - // 设置压测识别回调函数,这里主要是从ctx 中识别出流量是否含有压测 - logger.RegisterGetShadowFromContext(GetShadowFromContext) -} - -// GetShadowFromContext ctx 中放的是lego/trace -func GetShadowFromContext(ctx context.Context) (ret bool) { - traceInfo := trace.GetTrace(ctx) - if traceInfo == nil { - return false - } - if traceInfo.GetHintCode() == DIDI_HINT_CODE || traceInfo.GetHintCode() == DIDI_HINT_CODE_TEST{ - return true - } - return false -} - - -func getLogLevel(l string) logger.Level { - switch strings.ToUpper(l) { - case "TRACE": - return logger.TRACE - case "DEBUG": - return logger.DEBUG - case "INFO": - return logger.INFO - case "WARNING": - return logger.WARNING - case "ERROR": - return logger.ERROR - case "FATAL": - return logger.FATAL - default: - return logger.ERROR - } -} - -/** - ctx: 请求上下文信息 - sc: 业务逻辑中间结果 - tag: 日志的标识,便于查找日志 - etype: 日志类型,主要包含日志所在的函数名,及唯一标识,便于odin监控分类统计 - content:日志内容 - err: 日志对应的错误信息,可为nil -**/ -func LogError(ctx context.Context, sc *model.StrategyContext, tag string, etype string, content string, err error) { - filename, line, path, ok, index := "", 0, "", false, 1 - for { - if index >= 10 { - break - } - _, filename, line, ok = runtime.Caller(index) - if ok { - filename = filepath.Base(filename) - } - if filename == "" { - break - } - index++ - if strings.Contains(filename, "autogenerated") || strings.Contains(filename, "asm_amd64") { - continue - } - if len(path) > 0 { - path = filename + ":" + fmt.Sprintf("%v", line) + "/" + path - } else { - path = filename + ":" + fmt.Sprintf("%v", line) - } - } - Handler.Errorf(ctx, tag, "etype=%v||log_path=%v||%v||error=%v", strings.Replace(etype, "\n", "", -1), path, strings.Replace(content, "\n", "", -1), err) -} - -/** - ctx: 请求上下文信息 - sc: 业务逻辑中间结果 - tag: 日志的标识,便于查找日志 - etype: 日志类型,主要包含日志所在的函数名,及唯一标识,便于odin监控分类统计 - content:日志内容 -**/ -func LogErrorInfo(ctx context.Context, sc *model.StrategyContext, tag string, etype string, content string) { - filename, line, path, ok, index := "", 0, "", false, 1 - for { - if index >= 10 { - break - } - _, filename, line, ok = runtime.Caller(index) - if ok { - filename = filepath.Base(filename) - } - if filename == "" { - break - } - index++ - if strings.Contains(filename, "autogenerated") || strings.Contains(filename, "asm_amd64") { - continue - } - if len(path) > 0 { - path = filename + ":" + fmt.Sprintf("%v", line) + "/" + path - } else { - path = filename + ":" + fmt.Sprintf("%v", line) - } - } - Handler.Errorf(ctx, tag, "etype=%v||log_path=%v||error=%v", strings.Replace(etype, "\n", "", -1), path, strings.Replace(content, "\n", "", -1)) - //上报error统计 - statsd.Counter(etype) -} - -/** - 打错误日志,并上报错误 - 后续将替代上面2个函数s - */ -func ErrorCount(ctx context.Context, metricName string, content string) { - path := FormatLogPath() - Handler.Errorf(ctx, " "+metricName, "etype=%v||log_path=%v||error=%v", metricName, path, strings.Replace(content, "\n", "", -1)) - //上报error统计 - statsd.Counter(metricName) -} - -/** - 打印错误日志,根据tags上报错误 - */ -func ErrorCountWithTags(ctx context.Context, metricName string, tags map[string]string, content string) { - path := FormatLogPath() - Handler.Errorf(ctx, " "+metricName, "etype=%v||log_path=%v||error=%v", metricName, path, strings.Replace(content, "\n", "", -1)) - //上报error统计 - statsd.Counter(metricName, tags) -} - - -func FormatLogPath() string { - filename, line, path, ok, index := "", 0, "", false, 1 - for { - if index >= 10 { - break - } - _, filename, line, ok = runtime.Caller(index) - if ok { - filename = filepath.Base(filename) - } - if filename == "" { - break - } - index++ - if strings.Contains(filename, "autogenerated") || strings.Contains(filename, "asm_amd64") { - continue - } - if len(path) > 0 { - path = filename + ":" + fmt.Sprintf("%v", line) + "/" + path - } else { - path = filename + ":" + fmt.Sprintf("%v", line) - } - } - return path -} \ No newline at end of file diff --git a/tg-core/common/utils/convert.go b/tg-core/common/utils/convert.go deleted file mode 100644 index f13534c850736ffaab06652000cce75fbf6d4dbe..0000000000000000000000000000000000000000 --- a/tg-core/common/utils/convert.go +++ /dev/null @@ -1,83 +0,0 @@ -package utils - -import "strconv" - -func Str2Int(s string) (int, error) { - i, err := strconv.Atoi(s) - if err != nil { - return 0, err - } - return i, nil -} - -func Str2IntMust(s string, defaultValue int) int { - i, err := strconv.Atoi(s) - if err != nil { - return defaultValue - } - return i -} - -func Str2Int32(s string) (int32, error) { - i64, err := strconv.ParseInt(s, 10, 32) - if err != nil { - return 0, err - } - return int32(i64), nil -} - -func Str2Int32Must(s string, defaultValue int32) int32 { - i64, err := strconv.ParseInt(s, 10, 32) - if err != nil { - return defaultValue - } - return int32(i64) -} - -func Str2Int64(s string) (int64, error) { - i64, err := strconv.ParseInt(s, 10, 64) - if err != nil { - return 0, err - } - return i64, nil -} - -func Str2Int64Must(s string, defaultValue int64) int64 { - i64, err := strconv.ParseInt(s, 10, 64) - if err != nil { - return defaultValue - } - return i64 -} - -func Str2Float32(s string) (float32, error) { - f32, err := strconv.ParseFloat(s, 32) - if err != nil { - return 0, err - } - return float32(f32), nil -} - -func Str2Float32Must(s string, defaultValue float32) float32 { - f32, err := strconv.ParseFloat(s, 32) - if err != nil { - return defaultValue - } - return float32(f32) -} - -func Str2Float64(s string) (float64, error) { - f64, err := strconv.ParseFloat(s, 64) - if err != nil { - return 0, err - } - return float64(f64), nil -} - -func Str2Float64Must(s string, defaultValue float64) float64 { - f64, err := strconv.ParseFloat(s, 64) - if err != nil { - return defaultValue - } - return float64(f64) -} \ No newline at end of file diff --git a/tg-core/common/utils/recover.go b/tg-core/common/utils/recover.go deleted file mode 100644 index 31197aea234a345ce022d2641eba426897f33b70..0000000000000000000000000000000000000000 --- a/tg-core/common/utils/recover.go +++ /dev/null @@ -1,37 +0,0 @@ -package utils - -import ( - "context" - "fmt" - "github.com/didi/tg-flow/tg-core/common/tlog" - "github.com/didi/tg-flow/tg-core/model" - "sync" -) -//////////////////////////以下都是带删除 -func Recover(ctx context.Context, sc *model.StrategyContext, tag string, subType string) { - if err := recover(); err != nil { - tlog.LogError(ctx, sc, tag, subType, "Recover system panic", fmt.Errorf("%v", err)) - } -} - -func RecoverThread(ctx context.Context, sc *model.StrategyContext, tag string, subType string, ch chan int) { - if err := recover(); err != nil { - tlog.LogError(ctx, sc, tag, subType, "RecoverThread system panic", fmt.Errorf("%v", err)) - ch <- 1 - } -} - -func RecoverThreadByWg(ctx context.Context, sc *model.StrategyContext, tag string, subType string, wg *sync.WaitGroup) { - if err := recover(); err != nil { - tlog.LogError(ctx, sc, tag, subType, "RecoverThreadByWg system panic", fmt.Errorf("%v", err)) - wg.Done() - } -} - -////////////////////////////////////以上都是待删除////////////////// - -func RecoverPanic(ctx context.Context, tag string) { - if err := recover(); err != nil { - tlog.ErrorCount(ctx, tag, fmt.Sprintf("Recover system panic : %v", err)) - } -} \ No newline at end of file diff --git a/tg-core/common/utils/stringsUtil.go b/tg-core/common/utils/stringsUtil.go deleted file mode 100644 index dc4a11dc98af511881a3d82b7a36f022ecf2e69e..0000000000000000000000000000000000000000 --- a/tg-core/common/utils/stringsUtil.go +++ /dev/null @@ -1,166 +0,0 @@ -package utils - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "strconv" - "crypto/md5" - "encoding/hex" - "time" - "strings" -) - -const ( - timeLayout = "2006-01-02 15:04:05" -) - -/** - 生成32位MD5 -**/ -func MD5(text string) string { - ctx := md5.New() - ctx.Write([]byte(text)) - return hex.EncodeToString(ctx.Sum(nil)) -} - -func GetCurrentTimeString() string { - return time.Now().Format(timeLayout) -} - -/** - 将原始的time格式转换成标准格式,如: - 原始格式:2020-08-17T14:36:31+08:00 ===> 转换后的标准格式 :2020-08-17 14:36:31 -**/ -func FormatDateTime(updateTime string) string { - length := len(updateTime) - if length > 19 { - updateTime = updateTime[:19] - } - - updateTime = strings.ReplaceAll(updateTime, "T", " ") - - return updateTime -} - -//截取字符串 start 起点下标 end 终点下标(不包括) -func SubStr(str string, start int, end int) (string, error) { - rs := []rune(str) - length := len(rs) - if start < 0 || start > length { - err := errors.New("SubStr start is wrong") - return "", err - } - if end < 0 || end > length { - err := errors.New("SubStr end is wrong.") - return "", err - } - return string(rs[start:end]), nil -} - -//将int64数组,转化为string字符串 -func Int64ArrayTOString(array []int64) string { - resultStr := "" - if array == nil || len(array) <= 0 { - return resultStr - } - for _, data := range array { - if len(resultStr) <= 0 { - resultStr += strconv.FormatInt(data, 10) - } else { - resultStr += "," + strconv.FormatInt(data, 10) - } - } - return resultStr -} - -//map[string]string,转化为string -func StringMapToString(strMap map[string]string) string { - resultStr := "" - if strMap == nil || len(strMap) <= 0 { - return resultStr - } - for key, value := range strMap { - if len(resultStr) <= 0 { - resultStr += key + ":" + value - } else { - resultStr += "," + key + ":" + value - } - } - return resultStr -} - -//map[int64]int64,转化为string -func Int64MapToString(int64Map map[int64]int64) string { - resultStr := "" - if int64Map == nil || len(int64Map) <= 0 { - return resultStr - } - for key, value := range int64Map { - if len(resultStr) <= 0 { - resultStr += strconv.FormatInt(key, 10) + ":" + strconv.FormatInt(value, 10) - } else { - resultStr += "," + strconv.FormatInt(key, 10) + ":" + strconv.FormatInt(value, 10) - } - } - return resultStr -} - -//map[int64]int,转化为string -func IntMapToString(intMap map[int64]int) string { - resultStr := "" - if intMap == nil || len(intMap) <= 0 { - return resultStr - } - for key, value := range intMap { - if len(resultStr) <= 0 { - resultStr += strconv.FormatInt(key, 10) + ":" + strconv.Itoa(value) - } else { - resultStr += "," + strconv.FormatInt(key, 10) + ":" + strconv.Itoa(value) - } - } - return resultStr -} - -//map[int64]map[string]float64,转化为string -func Float64MapToString(float64Map map[int64]map[string]float64) string { - resultStr := "" - if float64Map == nil || len(float64Map) <= 0 { - return resultStr - } - for key, hourMap := range float64Map { - hourStr := "" - if hourMap == nil || len(hourMap) <= 0 { - hourStr += "nil" - } else { - for hour, value := range hourMap { - if len(hourStr) <= 0 { - hourStr += hour + ":" + strconv.FormatFloat(value, 'f', -1, 64) - } else { - hourStr += "," + hour + ":" + strconv.FormatFloat(value, 'f', -1, 64) - } - } - } - hourStr = strconv.FormatInt(key, 10) + ":{" + hourStr + "}" - if len(resultStr) <= 0 { - resultStr += hourStr - } else { - resultStr += "," + hourStr - } - } - return resultStr -} - -func ToString(itr interface{}) string { - b, err := json.Marshal(itr) - if err != nil { - return fmt.Sprintf("%+v", itr) - } - var out bytes.Buffer - err = json.Indent(&out, b, "", " ") - if err != nil { - return fmt.Sprintf("%+v", itr) - } - return out.String() -} diff --git a/tg-core/conf/init.go b/tg-core/conf/init.go deleted file mode 100644 index 744f605e674a18c9e1fc67c11f514a8a41334cc0..0000000000000000000000000000000000000000 --- a/tg-core/conf/init.go +++ /dev/null @@ -1,105 +0,0 @@ -package conf - -import ( - "git.xiaojukeji.com/gobiz/config" - "github.com/didi/tg-flow/tg-core/common/path" - "git.xiaojukeji.com/nuwa/go-monitor" - "go.intra.xiaojukeji.com/platform-ha/onekey-degrade_sdk_go/degrade" - "log" - _ "net/http/pprof" -) - -var Handler config.Configer - -//center服务url地址 -var CENTER_URL string -var CENTER_HTTP_TIMEOUT int64 - -//911限流预案名称 -var RateLimitName string - -//911降级预案名称 -var DownGradeName string - -//系统运行环境:正式、预发、线下 -var ENV string - -func init() { - log.Println("tg-core conf init start, path.Root=" + path.Root) - var err error - Handler, err = config.New(path.Root + "/conf/app.conf") - if err != nil { - log.Println("Configer init error:", err, "(本地环境及单元测试可忽略该错误)") - // 适配读取配置文件 解决本地单元测试中无法正确读取配置路径的问题 - /*Handler, err = config.New(path.ConfLocal + "/conf/app.conf") - if err != nil { - log.Fatal("读取本地配置失败 =>", path.ConfLocal) - }*/ - } - - initRateLimitName() - - initDownGradeName() - - initEnv() - - nuwaMonitor() -} - -//初始化系统911限流预案名称 -func initRateLimitName() { - var err error - if RateLimitName, err = Handler.GetSetting("ratelimit", "name"); err != nil { - log.Println("Fail to get ratelimit name!", err) - return - } -} - -//初始化系统911降级预案名称 -func initDownGradeName() { - var downGradeName string - var err error - //获取降级预案配置 - if downGradeName, err = Handler.GetSetting("downgrade", "name"); err != nil { - log.Println("Fail to get downgrade name!", err) - return - } else { - DownGradeName = downGradeName - } - - //初始化911sdk - configMeta := degrade.NewConfigMeta() - configMeta.Add(DownGradeName, degrade.SWITCH_CONFIG) - if err := degrade.Init(configMeta); err != nil { - log.Println("Fail to init 911 sdk!", err) - return - } -} - -//性能监控 -func nuwaMonitor() { - var isopen bool - var port string - var err error - log.Println("tg-core nuwaMonitor init start...") - if isopen, err = Handler.GetBoolSetting("pprof", "isopen"); err != nil { - log.Println("Fail to get nuwaMonitor isopen config!", err) - return - } - if port, err = Handler.GetSetting("pprof", "port"); err != nil { - log.Println("Fail to get nuwaMonitor port config!", err) - return - } - if isopen { - go monitor.Start(":"+port, monitor.AllPlugin) - } -} - -//初始化系统运行环境变量 -func initEnv() { - var err error - if ENV, err = Handler.GetSetting("env", "name"); err != nil { - return - } - log.Println("tg-core env init end") -} diff --git a/tg-core/consts/dltag.go b/tg-core/consts/dltag.go deleted file mode 100644 index beec5b3be05edeaf18a649875a22d7bdc7a8df17..0000000000000000000000000000000000000000 --- a/tg-core/consts/dltag.go +++ /dev/null @@ -1,27 +0,0 @@ -package consts - -const ( - DLTagSystemPanic = " _com_strategybase_system_panic" - DLTagControll = " _com_strategy_controll" - DLTagDispatcher = " _com_strategybase_dispatcher" - DLTagDispatcherPanic = " _com_strategybase_dispatcher_panic" - DLTagDispatcherFail = " _com_strategybase_dispatcher_fail" - DLTagRanker = " _com_strategybase_ranker" - DLTagCronTask = " _com_strategybase_cron_task" - DLTagFushion = " _com_strategybase_fushion" - DLTagLocalCache = " _com_strategybase_localcache" - DLTagLocalCacheFail = " _com_strategybase_localcache_fail" - DLTagOdin = " _com_strategybase_odin" - DLTagModuleInitStore = " _com_strategybase_module_init_store" - DLTagUfsClientInit = " _com_strategybase_ufs_client_init" - DLTagDfsClientInit = " _com_strategybase_dfs_client_init" - DLTagUserCenterClientInit = " _com_strategybase_usercenter_client_init" - DLTagRankerClientInit = " _com_strategybase_ranker_client_init" - DLTagDufeClientInit = " _com_strategybase_dufe_client_init" - - //要执行的维度类型集合 - DISPATCHERDIMENSION = "dispatcher_dimension" - - //要执行的维度名称 - DIMENSION_CITY = "city" -) diff --git a/tg-core/consts/genrec_config_c.go b/tg-core/consts/genrec_config_c.go deleted file mode 100644 index 8eb61870874cba58ed9c4650f36119ba7fa978ce..0000000000000000000000000000000000000000 --- a/tg-core/consts/genrec_config_c.go +++ /dev/null @@ -1,19 +0,0 @@ -package consts - -const ( - FEATURE_KEY_ITEM = "feature_key_item" - FEATURE_KEY_USER = "feature_key_user" - FEATURE_KEY_CONTEXT = "feature_key_context" - FEATURE_KEY_CONTEXTEXT = "feature_key_contextext" - FEATURE_KEY_USERTYPE = "feature_key_usertype" - FEATURE_KEY_CROSS = "feature_key_cross" - FEATURE_KEY_EVENTATTRS = "feature_key_eventAttrs" - FEATURE_KEY_EVENTIDS = "feature_key_eventIds" - FEATURE_KEY_BURYDATA = "feature_key_buryData" - FEATURE_KEY_FEATUREOPERATION = "feature_key_featureOperation" - - //fusion中的key - REC_SCENE_CONFIG = "rec_scene_config" - REC_SCENE_ITEM = "rec_scene_item" - BUSINESS_GROUP = "rec_business_group" -) diff --git a/tg-core/consts/global_c.go b/tg-core/consts/global_c.go deleted file mode 100644 index 45851d6d55df7c483592ab7e27a42d405ff198b7..0000000000000000000000000000000000000000 --- a/tg-core/consts/global_c.go +++ /dev/null @@ -1,32 +0,0 @@ -package consts - -import () - -const ( - FEATURE_VALUE_DEFAULT_FLOAT = -1 //TODO 全部工程用NUMBER替换后删除 - - FEATURE_VALUE_NEGATIVE_ONE = "-1" //TODO 全部工程用STRING替换后删除 - - FEATURE_VALUE_DEFAULT_NUMBER = -1 - - FEATURE_VALUE_DEFAULT_STRING = "-1" - - LOCALCACHE_TTL = 1800 //unit:s - - USER_LOCALCACHE_TTL = 3600 //unit:s - - FLOW_BY_ONLINE_RANDOM = 0 //在线随机分流 - FLOW_BY_ONLINE_SALT = 1 //在线salt分流 - FLOW_BY_OFFLINE = 2 //离线分流 - FLOW_BY_APOLLO = 3 //apollo分流 - - DefaultWorkflowVersion = "1.0" - - //strategycontext中set的key常量 - RANKER_IP = "ranker_ip" - -) - -//fusion中按在线salt分流和离线分流数据的表名 -var SALT_ONLINE_KEY string -var OFFLINE_KEY string diff --git a/tg-core/consts/ranker_config_status.go b/tg-core/consts/ranker_config_status.go deleted file mode 100644 index 2cdb95da26e03790e95a2226e396eaab12a60dcd..0000000000000000000000000000000000000000 --- a/tg-core/consts/ranker_config_status.go +++ /dev/null @@ -1,15 +0,0 @@ -package consts - -const ( - RANKER_STATUS_UNKNOWN = -1 //未知 - RANKER_STATUS_TOONLINE = 1 //模型待上线 - RANKER_STATUS_ONLINE_FAIL = 2 //模型上线失败 - RANKER_STATUS_ONLINE = 3 //模型上线成功 -) - -/** -1. 新增配置时,scene_id、algo_name、model_name(以后简称sam)均不许为空,初始状态统一为status=1 -2. 更新配置时,sam改为非空的sam,则状态置为模型待加载;sam改为空的sam,则状态置为模型加载成功; -3. 删除配置时,必须满足当前状态为空闲时才允许删除(当ranker发现过期模型卸载成功且sam均为空时,会将状态置为空闲) -4. 更新配置时,不允许更新ip字段,如果要删除该ip对应的记录,需要先使之为空闲状态 -**/ \ No newline at end of file diff --git a/tg-core/consts/redis_keys.go b/tg-core/consts/redis_keys.go deleted file mode 100644 index 64ffb74898c3d933ee7d783664bf7d516f146f12..0000000000000000000000000000000000000000 --- a/tg-core/consts/redis_keys.go +++ /dev/null @@ -1,29 +0,0 @@ -package consts - -import () - -/** - 策略服务公用业务相关的key,一律以"strategy_"作为前缀 -**/ -const ( - //TODO ZYF待删除 - StrategySceneAndModuleMap = "strategy_sceneAndModule_map" - StrategyWorkflowMap = "strategy_workflow_map" - StrategyDimensionMap = "strategy_dimension_map" - - //算法模型索引key - RedisKeyAlgoModelConfig = "strategy_algo_model_config" - RedisKeyRankerConfigMap = "strategy_rediskey_ranker_config_map" - - //机器ip - RedisKeyMachineIp = "rediskey_machine_ip" - - //systemConfig信息 - RedisKeySystemConf = "strategy_system_conf" - - //特征数据类型前缀 - FeatureDataType = "feature_data_type_scene_%v" - - //召回配置 - RedisKeyRecallConfig = "strategy_recall_config" -) diff --git a/tg-core/dispatcher/base_dispatcher.go b/tg-core/dispatcher/base_dispatcher.go deleted file mode 100644 index a33142c7fe887961da63f4265aa2d9f133697d3d..0000000000000000000000000000000000000000 --- a/tg-core/dispatcher/base_dispatcher.go +++ /dev/null @@ -1,196 +0,0 @@ -/** -Description : dispatcher of workflow engine -Author: dayunzhangyunfeng@didiglobal.com -Date: 2021-07-20 -*/ -package dispatcher - -import ( - "context" - "fmt" - trace "git.xiaojukeji.com/lego/context-go" - "github.com/didi/tg-flow/tg-core/common/timeutils" - "github.com/didi/tg-flow/tg-core/common/tlog" - "github.com/didi/tg-flow/tg-core/common/utils" - "github.com/didi/tg-flow/tg-core/model" - "github.com/didi/tg-flow/tg-core/wfengine" - "sync" -) - -type Dispatcher interface { - BuildRequest(ctx context.Context, requestParam interface{}) *model.StrategyContext - BuildResponse(sc *model.StrategyContext) interface{} - WriteLog(ctx context.Context, sc *model.StrategyContext) map[string]interface{} - GetWorkflowEngine() *wfengine.WorkflowEngine - GetPublicKey() string - GetInterfaceName() string -} - -func getInterfaceErrorTag(interfaceName string) string { - return interfaceName + "_err" -} - -/**最新逻辑 - moduleName:业务模块名称 - systemName:系统名称 - tags:public日志类型标记 -*/ -func DoStrategy(ctx context.Context, requestParam interface{}, d Dispatcher, tc *timeutils.TimeCoster) (interface{}, *model.StrategyContext) { - errTag := getInterfaceErrorTag(d.GetInterfaceName()) - defer utils.RecoverPanic(ctx, errTag) - - //1、请求参数解析 - tc.StartSectionCount("BuildRequest") - sc := d.BuildRequest(ctx, requestParam) - tc.StopSectionCount("BuildRequest") - - //2. 执行业务逻辑 - d.GetWorkflowEngine().Run(ctx, sc) - errMap := sc.GetErrorMap() - errMap.Range(func(key, val interface{}) bool { - tlog.ErrorCount(ctx, "WorkflowEngine.Run_err", fmt.Sprintf("workflowengine run error, key=%v, val=%v", key, val)) - return true - }) - - //3. 耗时 - resultMap := sc.GetModuleResultMap() - resultMap.Range(func(key, val interface{}) bool { - moduleResult, ok := val.(*model.ModuleResultInfo) - if ok && moduleResult != nil { - tc.SetSectionCount(moduleResult.StrategyName, moduleResult.CostTime) - return true - } - return false - }) - - //3、组装返回结果 - tc.StartSectionCount("BuildResponse") - responseInfo := d.BuildResponse(sc) - tc.StopSectionCount("BuildResponse") - - //4、异步日志 - go writeLog(ctx, sc, d, errTag) - - return responseInfo, sc -} - -// DoStrategyBatch 批量执行 Workflow 的接口,根据 requestParam 批量执行多次 Workflow,并将结果返回,返回结果的数量总是和请求的数量相同。 -func DoStrategyBatch(ctx context.Context, requestParams []interface{}, d Dispatcher) ([]interface{}, []*model.StrategyContext, []*timeutils.TimeCoster) { - errTag := getInterfaceErrorTag(d.GetInterfaceName()) - defer utils.RecoverPanic(ctx, errTag) - - responseInfos := make([]interface{}, len(requestParams)) - scs := make([]*model.StrategyContext, len(requestParams)) - tcs := make([]*timeutils.TimeCoster, len(requestParams)) - - wg := sync.WaitGroup{} - wg.Add(len(requestParams)) - - for i, req := range requestParams { - - tcs[i] = timeutils.NewTimeCoster() - - go func(curIdx int, curReq interface{}) { - - tc := tcs[curIdx] - tc.StartCount() - - defer func() { - - if err := recover(); err != nil { - tlog.ErrorCount(ctx, errTag, fmt.Sprintf("Recover system panic : %v", err)) - // 如果某个出现 panic,停止计时 - for section := range tc.GetAllCounts() { - tc.StopSectionCount(section) - } - } else { - tc.StopCount() - } - - wg.Done() - - }() - - //1、请求参数解析 - tc.StartSectionCount("BuildRequest") - sc := d.BuildRequest(ctx, curReq) - tc.StopSectionCount("BuildRequest") - - //2. 执行业务逻辑 - d.GetWorkflowEngine().Run(ctx, sc) - errMap := sc.GetErrorMap() - errMap.Range(func(key, val interface{}) bool { - tlog.ErrorCount(ctx, "WorkflowEngine.BatchRun_err", fmt.Sprintf("workflowengine batch run error, key=%v, val=%v, reqNum=%v", key, val, curIdx)) - return true - }) - - //3. 耗时 - resultMap := sc.GetModuleResultMap() - resultMap.Range(func(key, val interface{}) bool { - moduleResult, ok := val.(*model.ModuleResultInfo) - if ok && moduleResult != nil { - tc.SetSectionCount(moduleResult.StrategyName, moduleResult.CostTime) - return true - } - return false - }) - - //3、组装返回结果 - tc.StartSectionCount("BuildResponse") - responseInfo := d.BuildResponse(sc) - tc.StopSectionCount("BuildResponse") - - //4、异步日志,每个请求单独打日志 - go writeLog(ctx, sc, d, errTag) - - responseInfos[curIdx] = responseInfo - scs[curIdx] = sc - - }(i, req) - } - - wg.Wait() - - return responseInfos, scs, tcs -} - -func GetCtxTrace(ctx context.Context) *trace.DefaultTrace { - if ctxTrace, ok := trace.GetCtxTrace(ctx); ok { - return ctxTrace - } else { - return trace.NewDefaultTrace() - } -} - -/****************************************************记录public日志时,调用该方法 - ctx: 上下文环境 - sc: base框架中存放的临时数据,可以传nil - publicKey: 数据采集平台的唯一表名( 建议保持格式: g_系统名_服务接口名 ) - d: base框架中的处理流程的结构体,不同系统都实现base中这个结构体内的方法 - tagName: 数据采集平台的唯一标识( 建议保持格式: 系统名_服务接口名, 注:本标识 全部大写 ) -*************************************************************************************/ -func writeLog(ctx context.Context, sc *model.StrategyContext, d Dispatcher, tagName string) { - defer utils.RecoverPanic(ctx, tagName) - params := d.WriteLog(ctx, sc) - if params == nil { - return - } - - //公有日志信息 - params["uid"] = sc.UserId - params["scene_id"] = sc.SceneId - params["is_rateLimit"] = sc.IsLimited - params["workflow_id"] = sc.FlowId - - mergeLog(params) - tlog.Handler.Public(ctx, d.GetPublicKey(), params, false) -} - -//将要记录到日志中的内容,再做一次非nil的过滤 -func mergeLog(pairs map[string]interface{}) { - for k, v := range pairs { - if v == nil { - pairs[k] = "NULL" - } - } -} diff --git a/tg-core/dispatcher/public_log.go b/tg-core/dispatcher/public_log.go deleted file mode 100644 index b8c83ef102c370bfe0026ec8ef8d8296a21f5099..0000000000000000000000000000000000000000 --- a/tg-core/dispatcher/public_log.go +++ /dev/null @@ -1,29 +0,0 @@ -package dispatcher - -import ( - "context" - "fmt" - "git.xiaojukeji.com/gobiz/logger" - ctxtrace "git.xiaojukeji.com/lego/context-go" - "github.com/didi/tg-flow/tg-core/common/utils" - "strings" - "time" -) - -func WriteCustomLog(ctx context.Context, publicKey string, filePrefix string, pairs map[string]interface{}, tagName string) { - defer utils.RecoverPanic(ctx, tagName) - mergeLog(pairs) - var kvs []string - kvs = append(kvs, publicKey) - kvs = append(kvs, "timestamp="+time.Now().Format("2006-01-02 15:04:05")) - kvs = append(kvs, ctxtrace.FormatCtx(ctx)) - for k, v := range pairs { - if v == nil { - v = "NULL" - } - kvs = append(kvs, k+"="+fmt.Sprint(v)) - } - //记本地日志 - logger.Track(filePrefix, strings.Join(kvs, "||")) -} - diff --git a/tg-core/go.mod b/tg-core/go.mod deleted file mode 100644 index a68ba4ecda8b5bee85cd8b030be15ba93a53fd4a..0000000000000000000000000000000000000000 --- a/tg-core/go.mod +++ /dev/null @@ -1,36 +0,0 @@ -module github.com/didi/tg-flow/tg-core - -go 1.14 - -require ( - git.apache.org/thrift.git v0.0.0-20151001171628-53dd39833a08 - git.xiaojukeji.com/foundation/thrift v0.9.3 - git.xiaojukeji.com/gobiz/cache v1.0.2 - git.xiaojukeji.com/gobiz/config v0.0.7 - git.xiaojukeji.com/gobiz/logger v1.4.7 - git.xiaojukeji.com/gobiz/utils v1.0.1 - git.xiaojukeji.com/lego/context-go v3.0.4+incompatible - git.xiaojukeji.com/lego/dirpc-go v1.16.24 - git.xiaojukeji.com/nuwa/go-monitor v1.1.5 - git.xiaojukeji.com/nuwa/golibs/redis v0.4.14 - git.xiaojukeji.com/nuwa/nuwa-go-httpclient v1.3.14 - git.xiaojukeji.com/nuwa/nuwa-go-httpserver/v2 v2.8.11 - git.xiaojukeji.com/nuwa/trace/v2 v2.0.7 // indirect - github.com/coocood/freecache v1.1.1 - github.com/didi/gendry v1.7.0 - github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c // indirect - github.com/facebookgo/freeport v0.0.0-20150612182905-d4adf43b75b9 // indirect - github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect - github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 // indirect - github.com/go-sql-driver/mysql v1.6.0 - github.com/golang/protobuf v1.5.2 - github.com/gomodule/redigo/redis v0.0.1 // indirect - github.com/robfig/cron v1.2.0 - go.intra.xiaojukeji.com/apollo/apollo-golang-sdk-v2 v2.7.7+incompatible - go.intra.xiaojukeji.com/foundation/didi-standard-lib v0.0.0-20201123053335-e67edadc52bf - go.intra.xiaojukeji.com/platform-ha/onekey-degrade_sdk_go v3.2.8+incompatible - golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect - golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 // indirect - google.golang.org/genproto v0.0.0-20210617175327-b9e0b3197ced // indirect - gopkg.in/go-playground/assert.v1 v1.2.1 // indirect -) diff --git a/tg-core/go.sum b/tg-core/go.sum deleted file mode 100644 index 2ba3b34406ff90f93da0affe266d4a4eef609870..0000000000000000000000000000000000000000 --- a/tg-core/go.sum +++ /dev/null @@ -1,683 +0,0 @@ -bou.ke/monkey v1.0.2 h1:kWcnsrCNUatbxncxR/ThdYqbytgOIArtYWqcQLQzKLI= -bou.ke/monkey v1.0.2/go.mod h1:OqickVX3tNx6t33n1xvtTtu85YN5s6cKwVug+oHMaIA= -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -git.apache.org/thrift.git v0.0.0-20151001171628-53dd39833a08 h1:goxS3HZARSCj217iYEtwVahA/7WJ9MbZR2QJMeMDmxM= -git.apache.org/thrift.git v0.0.0-20151001171628-53dd39833a08/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= -git.xiaojukeji.com/devops/statsd v0.0.10/go.mod h1:VwNi66bpKq2QSqq8xYHEhl1QVkaKWRqH9nXUPbRnMhM= -git.xiaojukeji.com/devops/statsd v0.0.13 h1:sdZPslY/C6bVEHQuqomgVNkbuuAfQfM4Zwsa0gwXA2c= -git.xiaojukeji.com/devops/statsd v0.0.13/go.mod h1:F9Q3cQhEZpMV+4iElWE6Oth6CW0Rk3bxMy6UbQhiHMA= -git.xiaojukeji.com/disf/disf-go-spl-v2 v0.1.36 h1:UxBWzR9+7VLrpQWXgin1efxcP+vHf0/U/8Msbov1NDA= -git.xiaojukeji.com/disf/disf-go-spl-v2 v0.1.36/go.mod h1:B4hJumWMTtOP4X4vm1jqPOi5XlD96ZFqTAuG4EKCiv0= -git.xiaojukeji.com/disf/disf-go-spl-v2 v0.1.37/go.mod h1:B4hJumWMTtOP4X4vm1jqPOi5XlD96ZFqTAuG4EKCiv0= -git.xiaojukeji.com/disf/disf-go-spl-v2 v0.1.39/go.mod h1:B4hJumWMTtOP4X4vm1jqPOi5XlD96ZFqTAuG4EKCiv0= -git.xiaojukeji.com/disf/disf-go-spl-v2 v0.1.40-0.20210819030951-70dcfc268e9a/go.mod h1:B4hJumWMTtOP4X4vm1jqPOi5XlD96ZFqTAuG4EKCiv0= -git.xiaojukeji.com/disf/disf-go-spl-v2 v0.1.40/go.mod h1:B4hJumWMTtOP4X4vm1jqPOi5XlD96ZFqTAuG4EKCiv0= -git.xiaojukeji.com/disf/disf-go-spl-v2 v0.1.43 h1:xqvDUnCIcZlgqgIYc0ZFkEDIJ6JPLVQG5UREXg0S/P4= -git.xiaojukeji.com/disf/disf-go-spl-v2 v0.1.43/go.mod h1:KVTUFxHUPxQVrzedCj1/3/u8IeWQM8Ka5aC2neD8TWY= -git.xiaojukeji.com/foundation/didi-standard-lib v0.0.0-20201123053335-e67edadc52bf h1:IqH2bM38ZLmza3beTh2c4Ay/CfVN2ILjNJt4cXuXy2g= -git.xiaojukeji.com/foundation/didi-standard-lib v0.0.0-20201123053335-e67edadc52bf/go.mod h1:BL9PrFeJAMNJrTbAKJA4dCVUUw4GWE6QuWSwFjxPm4k= -git.xiaojukeji.com/foundation/thrift v0.9.3 h1:LCcExsZL5T/bTnGhVyNHfsjs5+MucWm+eCFa6R/Iq+A= -git.xiaojukeji.com/foundation/thrift v0.9.3/go.mod h1:mr0sUXUW5iUveD+BQlkx2kam22mYnzc9plIAhQkg+1U= -git.xiaojukeji.com/gobiz/cache v1.0.2 h1:J7zmMPrQkgbuouVYyXub8AX53+ONSU14bj6ed2V5qxk= -git.xiaojukeji.com/gobiz/cache v1.0.2/go.mod h1:kTCNYF32G1nXdAR3DpgXxK6isKCh4iluWmemDnZmg2Y= -git.xiaojukeji.com/gobiz/config v0.0.7 h1:f96cMLEjIKrh/Hmy5xPN+ccHZhmLV992l0OGsFfqD9I= -git.xiaojukeji.com/gobiz/config v0.0.7/go.mod h1:FJEpa4infv+1bQ09dywzUWAVtjejzzWWL9968tPVzt8= -git.xiaojukeji.com/gobiz/elapsed v0.0.2 h1:JARCp5+9pU+FzOiNE4y6zkax+J+hkNxpucS38oSnTKI= -git.xiaojukeji.com/gobiz/elapsed v0.0.2/go.mod h1:GGQzLBmcvN0WOQ91cNqvg8Lg/+Z2Hrd6empMYH+lY2Q= -git.xiaojukeji.com/gobiz/logger v1.2.28/go.mod h1:wcP4mP7epj0D2er88Try58mCZB7goPf4Cjykd6YkWKc= -git.xiaojukeji.com/gobiz/logger v1.3.3/go.mod h1:RFNcCXNy3+Rz+TkKQZvi7g3PKT/EyG3sxW+Jr7d+pG8= -git.xiaojukeji.com/gobiz/logger v1.3.4/go.mod h1:qI83N+0IDFBYtja87v+ah3js4ANg+Jpl8/8QzVFTSjc= -git.xiaojukeji.com/gobiz/logger v1.4.4 h1:ZTet5AoL6RLx9yHDCtHVnDKhXzTi+BNFzlY+4p7/gik= -git.xiaojukeji.com/gobiz/logger v1.4.4/go.mod h1:qI83N+0IDFBYtja87v+ah3js4ANg+Jpl8/8QzVFTSjc= -git.xiaojukeji.com/gobiz/logger v1.4.5/go.mod h1:qI83N+0IDFBYtja87v+ah3js4ANg+Jpl8/8QzVFTSjc= -git.xiaojukeji.com/gobiz/logger v1.4.7 h1:CwOQTMimodav3l+Fh6WmKOrX1XHYDbIZAqOjy8Stcfk= -git.xiaojukeji.com/gobiz/logger v1.4.7/go.mod h1:qI83N+0IDFBYtja87v+ah3js4ANg+Jpl8/8QzVFTSjc= -git.xiaojukeji.com/gobiz/utils v0.0.7/go.mod h1:myE5vDJLUH3ME5Rc7ebg+7QSVusHABrHwbgYxE8YCWI= -git.xiaojukeji.com/gobiz/utils v1.0.1 h1:BftvQ8VdFC1KqE5gfkJ08XiM5DWmMyCbBNrrS2eGvhw= -git.xiaojukeji.com/gobiz/utils v1.0.1/go.mod h1:myE5vDJLUH3ME5Rc7ebg+7QSVusHABrHwbgYxE8YCWI= -git.xiaojukeji.com/golang/go-tdigest v0.0.0-20160413204300-577940117044/go.mod h1:C7L62J5e+T2mAUXpgJck6EakqV3aMEz4UAzfN7Br2ak= -git.xiaojukeji.com/lego/common-go v0.1.19 h1:2lNnuHj62ZhwpqpHQ7c7TfOfPrqjSJYJo7EFrONb0pg= -git.xiaojukeji.com/lego/common-go v0.1.19/go.mod h1:6KXHn+oe36kXyiImOGwjSCoVT7lrkRUqm/OjWClCVhQ= -git.xiaojukeji.com/lego/common-go v0.1.22 h1:y9/AJdigi4eljGC3ZSLhOSb0annaCKKqml6pu3N56E4= -git.xiaojukeji.com/lego/common-go v0.1.22/go.mod h1:0E8emkc2GJPf2zSclkMMCTcrZkEHX00EuDxxXvSE5JM= -git.xiaojukeji.com/lego/context-go v3.0.1+incompatible/go.mod h1:PEQ2BpFDQs/uAWpGO/tC9bMfWrnptw3M9MO2DaY1KVY= -git.xiaojukeji.com/lego/context-go v3.0.3-0.20210204053446-cc0c77017173+incompatible/go.mod h1:PEQ2BpFDQs/uAWpGO/tC9bMfWrnptw3M9MO2DaY1KVY= -git.xiaojukeji.com/lego/context-go v3.0.3+incompatible/go.mod h1:PEQ2BpFDQs/uAWpGO/tC9bMfWrnptw3M9MO2DaY1KVY= -git.xiaojukeji.com/lego/context-go v3.0.4+incompatible h1:J0RE54vG7heU4LlrLQx+oAmRoaEe+Uki1EoRs8xcMOc= -git.xiaojukeji.com/lego/context-go v3.0.4+incompatible/go.mod h1:PEQ2BpFDQs/uAWpGO/tC9bMfWrnptw3M9MO2DaY1KVY= -git.xiaojukeji.com/lego/dirpc-go v1.16.9/go.mod h1:HbVRjEnrfpYTM2nwqqTwJaKZwmfRyEsVa8cjBscaeh4= -git.xiaojukeji.com/lego/dirpc-go v1.16.11-0.20210816074537-6e2a7ab987c1/go.mod h1:EfOBTBplIfu8ua3WpX1OT621kaeHO+lErjngU9xvF8U= -git.xiaojukeji.com/lego/dirpc-go v1.16.11-0.20210819033055-b145eb63fb00/go.mod h1:IY4Eps2zn266XXqnvM6q4mbqjJByNjwRmDVAt/CFXtQ= -git.xiaojukeji.com/lego/dirpc-go v1.16.11-0.20210820022224-2f84346236de/go.mod h1:+PjDjcXqeTsv6jAF+GlzDL8u6lbbRcoRqelIo/1hDVw= -git.xiaojukeji.com/lego/dirpc-go v1.16.13/go.mod h1:GFpAKh+xbcCp3eKTbSKODHHRh6FbuzKlFr/Rnotftqs= -git.xiaojukeji.com/lego/dirpc-go v1.16.24 h1:TnbnxvVy6Y11i8trSNkyZfv4rMzezQGoVtT12glqM8M= -git.xiaojukeji.com/lego/dirpc-go v1.16.24/go.mod h1:rfAMEZLwY9h96yvgIC4/dFN/gHZaAfpVBdjkqiqYXpc= -git.xiaojukeji.com/lego/ruleEngine v1.0.0 h1:bLaRaf44ckhFe+vLKcfGYu7gu8+DJh8xJUw8Z95CQ7A= -git.xiaojukeji.com/lego/ruleEngine v1.0.0/go.mod h1:RRcCo5URt7nhBMQcpEnI780n0rlpeND4B+gVKczuV7U= -git.xiaojukeji.com/lego/sentinel-golang v1.1.3 h1:0Am+H/M5vHA09CFr2XQSvNpbEA2Txp+E+y0TFlnkeqA= -git.xiaojukeji.com/lego/sentinel-golang v1.1.3/go.mod h1:zAu2UQPlhAnXSt8ZjQMqG6Z2KMo8jyytmh3SVwXJii4= -git.xiaojukeji.com/nuwa/binding v0.1.2 h1:PE4l6gZIYTnuUHe/SXJQxJL3T124vay6gtvHgwLOfps= -git.xiaojukeji.com/nuwa/binding v0.1.2/go.mod h1:yRWzl8Cjj62nCxibZvXKbLeDTcO1dToXlu0f2xHaHms= -git.xiaojukeji.com/nuwa/go-monitor v1.1.5 h1:3YNQJ3IKn5sRA81A1z9xBmFGwJV1BllFv7ziJTcuJSU= -git.xiaojukeji.com/nuwa/go-monitor v1.1.5/go.mod h1:C0m8zJlL59dpoiQSR8T1RqLHOLB2MeMnI8o2YYFRgkg= -git.xiaojukeji.com/nuwa/golibs/discover v0.0.5 h1:yflPBzKHJ2IcwWobmf8E3J1Bay1YZliXRWQmLc+N6Qw= -git.xiaojukeji.com/nuwa/golibs/discover v0.0.5/go.mod h1:7nTcaUccQIpjHWfmocU6Htny8j7vpPfSAfo1cGPjiDg= -git.xiaojukeji.com/nuwa/golibs/httprouter v0.0.11 h1:5PpQzsYLDIMGgSwTq9BjaMdHEBgGOf468BaFVmKRWyc= -git.xiaojukeji.com/nuwa/golibs/httprouter v0.0.11/go.mod h1:LpU0X+hTVxQ6yY8vEg+FrmpaB7DAUPxuFShbZaj8yYs= -git.xiaojukeji.com/nuwa/golibs/metrics v0.2.4 h1:ZQdZxSBiOvLqTzgie780B4LQZPyBRw37f0JNT65pe34= -git.xiaojukeji.com/nuwa/golibs/metrics v0.2.4/go.mod h1:qy3ra5x3CM8zPCDdGjAvqGv9P1amYXTCf6cv4C7rWVI= -git.xiaojukeji.com/nuwa/golibs/redigo v1.8.8 h1:6VkPRL5/PfmCiiPqxyAp8O+q2d7MwEUUq8MwvvtfS/U= -git.xiaojukeji.com/nuwa/golibs/redigo v1.8.8/go.mod h1:AceIcnRHXupwGQ6IF4HL/iTi/tLxcBOPQfIHGlhpKmk= -git.xiaojukeji.com/nuwa/golibs/redis v0.4.14 h1:YTW07Y558d9EmR0PVpOVNrBUfbtTFhPIR1A1dEIpJYs= -git.xiaojukeji.com/nuwa/golibs/redis v0.4.14/go.mod h1:Wjd1J4OBY9Ay2uDRE67SO3y5v8dg3IYC1Poa8ls3wT8= -git.xiaojukeji.com/nuwa/gorequest v1.0.3 h1:sIICDH0TYPK8XMELrhMjXBt15j61kwpxpi3gIiS7tJ0= -git.xiaojukeji.com/nuwa/gorequest v1.0.3/go.mod h1:ritycdzL+I1Dipfd7P3dzS5lTU+lbEPBFga0bj0aMcI= -git.xiaojukeji.com/nuwa/nuwa-go-httpclient v1.3.14 h1:fFf+2im576SS7p+t4OB5eDFBB5C1pxwNoyVCy/qIA+I= -git.xiaojukeji.com/nuwa/nuwa-go-httpclient v1.3.14/go.mod h1:URmom/bcADz5m0hFmNIRpxKosi80imYuva3w8tzEGEM= -git.xiaojukeji.com/nuwa/nuwa-go-httpserver/v2 v2.8.11 h1:lUBwsPyvom6CHnG5Vy6Rrd2eB6vrLSGyd3NzPLXdeQ4= -git.xiaojukeji.com/nuwa/nuwa-go-httpserver/v2 v2.8.11/go.mod h1:WJI5y1Dy+6y8BClx9SYzUXETVwmRR7sTFbrmyVGCOlA= -git.xiaojukeji.com/nuwa/protoc-dirpc v1.2.0/go.mod h1:gzfVNNsbUshc1LPU4FIWSVeRwqL2arLuc3o/G785hME= -git.xiaojukeji.com/nuwa/trace v1.3.12 h1:15K0Y+PG3p1lSCpwdhRlQM/mN7NwravpeY/l+rmqu0g= -git.xiaojukeji.com/nuwa/trace v1.3.12/go.mod h1:8Og3kmWTAaXezXM4Aq3HWe75sMY+d3jA77nmyn4c9DA= -git.xiaojukeji.com/nuwa/trace/v2 v2.0.3 h1:40KrHWzHMiGzBPSYPhwXoXKL1Ifni9SnPV4ISSO+TKg= -git.xiaojukeji.com/nuwa/trace/v2 v2.0.3/go.mod h1:Mlg8+AlIxlUh7l0Vc+sVhx8Ef6G9Q0UKTURUCV8rC6g= -git.xiaojukeji.com/nuwa/trace/v2 v2.0.7 h1:4SmofQ5PUxn43JozBVYc5qA3s5JvWByqaZgkMehk0JU= -git.xiaojukeji.com/nuwa/trace/v2 v2.0.7/go.mod h1:bj9wOA2DCLwBG1Dv5dl+zD4n3EikxolGooXPzCyJWP4= -git.xiaojukeji.com/ops-sec/disf_kms_sdk_go v0.0.0-20190107121632-c61f10c1e31c/go.mod h1:iIi/pKbE7lHEEoae1JMXQFKljtvF7Fadc030GjKDB3E= -git.xiaojukeji.com/pt-arch/warden-client-go v0.0.2 h1:T+OD/jrsTtuWQfI+5x6QrpJlAZYMCTqaAGgkgJ5ipz8= -git.xiaojukeji.com/pt-arch/warden-client-go v0.0.2/go.mod h1:YUic+w1o/mEreI9DnNSIBoc31uU6A7Jl7pZZXT3CWOc= -git.xiaojukeji.com/sre-ha/chaos-interceptor v0.0.0-20210804142554-1df30aae0688/go.mod h1:pWxnUiWor02/XhYPNRibAmm1sp5k3AltYx6WB460Fvg= -git.xiaojukeji.com/sre-ha/chaos-interceptor v0.0.0-20210816124301-0acc0ae1c20f/go.mod h1:5f/Rzc4tA9h9CoFduCpcSsfHU35fR3kzTZ7qOTnp75U= -git.xiaojukeji.com/sre-ha/chaos-interceptor v0.0.0-20210819121323-90575b150ac4/go.mod h1:xPRjOpqUXSC5piE5IPRtFz8h+m8sfpMFUkmnhmDAgbg= -git.xiaojukeji.com/sre-ha/chaos-interceptor v0.0.0-20210831103212-e97e2e927a7c/go.mod h1:uphE+MJrMys/D7Yw18y05N3IzrgZsx1xnCrM0haxjQI= -git.xiaojukeji.com/sre-ha/chaos-interceptor v0.0.4 h1:oJoEwZzAOgB+sF3VxrGaUXLf5+tb/drOpJ/4D21h2Oo= -git.xiaojukeji.com/sre-ha/chaos-interceptor v0.0.4/go.mod h1:3ori74OkxOH/XgqL+FGU9ldXIMfZEyYLRI02f8d0r/M= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/DATA-DOG/go-sqlmock v1.4.0/go.mod h1:3TucWNLPFOLcHhha1CPp7Kis1UG2h/AqGROPyOeZzsM= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= -github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/caio/go-tdigest v3.1.0+incompatible h1:uoVMJ3Q5lXmVLCCqaMGHLBWnbGoN6Lpu7OAUPR60cds= -github.com/caio/go-tdigest v3.1.0+incompatible/go.mod h1:sHQM/ubZStBUmF1WbB8FAm8q9GjDajLC5T7ydxE3JHI= -github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/coocood/freecache v1.1.1 h1:uukNF7QKCZEdZ9gAV7WQzvh0SbjwdMF6m3x3rxEkaPc= -github.com/coocood/freecache v1.1.1/go.mod h1:OKrEjkGVoxZhyWAJoeFi5BMLUJm2Tit0kpGkIr7NGYY= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/didi/gendry v1.7.0 h1:dFR6+TVCnbjvLfNiGN53xInG/C5HqG7u0gfnkF5J/Vo= -github.com/didi/gendry v1.7.0/go.mod h1:cSLuShZ1Zbs1S05RIOLNQv616aBaOQ1BDrXJP9A3J+M= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/elazarl/goproxy v0.0.0-20201021153353-00ad82a08272 h1:Am81SElhR3XCQBunTisljzNkNese2T1FiV8jP79+dqg= -github.com/elazarl/goproxy v0.0.0-20201021153353-00ad82a08272/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= -github.com/elazarl/goproxy v0.0.0-20210110162100-a92cc753f88e h1:/cwV7t2xezilMljIftb7WlFtzGANRCnoOhPjtl2ifcs= -github.com/elazarl/goproxy v0.0.0-20210110162100-a92cc753f88e/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= -github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 h1:dWB6v3RcOy03t/bUadywsbyrQwCqZeNIEX6M1OtSZOM= -github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= -github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a h1:yDWHCSQ40h88yih2JAcL6Ls/kVkSE8GFACTGVnMPruw= -github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a/go.mod h1:7Ga40egUymuWXxAe151lTNnCv97MddSOVsjpPPkityA= -github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= -github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= -github.com/facebookgo/freeport v0.0.0-20150612182905-d4adf43b75b9 h1:wWke/RUCl7VRjQhwPlR/v0glZXNYzBHdNUzf/Am2Nmg= -github.com/facebookgo/freeport v0.0.0-20150612182905-d4adf43b75b9/go.mod h1:uPmAp6Sws4L7+Q/OokbWDAK1ibXYhB3PXFP1kol5hPg= -github.com/facebookgo/grace v0.0.0-20180706040059-75cf19382434 h1:mOp33BLbcbJ8fvTAmZacbBiOASfxN+MLcLxymZCIrGE= -github.com/facebookgo/grace v0.0.0-20180706040059-75cf19382434/go.mod h1:KigFdumBXUPSwzLDbeuzyt0elrL7+CP7TKuhrhT4bcU= -github.com/facebookgo/httpdown v0.0.0-20180706035922-5979d39b15c2 h1:nXeeRHmgNgjLxi+7dY9l9aDvSS1uwVlNLqUWIY4Ath0= -github.com/facebookgo/httpdown v0.0.0-20180706035922-5979d39b15c2/go.mod h1:TUV/fX3XrTtBQb5+ttSUJzcFgLNpILONFTKmBuk5RSw= -github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= -github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= -github.com/facebookgo/stats v0.0.0-20151006221625-1b76add642e4 h1:0YtRCqIZs2+Tz49QuH6cJVw/IFqzo39gEqZ0iYLxD2M= -github.com/facebookgo/stats v0.0.0-20151006221625-1b76add642e4/go.mod h1:vsJz7uE339KUCpBXx3JAJzSRH7Uk4iGGyJzR529qDIA= -github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= -github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= -github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= -github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= -github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= -github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomodule/redigo/redis v0.0.1 h1:tQQSZyg4O0N0Dh2hli1pOrRdj+WHl1xf3w/x7olDgu0= -github.com/gomodule/redigo/redis v0.0.1/go.mod h1:QhGMo2EGfdSsmrYDENZq12/Y23fRP6X6nyFZ4TGSUvM= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/leesper/go_rng v0.0.0-20190531154944-a612b043e353 h1:X/79QL0b4YJVO5+OsPH9rF2u428CIrGL/jLmPsoOQQ4= -github.com/leesper/go_rng v0.0.0-20190531154944-a612b043e353/go.mod h1:N0SVk0uhy+E1PZ3C9ctsPRlvOPAFPkCNlcPBDkt0N3U= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= -github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= -github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= -github.com/parnurzeal/gorequest v0.2.16 h1:T/5x+/4BT+nj+3eSknXmCTnEVGSzFzPGdpqmUVVZXHQ= -github.com/parnurzeal/gorequest v0.2.16/go.mod h1:3Kh2QUMJoqw3icWAecsyzkpY7UzRfDhbRdTjtNwNiUE= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.9.0 h1:Rrch9mh17XcxvEu9D9DEpb4isxjGBtcevQjKvxPRQIU= -github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.15.0 h1:4fgOnadei3EZvgRwxJ7RMpG1k1pOZth5Pc13tyspaKM= -github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4= -github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= -github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/shirou/gopsutil/v3 v3.21.6 h1:vU7jrp1Ic/2sHB7w6UNs7MIkn7ebVtTb5D9j45o9VYE= -github.com/shirou/gopsutil/v3 v3.21.6/go.mod h1:JfVbDpIBLVzT8oKbvMg9P3wEIMDDpVn+LwHTKj0ST88= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= -github.com/spaolacci/murmur3 v0.0.0-20170819071325-9f5d223c6079/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/tklauser/go-sysconf v0.3.6 h1:oc1sJWvKkmvIxhDHeKWvZS4f6AW+YcoguSfRF2/Hmo4= -github.com/tklauser/go-sysconf v0.3.6/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= -github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA= -github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/ugorji/go v1.2.6 h1:tGiWC9HENWE2tqYycIqFTNorMmFRVhNwCpDOpWqnk8E= -github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0= -github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ= -github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.intra.xiaojukeji.com/apollo/apollo-golang-sdk-v2 v2.7.7+incompatible h1:f4YXPEGDypeNbQp2vG8j5AJIK35Aezq5fiYbj8Nl6Bc= -go.intra.xiaojukeji.com/apollo/apollo-golang-sdk-v2 v2.7.7+incompatible/go.mod h1:1fUxSjrbbsP3ktoGq3RtmeFvSZNEKfJhiXwQKlPLGBo= -go.intra.xiaojukeji.com/foundation/didi-standard-lib v0.0.0-20201123053335-e67edadc52bf h1:UbZ983164rDlXHI+NwhyJuZl2qY2eE55dFWbDXfnxg0= -go.intra.xiaojukeji.com/foundation/didi-standard-lib v0.0.0-20201123053335-e67edadc52bf/go.mod h1:xq25s/hZNGEYYgLfZAwF64xgQAivPGNZYij6/4RiuRo= -go.intra.xiaojukeji.com/platform-ha/onekey-degrade_sdk_go v3.2.8+incompatible h1:TiwDYfzeNZ7YCMol+vNXpprXX4kuvc1htbgJaNE/7Sw= -go.intra.xiaojukeji.com/platform-ha/onekey-degrade_sdk_go v3.2.8+incompatible/go.mod h1:4nbUEJpW13dUlRufRpPNyOFnpAo+UGS2MGiVq59P4sY= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2 h1:y102fOLFqhV41b+4GPiJoa0k/x+pJcEi2/HB1Y5T6fU= -golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191207000613-e7e4b65ae663/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e/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-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 h1:RqytpXGR1iVNX7psjB3ff8y7sNFinVFvkx1c8SjBkio= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.8.2 h1:CCXrcPKiGGotvnN6jfUsKk4rRqm7q09/YbKb5xCEvtM= -gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0 h1:OE9mWmgKkjJyEmDAAtGMPjXu+YNeGvK9VTSHY6+Qihc= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20210617175327-b9e0b3197ced h1:c5geK1iMU3cDKtFrCVQIcjR3W+JOZMuhIyICMCTbtus= -google.golang.org/genproto v0.0.0-20210617175327-b9e0b3197ced/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ= -gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/validator.v2 v2.0.0-20200605151824-2b28d334fa05 h1:l9eKDCWy9n7C5NAiQAMvDePh0vyLAweR6LcSUVXFUGg= -gopkg.in/validator.v2 v2.0.0-20200605151824-2b28d334fa05/go.mod h1:o4V0GXN9/CAmCsvJ0oXYZvrZOe7syiDZSN1GWGZTGzc= -gopkg.in/validator.v2 v2.0.0-20210331031555-b37d688a7fb0 h1:EFLtLCwd8tGN+r/ePz3cvRtdsfYNhDEdt/vp6qsT+0A= -gopkg.in/validator.v2 v2.0.0-20210331031555-b37d688a7fb0/go.mod h1:o4V0GXN9/CAmCsvJ0oXYZvrZOe7syiDZSN1GWGZTGzc= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -moul.io/http2curl v1.0.0/go.mod h1:f6cULg+e4Md/oW1cYmwW4IWQOVl2lGbmCNGOHvzX2kE= -moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e h1:C7q+e9M5nggAvWfVg9Nl66kebKeuJlP3FD58V4RR5wo= -moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e/go.mod h1:nejbQVfXh96n9dSF6cH3Jsk/QI1Z2oEL7sSI2ifXFNA= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/tg-core/model/algo_model.go b/tg-core/model/algo_model.go deleted file mode 100644 index 311a78551ab133e11ebca12236459539e7771aad..0000000000000000000000000000000000000000 --- a/tg-core/model/algo_model.go +++ /dev/null @@ -1,18 +0,0 @@ -package model - -import ( - "time" -) - -//算法模型配置索引 -type AlgoModelIndex struct { - IndexVersion string `json:"index_version"` - IndexMap map[string][]string `json:"index_map"` - UpdateTime time.Time `json:"updateTime"` -} - -//索引更新后,向center回报状态的返回结果:ErrNo=0,表示操作成功 -type CenterServerReportResponseInfo struct { - ErrNo int32 `thrift:"err_no,1,required" json:"err_no"` - ErrMsg string `thrift:"err_msg,2,required" json:"err_msg"` -} diff --git a/tg-core/model/apollo_config.go b/tg-core/model/apollo_config.go deleted file mode 100644 index 0a6b174d9cf7bdd42a06559e43d7ccb1c43461ad..0000000000000000000000000000000000000000 --- a/tg-core/model/apollo_config.go +++ /dev/null @@ -1,148 +0,0 @@ -/** - Description: 存放apollo实验相关的配置信息,提供相关访问方法的封装 - Author: dayunzhangyunfeng@didiglobal.com - Date: 2020-08-31 -**/ - -package model - -import ( - "fmt" - "go.intra.xiaojukeji.com/apollo/apollo-golang-sdk-v2" - apolloModel "go.intra.xiaojukeji.com/apollo/apollo-golang-sdk-v2/model" -) - -type ApolloConfig struct { - ApolloUsers map[string]*apolloModel.User - dispatchUser *apolloModel.User - dispatchExperimentName string -} - -func NewApolloConfig() *ApolloConfig { - apolloUsers := make(map[string]*apolloModel.User) - return &ApolloConfig{ApolloUsers: apolloUsers} -} - -// SetDispatchUser 设置分流 User -func (this *ApolloConfig) SetDispatchUser(apolloUser *apolloModel.User) { - this.dispatchUser = apolloUser -} - -// SetDispatchExperimentName 设置分流实验名,如果分流实验名保存在数据库中,则不需要 SetDispatchExperimentName -func (this *ApolloConfig) SetDispatchExperimentName(experimentName string) { - this.dispatchExperimentName = experimentName -} - -func (this *ApolloConfig) GetDispatchExperimentName() string { - return this.dispatchExperimentName -} - -func (this *ApolloConfig) GetDispatchGroupName() (string, error) { - - if this.dispatchUser == nil || this.dispatchExperimentName == "" { - return "", fmt.Errorf("dispatch info not correct, user=%v, exp_name=%v", this.dispatchUser, this.dispatchExperimentName) - } - - toggle, err := apollo.FeatureToggle(this.dispatchExperimentName, this.dispatchUser) - if err != nil { - return "", err - } - - if toggle.IsAllow() { - return toggle.GetAssignment().GetGroupName(), nil - } else { - //The individual which is not allowed to enter the experiment using the default strategy - return "", fmt.Errorf("the user is not permitted to enter the apollo experiment: %v", this.dispatchExperimentName) - } -} - -// SetApolloUser 已经弃用,建议自己采用 Apollo SDK 执行实验相关操作 -func (this *ApolloConfig) SetApolloUser(experimentName string, apolloUser *apolloModel.User) { - this.ApolloUsers[experimentName] = apolloUser -} - -// GetGroupName 已经弃用,建议自己采用 Apollo SDK 执行实验相关操作 -func (this *ApolloConfig) GetGroupName(experimentName string) (string, error) { - toggleResult, err := apollo.FeatureToggle(experimentName, this.ApolloUsers[experimentName]) - if err != nil { - return "", err - } - - //If toggle.allow is true, this individual is allowed to enter the experiment - if toggleResult.IsAllow() { - assignment := toggleResult.GetAssignment() - return assignment.GetGroupName(), nil - } else { - //The individual which is not allowed to enter the experiment using the default strategy - return "", fmt.Errorf("the user is not permitted to enter the apollo experiment: %v", experimentName) - } -} - -// GetApolloParam 取指定实验的指定参数值,注意:此函数有可能由于缺省值的补漏而隐藏取参数值失败的错误, -// 已经弃用,建议自己采用 Apollo SDK 执行实验相关操作 -func (this *ApolloConfig) GetApolloParam(experimentName, paramName, defaultParamValue string) (string, error) { - apolloUser, ok := this.ApolloUsers[experimentName] - if !ok { - return defaultParamValue, fmt.Errorf("apollo user for experimentName:%v not initialzed!", experimentName) - } - - toggleResult, err := apollo.FeatureToggle(experimentName, apolloUser) - if err != nil { - return defaultParamValue, err - } - - //If toggle.allow is true, this individual is allowed to enter the experiment - if toggleResult.IsAllow() { - //The sample were divided into different groups and used different strategies. - assignment := toggleResult.GetAssignment() - return assignment.GetParameter(paramName, defaultParamValue), nil - } else { - return defaultParamValue, fmt.Errorf("user not allowed in apollo experiment:%v", experimentName) - } -} - -// GetApolloParams 取指定实验的全部参数并以map[string]string格式返回,如value不为string类型,则转为string -// 已经弃用,建议自己采用 Apollo SDK 执行实验相关操作 -func (this *ApolloConfig) GetApolloParams(experimentName string) (map[string]string, error) { - apolloUser, ok := this.ApolloUsers[experimentName] - if !ok { - return nil, fmt.Errorf("apollo user for experimentName:%v not initialzed!", experimentName) - } - - toggleResult, err := apollo.FeatureToggle(experimentName, apolloUser) - if err != nil { - return nil, err - } - - //If toggle.allow is true, this individual is allowed to enter the experiment - if toggleResult.IsAllow() { - //The sample were divided into different groups and used different strategies. - assignment := toggleResult.GetAssignment() - return assignment.GetParameters(), nil - } else { - return nil, fmt.Errorf("user not allowed in apollo experiment:%v", experimentName) - } -} - -// GetRawApolloParams 取指定实验的全部原始参数 -// 已经弃用,建议自己采用 Apollo SDK 执行实验相关操作 -func (this *ApolloConfig) GetRawApolloParams(experimentName string) (map[string]interface{}, error) { - apolloUser, ok := this.ApolloUsers[experimentName] - if !ok { - return nil, fmt.Errorf("apollo user for experimentName:%v not initialzed!", experimentName) - } - - toggleResult, err := apollo.FeatureToggle(experimentName, apolloUser) - if err != nil { - return nil, err - } - - //If toggle.allow is true, this individual is allowed to enter the experiment - if toggleResult.IsAllow() { - //The sample were divided into different groups and used different strategies. - assignment := toggleResult.GetAssignment() - return assignment.GetRawParameters(), nil - } else { - return nil, fmt.Errorf("user not allowed in apollo experiment:%v", experimentName) - } -} diff --git a/tg-core/model/dimension.go b/tg-core/model/dimension.go deleted file mode 100644 index 5e7e75f313bd90594fb26767fb91354fca686ad7..0000000000000000000000000000000000000000 --- a/tg-core/model/dimension.go +++ /dev/null @@ -1,20 +0,0 @@ -package model - -import ( - "time" -) - -type Dimension struct { - Id int64 `json:"id"` - Name string `json:"name"` - SceneId int64 `json:"sceneId"` - //第一层key:维度(如"city");value:值的数组 - ContentMap map[string][]string `json:"contentMap"` - UpdateTime time.Time `json:"updateTime"` -} - -type DimensionIndex struct { - //一级key->场景id;二级key->维度类型(如"city");三级key->维度值;value->维度id - DimensionMap map[int64]map[string]map[string]int64 `json:"dimensionMap"` - UpdateTime time.Time `json:"updateTime"` -} diff --git a/tg-core/model/down_grade.go b/tg-core/model/down_grade.go deleted file mode 100644 index fb42e42e88ce893b98400d441231bbccc6d700aa..0000000000000000000000000000000000000000 --- a/tg-core/model/down_grade.go +++ /dev/null @@ -1,17 +0,0 @@ -package model - -import ( - "time" -) - -type DowngradeStrategyInfo struct { - LevelList []*DowngradeLevel `json:"levels"` - SceneIds []int64 `json:"scene_ids"` - UpdateTime time.Time -} - -type DowngradeLevel struct { - Level int `json:"level"` - Rate int64 `json:"rate"` - Status bool `json:"status"` -} diff --git a/tg-core/model/omega_info.go b/tg-core/model/omega_info.go deleted file mode 100644 index 47266fae465a6b421fd05ca55cc44d34edf89c4a..0000000000000000000000000000000000000000 --- a/tg-core/model/omega_info.go +++ /dev/null @@ -1,12 +0,0 @@ -package model - -type OmegaInfo struct { - Bootstrap string `json:"boot_strap"` - User string `json:"user"` - Password string `json:"pass_word"` - Topic string `json:"topic"` - SceneId int64 `json:"scene_id"` - EventId map[string]string `json:"event_id"` - BuryData map[string]string `json:"bury_data"` - IsCollectUserAction bool `json:"is_collect_user_action"` -} diff --git a/tg-core/model/recall_config.go b/tg-core/model/recall_config.go deleted file mode 100644 index eda65303dbf543801b54bdea2504ba4ddacb4c19..0000000000000000000000000000000000000000 --- a/tg-core/model/recall_config.go +++ /dev/null @@ -1,16 +0,0 @@ -package model - -import ( - -) - -type RecallConfig struct { - Id int64 `json:"id"` - SceneId int64 `json:"scene_id"` - RecallRule []RecallRuleType `json:"recall_rule"` -} - -type RecallRuleType struct { - RecallType string `json:"recall_type"` - TopN int64 `json:"top_n"` -} \ No newline at end of file diff --git a/tg-core/model/system_config.go b/tg-core/model/system_config.go deleted file mode 100644 index 93f4bd4ad9f5d8f5d2e808b163b21c0b1ce21126..0000000000000000000000000000000000000000 --- a/tg-core/model/system_config.go +++ /dev/null @@ -1,13 +0,0 @@ -package model - -import ( - "time" -) - -type SystemConfigInfo struct { - Id int64 `json:"id"` - Type int `json:"type"` - KeyName string `json:"keyname"` - Content string `json:"content"` - UpdateTime time.Time `json:"updateTime"` -} diff --git a/tg-core/model/trace_info.go b/tg-core/model/trace_info.go deleted file mode 100644 index 68581f3253fafb61302b1f9d9e88ec1e85ed6f5e..0000000000000000000000000000000000000000 --- a/tg-core/model/trace_info.go +++ /dev/null @@ -1,14 +0,0 @@ -package model - -import ( - -) - -type TraceInfo struct { - TraceId string `thrift:"traceId,1,required" json:"traceId"` - Caller string `thrift:"caller,2,required" json:"caller"` - SpanId string `thrift:"spanId,3" json:"spanId,omitempty"` - SrcMethod string `thrift:"srcMethod,4" json:"srcMethod,omitempty"` - HintCode int64 `thrift:"hintCode,5" json:"hintCode,omitempty"` - HintContent string `thrift:"hintContent,6" json:"hintContent,omitempty"` -} \ No newline at end of file diff --git a/tg-core/model/workflow.go b/tg-core/model/workflow.go deleted file mode 100644 index e930c15a72c11acc65de7ea1fb4d95653033e167..0000000000000000000000000000000000000000 --- a/tg-core/model/workflow.go +++ /dev/null @@ -1,137 +0,0 @@ -package model - -import ( - "time" - "sync" - "errors" - "encoding/json" - "fmt" -) - -type Workflow struct { - Id int64 `json:"id"` - DimensionId int64 `json:"dimensionId"` - ExperimentId int64 `json:"experimentId"` - ModulesArray [][]string `json:"modulesArray"` - FlowChart *WorkflowChart `json:"flow_chart"` - IsDefault int `json:"isDefault"` - Range1 string `json:"range1"` - Range2 string `json:"range2"` - Remark string `json:"remark"` - UpdateTime time.Time `json:"updateTime"` - ManualSlotIds []int64 `json:"manual_slot_ids"` - GroupName string `json:"group_name"` -} - -type WorkflowChart struct { - FirstActionId string `json:"first_action_id"` - ActionMap map[string]*Action `json:"actions"` - ParamMap map[string]string `json:"params"` -} - -type Action struct { - ActionId string `json:"action_id"` - ActionName string `json:"action_name"` - Params map[string]string `json:"params"` - NextActionIds []string `json:"next_action_ids"` - PrevActionIds []string `json:"prev_action_ids"` -} - -func NewWorkflowChart(flowChartStr string) (*WorkflowChart, error) { - if len(flowChartStr) ==0 { - return nil, errors.New("create WorkflowChart fail, flowChartStr is empty") - } - - flowChart := &WorkflowChart{} - //读取的数据为json格式,需要进行解码 - err := json.Unmarshal([]byte(flowChartStr), flowChart) - if err != nil { - return nil, fmt.Errorf("create WorkflowChart fail, invalid json:%v, err:%v", flowChartStr, err) - } - - err = flowChart.setFirstActionId() - if err != nil { - return nil, fmt.Errorf("create WorkflowChart fail, err:%v", err) - } - - //setFirstActionId first, then setPrevActionIds - flowChart.setPrevActionIds(flowChart.FirstActionId) - return flowChart, nil -} - -func (this *WorkflowChart) setPrevActionIds(actionId string){ - action, ok := this.ActionMap[actionId] - if !ok { - return - } - - //默认第一个action的id为1,没有前驱节点 - if actionId == this.FirstActionId { - action.PrevActionIds = []string{} - } - - nextActionIds := action.NextActionIds - for _, nextActionId := range nextActionIds { - nextAction, ok := this.ActionMap[nextActionId] - if !ok { - //报个error? - continue - } - - if nextAction.PrevActionIds == nil || len(nextAction.PrevActionIds) == 0 { - nextAction.PrevActionIds = []string{actionId} - }else{ - isAlreadyAdd := false - var prevActionId string - for _, prevActionId = range nextAction.PrevActionIds { - if prevActionId == actionId { - isAlreadyAdd = true - } - } - if !isAlreadyAdd { - nextAction.PrevActionIds = append(nextAction.PrevActionIds, actionId) - } - } - - this.setPrevActionIds(nextActionId) - } -} - -/* - 耗时搜索 -*/ -func (this *WorkflowChart) setFirstActionId() error { - nextActionIds := make(map[string]bool) - for _, action := range this.ActionMap { - if len(action.NextActionIds) <= 0 { - continue - } - - for _, nextId := range action.NextActionIds { - nextActionIds[nextId] = true - } - } - - for actionId,_ := range this.ActionMap { - if _, ok := nextActionIds[actionId]; !ok { - this.FirstActionId = actionId - return nil - } - } - - return errors.New("first action not found") -} - -func (this *WorkflowChart) CreateWaitMap() map[string]*sync.WaitGroup { - wgMap:= make(map[string]*sync.WaitGroup) - for actionId, action := range this.ActionMap { - prevCount := len(action.PrevActionIds) - if prevCount >1 { - wg := &sync.WaitGroup{} - wg.Add(prevCount) - wgMap[actionId]= wg - } - } - - return wgMap -} diff --git a/tg-core/reset_import.sh b/tg-core/reset_import.sh deleted file mode 100755 index 9db82f38fc91568d90551c675700a14f80e610cd..0000000000000000000000000000000000000000 --- a/tg-core/reset_import.sh +++ /dev/null @@ -1,9 +0,0 @@ -rm -rf go.mod -rm -rf go.sum -rm -rf vendor -go mod init -go get -u -t ./... -sed -i "___bak" "s/v0.14.1/0.9.3/g" go.mod -rm -rf go.mod___bak -go mod download -go mod vendor diff --git a/tg-core/router/router.go b/tg-core/router/router.go deleted file mode 100644 index f17515c498986979a7888d12f85acab9a92e5a61..0000000000000000000000000000000000000000 --- a/tg-core/router/router.go +++ /dev/null @@ -1,48 +0,0 @@ -/** - * This file is auto-generated by dirpcgen don't modify manaully - * - * Copyright (c) 2018 didichuxing.com, Inc. All Rights Reserved - * - * Generated-date: 2018-07-13 - */ - -package router - -import ( - lego "git.xiaojukeji.com/lego/context-go" - "github.com/didi/tg-flow/tg-core/common/tlog" - "github.com/didi/tg-flow/tg-core/conf" - ngs "git.xiaojukeji.com/nuwa/nuwa-go-httpserver/v2" - "git.xiaojukeji.com/nuwa/nuwa-go-httpserver/v2/middleware" - "log" - "net/http" -) - -var Handler ngs.Route -var IdlHandler *ngs.IDLHandler - -func init() { - log.Println("tg-core router init start...") - Handler = ngs.NewRouter() - logLimit, err := conf.Handler.GetBoolSetting("log", "log_limit") - tlog.Handler.RegisterContextFormat(lego.FormatCtx) - if err == nil && logLimit { - Handler = Handler.Use( - middleware.RecoveryWithConfig(middleware.RecoveryConfig{tlog.Handler}), - middleware.TraceWithConfig(middleware.TraceConfig{Log: nil}), - middleware.RateLimitWithConfig(middleware.RateLimitConfig{Log: tlog.Handler, RateLimitKeyName: conf.RateLimitName})) - } else { - Handler = Handler.Use( - middleware.RecoveryWithConfig(middleware.RecoveryConfig{tlog.Handler}), - middleware.TraceWithConfig(middleware.TraceConfig{Log: tlog.Handler}), - middleware.RateLimitWithConfig(middleware.RateLimitConfig{Log: tlog.Handler, RateLimitKeyName: conf.RateLimitName})) - } - IdlHandler = ngs.NewDiRPC(tlog.Handler) - Handler.GET("/checkstatus", func(writer http.ResponseWriter, request *http.Request) { - writer.WriteHeader(200) - }) -} - -func AddRouter(requestType string, routerPath string, handlerMethod interface{}) { - Handler.Handler(requestType, routerPath, IdlHandler.Handle(handlerMethod)) -} diff --git a/tg-core/store/algomodel_index_map.go b/tg-core/store/algomodel_index_map.go deleted file mode 100644 index e1fea437f54406faa2460a5b7bf44afc2681ce0e..0000000000000000000000000000000000000000 --- a/tg-core/store/algomodel_index_map.go +++ /dev/null @@ -1,28 +0,0 @@ -package store - -import ( - "context" - "encoding/json" - "github.com/didi/tg-flow/tg-core/common/redis" - "github.com/didi/tg-flow/tg-core/consts" - "github.com/didi/tg-flow/tg-core/model" -) - -var AlgoModelIndexObj *model.AlgoModelIndex = &model.AlgoModelIndex{} - -func LoadAlgoModelIndex() error { - algoModelIndexByte, err := redis.Handler.Get(context.TODO(), consts.RedisKeyAlgoModelConfig) - if err != nil && err.Error() != redis.ErrNil { - return err - } - - var algoModelIndexTemp *model.AlgoModelIndex - err = json.Unmarshal([]byte(algoModelIndexByte), &algoModelIndexTemp) - if err != nil { - return err - } - AlgoModelIndexObj.IndexVersion = algoModelIndexTemp.IndexVersion - AlgoModelIndexObj.IndexMap = algoModelIndexTemp.IndexMap - AlgoModelIndexObj.UpdateTime = algoModelIndexTemp.UpdateTime - return nil -} diff --git a/tg-core/store/debug_info_list.go b/tg-core/store/debug_info_list.go deleted file mode 100644 index f766a4f824bf96b5d4aea027a042b91a6f0f86cf..0000000000000000000000000000000000000000 --- a/tg-core/store/debug_info_list.go +++ /dev/null @@ -1,69 +0,0 @@ -/** - @Description: - @Author:zhouzichun - @Date:2022/4/25 -**/ - -package store - -import ( - "context" - "encoding/json" - "fmt" - "github.com/didi/tg-flow/tg-core/common/redis" - "github.com/didi/tg-flow/tg-core/model" - "go.intra.xiaojukeji.com/apollo/apollo-golang-sdk-v2" - apolloModel "go.intra.xiaojukeji.com/apollo/apollo-golang-sdk-v2/model" - "strconv" - "time" -) - -type DebugResponse struct { - UserId string `json:"user_id"` - AppId int64 `json:"app_id"` - SceneId int64 `json:"scene_id"` - FlowId int64 `json:"flow_id"` - TimeStamp int64 `json:"time_stamp"` - ActionResultMap map[string]map[string]string `json:"action_result_map"` -} - -func Debug(sc *model.StrategyContext) error { - redisKey := fmt.Sprintf("debug_info_%v_%v", sc.AppName, sc.Phone) - debugResponse := &DebugResponse{ - AppId: sc.AppId, - SceneId: sc.SceneId, - FlowId: sc.FlowId, - TimeStamp: time.Now().Unix(), - ActionResultMap: sc.ActionResultMap, - } - debugResponseStr, err := json.Marshal(debugResponse) - if err != nil { - return err - } - var limitLength int64 - limitLength = 100 - user := apolloModel.NewUser(sc.Phone).With("phone", sc.Phone) - apolloToggle, apolloErr := apollo.FeatureToggle("online_debug_config", user) - if apolloErr != nil || !apolloToggle.IsAllow() { - return apolloErr - } else { - limitLengthStr := apolloToggle.GetAssignment().GetParameter("limit_num", "100") - limitLength, _ = strconv.ParseInt(limitLengthStr, 10, 64) - } - ctx := context.TODO() - length, err := redis.Handler.LPush(ctx, redisKey, string(debugResponseStr)) - if err != nil { - return err - } - _, err = redis.Handler.Expire(ctx, redisKey, 24*60*60) - if err != nil { - return err - } - if length > limitLength { - _, err = redis.Handler.LTrim(ctx, redisKey, int(length-limitLength), int(length-1)) - if err != nil { - return err - } - } - return nil -} diff --git a/tg-core/store/dimension_index_map.go b/tg-core/store/dimension_index_map.go deleted file mode 100644 index 4b3af8d28f14ea4bdea4c1223b790474e041e278..0000000000000000000000000000000000000000 --- a/tg-core/store/dimension_index_map.go +++ /dev/null @@ -1,29 +0,0 @@ -package store - -import ( - "context" - "encoding/json" - "github.com/didi/tg-flow/tg-core/common/redis" - "github.com/didi/tg-flow/tg-core/consts" - "github.com/didi/tg-flow/tg-core/model" -) - -var DimensionIndexObj *model.DimensionIndex = &model.DimensionIndex{} - -func LoadDimensionIndex() error { - dimensionIndexString, err := redis.Handler.Get(context.TODO(), consts.StrategyDimensionMap) - if err != nil && err.Error() != redis.ErrNil { - return err - } - - var dimensionIndexTemp *model.DimensionIndex - err = json.Unmarshal([]byte(dimensionIndexString), &dimensionIndexTemp) - if err != nil { - return err - } - - DimensionIndexObj.DimensionMap = dimensionIndexTemp.DimensionMap - DimensionIndexObj.UpdateTime = dimensionIndexTemp.UpdateTime - - return nil -} diff --git a/tg-core/store/machine_map.go b/tg-core/store/machine_map.go deleted file mode 100644 index 41d95760009e3bf5de56cb94ee77369fb0356286..0000000000000000000000000000000000000000 --- a/tg-core/store/machine_map.go +++ /dev/null @@ -1,43 +0,0 @@ -package store - -import ( - "context" - "encoding/json" - "github.com/didi/tg-flow/tg-core/common/redis" - "github.com/didi/tg-flow/tg-core/common/tlog" - "github.com/didi/tg-flow/tg-core/consts" -) - -var MachineIpMap map[string][]string = make(map[string][]string) - -func LoadMachineIp(appId int) error { - machineIpStr := redis.GetRedis(context.TODO(), nil, redis.Handler, consts.RedisKeyMachineIp, "task.LoadMachineIp") - - if machineIpStr == "" { - return nil - } - - var machineIpMap map[int]map[string][]string - err := json.Unmarshal([]byte(machineIpStr), &machineIpMap) - if err != nil { - return err - } - - //只获取本系统下的机器ip - tempMachineIpMap := make(map[string][]string) - //appId := *(*int)(unsafe.Pointer(&module.AppId)) - - if tempMap := machineIpMap[appId]; tempMap != nil { - for machineRoom, ipList := range tempMap { - tempMachineIpMap[machineRoom] = ipList - } - } - - if len(tempMachineIpMap) <= 0 { - return nil - } - - MachineIpMap = tempMachineIpMap - tlog.Handler.Infof(context.TODO(), consts.DLTagCronTask, "etype=task.LoadMachineIp||machineIpMap=%v", MachineIpMap) - return nil -} diff --git a/tg-core/store/workflow_map.go b/tg-core/store/workflow_map.go deleted file mode 100644 index 36669d534fab69b629400eadd8a8d35ab6e5a607..0000000000000000000000000000000000000000 --- a/tg-core/store/workflow_map.go +++ /dev/null @@ -1,28 +0,0 @@ -package store - -import ( - "context" - "encoding/json" - "github.com/didi/tg-flow/tg-core/common/redis" - "github.com/didi/tg-flow/tg-core/consts" - "github.com/didi/tg-flow/tg-core/model" -) - -var WorkflowMap map[int64]model.Workflow = make(map[int64]model.Workflow) - -func LoadWorkflow() error { - workflowMapByte, err := redis.Handler.Get(context.TODO(), consts.StrategyWorkflowMap) - if err != nil && err.Error() != redis.ErrNil { - return err - } - - var workflowMap map[int64]model.Workflow - err = json.Unmarshal([]byte(workflowMapByte), &workflowMap) - if err != nil { - return err - } - - WorkflowMap = workflowMap - - return nil -} diff --git a/tg-core/wfengine/action_counter.go b/tg-core/wfengine/action_counter.go deleted file mode 100644 index aa4cc1b0a007fcf080f9d2fa8a6f8975ce341b7b..0000000000000000000000000000000000000000 --- a/tg-core/wfengine/action_counter.go +++ /dev/null @@ -1,9 +0,0 @@ -package wfengine - -import "sync" - -type ActionCounter struct { - wgMap map[string]*sync.WaitGroup - skipedActionIdPairs *sync.Map - -} diff --git a/tg-core/wfengine/apollo/apollo_config.go b/tg-core/wfengine/apollo/apollo_config.go deleted file mode 100644 index ad976039bad03b4bb387d05a6d4b8e59eb2bf567..0000000000000000000000000000000000000000 --- a/tg-core/wfengine/apollo/apollo_config.go +++ /dev/null @@ -1,31 +0,0 @@ -package apollo - -import ( - "go.intra.xiaojukeji.com/apollo/apollo-golang-sdk-v2" - "go.intra.xiaojukeji.com/apollo/apollo-golang-sdk-v2/model" -) - -type AppConfig struct { - config *model.ConfResult -} - -func NewApolloConfig(namespace string, configName string) (*AppConfig, error){ - cfg, err := apollo.GetConfig(namespace, configName) - if err != nil { - return nil, err - } - - return &AppConfig{config: cfg}, nil -} - -func (a *AppConfig) IsVersion(version string) bool { - if version == a.config.GetVersion(){ - return true - } - - return false -} - -func (a *AppConfig) GetConfigs() map[string]string { - return a.config.GetConfigs() -} \ No newline at end of file diff --git a/tg-core/wfengine/logger_interface.go b/tg-core/wfengine/logger_interface.go deleted file mode 100644 index 090acdd83ae2a0ea5393890f21db4b9df4841752..0000000000000000000000000000000000000000 --- a/tg-core/wfengine/logger_interface.go +++ /dev/null @@ -1,37 +0,0 @@ -package wfengine -/* -import ( - "bytes" - "context" - "log" - "sync" -) - -type Logger interface { - Error(ctx context.Context, tag string, errMsg string) -} - -var Log Logger -var logOnce sync.Once -func SetLogger(logger Logger){ - Log = logger -} - -func ConfirmLoggerInit() { - logOnce.Do(func(){ - if Log == nil { - Log = &DefaultLogger{} - } - }) -} - -type DefaultLogger struct {} - -func (i *DefaultLogger) Error(ctx context.Context, tag string, errMsg string){ - buf := bytes.Buffer{} - buf.WriteString("[ERROR]||tag=") - buf.WriteString(tag) - buf.WriteString("||errMsg=") - buf.WriteString(errMsg) - log.Println(buf.String()) -}*/ \ No newline at end of file diff --git a/tg-core/wfengine/scene_module_store.go b/tg-core/wfengine/scene_module_store.go deleted file mode 100644 index ee8ddd305702712252fd3543d04ac6be73c7061d..0000000000000000000000000000000000000000 --- a/tg-core/wfengine/scene_module_store.go +++ /dev/null @@ -1,74 +0,0 @@ -/** - Description : loader of scene and module config info - Author : dayunzhangyunfeng@didiglobal.com - Date : 2021-05-14 -*/ - -package wfengine - -import ( - "context" - "encoding/json" - "fmt" - "github.com/didi/tg-flow/tg-core/common/redis" - "io/ioutil" - "os" -) - -const ( - //新版redis key - RedisKeySceneModule = "scene_module_app_" -) -func LoadSceneModuleMap(appId int64) (map[int64]*SceneModule, error) { - //加载redis中的数据到内存 - sceneModuleMap, err := loadSceneModules(appId) - if err != nil { - return sceneModuleMap, err - } - - //根据app_id,获取对应的场景id - for sceneId, sceneModule := range sceneModuleMap { - if sceneModule.AppId != appId { - delete(sceneModuleMap, sceneId) - } - } - - return sceneModuleMap, nil -} - -//获取redis中的数据 -func loadSceneModules(appId int64) (map[int64]*SceneModule, error) { - sceneModuleMapString, err := redis.Handler.Get(context.TODO(), fmt.Sprintf("%v%v", RedisKeySceneModule, appId)) - if err != nil && err.Error() != redis.ErrNil { - return nil, err - } - - var sceneModuleMap map[int64]*SceneModule - err = json.Unmarshal([]byte(sceneModuleMapString), &sceneModuleMap) - if err != nil { - return nil, fmt.Errorf("err:%v, sceneModule:%v", err, sceneModuleMapString) - } - - return sceneModuleMap, nil -} - -func LoadSceneModuleMapFromFile(path string) (map[int64]*SceneModule, error) { - jsonFile, err := os.Open(path) - if err != nil { - return nil, fmt.Errorf("os.open error, file:%v, err:%v", path, err) - } - defer jsonFile.Close() - - byteValue, err := ioutil.ReadAll(jsonFile) - if err != nil { - return nil, fmt.Errorf("ioutil.ReadAll error, byteValue:%v,err=%v", string(byteValue), err) - } - - var sceneModuleMap map[int64]*SceneModule - err = json.Unmarshal(byteValue, &sceneModuleMap) - if err != nil { - return nil, fmt.Errorf("json.Unmarshal error, byteValue:%v,err=%v", string(byteValue), err) - } - - return sceneModuleMap, nil -} \ No newline at end of file diff --git a/tg-service/README.md b/tg-service/README.md deleted file mode 100644 index c6e679284e7fc693dae9de429a3753ce01428bae..0000000000000000000000000000000000000000 --- a/tg-service/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# tg-service -算法平台管理系统 - -## 系统介绍 -对包含接入算法平台的在线策略服务和模型服务在内的所有系统进行分模块的统一管理,同时用于连接在线与离线,模型与特征,实现各个子系统之间数据的联通和流程的联动,以提升算法平台使用的便捷性。 - -## 部署步骤 -##### 1. 进入项目目录 -cd tg-service - -##### 2. 编译源代码 -make - -##### 3. 部署服务 -./tg-service(加载编译好的二进制文件) - -##### 4. 检查服务 -查看相应的端口号是否被占用 diff --git a/tg-service/common/logs/dltag.go b/tg-service/common/logs/dltag.go deleted file mode 100644 index 314f020062fc2d5882a812e61d97e6df1c7e544d..0000000000000000000000000000000000000000 --- a/tg-service/common/logs/dltag.go +++ /dev/null @@ -1,22 +0,0 @@ -package logs - -const ( - DLTagLoadExperimentWorkflowFail = " _com_strategyadmin_load_experiment_workflow_fail" - DLTagLoadOldWorkflowFail = " _com_strategyadmin_load_old_workflow_fail" - DLTagLoadDBFail = " _com_strategyadmin_load_db_fail" - - DLTagSystemPanic = " _com_strategyadmin_system_panic" - - DLTagLoginSetRedisKey = " _com_strategyadmin_login_set_redis_key" - DLTagProcessLog = " _com_strategyadmin_process_log" - - DLTagLoadRankerHost = " _com_strategyadmin_load_ranker_host" - DLTagLoadRankerHostFail = " _com_strategyadmin_load_ranker_host_fail" - DLTagDelRankerHostFail = " _com_strategyadmin_del_ranker_host_fail" - - DLTagSearchDebugInfoFail = " _com_strategyadmin_search_debug_info_fail" - - DLTagEventPost = "_com_strategyadmin_event_post_failed" - - DLTagGitApiFail = " com_strategyadmin_git_api_failed" -) diff --git a/tg-service/common/template/init.go b/tg-service/common/template/init.go deleted file mode 100644 index 8fcd5cbd8894fdc0535e28101b1fb7ad4b598849..0000000000000000000000000000000000000000 --- a/tg-service/common/template/init.go +++ /dev/null @@ -1,63 +0,0 @@ -package template - -import ( - "github.com/didi/tg-flow/tg-core/common/path" - "html/template" - "net/http" -) - -var Handler *template.Template - -//模型状态编号和中文映射关系 -var ModelNameMap map[string]int = make(map[string]int) -var ModelStatusMap map[int]string = make(map[int]string) - -//场景编号和中文映射关系 -var AppNameMap map[string]int = make(map[string]int) -var AppIdMap map[int]string = make(map[int]string) - -//索引状态编号和中文映射关系 -var IndexNameMap map[string]int = make(map[string]int) -var IndexIdMap map[int]string = make(map[int]string) - -//场景编号和场景名称映射关系 -var SceneNameAndIdMap map[string]int = make(map[string]int) -var SceneIdAndNameMap map[int]string = make(map[int]string) - -//场景组编号和场景组名称映射关系 -var SceneNameAndIdsMap map[string]int = make(map[string]int) -var SceneIdsAndNameMap map[int]string = make(map[int]string) - -//流量主从和主从编号映射关系 -var DefultNameAndIdMap map[string]int = make(map[string]int) -var DefultIdAndNameMap map[int]string = make(map[int]string) - -func init() { - Handler = template.Must(template.ParseGlob(path.Root + "/template/*.html")) - ModelNameMap["未知"] = -1 - ModelNameMap["待上线"] = 1 - ModelNameMap["上线失败"] = 2 - ModelNameMap["已上线"] = 3 - - ModelStatusMap[-1] = "未知" - ModelStatusMap[1] = "待上线" - ModelStatusMap[2] = "上线失败" - ModelStatusMap[3] = "已上线" - - IndexNameMap["离线"] = 0 - IndexNameMap["在线"] = 1 - - IndexIdMap[0] = "离线" - IndexIdMap[1] = "在线" - - DefultNameAndIdMap["从"] = 0 - DefultNameAndIdMap["主"] = 1 - - DefultIdAndNameMap[0] = "从" - DefultIdAndNameMap[1] = "主" -} - -func Render(w http.ResponseWriter, name string, data interface{}) error { - w.Header().Set("Content-Type", "text/html; charset=utf-8") - return Handler.ExecuteTemplate(w, name, data) -} diff --git a/tg-service/conf/init.go b/tg-service/conf/init.go deleted file mode 100644 index a657df8a0e4d0124bd244d7c7a9ca69f8841aed7..0000000000000000000000000000000000000000 --- a/tg-service/conf/init.go +++ /dev/null @@ -1,42 +0,0 @@ -/** - @Description: - @Author:zhouzichun - @Date:2023/5/7 -**/ - -package conf - -import ( - "github.com/didi/tg-flow/tg-core/conf" - "github.com/didi/tg-flow/tg-core/router" - "log" - "tg-service/constant" - "tg-service/controller" -) - -func init() { - log.Println("point-admin router init...") - svc := new(controller.RPCService) - router.Handler.POST("/checklogin", svc.CheckLogin) - router.Handler.POST("/login", svc.Login) - router.Handler.POST("/logout", svc.Logout) - - //workflow相关操作(新) - router.Handler.POST("/searchWorkFlow", svc.SearchWorkFlow) - router.Handler.POST("/addOrUpdateWorkFlow", svc.AddOrUpdateWorkFlow) - router.Handler.POST("/deleteWorkFlow", svc.DeleteWorkFlow) - router.Handler.POST("/exportWorkFlow", svc.ExportWorkFlow) - router.Handler.POST("/getWorkFlowChart", svc.GetWorkFlowChart) - router.Handler.POST("/saveWorkFlowChart", svc.SaveWorkFlowChart) - router.Handler.POST("/importWorkFlow", svc.ImportWorkFlow) -} - -func InitConfig() { - //初始化:获取配置文件中sso服务接口地址 - var err error - if constant.Env, err = conf.Handler.GetSetting("env", "type"); err != nil { - log.Println("Fail to init env!", err) - return - } - log.Println("point-admin config init finished") -} diff --git a/tg-service/conf/mysql_compile/app_config b/tg-service/conf/mysql_compile/app_config deleted file mode 100644 index c8fe50b4ed647e808e0c73f2e1becb995df53358..0000000000000000000000000000000000000000 --- a/tg-service/conf/mysql_compile/app_config +++ /dev/null @@ -1,11 +0,0 @@ -CREATE TABLE `your_table_name` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `app_name` varchar(50) NOT NULL, - `machine_room` varchar(50) NOT NULL, - `node_name` varchar(50) NOT NULL, - `operator` varchar(20) NOT NULL, - `create_time` datetime NOT NULL DEFAULT '1970-01-01 08:00:00', - `update_time` datetime NOT NULL DEFAULT '1970-01-01 08:00:00', - `git_url` varchar(100) NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/tg-service/conf/mysql_compile/scene_config b/tg-service/conf/mysql_compile/scene_config deleted file mode 100644 index cda3a1ba2ca9376047116be12416bf0a42ff5993..0000000000000000000000000000000000000000 --- a/tg-service/conf/mysql_compile/scene_config +++ /dev/null @@ -1,13 +0,0 @@ -CREATE TABLE `scene_config` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `name` varchar(50) NOT NULL, - `app_id` int(11) NOT NULL DEFAULT 0, - `bucket_type` int(11) NOT NULL DEFAULT 0, - `create_time` datetime NOT NULL DEFAULT '1971-01-01 08:00:00', - `update_time` datetime NOT NULL DEFAULT '1971-01-01 08:00:00', - `operator` varchar(20) NOT NULL, - `flow_type` int(4) NOT NULL DEFAULT 0, - `name_zh` varchar(8192) NOT NULL, - `exp_name` varchar(128) NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/tg-service/conf/mysql_compile/workflow b/tg-service/conf/mysql_compile/workflow deleted file mode 100644 index 11d7c9eb10175af9d77ad5f4be99df859bd2dce0..0000000000000000000000000000000000000000 --- a/tg-service/conf/mysql_compile/workflow +++ /dev/null @@ -1,19 +0,0 @@ -CREATE TABLE `workflow` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `dimension_id` int(11) NOT NULL DEFAULT -1, - `experiment_id` bigint(20) NOT NULL DEFAULT 0, - `modules` varchar(8192) NOT NULL, - `flow_chart` varchar(10240) NOT NULL, - `is_default` int(11) NOT NULL DEFAULT 0, - `status` int(11) NOT NULL DEFAULT 1, - `range1` varchar(300) NOT NULL DEFAULT '0,1', - `range2` varchar(300) NOT NULL DEFAULT '[0-1]', - `remark` text NOT NULL, - `create_time` datetime NOT NULL DEFAULT '2018-09-20 10:00:00', - `update_time` datetime NOT NULL DEFAULT '2018-09-20 10:00:00', - `operator` varchar(50) NOT NULL DEFAULT 'admin', - `manual_slot_ids` varchar(200) NOT NULL, - `group_name` varchar(100) NOT NULL, - PRIMARY KEY (`id`), - KEY `experiment_id` (`experiment_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; \ No newline at end of file diff --git a/tg-service/constant/const.go b/tg-service/constant/const.go deleted file mode 100644 index fcdbc12497ea2897059655740533b5431154951b..0000000000000000000000000000000000000000 --- a/tg-service/constant/const.go +++ /dev/null @@ -1,46 +0,0 @@ -package constant - -var Env string - -var SsoAppId string -var SsoAppKey string -var LoginUrl string -var LogoutUrl string -var CheckCodeUrl string -var CheckTicketUrl string -var GetUserNameUrl string - -var OldSsoAppId string -var OldSsoAppKey string -var OldLoginUrl string -var OldLogoutUrl string - -var RdId string -var AdminId string -var UserInfoPermissUrl string -var UpmPermissUrl string - -var HttpTimeOut int64 = 500 - -var Msg string = "请申请相应角色,获取权限:" - -const NameSpaceOnlineDebug = "140" -const NameSpacePointSys = "point_sys" -const ToggleIdOnlineDebug = "155765" -const WhiteKeyOnlineDebug = "phone" - -const ToggleNotFound = "toggle not found" - -const ApolloSettingNameSpace = "point_arch" -const ApolloTypeAB = "ab" -const ApolloTypeGray = "gray" - -// WorkflowConfigName Apollo workflow 配置名称 -const WorkflowConfigName = "workflow" - -// ConfigBlacklist 不允许在自定义配置中使用的 Key -var ConfigBlacklist = map[string]struct{}{ - WorkflowConfigName: {}, -} - -const ApolloServicePrefix = "map_base_" diff --git a/tg-service/controller/controller.go b/tg-service/controller/controller.go deleted file mode 100644 index 7d9203dae9508bc6e1372c9028d3e6ccec7ae8b3..0000000000000000000000000000000000000000 --- a/tg-service/controller/controller.go +++ /dev/null @@ -1,147 +0,0 @@ -/** - * This file is auto-generated by dirpcgen don't modify manaully - * - * Copyright (c) 2018 didichuxing.com, Inc. All Rights Reserved - * - * Generated-date: 2018-07-13 - */ - -package controller - -import ( - "context" - "github.com/didi/tg-flow/tg-core/common/tlog" - "github.com/didi/tg-flow/tg-core/common/utils" - ngs "git.xiaojukeji.com/nuwa/nuwa-go-httpserver/v2" - "net/http" - "tg-service/common/logs" - "tg-service/constant" - "tg-service/idl" - "tg-service/logic" -) - -type RPCService struct { - ngs.BaseController -} - -var isNewAdmin bool - -/** - * 登录校验1 - */ -func (h RPCService) CheckLogin(w http.ResponseWriter, r *http.Request) { - defer utils.Recover(context.TODO(), nil, logs.DLTagSystemPanic, "logic_CheckLogin") - responseInfo := &idl.ResponseInfo{} - data := logic.ParsRequestParam(r) - tlog.Handler.Infof(context.TODO(), logs.DLTagProcessLog, "etype=controller_CheckLogin||econtent=%v||err=", data) - if data.UserCookie == "" { - responseInfo.Tag = false - responseInfo.ErrMsg = "用户cookie为空,需要登录" - } else { - tag, err := logic.Login(r.FormValue("usercookie"), r.FormValue("passcookie")) - if tag { - responseInfo.Tag = true - responseInfo.ErrMsg = "success" - } else { - responseInfo.Tag = false - responseInfo.TypeNum = 1 //登录校验不通过 - responseInfo.ErrMsg = err - } - } - logic.EchoJSON(w, r, responseInfo) -} - -/** - * 登录校验2 - */ -func (h RPCService) Login(w http.ResponseWriter, r *http.Request) { - defer utils.Recover(context.TODO(), nil, logs.DLTagSystemPanic, "logic_Login") - responseInfo := &idl.ResponseInfo{} - data := logic.ParsRequestParam(r) - data.UserCookie = r.FormValue("username") - tlog.Handler.Infof(context.TODO(), logs.DLTagProcessLog, "etype=controller_Login||econtent=%v||err=", data) - tag, err := logic.Login(r.FormValue("username"), r.FormValue("password")) - if tag { - responseInfo.Tag = true - responseInfo.ErrMsg = "success" - } else { - responseInfo.Tag = false - responseInfo.ErrMsg = err - } - logic.EchoJSON(w, r, responseInfo) -} - -//退出系统 -func (h RPCService) Logout(w http.ResponseWriter, r *http.Request) { - logOutUrl := constant.LogoutUrl - hashCache, _ := r.Cookie("__hash__cache") - referer := r.Referer() - if hashCache == nil || referer != "http://strategy-arch-platform.intra.xiaojukeji.com/" { - logOutUrl = constant.OldLogoutUrl - } - responseInfo := &idl.ResponseInfo{ - Tag: false, - ErrMsg: logOutUrl, - } - logic.EchoJSON(w, r, responseInfo) -} - -func ReturnOpFailMsg(w http.ResponseWriter, r *http.Request, errMsg string) { - responseInfo := &idl.ResponseInfo{ - Tag: false, - TypeNum: 2, //权限校验不通过 - ErrMsg: errMsg, - } - w.WriteHeader(http.StatusFound) - logic.EchoJSON(w, r, responseInfo) -} - -//如果登录校验通过,则统一返回信息 -func ReturnLoginSuccessMsg(w http.ResponseWriter, r *http.Request, content interface{}) { - responseInfo := &idl.ResponseInfo{ - Tag: true, - Content: content, - } - logic.EchoJSON(w, r, responseInfo) -} - -// -//如果登录校验通过,则统一返回信息 -func ReturnLoginSuccessMessage(w http.ResponseWriter, r *http.Request, content interface{}) { - - responseMsg := &idl.ResponseMsg{ - Code: 0, - Message: "Sucess!", - Data: content, - } - - logic.EchoToJSON(w, r, responseMsg) -} - -func ReturnOpFailMessage(w http.ResponseWriter, r *http.Request, errMsg string) { - responseMsg := &idl.ResponseMsg{ - Code: 1, - Message: "权限校验不通过", //权限校验不通过 - } - w.WriteHeader(http.StatusFound) - logic.EchoToJSON(w, r, responseMsg) -} - -//如果登录校验不通过,则统一返回提示信息 -func ReturnLoginFailMessage(w http.ResponseWriter, r *http.Request) { - responseMsg := &idl.ResponseMsg{ - Code: 2, - Message: "登录校验不通过", //登录校验不通过 - } - w.WriteHeader(http.StatusFound) - logic.EchoToJSON(w, r, responseMsg) -} - -func ReturnFailMessage(w http.ResponseWriter, r *http.Request, errMsg string) { - responseMsg := &idl.ResponseInfo{ - Tag: false, - ErrMsg: errMsg, - } - w.WriteHeader(http.StatusFound) - logic.EchoToJSON(w, r, responseMsg) -} diff --git a/tg-service/controller/workflow_controller.go b/tg-service/controller/workflow_controller.go deleted file mode 100644 index 042db23876a5137e634316e355d216d40656d807..0000000000000000000000000000000000000000 --- a/tg-service/controller/workflow_controller.go +++ /dev/null @@ -1,167 +0,0 @@ -/** - * This file is auto-generated by dirpcgen don't modify manaully - * - * Copyright (c) 2018 didichuxing.com, Inc. All Rights Reserved - * - * Generated-date: 2018-07-13 - */ - -package controller - -import ( - "context" - "encoding/json" - "fmt" - "github.com/didi/tg-flow/tg-core/common/tlog" - "github.com/didi/tg-flow/tg-core/common/utils" - "net/http" - "strconv" - "tg-service/common/logs" - "tg-service/idl" - "tg-service/logic" - "tg-service/logic/workflowadmin" -) - -//查询workflow信息 -func (h RPCService) SearchWorkFlow(w http.ResponseWriter, r *http.Request) { - defer utils.Recover(context.TODO(), nil, logs.DLTagSystemPanic, "controller.SearchWorkFlow") - data, err := logic.ParsRequsetWorkFlowParam(r) - tlog.Handler.Infof(context.TODO(), logs.DLTagProcessLog, "etype=controller.SearchWorkFlow||data=%v||err=%v", data, err) - if err != nil { - workFlowList := make([]*idl.WorkFlowConfig, 0) - logic.EchoJSON(w, r, workFlowList) - } else { - if data.Operator == "" { - ReturnLoginFailMessage(w, r) - } else { - pageLimit, pageNum := logic.ParsRequestPageParam(r) - useLimit := false - if pageLimit != 0 && pageNum != 0 { - useLimit = true - } - workFlowList, _ := workflowadmin.SelectWorkFlowConfig(data, pageLimit, pageNum, useLimit) - ReturnLoginSuccessMsg(w, r, workFlowList) - } - } -} - -//新增和修改workflow信息 -func (h RPCService) AddOrUpdateWorkFlow(w http.ResponseWriter, r *http.Request) { - defer utils.Recover(context.TODO(), nil, logs.DLTagSystemPanic, "controller.AddOrUpdateWorkFlow") - - data, err := logic.ParsRequsetWorkFlowParam(r) - - tlog.Handler.Infof(context.TODO(), logs.DLTagProcessLog, "etype=controller.AddOrUpdateWorkFlow||data=%v||err=%v", data, err) - - if err != nil { - logic.EchoJSON(w, r, &idl.ResponseInfo{Tag: false, ErrMsg: err.Error()}) - } else { - if data.Operator == "" { - ReturnLoginFailMessage(w, r) - } else { - logic.EchoJSON(w, r, workflowadmin.AddOrUpdateWorkFlowConfig(data)) - } - } -} - -//删除workflow信息 -func (h RPCService) DeleteWorkFlow(w http.ResponseWriter, r *http.Request) { - defer utils.Recover(context.TODO(), nil, logs.DLTagSystemPanic, "controller.DeleteWorkFlow") - data, err := logic.ParsRequsetWorkFlowParam(r) - tlog.Handler.Infof(context.TODO(), logs.DLTagProcessLog, "etype=controller.DeleteWorkFlow||data=%v||err=%v", data, err) - if err != nil { - logic.EchoJSON(w, r, &idl.ResponseInfo{Tag: false, ErrMsg: err.Error()}) - } else { - if data.Operator == "" { - ReturnLoginFailMessage(w, r) - } else { - logic.EchoJSON(w, r, workflowadmin.DeleteWorkflowConfig(data)) - } - } -} - -//导出workflow信息 -func (h RPCService) ExportWorkFlow(w http.ResponseWriter, r *http.Request) { - defer utils.Recover(context.TODO(), nil, logs.DLTagSystemPanic, "controller.ExportWorkFlow") - data, err := logic.ParsRequsetWorkFlowParam(r) - tlog.Handler.Infof(context.TODO(), logs.DLTagProcessLog, "etype=controller.ExportWorkFlow||data=%v||err=%v", data, err) - if err != nil { - logic.EchoJSON(w, r, &idl.ResponseInfo{Tag: false, ErrMsg: err.Error()}) - } else { - if data.Operator == "" { - ReturnLoginFailMessage(w, r) - } else { - logic.EchoJSON(w, r, workflowadmin.ExportWorkFlow(data)) - } - } -} - -// ImportWorkFlow 导入workflow信息 -func (h RPCService) ImportWorkFlow(w http.ResponseWriter, r *http.Request) { - // - defer utils.Recover(context.TODO(), nil, logs.DLTagSystemPanic, "controller.ImportWorkFlow") - // 获取流程图信息和操作者信息,以及workflowId - dataJson := logic.CancelEmptyStr(r.FormValue("dataJson")) - username, _ := r.Cookie("username") - var operator string - if username != nil { - operator = logic.CancelEmptyStr(username.Value) - } - workflowId, _ := strconv.ParseInt(r.FormValue("workflowid"), 10, 64) - // - tlog.Handler.Infof(context.TODO(), logs.DLTagProcessLog, "etype=controller.importWorkFlow||data=%v", dataJson) - - if operator == "" { - ReturnLoginFailMessage(w, r) - } else { - workflowChart := new(idl.WorkflowChart) - err := json.Unmarshal([]byte(dataJson), &workflowChart) - if err != nil { - logic.EchoJSON(w, r, &idl.ResponseInfo{Tag: false, ErrMsg: err.Error()}) - } else { - logic.EchoJSON(w, r, workflowadmin.SaveImportWorkFlowChart(workflowChart, workflowId, operator)) - } - } - -} - -//获取流程图信息 -func (h RPCService) GetWorkFlowChart(w http.ResponseWriter, r *http.Request) { - defer utils.Recover(context.TODO(), nil, logs.DLTagSystemPanic, "controller.GetWorkFlowChart") - data, err := logic.ParsRequsetWorkFlowParam(r) - tlog.Handler.Infof(context.TODO(), logs.DLTagProcessLog, "etype=controller.getWorkFlowChart||data=%v||err=%v", data, err) - if err != nil { - logic.EchoJSON(w, r, &idl.ResponseInfo{Tag: false, ErrMsg: err.Error()}) - } else { - if data.Operator == "" { - ReturnLoginFailMessage(w, r) - } else { - logic.EchoJSON(w, r, workflowadmin.GetWorkFlowChart(data)) - } - } -} - -//保存流程图修改 -func (h RPCService) SaveWorkFlowChart(w http.ResponseWriter, r *http.Request) { - defer utils.Recover(context.TODO(), nil, logs.DLTagSystemPanic, "controller.SaveWorkFlowChart") - dataJson := logic.CancelEmptyStr(r.FormValue("dataJson")) - operator := logic.CancelEmptyStr(r.FormValue("operator")) - err := logic.CheckParam(r.FormValue("workflowid")) - if err != nil { - logic.EchoJSON(w, r, &idl.ResponseInfo{Tag: false, ErrMsg: fmt.Errorf("实验编号需要是数字").Error()}) - } - workflowId, _ := strconv.ParseInt(r.FormValue("workflowid"), 10, 64) - tlog.Handler.Infof(context.TODO(), logs.DLTagProcessLog, "etype=controller.saveWorkFlowChart||data=%v", dataJson) - - flowChart := new(idl.ChartG6) - err = json.Unmarshal([]byte(dataJson), &flowChart) - if err != nil { - logic.EchoJSON(w, r, &idl.ResponseInfo{Tag: false, ErrMsg: err.Error()}) - } else { - if operator == "" { - ReturnLoginFailMessage(w, r) - } else { - logic.EchoJSON(w, r, workflowadmin.SaveWorkFlowChart(flowChart, workflowId, operator)) - } - } -} diff --git a/tg-service/cron/cron_task.go b/tg-service/cron/cron_task.go deleted file mode 100644 index d272f5d0823c6f132c0e5fa6d8bc528ef3c1ab21..0000000000000000000000000000000000000000 --- a/tg-service/cron/cron_task.go +++ /dev/null @@ -1,22 +0,0 @@ -/** - author:dingyi - time:2019-08-28 -**/ - -package cron - -import ( - "github.com/didi/tg-flow/tg-core/common/crontask" -) - -const ( - //定时任务周期 - BASE_TASK_TIME = "0 0/2 * * * ?" - HOUR_TASK_TIME = "0 0 0/4 * * ?" -) - -func StartCronTask() { - - //启动所有定时任务 - crontask.TaskStart() -} diff --git a/tg-service/go.mod b/tg-service/go.mod deleted file mode 100644 index 58c1a8f1f9fbab0d1d89c09a0e9569c65ca3e17c..0000000000000000000000000000000000000000 --- a/tg-service/go.mod +++ /dev/null @@ -1,8 +0,0 @@ -module tg-service - -go 1.17 - -require ( - github.com/didi/tg-flow/tg-core v0.0.0-20230518032332-3b95688f6d4f - github.com/gin-gonic/gin v1.9.0 -) \ No newline at end of file diff --git a/tg-service/idl/types.go b/tg-service/idl/types.go deleted file mode 100644 index 7893794d43ded79897e00167aa7cdfea4462cd7a..0000000000000000000000000000000000000000 --- a/tg-service/idl/types.go +++ /dev/null @@ -1,718 +0,0 @@ -/** - * This file is auto-generated by dirpcgen - * - * Copyright (c) 2018 didichuxing.com, Inc. All Rights Reserved - * - * Generated-date: 2018-07-13 - */ - -package idl - -import ( - "github.com/didi/tg-flow/tg-core/wfengine" -) - -type NoticeRequestInfo struct { - RequestId string `thrift:"request_id,1,required" json:"request_id"` - NoticeType string `thrift:"notice_type,2,required" json:"notice_type"` - NoticeInfo string `thrift:"notice_info,3,required" json:"notice_info"` -} - -type LoginInfo struct { - UserName string `thrift:"user_name,1,required" json:"user_name"` - PassWord string `thrift:"pass_word,2,required" json:"pass_word"` -} - -type ResponseInfo struct { - Tag bool `thrift:"request_id,1,required" json:"tag"` - TypeNum int `thrift:"err_msg,2,required" json:"typenum"` - ErrMsg string `thrift:"err_msg,3,required" json:"err_msg"` - Content interface{} `thrift:"err_msg,4,required" json:"content"` -} - -type ResponseMsg struct { - Code int `thrift:"request_id,1,required" json:"code"` - Message string `thrift:"err_msg,2,required" json:"message"` - Data interface{} `thrift:"err_msg,3,required" json:"data"` -} - -type WorkFlowData struct { - ExperimentId string `json:"experimentid"` - OldWorkFlowId string `json:"oldworkflowid"` - WorkFlowId string `json:"workflowid"` - Modules string `json:"modules"` - Proportion string `json:"proportion"` - Defult string `json:"defult"` - Remark string `json:"remark"` - UserCookie string `json:"usercookie"` - CreateTime string `json:"createtime"` - UpdateTime string `json:"updatetime"` - Operator string `json:"operator"` - ManualSlotIds string `json:"manual_slot_ids"` -} - -type SenceData struct { - ExperimentId string `json:"experimentid"` - Name string `json:"name"` - AppName string `json:"appname"` - BucketType string `json:"buckettype"` - UserCookie string `json:"usercookie"` -} - -type WorkFlow struct { - Id int64 `json:"id"` - DimensionId int64 `json:"dimension_id"` - ExperimentId int64 `json:"experimentId"` - Modules string `json:"modules"` - IsDefault int `json:"isDefault"` - Range1 string `json:"range1"` - Range2 string `json:"range2"` - Remark string `json:"remark"` - CreateTime string `json:"createtime"` - UpdateTime string `json:"updatetime"` - Operator string `json:"operator"` - ManualSlotIds string `json:"manual_slot_ids"` - GroupName string `json:"group_name"` - FlowCharts string `json:"flow_charts"` -} - -type Asd struct { - Experimentid string - Usercookie string - Passcookie string -} - -type UserInfo struct { - UserName string - PassWord string - RoleId int -} - -type RankConfig struct { - Id int64 `json:"id"` - Ip string `json:"ip"` - SceneId string `json:"sceneId"` - AlgoName string `json:"algoname"` - ModelName string `json:"modelname"` - ModelVersion string `json:"modelversion"` - Status string `json:"status"` - HistoryConfig string `json:"historyconfig"` - Operator string `json:"operator"` - CreateTime string `json:"createtime"` - UpdateTime string `json:"updatetime"` - AutoUpdate string `json:"autoupdate"` - MachineRoom string `json:"machineRoom"` -} - -type RankerService struct { - Id int64 `json:"id"` - AppId string `json:"app_id"` - SceneId string `json:"scene_id"` - ServiceUsn string `json:"service_usn"` - AlgoName string `json:"algo_name"` - ModelName string `json:"model_name"` - ModelVersion string `json:"model_version"` - HistoryConfig string `json:"history_config"` - Operator string `json:"operator"` - CreateTime string `json:"create_time"` - UpdateTime string `json:"update_time"` - AutoUpdateVersion string `json:"auto_update_version"` - UsnType string `json:"usn_type"` - HdfsPath string `json:"hdfs_path"` -} - -type ServerConfig struct { - Id int64 `json:"id"` - MachineRoom string `json:"machine_room"` - Ip string `json:"ip"` - Role string `json:"role"` - IndexVersion string `json:"indexversion"` - UpdateTime string `json:"updatetime"` - Status string `json:"status"` -} - -type SceneConfig struct { - OldId int64 `json:"oldid"` - Id int64 `json:"id"` - Name string `json:"name"` - NameZh string `json:"namezh"` - AppId int `json:"appid"` - AppName string `json:"appname"` - BucketType int64 `json:"buckettype"` - Operator string `json:"operator"` - CreateTime string `json:"createtime"` - UpdateTime string `json:"updatetime"` - BifrostConfig string `json:"bifrost_config"` - FlowType int64 `json:"flow_type"` - ExpName string `json:"expname"` -} - -type SceneFeature struct { - Id int64 `json:"id"` - SceneName string `json:"scene_name"` - FeatureList string `json:"feature_list"` - Operator string `json:"operator"` - CreateTime string `json:"createtime"` - UpdateTime string `json:"updatetime"` -} - -type WorkFlowConfig struct { - SceneName string `json:"scenename"` - OldWorkFlowId string `json:"oldworkflowid"` - WorkFlowId string `json:"workflowid"` - DimensionId int64 `json:"dimension_id"` - Modules string `json:"modules"` - ShowModules string `json:"showmodules"` - Proportion string `json:"proportion"` - Defult string `json:"defult"` - Range1 string `json:"range1"` - Range2 string `json:"range2"` - Remark string `json:"remark"` - CreateTime string `json:"createtime"` - UpdateTime string `json:"updatetime"` - Operator string `json:"operator"` - ManualSlotIds string `json:"manual_slot_ids"` - GroupName string `json:"groupname"` - SceneId int64 `json:"scene_id"` - Configured bool `json:"configured"` - FlowChartJson string `json:"flow_charts_json"` -} - -type RecSceneConfig struct { - OldId int64 `json:"oldid"` - Id int64 `json:"id"` - SceneId int64 `json:"scene_id"` - SceneName string `json:"scene_name"` - RecallRule string `json:"recall_rule"` - Operator string `json:"operator"` - CreateTime string `json:"createtime"` - UpdateTime string `json:"updatetime"` -} - -type MachineConfigInfo struct { - Id int `json:"id"` - AppId int `json:"app_id"` - AppName string `json:"app_name"` - MachineRoom string `json:"machine_room"` - DockerIp string `json:"docker_ip"` - DockerName string `json:"docker_name"` - Operator string `json:"operator"` - UpdateTime string `json:"update_time"` -} - -type SystemConfigInfo struct { - Id int `json:"id"` - AppId int `json:"app_id"` - KeyName string `json:"key_name"` - Content string `json:"content"` - Operator string `json:"operator"` - CreateTime string `json:"create_time"` - UpdateTime string `json:"update_time"` - Remark string `json:"remark"` -} - -type BifrostConfigInfo struct { - Id int `json:"id"` - SceneId int `json:"scene_id"` - BifrostValue string `json:"bifrost_value"` - Operator string `json:"operator"` - CreateTime string `json:"create_time"` - UpdateTime string `json:"update_time"` -} - -type AppConfigInfo struct { - OldId int `json:"old_id"` - Id int `json:"id"` - AppName string `json:"app_name"` - MachineRoom string `json:"machine_room"` - NodeName string `json:"node_name"` - Operator string `json:"operator"` - CreateTime string `json:"create_time"` - UpdateTime string `json:"update_time"` - Description string `json:"description"` - GitUrl string `json:"git_url"` -} - -type ResourceToSceneInfo struct { - ResourceId string `json:"resource_id"` - ResourceName string `json:"resource_name"` - SceneId string `json:"scene_id"` - SceneName string `json:"scene_name"` - ResourceInfo string `json:"resource_info"` - Operator string `json:"operator"` -} - -type DimensionConfig struct { - OldId int64 `json:"old_id"` - Id int64 `json:"id"` - Name string `json:"name"` - SceneName string `json:"scene_name"` - Content string `json:"content"` - Operator string `json:"operator"` - CreateTime string `json:"createtime"` - UpdateTime string `json:"updatetime"` -} - -type OldWorkFlowVersionConfig struct { - SceneName string `json:"scenename"` - DimensionId int64 `json:"dimension_id"` - VersionId int64 `json:"version_id"` - VersionCreateTime string `json:"version_create_time"` - Operator string `json:"operator"` -} - -type ModelConfig struct { - UserName string `json:"username"` - Id int64 `json:"id"` - SceneId int64 `json:"scene_id"` - AlgoName string `json:"algo_name"` - ModelName string `json:"model_name"` - BifrostKeyName string `json:"bifrost_key_name"` - BifrostJobId int64 `json:"bifrost_job_id"` - BifrostJobName string `json:"bifrost_job_name"` - Path string `json:"path"` - Period int64 `json:"period"` - LastTransferTime string `json:"last_transfer_time"` - LastTransferVersion int64 `json:"last_transfer_version"` - LastTransferResult string `json:"last_transfer_result"` - Operator string `json:"operator"` - CreateTime string `json:"create_time"` - UpdateTime string `json:"update_time"` - Status int64 `json:"status"` - Limit int64 `json:"limit"` -} -type DdlConfig struct { - Id string `json:"id"` - RegionName string `json:"region_name"` - ProjectUUID string `json:"projectUUID"` - Token string `json:"token"` - UserUUID string `json:"userUUID"` - Operator string `json:"operator"` - CreateTime string `json:"create_time"` - UpdateTime string `json:"update_time"` -} -type CityOpenConfig struct { - Id int64 `json:"id"` - CityId int64 `json:"city_id"` - SceneId int64 `json:"scene_id"` - IsOpen int64 `json:"is_open"` - BegDate string `json:"beg_date"` - EndDate string `json:"end_date"` - RotationPattern string `json:"rotation_pattern"` - Budget int64 `json:"budget"` - Operator string `json:"operator"` - CreateTime string `json:"create_time"` - UpdateTime string `json:"update_time"` -} -type GitLabFileConfig struct { - FileName string `json:"file_name"` - FilePath string `json:"file_path"` - Size string `json:"size"` - Encoding string `json:"encoding"` - ContentSha256 string `json:"beg_date"` - Ref string `json:"ref"` - BlobId string `json:"blob_id"` - CommitId string `json:"commit_id"` - LastCommitId string `json:"last_commit_id"` - Content string `json:"content"` -} - -type SceneName struct { - SceneName string -} -type NodeTypeMenu struct { - NodeType string -} -type NodeType struct { - NodeType string `json:"node_type"` - NodeName []string `json:"node_name"` -} - -//前端传入时 NodeName是 NodeType.NodeName 返回结果时是NodeName -type NodeNameMenu struct { - NodeName string -} - -type NodeParamMenu struct { - ParamName string - ParamType string -} - -type ChartG6 struct { - Nodes []*Node `json:"nodes"` - Edges []*Edge `json:"edges"` -} - -type Node struct { - Id string `json:"id"` - Label string `json:"label"` - NodeType string `json:"type"` - Params []*wfengine.Param `json:"params"` - Timeout int `json:"timeout"` - RefWorkflowId int `json:"ref_workflow_id"` - TimeoutAsync bool `json:"timeout_async"` - TimeoutDynamic bool `json:"timeout_dynamic"` - Location string `json:"location"` -} - -type Edge struct { - Id string `json:"id"` - EdgeType string `json:"type"` - Source string `json:"source"` - Target string `json:"target"` - Label string `json:"label,omitempty"` -} - -type RankerHost struct { - MachineRoom string `json:"machine_room"` - ServiceUsn string `json:"service_usn"` - Ip string `json:"ip"` - AppId int64 `json:"app_id"` - SceneId int64 `json:"scene_id"` - AlgoName string `json:"algo_name"` - ModelName string `json:"model_name"` - ModelVersion string `json:"model_version"` - ExpectVersion string `json:"expect_version"` - Status int64 `json:"status"` - UpdateTime string `json:"update_time"` - Operator string `json:"operator"` - ShowStatus string `json:"show_status"` -} - -type DebugInfo struct { - UserId string `json:"user_id"` - AppName string `json:"app_name"` - AppId int64 `json:"app_id"` - SceneId int64 `json:"scene_id"` - FlowId int64 `json:"flow_id"` - TimeStamp int64 `json:"time_stamp"` - ActionResultMap map[string]map[string]string `json:"action_result_map"` - Operator string `json:"operator"` -} - -type DebugUserInfo struct { - AppName string `json:"app_name"` - UserIdList string `json:"user_id"` - LimitNum int64 `json:"limit_num"` - Operator string `json:"operator"` - ModifyAppName string `json:"modify_app_name"` -} - -//Apollo Open API 相关 - -type ApolloLaunchInfo struct { - Code int64 `json:"code"` - Message string `json:"message"` - Data ApolloLaunchDataInfo `json:"data"` -} - -type ApolloLaunchDataInfo struct { - ToggleInfo ApolloLaunchToggleInfo `json:"toggleInfo"` - Rules [][]ApolloLaunchRuleInfo `json:"rules"` - Groups []ApolloLaunchGroupInfo `json:"groups"` -} - -type ApolloLaunchToggleInfo struct { - Name string `json:"name"` - Description string `json:"description"` - VersionDescription string `json:"versionDescription"` -} - -type ApolloLaunchRuleInfo struct { - Key string `json:"key"` - Value [][]int64 `json:"value"` - Operator string `json:"operator"` - //IsWhiteList bool `json:"isWhiteList"` -} - -type ApolloLaunchGroupInfo struct { - Name string `json:"name"` - Rule ApolloLaunchRuleInfo `json:"rule"` - WhiteList *ApolloLaunchParamInfo `json:"whiteList"` - Params []ApolloLaunchParamInfo `json:"params"` - Remark string `json:"remark"` -} - -type ApolloLaunchParamInfo struct { - Key string `json:"key"` - Type string `json:"type"` - Value interface{} `json:"value"` -} - -type ApolloResponse struct { - Code int64 `json:"code"` - Message string `json:"message"` - Data interface{} `json:"data"` -} - -type ApolloAbResponse struct { - Code int64 `json:"code"` - Message string `json:"message"` - Data ApolloAbDataInfo `json:"data"` -} - -type ApolloAbDataInfo struct { - Name string `json:"name"` - Owner string `json:"owner"` - CountryCode string `json:"countryCode"` - Experiment AbExperimentInfo `json:"experiment"` -} - -type AbExperimentInfo struct { - Partition ApolloPartitionInfo `json:"partition"` - Groups []ApolloAbGroupInfo `json:"groups"` -} - -type ApolloAbGroupInfo struct { - Name string `json:"name"` - Description string `json:"description"` - WhiteList ApolloWhiteListInfo `json:"whitelist"` - Params []ApolloLaunchParamInfo `json:"params"` -} - -type ApolloPartitionInfo struct { - Type string `json:"type"` - Value []int64 `json:"value"` -} - -type ApolloWhiteListInfo struct { - Type string `json:"type"` - Value []string `json:"value"` -} - -type Template struct { - ID int `json:"id"` - Name string `json:"name"` -} - -type ValueMeta struct { - Key string `json:"key"` - Value string `json:"value"` - Type string `json:"type"` - KeyType string `json:"keyType"` -} - -type ApolloConfigResponse struct { - Code int `json:"code"` - Message string `json:"message"` - Data []ApolloConfigData `json:"data"` -} - -type ApolloConfigUpdateResponse struct { - Code int `json:"code"` - Message string `json:"message"` - Data ApolloConfigData `json:"data"` -} -type TemplateInfo struct { -} -type Value struct { - KeyType string `json:"keyType"` - Key string `json:"key"` - Type string `json:"type"` - Value interface{} `json:"value"` -} -type Servers struct { - ID int `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - Type int `json:"type"` - CreateTime int64 `json:"createTime"` - EnvID int `json:"envId"` - IP bool `json:"ip"` - Cluster bool `json:"cluster"` - Service bool `json:"service"` -} -type Handler struct { -} -type Region struct { - ID int `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - Type int `json:"type"` - CreateTime int64 `json:"createTime"` - ServiceID int `json:"serviceId"` - PublishType int `json:"publishType"` - Servers []Servers `json:"servers"` - OdinNodes interface{} `json:"odinNodes"` - Handler Handler `json:"handler"` - FullTraffic bool `json:"fullTraffic"` - ApolloServerFullTraffic bool `json:"apolloServerFullTraffic"` - PublishName string `json:"publishName"` -} -type MultiLangStatus struct { -} -type PublishRegions struct { - ID int `json:"id"` - ConfigID int `json:"configId"` - EnvID int `json:"envId"` - ConfigVersionID int `json:"configVersionId"` - PublishOrder int `json:"publishOrder"` - Status int `json:"status"` - Region Region `json:"region"` - MultiLangStatus MultiLangStatus `json:"multiLangStatus"` - CreateTime interface{} `json:"createTime"` - UpdateTime int64 `json:"updateTime"` - CheckTimeRemaining int `json:"checkTimeRemaining"` - DoubleCheckers string `json:"doubleCheckers"` - CurrentPublishHistory interface{} `json:"currentPublishHistory"` - DoubleCheckerList []interface{} `json:"doubleCheckerList"` - Offline bool `json:"offline"` - Published bool `json:"published"` - Publishing bool `json:"publishing"` - PublishUnfinished bool `json:"publishUnfinished"` -} -type Environments struct { - ID int `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - Type int `json:"type"` - CreateTime int64 `json:"createTime"` - ServiceID int `json:"serviceId"` - PublishType int `json:"publishType"` - Servers []Servers `json:"servers"` - OdinNodes interface{} `json:"odinNodes"` - Handler Handler `json:"handler"` - FullTraffic bool `json:"fullTraffic"` - ApolloServerFullTraffic bool `json:"apolloServerFullTraffic"` - PublishName string `json:"publishName"` -} -type Services struct { - ID int `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - CreatedBy string `json:"createdBy"` - CreateTime int64 `json:"createTime"` - DefaultEnvID int `json:"defaultEnvId"` - AppID int `json:"appId"` - Icon string `json:"icon"` - Owner string `json:"owner"` - Version string `json:"version"` - NeedApprove int `json:"needApprove"` - ConfigType int `json:"configType"` - Mine interface{} `json:"mine"` - Permission interface{} `json:"permission"` - Environments []Environments `json:"environments"` - Machines interface{} `json:"machines"` - DingdingGroup string `json:"dingdingGroup"` - MinPublishStep int `json:"minPublishStep"` - ConfigNameRule string `json:"configNameRule"` - DisplayName string `json:"displayName"` - LastSyncTime int64 `json:"lastSyncTime"` - PublishCheckInterval int `json:"publishCheckInterval"` - EnableDelete interface{} `json:"enableDelete"` - Stat int `json:"stat"` - V2 bool `json:"v2"` - ConfigPublishNeedDoubleCheck bool `json:"configPublishNeedDoubleCheck"` - V1 bool `json:"v1"` -} -type Namespace struct { - ID int `json:"id"` - Name string `json:"name"` - DisplayName string `json:"displayName"` - ConfigNameRule interface{} `json:"configNameRule"` - Description interface{} `json:"description"` - CreateTime int64 `json:"createTime"` - ConfigType int `json:"configType"` - Shared int `json:"shared"` - CreatedBy string `json:"createdBy"` - EnableScenes int `json:"enableScenes"` - SceneFields interface{} `json:"sceneFields"` - Stat int `json:"stat"` - IncConfigID int `json:"incConfigId"` - ChannelVersion int `json:"channelVersion"` - Services interface{} `json:"services"` - Permissions interface{} `json:"permissions"` - EnableAutoPublish int `json:"enableAutoPublish"` - IncField string `json:"incField"` - ConfigValueFormat interface{} `json:"configValueFormat"` - V2Channel bool `json:"v2Channel"` - OperationTemplateConfig bool `json:"operationTemplateConfig"` - EnableAutoIncConfID bool `json:"enableAutoIncConfId"` - TemplateConfig bool `json:"templateConfig"` - V1Channel bool `json:"v1Channel"` -} -type ApolloConfigData struct { - ID int `json:"id"` - Name string `json:"name"` - CanChangePublishType bool `json:"canChangePublishType"` - Template interface{} `json:"template"` - IsMultiLang int `json:"isMultiLang"` - UsedByDict bool `json:"usedByDict"` - Description string `json:"description"` - CurrentVersion int `json:"currentVersion"` - CreatedBy string `json:"createdBy"` - LockedBy string `json:"lockedBy"` - VersionID int `json:"versionId"` - VersionCreateTime int64 `json:"versionCreateTime"` - TemplateInfo TemplateInfo `json:"templateInfo"` - Value []Value `json:"value"` - OriginValue []interface{} `json:"originValue"` - KeyDesc []interface{} `json:"keyDesc"` - EnableFrom interface{} `json:"enableFrom"` - Type int `json:"type"` - Status int `json:"status"` - ErrorTypeParams []interface{} `json:"errorTypeParams"` - ConfigStatus string `json:"configStatus"` - DeleteStatus int `json:"deleteStatus"` - OfflineStatus int `json:"offlineStatus"` - PublishApproval interface{} `json:"publishApproval"` - OperatingTime int64 `json:"operatingTime"` - Operator string `json:"operator"` - PublishRegions PublishRegions `json:"publishRegions"` - CreateTime int64 `json:"createTime"` - ModifyTime int64 `json:"modifyTime"` - ModifiedBy string `json:"modifiedBy"` - Services []Services `json:"services"` - IsDefault int `json:"isDefault"` - Namespace Namespace `json:"namespace"` - VersionDescription string `json:"versionDescription"` - IsSyncOverwrite int `json:"isSyncOverwrite"` - DisplayName interface{} `json:"displayName"` - Permission []interface{} `json:"permission"` - MarketingActivity interface{} `json:"marketingActivity"` - EnableApproval bool `json:"enableApproval"` - Approver string `json:"approver"` - Regions []string `json:"regions"` -} - -type ApolloConfigRequest struct { - Name string `json:"name"` - Description string `json:"description"` - Type int `json:"type"` - EnableApproval bool `json:"enableApproval"` - Approver string `json:"approver"` - Regions []string `json:"regions"` - Value []Value `json:"value"` - VersionDescription string `json:"versionDescription"` -} - -//model-repository 返回结构体 - -type ModelRepositoryRequest struct { - ModelEntryList []*ModelEntry `json:"models"` -} - -type ModelEntry struct { - AppId int64 `json:"appId"` - ModelName string `json:"modelName"` - ModelType string `json:"modelType"` -} - -type ModelRepositoryResponse struct { -} - -type ModelInfo struct { - Id int64 `json:"id"` - Name string `json:"name"` - Version string `json:"version"` - ProduceType string `json:"produceType"` - ModelType string `json:"modelType"` - AppId int64 `json:"appId"` - HdfsPath string `json:"hdfsPath"` -} - -type AppModuleData struct { - AppName string `json:"app_name"` - ProjectBranch string `json:"project_branch"` - Operator string `json:"operator"` -} diff --git a/tg-service/idl/workflow.go b/tg-service/idl/workflow.go deleted file mode 100644 index 3c9805f6f3c1270bbb6a47f2c31e8119dd298046..0000000000000000000000000000000000000000 --- a/tg-service/idl/workflow.go +++ /dev/null @@ -1,91 +0,0 @@ -package idl - -import ( - "errors" - "fmt" - "github.com/didi/tg-flow/tg-core/wfengine" - "reflect" -) - -type WorkflowExport struct { - Id int64 `json:"id"` - SceneId int64 `json:"scene_id"` - FlowCharts *WorkflowChart `json:"flow_charts"` - SceneName string `json:"scene_name"` - GroupName string `json:"group_name"` -} - -type Workflow struct { - Id int64 `json:"id"` - SceneId int64 `json:"scene_id"` - FlowCharts map[string]*WorkflowChart `json:"flow_charts"` - SceneName string `json:"scene_name"` -} - -type WorkflowChart struct { - ActionMap map[string]*Action `json:"actions"` -} - -type Action struct { - ActionType string `json:"action_type"` - ActionId string `json:"action_id"` - ActionName string `json:"action_name"` - Params []*wfengine.Param `json:"params"` - NextActionIds []string `json:"next_action_ids,omitempty"` - NextConditions []string `json:"next_conditions,omitempty"` - Description string `json:"description"` - Timeout int `json:"timeout"` - RefWorkflowId int `json:"ref_workflow_id"` - TimeoutAsync bool `json:"timeout_async"` - TimeoutDynamic bool `json:"timeout_dynamic"` - Location string `json:"location"` -} - -func SimpleCopyProperties(dst, src interface{}) (err error) { - // 防止意外panic - defer func() { - if e := recover(); e != nil { - err = errors.New(fmt.Sprintf("%v", e)) - } - }() - - dstType, dstValue := reflect.TypeOf(dst), reflect.ValueOf(dst) - srcType, srcValue := reflect.TypeOf(src), reflect.ValueOf(src) - - // dst必须结构体指针类型 - if dstType.Kind() != reflect.Ptr || dstType.Elem().Kind() != reflect.Struct { - return errors.New("dst type should be a struct pointer") - } - - // src必须为结构体或者结构体指针,.Elem()类似于*ptr的操作返回指针指向的地址反射类型 - if srcType.Kind() == reflect.Ptr { - srcType, srcValue = srcType.Elem(), srcValue.Elem() - } - if srcType.Kind() != reflect.Struct { - return errors.New("src type should be a struct or a struct pointer") - } - - // 取具体内容 - dstType, dstValue = dstType.Elem(), dstValue.Elem() - - // 属性个数 - propertyNums := dstType.NumField() - - for i := 0; i < propertyNums; i++ { - // 属性 - property := dstType.Field(i) - // 待填充属性值 - propertyValue := srcValue.FieldByName(property.Name) - - // 无效,说明src没有这个属性 || 属性同名但类型不同 - if !propertyValue.IsValid() || property.Type != propertyValue.Type() { - continue - } - - if dstValue.Field(i).CanSet() { - dstValue.Field(i).Set(propertyValue) - } - } - - return nil -} diff --git a/tg-service/logic/appconfigadmin/add_update_app_config.go b/tg-service/logic/appconfigadmin/add_update_app_config.go deleted file mode 100644 index 728329f77bcb222226b4a0aeb4b388cce5267dea..0000000000000000000000000000000000000000 --- a/tg-service/logic/appconfigadmin/add_update_app_config.go +++ /dev/null @@ -1,60 +0,0 @@ -package appconfigadmin - -import ( - "context" - "github.com/didi/tg-flow/tg-core/common/mysql" - "github.com/didi/tg-flow/tg-core/common/tlog" - "tg-service/common/logs" - "tg-service/idl" - "time" -) - -//新增数据 -func AddOrUpdateAppConfig(addData *idl.AppConfigInfo) *idl.ResponseInfo { - responseInfo := &idl.ResponseInfo{ - Tag: true, - ErrMsg: "", - } - - nowTime := time.Now().Format("2006-01-02 15:04:05") - var sql string - var err error - - if addData.AppName == "" { - responseInfo.Tag = false - responseInfo.ErrMsg = "系统名称 不能为空,或空串" - return responseInfo - } - if addData.MachineRoom == "" { - responseInfo.Tag = false - responseInfo.ErrMsg = "部署机房 不能为空,或空串" - return responseInfo - } - if addData.NodeName == "" { - responseInfo.Tag = false - responseInfo.ErrMsg = "节点名称 不能为空,或空串" - return responseInfo - } - - //先判断数据库中是否有相同记录 - appConfigList := SelectAppConf(addData, -1, 0, false) - - if addData.OldId <= 0 { //添加数据 - if len(appConfigList) > 0 { - responseInfo.Tag = false - responseInfo.ErrMsg = "数据库中已存在 相同app id 的记录,无法添加本条数据!" - return responseInfo - } - sql = "insert into app_config(id, app_name, machine_room, node_name, git_url, operator, create_time, update_time) values(?,?,?,?,?,?,?)" - _, err = mysql.Handler.Exec(sql, addData.Id, addData.AppName, addData.MachineRoom, addData.NodeName, addData.GitUrl, addData.Operator, nowTime, nowTime) - } else { //更新数据 - sql = "update app_config set app_name=?,machine_room=?,node_name=?, git_url=?, operator=?,update_time=? where id=?" - _, err = mysql.Handler.Exec(sql, addData.AppName, addData.MachineRoom, addData.NodeName, addData.GitUrl, addData.Operator, nowTime, addData.Id) - } - if err != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = err.Error() - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=appconfigadmin.AddOrUpdateSystemConfig||sql=%v||err=%v", sql, err) - } - return responseInfo -} diff --git a/tg-service/logic/appconfigadmin/delete_app_config.go b/tg-service/logic/appconfigadmin/delete_app_config.go deleted file mode 100644 index 94c5a89e74f073697337fbe36127cd8d7f3e4a7b..0000000000000000000000000000000000000000 --- a/tg-service/logic/appconfigadmin/delete_app_config.go +++ /dev/null @@ -1,26 +0,0 @@ -package appconfigadmin - -import ( - "context" - "github.com/didi/tg-flow/tg-core/common/mysql" - "github.com/didi/tg-flow/tg-core/common/tlog" - "tg-service/common/logs" - "tg-service/idl" -) - -//删除数据 -func DeleteAppConfig(deleteData *idl.AppConfigInfo) *idl.ResponseInfo { - responseInfo := &idl.ResponseInfo{ - Tag: true, - ErrMsg: "", - } - sql := "delete from app_config where id = ?" - _, err := mysql.Handler.Exec(sql, deleteData.Id) - if err != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = err.Error() - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=appconfigadmin.DeleteSystemConfig||sql=%v||err=%v", sql, err) - } - - return responseInfo -} diff --git a/tg-service/logic/appconfigadmin/export_app_config.go b/tg-service/logic/appconfigadmin/export_app_config.go deleted file mode 100644 index f74b21628a80a83ab23f58ae196f160762b7e579..0000000000000000000000000000000000000000 --- a/tg-service/logic/appconfigadmin/export_app_config.go +++ /dev/null @@ -1,169 +0,0 @@ -package appconfigadmin - -import ( - "container/list" - "context" - "encoding/json" - "github.com/didi/tg-flow/tg-core/common/mysql" - "github.com/didi/tg-flow/tg-core/common/tlog" - "github.com/didi/tg-flow/tg-core/wfengine" - "tg-service/common/logs" - "tg-service/idl" - - "strconv" -) - -//导出数据 -func ExportAppConfig(exportData *idl.AppConfigInfo) *idl.ResponseInfo { - responseInfo := &idl.ResponseInfo{ - Tag: true, - ErrMsg: "", - } - sceneConfigList, err := getSceneListByAppId(exportData) - if err != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = err.Error() - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=appconfigadmin.getSceneIdErr||err=%v", err) - return responseInfo - } - sceneMap := make(map[string]*wfengine.SceneModule) - workflowList := list.New() - for scene := sceneConfigList.Front(); scene != nil; scene = scene.Next() { - sceneModule, ok := scene.Value.(*wfengine.SceneModule) - if ok { - sceneMap[strconv.FormatInt(sceneModule.Id, 10)] = sceneModule - workflowListByScene, err := getSceneWorkflowList(sceneModule) - if err != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = err.Error() - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=appconfigadmin.getSceneWorkflowErr||err=%v", err) - return responseInfo - } - workflowList.PushBackList(workflowListByScene) - } - } - content := make(map[string]interface{}) - workflowStr := "[" - for workflow := workflowList.Front(); workflow != nil; workflow = workflow.Next() { - json, err := json.Marshal(workflow.Value) - if err != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = err.Error() - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=appconfigadmin.getSceneWorkflowErr||err=%v", err) - return responseInfo - } - workflowStr = workflowStr + "'" + string(json) + "'," - } - workflowStr = workflowStr + "]" - sceneJson, err := json.Marshal(sceneMap) - content["scene"] = string(sceneJson) - content["workflowList"] = workflowStr - response, err := json.Marshal(content) - responseInfo.Content = string(response) - return responseInfo -} - -func ExportAppConfigForApollo(exportData *idl.AppConfigInfo) map[string]interface{} { - appWorkflowMap := make(map[string]interface{}) - sceneConfigList, err := getSceneListByAppId(exportData) - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=asyncWorkflowToApollo.getSceneIdErr||err=%v", err) - return appWorkflowMap - } - sceneMap := make(map[string]*wfengine.SceneModule) - workflowList := list.New() - for scene := sceneConfigList.Front(); scene != nil; scene = scene.Next() { - sceneModule, ok := scene.Value.(*wfengine.SceneModule) - if ok { - sceneMap[strconv.FormatInt(sceneModule.Id, 10)] = sceneModule - workflowListByScene, err := getSceneWorkflowList(sceneModule) - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=asyncWorkflowToApollo.getSceneWorkflowErr||err=%v", err) - return appWorkflowMap - } - workflowList.PushBackList(workflowListByScene) - } - } - appWorkflowMap["scene"] = sceneMap - for workflow := workflowList.Front(); workflow != nil; workflow = workflow.Next() { - workflowValue, ok := workflow.Value.(idl.WorkflowExport) - if ok { - workflowKey := "workflow-" + strconv.FormatInt(workflowValue.SceneId, 10) + "-" + strconv.FormatInt(workflowValue.Id, 10) + "-" + workflowValue.SceneName - appWorkflowMap[workflowKey] = workflowValue.FlowCharts - } - } - return appWorkflowMap -} - -func getSceneListByAppId(exportData *idl.AppConfigInfo) (*list.List, error) { - sql := "select id,`name`,app_id,bucket_type,update_time,flow_type,exp_name from scene_config where app_id = ?" - rows, err := mysql.Handler.Query(sql, exportData.Id) - if err != nil { - return nil, err - } - defer rows.Close() - err = rows.Err() - if err != nil { - return nil, err - } - var sceneConfigList = list.New() - for rows.Next() { - var sceneConfig wfengine.SceneModule - err := rows.Scan(&sceneConfig.Id, &sceneConfig.Name, &sceneConfig.AppId, &sceneConfig.BucketType, &sceneConfig.UpdateTime, &sceneConfig.FlowType, &sceneConfig.DispatchExperimentName) - if err != nil { - return nil, err - } - sceneConfigList.PushBack(&sceneConfig) - } - return sceneConfigList, nil -} - -func getSceneWorkflowList(sceneModule *wfengine.SceneModule) (*list.List, error) { - sql := "select id,experiment_id,flow_chart,group_name,is_default from workflow where status = 1 and experiment_id = ?" - sceneWorkflowList := list.New() - - var sceneId = sceneModule.Id - groupWorkflowMap := make(map[string]int64) - rows, err := mysql.Handler.Query(sql, sceneId) - if err != nil { - return list.New(), err - } - defer rows.Close() - err = rows.Err() - if err != nil { - return list.New(), err - } - var defaultWorkflowId int64 - for rows.Next() { - var workflow = new(wfengine.Workflow) - var flowChartStr string - err := rows.Scan(&workflow.Id, &workflow.SceneId, &flowChartStr, &workflow.GroupName, &workflow.IsDefault) - if err != nil { - return list.New(), err - } - if defaultWorkflowId == 0 && workflow.IsDefault == 1 { - defaultWorkflowId = workflow.Id - } - var actionMap = new(idl.WorkflowChart) - if len(flowChartStr) == 0 { - actionMap.ActionMap = make(map[string]*idl.Action) - } else { - err = json.Unmarshal([]byte(flowChartStr), actionMap) - } - if err != nil { - return list.New(), err - } - var exportWorkflow = idl.WorkflowExport{ - Id: workflow.Id, - SceneId: workflow.SceneId, - FlowCharts: actionMap, - SceneName: sceneModule.Name, - GroupName: workflow.GroupName, - } - sceneWorkflowList.PushBack(exportWorkflow) - groupWorkflowMap[workflow.GroupName] = workflow.Id - } - sceneModule.GroupWorkflowMap = groupWorkflowMap - sceneModule.DefaultWorkflowId = defaultWorkflowId - return sceneWorkflowList, nil -} diff --git a/tg-service/logic/appconfigadmin/select_app_config.go b/tg-service/logic/appconfigadmin/select_app_config.go deleted file mode 100644 index 699348f11111b50b189bc175661434c251f9e4ba..0000000000000000000000000000000000000000 --- a/tg-service/logic/appconfigadmin/select_app_config.go +++ /dev/null @@ -1,111 +0,0 @@ -package appconfigadmin - -import ( - "context" - "database/sql" - "github.com/didi/tg-flow/tg-core/common/mysql" - "github.com/didi/tg-flow/tg-core/common/tlog" - "tg-service/common/logs" - "tg-service/common/template" - "tg-service/idl" - "tg-service/logic" - "time" -) - -//查询AppConf数据 -func SelectAppConf(selectData *idl.AppConfigInfo, pageLimit int64, pageNum int64, useLimit bool) []*idl.AppConfigInfo { - sqlStr := "select id, app_name, machine_room, node_name, git_url, operator, create_time, update_time from app_config" - tempSql := " order by id desc" - - if selectData.Id > 0 { //按条件查询 - sqlStr += " where id = ?" + tempSql - } else { //全量️查询 - sqlStr += tempSql - } - - if useLimit { - sqlStr = logic.AddSelectLimit(sqlStr, pageLimit, pageNum) - } - - return SelectAppConfPre(sqlStr, selectData) -} - -//查询数据库 -func SelectAppConfPre(sqlStr string, selectData *idl.AppConfigInfo) []*idl.AppConfigInfo { - stmt, err := GetAppConfStmt(sqlStr) - if err != nil { - return make([]*idl.AppConfigInfo, 0) - } - return QueryAppConf(stmt, selectData) -} - -func GetAppConfStmt(sqlStr string) (*sql.Stmt, error) { - stmt, err := mysql.Handler.Prepare(sqlStr) - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=appconfigadmin.GetAppConfStmt||sql=%v||err=%v", sqlStr, err) - } - return stmt, err -} - -//数据库查询 -func QueryAppConf(stmt *sql.Stmt, selectData *idl.AppConfigInfo) []*idl.AppConfigInfo { - defer stmt.Close() - var rows *sql.Rows - var err error - if selectData.Id > 0 { //按条件查询 - rows, err = stmt.Query(selectData.Id) - } else { - rows, err = stmt.Query() - } - - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=appconfigadmin.Query||stmt query is fail||err=%v", err) - return make([]*idl.AppConfigInfo, 0) - } - - err = rows.Err() - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=appconfigadmin.RowsErr||respones row is err||err=%v", err) - return make([]*idl.AppConfigInfo, 0) - } - - return parasRowAppConf(rows) -} - -func parasRowAppConf(rows *sql.Rows) []*idl.AppConfigInfo { - defer rows.Close() - appConfigList := make([]*idl.AppConfigInfo, 0) - for rows.Next() { - var appConfig = new(idl.AppConfigInfo) - var createTime time.Time - var updateTime time.Time - err := rows.Scan(&appConfig.Id, &appConfig.AppName, &appConfig.MachineRoom, &appConfig.NodeName, &appConfig.GitUrl, &appConfig.Operator, &createTime, &updateTime) - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=appconfigadmin.RowsScan||rows=%v||err=%v", rows, err) - return appConfigList - } - //时间格式转化 - appConfig.CreateTime = createTime.Format(logic.TIME_FORMAT) - appConfig.UpdateTime = updateTime.Format(logic.TIME_FORMAT) - - appConfigList = append(appConfigList, appConfig) - } - - return appConfigList -} - -//更新系统id和对应中文映射关系 -func UpdateAppMenuCacheData(appConfigList []*idl.AppConfigInfo) { - logic.Mutex.Lock() - var appNameMap map[string]int = make(map[string]int) - var appIdMap map[int]string = make(map[int]string) - for _, appConfig := range appConfigList { - appNameMap[appConfig.AppName] = appConfig.Id - appIdMap[appConfig.Id] = appConfig.AppName - } - if len(appConfigList) > 0 { - template.AppNameMap = appNameMap - template.AppIdMap = appIdMap - } - logic.Mutex.Unlock() -} diff --git a/tg-service/logic/common.go b/tg-service/logic/common.go deleted file mode 100644 index 829b9d56cdc31d16a64603b01e9b08557f58b7ee..0000000000000000000000000000000000000000 --- a/tg-service/logic/common.go +++ /dev/null @@ -1,367 +0,0 @@ -/** - @Description: - @Author:zhouzichun - @Date:2023/5/8 -**/ - -package logic - -import ( - "container/list" - "encoding/json" - "errors" - "fmt" - "github.com/didi/tg-flow/tg-core/common/tlog" - "math/rand" - "net/http" - "sort" - "strconv" - "strings" - "sync" - "tg-service/idl" - "time" -) - -const TIME_FORMAT = "2006-01-02 15:04:05" - -var Mutex sync.Mutex - -//解析请求参数 -func ParsRequestParam(r *http.Request) *idl.WorkFlowData { - data := &idl.WorkFlowData{ - ExperimentId: CancelEmptyStr(r.FormValue("experimentid")), - OldWorkFlowId: CancelEmptyStr(r.FormValue("oldworkflowid")), - WorkFlowId: CancelEmptyStr(r.FormValue("workflowid")), - Modules: CancelEmptyStr(r.FormValue("modules")), - Proportion: CancelEmptyStr(r.FormValue("proportion")), - Defult: CancelEmptyStr(r.FormValue("defult")), - Remark: CancelEmptyStr(r.FormValue("remark")), - UserCookie: CancelEmptyStr(r.FormValue("usercookie")), - } - return data -} - -//解析workflow请求参数 -func ParsRequsetWorkFlowParam(r *http.Request) (*idl.WorkFlowConfig, error) { - err := CheckParam(r.FormValue("oldworkflowid")) - if err != nil { - return &idl.WorkFlowConfig{}, fmt.Errorf("实验编号需要是数字") - } - err = CheckParam(r.FormValue("workflowid")) - if err != nil { - return &idl.WorkFlowConfig{}, fmt.Errorf("新增实验编号需要是数字") - } - - //去掉流量占比数字后面的“%”号 - proportion := strings.Split(CancelEmptyStr(r.FormValue("proportion")), "%")[0] - err = CheckParam(proportion) - if err != nil { - return &idl.WorkFlowConfig{}, fmt.Errorf("流量占比需要是数字") - } - - dimensionId, _ := strconv.ParseInt(r.FormValue("dimension_id"), 10, 64) - dataJson := CancelEmptyStr(r.FormValue("dataJson")) - var updateJson string - if dataJson != "" { - flowChart := new(idl.ChartG6) - err = json.Unmarshal([]byte(dataJson), &flowChart) - if err != nil { - return &idl.WorkFlowConfig{}, fmt.Errorf("流程图不符合规范") - } - workflowChart := formatChartG6(flowChart) - - updateJsonByte, err := json.Marshal(workflowChart) - updateJson = string(updateJsonByte) - if err != nil { - return &idl.WorkFlowConfig{}, fmt.Errorf("流程图不符合规范") - } - } - - data := &idl.WorkFlowConfig{ - SceneName: CancelEmptyStr(r.FormValue("scenename")), - OldWorkFlowId: CancelEmptyStr(r.FormValue("oldworkflowid")), - WorkFlowId: CancelEmptyStr(r.FormValue("workflowid")), - DimensionId: dimensionId, - Modules: CancelEmptyStr(r.FormValue("modules")), - Proportion: proportion, - Defult: CancelEmptyStr(r.FormValue("defult")), - Remark: CancelEmptyStr(r.FormValue("remark")), - CreateTime: r.FormValue("createtime"), - Operator: CancelEmptyStr(r.FormValue("operator")), - ManualSlotIds: CancelEmptyStr(r.FormValue("manual_slot_ids")), - GroupName: r.FormValue("groupname"), - FlowChartJson: updateJson, - } - return data, nil -} - -//解析请求中的页码参数 -func ParsRequestPageParam(r *http.Request) (pageLimit int64, pageNum int64) { - pageNum, _ = strconv.ParseInt(r.FormValue("page_num"), 10, 64) - pageLimit, _ = strconv.ParseInt(r.FormValue("page_limit"), 10, 64) - return pageLimit, pageNum -} - -func formatChartG6(saveData *idl.ChartG6) *idl.WorkflowChart { - nodes := saveData.Nodes - edges := saveData.Edges - workflowChart := new(idl.WorkflowChart) - actionMap := make(map[string]*idl.Action) - typeMap := map[string]string{"rect": "task", "diamond": "condition", "circle": "flow", "clock": "timeout"} - for _, node := range nodes { - action := idl.Action{ - ActionType: typeMap[node.NodeType], - ActionId: node.Id, - ActionName: node.Label, - Params: node.Params, - Timeout: node.Timeout, - RefWorkflowId: node.RefWorkflowId, - TimeoutAsync: node.TimeoutAsync, - TimeoutDynamic: node.TimeoutDynamic, - Location: node.Location, - } - deleteIndex := list.New() - for edgeIndex, edge := range edges { - if edge.Source == node.Id { - action.NextActionIds = append(action.NextActionIds, edge.Target) - if action.ActionType == "condition" { - action.NextConditions = append(action.NextConditions, edge.Label) - } - deleteIndex.PushBack(edgeIndex) - } - } - for i := deleteIndex.Back(); i != nil; i = i.Prev() { - index := i.Value.(int) - edges = append(edges[:index], edges[index+1:]...) - } - actionMap[node.Id] = &action - } - workflowChart.ActionMap = actionMap - return workflowChart - -} - -//检验请求参数 -func CheckParam(param string) error { - if param == "" { - param = "0" - } - _, err := strconv.ParseInt(param, 10, 64) - if err != nil { - return err - } - return nil -} - -//去除换行符和空字符串 -func CancelEmptyStr(str string) string { - str = strings.Replace(str, "\n", "", -1) - str = strings.Replace(str, " ", "", -1) - return str -} - -// EchoJSON json格式输出 -func EchoJSON(w http.ResponseWriter, r *http.Request, data interface{}) { - if cType := w.Header().Get("Content-Type"); cType == "" { - w.Header().Set("Content-Type", "application/json") - } - b, err := json.Marshal(data) - if err != nil { - Echo(w, r, []byte(`{"errno":1, "errmsg":"`+err.Error()+`"}`)) - } else { - Echo(w, r, b) - } -} - -func EchoToJSON(w http.ResponseWriter, r *http.Request, data interface{}) { - if cType := w.Header().Get("Content-Type"); cType == "" { - w.Header().Set("Content-Type", "application/json") - } - b, err := json.Marshal(data) - if err != nil { - EchoTo(w, r, []byte(`{"errno":1, "errmsg":"`+err.Error()+`"}`)) - } else { - EchoTo(w, r, b) - } -} - -func EchoTo(w http.ResponseWriter, req *http.Request, body []byte) { - - if cType := w.Header().Get("Content-Type"); cType == "" { - w.Header().Set("Content-Type", "text/html") - } - if req.Method == "options" { - return - } - if origin := req.Header.Get("Origin"); origin != "" { - w.Header().Set("Access-Control-Allow-Origin", "*") - w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE") - w.Header().Set("Access-Control-Allow-Headers", "Content-Type,Authorization,X-Token") - } - w.Write(body) -} - -// Echo 原始输出 -func Echo(w http.ResponseWriter, req *http.Request, body []byte) { - if cType := w.Header().Get("Content-Type"); cType == "" { - w.Header().Set("Content-Type", "text/plain") - } - w.Header().Set("Access-Control-Allow-Origin", "*") - w.Write(body) -} - -//为Sql语句加上页码限制 -func AddSelectLimit(sqlStr string, pageLimit int64, pageNum int64) (newSqlStr string) { - startIndex := (pageNum - 1) * pageLimit - newSqlStr = sqlStr + " limit " + strconv.FormatInt(startIndex, 10) + ", " + strconv.FormatInt(pageLimit, 10) + ";" - tlog.Handler.Info(newSqlStr) - return newSqlStr -} - -//生成count个[start,end)结束的不重复的随机数 -func GenerateRandomNumber(start int, end int, count int) []int { - //范围检查 - if end < start || (end-start) < count { - return nil - } - //存放结果的slice - nums := make([]int, 0) - //随机数生成器,加入时间戳保证每次生成的随机数不一样 - r := rand.New(rand.NewSource(time.Now().UnixNano())) - for len(nums) < count { - //生成随机数 - num := r.Intn((end - start)) + start - //查重 - exist := false - for _, v := range nums { - if v == num { - exist = true - break - } - } - if !exist { - nums = append(nums, num) - } - } - return nums -} - -//校验添加操作后,流量占比是否为100 -func CheckAfterAddOP(experimentId string, dimendionId int64, mainWorkFlowId string, mainWorkFlowRange string, addRange string) error { - sql := "select id,dimension_id,experiment_id, modules,is_default,range1, remark,create_time,update_time,operator,manual_slot_ids from workflow where status=1 and experiment_id = ? and dimension_id = ?" - experimentMap := SelectWorkFlow(sql, experimentId, dimendionId) - sum := 0 - for _, workFlowMap := range experimentMap { - for workFlowId, workFlow := range workFlowMap { - if strconv.FormatInt(workFlowId, 10) == mainWorkFlowId { - continue - } - if workFlow.Range1 != "" { - sum += len(strings.Split(workFlow.Range1, ",")) - } - } - } - if len(mainWorkFlowRange) > 0 { - if mainWorkFlowRange != "" { - sum += len(strings.Split(mainWorkFlowRange, ",")) - } - } - - if len(addRange) > 0 { - sum += len(strings.Split(addRange, ",")) - } - - if sum > 100 { - err := errors.New("添加操作造成该场景下所有实验的流量占比超过了100,添加操作失败.") - return err - } - return nil -} - -//根据字符串,生成区间表达式,如:"1,2,5,6,7,8,9" -> "[1-2][5-9]" -func CreateRangeStr(str string) string { - resultStr := "" - if len(str) <= 0 { - return resultStr - } - list := make([]string, 0) - addStr := strings.Split(str, ",") - tempAddStr := addStr[0] - for i := 1; i < len(addStr); i++ { - before, _ := strconv.Atoi(addStr[i-1]) - after, _ := strconv.Atoi(addStr[i]) - if after-1 == before { - if len(tempAddStr) <= 0 { - tempAddStr += addStr[i] - } else { - tempAddStr += "," + addStr[i] - } - } else { - list = append(list, tempAddStr) - tempAddStr = addStr[i] - } - } - list = append(list, tempAddStr) - - for _, v := range list { - tempArry := strings.Split(v, ",") - if len(tempArry) == 1 { - resultStr += "[" + v + "]" - } else { - resultStr += "[" + tempArry[0] + "-" + tempArry[len(tempArry)-1] + "]" - } - } - return resultStr -} - -func CheckDeleteOP(mainWorkFlowRange string) error { - if len(strings.Split(mainWorkFlowRange, ",")) > 100 { - err := errors.New("删除操作造成该场景下主流量占比超过了100,删除操作失败.") - return err - } - return nil -} - -func CheckModifyOP(haveUseProportion int, mainWorkFlowRange string, addRange string) error { - mainLen := 0 - if mainWorkFlowRange != "" { - mainLen = len(strings.Split(mainWorkFlowRange, ",")) - - } - modifyLen := 0 - if addRange != "" { - modifyLen = len(strings.Split(addRange, ",")) - } - totalSum := haveUseProportion + mainLen + modifyLen - if totalSum > 100 { - err := errors.New("修改操作,造成该场景下所有实验的流量占比之和,超过了100,修改操作失败.") - return err - } - return nil -} - -//对字符串中的数字排序,如:“4,3,1,5,8,6” -> "1,3,4,5,6,8" -func SortStr(str string) string { - // 去除空格 - str = strings.Replace(str, " ", "", -1) - // 去除换行符 - str = strings.Replace(str, "\n", "", -1) - resultStr := "" - strs := strings.Split(str, ",") - array := make([]int, 0) - for _, v := range strs { - temp, err := strconv.Atoi(v) - if err == nil { - array = append(array, temp) - } - } - sort.Ints(array) - for _, v := range array { - if len(resultStr) <= 0 { - resultStr += strconv.Itoa(v) - } else { - resultStr += "," + strconv.Itoa(v) - } - } - return resultStr -} diff --git a/tg-service/logic/login.go b/tg-service/logic/login.go deleted file mode 100644 index 929f0ec4609b7ae060b59095832f9340f90af869..0000000000000000000000000000000000000000 --- a/tg-service/logic/login.go +++ /dev/null @@ -1,63 +0,0 @@ -package logic - -import ( - "context" - "github.com/didi/tg-flow/tg-core/common/mysql" - "github.com/didi/tg-flow/tg-core/common/tlog" - "tg-service/common/logs" - "tg-service/constant" - "tg-service/idl" -) - -//登录校验 -func Login(username string, password string) (bool, string) { - if constant.Env == "test" { - return true, "login success." - } - //将请求密码,转为md5值,进行校验 - // md5PassWord := MD5(password) - md5PassWord := "" - sqlStr := "select user_name,pass_word,role_id from user_info where user_name=? and pass_word = ?" - tag, err := selectUserInfo(sqlStr, username, md5PassWord) - return tag, err -} - -//数据库查询 -func selectUserInfo(sqlStr string, userName string, passWord string) (bool, string) { - stmt, err := mysql.Handler.Prepare(sqlStr) - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagProcessLog, "etype=logic_selectUserInfo||econtent=sql:%v||err=%v", sqlStr, err) - return false, err.Error() - } - defer stmt.Close() - - rows, err := stmt.Query(userName, passWord) - defer rows.Close() - - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagProcessLog, "etype=logic_SelectUserInfo_Query||econtent=sql:%v||err=%v", sqlStr, err) - return false, err.Error() - } - - if rows.Err() != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagProcessLog, "etype=logic_UserInforowsErr||econtent=||err=%v", err) - return false, err.Error() - } - - tag := false - for rows.Next() { - var userInfo = new(idl.UserInfo) - err := rows.Scan(&userInfo.UserName, &userInfo.PassWord, &userInfo.RoleId) - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagProcessLog, "etype=logic_UserInforowsScan||econtent=rows:%v||err=%v", rows, err) - return false, err.Error() - } - tag = true - } - - msg := "login success." - if !tag { - msg = "userName or passWord is error." - } - return tag, msg -} diff --git a/tg-service/logic/sceneadmin/add_update_scene.go b/tg-service/logic/sceneadmin/add_update_scene.go deleted file mode 100644 index 0dd5a62ece8a708af1b24c9b1423aff598f0fe73..0000000000000000000000000000000000000000 --- a/tg-service/logic/sceneadmin/add_update_scene.go +++ /dev/null @@ -1,126 +0,0 @@ -package sceneadmin - -import ( - "context" - "fmt" - "github.com/didi/tg-flow/tg-core/common/mysql" - "github.com/didi/tg-flow/tg-core/common/tlog" - "strconv" - "tg-service/common/logs" - "tg-service/common/template" - "tg-service/idl" - "time" - "unicode" -) - -//新增 数据 -func AddAddOrUpdateSceneConfig(addData *idl.SceneConfig) *idl.ResponseInfo { - responseInfo := &idl.ResponseInfo{ - Tag: true, - ErrMsg: "", - } - - if len(addData.Name) <= 0 { - responseInfo.Tag = false - responseInfo.ErrMsg = "场景名称 不能为空或者空格,无法添加本条数据!" - return responseInfo - } - - for _, v := range addData.Name { - if unicode.Is(unicode.Han, v) { - responseInfo.Tag = false - responseInfo.ErrMsg = "场景名称 不支持中文,请输入英文!" - return responseInfo - } - } - if len(addData.NameZh) > 0 { - hasZh := false - for _, zhv := range addData.NameZh { - if unicode.Is(unicode.Han, zhv) { - hasZh = true - break - } - } - if !hasZh { - responseInfo.Tag = false - responseInfo.ErrMsg = "中文场景名称不为空时则至少输入一个中文字符!" - return responseInfo - } - } - nowTime := time.Now().Format("2006-01-02 15:04:05") - var sql string - var err error - //判断数据库中是否已经存在该场景id - selectData := &idl.SceneConfig{ - Id: addData.Id, - } - sceneConfigIdList := SelectSceneConf(selectData, -1, 0, false) - //判断数据库中是否已经存在该场景名称 - selectData = &idl.SceneConfig{ - Name: addData.Name, - } - sceneConfigNameList := SelectSceneConf(selectData, -1, 0, false) - - if len(sceneConfigNameList) > 0 && sceneConfigNameList[0].Id != addData.Id { - responseInfo.Tag = false - responseInfo.ErrMsg = "数据库中已存在 其他不同场景编号,但相同场景名称 的记录,无法添加本条数据!" - return responseInfo - } - - appId := template.AppNameMap[addData.AppName] - - if addData.OldId <= 0 { //添加数据 - if len(sceneConfigIdList) > 0 { - responseInfo.Tag = false - responseInfo.ErrMsg = "数据库中已存在 相同场景编号 的记录,无法添加本条数据!" - return responseInfo - } - sql = "insert into scene_config(id,name,app_id,bucket_type,operator,create_time,update_time,flow_type,name_zh,exp_name) values(?,?,?,?,?,?,?,?,?,?)" - _, err = mysql.Handler.Exec(sql, addData.Id, addData.Name, appId, addData.BucketType, addData.Operator, nowTime, nowTime, addData.FlowType, addData.NameZh, addData.ExpName) - } else { //更新数据 - sql = "UPDATE scene_config SET name=?,app_id= ?, bucket_type=?, operator=?, update_time= ?, flow_type=?, name_zh=?, exp_name=? WHERE id=?" - _, err = mysql.Handler.Exec(sql, addData.Name, appId, addData.BucketType, addData.Operator, nowTime, addData.FlowType, addData.NameZh, addData.ExpName, addData.Id) - } - - if err != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = err.Error() - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=sceneadmin.AddAddOrUpdateSceneConfig||sql=%v||err=%v", sql, err) - return responseInfo - } - - //如果是新增场景,需要向workflow表中插入一条该场景的主流量,且占比100% - if addData.OldId <= 0 { - var range1 string //流量占比 - for i := 0; i < 100; i++ { - value := strconv.Itoa(i) - if len(range1) <= 0 { - range1 = value - } else { - range1 += "," + value - } - } - addSql := "insert into workflow(dimension_id, experiment_id, modules,is_default,status,range1,range2,remark,create_time,update_time,operator,flow_chart) values(-1,?,'',1,1,?,'[0-99]','',?,?,?,'')" - _, addErr := mysql.Handler.Exec(addSql, addData.Id, range1, nowTime, nowTime, addData.Operator) - if addErr != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = fmt.Sprintf("插入数据失败:%v", addErr.Error()) - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=sceneadmin.AddOrUpdateSceneConfig||sql=%v||err=%v", addSql, err) - } - } - - //对于推荐引擎,即appid=1的场景,需要向rec_scene_config表中插入一条该场景和场景组的对应关系 - /* if appId == 1 { - recSceneAddData := &idl.RecSceneConfig{ - SceneId: addData.Id, - SceneName: addData.Name, - Operator: addData.Operator, - } - recSceneConfigList := recalladmin.SelectRecSceneConf(recSceneAddData) - if len(recSceneConfigList) > 0 { - recSceneAddData.Id = recSceneConfigList[0].Id - } - responseInfo = recalladmin.AddOrUpdateRecSceneConfig(recSceneAddData) - }*/ - return responseInfo -} diff --git a/tg-service/logic/sceneadmin/delete_scene.go b/tg-service/logic/sceneadmin/delete_scene.go deleted file mode 100644 index df59aacbd4a2cc13ba6199edf65dee2a62e9b320..0000000000000000000000000000000000000000 --- a/tg-service/logic/sceneadmin/delete_scene.go +++ /dev/null @@ -1,54 +0,0 @@ -package sceneadmin - -import ( - "context" - "github.com/didi/tg-flow/tg-core/common/mysql" - "github.com/didi/tg-flow/tg-core/common/tlog" - "tg-service/common/logs" - "tg-service/idl" -) - -//删除数据 -func DeleteSceneConfig(deleteData *idl.SceneConfig) *idl.ResponseInfo { - responseInfo := &idl.ResponseInfo{ - Tag: true, - ErrMsg: "", - } - - //删除workflow表配置 - sql := "delete from workflow where experiment_id=?" - _, err := mysql.Handler.Exec(sql, deleteData.Id) - if err != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = "删除workflow表 该场景的配置 失败!" + err.Error() - return responseInfo - } - - //删除rec_scene_config表配置 - //sql = "delete from rec_scene_config where scene_id = ?" - //_, err = mysql.Handler.Exec(sql, deleteData.Id) - //if err != nil { - // responseInfo.Tag = false - // responseInfo.ErrMsg = "删除rec_scene_config表 该场景的配置 失败!" + err.Error() - // return responseInfo - // } - - //删除dimension表配置 - sql = "delete from dimension where scene_id = ?" - _, err = mysql.Handler.Exec(sql, deleteData.Id) - if err != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = "删除 dimension表 该场景的配置 失败!" + err.Error() - return responseInfo - } - - //删除场景配置 - sql = "delete from scene_config where id=?" - _, err = mysql.Handler.Exec(sql, deleteData.Id) - if err != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = "删除该场景的配置 失败!" + err.Error() - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=sceneadmin.DeleteSceneConfig||sql=%v||err=%v", sql, err) - } - return responseInfo -} diff --git a/tg-service/logic/sceneadmin/select_scene_conf.go b/tg-service/logic/sceneadmin/select_scene_conf.go deleted file mode 100644 index 1b10ed8a213d2b219431acb89f6fd3b75961c81a..0000000000000000000000000000000000000000 --- a/tg-service/logic/sceneadmin/select_scene_conf.go +++ /dev/null @@ -1,146 +0,0 @@ -package sceneadmin - -import ( - "context" - "database/sql" - "github.com/didi/tg-flow/tg-core/common/mysql" - "github.com/didi/tg-flow/tg-core/common/tlog" - "tg-service/common/logs" - "tg-service/common/template" - "tg-service/idl" - "tg-service/logic" - "tg-service/logic/appconfigadmin" - - "time" -) - -//查询sceneconfig数据 -func SelectSceneConf(selectData *idl.SceneConfig, pageLimit int64, pageNum int64, useLimit bool) []*idl.SceneConfig { - sqlStr := "select id,name,app_id,bucket_type,operator,create_time,update_time,flow_type,name_zh,exp_name from scene_config" - tempSql := " order by id desc" - if selectData.Id > 0 { //按场景编号查询 - sqlStr += " where id = ?" + tempSql - } else if selectData.Name != "" && selectData.Name != "-1" && selectData.Name != "全部" { //按场景名称查询 - sqlStr += " where name = ?" + tempSql - } else if selectData.AppName != "" && selectData.AppName != "-1" { //按系统名称查询 - //传过来的是系统名称,但是系统相关信息已经拆分到app_config表,因此,此处需要将名称转化成系统id查询 - sqlStr += " where app_id = ?" + tempSql - } else if selectData.BucketType > 0 { //按分桶类型查询 - sqlStr += " where bucket_type = ?" + tempSql - } else { //全量️查询 - sqlStr += tempSql - } - - if useLimit { - sqlStr = logic.AddSelectLimit(sqlStr, pageLimit, pageNum) - } - - return SelectSceneConfPre(sqlStr, selectData) -} - -func SelectSceneConfPre(sqlStr string, selectData *idl.SceneConfig) []*idl.SceneConfig { - //查询数据库 - sceneConfigList := SelectServerDB(sqlStr, selectData) - return sceneConfigList -} - -//数据库查询 -func SelectServerDB(sqlStr string, selectData *idl.SceneConfig) []*idl.SceneConfig { - sceneConfigList := make([]*idl.SceneConfig, 0) - stmt, err := mysql.Handler.Prepare(sqlStr) - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=sceneadmin.SelectServerDB||sql=%v||err=%v", sqlStr, err) - return sceneConfigList - } - defer stmt.Close() - - var rows *sql.Rows - if selectData.Id > 0 { //按场景编号查询 - rows, err = stmt.Query(selectData.Id) - } else if selectData.Name != "" && selectData.Name != "-1" && selectData.Name != "全部" { //按场景名称查询 - rows, err = stmt.Query(selectData.Name) - } else if selectData.AppName != "" && selectData.AppName != "-1" { //按系统名称查询 - appId := template.AppNameMap[selectData.AppName] - rows, err = stmt.Query(appId) - } else if selectData.BucketType > 0 { //按分桶类型查询 - rows, err = stmt.Query(selectData.BucketType) - } else { - rows, err = stmt.Query() - } - - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=sceneadmin.SelectServerDB||sql=%v||err=%v", sqlStr, err) - return sceneConfigList - } - defer rows.Close() - - for rows.Next() { - var createTime time.Time - var updateTime time.Time - var sceneConfig = new(idl.SceneConfig) - err := rows.Scan(&sceneConfig.Id, &sceneConfig.Name, &sceneConfig.AppId, &sceneConfig.BucketType, &sceneConfig.Operator, &createTime, &updateTime, &sceneConfig.FlowType, &sceneConfig.NameZh, &sceneConfig.ExpName) - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=sceneadmin.SceneRowsScan||rows=%v||err=%v", rows, err) - return sceneConfigList - } - - //根据appid,查询app_config表,获取appname - appData := &idl.AppConfigInfo{ - Id: sceneConfig.AppId, - } - appInfo := appconfigadmin.SelectAppConf(appData, -1, 0, false) - - if len(appInfo) > 0 { - sceneConfig.AppName = appInfo[0].AppName - } else { - sceneConfig.AppName = "数据异常" - } - - //时间格式转化 - sceneConfig.CreateTime = createTime.Format(logic.TIME_FORMAT) - sceneConfig.UpdateTime = updateTime.Format(logic.TIME_FORMAT) - - sceneConfigList = append(sceneConfigList, sceneConfig) - } - err = rows.Err() - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=sceneadmin.SceneRowsErr||respones row is err||err=%v", err) - return sceneConfigList - } - return sceneConfigList -} - -//查询数据库中最大的appid -func SelectMaxAppId() int { - sqlStr := "select MAX(app_id) from scene_config" - stmt, err := mysql.Handler.Prepare(sqlStr) - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=sceneadmin.SelectMaxAppId||sql=%v||err=%v", sqlStr, err) - return -1 - } - defer stmt.Close() - - var rows *sql.Rows - rows, err = stmt.Query() - - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=sceneadmin.SelectMaxAppId||sql=%v||err=%v", sqlStr, err) - return -1 - } - defer rows.Close() - - var maxAppId int - for rows.Next() { - err := rows.Scan(&maxAppId) - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=sceneadmin.SelectMaxAppIdRowsScan||rows=%v||err=%v", rows, err) - return -1 - } - } - err = rows.Err() - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=sceneadmin.SelectMaxAppIdRowsErr||respones row is err||err=%v", err) - return -1 - } - return maxAppId -} diff --git a/tg-service/logic/select.go b/tg-service/logic/select.go deleted file mode 100644 index 40048e729f85b3193816e9b8bbca342cd1799557..0000000000000000000000000000000000000000 --- a/tg-service/logic/select.go +++ /dev/null @@ -1,131 +0,0 @@ -package logic - -import ( - "context" - "database/sql" - "github.com/didi/tg-flow/tg-core/common/mysql" - "github.com/didi/tg-flow/tg-core/common/tlog" - "sort" - "strconv" - "strings" - "tg-service/common/logs" - "tg-service/idl" -) - -//查询数据 -func Select(selectData *idl.WorkFlowData) []*idl.WorkFlowData { - var sqlStr string - if selectData.ExperimentId == "" { //全量️查询 - sqlStr = "select id,experiment_id, modules,is_default,range1,remark,create_time,update_time,operator,manual_slot_ids from workflow where status=1" - } else { //按场景id查询 - _, err := strconv.ParseInt(selectData.ExperimentId, 10, 64) - if err != nil { - return make([]*idl.WorkFlowData, 0) - } - sqlStr = "select id,experiment_id, modules,is_default,range1, remark,create_time,update_time,operator,manual_slot_ids from workflow where status=1 and experiment_id = ?" - } - return SelectWorkFlowPre(sqlStr, selectData.ExperimentId, 0) -} - -func SelectWorkFlowPre(sqlStr string, experimentId string, dimendionId int64) []*idl.WorkFlowData { - //查询数据库 - workFlowMap := SelectWorkFlow(sqlStr, experimentId, dimendionId) - //组装返回结果 - workFlowDataList := Process(workFlowMap) - return workFlowDataList -} - -//数据库查询 -func SelectWorkFlow(sqlStr string, id string, dimendionId int64) map[int64]map[int64]*idl.WorkFlow { - workFlowMap := make(map[int64]map[int64]*idl.WorkFlow) - stmt, err := mysql.Handler.Prepare(sqlStr) - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadExperimentWorkflowFail, "etype=logic_SelectWorkFlow_Prepare||econtent=sql:%v||err=%v", sqlStr, err) - return workFlowMap - } - defer stmt.Close() - - var rows *sql.Rows - if id == "" { - rows, err = stmt.Query() - } else { - rows, err = stmt.Query(id, dimendionId) - } - - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadExperimentWorkflowFail, "etype=logic_SelectWorkFlow_Query||econtent=sql:%v||err=%v", sqlStr, err) - return workFlowMap - } - defer rows.Close() - - for rows.Next() { - var workFlow = new(idl.WorkFlow) - err := rows.Scan(&workFlow.Id, &workFlow.DimensionId, &workFlow.ExperimentId, &workFlow.Modules, &workFlow.IsDefault, &workFlow.Range1, &workFlow.Remark, &workFlow.CreateTime, &workFlow.UpdateTime, &workFlow.Operator, &workFlow.ManualSlotIds) - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadExperimentWorkflowFail, "etype=logic_workflowrowsScan||econtent=rows:%v||err=%v", rows, err) - return workFlowMap - } - tempMap := workFlowMap[workFlow.ExperimentId] - if tempMap == nil { - tempMap = make(map[int64]*idl.WorkFlow) - workFlowMap[workFlow.ExperimentId] = tempMap - } - tempMap[workFlow.Id] = workFlow - } - err = rows.Err() - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadExperimentWorkflowFail, "etype=logic_workflowrowsErr||econtent=||err=%v", err) - return workFlowMap - } - return workFlowMap -} - -//对查询的数据库数据整理 -func Process(workFlowMap map[int64]map[int64]*idl.WorkFlow) []*idl.WorkFlowData { - workFlowDataList := make([]*idl.WorkFlowData, 0) - if workFlowMap == nil || len(workFlowMap) <= 0 { - return workFlowDataList - } - - keys := make([]int, 0) - for key := range workFlowMap { - keys = append(keys, int(key)) - } - // 给key排序,从小到大 - sort.Sort(sort.IntSlice(keys)) - - for _, key := range keys { - tempMap := workFlowMap[int64(key)] - if len(tempMap) <= 0 { - continue - } - tempKeys := make([]int, 0) - for tempkey := range tempMap { - tempKeys = append(tempKeys, int(tempkey)) - } - // 给key排序,从小到大 - sort.Sort(sort.IntSlice(tempKeys)) - - for _, k := range tempKeys { - value := tempMap[int64(k)] - var data = new(idl.WorkFlowData) - data.ExperimentId = strconv.FormatInt(value.ExperimentId, 10) - data.WorkFlowId = strconv.FormatInt(value.Id, 10) - data.Modules = value.Modules - data.Defult = strconv.Itoa(value.IsDefault) - data.Remark = value.Remark - data.CreateTime = value.CreateTime - data.UpdateTime = value.UpdateTime - data.Operator = value.Operator - data.ManualSlotIds = value.ManualSlotIds - proportionStr := strings.Split(value.Range1, ",") - if len(proportionStr) == 1 && proportionStr[0] == "" { - data.Proportion = "0%" - } else { - data.Proportion = strconv.Itoa(len(proportionStr)) + "%" - } - workFlowDataList = append(workFlowDataList, data) - } - } - return workFlowDataList -} diff --git a/tg-service/logic/workflowadmin/add_update_workflow.go b/tg-service/logic/workflowadmin/add_update_workflow.go deleted file mode 100644 index 0567ae947d8fceb54dc380f68b7ac1defc40e6d7..0000000000000000000000000000000000000000 --- a/tg-service/logic/workflowadmin/add_update_workflow.go +++ /dev/null @@ -1,112 +0,0 @@ -package workflowadmin - -import ( - "fmt" - "sort" - "strconv" - "strings" - "tg-service/common/template" - "tg-service/idl" - "tg-service/logic" -) - -func AddOrUpdateWorkFlowConfig(addData *idl.WorkFlowConfig) *idl.ResponseInfo { - responseInfo := &idl.ResponseInfo{ - Tag: true, - ErrMsg: "", - } - - if addData.OldWorkFlowId == "" { //新增数据 - AddWorkFlow(addData, responseInfo) - } else { //更新数据 - UpdateDBWorkFlow(addData, responseInfo) - } - return responseInfo -} - -//查询指定场景id下的主流量、非主流量占比等信息 -func SelectDBMainAndThisWorkFlow(data *idl.WorkFlowConfig) (*idl.WorkFlowConfig, *idl.WorkFlowConfig, int, string, error) { - //根据场景名称,获取场景id - var sceneId int - sceneId, ok := template.SceneNameAndIdMap[data.SceneName] - if !ok { - return nil, nil, 0, "", fmt.Errorf("SceneNameAndIdMap not has sceneid=%v", data.SceneName) - } - selectSql := "select id,dimension_id,experiment_id, modules,is_default,range1,range2, remark , create_time ,update_time , operator, manual_slot_ids,group_name, flow_chart from workflow where status=1 and experiment_id = ? and dimension_id = ?" - sceneMap, err := SelectDBWorkFlow(selectSql, sceneId, data.DimensionId) - if err != nil { - return nil, nil, 0, "", err - } - - haveUseProportion := 0 //不包括该非主流量的,其他非主流量的总占比百分数 - haveUseRange1 := "" //不包括该非主流量的,其他非主流量的总占比离散数字值 - var defaultWorkFlow = new(idl.WorkFlowConfig) //主流量 - var thisWorkFlow = new(idl.WorkFlowConfig) //本条流量在数据库中的记录 - for _, workFlowMap := range sceneMap { - for _, workFlow := range workFlowMap { - if workFlow.IsDefault == 1 { //主流量 - defaultWorkFlow.WorkFlowId = strconv.FormatInt(workFlow.Id, 10) - defaultWorkFlow.Modules = workFlow.Modules - defaultWorkFlow.Proportion = workFlow.Range1 - defaultWorkFlow.Remark = workFlow.Remark - defaultWorkFlow.ManualSlotIds = workFlow.ManualSlotIds - } else { - //未修改workflow id时,需要将数据库中的流量占比离散数字,赋值给请求的记录中,便于后续计算新的流量占比离散数字 - if strconv.FormatInt(workFlow.Id, 10) == data.WorkFlowId { - data.Proportion = workFlow.Range1 - } - //修改了workflow id时,需要将数据库中该条流量对应的原始数据返回 - if strconv.FormatInt(workFlow.Id, 10) == data.OldWorkFlowId { - thisWorkFlow.WorkFlowId = strconv.FormatInt(workFlow.Id, 10) - thisWorkFlow.Modules = workFlow.Modules - thisWorkFlow.Proportion = workFlow.Range1 - thisWorkFlow.Remark = workFlow.Remark - thisWorkFlow.Defult = strconv.Itoa(workFlow.IsDefault) - thisWorkFlow.ManualSlotIds = workFlow.ManualSlotIds - } else { - //将其他非主流量的占比,离散数字加在一起 - if len(haveUseRange1) <= 0 { - haveUseRange1 += workFlow.Range1 - } else { - haveUseRange1 += "," + workFlow.Range1 - } - //将其他非主流量的占比,百分数加在一起 - if workFlow.Range1 != "" { - proportionStr := strings.Split(workFlow.Range1, ",") - haveUseProportion += len(proportionStr) - } - } - } - } - } - return defaultWorkFlow, thisWorkFlow, haveUseProportion, haveUseRange1, nil -} - -//调整主流量占比值和给新增流量分配占比离散数字(0-99) -func ModifyWorkFlowRange(proportionStr []string, proportion int) (string, string) { - var addRangeStr string //新增的分桶流量占比 - var rangeStr string //更新主流量占比 - index := 0 - //在主流量proportionStr中,随机挑选proportion个新增的流量占比值 - indexArry := logic.GenerateRandomNumber(0, len(proportionStr), proportion) - //对indexArry数组从小到大排序 - sort.Ints(indexArry) - for i := 0; i < len(proportionStr); i++ { - if index < len(indexArry) && i == indexArry[index] { - if len(addRangeStr) <= 0 { - addRangeStr += proportionStr[i] - } else { - addRangeStr += "," + proportionStr[i] - } - index += 1 - } else { - if len(rangeStr) <= 0 { - rangeStr += proportionStr[i] - } else { - rangeStr += "," + proportionStr[i] - } - } - } - - return addRangeStr, rangeStr -} diff --git a/tg-service/logic/workflowadmin/add_workflow.go b/tg-service/logic/workflowadmin/add_workflow.go deleted file mode 100644 index 4d1ed319cb14611a7e9b6f9163cff73ab891063d..0000000000000000000000000000000000000000 --- a/tg-service/logic/workflowadmin/add_workflow.go +++ /dev/null @@ -1,126 +0,0 @@ -package workflowadmin - -import ( - "github.com/didi/tg-flow/tg-core/common/mysql" - "strconv" - "strings" - "tg-service/common/template" - "tg-service/idl" - "tg-service/logic" - "tg-service/logic/sceneadmin" - "time" -) - -func AddWorkFlow(addData *idl.WorkFlowConfig, responseInfo *idl.ResponseInfo) { - var flowType int64 - flowType = -1 - if addData.SceneId != 0 { - sceneData := &idl.SceneConfig{ - Id: addData.SceneId, - } - sceneConfigList := sceneadmin.SelectSceneConf(sceneData, -1, 0, false) - if len(sceneConfigList) != 0 { - flowType = sceneConfigList[0].FlowType - } - } - - nowTime := time.Now().Format("2006-01-02 15:04:05") - //新增流量占比 - proportion, _ := strconv.Atoi(addData.Proportion) - - //根据场景id,查询主流量占比,并更新 - var sceneId int - sceneId, ok := template.SceneNameAndIdMap[addData.SceneName] - if !ok { - sceneId = 0 - } - - //查询该场景和维度下的信息 - sql := "select id,dimension_id,experiment_id, modules,is_default,range1,range2, remark ,create_time,update_time,operator,manual_slot_ids,group_name, flow_chart from workflow where status=1 and experiment_id = ? and dimension_id = ?" - workFlowMap, err := SelectDBWorkFlow(sql, sceneId, addData.DimensionId) - if err != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = "添加数据失败:" + err.Error() - return - } - - //找出主流量 - defaultWorkFlow := new(idl.WorkFlow) - for _, sceneMap := range workFlowMap { //同一个场景和维度下,主流量只会有一条记录 - for _, workFlow := range sceneMap { - if workFlow.IsDefault == 1 { - defaultWorkFlow = workFlow - break - } - } - } - - //新增的分桶流量占比离散数字(0-99)字符串 - var addRangeStr string - //需要更新的主流量的分桶流量占比离散数字(0-99)字符串 - var defaultRangeStr string - //主流量实验编号 - var defaultWorkFlowId int64 - - defaultProportion := strings.Split(defaultWorkFlow.Range1, ",") - - defaultProportionLength := 0 - if len(defaultWorkFlow.Range1) > 0 { //排除主流量占比值为空的情况 - defaultProportionLength = len(defaultProportion) - } - - if flowType == 0 { - if defaultProportionLength < proportion { - responseInfo.Tag = false - responseInfo.ErrMsg = "新增的流量占比,超过了可分配的流量" - return - } else { - defaultWorkFlowId = defaultWorkFlow.Id - //生成新增流量和主流量占比的离散数字(0-99)字符串 - addRangeStr, defaultRangeStr = ModifyWorkFlowRange(defaultProportion, proportion) - - //校验添加操作后的流量总占比,是否为100 - err := logic.CheckAfterAddOP(strconv.FormatInt(defaultWorkFlow.ExperimentId, 10), addData.DimensionId, strconv.FormatInt(defaultWorkFlow.Id, 10), defaultRangeStr, addRangeStr) - if err != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = err.Error() - return - } - } - } - - /**************先入库新增流量成功了,才能去更新之前的主流量占比*********************/ - - //if len(addRangeStr) <= 0 || addRangeStr == "" { - // responseInfo.Tag = false - // responseInfo.ErrMsg = "新增分桶流量分配占比,必须大于0" - // return - //} - - var addSql string - var addErr error - addRange2 := logic.CreateRangeStr(addRangeStr) - if addData.WorkFlowId == "" { //新增时,没有填写实验编号 - addSql = "insert into workflow(dimension_id,experiment_id, modules,is_default,status,range1,range2,remark,create_time,update_time,operator,manual_slot_ids,group_name,flow_chart) values(?,?,?,0,1,?,?,?,?,?,?,?,?,?)" - _, addErr = mysql.Handler.Exec(addSql, addData.DimensionId, sceneId, addData.Modules, addRangeStr, addRange2, addData.Remark, nowTime, nowTime, addData.Operator, addData.ManualSlotIds, addData.GroupName, addData.FlowChartJson) - } else { - addSql = "insert into workflow(id,dimension_id,experiment_id, modules,is_default,status,range1,range2,remark,create_time,update_time,operator,manual_slot_ids,group_name,flow_chart) values(?,?,?,?,0,1,?,?,?,?,?,?,?,?,?)" - _, addErr = mysql.Handler.Exec(addSql, addData.WorkFlowId, addData.DimensionId, sceneId, addData.Modules, addRangeStr, addRange2, addData.Remark, nowTime, nowTime, addData.Operator, addData.ManualSlotIds, addData.GroupName, addData.FlowChartJson) - } - - if addErr != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = addErr.Error() - return - } - - //更新主流量占比,修改数据库 - range2 := logic.CreateRangeStr(defaultRangeStr) - updateSql := "update workflow set range1 = ? ,range2 = ? ,update_time = ?, operator =?, manual_slot_ids =? where id= ?" - _, updateErr := mysql.Handler.Exec(updateSql, defaultRangeStr, range2, nowTime, addData.Operator, defaultWorkFlow.ManualSlotIds, defaultWorkFlowId) - if updateErr != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = updateErr.Error() - return - } -} diff --git a/tg-service/logic/workflowadmin/delete_workflow.go b/tg-service/logic/workflowadmin/delete_workflow.go deleted file mode 100644 index 6f3d8d16af3789d09fdf219b1a938715fb115e9c..0000000000000000000000000000000000000000 --- a/tg-service/logic/workflowadmin/delete_workflow.go +++ /dev/null @@ -1,73 +0,0 @@ -package workflowadmin - -import ( - "context" - "github.com/didi/tg-flow/tg-core/common/mysql" - "github.com/didi/tg-flow/tg-core/common/tlog" - "tg-service/common/logs" - "tg-service/idl" - "tg-service/logic" - "time" -) - -//删除数据 -func DeleteWorkflowConfig(deleteData *idl.WorkFlowConfig) *idl.ResponseInfo { - responseInfo := &idl.ResponseInfo{ - Tag: true, - ErrMsg: "", - } - - //1、查询对应主流量信息 - workFlow, _, _, _, err := SelectDBMainAndThisWorkFlow(deleteData) - if err != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = "数据删除失败:" + err.Error() - return responseInfo - } - - //2、更新主流量range1和range2区间字段值 - var tempRange string - if len(deleteData.Proportion) <= 0 || deleteData.Proportion == "" { - tempRange = workFlow.Proportion - } else { - //因为SelectDBMainAndThisWorkFlow方法中,将这条被删除记录的Proportion属性值(请求中是百分数),用数据库中原始的占比离散数字字符串替换了 - //所以,此处可以直接将deleteData.Proportion中的占比离散数字,直接追加到主流量中 - tempRange = deleteData.Proportion + "," + workFlow.Proportion - } - - //3、删除操作后,对流量占比的校验 - err = logic.CheckDeleteOP(tempRange) - if err != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = err.Error() - return responseInfo - } - - nowTime := time.Now().Format("2006-01-02 15:04:05") - - //4、需要对range1的值按从小到大顺序排列 - range1 := logic.SortStr(tempRange) - - //5、对range1生成对应的区间表达式 - range2 := logic.CreateRangeStr(range1) - - //6、先更新主流量,如果失败,则不需要执行后续的删除操作 - updateSql := "update workflow set range1 = ?,range2 = ?,update_time =?,operator=?,manual_slot_ids=? where id = ?" - _, updateErr := mysql.Handler.Exec(updateSql, range1, range2, nowTime, deleteData.Operator, workFlow.ManualSlotIds, workFlow.WorkFlowId) - if updateErr != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = updateErr.Error() - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=workflowadmin.DeleteWorkflowConfig||sql=%v||err=%v", updateSql, err) - return responseInfo - } - - //7、删除该条副流量实验 - deleteSql := "delete from workflow where id = ?" - _, deleteErr := mysql.Handler.Exec(deleteSql, deleteData.WorkFlowId) - if deleteErr != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = deleteErr.Error() - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=workflowadmin.DeleteWorkflowConfig||sql=%v||err=%v", deleteSql, err) - } - return responseInfo -} diff --git a/tg-service/logic/workflowadmin/export_workflow.go b/tg-service/logic/workflowadmin/export_workflow.go deleted file mode 100644 index 0d81229d5278574157e03dfbd89384905263e04f..0000000000000000000000000000000000000000 --- a/tg-service/logic/workflowadmin/export_workflow.go +++ /dev/null @@ -1,97 +0,0 @@ -package workflowadmin - -import ( - "context" - "encoding/json" - "github.com/didi/tg-flow/tg-core/common/mysql" - "github.com/didi/tg-flow/tg-core/common/tlog" - "github.com/didi/tg-flow/tg-core/wfengine" - "strconv" - "tg-service/common/logs" - "tg-service/common/template" - "tg-service/idl" - "time" -) - -//导出数据 -func ExportWorkFlow(exportData *idl.WorkFlowConfig) *idl.ResponseInfo { - responseInfo := &idl.ResponseInfo{ - Tag: true, - ErrMsg: "", - } - workFlow, err := GetWorkFlowExport(exportData) - if err != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = err.Error() - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=workflowAdmin.getWorkFlowErr||err=%v", err) - return responseInfo - } - response, err := json.Marshal(workFlow) - if err != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = err.Error() - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=workflowAdmin.getWorkFlowErr||err=%v", err) - return responseInfo - } - responseInfo.Content = string(response) - return responseInfo -} -func GetWorkFlowExport(exportData *idl.WorkFlowConfig) (*idl.WorkflowExport, error) { - workflow, flowChartStr, err := getWorkFlow(exportData) - if err != nil { - return nil, err - } - var actionMap = new(idl.WorkflowChart) - if len(flowChartStr) == 0 { - actionMap.ActionMap = make(map[string]*idl.Action) - } else { - err = json.Unmarshal([]byte(flowChartStr), actionMap) - } - if err != nil { - return nil, err - } - var exportWorkflow = idl.WorkflowExport{ - Id: workflow.Id, - SceneId: workflow.SceneId, - FlowCharts: actionMap, - } - sceneId, err := strconv.Atoi(strconv.FormatInt(workflow.SceneId, 10)) - if err != nil { - return nil, err - } - exportWorkflow.SceneName = template.SceneIdAndNameMap[sceneId] - return &exportWorkflow, nil - -} -func getWorkFlowShow(exportData *idl.WorkFlowConfig) (*wfengine.Workflow, string, error) { - workflow, flowChartStr, err := getWorkFlow(exportData) - return workflow, flowChartStr, err -} -func getWorkFlow(workflowConfig *idl.WorkFlowConfig) (*wfengine.Workflow, string, error) { - sql := "select id,dimension_id,experiment_id,flow_chart,is_default,range1,range2,remark,group_name from workflow where id = ?" - rows, err := mysql.Handler.Query(sql, workflowConfig.WorkFlowId) - if err != nil { - return nil, "", err - } - defer rows.Close() - err = rows.Err() - if err != nil { - return nil, "", err - } - var workflow = new(wfengine.Workflow) - var flowChartStr string - for rows.Next() { - err := rows.Scan(&workflow.Id, &workflow.DimensionId, &workflow.SceneId, &flowChartStr, &workflow.IsDefault, &workflow.Range1, &workflow.Range2, &workflow.Remark, &workflow.GroupName) - if err != nil { - return nil, "", err - } - //if len(flowChartStr) > 0 { - // workflow.FlowCharts, workflow.FlowBranch, err = wfengine.NewWorkflowChart(flowChartStr) - // if err != nil { - // return nil, "", err - // } - //} - workflow.UpdateTime = time.Now() - } - return workflow, flowChartStr, nil -} diff --git a/tg-service/logic/workflowadmin/flowchecker/checker.go b/tg-service/logic/workflowadmin/flowchecker/checker.go deleted file mode 100644 index 950437b886c38424aa9b37473cabd3b6e6d1a9e5..0000000000000000000000000000000000000000 --- a/tg-service/logic/workflowadmin/flowchecker/checker.go +++ /dev/null @@ -1,131 +0,0 @@ -package flowchecker - -import ( - "fmt" - "strconv" - "strings" - "tg-service/idl" -) - -func replaceWorkflowID(id string, workflowId int64) (string, error) { - idSeg := strings.Split(id, "-") - if len(idSeg) != 3 || idSeg[0] != "action" { - return "", fmt.Errorf("action id " + id + "is illegal") - } - - // 将 action ID 中的 Workflow ID 替换为当前的 Workflow ID - idSeg[1] = strconv.Itoa(int(workflowId)) - return strings.Join(idSeg, "-"), nil -} - -func replaceIDsForAction(action *idl.Action, workflowId int64) error { - if action == nil { - return fmt.Errorf("action is nil") - } - - // replace action id - newId, err := replaceWorkflowID(action.ActionId, workflowId) - if err != nil { - return fmt.Errorf("action id illegal: %v", err) - } - action.ActionId = newId - - if len(action.NextActionIds) == 0 { - return nil - } - - // replace next action id - newNextIds := make([]string, 0) - for _, id := range action.NextActionIds { - newId, err = replaceWorkflowID(id, workflowId) - if err != nil { - return fmt.Errorf("action id illegal: %v", err) - } - newNextIds = append(newNextIds, newId) - } - action.NextActionIds = newNextIds - return nil -} - -func isDup(strs []string) bool { - m := make(map[string]bool) - for _, s := range strs { - if m[s] { - return true - } - m[s] = true - } - return false -} - -func checkFlowChart(flowChart *idl.WorkflowChart) error { - - if flowChart == nil { - return fmt.Errorf("flow chart is nil") - } - - if len(flowChart.ActionMap) == 0 { - return fmt.Errorf("not action in flow chart") - } - - for id, action := range flowChart.ActionMap { - if id != action.ActionId { - return fmt.Errorf("action id is not match, id: %v", id) - } - - if isDup(action.NextActionIds) { - return fmt.Errorf("next action ids duplicated, action id %v", action.ActionId) - } - - for _, id := range action.NextActionIds { - if flowChart.ActionMap[id] == nil { - return fmt.Errorf("next action id is not in flow chart, id: %v", id) - } - } - - } - return nil -} - -func reaplceActionIdsAndCreateNewFlow(flowChart *idl.WorkflowChart, workflowId int64) (*idl.WorkflowChart, error) { - newActions := make([]*idl.Action, 0) - for aid, action := range flowChart.ActionMap { - err := replaceIDsForAction(action, workflowId) - if err != nil { - return nil, fmt.Errorf("replace id for action %v error: %v", aid, err) - } - newActions = append(newActions, action) - } - - newFLowChart := &idl.WorkflowChart{ - ActionMap: make(map[string]*idl.Action), - } - - for _, action := range newActions { - newFLowChart.ActionMap[action.ActionId] = action - } - - if len(newFLowChart.ActionMap) != len(newActions) { - return nil, fmt.Errorf("there are action ids duplicated") - } - return newFLowChart, nil -} - -// ReplaceActionIDsForFlow 替换流程中的 ActionID 以匹配新的 workflowId, action ID 格式必须为 action-{workflowId}-{uid} -func ReplaceActionIDsForFlow(flowChart *idl.WorkflowChart, workflowId int64) (*idl.WorkflowChart, error) { - - if err := checkFlowChart(flowChart); err != nil { - return nil, err - } - - newFlowChart, err := reaplceActionIdsAndCreateNewFlow(flowChart, workflowId) - if err != nil { - return nil, err - } - - if err := checkFlowChart(newFlowChart); err != nil { - return nil, err - } - - return newFlowChart, nil -} diff --git a/tg-service/logic/workflowadmin/flowchecker/checker_test.go b/tg-service/logic/workflowadmin/flowchecker/checker_test.go deleted file mode 100644 index 699475407af5b233c6a7c1f2a9118a072bca7806..0000000000000000000000000000000000000000 --- a/tg-service/logic/workflowadmin/flowchecker/checker_test.go +++ /dev/null @@ -1,156 +0,0 @@ -package flowchecker - -import ( - "reflect" - "testing" - "tg-service/idl" -) - -func TestCheckAndConvertID(t *testing.T) { - type args struct { - flowChart *idl.WorkflowChart - workflowId int64 - } - tests := []struct { - name string - args args - want *idl.WorkflowChart - wantErr bool - }{ - { - name: "flow char is nil", - args: args{ - flowChart: nil, - workflowId: 0, - }, - want: nil, - wantErr: true, - }, - { - name: "workflowId illegal", - args: args{ - flowChart: &idl.WorkflowChart{ActionMap: map[string]*idl.Action{"action-1-1": {}}}, - workflowId: 0, - }, - want: nil, - wantErr: true, - }, - { - name: "flow char actions emtpy", - args: args{ - flowChart: &idl.WorkflowChart{ActionMap: map[string]*idl.Action{}}, - workflowId: 1, - }, - want: nil, - wantErr: true, - }, - { - name: "flow char actions id illegal", - args: args{ - flowChart: &idl.WorkflowChart{ActionMap: map[string]*idl.Action{"foo-123": {}}}, - workflowId: 1, - }, - want: nil, - wantErr: true, - }, - { - name: "repeat action uid", - args: args{ - flowChart: &idl.WorkflowChart{ActionMap: map[string]*idl.Action{ - "action-103-1": {ActionId: "action-103-1"}, - "action-104-1": {ActionId: "action-104-1"}, - "action-103-3": {ActionId: "action-103-3"}, - "action-103-4": {ActionId: "action-103-4"}, - "action-103-5": {ActionId: "action-103-5"}, - }}, - workflowId: 100, - }, - want: nil, - wantErr: true, - }, - { - name: "flow char", - args: args{ - flowChart: &idl.WorkflowChart{ActionMap: map[string]*idl.Action{ - "action-103-1": {ActionId: "action-103-1"}, - "action-103-2": {ActionId: "action-103-2"}, - "action-103-3": {ActionId: "action-103-3"}, - "action-103-4": {ActionId: "action-103-4"}, - "action-103-5": {ActionId: "action-103-5"}, - }}, - workflowId: 100, - }, - want: &idl.WorkflowChart{ActionMap: map[string]*idl.Action{ - "action-100-1": {ActionId: "action-100-1"}, - "action-100-2": {ActionId: "action-100-2"}, - "action-100-3": {ActionId: "action-100-3"}, - "action-100-4": {ActionId: "action-100-4"}, - "action-100-5": {ActionId: "action-100-5"}, - }}, - wantErr: false, - }, - { - name: "action next ids", - args: args{ - flowChart: &idl.WorkflowChart{ActionMap: map[string]*idl.Action{ - "action-103-1": {ActionId: "action-103-1", NextActionIds: []string{"action-103-3"}}, - "action-103-2": {ActionId: "action-103-2", NextActionIds: []string{"action-103-4"}}, - "action-103-3": {ActionId: "action-103-3", NextActionIds: []string{"action-103-4", "action-103-5"}}, - "action-103-4": {ActionId: "action-103-4", NextActionIds: []string{"action-103-5"}}, - "action-103-5": {ActionId: "action-103-5"}, - }}, - workflowId: 100, - }, - want: &idl.WorkflowChart{ActionMap: map[string]*idl.Action{ - "action-100-1": {ActionId: "action-100-1", NextActionIds: []string{"action-100-3"}}, - "action-100-2": {ActionId: "action-100-2", NextActionIds: []string{"action-100-4"}}, - "action-100-3": {ActionId: "action-100-3", NextActionIds: []string{"action-100-4", "action-100-5"}}, - "action-100-4": {ActionId: "action-100-4", NextActionIds: []string{"action-100-5"}}, - "action-100-5": {ActionId: "action-100-5"}, - }}, - wantErr: false, - }, - { - name: "action next ids duplicated", - args: args{ - flowChart: &idl.WorkflowChart{ActionMap: map[string]*idl.Action{ - "action-103-1": {ActionId: "action-103-1", NextActionIds: []string{"action-103-3"}}, - "action-103-2": {ActionId: "action-103-2", NextActionIds: []string{"action-103-4"}}, - "action-103-3": {ActionId: "action-103-3", NextActionIds: []string{"action-103-4", "action-103-4"}}, - "action-103-4": {ActionId: "action-103-4", NextActionIds: []string{"action-103-5"}}, - "action-103-5": {ActionId: "action-103-5"}, - }}, - workflowId: 100, - }, - want: nil, - wantErr: true, - }, - { - name: "action next ids not exits", - args: args{ - flowChart: &idl.WorkflowChart{ActionMap: map[string]*idl.Action{ - "action-103-1": {ActionId: "action-103-1", NextActionIds: []string{"action-103-9"}}, - "action-103-2": {ActionId: "action-103-2", NextActionIds: []string{"action-103-4"}}, - "action-103-3": {ActionId: "action-103-3", NextActionIds: []string{"action-103-4", "action-103-5"}}, - "action-103-4": {ActionId: "action-103-4", NextActionIds: []string{"action-103-5"}}, - "action-103-5": {ActionId: "action-103-5"}, - }}, - workflowId: 100, - }, - want: nil, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ReplaceActionIDsForFlow(tt.args.flowChart, tt.args.workflowId) - if (err != nil) != tt.wantErr { - t.Errorf("ReplaceActionIDsForFlow() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ReplaceActionIDsForFlow() got = %#v, want %#v", got, tt.want) - } - }) - } -} diff --git a/tg-service/logic/workflowadmin/get_save_workflow.go b/tg-service/logic/workflowadmin/get_save_workflow.go deleted file mode 100644 index 19c2312172240fe61d0a2cd6aaa23fb26dfbefc5..0000000000000000000000000000000000000000 --- a/tg-service/logic/workflowadmin/get_save_workflow.go +++ /dev/null @@ -1,190 +0,0 @@ -package workflowadmin - -import ( - "container/list" - "context" - "encoding/json" - "github.com/didi/tg-flow/tg-core/common/mysql" - "github.com/didi/tg-flow/tg-core/common/tlog" - "strings" - "tg-service/common/logs" - "tg-service/idl" - "tg-service/logic/workflowadmin/flowchecker" - "time" -) - -//获取可以绘制的流程图信息 -func GetWorkFlowChart(exportData *idl.WorkFlowConfig) *idl.ResponseInfo { - responseInfo := &idl.ResponseInfo{ - Tag: true, - ErrMsg: "", - } - workFlow, err := GetWorkFlowExport(exportData) - if err != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = err.Error() - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=workflowAdmin.getWorkFlowErr||err=%v", err) - return responseInfo - } - - workFlowChart := formatWorkflow(workFlow) - - workFlowJson, err := json.Marshal(workFlowChart) - responseInfo.Content = string(workFlowJson) - return responseInfo -} - -func formatWorkflow(workflow *idl.WorkflowExport) idl.ChartG6 { - var nodeList []*idl.Node - var edgeList []*idl.Edge - - actions := workflow.FlowCharts.ActionMap - - typeMap := map[string]string{"task": "rect", "condition": "diamond", "flow": "circle", "timeout": "clock"} - - for _, v := range actions { - node := &idl.Node{ - Id: v.ActionId, - Label: v.ActionName, - NodeType: typeMap[v.ActionType], - Params: v.Params, - Timeout: v.Timeout, - RefWorkflowId: v.RefWorkflowId, - TimeoutAsync: v.TimeoutAsync, - TimeoutDynamic: v.TimeoutDynamic, - } - nodeList = append(nodeList, node) - if strings.EqualFold(v.ActionType, "condition") { - for i := 0; i < len(v.NextActionIds); i++ { - edge := &idl.Edge{ - Id: v.ActionId + "_" + v.NextActionIds[i], - EdgeType: "line", - Source: v.ActionId, - Target: v.NextActionIds[i], - Label: v.NextConditions[i], - } - edgeList = append(edgeList, edge) - } - node.Params = v.Params - } else { - for _, actionId := range v.NextActionIds { - edge := &idl.Edge{ - Id: v.ActionId + "_" + actionId, - EdgeType: "line", - Source: v.ActionId, - Target: actionId, - } - edgeList = append(edgeList, edge) - } - } - - } - workflowChart := idl.ChartG6{ - Nodes: nodeList, - Edges: edgeList, - } - return workflowChart -} - -// SaveImportWorkFlowChart 处理导入信息的保存 -func SaveImportWorkFlowChart(saveData *idl.WorkflowChart, workflowId int64, operator string) *idl.ResponseInfo { - responseInfo := &idl.ResponseInfo{ - Tag: true, - ErrMsg: "", - } - - flowChart, err := flowchecker.ReplaceActionIDsForFlow(saveData, workflowId) - if err != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = err.Error() - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=workflowAdmin.saveImportWorkFlowErr||err=%v", err) - return responseInfo - } - - updateJson, err := json.Marshal(flowChart) - if err != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = err.Error() - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=workflowAdmin.saveImportWorkFlowErr||err=%v", err) - return responseInfo - } - err = SaveUpdateJson(string(updateJson), workflowId) - if err != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = err.Error() - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=workflowAdmin.saveImportWorkFlowErr||err=%v", err) - return responseInfo - } - return responseInfo - -} - -func SaveWorkFlowChart(saveData *idl.ChartG6, workflowId int64, operator string) *idl.ResponseInfo { - responseInfo := &idl.ResponseInfo{ - Tag: true, - ErrMsg: "", - } - workflowChart := formatChartG6(saveData) - - updateJson, err := json.Marshal(workflowChart) - if err != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = err.Error() - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=workflowAdmin.saveWorkFlowErr||err=%v", err) - return responseInfo - } - err = SaveUpdateJson(string(updateJson), workflowId) - if err != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = err.Error() - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadDBFail, "etype=workflowAdmin.saveWorkFlowErr||err=%v", err) - return responseInfo - } - return responseInfo -} -func formatChartG6(saveData *idl.ChartG6) *idl.WorkflowChart { - nodes := saveData.Nodes - edges := saveData.Edges - workflowChart := new(idl.WorkflowChart) - actionMap := make(map[string]*idl.Action) - typeMap := map[string]string{"rect": "task", "diamond": "condition", "circle": "flow", "clock": "timeout"} - for _, node := range nodes { - action := idl.Action{ - ActionType: typeMap[node.NodeType], - ActionId: node.Id, - ActionName: node.Label, - Params: node.Params, - Timeout: node.Timeout, - RefWorkflowId: node.RefWorkflowId, - } - deleteIndex := list.New() - for edgeIndex, edge := range edges { - if edge.Source == node.Id { - action.NextActionIds = append(action.NextActionIds, edge.Target) - if action.ActionType == "condition" { - action.NextConditions = append(action.NextConditions, edge.Label) - } - deleteIndex.PushBack(edgeIndex) - } - } - for i := deleteIndex.Back(); i != nil; i = i.Prev() { - index := i.Value.(int) - edges = append(edges[:index], edges[index+1:]...) - } - actionMap[node.Id] = &action - } - workflowChart.ActionMap = actionMap - return workflowChart - -} - -//更新workflow信息 -func SaveUpdateJson(updateJson string, workflowId int64) error { - ctx := context.TODO() - updateTime := time.Now() - updateModifySql := "update workflow set flow_chart = ?, update_time = ? where id = ?" - _, updateModifyErr := mysql.Handler.Exec(updateModifySql, updateJson, updateTime, workflowId) - - tlog.Handler.Infof(ctx, logs.DLTagProcessLog, "etype=workflowadmin.UpdateDBWorkFlow||data=%v||err=本条记录修改成功", updateJson) - return updateModifyErr -} diff --git a/tg-service/logic/workflowadmin/select_workflow_config.go b/tg-service/logic/workflowadmin/select_workflow_config.go deleted file mode 100644 index 8226c051b173d2727bcb136a441242f683893c45..0000000000000000000000000000000000000000 --- a/tg-service/logic/workflowadmin/select_workflow_config.go +++ /dev/null @@ -1,163 +0,0 @@ -package workflowadmin - -import ( - "context" - "database/sql" - "github.com/didi/tg-flow/tg-core/common/mysql" - "github.com/didi/tg-flow/tg-core/common/tlog" - "sort" - "strconv" - "strings" - "tg-service/common/logs" - "tg-service/common/template" - "tg-service/idl" - "tg-service/logic" - "time" -) - -//查询workflow数据 -func SelectWorkFlowConfig(selectData *idl.WorkFlowConfig, pageLimit int64, pageNum int64, useLimit bool) ([]*idl.WorkFlowConfig, error) { - sqlStr := "select id, dimension_id, experiment_id, modules,is_default,range1,range2,remark,create_time,update_time,operator,manual_slot_ids,group_name, flow_chart from workflow where status=1" - workFlowMap := make(map[int64]map[int64]*idl.WorkFlow) - err := new(error) - //查询数据库,根据前端传回的名称,获取到场景id,再查询数据库 - if strings.HasPrefix(selectData.SceneName, "全部") && len(strings.Split(selectData.SceneName, ",")) > 1 { - sceneNameList := strings.Split(selectData.SceneName, ",") - sqlStr += " and experiment_id in (" - for _, sceneName := range sceneNameList[1:] { - sqlStr += strconv.Itoa(template.SceneNameAndIdMap[sceneName]) + "," - } - sqlStr = sqlStr[:len(sqlStr)-1] - sqlStr += ") and dimension_id = ?" - - if useLimit { - sqlStr = logic.AddSelectLimit(sqlStr, pageLimit, pageNum) - } - - workFlowMap, *err = SelectDBWorkFlow(sqlStr, -1, selectData.DimensionId) - } else { - sqlStr += " and experiment_id = ? and dimension_id = ?" - - if useLimit { - sqlStr = logic.AddSelectLimit(sqlStr, pageLimit, pageNum) - } - - workFlowMap, *err = SelectDBWorkFlow(sqlStr, template.SceneNameAndIdMap[selectData.SceneName], selectData.DimensionId) - } - - //组装返回结果 - workFlowDataList := Process(workFlowMap) - return workFlowDataList, *err -} - -//数据库查询 -func SelectDBWorkFlow(sqlStr string, sceneId int, dimensionId int64) (map[int64]map[int64]*idl.WorkFlow, error) { - workFlowMap := make(map[int64]map[int64]*idl.WorkFlow) - stmt, err := mysql.Handler.Prepare(sqlStr) - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadExperimentWorkflowFail, "etype=workflowadmin.SelectWorkFlow||econtent=sql:%v||err=%v", sqlStr, err) - return workFlowMap, err - } - defer stmt.Close() - - var rows *sql.Rows - if sceneId == -1 { - rows, err = stmt.Query(dimensionId) - } else { - rows, err = stmt.Query(sceneId, dimensionId) - } - - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadExperimentWorkflowFail, "etype=workflowadmin.SelectWorkFlow||econtent=sql:%v||err=%v", sqlStr, err) - return workFlowMap, err - } - defer rows.Close() - - for rows.Next() { - var createTime time.Time - var updateTime time.Time - var workFlow = new(idl.WorkFlow) - err := rows.Scan(&workFlow.Id, &workFlow.DimensionId, &workFlow.ExperimentId, &workFlow.Modules, &workFlow.IsDefault, &workFlow.Range1, &workFlow.Range2, &workFlow.Remark, &createTime, &updateTime, &workFlow.Operator, &workFlow.ManualSlotIds, &workFlow.GroupName, &workFlow.FlowCharts) - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadExperimentWorkflowFail, "etype=workflowadmin.workflowrowsScan||econtent=rows:%v||err=%v", rows, err) - return workFlowMap, err - } - tempMap := workFlowMap[workFlow.ExperimentId] - if tempMap == nil { - tempMap = make(map[int64]*idl.WorkFlow) - workFlowMap[workFlow.ExperimentId] = tempMap - } - - //时间格式转化 - workFlow.CreateTime = createTime.Format(logic.TIME_FORMAT) - workFlow.UpdateTime = updateTime.Format(logic.TIME_FORMAT) - - tempMap[workFlow.Id] = workFlow - } - err = rows.Err() - if err != nil { - tlog.Handler.Errorf(context.TODO(), logs.DLTagLoadExperimentWorkflowFail, "etype=workflowadmin.workflowrowsErr||econtent=||err=%v", err) - return workFlowMap, err - } - return workFlowMap, nil -} - -//对查询的数据库数据整理 -func Process(workFlowMap map[int64]map[int64]*idl.WorkFlow) []*idl.WorkFlowConfig { - workFlowDataList := make([]*idl.WorkFlowConfig, 0) - if workFlowMap == nil || len(workFlowMap) <= 0 { - return workFlowDataList - } - - keys := make([]int, 0) - for key := range workFlowMap { - keys = append(keys, int(key)) - } - // 给key排序,从小到大 - sort.Sort(sort.IntSlice(keys)) - - for _, key := range keys { - tempMap := workFlowMap[int64(key)] - if len(tempMap) <= 0 { - continue - } - tempKeys := make([]int, 0) - for tempkey := range tempMap { - tempKeys = append(tempKeys, int(tempkey)) - } - // 给key排序,从小到大 - sort.Sort(sort.IntSlice(tempKeys)) - - for _, k := range tempKeys { - - value := tempMap[int64(k)] - - var data = new(idl.WorkFlowConfig) - sceneId, _ := strconv.Atoi(strconv.FormatInt(value.ExperimentId, 10)) - data.SceneName = template.SceneIdAndNameMap[sceneId] - data.SceneId = value.ExperimentId - data.DimensionId = value.DimensionId - data.WorkFlowId = strconv.FormatInt(value.Id, 10) - data.Modules = value.Modules - data.ShowModules = value.FlowCharts - data.Defult = template.DefultIdAndNameMap[value.IsDefault] - data.Remark = value.Remark - data.Range1 = value.Range1 - data.Range2 = value.Range2 - data.CreateTime = value.CreateTime - data.UpdateTime = value.UpdateTime - data.Operator = value.Operator - data.ManualSlotIds = value.ManualSlotIds - data.GroupName = value.GroupName - proportionStr := strings.Split(value.Range1, ",") - if len(proportionStr) == 1 && proportionStr[0] == "" { - data.Proportion = "0%" - } else { - data.Proportion = strconv.Itoa(len(proportionStr)) + "%" - } - workFlowDataList = append(workFlowDataList, data) - } - } - - return workFlowDataList -} diff --git a/tg-service/logic/workflowadmin/update_workflow.go b/tg-service/logic/workflowadmin/update_workflow.go deleted file mode 100644 index f98f0aefe7668e67f3c8dfaef0f5d92062eb4695..0000000000000000000000000000000000000000 --- a/tg-service/logic/workflowadmin/update_workflow.go +++ /dev/null @@ -1,160 +0,0 @@ -package workflowadmin - -import ( - "context" - "github.com/didi/tg-flow/tg-core/common/mysql" - "github.com/didi/tg-flow/tg-core/common/tlog" - "strconv" - "strings" - "tg-service/common/logs" - "tg-service/common/template" - "tg-service/idl" - "tg-service/logic" - "tg-service/logic/sceneadmin" - "time" -) - -//更新workflow信息 -func UpdateDBWorkFlow(modifyData *idl.WorkFlowConfig, responseInfo *idl.ResponseInfo) { - var flowType int64 - flowType = -1 - if modifyData.SceneId != 0 { - sceneData := &idl.SceneConfig{ - Id: modifyData.SceneId, - } - sceneConfigList := sceneadmin.SelectSceneConf(sceneData, -1, 0, false) - if len(sceneConfigList) != 0 { - flowType = sceneConfigList[0].FlowType - } - } - ctx := context.TODO() - //1、先将请求记录中的流量占比取出来,第2步中会用数据库中的占比离散数字字符串,替换Proportion属性值 - proportion, _ := strconv.Atoi(modifyData.Proportion) - //2、查询对应主流量、数据库中该流量的信息和不包括该非主流量的,其他非主流量的总占比 和总占比值 - workFlow, thismodifyWorkFlow, haveUseProportion, _, err := SelectDBMainAndThisWorkFlow(modifyData) - if err != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = "修改数据失败:" + err.Error() - return - } - if workFlow == nil && thismodifyWorkFlow == nil { - responseInfo.Tag = false - responseInfo.ErrMsg = "查询数据库失败,导致更新操作失败,请重新更新!" - return - } - - if proportion > (100-haveUseProportion) && flowType == 0 { - responseInfo.Tag = false - responseInfo.ErrMsg = "修改的占比,超过了可分配占比,可分配占比 = " + strconv.Itoa(100-haveUseProportion) - return - } - - nowTime := time.Now().Format("2006-01-02 15:04:05") - - //3、表示要修改的是主流量 - if modifyData.OldWorkFlowId == workFlow.WorkFlowId { - sql := "update workflow set id=?,modules =?,remark =?,update_time =?,operator=?,manual_slot_ids=?,group_name=?,flow_chart=? where id = ?" - _, updateMainErr := mysql.Handler.Exec(sql, modifyData.WorkFlowId, modifyData.Modules, modifyData.Remark, nowTime, modifyData.Operator, modifyData.ManualSlotIds, modifyData.GroupName, modifyData.FlowChartJson, modifyData.OldWorkFlowId) - if updateMainErr != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = updateMainErr.Error() - } - tlog.Handler.Infof(ctx, logs.DLTagProcessLog, "etype=workflowadmin.UpdateDBWorkFlow||data=%v||err=主流量修改成功", modifyData) - return - } - - //4、该流量对应的数据库中的数据 - dbMainWorkFlowRangeArry := strings.Split(workFlow.Proportion, ",") - dbThismodifyWorkFlowRangeArry := strings.Split(thismodifyWorkFlow.Proportion, ",") - - thisModifyWorkFlowRang1 := "" //修改后的该条非主流量占比 - MainWorkFlowRang1 := "" //修改后的主流量调整后的占比 - dbThismodifyWorkFlowRangeArryLen := 0 //该条非主流量,数据库原始占比离散数字个数 - - if thismodifyWorkFlow.Proportion != "" { - dbThismodifyWorkFlowRangeArryLen = len(dbThismodifyWorkFlowRangeArry) - } - - //5、对流量占比,未做修改 - if dbThismodifyWorkFlowRangeArryLen == proportion { - MainWorkFlowRang1 = workFlow.Proportion - thisModifyWorkFlowRang1 = thismodifyWorkFlow.Proportion - } else if dbThismodifyWorkFlowRangeArryLen < proportion { - //6、新增了流量占比,新增部分,需要从主流量占比值中随机抽取 - count := proportion - dbThismodifyWorkFlowRangeArryLen - addRangeStr, rangeStr := ModifyWorkFlowRange(dbMainWorkFlowRangeArry, count) - MainWorkFlowRang1 = rangeStr - - //将新增部分占比的离散数字,和原始的占比离散数字,按从小到大排序组合在一起 - if len(addRangeStr) <= 0 { - thisModifyWorkFlowRang1 = logic.SortStr(thismodifyWorkFlow.Proportion) - } else { - if thismodifyWorkFlow.Proportion == "" { - thisModifyWorkFlowRang1 = logic.SortStr(addRangeStr) - } else { - thisModifyWorkFlowRang1 = logic.SortStr(addRangeStr + "," + thismodifyWorkFlow.Proportion) - } - } - } else { - //7、减少了流量占比,从该流量占比值中随机抽取减少部分,且还原给主流量 - count := dbThismodifyWorkFlowRangeArryLen - proportion - addRangeStr, rangeStr := ModifyWorkFlowRange(dbThismodifyWorkFlowRangeArry, count) - thisModifyWorkFlowRang1 = rangeStr - if len(addRangeStr) <= 0 { - MainWorkFlowRang1 = logic.SortStr(workFlow.Proportion) - } else { - MainWorkFlowRang1 = logic.SortStr(addRangeStr + "," + workFlow.Proportion) - } - } - - //8、校验修改操作后的流量总占比,是否为100 - err = logic.CheckModifyOP(haveUseProportion, MainWorkFlowRang1, thisModifyWorkFlowRang1) - if err != nil && flowType == 0 { - responseInfo.Tag = false - responseInfo.ErrMsg = err.Error() - return - } - - //9、生成对应的区间表达式 - thisModifyWorkFlowRang2 := logic.CreateRangeStr(thisModifyWorkFlowRang1) - MainWorkFlowRang2 := logic.CreateRangeStr(MainWorkFlowRang1) - - //10、判断是否需要将原主流量变成副流量 - mainDefult := "1" - if thismodifyWorkFlow.Defult == "0" && modifyData.Defult == "主" { - mainDefult = "0" - } - - //11、更新需要修改的流量信息 - - //强校验,最终入库的流量比例是否和修改传入的流量比例一致 - var thisModifyWorkFlowRang1Array []string - if thisModifyWorkFlowRang1 != "" { - thisModifyWorkFlowRang1Array = strings.Split(thisModifyWorkFlowRang1, ",") - } - if len(thisModifyWorkFlowRang1Array) != proportion && flowType == 0 { - responseInfo.Tag = false - responseInfo.ErrMsg = "最终入库的流量比例 和 修改传入的流量比例 不一致,入库失败,请重新更新!" - return - } - - updateModifySql := "update workflow set id=?,range1 = ?,range2 = ?,is_default = ?,modules =?,remark =?,update_time =?,operator=?,manual_slot_ids=?,group_name=?,flow_chart=? where id = ?" - _, updateModifyErr := mysql.Handler.Exec(updateModifySql, modifyData.WorkFlowId, thisModifyWorkFlowRang1, thisModifyWorkFlowRang2, template.DefultNameAndIdMap[modifyData.Defult], modifyData.Modules, modifyData.Remark, nowTime, modifyData.Operator, modifyData.ManualSlotIds, modifyData.GroupName, modifyData.FlowChartJson, modifyData.OldWorkFlowId) - if updateModifyErr != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = updateModifyErr.Error() - return - } - - tlog.Handler.Infof(ctx, logs.DLTagProcessLog, "etype=workflowadmin.UpdateDBWorkFlow||data=%v||Rang1=%v||Rang2=%v||err=本条记录修改成功", modifyData, thisModifyWorkFlowRang1, thisModifyWorkFlowRang2) - - //12、更新主流量信息 - updateMainSql := "update workflow set range1 = ?,range2 = ?,is_default = ?,update_time =?,operator=?,manual_slot_ids=? where id = ?" - _, updateMainErr := mysql.Handler.Exec(updateMainSql, MainWorkFlowRang1, MainWorkFlowRang2, mainDefult, nowTime, modifyData.Operator, workFlow.ManualSlotIds, workFlow.WorkFlowId) - if updateMainErr != nil { - responseInfo.Tag = false - responseInfo.ErrMsg = updateMainErr.Error() - return - } - tlog.Handler.Infof(ctx, logs.DLTagProcessLog, "etype=workflowadmin.UpdateDBWorkFlow||Rang1=%v||Rang2=%v||err=主流量修改成功", MainWorkFlowRang1, MainWorkFlowRang2) -} diff --git a/tg-service/main.go b/tg-service/main.go deleted file mode 100644 index 9a8e8220260bb451484caed262dfdaffb8bd7161..0000000000000000000000000000000000000000 --- a/tg-service/main.go +++ /dev/null @@ -1,21 +0,0 @@ -package main - -import ( - "github.com/didi/tg-flow/tg-core/common/httpserv" - "log" - "tg-service/conf" - "tg-service/cron" -) - -func main() { - //初始化配置 - conf.InitConfig() - - //启动定时任务 - cron.StartCronTask() - - //启动服务监听 - httpserv.Handler.Run() - - log.Println("Finished!") -} diff --git a/tg-web/CHANGELOG.md b/tg-web/CHANGELOG.md deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/tg-web/LICENSE b/tg-web/LICENSE deleted file mode 100644 index 6f6a7ea18f1d406a5a9f6dd848e8d81873e3b798..0000000000000000000000000000000000000000 --- a/tg-web/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 lyt-Top - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/tg-web/README.md b/tg-web/README.md deleted file mode 100644 index 58d0262d47a0a08f7851ba20ab377b11eb8b80a6..0000000000000000000000000000000000000000 --- a/tg-web/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# tg-admin - -#### 🌈 介绍 - -tg-flow前端 - -#### 🏭 环境支持 - -| Edge | Firefox | Chrome | Safari | -| --------- | ------------ | ----------- | ----------- | -| Edge ≥ 79 | Firefox ≥ 78 | Chrome ≥ 64 | Safari ≥ 12 | - - -#### ⚡ 使用说明 - -# 安装依赖 -npm install - -# 运行项目 -npm run dev - -# 打包发布 -npm run build -``` - -## Contribution - -Node 依赖: - -* `node>=12.0.0` -* `npm>=6.0.0` diff --git a/tg-web/build-exclude-list.txt b/tg-web/build-exclude-list.txt deleted file mode 100644 index 3e4e48b0b5fe6b468434d6767749b399319f2da2..0000000000000000000000000000000000000000 --- a/tg-web/build-exclude-list.txt +++ /dev/null @@ -1 +0,0 @@ -.gitignore \ No newline at end of file diff --git a/tg-web/env/.env b/tg-web/env/.env deleted file mode 100644 index 812bae3f29cd0fe1343fe5e2f57809309ec9870a..0000000000000000000000000000000000000000 --- a/tg-web/env/.env +++ /dev/null @@ -1,2 +0,0 @@ -VITE_API_BASE_URL=http://127.0.0.1:7001/api/ -VITE_TITLE=tg-flow \ No newline at end of file diff --git a/tg-web/env/.env.alpha b/tg-web/env/.env.alpha deleted file mode 100644 index 6968b60a3a5be885f9d0dfbf254d3655b209948e..0000000000000000000000000000000000000000 --- a/tg-web/env/.env.alpha +++ /dev/null @@ -1,2 +0,0 @@ -VITE_API_BASE_URL=/trajectory/api/ -VITE_PUBLIC_PATH=/trajectory/ \ No newline at end of file diff --git a/tg-web/env/.env.pre b/tg-web/env/.env.pre deleted file mode 100644 index 8cbffa91a6945e4d7dab3bf47a056230c735b752..0000000000000000000000000000000000000000 --- a/tg-web/env/.env.pre +++ /dev/null @@ -1,2 +0,0 @@ -VITE_API_BASE_URL=/api/ -VITE_TITLE=tg-flow \ No newline at end of file diff --git a/tg-web/env/.env.production b/tg-web/env/.env.production deleted file mode 100644 index 5b02e97e8ee64518cc127769d7bc7bec61356b4a..0000000000000000000000000000000000000000 --- a/tg-web/env/.env.production +++ /dev/null @@ -1 +0,0 @@ -VITE_API_BASE_URL=/api/ \ No newline at end of file diff --git a/tg-web/index.html b/tg-web/index.html deleted file mode 100644 index 26e03d53badb7043870983084d099e3afd2456a0..0000000000000000000000000000000000000000 --- a/tg-web/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - tg-flow - - -
- - - diff --git a/tg-web/package-lock.json b/tg-web/package-lock.json deleted file mode 100644 index 024e000f6c74f7937990599c4f1140f482e90ecc..0000000000000000000000000000000000000000 --- a/tg-web/package-lock.json +++ /dev/null @@ -1,3943 +0,0 @@ -{ - "name": "vue-next-admin", - "version": "2.2.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@ant-design/colors": { - "version": "4.0.5", - "resolved": "https://registry.npmmirror.com/@ant-design/colors/-/colors-4.0.5.tgz", - "integrity": "sha512-3mnuX2prnWOWvpFTS2WH2LoouWlOgtnIpc6IarWN6GOzzLF8dW/U8UctuvIPhoboETehZfJ61XP+CGakBEPJ3Q==", - "requires": { - "tinycolor2": "^1.4.1" - } - }, - "@antv/algorithm": { - "version": "0.1.25", - "resolved": "https://registry.npmmirror.com/@antv/algorithm/-/algorithm-0.1.25.tgz", - "integrity": "sha512-TGwPyFoAu4+iEJd0y1l0gHdBXCbUj8a4gR7P3GzZRfEfRnWfk+gswApzOSTd7c6HP402JOEF64PAJQKxQgSPSQ==", - "requires": { - "@antv/util": "^2.0.13", - "tslib": "^2.0.0" - } - }, - "@antv/dom-util": { - "version": "2.0.4", - "resolved": "https://registry.npmmirror.com/@antv/dom-util/-/dom-util-2.0.4.tgz", - "integrity": "sha512-2shXUl504fKwt82T3GkuT4Uoc6p9qjCKnJ8gXGLSW4T1W37dqf9AV28aCfoVPHp2BUXpSsB+PAJX2rG/jLHsLQ==", - "requires": { - "tslib": "^2.0.3" - } - }, - "@antv/event-emitter": { - "version": "0.1.3", - "resolved": "https://registry.npmmirror.com/@antv/event-emitter/-/event-emitter-0.1.3.tgz", - "integrity": "sha512-4ddpsiHN9Pd4UIlWuKVK1C4IiZIdbwQvy9i7DUSI3xNJ89FPUFt8lxDYj8GzzfdllV0NkJTRxnG+FvLk0llidg==" - }, - "@antv/g-base": { - "version": "0.5.14", - "resolved": "https://registry.npmmirror.com/@antv/g-base/-/g-base-0.5.14.tgz", - "integrity": "sha512-Wyx+ddatDdQBjidLHXmV3NgKp1oiyNZNX9gGflaBFDfGgywnvs85bXnKswayFXsFBg5TQ6Goi8SnBufEqwemgg==", - "requires": { - "@antv/event-emitter": "^0.1.1", - "@antv/g-math": "^0.1.9", - "@antv/matrix-util": "^3.1.0-beta.1", - "@antv/path-util": "~2.0.5", - "@antv/util": "~2.0.13", - "@types/d3-timer": "^2.0.0", - "d3-ease": "^1.0.5", - "d3-interpolate": "^3.0.1", - "d3-timer": "^1.0.9", - "detect-browser": "^5.1.0", - "tslib": "^2.0.3" - }, - "dependencies": { - "d3-timer": { - "version": "1.0.10", - "resolved": "https://registry.npmmirror.com/d3-timer/-/d3-timer-1.0.10.tgz", - "integrity": "sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw==" - } - } - }, - "@antv/g-canvas": { - "version": "0.5.13", - "resolved": "https://registry.npmmirror.com/@antv/g-canvas/-/g-canvas-0.5.13.tgz", - "integrity": "sha512-nu6wNeZhYomkEks2aniWlYML0ZGb9t5PGzjiOIp+B4z4HUEUvHOTdIPNfinzl5+4QC7fVZntsQKZK5dBFO5MDQ==", - "requires": { - "@antv/g-base": "^0.5.12", - "@antv/g-math": "^0.1.9", - "@antv/matrix-util": "^3.1.0-beta.1", - "@antv/path-util": "~2.0.5", - "@antv/util": "~2.0.0", - "gl-matrix": "^3.0.0", - "tslib": "^2.0.3" - } - }, - "@antv/g-math": { - "version": "0.1.9", - "resolved": "https://registry.npmmirror.com/@antv/g-math/-/g-math-0.1.9.tgz", - "integrity": "sha512-KHMSfPfZ5XHM1PZnG42Q2gxXfOitYveNTA7L61lR6mhZ8Y/aExsYmHqaKBsSarU0z+6WLrl9C07PQJZaw0uljQ==", - "requires": { - "@antv/util": "~2.0.0", - "gl-matrix": "^3.0.0" - } - }, - "@antv/g-svg": { - "version": "0.5.7", - "resolved": "https://registry.npmmirror.com/@antv/g-svg/-/g-svg-0.5.7.tgz", - "integrity": "sha512-jUbWoPgr4YNsOat2Y/rGAouNQYGpw4R0cvlN0YafwOyacFFYy2zC8RslNd6KkPhhR3XHNSqJOuCYZj/YmLUwYw==", - "requires": { - "@antv/g-base": "^0.5.12", - "@antv/g-math": "^0.1.9", - "@antv/util": "~2.0.0", - "detect-browser": "^5.0.0", - "tslib": "^2.0.3" - } - }, - "@antv/g-webgpu": { - "version": "0.7.2", - "resolved": "https://registry.npmmirror.com/@antv/g-webgpu/-/g-webgpu-0.7.2.tgz", - "integrity": "sha512-kw+oYGsdvj5qeUfy5DPb/jztZBV+2fmqBd3Vv8NlKatfBmv8AirYX/CCW74AUSdWm99rEiLyxFB1VdRZ6b/wnQ==", - "requires": { - "@antv/g-webgpu-core": "^0.7.2", - "@antv/g-webgpu-engine": "^0.7.2", - "gl-matrix": "^3.1.0", - "gl-vec2": "^1.3.0", - "lodash": "^4.17.15" - } - }, - "@antv/g-webgpu-core": { - "version": "0.7.2", - "resolved": "https://registry.npmmirror.com/@antv/g-webgpu-core/-/g-webgpu-core-0.7.2.tgz", - "integrity": "sha512-xUMmop7f3Rs34zFYKXLqHhDR1CQTeDl/7vI7Sn3X/73BqJc3X3HIIRvm83Fg2CjVACaOzw4WeLRXNaOCp9fz9w==", - "requires": { - "eventemitter3": "^4.0.0", - "gl-matrix": "^3.1.0", - "lodash": "^4.17.15", - "probe.gl": "^3.1.1" - } - }, - "@antv/g-webgpu-engine": { - "version": "0.7.2", - "resolved": "https://registry.npmmirror.com/@antv/g-webgpu-engine/-/g-webgpu-engine-0.7.2.tgz", - "integrity": "sha512-lx8Y93IW2cnJvdoDRKyMmTdYqSC1pOmF0nyG3PGGyA0NI9vBYVgO0KTF6hkyWjdTWVq7XDZyf/h8CJridLh3lg==", - "requires": { - "@antv/g-webgpu-core": "^0.7.2", - "gl-matrix": "^3.1.0", - "lodash": "^4.17.15", - "regl": "^1.3.11" - } - }, - "@antv/g6": { - "version": "4.8.8", - "resolved": "https://registry.npmmirror.com/@antv/g6/-/g6-4.8.8.tgz", - "integrity": "sha512-xJEOZX5YkUrHZ4b6zMAfKDEgJZ6DjNaanqMpKmzvbuQ2iUq2H3le4Y1OgrXCebusqYZC+GwZA4V26DCc3ei6zw==", - "requires": { - "@antv/g6-pc": "0.8.8" - } - }, - "@antv/g6-core": { - "version": "0.8.8", - "resolved": "https://registry.npmmirror.com/@antv/g6-core/-/g6-core-0.8.8.tgz", - "integrity": "sha512-cWFoxGIyscl0OZSCGmyILBFy6xd527LcVJMmpIKgJ0E3lT37b8NHDHRbar0GLq7sdyBj2cHVOWtCHjA99FyZ6g==", - "requires": { - "@antv/algorithm": "^0.1.8", - "@antv/dom-util": "^2.0.1", - "@antv/event-emitter": "~0.1.0", - "@antv/g-base": "^0.5.1", - "@antv/g-math": "^0.1.1", - "@antv/matrix-util": "^3.1.0-beta.3", - "@antv/path-util": "^2.0.3", - "@antv/util": "~2.0.5", - "ml-matrix": "^6.5.0", - "tslib": "^2.1.0" - } - }, - "@antv/g6-element": { - "version": "0.8.8", - "resolved": "https://registry.npmmirror.com/@antv/g6-element/-/g6-element-0.8.8.tgz", - "integrity": "sha512-0EOr2yJVXOqR4uFeY9K+m2bAuq3eNntnAWRa1GYUbtrjBh7N/wTn3l+Xl3RZC5Ch1dAFgxQMX4n1+PGvcCRcJA==", - "requires": { - "@antv/g-base": "^0.5.1", - "@antv/g6-core": "0.8.8", - "@antv/util": "~2.0.5" - } - }, - "@antv/g6-pc": { - "version": "0.8.8", - "resolved": "https://registry.npmmirror.com/@antv/g6-pc/-/g6-pc-0.8.8.tgz", - "integrity": "sha512-hemwe0cyjExdQiAOpzwmUchrp1/qVEHNHru9O9TqtnXlFM0VrRyPKCp3cL+Yv8N25JseOp1fboEmhMuPFeqN3Q==", - "requires": { - "@ant-design/colors": "^4.0.5", - "@antv/algorithm": "^0.1.8", - "@antv/dom-util": "^2.0.1", - "@antv/event-emitter": "~0.1.0", - "@antv/g-base": "^0.5.1", - "@antv/g-canvas": "^0.5.2", - "@antv/g-math": "^0.1.1", - "@antv/g-svg": "^0.5.1", - "@antv/g6-core": "0.8.8", - "@antv/g6-element": "0.8.8", - "@antv/g6-plugin": "^0.8.7", - "@antv/hierarchy": "^0.6.10", - "@antv/layout": "^0.3.0", - "@antv/matrix-util": "^3.1.0-beta.3", - "@antv/path-util": "^2.0.3", - "@antv/util": "~2.0.5", - "color": "^3.1.3", - "d3-force": "^2.0.1", - "dagre": "^0.8.5", - "insert-css": "^2.0.0", - "ml-matrix": "^6.5.0" - } - }, - "@antv/g6-plugin": { - "version": "0.8.8", - "resolved": "https://registry.npmmirror.com/@antv/g6-plugin/-/g6-plugin-0.8.8.tgz", - "integrity": "sha512-wc2oTAKUaCzpHzhDxYEdkTVeWa6D6tILWAcheW5r6EabEny9gg34yWTzf+wbRp8kbWWLRNNnRTkMV8mV5LSH5g==", - "requires": { - "@antv/dom-util": "^2.0.2", - "@antv/g-base": "^0.5.1", - "@antv/g-canvas": "^0.5.2", - "@antv/g-svg": "^0.5.2", - "@antv/g6-core": "0.8.8", - "@antv/g6-element": "0.8.8", - "@antv/matrix-util": "^3.1.0-beta.3", - "@antv/path-util": "^2.0.3", - "@antv/scale": "^0.3.4", - "@antv/util": "^2.0.9", - "insert-css": "^2.0.0" - } - }, - "@antv/graphlib": { - "version": "1.2.0", - "resolved": "https://registry.npmmirror.com/@antv/graphlib/-/graphlib-1.2.0.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2F%40antv%2Fgraphlib%2F-%2Fgraphlib-1.2.0.tgz", - "integrity": "sha1-yI+X1LNFbSYUgKEgf/xPvF19zw0=" - }, - "@antv/hierarchy": { - "version": "0.6.11", - "resolved": "https://registry.npmmirror.com/@antv/hierarchy/-/hierarchy-0.6.11.tgz", - "integrity": "sha512-RJVhEMCuu4vj+Dt25lXIiNdd7jaqm/fqWGYikiELha4S5tnzdJoTUaUvvpfWlxLx4B0RsS9XRwBs1bOKN71TKg==", - "requires": { - "@antv/util": "^2.0.7" - } - }, - "@antv/layout": { - "version": "0.3.17", - "resolved": "https://registry.npmmirror.com/@antv/layout/-/layout-0.3.17.tgz", - "integrity": "sha512-KYqnTkqQ1Dddv57yM39FVR//OHFituWJ6Fjhip4VqIYsD07RIvo4g6gMRRqVwEZufGJjgdYJKVn4xIEh/8Ezhw==", - "requires": { - "@antv/g-webgpu": "0.7.2", - "@antv/graphlib": "^1.0.0", - "d3-force": "^2.1.1", - "d3-quadtree": "^2.0.0", - "dagre-compound": "^0.0.11", - "ml-matrix": "^6.5.0" - } - }, - "@antv/matrix-util": { - "version": "3.1.0-beta.3", - "resolved": "https://registry.npmmirror.com/@antv/matrix-util/-/matrix-util-3.1.0-beta.3.tgz", - "integrity": "sha512-W2R6Za3A6CmG51Y/4jZUM/tFgYSq7vTqJL1VD9dKrvwxS4sE0ZcXINtkp55CdyBwJ6Cwm8pfoRpnD4FnHahN0A==", - "requires": { - "@antv/util": "^2.0.9", - "gl-matrix": "^3.4.3", - "tslib": "^2.0.3" - } - }, - "@antv/path-util": { - "version": "2.0.15", - "resolved": "https://registry.npmmirror.com/@antv/path-util/-/path-util-2.0.15.tgz", - "integrity": "sha512-R2VLZ5C8PLPtr3VciNyxtjKqJ0XlANzpFb5sE9GE61UQqSRuSVSzIakMxjEPrpqbgc+s+y8i+fmc89Snu7qbNw==", - "requires": { - "@antv/matrix-util": "^3.0.4", - "@antv/util": "^2.0.9", - "tslib": "^2.0.3" - }, - "dependencies": { - "@antv/matrix-util": { - "version": "3.0.4", - "resolved": "https://registry.npmmirror.com/@antv/matrix-util/-/matrix-util-3.0.4.tgz", - "integrity": "sha512-BAPyu6dUliHcQ7fm9hZSGKqkwcjEDVLVAstlHULLvcMZvANHeLXgHEgV7JqcAV/GIhIz8aZChIlzM1ZboiXpYQ==", - "requires": { - "@antv/util": "^2.0.9", - "gl-matrix": "^3.3.0", - "tslib": "^2.0.3" - } - } - } - }, - "@antv/scale": { - "version": "0.3.18", - "resolved": "https://registry.npmmirror.com/@antv/scale/-/scale-0.3.18.tgz", - "integrity": "sha512-GHwE6Lo7S/Q5fgaLPaCsW+CH+3zl4aXpnN1skOiEY0Ue9/u+s2EySv6aDXYkAqs//i0uilMDD/0/4n8caX9U9w==", - "requires": { - "@antv/util": "~2.0.3", - "fecha": "~4.2.0", - "tslib": "^2.0.0" - } - }, - "@antv/util": { - "version": "2.0.17", - "resolved": "https://registry.npmmirror.com/@antv/util/-/util-2.0.17.tgz", - "integrity": "sha512-o6I9hi5CIUvLGDhth0RxNSFDRwXeywmt6ExR4+RmVAzIi48ps6HUy+svxOCayvrPBN37uE6TAc2KDofRo0nK9Q==", - "requires": { - "csstype": "^3.0.8", - "tslib": "^2.0.3" - }, - "dependencies": { - "csstype": { - "version": "3.1.1", - "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" - } - } - }, - "@antv/x6": { - "version": "2.9.4", - "resolved": "https://registry.npmmirror.com/@antv/x6/-/x6-2.9.4.tgz", - "integrity": "sha512-Q9AuU6gGnTF8zFFGzpH2q6kvO5giPJpXQdgDp2mQGpu2DPm8howovtXCWRKCfDx8WJ8ccNbZ3RrzusN8kk6iYA==", - "requires": { - "@antv/x6-common": "^2.0.11", - "@antv/x6-geometry": "^2.0.4", - "utility-types": "^3.10.0" - } - }, - "@antv/x6-common": { - "version": "2.0.11", - "resolved": "https://registry.npmmirror.com/@antv/x6-common/-/x6-common-2.0.11.tgz", - "integrity": "sha512-tSs1fa+xAE1Ty0ecu3GtvQh482CbeuTaHJjuXXfKHjaUoAjI7I5qOe/h4BFF0SnjQSxqHj+HyBT4aXsgNmJ8lg==", - "requires": { - "lodash-es": "^4.17.15", - "utility-types": "^3.10.0" - } - }, - "@antv/x6-geometry": { - "version": "2.0.4", - "resolved": "https://registry.npmmirror.com/@antv/x6-geometry/-/x6-geometry-2.0.4.tgz", - "integrity": "sha512-dlsLNRRTiCw8TsJ/03j3y5IbbbK4Npf6zBH6kAx8nnW+edNT/TAOChvPRzizwD+vA7wY9Rp2AiRnp/vCdIYC5w==" - }, - "@babel/parser": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.9.tgz", - "integrity": "sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg==" - }, - "@babel/runtime": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz", - "integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==", - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, - "@codemirror/autocomplete": { - "version": "6.4.2", - "resolved": "https://registry.npmmirror.com/@codemirror/autocomplete/-/autocomplete-6.4.2.tgz", - "integrity": "sha512-8WE2xp+D0MpWEv5lZ6zPW1/tf4AGb358T5GWYiKEuCP8MvFfT3tH2mIF9Y2yr2e3KbHuSvsVhosiEyqCpiJhZQ==", - "requires": { - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.6.0", - "@lezer/common": "^1.0.0" - } - }, - "@codemirror/commands": { - "version": "6.2.1", - "resolved": "https://registry.npmmirror.com/@codemirror/commands/-/commands-6.2.1.tgz", - "integrity": "sha512-FFiNKGuHA5O8uC6IJE5apI5rT9gyjlw4whqy4vlcX0wE/myxL6P1s0upwDhY4HtMWLOwzwsp0ap3bjdQhvfDOA==", - "requires": { - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.2.0", - "@codemirror/view": "^6.0.0", - "@lezer/common": "^1.0.0" - } - }, - "@codemirror/lang-javascript": { - "version": "6.1.4", - "resolved": "https://registry.npmmirror.com/@codemirror/lang-javascript/-/lang-javascript-6.1.4.tgz", - "integrity": "sha512-OxLf7OfOZBTMRMi6BO/F72MNGmgOd9B0vetOLvHsDACFXayBzW8fm8aWnDM0yuy68wTK03MBf4HbjSBNRG5q7A==", - "requires": { - "@codemirror/autocomplete": "^6.0.0", - "@codemirror/language": "^6.6.0", - "@codemirror/lint": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0", - "@lezer/common": "^1.0.0", - "@lezer/javascript": "^1.0.0" - } - }, - "@codemirror/language": { - "version": "6.6.0", - "resolved": "https://registry.npmmirror.com/@codemirror/language/-/language-6.6.0.tgz", - "integrity": "sha512-cwUd6lzt3MfNYOobdjf14ZkLbJcnv4WtndYaoBkbor/vF+rCNguMPK0IRtvZJG4dsWiaWPcK8x1VijhvSxnstg==", - "requires": { - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0", - "@lezer/common": "^1.0.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.0.0", - "style-mod": "^4.0.0" - } - }, - "@codemirror/lint": { - "version": "6.2.0", - "resolved": "https://registry.npmmirror.com/@codemirror/lint/-/lint-6.2.0.tgz", - "integrity": "sha512-KVCECmR2fFeYBr1ZXDVue7x3q5PMI0PzcIbA+zKufnkniMBo1325t0h1jM85AKp8l3tj67LRxVpZfgDxEXlQkg==", - "requires": { - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0", - "crelt": "^1.0.5" - } - }, - "@codemirror/search": { - "version": "6.3.0", - "resolved": "https://registry.npmmirror.com/@codemirror/search/-/search-6.3.0.tgz", - "integrity": "sha512-rBhZxzT34CarfhgCZGhaLBScABDN3iqJxixzNuINp9lrb3lzm0nTpR77G1VrxGO3HOGK7j62jcJftQM7eCOIuw==", - "requires": { - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0", - "crelt": "^1.0.5" - } - }, - "@codemirror/state": { - "version": "6.2.0", - "resolved": "https://registry.npmmirror.com/@codemirror/state/-/state-6.2.0.tgz", - "integrity": "sha512-69QXtcrsc3RYtOtd+GsvczJ319udtBf1PTrr2KbLWM/e2CXUPnh0Nz9AUo8WfhSQ7GeL8dPVNUmhQVgpmuaNGA==" - }, - "@codemirror/theme-one-dark": { - "version": "6.1.1", - "resolved": "https://registry.npmmirror.com/@codemirror/theme-one-dark/-/theme-one-dark-6.1.1.tgz", - "integrity": "sha512-+CfzmScfJuD6uDF5bHJkAjWTQ2QAAHxODCPxUEgcImDYcJLT+4l5vLnBHmDVv46kCC5uUJGMrBJct2Z6JbvqyQ==", - "requires": { - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0", - "@lezer/highlight": "^1.0.0" - } - }, - "@codemirror/view": { - "version": "6.9.1", - "resolved": "https://registry.npmmirror.com/@codemirror/view/-/view-6.9.1.tgz", - "integrity": "sha512-bzfSjJn9dAADVpabLKWKNmMG4ibyTV2e3eOGowjElNPTdTkSbi6ixPYHm2u0ADcETfKsi2/R84Rkmi91dH9yEg==", - "requires": { - "@codemirror/state": "^6.1.4", - "style-mod": "^4.0.0", - "w3c-keyname": "^2.2.4" - } - }, - "@css-render/plugin-bem": { - "version": "0.15.12", - "resolved": "https://registry.npmmirror.com/@css-render/plugin-bem/-/plugin-bem-0.15.12.tgz", - "integrity": "sha512-Lq2jSOZn+wYQtsyaFj6QRz2EzAnd3iW5fZeHO1WSXQdVYwvwGX0ZiH3X2JQgtgYLT1yeGtrwrqJdNdMEUD2xTw==" - }, - "@css-render/vue3-ssr": { - "version": "0.15.12", - "resolved": "https://registry.npmmirror.com/@css-render/vue3-ssr/-/vue3-ssr-0.15.12.tgz", - "integrity": "sha512-AQLGhhaE0F+rwybRCkKUdzBdTEM/5PZBYy+fSYe1T9z9+yxMuV/k7ZRqa4M69X+EI1W8pa4kc9Iq2VjQkZx4rg==" - }, - "@ctrl/tinycolor": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.4.1.tgz", - "integrity": "sha512-ej5oVy6lykXsvieQtqZxCOaLT+xD4+QNarq78cIYISHmZXshCvROLudpQN3lfL8G0NL7plMSSK+zlyvCaIJ4Iw==" - }, - "@element-plus/icons-vue": { - "version": "2.0.9", - "resolved": "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.0.9.tgz", - "integrity": "sha512-okdrwiVeKBmW41Hkl0eMrXDjzJwhQMuKiBOu17rOszqM+LS/yBYpNQNV5Jvoh06Wc+89fMmb/uhzf8NZuDuUaQ==" - }, - "@emotion/hash": { - "version": "0.8.0", - "resolved": "https://registry.npmmirror.com/@emotion/hash/-/hash-0.8.0.tgz", - "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" - }, - "@eslint/eslintrc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", - "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.3.2", - "globals": "^13.15.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - } - }, - "@floating-ui/core": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-0.7.3.tgz", - "integrity": "sha512-buc8BXHmG9l82+OQXOFU3Kr2XQx9ys01U/Q9HMIrZ300iLc8HLMgh7dcCqgYzAzf4BkoQvDcXf5Y+CuEZ5JBYg==" - }, - "@floating-ui/dom": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-0.5.4.tgz", - "integrity": "sha512-419BMceRLq0RrmTSDxn8hf9R3VCJv2K9PUfugh5JyEFmdjzDo+e8U5EdR8nzKq8Yj1htzLm3b6eQEEam3/rrtg==", - "requires": { - "@floating-ui/core": "^0.7.3" - } - }, - "@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - } - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "@interactjs/actions": { - "version": "1.10.17", - "resolved": "https://registry.npmjs.org/@interactjs/actions/-/actions-1.10.17.tgz", - "integrity": "sha512-wyB1ZqpaZy5gmz6VDqK9KWh98xKnFgL7VyLvxHODFi9V0IYX4HJAAOBlhtfze0D1R1f1cY+gqPDK+dLaHMlE+w==", - "requires": { - "@interactjs/interact": "1.10.17" - } - }, - "@interactjs/auto-scroll": { - "version": "1.10.17", - "resolved": "https://registry.npmjs.org/@interactjs/auto-scroll/-/auto-scroll-1.10.17.tgz", - "integrity": "sha512-IQcW7N3xOaoL8RnAGOGMk0Y2gue7L4S3BT6Id4VBBu8so163DtLiZVW6jXu9rKVntzbluaAeqNZlfAVyu3kIWg==", - "requires": { - "@interactjs/interact": "1.10.17" - } - }, - "@interactjs/auto-start": { - "version": "1.10.17", - "resolved": "https://registry.npmjs.org/@interactjs/auto-start/-/auto-start-1.10.17.tgz", - "integrity": "sha512-qYVxhAbYnwxjD/NLEegUoAST7WASJ4VmWNjsyWRx/js5Op+I4E2zteARIeZGgrutcGIXMCcQzhCMgE3PjOpbpw==", - "requires": { - "@interactjs/interact": "1.10.17" - } - }, - "@interactjs/core": { - "version": "1.10.17", - "resolved": "https://registry.npmjs.org/@interactjs/core/-/core-1.10.17.tgz", - "integrity": "sha512-rL9w+83HDRuXub8Ezqs+97CYLl/ne7bLT/sAeduUWaxYhsW9iOqBoob9JnkkCZOaOsYizWI1EWy0+fNc5ibtLQ==" - }, - "@interactjs/dev-tools": { - "version": "1.10.17", - "resolved": "https://registry.npmjs.org/@interactjs/dev-tools/-/dev-tools-1.10.17.tgz", - "integrity": "sha512-Oi9nEw3FfSwkNmW+V0WwdHqvzEkVHc24mH1v5EjRn60sqgrGLK9nTQ+NSuqcnUY8GxC3TkyuxnsOodxiadIRmA==", - "requires": { - "@interactjs/interact": "1.10.17" - } - }, - "@interactjs/inertia": { - "version": "1.10.17", - "resolved": "https://registry.npmjs.org/@interactjs/inertia/-/inertia-1.10.17.tgz", - "integrity": "sha512-41vbYUjZIDCKt2/yhmjPrEW5+0uoL/hldFsll9pkvnLhmm12Xk0VXOlmR2zXKAmsTK3fJlKMyBYUX92qHLkyVQ==", - "requires": { - "@interactjs/interact": "1.10.17", - "@interactjs/offset": "1.10.17" - } - }, - "@interactjs/interact": { - "version": "1.10.17", - "resolved": "https://registry.npmjs.org/@interactjs/interact/-/interact-1.10.17.tgz", - "integrity": "sha512-NyKsf8EFudvdahBjPz1Gt5QnynVwa/2LUfBc2/w8QOnOBiyzUm0HLloJSaB8a50QbQkSWN243/Lgpd8GTMQvuQ==", - "requires": { - "@interactjs/core": "1.10.17", - "@interactjs/types": "1.10.17", - "@interactjs/utils": "1.10.17" - } - }, - "@interactjs/interactjs": { - "version": "1.10.17", - "resolved": "https://registry.npmjs.org/@interactjs/interactjs/-/interactjs-1.10.17.tgz", - "integrity": "sha512-hHmiukARbZhiM12zNKx0yQlFVl4C+NMeYNAYh6Mf9U3ZziQ47C+JEW8Gr7Zr/MxfNZyPu5nLKCpVQjh/JvBO9g==", - "requires": { - "@interactjs/actions": "1.10.17", - "@interactjs/auto-scroll": "1.10.17", - "@interactjs/auto-start": "1.10.17", - "@interactjs/core": "1.10.17", - "@interactjs/dev-tools": "1.10.17", - "@interactjs/inertia": "1.10.17", - "@interactjs/interact": "1.10.17", - "@interactjs/modifiers": "1.10.17", - "@interactjs/offset": "1.10.17", - "@interactjs/pointer-events": "1.10.17", - "@interactjs/reflow": "1.10.17", - "@interactjs/utils": "1.10.17" - } - }, - "@interactjs/modifiers": { - "version": "1.10.17", - "resolved": "https://registry.npmjs.org/@interactjs/modifiers/-/modifiers-1.10.17.tgz", - "integrity": "sha512-Dxw8kv9VBIxnhNvQncR6CKAGMzKXczLvuAUIdSPFYtyerX/XiDulJUqhR+jVKNp/WjF1DvdBxWo0kGGLbM84LQ==", - "requires": { - "@interactjs/interact": "1.10.17", - "@interactjs/snappers": "1.10.17" - } - }, - "@interactjs/offset": { - "version": "1.10.17", - "resolved": "https://registry.npmjs.org/@interactjs/offset/-/offset-1.10.17.tgz", - "integrity": "sha512-wWBnIQWgLrmJNTBbd/FdxHxAJjiXl/5ND8Jbw2DuP9gIGDxhFSdEt62Fgqimn9ICb8v8ycvSLObEmcvJF/8hQQ==", - "requires": { - "@interactjs/interact": "1.10.17" - } - }, - "@interactjs/pointer-events": { - "version": "1.10.17", - "resolved": "https://registry.npmjs.org/@interactjs/pointer-events/-/pointer-events-1.10.17.tgz", - "integrity": "sha512-VsfluouEKb8QRGyH6jQATCW+QdAd/3dkENS7rj2m+EcVUhz2Ob5mpMRopjALi4pwltMowqTfuJ4LtwMSX2G29A==", - "requires": { - "@interactjs/interact": "1.10.17" - } - }, - "@interactjs/reflow": { - "version": "1.10.17", - "resolved": "https://registry.npmjs.org/@interactjs/reflow/-/reflow-1.10.17.tgz", - "integrity": "sha512-ncpWP5k93FRQptEhjzPZsbuRRajd4rkW17lDavCrEjrDi/LHnYekWGqZTaFzfJ80n1x8xUm9ujDjxCTylNqEIA==", - "requires": { - "@interactjs/interact": "1.10.17" - } - }, - "@interactjs/snappers": { - "version": "1.10.17", - "resolved": "https://registry.npmjs.org/@interactjs/snappers/-/snappers-1.10.17.tgz", - "integrity": "sha512-m753DGsNOts797e3zDT6wqELoc+BlpIC1w+TyMyISRxU6n1RlS8Q6LHBGgwAgV79LHLaahv/a5haFF9H1VG0FQ==", - "requires": { - "@interactjs/interact": "1.10.17" - } - }, - "@interactjs/types": { - "version": "1.10.17", - "resolved": "https://registry.npmjs.org/@interactjs/types/-/types-1.10.17.tgz", - "integrity": "sha512-X2JpoM7xUw0p9Me0tMaI0HNfcF/Hd07ZZlzpnpEMpGerUZOLoyeThrV9P+CrBHxZrluWJrigJbcdqXliFd0YMA==" - }, - "@interactjs/utils": { - "version": "1.10.17", - "resolved": "https://registry.npmjs.org/@interactjs/utils/-/utils-1.10.17.tgz", - "integrity": "sha512-sZAW08CkqgvqRjUIaLRjScjObcCzN9D75yekLA21EClYAZIhi4A+GEt2z/WqOCOksTaEPLYmQyhkpXcboc0LhQ==" - }, - "@intlify/core-base": { - "version": "9.1.10", - "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.1.10.tgz", - "integrity": "sha512-So9CNUavB/IsZ+zBmk2Cv6McQp6vc2wbGi1S0XQmJ8Vz+UFcNn9MFXAe9gY67PreIHrbLsLxDD0cwo1qsxM1Nw==", - "requires": { - "@intlify/devtools-if": "9.1.10", - "@intlify/message-compiler": "9.1.10", - "@intlify/message-resolver": "9.1.10", - "@intlify/runtime": "9.1.10", - "@intlify/shared": "9.1.10", - "@intlify/vue-devtools": "9.1.10" - } - }, - "@intlify/devtools-if": { - "version": "9.1.10", - "resolved": "https://registry.npmjs.org/@intlify/devtools-if/-/devtools-if-9.1.10.tgz", - "integrity": "sha512-SHaKoYu6sog3+Q8js1y3oXLywuogbH1sKuc7NSYkN3GElvXSBaMoCzW+we0ZSFqj/6c7vTNLg9nQ6rxhKqYwnQ==", - "requires": { - "@intlify/shared": "9.1.10" - } - }, - "@intlify/message-compiler": { - "version": "9.1.10", - "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.1.10.tgz", - "integrity": "sha512-+JiJpXff/XTb0EadYwdxOyRTB0hXNd4n1HaJ/a4yuV960uRmPXaklJsedW0LNdcptd/hYUZtCkI7Lc9J5C1gxg==", - "requires": { - "@intlify/message-resolver": "9.1.10", - "@intlify/shared": "9.1.10", - "source-map": "0.6.1" - } - }, - "@intlify/message-resolver": { - "version": "9.1.10", - "resolved": "https://registry.npmjs.org/@intlify/message-resolver/-/message-resolver-9.1.10.tgz", - "integrity": "sha512-5YixMG/M05m0cn9+gOzd4EZQTFRUu8RGhzxJbR1DWN21x/Z3bJ8QpDYj6hC4FwBj5uKsRfKpJQ3Xqg98KWoA+w==" - }, - "@intlify/runtime": { - "version": "9.1.10", - "resolved": "https://registry.npmjs.org/@intlify/runtime/-/runtime-9.1.10.tgz", - "integrity": "sha512-7QsuByNzpe3Gfmhwq6hzgXcMPpxz8Zxb/XFI6s9lQdPLPe5Lgw4U1ovRPZTOs6Y2hwitR3j/HD8BJNGWpJnOFA==", - "requires": { - "@intlify/message-compiler": "9.1.10", - "@intlify/message-resolver": "9.1.10", - "@intlify/shared": "9.1.10" - } - }, - "@intlify/shared": { - "version": "9.1.10", - "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.1.10.tgz", - "integrity": "sha512-Om54xJeo1Vw+K1+wHYyXngE8cAbrxZHpWjYzMR9wCkqbhGtRV5VLhVc214Ze2YatPrWlS2WSMOWXR8JktX/IgA==" - }, - "@intlify/vue-devtools": { - "version": "9.1.10", - "resolved": "https://registry.npmjs.org/@intlify/vue-devtools/-/vue-devtools-9.1.10.tgz", - "integrity": "sha512-5l3qYARVbkWAkagLu1XbDUWRJSL8br1Dj60wgMaKB0+HswVsrR6LloYZTg7ozyvM621V6+zsmwzbQxbVQyrytQ==", - "requires": { - "@intlify/message-resolver": "9.1.10", - "@intlify/runtime": "9.1.10", - "@intlify/shared": "9.1.10" - } - }, - "@juggle/resize-observer": { - "version": "3.4.0", - "resolved": "https://registry.npmmirror.com/@juggle/resize-observer/-/resize-observer-3.4.0.tgz", - "integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==" - }, - "@lezer/common": { - "version": "1.0.2", - "resolved": "https://registry.npmmirror.com/@lezer/common/-/common-1.0.2.tgz", - "integrity": "sha512-SVgiGtMnMnW3ActR8SXgsDhw7a0w0ChHSYAyAUxxrOiJ1OqYWEKk/xJd84tTSPo1mo6DXLObAJALNnd0Hrv7Ng==" - }, - "@lezer/highlight": { - "version": "1.1.3", - "resolved": "https://registry.npmmirror.com/@lezer/highlight/-/highlight-1.1.3.tgz", - "integrity": "sha512-3vLKLPThO4td43lYRBygmMY18JN3CPh9w+XS2j8WC30vR4yZeFG4z1iFe4jXE43NtGqe//zHW5q8ENLlHvz9gw==", - "requires": { - "@lezer/common": "^1.0.0" - } - }, - "@lezer/javascript": { - "version": "1.4.1", - "resolved": "https://registry.npmmirror.com/@lezer/javascript/-/javascript-1.4.1.tgz", - "integrity": "sha512-Hqx36DJeYhKtdpc7wBYPR0XF56ZzIp0IkMO/zNNj80xcaFOV4Oj/P7TQc/8k2TxNhzl7tV5tXS8ZOCPbT4L3nA==", - "requires": { - "@lezer/highlight": "^1.1.3", - "@lezer/lr": "^1.3.0" - } - }, - "@lezer/lr": { - "version": "1.3.3", - "resolved": "https://registry.npmmirror.com/@lezer/lr/-/lr-1.3.3.tgz", - "integrity": "sha512-JPQe3mwJlzEVqy67iQiiGozhcngbO8QBgpqZM6oL1Wj/dXckrEexpBLeFkq0edtW5IqnPRFxA24BHJni8Js69w==", - "requires": { - "@lezer/common": "^1.0.0" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@probe.gl/env": { - "version": "3.6.0", - "resolved": "https://registry.npmmirror.com/@probe.gl/env/-/env-3.6.0.tgz", - "integrity": "sha512-4tTZYUg/8BICC3Yyb9rOeoKeijKbZHRXBEKObrfPmX4sQmYB15ZOUpoVBhAyJkOYVAM8EkPci6Uw5dLCwx2BEQ==", - "requires": { - "@babel/runtime": "^7.0.0" - } - }, - "@probe.gl/log": { - "version": "3.6.0", - "resolved": "https://registry.npmmirror.com/@probe.gl/log/-/log-3.6.0.tgz", - "integrity": "sha512-hjpyenpEvOdowgZ1qMeCJxfRD4JkKdlXz0RC14m42Un62NtOT+GpWyKA4LssT0+xyLULCByRAtG2fzZorpIAcA==", - "requires": { - "@babel/runtime": "^7.0.0", - "@probe.gl/env": "3.6.0" - } - }, - "@probe.gl/stats": { - "version": "3.6.0", - "resolved": "https://registry.npmmirror.com/@probe.gl/stats/-/stats-3.6.0.tgz", - "integrity": "sha512-JdALQXB44OP4kUBN/UrQgzbJe4qokbVF4Y8lkIA8iVCFnjVowWIgkD/z/0QO65yELT54tTrtepw1jScjKB+rhQ==", - "requires": { - "@babel/runtime": "^7.0.0" - } - }, - "@swc/core": { - "version": "1.2.246", - "resolved": "https://registry.npmmirror.com/@swc/core/-/core-1.2.246.tgz", - "integrity": "sha512-wi0IZLv5GC2zjZoiEDoLZraS7/ZV2Y6vnAII//Ulobvdc4zuQoceJvYvyO3IJMB0bZVoiY/fn0Ae/iEMx9PFBQ==", - "dev": true, - "requires": { - "@swc/core-android-arm-eabi": "1.2.246", - "@swc/core-android-arm64": "1.2.246", - "@swc/core-darwin-arm64": "1.2.246", - "@swc/core-darwin-x64": "1.2.246", - "@swc/core-freebsd-x64": "1.2.246", - "@swc/core-linux-arm-gnueabihf": "1.2.246", - "@swc/core-linux-arm64-gnu": "1.2.246", - "@swc/core-linux-arm64-musl": "1.2.246", - "@swc/core-linux-x64-gnu": "1.2.246", - "@swc/core-linux-x64-musl": "1.2.246", - "@swc/core-win32-arm64-msvc": "1.2.246", - "@swc/core-win32-ia32-msvc": "1.2.246", - "@swc/core-win32-x64-msvc": "1.2.246" - } - }, - "@swc/core-android-arm-eabi": { - "version": "1.2.246", - "resolved": "https://registry.npmmirror.com/@swc/core-android-arm-eabi/-/core-android-arm-eabi-1.2.246.tgz", - "integrity": "sha512-3LXgOhtZnDsBacv71WRhuiuzjD0Q7m3XLzGyndtNZ+os4SOlmFiOTjZ3iMhnafKWZslmgAFrMemLPDOH+Np8OQ==", - "dev": true, - "optional": true, - "requires": { - "@swc/wasm": "1.2.122" - } - }, - "@swc/core-android-arm64": { - "version": "1.2.246", - "resolved": "https://registry.npmmirror.com/@swc/core-android-arm64/-/core-android-arm64-1.2.246.tgz", - "integrity": "sha512-m/BCkI7Wo4nMN6PLM1EnO43p7aoi9sxY3KESVCyAEZ07QlY++a0GEgVqCkKHWZ8zcfbLsesDA2E9/DYMOgPzxg==", - "dev": true, - "optional": true, - "requires": { - "@swc/wasm": "1.2.130" - }, - "dependencies": { - "@swc/wasm": { - "version": "1.2.130", - "resolved": "https://registry.npmmirror.com/@swc/wasm/-/wasm-1.2.130.tgz", - "integrity": "sha512-rNcJsBxS70+pv8YUWwf5fRlWX6JoY/HJc25HD/F8m6Kv7XhJdqPPMhyX6TKkUBPAG7TWlZYoxa+rHAjPy4Cj3Q==", - "dev": true, - "optional": true - } - } - }, - "@swc/core-darwin-arm64": { - "version": "1.2.246", - "resolved": "https://registry.npmmirror.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.2.246.tgz", - "integrity": "sha512-w3RbXiGPE1LshUS5T3McBJAxl9gCFZanaY5ALuUNERAIdjVxjGmB815O0hPDmjlJrhvwhKI9+Rx4X/M1vlZDtA==", - "dev": true, - "optional": true - }, - "@swc/core-darwin-x64": { - "version": "1.2.246", - "resolved": "https://registry.npmmirror.com/@swc/core-darwin-x64/-/core-darwin-x64-1.2.246.tgz", - "integrity": "sha512-2odv/ZlV9VsQuQDIul1jU2+u5vPCw6Xyg0BaejaA5FCcnXi6w2xf6/ryFFgQy4i+LP3oZdOtJG1dZiA8ozplKw==", - "dev": true, - "optional": true - }, - "@swc/core-freebsd-x64": { - "version": "1.2.246", - "resolved": "https://registry.npmmirror.com/@swc/core-freebsd-x64/-/core-freebsd-x64-1.2.246.tgz", - "integrity": "sha512-GvQuHKTc8TyJ3jn1e4HZasgGfBvD3nGe55syzAAaedh8tuU7VnQjxl1Dtq5DtyCBDDbulzuHcwLFQnWNWgEMyA==", - "dev": true, - "optional": true, - "requires": { - "@swc/wasm": "1.2.130" - }, - "dependencies": { - "@swc/wasm": { - "version": "1.2.130", - "resolved": "https://registry.npmmirror.com/@swc/wasm/-/wasm-1.2.130.tgz", - "integrity": "sha512-rNcJsBxS70+pv8YUWwf5fRlWX6JoY/HJc25HD/F8m6Kv7XhJdqPPMhyX6TKkUBPAG7TWlZYoxa+rHAjPy4Cj3Q==", - "dev": true, - "optional": true - } - } - }, - "@swc/core-linux-arm-gnueabihf": { - "version": "1.2.246", - "resolved": "https://registry.npmmirror.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.2.246.tgz", - "integrity": "sha512-J1g/q9S9I0uLn/erHoIEpYvzr48oTiVY2cmniw/q0jRfg+ECTI24AjWQj5sdIoB+GLqEn5+GNhUbYIVoCTubRA==", - "dev": true, - "optional": true, - "requires": { - "@swc/wasm": "1.2.130" - }, - "dependencies": { - "@swc/wasm": { - "version": "1.2.130", - "resolved": "https://registry.npmmirror.com/@swc/wasm/-/wasm-1.2.130.tgz", - "integrity": "sha512-rNcJsBxS70+pv8YUWwf5fRlWX6JoY/HJc25HD/F8m6Kv7XhJdqPPMhyX6TKkUBPAG7TWlZYoxa+rHAjPy4Cj3Q==", - "dev": true, - "optional": true - } - } - }, - "@swc/core-linux-arm64-gnu": { - "version": "1.2.246", - "resolved": "https://registry.npmmirror.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.2.246.tgz", - "integrity": "sha512-J7B6XgOiNgCyZp5WXkC0wi2ov3SpS5z3o6++n0qz8d1UqswDaOjnpGQgPITXFkKFFrs/uWdPiNbbBsMum6C5gQ==", - "dev": true, - "optional": true - }, - "@swc/core-linux-arm64-musl": { - "version": "1.2.246", - "resolved": "https://registry.npmmirror.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.2.246.tgz", - "integrity": "sha512-AFv/95BgZkdrLa5YfvP/69v8qT+zq0pRVZxv/IUW1mmM1UGVKrcU0i0y/haYivIFcLX+Ox5IYmIibO9C9P9pOA==", - "dev": true, - "optional": true - }, - "@swc/core-linux-x64-gnu": { - "version": "1.2.246", - "resolved": "https://registry.npmmirror.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.2.246.tgz", - "integrity": "sha512-egM6QX7PaLB2cQXJidfQvwT9OzUkTl1XIUVz+IOpv4om0xxtyJQjy/2ENjjtiw7C9IuV1xASOLlE1tMfLY7osw==", - "dev": true, - "optional": true - }, - "@swc/core-linux-x64-musl": { - "version": "1.2.246", - "resolved": "https://registry.npmmirror.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.2.246.tgz", - "integrity": "sha512-SKJRqgcbiZ4h2O0p+JA/NsmmV1ZwHTxdMRKkiNSvkyybGyOwPgP01CVITggVohz0j9NGwgIVAJOcn4Hx5WCcuw==", - "dev": true, - "optional": true - }, - "@swc/core-win32-arm64-msvc": { - "version": "1.2.246", - "resolved": "https://registry.npmmirror.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.2.246.tgz", - "integrity": "sha512-VISXunc1sU0jm5dC37TLXYTdmIcz4b9ItfrGpc+hIZWDwGbagSwHiThnJL3OlpZQrcrbZ0w+/zg4EYb5JenbXg==", - "dev": true, - "optional": true, - "requires": { - "@swc/wasm": "1.2.130" - }, - "dependencies": { - "@swc/wasm": { - "version": "1.2.130", - "resolved": "https://registry.npmmirror.com/@swc/wasm/-/wasm-1.2.130.tgz", - "integrity": "sha512-rNcJsBxS70+pv8YUWwf5fRlWX6JoY/HJc25HD/F8m6Kv7XhJdqPPMhyX6TKkUBPAG7TWlZYoxa+rHAjPy4Cj3Q==", - "dev": true, - "optional": true - } - } - }, - "@swc/core-win32-ia32-msvc": { - "version": "1.2.246", - "resolved": "https://registry.npmmirror.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.2.246.tgz", - "integrity": "sha512-4tp3BrFur90PB2EM5vvfsw2zyBDFhC1PRAYGXJf9oF0Fnf4kQt+cBYXGy13I/kJfhd/cKQJC8o9lBV+dtLtGDg==", - "dev": true, - "optional": true, - "requires": { - "@swc/wasm": "1.2.130" - }, - "dependencies": { - "@swc/wasm": { - "version": "1.2.130", - "resolved": "https://registry.npmmirror.com/@swc/wasm/-/wasm-1.2.130.tgz", - "integrity": "sha512-rNcJsBxS70+pv8YUWwf5fRlWX6JoY/HJc25HD/F8m6Kv7XhJdqPPMhyX6TKkUBPAG7TWlZYoxa+rHAjPy4Cj3Q==", - "dev": true, - "optional": true - } - } - }, - "@swc/core-win32-x64-msvc": { - "version": "1.2.246", - "resolved": "https://registry.npmmirror.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.2.246.tgz", - "integrity": "sha512-wD22xEFdiYtpq7Nwq1k8Dqwe08zrgaEhO9rn7G9DUtjHPSeIOpNQ1dQrzGBVK5Ah/3WJuciCAyUbVtaDUROhEQ==", - "dev": true, - "optional": true - }, - "@swc/wasm": { - "version": "1.2.122", - "resolved": "https://registry.npmmirror.com/@swc/wasm/-/wasm-1.2.122.tgz", - "integrity": "sha512-sM1VCWQxmNhFtdxME+8UXNyPNhxNu7zdb6ikWpz0YKAQQFRGT5ThZgJrubEpah335SUToNg8pkdDF7ibVCjxbQ==", - "dev": true, - "optional": true - }, - "@transloadit/prettier-bytes": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/@transloadit/prettier-bytes/-/prettier-bytes-0.0.7.tgz", - "integrity": "sha512-VeJbUb0wEKbcwaSlj5n+LscBl9IPgLPkHVGBkh00cztv6X4L/TJXK58LzFuBKX7/GAfiGhIwH67YTLTlzvIzBA==" - }, - "@types/d3-timer": { - "version": "2.0.1", - "resolved": "https://registry.npmmirror.com/@types/d3-timer/-/d3-timer-2.0.1.tgz", - "integrity": "sha512-TF8aoF5cHcLO7W7403blM7L1T+6NF3XMyN3fxyUolq2uOcFeicG/khQg/dGxiCJWoAcmYulYN7LYSRKO54IXaA==" - }, - "@types/event-emitter": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@types/event-emitter/-/event-emitter-0.3.3.tgz", - "integrity": "sha512-UfnOK1pIxO7P+EgPRZXD9jMpimd8QEFcEZ5R67R1UhGbv4zghU5+NE7U8M8G9H5Jc8FI51rqDWQs6FtUfq2e/Q==" - }, - "@types/insert-css": { - "version": "2.0.1", - "resolved": "https://registry.npmmirror.com/@types/insert-css/-/insert-css-2.0.1.tgz", - "integrity": "sha512-slUriXg8Y0JvpQoZlQ96bzzi86AU0DvtstKmGtBWpzJilFnpMUDbREi28Gpa+ZaIrTTCQUfvpDS7z7F1uwlYjQ==", - "dev": true - }, - "@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true - }, - "@types/katex": { - "version": "0.14.0", - "resolved": "https://registry.npmmirror.com/@types/katex/-/katex-0.14.0.tgz", - "integrity": "sha512-+2FW2CcT0K3P+JMR8YG846bmDwplKUTsWgT2ENwdQ1UdVfRk3GQrh6Mi4sTopy30gI8Uau5CEqHTDZ6YvWIUPA==" - }, - "@types/lodash": { - "version": "4.14.182", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz", - "integrity": "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==" - }, - "@types/lodash-es": { - "version": "4.17.6", - "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.6.tgz", - "integrity": "sha512-R+zTeVUKDdfoRxpAryaQNRKk3105Rrgx2CFRClIgRGaqDTdjsm8h6IYA8ir584W3ePzkZfst5xIgDwYrlh9HLg==", - "requires": { - "@types/lodash": "*" - } - }, - "@types/node": { - "version": "18.0.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.6.tgz", - "integrity": "sha512-/xUq6H2aQm261exT6iZTMifUySEt4GR5KX8eYyY+C4MSNPqSh9oNIP7tz2GLKTlFaiBbgZNxffoR3CVRG+cljw==", - "dev": true - }, - "@types/nprogress": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@types/nprogress/-/nprogress-0.2.0.tgz", - "integrity": "sha512-1cYJrqq9GezNFPsWTZpFut/d4CjpZqA0vhqDUPFWYKF1oIyBz5qnoYMzR+0C/T96t3ebLAC1SSnwrVOm5/j74A==", - "dev": true - }, - "@types/sortablejs": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@types/sortablejs/-/sortablejs-1.13.0.tgz", - "integrity": "sha512-C3064MH72iEfeGCYEGCt7FCxXoAXaMPG0QPnstcxvPmbl54erpISu06d++FY37Smja64iWy5L8wOyHHBghWbJQ==", - "dev": true - }, - "@types/web-bluetooth": { - "version": "0.0.14", - "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.14.tgz", - "integrity": "sha512-5d2RhCard1nQUC3aHcq/gHzWYO6K0WJmAbjO7mQJgCQKtZpgXxv1rOM6O/dBDhDYYVutk1sciOgNSe+5YyfM8A==" - }, - "@typescript-eslint/eslint-plugin": { - "version": "5.30.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.30.7.tgz", - "integrity": "sha512-l4L6Do+tfeM2OK0GJsU7TUcM/1oN/N25xHm3Jb4z3OiDU4Lj8dIuxX9LpVMS9riSXQs42D1ieX7b85/r16H9Fw==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "5.30.7", - "@typescript-eslint/type-utils": "5.30.7", - "@typescript-eslint/utils": "5.30.7", - "debug": "^4.3.4", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.2.0", - "regexpp": "^3.2.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/parser": { - "version": "5.30.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.30.7.tgz", - "integrity": "sha512-Rg5xwznHWWSy7v2o0cdho6n+xLhK2gntImp0rJroVVFkcYFYQ8C8UJTSuTw/3CnExBmPjycjmUJkxVmjXsld6A==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "5.30.7", - "@typescript-eslint/types": "5.30.7", - "@typescript-eslint/typescript-estree": "5.30.7", - "debug": "^4.3.4" - } - }, - "@typescript-eslint/scope-manager": { - "version": "5.30.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.30.7.tgz", - "integrity": "sha512-7BM1bwvdF1UUvt+b9smhqdc/eniOnCKxQT/kj3oXtj3LqnTWCAM0qHRHfyzCzhEfWX0zrW7KqXXeE4DlchZBKw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.30.7", - "@typescript-eslint/visitor-keys": "5.30.7" - } - }, - "@typescript-eslint/type-utils": { - "version": "5.30.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.30.7.tgz", - "integrity": "sha512-nD5qAE2aJX/YLyKMvOU5jvJyku4QN5XBVsoTynFrjQZaDgDV6i7QHFiYCx10wvn7hFvfuqIRNBtsgaLe0DbWhw==", - "dev": true, - "requires": { - "@typescript-eslint/utils": "5.30.7", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/types": { - "version": "5.30.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.30.7.tgz", - "integrity": "sha512-ocVkETUs82+U+HowkovV6uxf1AnVRKCmDRNUBUUo46/5SQv1owC/EBFkiu4MOHeZqhKz2ktZ3kvJJ1uFqQ8QPg==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.30.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.7.tgz", - "integrity": "sha512-tNslqXI1ZdmXXrHER83TJ8OTYl4epUzJC0aj2i4DMDT4iU+UqLT3EJeGQvJ17BMbm31x5scSwo3hPM0nqQ1AEA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.30.7", - "@typescript-eslint/visitor-keys": "5.30.7", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/utils": { - "version": "5.30.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.30.7.tgz", - "integrity": "sha512-Z3pHdbFw+ftZiGUnm1GZhkJgVqsDL5CYW2yj+TB2mfXDFOMqtbzQi2dNJIyPqPbx9mv2kUxS1gU+r2gKlKi1rQ==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.30.7", - "@typescript-eslint/types": "5.30.7", - "@typescript-eslint/typescript-estree": "5.30.7", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.30.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.7.tgz", - "integrity": "sha512-KrRXf8nnjvcpxDFOKej4xkD7657+PClJs5cJVSG7NNoCNnjEdc46juNAQt7AyuWctuCgs6mVRc1xGctEqrjxWw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.30.7", - "eslint-visitor-keys": "^3.3.0" - } - }, - "@uppy/companion-client": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@uppy/companion-client/-/companion-client-2.2.1.tgz", - "integrity": "sha512-Y3E10NJLMfp/wjgthNhx3gJtT67fzFCPNPFwpNNRs5iJsW6PANhJ420eyMUFzfmEZ56ZzGYxr5pzJZx8YxHICQ==", - "requires": { - "@uppy/utils": "^4.1.0", - "namespace-emitter": "^2.0.1" - } - }, - "@uppy/core": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@uppy/core/-/core-2.3.1.tgz", - "integrity": "sha512-KV04X7ueYbYX1p37/i3QsoQSw8IDP8Yb+Bh9KNN0X2Vcun6K2VnNjhVtPmPXtyjDZooK7lVIqhRX8TZWcSfgSQ==", - "requires": { - "@transloadit/prettier-bytes": "0.0.7", - "@uppy/store-default": "^2.1.0", - "@uppy/utils": "^4.1.0", - "lodash.throttle": "^4.1.1", - "mime-match": "^1.0.2", - "namespace-emitter": "^2.0.1", - "nanoid": "^3.1.25", - "preact": "^10.5.13" - } - }, - "@uppy/store-default": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@uppy/store-default/-/store-default-2.1.0.tgz", - "integrity": "sha512-BkcR1wGw6Kwbvr8m1tKF9EDDWSTJoTGnVseBF/iW4bzR22assbtxZIE1iroo68UMqYEG4rv63SX4BUEtNvVjdA==" - }, - "@uppy/utils": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@uppy/utils/-/utils-4.1.0.tgz", - "integrity": "sha512-C47DUl4uLzmQZdW+VmetIgGRurXuPsvb+/pyYqh9DJn0Phep8u7AOj/tlJA5CHv4pefNHsFjXpaWfSUG3HtW3A==", - "requires": { - "lodash.throttle": "^4.1.1" - } - }, - "@uppy/xhr-upload": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@uppy/xhr-upload/-/xhr-upload-2.1.2.tgz", - "integrity": "sha512-VCsb7J5yHsof49nnUa+Y1n27UMtqHPttQmmoCa5hmjqa9R7ZISpBkXKOQmZo526eopKNuAKSAdkHWfCm8efJTA==", - "requires": { - "@uppy/companion-client": "^2.2.1", - "@uppy/utils": "^4.1.0", - "nanoid": "^3.1.25" - } - }, - "@vicons/ionicons5": { - "version": "0.12.0", - "resolved": "https://registry.npmmirror.com/@vicons/ionicons5/-/ionicons5-0.12.0.tgz", - "integrity": "sha512-Iy1EUVRpX0WWxeu1VIReR1zsZLMc4fqpt223czR+Rpnrwu7pt46nbnC2ycO7ItI/uqDLJxnbcMC7FujKs9IfFA==" - }, - "@vitejs/plugin-vue": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-2.3.3.tgz", - "integrity": "sha512-SmQLDyhz+6lGJhPELsBdzXGc+AcaT8stgkbiTFGpXPe8Tl1tJaBw1A6pxDqDuRsVkD8uscrkx3hA7QDOoKYtyw==", - "dev": true - }, - "@vue/compiler-core": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.37.tgz", - "integrity": "sha512-81KhEjo7YAOh0vQJoSmAD68wLfYqJvoiD4ulyedzF+OEk/bk6/hx3fTNVfuzugIIaTrOx4PGx6pAiBRe5e9Zmg==", - "requires": { - "@babel/parser": "^7.16.4", - "@vue/shared": "3.2.37", - "estree-walker": "^2.0.2", - "source-map": "^0.6.1" - } - }, - "@vue/compiler-dom": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.37.tgz", - "integrity": "sha512-yxJLH167fucHKxaqXpYk7x8z7mMEnXOw3G2q62FTkmsvNxu4FQSu5+3UMb+L7fjKa26DEzhrmCxAgFLLIzVfqQ==", - "requires": { - "@vue/compiler-core": "3.2.37", - "@vue/shared": "3.2.37" - } - }, - "@vue/compiler-sfc": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.37.tgz", - "integrity": "sha512-+7i/2+9LYlpqDv+KTtWhOZH+pa8/HnX/905MdVmAcI/mPQOBwkHHIzrsEsucyOIZQYMkXUiTkmZq5am/NyXKkg==", - "requires": { - "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.37", - "@vue/compiler-dom": "3.2.37", - "@vue/compiler-ssr": "3.2.37", - "@vue/reactivity-transform": "3.2.37", - "@vue/shared": "3.2.37", - "estree-walker": "^2.0.2", - "magic-string": "^0.25.7", - "postcss": "^8.1.10", - "source-map": "^0.6.1" - } - }, - "@vue/compiler-ssr": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.37.tgz", - "integrity": "sha512-7mQJD7HdXxQjktmsWp/J67lThEIcxLemz1Vb5I6rYJHR5vI+lON3nPGOH3ubmbvYGt8xEUaAr1j7/tIFWiEOqw==", - "requires": { - "@vue/compiler-dom": "3.2.37", - "@vue/shared": "3.2.37" - } - }, - "@vue/devtools-api": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.2.1.tgz", - "integrity": "sha512-OEgAMeQXvCoJ+1x8WyQuVZzFo0wcyCmUR3baRVLmKBo1LmYZWMlRiXlux5jd0fqVJu6PfDbOrZItVqUEzLobeQ==" - }, - "@vue/reactivity": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.37.tgz", - "integrity": "sha512-/7WRafBOshOc6m3F7plwzPeCu/RCVv9uMpOwa/5PiY1Zz+WLVRWiy0MYKwmg19KBdGtFWsmZ4cD+LOdVPcs52A==", - "requires": { - "@vue/shared": "3.2.37" - } - }, - "@vue/reactivity-transform": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.37.tgz", - "integrity": "sha512-IWopkKEb+8qpu/1eMKVeXrK0NLw9HicGviJzhJDEyfxTR9e1WtpnnbYkJWurX6WwoFP0sz10xQg8yL8lgskAZg==", - "requires": { - "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.37", - "@vue/shared": "3.2.37", - "estree-walker": "^2.0.2", - "magic-string": "^0.25.7" - } - }, - "@vue/runtime-core": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.37.tgz", - "integrity": "sha512-JPcd9kFyEdXLl/i0ClS7lwgcs0QpUAWj+SKX2ZC3ANKi1U4DOtiEr6cRqFXsPwY5u1L9fAjkinIdB8Rz3FoYNQ==", - "requires": { - "@vue/reactivity": "3.2.37", - "@vue/shared": "3.2.37" - } - }, - "@vue/runtime-dom": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.37.tgz", - "integrity": "sha512-HimKdh9BepShW6YozwRKAYjYQWg9mQn63RGEiSswMbW+ssIht1MILYlVGkAGGQbkhSh31PCdoUcfiu4apXJoPw==", - "requires": { - "@vue/runtime-core": "3.2.37", - "@vue/shared": "3.2.37", - "csstype": "^2.6.8" - } - }, - "@vue/server-renderer": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.37.tgz", - "integrity": "sha512-kLITEJvaYgZQ2h47hIzPh2K3jG8c1zCVbp/o/bzQOyvzaKiCquKS7AaioPI28GNxIsE/zSx+EwWYsNxDCX95MA==", - "requires": { - "@vue/compiler-ssr": "3.2.37", - "@vue/shared": "3.2.37" - } - }, - "@vue/shared": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.37.tgz", - "integrity": "sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==" - }, - "@vueuse/core": { - "version": "8.9.4", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-8.9.4.tgz", - "integrity": "sha512-B/Mdj9TK1peFyWaPof+Zf/mP9XuGAngaJZBwPaXBvU3aCTZlx3ltlrFFFyMV4iGBwsjSCeUCgZrtkEj9dS2Y3Q==", - "requires": { - "@types/web-bluetooth": "^0.0.14", - "@vueuse/metadata": "8.9.4", - "@vueuse/shared": "8.9.4", - "vue-demi": "*" - }, - "dependencies": { - "@vueuse/shared": { - "version": "8.9.4", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-8.9.4.tgz", - "integrity": "sha512-wt+T30c4K6dGRMVqPddexEVLa28YwxW5OFIPmzUHICjphfAuBFTTdDoyqREZNDOFJZ44ARH1WWQNCUK8koJ+Ag==", - "requires": { - "vue-demi": "*" - } - }, - "vue-demi": { - "version": "0.13.5", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.5.tgz", - "integrity": "sha512-tO3K2bML3AwiHmVHeKCq6HLef2st4zBXIV5aEkoJl6HZ+gJWxWv2O8wLH8qrA3SX3lDoTDHNghLX1xZg83MXvw==" - } - } - }, - "@vueuse/metadata": { - "version": "8.9.4", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-8.9.4.tgz", - "integrity": "sha512-IwSfzH80bnJMzqhaapqJl9JRIiyQU0zsRGEgnxN6jhq7992cPUJIRfV+JHRIZXjYqbwt07E1gTEp0R0zPJ1aqw==" - }, - "@wangeditor/basic-modules": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@wangeditor/basic-modules/-/basic-modules-1.1.3.tgz", - "integrity": "sha512-TGJix4UelO46yAgwI946ctx4lSIJbYBwNvjSJ9Tf8mKr0WMCeLVBV+MV85rXPsfcmWtR4wBNwSg648Z+RbqRUg==", - "requires": { - "is-url": "^1.2.4" - } - }, - "@wangeditor/code-highlight": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@wangeditor/code-highlight/-/code-highlight-1.0.2.tgz", - "integrity": "sha512-SCtOcUxjKqIso/LSxGSOaYr3G6MC2En0gNTyHIMCG928T0fo0ufaqp/vIXKQzVL2Y+X/CSAOB2EbrFlgGvr0AQ==", - "requires": { - "prismjs": "^1.23.0" - } - }, - "@wangeditor/core": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/@wangeditor/core/-/core-1.1.8.tgz", - "integrity": "sha512-TfCtAXfL/bgmUKQbtLEaboK7wH49G7BQqYoQsylZ7MyD1LhYnVLXp/4RzJbuIr4cV9Bs1Ncz1JoZ9tqDe6WImw==", - "requires": { - "@types/event-emitter": "^0.3.3", - "event-emitter": "^0.3.5", - "html-void-elements": "^2.0.0", - "i18next": "^20.4.0", - "scroll-into-view-if-needed": "^2.2.28", - "slate-history": "^0.66.0" - } - }, - "@wangeditor/editor": { - "version": "5.1.11", - "resolved": "https://registry.npmjs.org/@wangeditor/editor/-/editor-5.1.11.tgz", - "integrity": "sha512-jJbY2OirSy16UY9OkOCBw0DhQpOzTIGRLYL724wYSWf9nO6DpO21bemmEoDDF5zULtabEm3w0dvSxTSVd7amLw==", - "requires": { - "@uppy/core": "^2.1.1", - "@uppy/xhr-upload": "^2.0.3", - "@wangeditor/basic-modules": "^1.1.3", - "@wangeditor/code-highlight": "^1.0.2", - "@wangeditor/core": "^1.1.8", - "@wangeditor/list-module": "^1.0.2", - "@wangeditor/table-module": "^1.1.1", - "@wangeditor/upload-image-module": "^1.0.1", - "@wangeditor/video-module": "^1.1.1", - "dom7": "^3.0.0", - "is-hotkey": "^0.2.0", - "lodash.camelcase": "^4.3.0", - "lodash.clonedeep": "^4.5.0", - "lodash.debounce": "^4.0.8", - "lodash.foreach": "^4.5.0", - "lodash.isequal": "^4.5.0", - "lodash.throttle": "^4.1.1", - "lodash.toarray": "^4.4.0", - "nanoid": "^3.2.0", - "slate": "^0.72.0", - "snabbdom": "^3.1.0" - } - }, - "@wangeditor/list-module": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@wangeditor/list-module/-/list-module-1.0.2.tgz", - "integrity": "sha512-VfENZEFvsLTiLxN/cj8cibFGy9NVV+/cfATTiLiH9ef+8lgKv8apttXYVlqIAfnlJLLuCk0cIm8c/zH+hbtrZg==" - }, - "@wangeditor/table-module": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@wangeditor/table-module/-/table-module-1.1.1.tgz", - "integrity": "sha512-VPjEWQtncS2DsXYXiHUxPSxn2Xhc8GdhG3la7N5YhvxQde1+4N0SZLXeWsYvbGzOq4um5XToq5pktLLbE8G+EA==" - }, - "@wangeditor/upload-image-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@wangeditor/upload-image-module/-/upload-image-module-1.0.1.tgz", - "integrity": "sha512-vgUV4ENttTITblqtVuzleIq732OmzmzzgrIvX6b3GRGPSw5u8glJ/87tOEhvHjHECc4oFo18B7xzJ1GpBj79/w==" - }, - "@wangeditor/video-module": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@wangeditor/video-module/-/video-module-1.1.1.tgz", - "integrity": "sha512-6gzpS5cnJihW2T0HFjqmbv6v8ouyaeMUjdM2X8BPohwD74p1ov00dCmRt5QekNTyYSmRHK0ASkUMOvRGqaDxMg==" - }, - "acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "async-validator": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz", - "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "requires": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "batch-processor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/batch-processor/-/batch-processor-1.0.0.tgz", - "integrity": "sha512-xoLQD8gmmR32MeuBHgH0Tzd5PuSZx71ZsbhVxOCRbgktZEPe4SQy7s9Z50uPp0F/f7iw2XmkHN2xkgbMfckMDA==" - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "claygl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/claygl/-/claygl-1.3.0.tgz", - "integrity": "sha512-+gGtJjT6SSHD2l2yC3MCubW/sCV40tZuSs5opdtn79vFSGUgp/lH139RNEQ6Jy078/L0aV8odCw8RSrUcMfLaQ==" - }, - "clipboard": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.11.tgz", - "integrity": "sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==", - "requires": { - "good-listener": "^1.2.2", - "select": "^1.1.2", - "tiny-emitter": "^2.0.0" - } - }, - "codemirror": { - "version": "6.0.1", - "resolved": "https://registry.npmmirror.com/codemirror/-/codemirror-6.0.1.tgz", - "integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==", - "requires": { - "@codemirror/autocomplete": "^6.0.0", - "@codemirror/commands": "^6.0.0", - "@codemirror/language": "^6.0.0", - "@codemirror/lint": "^6.0.0", - "@codemirror/search": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0" - } - }, - "color": { - "version": "3.2.1", - "resolved": "https://registry.npmmirror.com/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "requires": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" - }, - "dependencies": { - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - } - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmmirror.com/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "requires": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "compute-scroll-into-view": { - "version": "1.0.17", - "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.17.tgz", - "integrity": "sha512-j4dx+Fb0URmzbwwMUrhqWM2BEWHdFGx+qZ9qqASHRPqvTYdqvWnHg0H1hIbcyLnvgnoNAVMlwkepyqM3DaIFUg==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "copy-anything": { - "version": "2.0.6", - "resolved": "https://registry.npmmirror.com/copy-anything/-/copy-anything-2.0.6.tgz", - "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", - "requires": { - "is-what": "^3.14.1" - } - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fcore-util-is%2F-%2Fcore-util-is-1.0.3.tgz", - "integrity": "sha1-pgQtNjTCsn6TKPg3uWX6yDgI24U=" - }, - "countup.js": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/countup.js/-/countup.js-2.3.2.tgz", - "integrity": "sha512-dQ7F/CmKGjaO6cDfhtEXwsKVlXIpJ89dFs8PvkaZH9jBVJ2Z8GU4iwG/qP7MgY8qwr+1skbwR6qecWWQLUzB8Q==" - }, - "crelt": { - "version": "1.0.5", - "resolved": "https://registry.npmmirror.com/crelt/-/crelt-1.0.5.tgz", - "integrity": "sha512-+BO9wPPi+DWTDcNYhr/W90myha8ptzftZT+LwcmUbbok0rcP/fequmFYCw8NMoH7pkAZQzU78b3kYrlua5a9eA==" - }, - "cropperjs": { - "version": "1.5.12", - "resolved": "https://registry.npmjs.org/cropperjs/-/cropperjs-1.5.12.tgz", - "integrity": "sha512-re7UdjE5UnwdrovyhNzZ6gathI4Rs3KGCBSc8HCIjUo5hO42CtzyblmWLj6QWVw7huHyDMfpKxhiO2II77nhDw==" - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "css-render": { - "version": "0.15.12", - "resolved": "https://registry.npmmirror.com/css-render/-/css-render-0.15.12.tgz", - "integrity": "sha512-eWzS66patiGkTTik+ipO9qNGZ+uNuGyTmnz6/+EJIiFg8+3yZRpnMwgFo8YdXhQRsiePzehnusrxVvugNjXzbw==", - "requires": { - "@emotion/hash": "~0.8.0", - "csstype": "~3.0.5" - }, - "dependencies": { - "csstype": { - "version": "3.0.11", - "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.0.11.tgz", - "integrity": "sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==" - } - } - }, - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true - }, - "csstype": { - "version": "2.6.20", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.20.tgz", - "integrity": "sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==" - }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "d3-color": { - "version": "3.1.0", - "resolved": "https://registry.npmmirror.com/d3-color/-/d3-color-3.1.0.tgz", - "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==" - }, - "d3-dispatch": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/d3-dispatch/-/d3-dispatch-2.0.0.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fd3-dispatch%2F-%2Fd3-dispatch-2.0.0.tgz", - "integrity": "sha1-ihjhb3bdP8rvQhY8l7kmqptV588=" - }, - "d3-ease": { - "version": "1.0.7", - "resolved": "https://registry.npmmirror.com/d3-ease/-/d3-ease-1.0.7.tgz", - "integrity": "sha512-lx14ZPYkhNx0s/2HX5sLFUI3mbasHjSSpwO/KaaNACweVwxUruKyWVcb293wMv1RqTPZyZ8kSZ2NogUZNcLOFQ==" - }, - "d3-force": { - "version": "2.1.1", - "resolved": "https://registry.npmmirror.com/d3-force/-/d3-force-2.1.1.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fd3-force%2F-%2Fd3-force-2.1.1.tgz", - "integrity": "sha1-8gzL8ebJ6ArdGSbwm1H2hqi8CTc=", - "requires": { - "d3-dispatch": "1 - 2", - "d3-quadtree": "1 - 2", - "d3-timer": "1 - 2" - } - }, - "d3-interpolate": { - "version": "3.0.1", - "resolved": "https://registry.npmmirror.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz", - "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", - "requires": { - "d3-color": "1 - 3" - } - }, - "d3-quadtree": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/d3-quadtree/-/d3-quadtree-2.0.0.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fd3-quadtree%2F-%2Fd3-quadtree-2.0.0.tgz", - "integrity": "sha1-7brQRc74hwH2/uOu6Ok/szLTD50=" - }, - "d3-timer": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/d3-timer/-/d3-timer-2.0.0.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fd3-timer%2F-%2Fd3-timer-2.0.0.tgz", - "integrity": "sha1-BV7bHRcM/jGrLaiWje7pQLVmI+Y=" - }, - "dagre": { - "version": "0.8.5", - "resolved": "https://registry.npmmirror.com/dagre/-/dagre-0.8.5.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fdagre%2F-%2Fdagre-0.8.5.tgz", - "integrity": "sha1-ujCwBV2sErbB/MJHgXRCd30Gr+4=", - "requires": { - "graphlib": "^2.1.8", - "lodash": "^4.17.15" - } - }, - "dagre-compound": { - "version": "0.0.11", - "resolved": "https://registry.npmmirror.com/dagre-compound/-/dagre-compound-0.0.11.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fdagre-compound%2F-%2Fdagre-compound-0.0.11.tgz", - "integrity": "sha1-jT0QBNdW9CBYLSnyjJIEU3UBiYc=" - }, - "date-fns": { - "version": "2.29.3", - "resolved": "https://registry.npmmirror.com/date-fns/-/date-fns-2.29.3.tgz", - "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==" - }, - "date-fns-tz": { - "version": "1.3.8", - "resolved": "https://registry.npmmirror.com/date-fns-tz/-/date-fns-tz-1.3.8.tgz", - "integrity": "sha512-qwNXUFtMHTTU6CFSFjoJ80W8Fzzp24LntbjFFBgL/faqds4e5mo9mftoRLgr3Vi1trISsg4awSpYVsOQCRnapQ==" - }, - "dayjs": { - "version": "1.11.4", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.4.tgz", - "integrity": "sha512-Zj/lPM5hOvQ1Bf7uAvewDaUcsJoI6JmNqmHhHl3nyumwe0XHwt8sWdOVAPACJzCebL8gQCi+K49w7iKWnGwX9g==" - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmmirror.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fdecode-uri-component%2F-%2Fdecode-uri-component-0.2.2.tgz", - "integrity": "sha1-5p2+JdN5QRcd1UDgJMREzVGI4ek=" - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" - }, - "delegate": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", - "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==" - }, - "detect-browser": { - "version": "5.3.0", - "resolved": "https://registry.npmmirror.com/detect-browser/-/detect-browser-5.3.0.tgz", - "integrity": "sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==" - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dom7": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/dom7/-/dom7-3.0.0.tgz", - "integrity": "sha512-oNlcUdHsC4zb7Msx7JN3K0Nro1dzJ48knvBOnDPKJ2GV9wl1i5vydJZUSyOfrkKFDZEud/jBsTk92S/VGSAe/g==", - "requires": { - "ssr-window": "^3.0.0-alpha.1" - } - }, - "dotenv": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.1.tgz", - "integrity": "sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==", - "dev": true - }, - "echarts": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.3.3.tgz", - "integrity": "sha512-BRw2serInRwO5SIwRviZ6Xgm5Lb7irgz+sLiFMmy/HOaf4SQ+7oYqxKzRHAKp4xHQ05AuHw1xvoQWJjDQq/FGw==", - "requires": { - "tslib": "2.3.0", - "zrender": "5.3.2" - } - }, - "echarts-gl": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/echarts-gl/-/echarts-gl-2.0.9.tgz", - "integrity": "sha512-oKeMdkkkpJGWOzjgZUsF41DOh6cMsyrGGXimbjK2l6Xeq/dBQu4ShG2w2Dzrs/1bD27b2pLTGSaUzouY191gzA==", - "requires": { - "claygl": "^1.2.1", - "zrender": "^5.1.1" - } - }, - "echarts-wordcloud": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/echarts-wordcloud/-/echarts-wordcloud-2.0.0.tgz", - "integrity": "sha512-K7l6pTklqdW7ZWzT/1CS0KhBSINr/cd7c5N1fVMzZMwLQHEwT7x+nivK7g5hkVh7WNcAv4Dn6/ZS5zMKRozC1g==" - }, - "element-plus": { - "version": "2.2.9", - "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.2.9.tgz", - "integrity": "sha512-jYbL0JkCdv95rkT6trZJjCAizLPySa0qcd2cgq+57SKQnCZAcNDDq4GbTuFRnNavdoeCJnuM3HIficTIUpsMOQ==", - "requires": { - "@ctrl/tinycolor": "^3.4.1", - "@element-plus/icons-vue": "^2.0.6", - "@floating-ui/dom": "^0.5.4", - "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7", - "@types/lodash": "^4.14.182", - "@types/lodash-es": "^4.17.6", - "@vueuse/core": "^8.7.5", - "async-validator": "^4.2.5", - "dayjs": "^1.11.3", - "escape-html": "^1.0.3", - "lodash": "^4.17.21", - "lodash-es": "^4.17.21", - "lodash-unified": "^1.0.2", - "memoize-one": "^6.0.0", - "normalize-wheel-es": "^1.1.2" - }, - "dependencies": { - "@popperjs/core": { - "version": "npm:@sxzz/popperjs-es@2.11.7", - "resolved": "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz", - "integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==" - } - } - }, - "element-resize-detector": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/element-resize-detector/-/element-resize-detector-1.2.4.tgz", - "integrity": "sha512-Fl5Ftk6WwXE0wqCgNoseKWndjzZlDCwuPTcoVZfCP9R3EHQF8qUtr3YUPNETegRBOKqQKPW3n4kiIWngGi8tKg==", - "requires": { - "batch-processor": "1.0.0" - } - }, - "errno": { - "version": "0.1.8", - "resolved": "https://registry.npmmirror.com/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "optional": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es5-ext": { - "version": "0.10.61", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.61.tgz", - "integrity": "sha512-yFhIqQAzu2Ca2I4SE2Au3rxVfmohU9Y7wqGR+s7+H7krk26NXhIRAZDgqd6xqjCEFUomDEA3/Bo/7fKmIkW1kA==", - "requires": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "esbuild": { - "version": "0.14.49", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.49.tgz", - "integrity": "sha512-/TlVHhOaq7Yz8N1OJrjqM3Auzo5wjvHFLk+T8pIue+fhnhIMpfAzsG6PLVMbFveVxqD2WOp3QHei+52IMUNmCw==", - "dev": true, - "requires": { - "esbuild-android-64": "0.14.49", - "esbuild-android-arm64": "0.14.49", - "esbuild-darwin-64": "0.14.49", - "esbuild-darwin-arm64": "0.14.49", - "esbuild-freebsd-64": "0.14.49", - "esbuild-freebsd-arm64": "0.14.49", - "esbuild-linux-32": "0.14.49", - "esbuild-linux-64": "0.14.49", - "esbuild-linux-arm": "0.14.49", - "esbuild-linux-arm64": "0.14.49", - "esbuild-linux-mips64le": "0.14.49", - "esbuild-linux-ppc64le": "0.14.49", - "esbuild-linux-riscv64": "0.14.49", - "esbuild-linux-s390x": "0.14.49", - "esbuild-netbsd-64": "0.14.49", - "esbuild-openbsd-64": "0.14.49", - "esbuild-sunos-64": "0.14.49", - "esbuild-windows-32": "0.14.49", - "esbuild-windows-64": "0.14.49", - "esbuild-windows-arm64": "0.14.49" - } - }, - "esbuild-android-64": { - "version": "0.14.49", - "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.49.tgz", - "integrity": "sha512-vYsdOTD+yi+kquhBiFWl3tyxnj2qZJsl4tAqwhT90ktUdnyTizgle7TjNx6Ar1bN7wcwWqZ9QInfdk2WVagSww==", - "dev": true, - "optional": true - }, - "esbuild-android-arm64": { - "version": "0.14.49", - "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.49.tgz", - "integrity": "sha512-g2HGr/hjOXCgSsvQZ1nK4nW/ei8JUx04Li74qub9qWrStlysaVmadRyTVuW32FGIpLQyc5sUjjZopj49eGGM2g==", - "dev": true, - "optional": true - }, - "esbuild-darwin-64": { - "version": "0.14.49", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.49.tgz", - "integrity": "sha512-3rvqnBCtX9ywso5fCHixt2GBCUsogNp9DjGmvbBohh31Ces34BVzFltMSxJpacNki96+WIcX5s/vum+ckXiLYg==", - "dev": true, - "optional": true - }, - "esbuild-darwin-arm64": { - "version": "0.14.49", - "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.49.tgz", - "integrity": "sha512-XMaqDxO846srnGlUSJnwbijV29MTKUATmOLyQSfswbK/2X5Uv28M9tTLUJcKKxzoo9lnkYPsx2o8EJcTYwCs/A==", - "dev": true, - "optional": true - }, - "esbuild-freebsd-64": { - "version": "0.14.49", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.49.tgz", - "integrity": "sha512-NJ5Q6AjV879mOHFri+5lZLTp5XsO2hQ+KSJYLbfY9DgCu8s6/Zl2prWXVANYTeCDLlrIlNNYw8y34xqyLDKOmQ==", - "dev": true, - "optional": true - }, - "esbuild-freebsd-arm64": { - "version": "0.14.49", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.49.tgz", - "integrity": "sha512-lFLtgXnAc3eXYqj5koPlBZvEbBSOSUbWO3gyY/0+4lBdRqELyz4bAuamHvmvHW5swJYL7kngzIZw6kdu25KGOA==", - "dev": true, - "optional": true - }, - "esbuild-linux-32": { - "version": "0.14.49", - "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.49.tgz", - "integrity": "sha512-zTTH4gr2Kb8u4QcOpTDVn7Z8q7QEIvFl/+vHrI3cF6XOJS7iEI1FWslTo3uofB2+mn6sIJEQD9PrNZKoAAMDiA==", - "dev": true, - "optional": true - }, - "esbuild-linux-64": { - "version": "0.14.49", - "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.49.tgz", - "integrity": "sha512-hYmzRIDzFfLrB5c1SknkxzM8LdEUOusp6M2TnuQZJLRtxTgyPnZZVtyMeCLki0wKgYPXkFsAVhi8vzo2mBNeTg==", - "dev": true, - "optional": true - }, - "esbuild-linux-arm": { - "version": "0.14.49", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.49.tgz", - "integrity": "sha512-iE3e+ZVv1Qz1Sy0gifIsarJMQ89Rpm9mtLSRtG3AH0FPgAzQ5Z5oU6vYzhc/3gSPi2UxdCOfRhw2onXuFw/0lg==", - "dev": true, - "optional": true - }, - "esbuild-linux-arm64": { - "version": "0.14.49", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.49.tgz", - "integrity": "sha512-KLQ+WpeuY+7bxukxLz5VgkAAVQxUv67Ft4DmHIPIW+2w3ObBPQhqNoeQUHxopoW/aiOn3m99NSmSV+bs4BSsdA==", - "dev": true, - "optional": true - }, - "esbuild-linux-mips64le": { - "version": "0.14.49", - "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.49.tgz", - "integrity": "sha512-n+rGODfm8RSum5pFIqFQVQpYBw+AztL8s6o9kfx7tjfK0yIGF6tm5HlG6aRjodiiKkH2xAiIM+U4xtQVZYU4rA==", - "dev": true, - "optional": true - }, - "esbuild-linux-ppc64le": { - "version": "0.14.49", - "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.49.tgz", - "integrity": "sha512-WP9zR4HX6iCBmMFH+XHHng2LmdoIeUmBpL4aL2TR8ruzXyT4dWrJ5BSbT8iNo6THN8lod6GOmYDLq/dgZLalGw==", - "dev": true, - "optional": true - }, - "esbuild-linux-riscv64": { - "version": "0.14.49", - "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.49.tgz", - "integrity": "sha512-h66ORBz+Dg+1KgLvzTVQEA1LX4XBd1SK0Fgbhhw4akpG/YkN8pS6OzYI/7SGENiN6ao5hETRDSkVcvU9NRtkMQ==", - "dev": true, - "optional": true - }, - "esbuild-linux-s390x": { - "version": "0.14.49", - "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.49.tgz", - "integrity": "sha512-DhrUoFVWD+XmKO1y7e4kNCqQHPs6twz6VV6Uezl/XHYGzM60rBewBF5jlZjG0nCk5W/Xy6y1xWeopkrhFFM0sQ==", - "dev": true, - "optional": true - }, - "esbuild-netbsd-64": { - "version": "0.14.49", - "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.49.tgz", - "integrity": "sha512-BXaUwFOfCy2T+hABtiPUIpWjAeWK9P8O41gR4Pg73hpzoygVGnj0nI3YK4SJhe52ELgtdgWP/ckIkbn2XaTxjQ==", - "dev": true, - "optional": true - }, - "esbuild-openbsd-64": { - "version": "0.14.49", - "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.49.tgz", - "integrity": "sha512-lP06UQeLDGmVPw9Rg437Btu6J9/BmyhdoefnQ4gDEJTtJvKtQaUcOQrhjTq455ouZN4EHFH1h28WOJVANK41kA==", - "dev": true, - "optional": true - }, - "esbuild-sunos-64": { - "version": "0.14.49", - "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.49.tgz", - "integrity": "sha512-4c8Zowp+V3zIWje329BeLbGh6XI9c/rqARNaj5yPHdC61pHI9UNdDxT3rePPJeWcEZVKjkiAS6AP6kiITp7FSw==", - "dev": true, - "optional": true - }, - "esbuild-windows-32": { - "version": "0.14.49", - "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.49.tgz", - "integrity": "sha512-q7Rb+J9yHTeKr9QTPDYkqfkEj8/kcKz9lOabDuvEXpXuIcosWCJgo5Z7h/L4r7rbtTH4a8U2FGKb6s1eeOHmJA==", - "dev": true, - "optional": true - }, - "esbuild-windows-64": { - "version": "0.14.49", - "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.49.tgz", - "integrity": "sha512-+Cme7Ongv0UIUTniPqfTX6mJ8Deo7VXw9xN0yJEN1lQMHDppTNmKwAM3oGbD/Vqff+07K2gN0WfNkMohmG+dVw==", - "dev": true, - "optional": true - }, - "esbuild-windows-arm64": { - "version": "0.14.49", - "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.49.tgz", - "integrity": "sha512-v+HYNAXzuANrCbbLFJ5nmO3m5y2PGZWLe3uloAkLt87aXiO2mZr3BTmacZdjwNkNEHuH3bNtN8cak+mzVjVPfA==", - "dev": true, - "optional": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.20.0.tgz", - "integrity": "sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA==", - "dev": true, - "requires": { - "@eslint/eslintrc": "^1.3.0", - "@humanwhocodes/config-array": "^0.9.2", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.2", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "eslint-plugin-vue": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.2.0.tgz", - "integrity": "sha512-W2hc+NUXoce8sZtWgZ45miQTy6jNyuSdub5aZ1IBune4JDeAyzucYX0TzkrQ1jMO52sNUDYlCIHDoaNePe0p5g==", - "dev": true, - "requires": { - "eslint-utils": "^3.0.0", - "natural-compare": "^1.4.0", - "nth-check": "^2.0.1", - "postcss-selector-parser": "^6.0.9", - "semver": "^7.3.5", - "vue-eslint-parser": "^9.0.1", - "xml-name-validator": "^4.0.0" - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true - }, - "espree": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", - "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", - "dev": true, - "requires": { - "acorn": "^8.7.1", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" - } - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, - "evtd": { - "version": "0.2.4", - "resolved": "https://registry.npmmirror.com/evtd/-/evtd-0.2.4.tgz", - "integrity": "sha512-qaeGN5bx63s/AXgQo8gj6fBkxge+OoLddLniox5qtLAEY5HSnuSlISXVPxnSae1dWblvTh4/HoMIB+mbMsvZzw==" - }, - "ext": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", - "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", - "requires": { - "type": "^2.5.0" - }, - "dependencies": { - "type": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.6.0.tgz", - "integrity": "sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ==" - } - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "fecha": { - "version": "4.2.3", - "resolved": "https://registry.npmmirror.com/fecha/-/fecha-4.2.3.tgz", - "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "filter-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/filter-obj/-/filter-obj-1.1.0.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Ffilter-obj%2F-%2Ffilter-obj-1.1.0.tgz", - "integrity": "sha1-mzERErxsYSehbgFsbF1/GeCAXFs=" - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz", - "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==", - "dev": true - }, - "follow-redirects": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==" - }, - "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, - "gl-matrix": { - "version": "3.4.3", - "resolved": "https://registry.npmmirror.com/gl-matrix/-/gl-matrix-3.4.3.tgz", - "integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==" - }, - "gl-vec2": { - "version": "1.3.0", - "resolved": "https://registry.npmmirror.com/gl-vec2/-/gl-vec2-1.3.0.tgz", - "integrity": "sha512-YiqaAuNsheWmUV0Sa8k94kBB0D6RWjwZztyO+trEYS8KzJ6OQB/4686gdrf59wld4hHFIvaxynO3nRxpk1Ij/A==" - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "globals": { - "version": "13.16.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.16.0.tgz", - "integrity": "sha512-A1lrQfpNF+McdPOnnFqY3kSN0AFTy485bTi1bkLk4mVPODIUEcSfhHgRqA+QdXPksrSTTztYXx37NFV+GpGk3Q==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "good-listener": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", - "integrity": "sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==", - "requires": { - "delegate": "^3.1.2" - } - }, - "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "optional": true - }, - "graphlib": { - "version": "2.1.8", - "resolved": "https://registry.npmmirror.com/graphlib/-/graphlib-2.1.8.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fgraphlib%2F-%2Fgraphlib-2.1.8.tgz", - "integrity": "sha1-V2HUFHN4cAhMkux7XbywWSydNdo=", - "requires": { - "lodash": "^4.17.15" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "highlight.js": { - "version": "11.7.0", - "resolved": "https://registry.npmmirror.com/highlight.js/-/highlight.js-11.7.0.tgz", - "integrity": "sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ==" - }, - "html-void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.1.tgz", - "integrity": "sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==" - }, - "i18next": { - "version": "20.6.1", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-20.6.1.tgz", - "integrity": "sha512-yCMYTMEJ9ihCwEQQ3phLo7I/Pwycf8uAx+sRHwwk5U9Aui/IZYgQRyMqXafQOw5QQ7DM1Z+WyEXWIqSuJHhG2A==", - "requires": { - "@babel/runtime": "^7.12.0" - } - }, - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "image-size": { - "version": "0.5.5", - "resolved": "https://registry.npmmirror.com/image-size/-/image-size-0.5.5.tgz", - "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", - "optional": true - }, - "immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmmirror.com/immediate/-/immediate-3.0.6.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fimmediate%2F-%2Fimmediate-3.0.6.tgz", - "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" - }, - "immer": { - "version": "9.0.15", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.15.tgz", - "integrity": "sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ==" - }, - "immutable": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", - "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "insert-css": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/insert-css/-/insert-css-2.0.0.tgz", - "integrity": "sha512-xGq5ISgcUP5cvGkS2MMFLtPDBtrtQPSFfC6gA6U8wHKqfjTIMZLZNxOItQnoSjdOzlXOLU/yD32RKC4SvjNbtA==" - }, - "is-any-array": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/is-any-array/-/is-any-array-2.0.0.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fis-any-array%2F-%2Fis-any-array-2.0.0.tgz", - "integrity": "sha1-5xvBN0FTfAavrAPAeIWWfvVth0I=" - }, - "is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-hotkey": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/is-hotkey/-/is-hotkey-0.2.0.tgz", - "integrity": "sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw==" - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" - }, - "is-url": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", - "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==" - }, - "is-what": { - "version": "3.14.1", - "resolved": "https://registry.npmmirror.com/is-what/-/is-what-3.14.1.tgz", - "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fisarray%2F-%2Fisarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "js-cookie": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.1.tgz", - "integrity": "sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw==" - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "jsplumb": { - "version": "2.15.6", - "resolved": "https://registry.npmjs.org/jsplumb/-/jsplumb-2.15.6.tgz", - "integrity": "sha512-sIpbpz5eMVM+vV+MQzFCidlaa1RsknrQs6LOTKYDjYUDdTAi2AN2bFi94TxB33TifcIsRNV1jebcaxg0tCoPzg==" - }, - "jszip": { - "version": "3.10.1", - "resolved": "https://registry.npmmirror.com/jszip/-/jszip-3.10.1.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fjszip%2F-%2Fjszip-3.10.1.tgz", - "integrity": "sha1-NK7nDrGOofrsL1iSCKFX0f6wkcI=", - "requires": { - "lie": "~3.3.0", - "pako": "~1.0.2", - "readable-stream": "~2.3.6", - "setimmediate": "^1.0.5" - }, - "dependencies": { - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fprocess-nextick-args%2F-%2Fprocess-nextick-args-2.0.1.tgz", - "integrity": "sha1-eCDZsWEgzFXKmud5JoCufbptf+I=" - }, - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.8.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Freadable-stream%2F-%2Freadable-stream-2.3.8.tgz", - "integrity": "sha1-kRJegEK7obmIf0k0X2J3Anzovps=", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fsafe-buffer%2F-%2Fsafe-buffer-5.1.2.tgz", - "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fstring_decoder%2F-%2Fstring_decoder-1.1.1.tgz", - "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "klona": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz", - "integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==" - }, - "less": { - "version": "4.1.3", - "resolved": "https://registry.npmmirror.com/less/-/less-4.1.3.tgz", - "integrity": "sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==", - "requires": { - "copy-anything": "^2.0.1", - "errno": "^0.1.1", - "graceful-fs": "^4.1.2", - "image-size": "~0.5.0", - "make-dir": "^2.1.0", - "mime": "^1.4.1", - "needle": "^3.1.0", - "parse-node-version": "^1.0.1", - "source-map": "~0.6.0", - "tslib": "^2.3.0" - } - }, - "less-loader": { - "version": "11.1.0", - "resolved": "https://registry.npmmirror.com/less-loader/-/less-loader-11.1.0.tgz", - "integrity": "sha512-C+uDBV7kS7W5fJlUjq5mPBeBVhYpTIm5gB09APT9o3n/ILeaXVsiSFTbZpTJCJwQ/Crczfn3DmfQFwxYusWFug==", - "requires": { - "klona": "^2.0.4" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lie": { - "version": "3.3.0", - "resolved": "https://registry.npmmirror.com/lie/-/lie-3.3.0.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Flie%2F-%2Flie-3.3.0.tgz", - "integrity": "sha1-3Pgt7lRfRgdNryAMfBxaCOD0D2o=", - "requires": { - "immediate": "~3.0.5" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" - }, - "lodash-unified": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/lodash-unified/-/lodash-unified-1.0.2.tgz", - "integrity": "sha512-OGbEy+1P+UT26CYi4opY4gebD8cWRDxAT6MAObIVQMiqYdxZr1g3QHWCToVsm31x2NkLS4K3+MC2qInaRMa39g==" - }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" - }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" - }, - "lodash.foreach": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", - "integrity": "sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ==" - }, - "lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "lodash.throttle": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", - "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==" - }, - "lodash.toarray": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", - "integrity": "sha512-QyffEA3i5dma5q2490+SgCvDN0pXLmRGSyAANuVi0HQ01Pkfr9fuoKQW8wm1wGBnJITs/mS7wQvS6VshUEBFCw==" - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", - "requires": { - "sourcemap-codec": "^1.4.8" - } - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmmirror.com/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "optional": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmmirror.com/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "optional": true - } - } - }, - "memoize-one": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", - "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "optional": true - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mime-match/-/mime-match-1.0.2.tgz", - "integrity": "sha512-VXp/ugGDVh3eCLOBCiHZMYWQaTNUHv2IJrut+yXA6+JbLPXHglHwfS/5A5L0ll+jkCY7fIzRJcH6OIunF+c6Cg==", - "requires": { - "wildcard": "^1.1.0" - } - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { - "mime-db": "1.52.0" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "mitt": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.0.tgz", - "integrity": "sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==" - }, - "ml-array-max": { - "version": "1.2.4", - "resolved": "https://registry.npmmirror.com/ml-array-max/-/ml-array-max-1.2.4.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fml-array-max%2F-%2Fml-array-max-1.2.4.tgz", - "integrity": "sha1-I3Pit+UciAfkVswO82TFhjcTYjs=", - "requires": { - "is-any-array": "^2.0.0" - } - }, - "ml-array-min": { - "version": "1.2.3", - "resolved": "https://registry.npmmirror.com/ml-array-min/-/ml-array-min-1.2.3.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fml-array-min%2F-%2Fml-array-min-1.2.3.tgz", - "integrity": "sha1-Zi8CfEABBYFrhJzDzXhpFdCAFJU=", - "requires": { - "is-any-array": "^2.0.0" - } - }, - "ml-array-rescale": { - "version": "1.3.7", - "resolved": "https://registry.npmmirror.com/ml-array-rescale/-/ml-array-rescale-1.3.7.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fml-array-rescale%2F-%2Fml-array-rescale-1.3.7.tgz", - "integrity": "sha1-xNEpMg0ROnMuYt2WPcFpW7qaU0A=", - "requires": { - "is-any-array": "^2.0.0", - "ml-array-max": "^1.2.4", - "ml-array-min": "^1.2.3" - } - }, - "ml-matrix": { - "version": "6.10.4", - "resolved": "https://registry.npmmirror.com/ml-matrix/-/ml-matrix-6.10.4.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fml-matrix%2F-%2Fml-matrix-6.10.4.tgz", - "integrity": "sha1-ur7jRLIAYtnBI6qAHC5dDQx0d/Y=", - "requires": { - "is-any-array": "^2.0.0", - "ml-array-rescale": "^1.3.7" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "naive-ui": { - "version": "2.34.3", - "resolved": "https://registry.npmmirror.com/naive-ui/-/naive-ui-2.34.3.tgz", - "integrity": "sha512-fUMr0dzb/iGsOTWgoblPVobY5X5dihQ1eam5dA+H74oyLYAvgX4pL96xQFPBLIYqvyRFBAsN85kHN5pLqdtpxA==", - "requires": { - "@css-render/plugin-bem": "^0.15.10", - "@css-render/vue3-ssr": "^0.15.10", - "@types/katex": "^0.14.0", - "@types/lodash": "^4.14.181", - "@types/lodash-es": "^4.17.6", - "async-validator": "^4.0.7", - "css-render": "^0.15.10", - "date-fns": "^2.28.0", - "date-fns-tz": "^1.3.3", - "evtd": "^0.2.4", - "highlight.js": "^11.5.0", - "lodash": "^4.17.21", - "lodash-es": "^4.17.21", - "seemly": "^0.3.6", - "treemate": "^0.3.11", - "vdirs": "^0.1.8", - "vooks": "^0.2.12", - "vueuc": "^0.4.47" - } - }, - "namespace-emitter": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/namespace-emitter/-/namespace-emitter-2.0.1.tgz", - "integrity": "sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g==" - }, - "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "needle": { - "version": "3.2.0", - "resolved": "https://registry.npmmirror.com/needle/-/needle-3.2.0.tgz", - "integrity": "sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==", - "optional": true, - "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.6.3", - "sax": "^1.2.4" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "optional": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "normalize-wheel-es": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz", - "integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==" - }, - "normalize.css": { - "version": "7.0.0", - "resolved": "https://registry.npmmirror.com/normalize.css/-/normalize.css-7.0.0.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fnormalize.css%2F-%2Fnormalize.css-7.0.0.tgz", - "integrity": "sha1-q/sd2CRwZ04DIrU86xqvQSk45L8=" - }, - "nprogress": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", - "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==" - }, - "nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, - "requires": { - "boolbase": "^1.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmmirror.com/pako/-/pako-1.0.11.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fpako%2F-%2Fpako-1.0.11.tgz", - "integrity": "sha1-bJWZ00DVTf05RjgCUqNXBaa5kr8=" - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-node-version": { - "version": "1.0.1", - "resolved": "https://registry.npmmirror.com/parse-node-version/-/parse-node-version-1.0.1.tgz", - "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmmirror.com/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "optional": true - }, - "pinia": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.0.16.tgz", - "integrity": "sha512-9/LMVO+/epny1NBfC77vnps4g3JRezxhhoF1xLUk8mZkUIxVnwfEAIRiAX8mYBTD/KCwZqnDMqXc8w3eU0FQGg==", - "requires": { - "@vue/devtools-api": "^6.1.4", - "vue-demi": "*" - }, - "dependencies": { - "vue-demi": { - "version": "0.13.5", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.5.tgz", - "integrity": "sha512-tO3K2bML3AwiHmVHeKCq6HLef2st4zBXIV5aEkoJl6HZ+gJWxWv2O8wLH8qrA3SX3lDoTDHNghLX1xZg83MXvw==" - } - } - }, - "postcss": { - "version": "8.4.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", - "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", - "requires": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - } - }, - "postcss-selector-parser": { - "version": "6.0.10", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", - "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - }, - "preact": { - "version": "10.10.0", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.10.0.tgz", - "integrity": "sha512-fszkg1iJJjq68I4lI8ZsmBiaoQiQHbxf1lNq+72EmC/mZOsFF5zn3k1yv9QGoFgIXzgsdSKtYymLJsrJPoamjQ==" - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", - "dev": true - }, - "print-js": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/print-js/-/print-js-1.6.0.tgz", - "integrity": "sha512-BfnOIzSKbqGRtO4o0rnj/K3681BSd2QUrsIZy/+WdCIugjIswjmx3lDEZpXB2ruGf9d4b3YNINri81+J0FsBWg==" - }, - "prismjs": { - "version": "1.28.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.28.0.tgz", - "integrity": "sha512-8aaXdYvl1F7iC7Xm1spqSaY/OJBpYW3v+KJ+F17iYxvdc8sfjW194COK5wVhMZX45tGteiBQgdvD/nhxcRwylw==" - }, - "probe.gl": { - "version": "3.6.0", - "resolved": "https://registry.npmmirror.com/probe.gl/-/probe.gl-3.6.0.tgz", - "integrity": "sha512-19JydJWI7+DtR4feV+pu4Mn1I5TAc0xojuxVgZdXIyfmTLfUaFnk4OloWK1bKbPtkgGKLr2lnbnCXmpZEcEp9g==", - "requires": { - "@babel/runtime": "^7.0.0", - "@probe.gl/env": "3.6.0", - "@probe.gl/log": "3.6.0", - "@probe.gl/stats": "3.6.0" - } - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmmirror.com/prr/-/prr-1.0.1.tgz", - "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", - "optional": true - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "qrcodejs2-fixes": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/qrcodejs2-fixes/-/qrcodejs2-fixes-0.0.2.tgz", - "integrity": "sha512-wMUXYMOixAEJlLnjk5MbLiFaz0gQObWYm/TIFWB5+j7sTY5gPyr09Cx1EpcLYbsgfFdN3wHjrKAhZofTuCBGhg==" - }, - "query-string": { - "version": "7.1.3", - "resolved": "https://registry.npmmirror.com/query-string/-/query-string-7.1.3.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fquery-string%2F-%2Fquery-string-7.1.3.tgz", - "integrity": "sha1-oc+Q6ZSrsROjJYBKly2YJ2/gIyg=", - "requires": { - "decode-uri-component": "^0.2.2", - "filter-obj": "^1.1.0", - "split-on-first": "^1.0.0", - "strict-uri-encode": "^2.0.0" - } - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "regl": { - "version": "1.7.0", - "resolved": "https://registry.npmmirror.com/regl/-/regl-1.7.0.tgz", - "integrity": "sha512-bEAtp/qrtKucxXSJkD4ebopFZYP0q1+3Vb2WECWv/T8yQEgKxDxJ7ztO285tAMaYZVR6mM1GgI6CCn8FROtL1w==" - }, - "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "requires": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "rollup": { - "version": "2.77.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.0.tgz", - "integrity": "sha512-vL8xjY4yOQEw79DvyXLijhnhh+R/O9zpF/LEgkCebZFtb6ELeN9H3/2T0r8+mp+fFTBHZ5qGpOpW2ela2zRt3g==", - "dev": true, - "requires": { - "fsevents": "~2.3.2" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "optional": true - }, - "sass": { - "version": "1.53.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.53.0.tgz", - "integrity": "sha512-zb/oMirbKhUgRQ0/GFz8TSAwRq2IlR29vOUJZOx0l8sV+CkHUfHa4u5nqrG+1VceZp7Jfj59SVW9ogdhTvJDcQ==", - "dev": true, - "requires": { - "chokidar": ">=3.0.0 <4.0.0", - "immutable": "^4.0.0", - "source-map-js": ">=0.6.2 <2.0.0" - } - }, - "sass-loader": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.0.2.tgz", - "integrity": "sha512-BbiqbVmbfJaWVeOOAu2o7DhYWtcNmTfvroVgFXa6k2hHheMxNAeDHLNoDy/Q5aoaVlz0LH+MbMktKwm9vN/j8Q==", - "dev": true, - "requires": { - "klona": "^2.0.4", - "neo-async": "^2.6.2" - } - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmmirror.com/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "optional": true - }, - "screenfull": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/screenfull/-/screenfull-6.0.2.tgz", - "integrity": "sha512-AQdy8s4WhNvUZ6P8F6PB21tSPIYKniic+Ogx0AacBMjKP1GUHN2E9URxQHtCusiwxudnCKkdy4GrHXPPJSkCCw==" - }, - "scroll-into-view-if-needed": { - "version": "2.2.29", - "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.29.tgz", - "integrity": "sha512-hxpAR6AN+Gh53AdAimHM6C8oTN1ppwVZITihix+WqalywBeFcQ6LdQP5ABNl26nX8GTEL7VT+b8lKpdqq65wXg==", - "requires": { - "compute-scroll-into-view": "^1.0.17" - } - }, - "seemly": { - "version": "0.3.6", - "resolved": "https://registry.npmmirror.com/seemly/-/seemly-0.3.6.tgz", - "integrity": "sha512-lEV5VB8BUKTo/AfktXJcy+JeXns26ylbMkIUco8CYREsQijuz4mrXres2Q+vMLdwkuLxJdIPQ8IlCIxLYm71Yw==" - }, - "select": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", - "integrity": "sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==" - }, - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmmirror.com/setimmediate/-/setimmediate-1.0.5.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fsetimmediate%2F-%2Fsetimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmmirror.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "requires": { - "is-arrayish": "^0.3.1" - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "slate": { - "version": "0.72.8", - "resolved": "https://registry.npmjs.org/slate/-/slate-0.72.8.tgz", - "integrity": "sha512-/nJwTswQgnRurpK+bGJFH1oM7naD5qDmHd89JyiKNT2oOKD8marW0QSBtuFnwEbL5aGCS8AmrhXQgNOsn4osAw==", - "requires": { - "immer": "^9.0.6", - "is-plain-object": "^5.0.0", - "tiny-warning": "^1.0.3" - } - }, - "slate-history": { - "version": "0.66.0", - "resolved": "https://registry.npmjs.org/slate-history/-/slate-history-0.66.0.tgz", - "integrity": "sha512-6MWpxGQZiMvSINlCbMW43E2YBSVMCMCIwQfBzGssjWw4kb0qfvj0pIdblWNRQZD0hR6WHP+dHHgGSeVdMWzfng==", - "requires": { - "is-plain-object": "^5.0.0" - } - }, - "snabbdom": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/snabbdom/-/snabbdom-3.5.1.tgz", - "integrity": "sha512-wHMNIOjkm/YNE5EM3RCbr/+DVgPg6AqQAX1eOxO46zYNvCXjKP5Y865tqQj3EXnaMBjkxmQA5jFuDpDK/dbfiA==" - }, - "sortablejs": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.0.tgz", - "integrity": "sha512-bv9qgVMjUMf89wAvM6AxVvS/4MX3sPeN0+agqShejLU5z5GX4C75ow1O2e5k4L6XItUyAK3gH6AxSbXrOM5e8w==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" - }, - "sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" - }, - "split-on-first": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/split-on-first/-/split-on-first-1.1.0.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fsplit-on-first%2F-%2Fsplit-on-first-1.1.0.tgz", - "integrity": "sha1-9hCv7uOxK84dDDBCXnY5i3gkml8=" - }, - "splitpanes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/splitpanes/-/splitpanes-3.1.1.tgz", - "integrity": "sha512-VUkxDJfIGSvTM/fm/+OSrx8ha9URwE/9B8FPvfzoBuAxVELIHBWpsfnJXIXv77zVwuex//QQL4kTU9SDBPeHjA==" - }, - "ssr-window": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ssr-window/-/ssr-window-3.0.0.tgz", - "integrity": "sha512-q+8UfWDg9Itrg0yWK7oe5p/XRCJpJF9OBtXfOPgSJl+u3Xd5KI328RUEvUqSMVM9CiQUEf1QdBzJMkYGErj9QA==" - }, - "strict-uri-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Fstrict-uri-encode%2F-%2Fstrict-uri-encode-2.0.0.tgz", - "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=" - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "style-mod": { - "version": "4.0.0", - "resolved": "https://registry.npmmirror.com/style-mod/-/style-mod-4.0.0.tgz", - "integrity": "sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "tiny-emitter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", - "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" - }, - "tiny-warning": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" - }, - "tinycolor2": { - "version": "1.6.0", - "resolved": "https://registry.npmmirror.com/tinycolor2/-/tinycolor2-1.6.0.tgz", - "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==" - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "treemate": { - "version": "0.3.11", - "resolved": "https://registry.npmmirror.com/treemate/-/treemate-0.3.11.tgz", - "integrity": "sha512-M8RGFoKtZ8dF+iwJfAJTOH/SM4KluKOKRJpjCMhI8bG3qB74zrFoArKZ62ll0Fr3mqkMJiQOmWYkdYgDeITYQg==" - }, - "tslib": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", - "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } - } - }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "typescript": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", - "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", - "dev": true - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "utility-types": { - "version": "3.10.0", - "resolved": "https://registry.npmmirror.com/utility-types/-/utility-types-3.10.0.tgz?dl=https%3A%2F%2Fregistry.npmmirror.com%2Futility-types%2F-%2Futility-types-3.10.0.tgz", - "integrity": "sha1-6kFI+adBAV8F7XT9YV4dIOa+2Cs=" - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "vdirs": { - "version": "0.1.8", - "resolved": "https://registry.npmmirror.com/vdirs/-/vdirs-0.1.8.tgz", - "integrity": "sha512-H9V1zGRLQZg9b+GdMk8MXDN2Lva0zx72MPahDKc30v+DtwKjfyOSXWRIX4t2mhDubM1H09gPhWeth/BJWPHGUw==", - "requires": { - "evtd": "^0.2.2" - } - }, - "vite": { - "version": "2.9.14", - "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.14.tgz", - "integrity": "sha512-P/UCjSpSMcE54r4mPak55hWAZPlyfS369svib/gpmz8/01L822lMPOJ/RYW6tLCe1RPvMvOsJ17erf55bKp4Hw==", - "dev": true, - "requires": { - "esbuild": "^0.14.27", - "fsevents": "~2.3.2", - "postcss": "^8.4.13", - "resolve": "^1.22.0", - "rollup": "^2.59.0" - } - }, - "vite-plugin-top-level-await": { - "version": "1.1.1", - "resolved": "https://registry.npmmirror.com/vite-plugin-top-level-await/-/vite-plugin-top-level-await-1.1.1.tgz", - "integrity": "sha512-il7YijMxjvQxx33I/mf5n+xUJscxcTqRSwPGck/jw92hUyGwjsJnIBYBcKRS+vhOtsJ5g+8xANoBEKx9G1NSEQ==", - "dev": true, - "requires": { - "@swc/core": "^1.2.147" - } - }, - "vooks": { - "version": "0.2.12", - "resolved": "https://registry.npmmirror.com/vooks/-/vooks-0.2.12.tgz", - "integrity": "sha512-iox0I3RZzxtKlcgYaStQYKEzWWGAduMmq+jS7OrNdQo1FgGfPMubGL3uGHOU9n97NIvfFDBGnpSvkWyb/NSn/Q==", - "requires": { - "evtd": "^0.2.2" - } - }, - "vue": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.37.tgz", - "integrity": "sha512-bOKEZxrm8Eh+fveCqS1/NkG/n6aMidsI6hahas7pa0w/l7jkbssJVsRhVDs07IdDq7h9KHswZOgItnwJAgtVtQ==", - "requires": { - "@vue/compiler-dom": "3.2.37", - "@vue/compiler-sfc": "3.2.37", - "@vue/runtime-dom": "3.2.37", - "@vue/server-renderer": "3.2.37", - "@vue/shared": "3.2.37" - } - }, - "vue-clipboard3": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/vue-clipboard3/-/vue-clipboard3-2.0.0.tgz", - "integrity": "sha512-Q9S7dzWGax7LN5iiSPcu/K1GGm2gcBBlYwmMsUc5/16N6w90cbKow3FnPmPs95sungns4yvd9/+JhbAznECS2A==", - "requires": { - "clipboard": "^2.0.6" - } - }, - "vue-codemirror": { - "version": "6.1.1", - "resolved": "https://registry.npmmirror.com/vue-codemirror/-/vue-codemirror-6.1.1.tgz", - "integrity": "sha512-rTAYo44owd282yVxKtJtnOi7ERAcXTeviwoPXjIc6K/IQYUsoDkzPvw/JDFtSP6T7Cz/2g3EHaEyeyaQCKoDMg==", - "requires": { - "@codemirror/commands": "6.x", - "@codemirror/language": "6.x", - "@codemirror/state": "6.x", - "@codemirror/view": "6.x" - } - }, - "vue-eslint-parser": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.0.3.tgz", - "integrity": "sha512-yL+ZDb+9T0ELG4VIFo/2anAOz8SvBdlqEnQnvJ3M7Scq56DvtjY0VY88bByRZB0D4J0u8olBcfrXTVONXsh4og==", - "dev": true, - "requires": { - "debug": "^4.3.4", - "eslint-scope": "^7.1.1", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", - "esquery": "^1.4.0", - "lodash": "^4.17.21", - "semver": "^7.3.6" - }, - "dependencies": { - "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "vue-grid-layout": { - "version": "3.0.0-beta1", - "resolved": "https://registry.npmjs.org/vue-grid-layout/-/vue-grid-layout-3.0.0-beta1.tgz", - "integrity": "sha512-MsW0yfYNtnAO/uDhfZvkP6effxSJxvhAFbIL37x6Rn3vW9xf0WHVefKaSbQMLpSq3mXnR6ut0pg2Cd5lqIIZzg==", - "requires": { - "@interactjs/actions": "^1.10.2", - "@interactjs/auto-start": "^1.10.2", - "@interactjs/dev-tools": "^1.10.2", - "@interactjs/interactjs": "^1.10.2", - "@interactjs/modifiers": "^1.10.2", - "element-resize-detector": "^1.2.1", - "mitt": "^2.1.0" - }, - "dependencies": { - "mitt": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-2.1.0.tgz", - "integrity": "sha512-ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg==" - } - } - }, - "vue-i18n": { - "version": "9.1.10", - "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.1.10.tgz", - "integrity": "sha512-jpr7gV5KPk4n+sSPdpZT8Qx3XzTcNDWffRlHV/cT2NUyEf+sEgTTmLvnBAibjOFJ0zsUyZlVTAWH5DDnYep+1g==", - "requires": { - "@intlify/core-base": "9.1.10", - "@intlify/shared": "9.1.10", - "@intlify/vue-devtools": "9.1.10", - "@vue/devtools-api": "^6.0.0-beta.7" - } - }, - "vue-router": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.1.2.tgz", - "integrity": "sha512-5BP1qXFncVRwgV/XnqzsKApdMjQPqWIpoUBdL1ynz8HyLxIX/UDAx7Ql2BjmA5CXT/p61JfZvkpiFWFpaqcfag==", - "requires": { - "@vue/devtools-api": "^6.1.4" - } - }, - "vueuc": { - "version": "0.4.51", - "resolved": "https://registry.npmmirror.com/vueuc/-/vueuc-0.4.51.tgz", - "integrity": "sha512-pLiMChM4f+W8czlIClGvGBYo656lc2Y0/mXFSCydcSmnCR1izlKPGMgiYBGjbY9FDkFG8a2HEVz7t0DNzBWbDw==", - "requires": { - "@css-render/vue3-ssr": "^0.15.10", - "@juggle/resize-observer": "^3.3.1", - "css-render": "^0.15.10", - "evtd": "^0.2.4", - "seemly": "^0.3.6", - "vdirs": "^0.1.4", - "vooks": "^0.2.4" - } - }, - "w3c-keyname": { - "version": "2.2.6", - "resolved": "https://registry.npmmirror.com/w3c-keyname/-/w3c-keyname-2.2.6.tgz", - "integrity": "sha512-f+fciywl1SJEniZHD6H+kUO8gOnwIr7f4ijKA6+ZvJFjeGi1r4PDLl53Ayud9O/rk64RqgoQine0feoeOU0kXg==" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wildcard": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-1.1.2.tgz", - "integrity": "sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng==" - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "xml-name-validator": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", - "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "zrender": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.3.2.tgz", - "integrity": "sha512-8IiYdfwHj2rx0UeIGZGGU4WEVSDEdeVCaIg/fomejg1Xu6OifAL1GVzIPHg2D+MyUkbNgPWji90t0a8IDk+39w==", - "requires": { - "tslib": "2.3.0" - } - } - } -} diff --git a/tg-web/package.json b/tg-web/package.json deleted file mode 100644 index d2089fbd4ef194ae721d85b7d3af570a77e49f71..0000000000000000000000000000000000000000 --- a/tg-web/package.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "name": "vue-next-admin", - "version": "2.2.0", - "description": "vue3 vite next admin template", - "author": "lyt_20201208", - "license": "MIT", - "scripts": { - "dev": "vite --force", - "build": "vite build", - "lint-fix": "eslint --fix --ext .js --ext .jsx --ext .vue src/" - }, - "dependencies": { - "@antv/g6": "^4.8.8", - "@antv/layout": "^0.3.17", - "@antv/x6": "^2.9.4", - "@codemirror/lang-javascript": "^6.1.4", - "@codemirror/theme-one-dark": "^6.1.1", - "@element-plus/icons-vue": "^2.0.9", - "@vicons/ionicons5": "^0.12.0", - "@wangeditor/editor": "^5.1.11", - "axios": "^0.27.2", - "codemirror": "^6.0.1", - "countup.js": "^2.3.2", - "cropperjs": "^1.5.12", - "echarts": "^5.3.3", - "echarts-gl": "^2.0.9", - "echarts-wordcloud": "^2.0.0", - "element-plus": "^2.2.9", - "insert-css": "^2.0.0", - "js-cookie": "^3.0.1", - "jsplumb": "^2.15.6", - "jszip": "^3.10.0", - "less": "^4.1.3", - "less-loader": "^11.1.0", - "mitt": "^3.0.0", - "naive-ui": "^2.34.3", - "normalize.css": "^7.0.0", - "nprogress": "^0.2.0", - "pinia": "^2.0.16", - "print-js": "^1.6.0", - "qrcodejs2-fixes": "^0.0.2", - "query-string": "^7.1.1", - "screenfull": "^6.0.2", - "sortablejs": "^1.15.0", - "splitpanes": "^3.1.1", - "vue": "^3.2.37", - "vue-clipboard3": "^2.0.0", - "vue-codemirror": "^6.1.1", - "vue-grid-layout": "^3.0.0-beta1", - "vue-i18n": "^9.1.10", - "vue-router": "^4.1.2" - }, - "devDependencies": { - "@types/insert-css": "^2.0.1", - "@types/node": "^18.0.6", - "@types/nprogress": "^0.2.0", - "@types/sortablejs": "^1.13.0", - "@typescript-eslint/eslint-plugin": "^5.30.7", - "@typescript-eslint/parser": "^5.30.7", - "@vitejs/plugin-vue": "^2.3.3", - "@vue/compiler-sfc": "^3.2.37", - "dotenv": "^16.0.1", - "eslint": "^8.20.0", - "eslint-plugin-vue": "^9.2.0", - "prettier": "^2.7.1", - "sass": "^1.53.0", - "sass-loader": "^13.0.2", - "typescript": "^4.7.4", - "vite": "^2.9.14", - "vite-plugin-top-level-await": "^1.1.1", - "vue-eslint-parser": "^9.0.3" - }, - "browserslist": [ - "> 1%", - "last 2 versions", - "not dead" - ], - "bugs": { - "url": "https://gitee.com/lyt-top/vue-next-admin/issues" - }, - "engines": { - "node": ">=12.0.0", - "npm": ">= 6.0.0" - }, - "keywords": [ - "vue", - "vue3", - "vuejs/vue-next", - "element-ui", - "element-plus", - "vue-next-admin", - "next-admin" - ], - "repository": { - "type": "git", - "url": "https://gitee.com/lyt-top/vue-next-admin.git" - } -} diff --git a/tg-web/plugins.d.ts b/tg-web/plugins.d.ts deleted file mode 100644 index be0457a51810044003d6779a27dc717934b23f43..0000000000000000000000000000000000000000 --- a/tg-web/plugins.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare module 'vue-grid-layout'; -declare module 'qrcodejs2-fixes'; -declare module 'splitpanes'; -declare module 'js-cookie'; diff --git a/tg-web/server.conf b/tg-web/server.conf deleted file mode 100644 index 45b7fcf383043b6addf0479bc1a596d761ff287d..0000000000000000000000000000000000000000 --- a/tg-web/server.conf +++ /dev/null @@ -1,8 +0,0 @@ -server { - listen 8080; - root /home/tg-flow/dist; - - location / { - index index.html; - } -} \ No newline at end of file diff --git a/tg-web/shim.d.ts b/tg-web/shim.d.ts deleted file mode 100644 index b7d1ffe011fcd1da7ee41441ce70508e1a0df201..0000000000000000000000000000000000000000 --- a/tg-web/shim.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* eslint-disable */ - -// 声明文件,*.vue 后缀的文件交给 vue 模块来处理 -declare module '*.vue' { - import type { DefineComponent } from 'vue'; - const component: DefineComponent<{}, {}, any>; - export default component; -} - -// 声明文件,定义全局变量。其它 app.config.globalProperties.xxx,使用 getCurrentInstance() 来获取 -interface Window { - nextLoading: boolean; - userInfo: any -} diff --git a/tg-web/source.d.ts b/tg-web/source.d.ts deleted file mode 100644 index 2f9c7682b27fc2b085a2a33ba926bec9fedd2e89..0000000000000000000000000000000000000000 --- a/tg-web/source.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare module '*.json'; -declare module '*.png'; -declare module '*.jpg'; -declare module '*.scss'; -declare module '*.ts'; -declare module '*.js'; diff --git a/tg-web/src/App.vue b/tg-web/src/App.vue deleted file mode 100644 index abee6fb2bc02049d0c72e6f3a10ead82bead96a0..0000000000000000000000000000000000000000 --- a/tg-web/src/App.vue +++ /dev/null @@ -1,122 +0,0 @@ - - - diff --git a/tg-web/src/api/request.ts b/tg-web/src/api/request.ts deleted file mode 100644 index e3a89f05ea99d7c7d9cd0f0986a00ebc56a95d7b..0000000000000000000000000000000000000000 --- a/tg-web/src/api/request.ts +++ /dev/null @@ -1,42 +0,0 @@ -import axios from "axios"; -import qs from "query-string"; - -// axios.defaults.baseURL = "/api"; -// axios的封装 -export async function request( - path: string, - params: object, - method: string, - type?: number -) { - let content = "x-www-form-urlencoded"; - let data = qs.stringify(params); - if (type === 1) { - content = "json"; - data = JSON.stringify(params); - } - try { - const serve = await axios({ - method, - url: path, - withCredentials: true, - headers: { - "Content-Type": `application/${content}`, - }, - data, - }); - if (serve.data) { - return serve.data as T; - } else { - return null; - } - } catch (err: any) { - if (err.response.status === 302 || err.response.status === 301) { - // TODO 登录认证 - window.location.replace("/main"); - } - return null; - } -} - -export default request; diff --git a/tg-web/src/api/strategy/index.ts b/tg-web/src/api/strategy/index.ts deleted file mode 100644 index 5ed877ae88cbddb871e2b82d03b4aaf63a48eca9..0000000000000000000000000000000000000000 --- a/tg-web/src/api/strategy/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './services' -export * from './types' -export * from './utils' \ No newline at end of file diff --git a/tg-web/src/api/strategy/services.ts b/tg-web/src/api/strategy/services.ts deleted file mode 100644 index 4fd5e25b8e1e29e6cddb9df1ba7159ebab1f042a..0000000000000000000000000000000000000000 --- a/tg-web/src/api/strategy/services.ts +++ /dev/null @@ -1,401 +0,0 @@ -import request from "@/api/request"; -import { - addOrUpdateWorkFlow, - deleteWorkflowI, - experimentConfigResI, - experimentHistoryVersionI, - experimentHistoryVersionParamsI, - experimentRollHistoryVersionParamsI, - experimentWorkflowNodeTypeResI, - FlowChartParamsI, - FlowChartResI, GetApolloResI, - getExperimentConfigDimensionResI, - getExperimentConfigParamsI, - globalConfigBaseContentNullI, - globalConfigBaseContentStringI, - ModuleBranchRequestI, ModuleBranchRespI, ModulesRequestI, ModulesResI, - operatorAndId, - OperatorI, - scenesConfigAppnameI, - ScenesConfigI, - scenesConfigNameI, - ScenesConfigUpdateI, - SystemConfigI, - SystemConfigUpdateI, -} from "./types"; -import { - experimentAppname, - filterData, - scenesSelectAppName, - scenesSelectName -} from "./utils"; - -export async function getWorkFlowChartByFlowIdV2(params: FlowChartParamsI) { - const res = await request( - "/api/exportWorkFlow", - params, - "POST" - ); - if (res) { - if (res.content) { - return JSON.parse(res.content); - } else { - return ""; - } - } else { - return ""; - } -} - -// 拿取系统管理中的数据 -export async function getSystemConfig(params: OperatorI) { - const res = await request( - "/api/searchAppConfig", - params, - "POST" - ); - if (res?.tag) { - return res?.content; - } - return res?.err_msg; -} - -// 更新系统管理中的数据 -export async function updateSystemConfig(params: SystemConfigUpdateI) { - const res = await request( - "/api/addOrUpdateAppConfig", - params, - "POST" - ); - if (res?.tag) { - return res; - } - return null; -} - -// 删除系统管理中的数据 -export async function deleteSystemConfig(params: operatorAndId) { - const res = await request( - "/api/deleteAppConfig", - params, - "POST" - ); - if (res?.tag) { - return res; - } - return res?.err_msg; -} - -// 导出系统管理中的部分数据 -export async function exportSystemConfig(params: operatorAndId) { - const res = await request( - "/api/exportAppConfig", - params, - "POST" - ); - if (res?.tag) { - return res; - } - return res?.err_msg; -} - -// 提交系统管理中的数据到 Apollo -export async function commitSystemConfig(params: operatorAndId, is_kflower: boolean) { - return await request( - "/api/submitAppConfig", - { - ...params, - is_kflower, - }, - "POST" - ) -} - -// 查询系统对应的 Apollo 的状态 -export async function getApolloInfo(params: operatorAndId, is_kflower: boolean) { - return await request( - "/api/getApolloInfo", - { - ...params, - is_kflower, - }, - "POST" - ) -} - - -// 添加系统管理中的数据 -export async function addSystemConfig(params: SystemConfigUpdateI) { - const res = await request( - "/api/addOrUpdateAppConfig", - params, - "POST" - ); - if (res?.tag) { - return res; - } - return res?.err_msg; -} - -// 拿到场景管理中的数据 -export async function getScenesConfig(params: OperatorI) { - const res = await request("/api/searchScene", params, "POST"); - if (res?.tag) { - return res["content"]; - } - return []; -} - -// 获取模块数据 -export async function getAppModules(params: ModulesRequestI) { - const res = await request("/api/getAppModules", params, "POST"); - if (res?.tag) { - return res["content"]; - } - return {}; -} - -// 查询系统对应分支信息 -export async function getGitBranches(params: ModuleBranchRequestI) { - const res = await request("/api/getGitBranches", params, "POST"); - if (res?.tag) { - return res["content"]; - } - return []; -} - -// 修改场景管理中的数据 -export async function updateScenesConfig(params: ScenesConfigUpdateI) { - const res = await request( - "/api/addOrUpdateScene", - params, - "POST" - ); - if (res?.tag) { - return true; - } - return res?.err_msg; -} - -// 删除场景管理中的数据 -export async function deleteScenesConfig(params: operatorAndId) { - const res = await request( - "/api/deleteScene", - params, - "POST" - ); - return !!res?.tag; - -} - -// 新增场景管理中的数据 -export async function addScenesConfig(params: ScenesConfigUpdateI) { - const res = await request( - "/api/addOrUpdateScene", - params, - "POST" - ); - if (res?.tag) { - return true; - } - return res?.err_msg; -} - -// 拿到场景管理中的系统名称数据 -export async function getScenesConfigAppname(params: OperatorI) { - const res = await request( - "/api/autoGetAPPNameMenu", - params, - "POST" - ); - if (res?.tag) { - return scenesSelectAppName(res["content"]); - } - return res?.err_msg; -} - -//拿到场景管理中的场景名称数据 -export async function getScenesConfigName(params: OperatorI) { - const res = await request( - "/api/autoGetSceneMenu", - params, - "POST" - ); - if (res?.tag) { - return scenesSelectName(res["content"]); - } - return res?.err_msg; -} - -// 拿到实验管理中的数据 -export async function getExperimentConfig(params: getExperimentConfigParamsI) { - const res = await request( - "/api/searchWorkFlow", - params, - "POST" - ); - if (res) { - if (res.tag) { - return res["content"]; - } else return res.err_msg; - } else { - return null; - } -} - -// 拿到实验管理中的scenes -export async function getExperimentScenes(types: number) { - const res = await request( - "/api/autoGetSceneMenu", - { - types, - }, - "POST" - ); - if (res?.tag) { - return scenesSelectName(res["content"]); - } - return res?.err_msg; -} - -// 拿到实验管理中的Appname -export async function getExperimentConfigAppname() { - const res = await request( - "/api/autoGetAPPNameMenu", - {}, - "POST" - ); - if (res?.tag) { - return experimentAppname(res["content"]); - } - return res?.err_msg; -} - -// 拿到实验管理中的DimensionMenu -export async function getExperimentConfigDimension(scene_name: string) { - const res = await request( - "/api/autoGetDimensionMenu", - { scene_name }, - "POST" - ); - if (res?.tag) { - return res["content"]; - } - return res?.err_msg; -} - -// 刷新实验管理中的NodeType -export async function refreshExperimentConfigNodeType(params:any) { - const res = await request( - "/api/setNodeTypeList", - params, - "POST" - ); - if (res?.tag) { - return true; - } - return res?.err_msg; -} - -// 复制实验管理中具体某个场景下的某一项 -export async function addOrUpdateWorkflow(params: addOrUpdateWorkFlow) { - const res = await request( - "/api/addOrUpdateWorkFlow", - params, - "POST" - ); - if (res) { - if (res.tag) { - return res.tag; - } else { - return res.err_msg; - } - } else { - return null; - } -} - -export async function updateWorkflowV2(params: addOrUpdateWorkFlow) { - const res = await request( - "/api/importWorkFlow", - params, - "POST" - ); - if (res) { - if (res.tag) { - return res.tag; - } else { - return res.err_msg; - } - } else { - return null; - } -} - -// 删除实验管理中具体某个场景下的某一项 -export async function deleteWorkflowData(params:deleteWorkflowI) { - const res = await request("/api/deleteWorkFlow",params,"POST") - if (res) { - if (res.tag) { - return res.tag; - } else { - return res.err_msg; - } - } else { - return null; - } -} - -// 拿到某个场景下的历史版本 -export async function getScenesHistoryVersion(params:experimentHistoryVersionParamsI) { - const res = await request("/api/searchWorkflowVersion",params,"POST") - if (res) { - if (res.tag) { - return filterData(res["content"]); - } else return res.err_msg; - } else { - return null; - } -} - -// 回滚到某个场景下的历史版本 -export async function backToHistoryVersion(params:experimentRollHistoryVersionParamsI) { - const res = await request("/api/rollBackWorkFlow",params,"POST") - if (res) { - if (res.tag) { - return res.tag; - } else { - return res.err_msg; - } - } else { - return null; - } -} - -// 导出实验管理中的某条数据 -export async function exportexperimentConfig(params:{operator:string,workflowid:string}){ - const res = await request("/api/exportWorkFlow",params,"POST") - if (res?.tag) { - return res['content']; - } - return res?.err_msg; -} - -// 导入实验管理workflow Json数据 -export async function requireWorkflowConfig(params:{workflowid:number,dataJson:string}){ - const res = await request('/api/importWorkFlow',params,"POST") - if (res?.tag) { - return true; - } - return res?.err_msg; -} - -//拿到实验管理中的nodetype -export async function getExperimentWorkflowNodeType(params:FlowChartParamsI){ - const res = await request("/api/getNodeTypeList",params,"POST") - if(res){ - return res['content'] - }else{ - return null - } -} diff --git a/tg-web/src/api/strategy/types.ts b/tg-web/src/api/strategy/types.ts deleted file mode 100644 index f164696d4b03159328c9f7f692490f45126d536b..0000000000000000000000000000000000000000 --- a/tg-web/src/api/strategy/types.ts +++ /dev/null @@ -1,221 +0,0 @@ -export interface OperatorI { - operator: string; -} -interface globalConfigBaseI { - err_msg: string; - tag: boolean; - typenum: number; -} - -export interface globalConfigBaseContentStringI extends globalConfigBaseI { - content: string; -} -interface ApolloNamespaceI { - id: number, -} - -interface ApolloServiceI { - id: number, - appId: number, -} - -interface ApolloResponseI { - id: number, - services: Array, - namespace: ApolloNamespaceI, - configStatus: string, -} - -export interface GetApolloResI extends globalConfigBaseI { - content: ApolloResponseI -} -export interface FlowChartParamsI extends OperatorI { - workflowid?: number; - scene_name?: string; -} - -export interface FlowChartResI extends globalConfigBaseI { - content: string | null -} - -// nodes: {label: string; id: string ...} -export interface SystemConfigI extends globalConfigBaseI { - content: Array -} - -export interface SystemConfigContentI extends SystemConfigUpdateI, createAndUpdate { -} - -export interface SystemConfigUpdateI extends operatorAndId { - app_name: string; - node_name: string; - old_id?: number; - machine_room: string; - git_url: string; -} - -export interface operatorAndId { - operator: string; - id: number; -} - -export interface ScenesConfigI extends globalConfigBaseI { - content: Array -} - -interface createAndUpdate { - create_time: string; - update_time: string; -} - -export interface ScenesConfigContentI extends ScenesConfigUpdateI { - appid: number; - bifrost_config: string; - createtime: string; - namezh: string; - updatetime: string; -} - -// ==================== Modules ==================== - -export interface ModulesRequestI extends OperatorI { - app_name: string, - project_branch: string, -} - -export interface ModulesContentI { - name: string, - type: string, - desc: string, - workflow_list: Array - scene_list: Array - create_time: string, -} - -export interface ModulesResI extends globalConfigBaseI { - content: Record> -} - -export interface ModuleBranchRequestI extends OperatorI { - app_name: string, -} - -export interface ModuleBranchRespI extends globalConfigBaseI { - content: Array -} - - -export interface ScenesConfigUpdateI { - oldid?: number; - operator: string; - id: number; - name: string; - appname: string; - expname: string; - buckettype: number; - flow_type: number; -} - -export interface globalConfigBaseContentNullI extends globalConfigBaseI { - content: null; -} -export interface scenesConfigAppnameI extends globalConfigBaseI { - content: Array -} - -export interface scenesConfigAppnameContentI { - AppId: string; - AppName: string; -} - -export interface scenesConfigNameContentI { - SceneId: string; - SceneName: string; -} - -export interface scenesConfigNameI extends globalConfigBaseI { - content: Array; -} -export interface getExperimentConfigParamsI extends OperatorI { - dimension_id: string; - scenename: string; -} - -export interface getExperimentConfigDimensionResI extends globalConfigBaseI { - content: Array; -} - -export interface getExperimentConfigDimensionResContentI { - DimensionId: string; - DimensionName: string; -} -export interface experimentConfigResI extends globalConfigBaseI { - content: Array -} - -export interface experimentConfigResContentI extends OperatorI { - configured: boolean; - createtime: string; - updatetime: string; - defult: string; - dimension_id: number; - groupname: string; - manual_slot_ids: string; - modules: string; - oldworkflowid: string; - proportion: string; - range1: string; - range2: string; - remark: string; - scene_id: number; - scenename: string; - showmodules: string; - workflowid: string; -} - -export interface addOrUpdateWorkFlow extends deleteWorkflowI { - oldworkflowid: string; - modules: string; - proportion: number; - defult: number; - remark: string; - dataJson?: string; -} - -export interface deleteWorkflowI extends experimentHistoryVersionParamsI { - workflowid: string; -} - -export interface experimentHistoryVersionI extends globalConfigBaseI { - content: Array; -} - -export interface experimentHistoryVersionParamsI extends OperatorI { - scenename: string; - dimension_id: number; -} - -export interface experimentHistoryVersionResI extends OperatorI, experimentHistoryVersionResFilterI { - scenename: string; -} - -export interface experimentHistoryVersionResFilterI { - dimension_id: number; - version_create_time: string; - version_id: number; -} - -export interface experimentRollHistoryVersionParamsI extends OperatorI { - version_id: number; - dimension_id: number; - scene_name: string; -} - -export interface experimentWorkflowNodeTypeResI extends globalConfigBaseI { - content: Array; -} - -export interface experimentWorkflowNodeTypeResContentI { - node_name: string[]; - node_type: string; -} diff --git a/tg-web/src/api/strategy/utils.ts b/tg-web/src/api/strategy/utils.ts deleted file mode 100644 index f56fdbf1d9508f92057816a5b9d62c7845e4043e..0000000000000000000000000000000000000000 --- a/tg-web/src/api/strategy/utils.ts +++ /dev/null @@ -1,115 +0,0 @@ -interface VauleAndLabelI { - value: string; - label: string; -} - -import { - scenesConfigAppnameContentI, - scenesConfigNameContentI, - experimentHistoryVersionResFilterI, - experimentHistoryVersionResI, -} from "./types"; -export function getTime(params: number): number { - let date = new Date(params * 1000); - return Number( - `${date.getFullYear()}${ - date.getMonth() + 1 < 10 - ? "0" + (date.getMonth() + 1) - : date.getMonth() + 1 - }${date.getDate() < 10 ? "0" + date.getDate() : date.getDate()}${ - date.getHours() < 10 ? "0" + date.getHours() : date.getHours() - }${date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()}${ - date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds() - }` - ); -} - -export function scenesSelectAppName( - params: Array -): Array { - const arr: Array = []; - params.forEach((p) => { - arr.push({ - label: p.AppName, - value: p.AppName, - }); - }); - arr.shift(); - return arr; -} - -export function scenesSelectName( - params: Array -): Array { - const arr: Array = []; - params.forEach((p) => { - arr.push({ - label: p.SceneName, - value: p.SceneName, - }); - }); - return arr; -} - -export function experimentAppname( - params: Array -): Array { - const arr: Array = []; - params.forEach((p) => { - arr.push({ - label: p.AppName, - value: p.AppId, - }); - }); - return arr; -} - -export function filterData( - params: Array -) :Array { - return params.map((p) => { - return { - dimension_id:p.dimension_id, - version_create_time:p.version_create_time, - version_id:p.version_id - } - }) -} - -export function algoName(params: any): Array{ - const arr: Array = []; - params.forEach((p : any) => { - if(p.AlgoName){ - arr.push({ - label:p.AlgoName, - value:p.AlgoName - }) - } - }); - return arr -} - -export function modelName(params:any[]): Array{ - const arr: Array = []; - params.forEach((p : any) => { - if(p.ModelName){ - arr.push({ - label:p.ModelName, - value:p.ModelName - }) - } - }); - return arr -} -export function appName(params:Object[]): Array{ - const arr: Array = []; - params.forEach((p : any) => { - if(p.AppName){ - arr.push({ - label:p.AppName, - value:p.AppId - }) - } - }); - return arr -} diff --git a/tg-web/src/components/g6/flow.vue b/tg-web/src/components/g6/flow.vue deleted file mode 100644 index d7154f0302e8a0c59e4d4830a0d1b5c7795c45a8..0000000000000000000000000000000000000000 --- a/tg-web/src/components/g6/flow.vue +++ /dev/null @@ -1,255 +0,0 @@ - - - diff --git a/tg-web/src/components/g6/g6.ts b/tg-web/src/components/g6/g6.ts deleted file mode 100644 index d465dc8c4c662ff659ba8ec7cc506e97a5ef912a..0000000000000000000000000000000000000000 --- a/tg-web/src/components/g6/g6.ts +++ /dev/null @@ -1,1158 +0,0 @@ -import G6 from '@antv/g6'; -import insertCss from 'insert-css'; - -insertCss(` - .g6-component-toolbar li { - list-style-type: none !important; - } - .g6-minimap-container { - border: 1px solid #e2e2e2; - } - .g6-minimap-viewport { - border: 2px solid rgb(25, 128, 255); - } -`); - -const ICON_MAP = { - a: 'https://gw.alipayobjects.com/mdn/rms_8fd2eb/afts/img/A*0HC-SawWYUoAAAAAAAAAAABkARQnAQ', - b: 'https://gw.alipayobjects.com/mdn/rms_8fd2eb/afts/img/A*sxK0RJ1UhNkAAAAAAAAAAABkARQnAQ', -}; -const color = '#5B8FF9'; - -function drawRect(cfg: any, group: any) { - // console.log(cfg) - const r = 2; - const width = 150 - const shape = group.addShape('rect', { - attrs: { - x: 0, - y: 0, - width, - height: 60, - stroke: color, - radius: r, - cursor: 'move', - anchorPoints: [ - [0, 0.5], - [1, 0.5], - ], - }, - // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type - name: 'main-box', - draggable: true, - }); - - group.addShape('rect', { - attrs: { - x: 0, - y: 0, - width, - height: 30, - fill: color, - radius: [r, r, 0, 0], - cursor: 'move', - }, - // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type - name: 'title-box', - draggable: true, - }); - - // left icon - group.addShape('image', { - attrs: { - x: 4, - y: 7, - height: 16, - width: 16, - cursor: 'pointer', - img: ICON_MAP['a'], - }, - // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type - name: 'node-icon', - }); - - // title text - group.addShape('text', { - attrs: { - textBaseline: 'top', - y: 9, - x: 24, - lineHeight: 20, - fontSize: 12, - fontWeight: 500, - text: 'ID:' + cfg.id, - fill: '#fff', - cursor: 'pointer', - }, - // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type - name: 'title', - }); - - // The content list - // name text - group.addShape('text', { - attrs: { - textBaseline: 'top', - y: 40, - x: 10, - lineHeight: 20, - fontSize: 12, - text: fittingString(cfg.label, 130, 12), - fill: 'rgba(0,0,0, 0.4)', - cursor: 'pointer', - }, - // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type - name: `desc`, - }); - return shape -} - -function drawTimeout(cfg: any, group: any) { - const r = 2; - const width = 150 - const shape = group.addShape('rect', { - attrs: { - x: 0, - y: 0, - width, - height: 60, - stroke: color, - radius: r, - anchorPoints: [ - [0, 0.5], - [1, 0.5], - ], - }, - // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type - name: 'main-box', - draggable: true, - }); - - group.addShape('rect', { - attrs: { - x: 0, - y: 0, - width, - height: 30, - fill: color, - radius: [r, r, 0, 0], - }, - // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type - name: 'title-box', - draggable: true, - }); - - // left icon - group.addShape('image', { - attrs: { - x: 4, - y: 7, - height: 16, - width: 16, - cursor: 'pointer', - img: ICON_MAP['a'], - }, - // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type - name: 'node-icon', - }); - - // title text - group.addShape('text', { - attrs: { - textBaseline: 'top', - y: 9, - x: 24, - lineHeight: 20, - fontSize: 12, - fontWeight: 500, - text: 'ID:' + cfg.id, - fill: '#fff', - }, - // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type - name: 'title', - }); - - // The content list - // name text - group.addShape('text', { - attrs: { - textBaseline: 'top', - y: 40, - x: 10, - lineHeight: 20, - fontSize: 12, - text: fittingString(cfg.label, 130, 12), - fill: '#666', - }, - // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type - name: `desc`, - }); - return shape -} - -function drawCondition(cfg: any, group: any) { - const width = 80 - const shape = group.addShape('polygon', { - attrs: { - points: [ - [40, 0], - [0, 30], - [40, 60], - [80, 30], - ], - stroke: color, - fill: color, - cursor: 'move', - anchorPoints: [ - [0, 0.5], - [1, 0.5], - ], - }, - // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type - name: 'main-box', - draggable: true, - }); - group.addShape('text', { - attrs: { - textBaseline: 'top', - y: 25, - x: 32, - lineHeight: 20, - fontSize: 12, - fontWeight: 500, - text: cfg.label, - fill: '#fff', - cursor: 'pointer', - }, - // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type - name: 'title', - }); - return shape -} - -function drawFlow(cfg: any, group: any) { - const shape = group.addShape('circle', { - attrs: { - x: 0, - y: 0, - r: 50, - stroke: color, - cursor: 'move', - fill: color, - anchorPoints: [ - [0, 0.5], - [1, 0.5], - ], - }, - // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type - name: 'main-box', - draggable: true, - }); - group.addShape('text', { - attrs: { - textBaseline: 'middle', - lineHeight: 20, - fontSize: 12, - fontWeight: 500, - textAlign: 'center', - text: cfg.label, - fill: '#fff', - cursor: 'pointer', - }, - // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type - name: 'title', - }); - return shape -} - -G6.registerNode( - 'timeout', - { - draw: function drawShape(cfg: any, group: any) { - return drawTimeout(cfg, group) - }, - afterDraw(cfg, group) { - const bbox = group.getBBox(); - const anchorPoints = this.getAnchorPoints(cfg) - anchorPoints.forEach((anchorPos, i) => { - group.addShape('circle', { - attrs: { - r: 5, - x: bbox.x + bbox.width * anchorPos[0], - y: bbox.y + bbox.height * anchorPos[1], - fill: '#fff', - stroke: '#5F95FF' - }, - // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type - name: `anchor-point`, // the name, for searching by group.find(ele => ele.get('name') === 'anchor-point') - anchorPointIdx: i, // flag the idx of the anchor-point circle - links: 0, // cache the number of edges connected to this shape - visible: false, // invisible by default, shows up when links > 1 or the node is in showAnchors state - draggable: true // allow to catch the drag events on this shape - }) - }) - }, - getAnchorPoints(cfg) { - return cfg.anchorPoints || [[0, 0.5], [0.33, 0], [0.66, 0], [1, 0.5], [0.33, 1], [0.66, 1]]; - }, - // update: function drawShape(cfg: any, item: any) { - // console.log('---',cfg, item) - // item.label = cfg.label - // } - setState(name, value, item) { - const group = item!.getContainer(); - if (name === 'selected') { - const box = group.find((element) => element.get('name') === 'main-box'); - const lineWidth = value ? 2 : 1 - box.attr('lineWidth', lineWidth) - } - if (name === 'showAnchors') { - const anchorPoints = item.getContainer().findAll(ele => ele.get('name') === 'anchor-point'); - anchorPoints.forEach(point => { - if (value || point.get('links') > 0) point.show() - else point.hide() - }) - } - } - }, -); - -G6.registerNode( - 'task', - { - draw: function drawShape(cfg: any, group: any) { - return drawRect(cfg, group) - }, - afterDraw(cfg, group) { - const bbox = group.getBBox(); - const anchorPoints = this.getAnchorPoints(cfg) - anchorPoints.forEach((anchorPos, i) => { - group.addShape('circle', { - attrs: { - r: 5, - x: bbox.x + bbox.width * anchorPos[0], - y: bbox.y + bbox.height * anchorPos[1], - fill: '#fff', - stroke: '#5F95FF' - }, - // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type - name: `anchor-point`, // the name, for searching by group.find(ele => ele.get('name') === 'anchor-point') - anchorPointIdx: i, // flag the idx of the anchor-point circle - links: 0, // cache the number of edges connected to this shape - visible: false, // invisible by default, shows up when links > 1 or the node is in showAnchors state - draggable: true // allow to catch the drag events on this shape - }) - }) - }, - getAnchorPoints(cfg) { - return cfg.anchorPoints || [[0, 0.5], [0.33, 0], [0.66, 0], [1, 0.5], [0.33, 1], [0.66, 1]]; - }, - // update: function drawShape(cfg: any, item: any) { - // console.log('---',cfg, item) - // item.label = cfg.label - // } - setState(name, value, item) { - const group = item!.getContainer(); - if (name === 'selected') { - const box = group.find((element) => element.get('name') === 'main-box'); - const lineWidth = value ? 2 : 1 - box.attr('lineWidth', lineWidth) - } - if (name === 'showAnchors') { - const anchorPoints = item.getContainer().findAll(ele => ele.get('name') === 'anchor-point'); - anchorPoints.forEach(point => { - if (value || point.get('links') > 0) point.show() - else point.hide() - }) - } - } - }, -); - -G6.registerNode( - 'condition', - { - draw: function drawShape(cfg: any, group: any) { - return drawCondition(cfg, group) - }, - afterDraw(cfg, group) { - const bbox = group.getBBox(); - const anchorPoints = this.getAnchorPoints(cfg) - anchorPoints.forEach((anchorPos, i) => { - group.addShape('circle', { - attrs: { - r: 5, - x: bbox.x + bbox.width * anchorPos[0], - y: bbox.y + bbox.height * anchorPos[1], - fill: '#fff', - stroke: '#5F95FF' - }, - // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type - name: `anchor-point`, // the name, for searching by group.find(ele => ele.get('name') === 'anchor-point') - anchorPointIdx: i, // flag the idx of the anchor-point circle - links: 0, // cache the number of edges connected to this shape - visible: false, // invisible by default, shows up when links > 1 or the node is in showAnchors state - draggable: true // allow to catch the drag events on this shape - }) - }) - }, - getAnchorPoints(cfg) { - return cfg.anchorPoints || [[0, 0.5], [0.33, 0], [0.66, 0], [1, 0.5], [0.33, 1], [0.66, 1]]; - }, - // update: function drawShape(cfg: any, item: any) { - // console.log('---',cfg, item) - // item.label = cfg.label - // } - setState(name, value, item) { - const group = item!.getContainer(); - if (name === 'selected') { - const box = group.find((element) => element.get('name') === 'main-box'); - const lineWidth = value ? 2 : 1 - box.attr('lineWidth', lineWidth) - } - if (name === 'showAnchors') { - const anchorPoints = item.getContainer().findAll(ele => ele.get('name') === 'anchor-point'); - anchorPoints.forEach(point => { - if (value || point.get('links') > 0) point.show() - else point.hide() - }) - } - } - }, -); - -G6.registerNode( - 'flow', - { - draw: function drawShape(cfg: any, group: any) { - return drawFlow(cfg, group) - }, - afterDraw(cfg, group) { - const bbox = group.getBBox(); - const anchorPoints = this.getAnchorPoints(cfg) - anchorPoints.forEach((anchorPos, i) => { - group.addShape('circle', { - attrs: { - r: 5, - x: bbox.x + bbox.width * anchorPos[0], - y: bbox.y + bbox.height * anchorPos[1], - fill: '#fff', - stroke: '#5F95FF' - }, - // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type - name: `anchor-point`, // the name, for searching by group.find(ele => ele.get('name') === 'anchor-point') - anchorPointIdx: i, // flag the idx of the anchor-point circle - links: 0, // cache the number of edges connected to this shape - visible: false, // invisible by default, shows up when links > 1 or the node is in showAnchors state - draggable: true // allow to catch the drag events on this shape - }) - }) - }, - getAnchorPoints(cfg) { - return cfg.anchorPoints || [[0, 0.5], [0.33, 0], [0.66, 0], [1, 0.5], [0.33, 1], [0.66, 1]]; - }, - // update: function drawShape(cfg: any, item: any) { - // console.log('---',cfg, item) - // item.label = cfg.label - // } - setState(name, value, item) { - const group = item!.getContainer(); - if (name === 'selected') { - const box = group.find((element) => element.get('name') === 'main-box'); - const lineWidth = value ? 2 : 1 - box.attr('lineWidth', lineWidth) - } - if (name === 'showAnchors') { - const anchorPoints = item.getContainer().findAll(ele => ele.get('name') === 'anchor-point'); - anchorPoints.forEach(point => { - if (value || point.get('links') > 0) point.show() - else point.hide() - }) - } - } - }, -); - -G6.registerNode( - 'card-node', - { - draw: function drawShape(cfg: any, group: any) { - return drawRect(cfg, group) - }, - afterDraw(cfg, group) { - const bbox = group.getBBox(); - const anchorPoints = this.getAnchorPoints(cfg) - anchorPoints.forEach((anchorPos, i) => { - group.addShape('circle', { - attrs: { - r: 5, - x: bbox.x + bbox.width * anchorPos[0], - y: bbox.y + bbox.height * anchorPos[1], - fill: '#fff', - stroke: '#5F95FF' - }, - // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type - name: `anchor-point`, // the name, for searching by group.find(ele => ele.get('name') === 'anchor-point') - anchorPointIdx: i, // flag the idx of the anchor-point circle - links: 0, // cache the number of edges connected to this shape - visible: false, // invisible by default, shows up when links > 1 or the node is in showAnchors state - draggable: true // allow to catch the drag events on this shape - }) - }) - }, - getAnchorPoints(cfg) { - return cfg.anchorPoints || [[0, 0.5], [0.33, 0], [0.66, 0], [1, 0.5], [0.33, 1], [0.66, 1]]; - }, - // update: function drawShape(cfg: any, item: any) { - // console.log('---',cfg, item) - // item.label = cfg.label - // } - setState(name, value, item) { - const group = item!.getContainer(); - if (name === 'selected') { - const box = group.find((element) => element.get('name') === 'main-box'); - const lineWidth = value ? 2 : 1 - box.attr('lineWidth', lineWidth) - } - if (name === 'showAnchors') { - const anchorPoints = item.getContainer().findAll(ele => ele.get('name') === 'anchor-point'); - anchorPoints.forEach(point => { - if (value || point.get('links') > 0) point.show() - else point.hide() - }) - } - } - }, -); - -const collapseIcon = (x, y, r) => { - return [ - ['M', x - r, y], - ['a', r, r, 0, 1, 0, r * 2, 0], - ['a', r, r, 0, 1, 0, -r * 2, 0], - ['M', x - r + 4, y], - ['L', x - r + 2 * r - 4, y], - ]; -}; - -const expandIcon = (x, y, r) => { - return [ - ['M', x - r, y], - ['a', r, r, 0, 1, 0, r * 2, 0], - ['a', r, r, 0, 1, 0, -r * 2, 0], - ['M', x - r + 4, y], - ['L', x - r + 2 * r - 4, y], - ['M', x - r + r, y - r + 4], - ['L', x, y + r - 4], - ]; -}; - -G6.registerCombo( - 'cCircle', - { - drawShape: function draw(cfg, group) { - const self = this; - // Get the shape style, where the style.r corresponds to the R in the Illustration of Built-in Rect Combo - const style = self.getShapeStyle(cfg); - const circle = group.addShape('circle', { - attrs: { - ...style, - x: 0, - y: 0, - // r: 100, - r: style.r, - fill: '#fff', - // fill: '#000', - }, - draggable: true, - // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type - name: 'combo-keyShape', - }); - // Add the marker on the bottom - const marker = group.addShape('marker', { - attrs: { - ...style, - fill: '#fff', - // fill: '#000', - opacity: 1, - x: 0, - // y: 100, - y: style.r, - r: 10, - symbol: collapseIcon, - }, - draggable: true, - // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type - name: 'combo-marker-shape', - }); - - return circle; - }, - // Define the updating logic for the marker - afterUpdate: function afterUpdate(cfg, combo) { - const self = this; - // Get the shape style, where the style.r corresponds to the R in the Illustration of Built-in Rect Combo - const style = self.getShapeStyle(cfg); - const group = combo.get('group'); - // Find the marker shape in the graphics group of the Combo - const marker = group.find((ele) => ele.get('name') === 'combo-marker-shape'); - // Update the marker shape - marker.attr({ - x: 0, - y: style.r, - // The property 'collapsed' in the combo data represents the collapsing state of the Combo - // Update the symbol according to 'collapsed' - symbol: cfg.collapsed ? expandIcon : collapseIcon, - }); - }, - }, - 'circle', -); - -G6.registerCombo( - 'cRect', - { - drawShape: function draw(cfg, group) { - const self = this; - cfg.padding = cfg.padding || [3, 3, 3, 3]; - // Get the shape style, where the style.r corresponds to the R in the Illustration of Built-in Rect Combo - const style = self.getShapeStyle(cfg); - const rect = group.addShape('rect', { - attrs: { - ...style, - x: - (cfg.padding[3] - cfg.padding[1]) / 2, - y: - (cfg.padding[0] - cfg.padding[2]) / 2, - width: style.width, - height: style.height, - fill: '#fff', - // fill: '#000', - }, - draggable: true, - // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type - name: 'combo-keyShape', - }); - // Add the marker on the bottom - const marker = group.addShape('marker', { - attrs: { - ...style, - fill: '#fff', - // fill: '#000', - opacity: 1, - x: cfg.style.width / 2 + cfg.padding[1], - y: (cfg.padding[2] - cfg.padding[0]) / 2, - r: 10, - symbol: collapseIcon, - }, - draggable: true, - // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type - name: 'combo-marker-shape', - }); - - return rect; - }, - // Define the updating logic for the marker - afterUpdate: function afterUpdate(cfg, combo) { - const group = combo.get('group'); - // Find the circle shape in the graphics group of the Combo by name - const marker = group.find((ele) => ele.get('name') === 'combo-marker-shape'); - // Update the position of the right circle - marker.attr({ - // cfg.style.width and cfg.style.heigth correspond to the innerWidth and innerHeight in the figure of Illustration of Built-in Rect Combo - x: cfg.style.width / 2 + cfg.padding[1], - y: (cfg.padding[2] - cfg.padding[0]) / 2, - // The property 'collapsed' in the combo data represents the collapsing state of the Combo - // Update the symbol according to 'collapsed' - symbol: cfg.collapsed ? expandIcon : collapseIcon, - }); - }, - }, - 'rect', -); - -const fittingString = (str: string, maxWidth: number, fontSize: number) => { - if (!str) { - return '' - } - const ellipsis = "..."; - const ellipsisLength = G6.Util.getTextSize(ellipsis, fontSize)[0]; - let currentWidth = 0; - let res = str; - const pattern = new RegExp("[\u4E00-\u9FA5]+"); // distinguish the Chinese charactors and letters - str.split("").forEach((letter, i) => { - if (currentWidth > maxWidth - ellipsisLength) return; - if (pattern.test(letter)) { - // Chinese charactors - currentWidth += fontSize; - } else { - // get the width of single letter according to the fontSize - currentWidth += G6.Util.getLetterWidth(letter, fontSize); - } - if (currentWidth > maxWidth - ellipsisLength) { - res = `${str.substr(0, i)}${ellipsis}`; - } - }); - return res; -}; - -const processParallelEdgesOnAnchorPoint = ( - edges, - offsetDiff = 15, - multiEdgeType = 'cubic-horizontal', - singleEdgeType = undefined, - loopEdgeType = undefined -) => { - const len = edges.length; - const cod = offsetDiff * 2; - const loopPosition = [ - 'top', - 'top-right', - 'right', - 'bottom-right', - 'bottom', - 'bottom-left', - 'left', - 'top-left', - ]; - const edgeMap = {}; - const tags = []; - const reverses = {}; - for (let i = 0; i < len; i++) { - const edge = edges[i]; - const { source, target, sourceAnchor, targetAnchor } = edge; - const sourceTarget = `${source}|${sourceAnchor}-${target}|${targetAnchor}`; - - if (tags[i]) continue; - if (!edgeMap[sourceTarget]) { - edgeMap[sourceTarget] = []; - } - tags[i] = true; - edgeMap[sourceTarget].push(edge); - for (let j = 0; j < len; j++) { - if (i === j) continue; - const sedge = edges[j]; - const { source: src, target: dst, sourceAnchor: srcAnchor, targetAnchor: dstAnchor } = sedge; - - // 两个节点之间共同的边 - // 第一条的source = 第二条的target - // 第一条的target = 第二条的source - if (!tags[j]) { - if (source === dst && sourceAnchor === dstAnchor - && target === src && targetAnchor === srcAnchor) { - edgeMap[sourceTarget].push(sedge); - tags[j] = true; - reverses[`${src}|${srcAnchor}|${dst}|${dstAnchor}|${edgeMap[sourceTarget].length - 1}`] = true; - } else if (source === src && sourceAnchor === srcAnchor - && target === dst && targetAnchor === dstAnchor) { - edgeMap[sourceTarget].push(sedge); - tags[j] = true; - } - } - } - } - - for (const key in edgeMap) { - const arcEdges = edgeMap[key]; - const { length } = arcEdges; - for (let k = 0; k < length; k++) { - const current = arcEdges[k]; - if (current.source === current.target) { - if (loopEdgeType) current.type = loopEdgeType; - // 超过8条自环边,则需要重新处理 - current.loopCfg = { - position: loopPosition[k % 8], - dist: Math.floor(k / 8) * 20 + 50, - }; - continue; - } - if (length === 1 && singleEdgeType && (current.source !== current.target || current.sourceAnchor !== current.targetAnchor)) { - current.type = singleEdgeType; - continue; - } - current.type = multiEdgeType; - const sign = - (k % 2 === 0 ? 1 : -1) * (reverses[`${current.source}|${current.sourceAnchor}|${current.target}|${current.targetAnchor}|${k}`] ? -1 : 1); - if (length % 2 === 1) { - current.curveOffset = sign * Math.ceil(k / 2) * cod; - } else { - current.curveOffset = sign * (Math.floor(k / 2) * cod + offsetDiff); - } - } - } - return edges; -}; - -export function renderFlow(containerId: string, nodes: any, edges: any, combos: any, events: any, editabel: boolean) { - const container = document.getElementById(containerId); - const width = container!.scrollWidth; - const height = container!.scrollHeight; - const toolbar = new G6.ToolBar({ - container: 'g6-toolbar', - position: { x: 10, y: 10 }, - }); - const minimap = new G6.Minimap({ - container: 'g6-minimap', - size: [150, 100] - }); - let sourceAnchorIdx, targetAnchorIdx - const graph = new G6.Graph({ - container: containerId, - width: width - 15, - height, - animate: true, - fitView: false, - fitCenter: false, - groupByTypes: false, - plugins: [toolbar, minimap], - // 设置为true,启用 redo & undo 栈功能 - enabledStack: true, - modes: { - default: [ - 'drag-canvas', 'zoom-canvas', 'drag-combo', - { - type: 'drag-node', - shouldBegin: e => { - if (e.target.get('name') === 'anchor-point') return false; - if(e.item?._cfg?.model?.hasOwnProperty('comboId') && e.item?._cfg?.model?.comboId !== undefined) return false; - return true; - } - }, - { - type: 'create-edge', - trigger: 'drag', // set the trigger to be drag to make the create-edge triggered by drag - shouldBegin: e => { - // avoid beginning at other shapes on the node - if (e.target && e.target.get('name') !== 'anchor-point') return false; - sourceAnchorIdx = e.target.get('anchorPointIdx'); - e.target.set('links', e.target.get('links') + 1); // cache the number of edge connected to this anchor-point circle - return true; - }, - shouldEnd: e => { - // avoid ending at other shapes on the node - if (e.target && e.target.get('name') !== 'anchor-point') return false; - if (e.target) { - targetAnchorIdx = e.target.get('anchorPointIdx'); - e.target.set('links', e.target.get('links') + 1); // cache the number of edge connected to this anchor-point circle - return true; - } - targetAnchorIdx = undefined; - return true; - }, - }, - ], - }, - // layout: { - // // type: 'dagre', - // // rankdir: 'LR', - // // align: 'UL', - // // controlPoints: false, - // // nodesepFunc: () => 20, - // // ranksepFunc: () => 50, - // }, - defaultNode: { - type: 'card-node', - anchorPoints: [[0, 0.5], [1, 0.5]] - }, - defaultEdge: { - type: 'cubic-horizontal', - size: 1, - style: { - stroke: '#AAB7C4', - endArrow: { - // path: G6.Arrow.circle(3, 2), - path: G6.Arrow.vee(6, 10, 2), - d: 2, - fill: '#AAB7C4', - }, - radius: 20, - }, - }, - defaultCombo: { - type: 'cRect', - // type: 'cCircle', - style:{ - lineWidth: 3, - stroke: color, - }, - fixCollapseSize: 5, - labelCfg: { - /* label's offset to the keyShape */ - refY: -15, - refX: -5, - // position: 'top', - style: { - fontSize: 12, - }, - }, - }, - nodeStateStyles: { - hover: { - lineWidth: 5, - stroke: '#000', - fill: '#000' - }, - }, - }); - const newNodes: any = [] - nodes.map((node: any) => { - const n: any = {} - n.id = node.id - n.label = node.label - n.data = node - n.type = node.type - n.x = node.x - n.y = node.y - n.comboId = node.comboId - newNodes.push(n) - }) - const newEdeges: any = [] - edges.map((edge: any) => { - newEdeges.push({ - source: edge.source, - target: edge.target, - data: edge, - comboId: edge.comboId, - }) - }) - const newCombos: any = [] - combos.map((combo: any) => { - newCombos.push({ - id: combo.id, - label: combo.label, - collapsed: combo.collapsed, - }) - }) - // console.log(JSON.stringify(newNodes)) - graph.data({ nodes: newNodes, edges: newEdeges, combos: newCombos}); - graph.node((node) => { - const data: any = node.data - // if (data.type === 'condition') { - if (data.type === 'task') { - node.type = 'task' - } - if (data.type === 'timeout') { - node.type = 'timeout' - } - if (data.type === 'condition') { - node.type = 'condition' - } - if (data.type === 'flow') { - node.type = 'flow' - } - return node - }); - graph.render(); - - // const temp_nodes = graph.getNodes(); - // for (let temp_k in temp_nodes) { - // const temp_node = temp_nodes[temp_k] - // console.log(temp_node) - // // afterDrawCircle(temp_node._cfg, temp_node._cfg?.group) - // } - - - graph.moveTo(0, graph.getHeight() / 2 - 75) - - graph.on('click', () => { - }); - graph.on('node:click', (evt: any) => { - const { item } = evt; - console.log(item) - graph.getNodes().forEach((node) => { - graph.clearItemStates(node); - }); - setTimeout(() => graph.setItemState(item, 'selected', true)); - if (editabel){ - events['click'](item) - } - - }); - graph.on('edge:mouseenter', (evt: any) => { - const { item } = evt; - // console.log(item) - graph.getEdges().forEach((edge) => { - graph.clearItemStates(edge); - }); - setTimeout(() => graph.setItemState(item, 'selected', true)); - // events['clickEdge'](item) - }); - - graph.on('edge:mouseleave', (evt: any) => { - const { item } = evt; - // console.log(item) - graph.getEdges().forEach((edge) => { - graph.clearItemStates(edge); - }); - setTimeout(() => graph.setItemState(item, 'selected', false)); - // events['clickEdge'](item) - }); - - // after drag from the first node, the edge is created, update the sourceAnchor - graph.on('afteradditem', e => { - if (e.item && e.item.getType() === 'edge') { - graph.updateItem(e.item, { - sourceAnchor: sourceAnchorIdx - }); - } - }) - - // if create-edge is canceled before ending, update the 'links' on the anchor-point circles - graph.on('afterremoveitem', e => { - if (e.item && e.item.source && e.item.target) { - const sourceNode = graph.findById(e.item.source); - const targetNode = graph.findById(e.item.target); - const { sourceAnchor, targetAnchor } = e.item; - if (sourceNode && !isNaN(sourceAnchor)) { - const sourceAnchorShape = sourceNode.getContainer().find(ele => (ele.get('name') === 'anchor-point' && ele.get('anchorPointIdx') === sourceAnchor)); - sourceAnchorShape.set('links', sourceAnchorShape.get('links') - 1); - } - if (targetNode && !isNaN(targetAnchor)) { - const targetAnchorShape = targetNode.getContainer().find(ele => (ele.get('name') === 'anchor-point' && ele.get('anchorPointIdx') === targetAnchor)); - targetAnchorShape.set('links', targetAnchorShape.get('links') - 1); - } - } - }) - - graph.on('aftercreateedge', (e) => { - graph.updateItem(e.edge, { - sourceAnchor: sourceAnchorIdx, - targetAnchor: targetAnchorIdx - }) - - // update the curveOffset for parallel edges - const edges = graph.save().edges; - processParallelEdgesOnAnchorPoint(edges); - graph.getEdges().forEach((edge, i) => { - graph.updateItem(edge, { - curveOffset: edges[i].curveOffset, - curvePosition: edges[i].curvePosition, - }); - }); - }); - - const dataChange = () => { - // const nodes: any = [], edges: any = [] - // graph.getNodes().map(node => { - // nodes.push(node.getModel()) - // }) - // graph.getEdges().map(edge => { - // edges.push(edge.getModel()) - // }) - // const data = { nodes, edges } - const data: any = graph.save() - const nodes: any = [] - const edges: any = [] - data.nodes.forEach((node: any) => { - nodes.push(Object.assign({}, {...node})) - }) - data.edges.forEach((edge: any) => { - edges.push(Object.assign({}, {...edge})) - }) - - const newData = {nodes, edges} - if (editabel){ - events['datachange'](newData) - } - // console.log('kkkkkkk',newData) - } - - graph.on('afterupdateitem', (e) => { - dataChange() - }); - - graph.on('stackchange', (e) => { - dataChange() - }); - - graph.on('afterrender', (e) => { - dataChange() - }); - - // some listeners to control the state of nodes to show and hide anchor-point circles - graph.on('node:mouseenter', e => { - graph.setItemState(e.item, 'showAnchors', true); - // setShowState('showAnchors', true, e.item); - }); - graph.on('node:mouseleave', e => { - graph.setItemState(e.item, 'showAnchors', false); - // setShowState('showAnchors', false, e.item); - }) - graph.on('node:dragenter', e => { - graph.setItemState(e.item, 'showAnchors', true); - // setShowState('showAnchors', true, e.item); - }); - graph.on('node:dragleave', e => { - graph.setItemState(e.item, 'showAnchors', false); - // setShowState('showAnchors', false, e.item); - }); - graph.on('node:dragstart', e => { - graph.setItemState(e.item, 'showAnchors', true); - // setShowState('showAnchors', true, e.item); - }); - graph.on('node:dragout', e => { - graph.setItemState(e.item, 'showAnchors', false); - // setShowState('showAnchors', false, e.item); - }); - - graph.on('combo:mouseenter', (evt) => { - const { item } = evt; - graph.setItemState(item, 'active', true); - }); - - graph.on('combo:mouseleave', (evt) => { - const { item } = evt; - graph.setItemState(item, 'active', false); - }); - // graph.on('combo:click', (evt) => { - // const { item } = evt; - // graph.setItemState(item, 'selected', true); - // }); - // graph.on('canvas:click', (evt) => { - // graph.getCombos().forEach((combo) => { - // graph.clearItemStates(combo); - // }); - // }); - - graph.on('combo:click', (e) => { - if (e.target.get('name') === 'combo-marker-shape') { - // graph.collapseExpandCombo(e.item.getModel().id); - graph.collapseExpandCombo(e.item); - if (graph.get('layout')) graph.layout(); - else graph.refreshPositions(); - } - }); - - - graph.on('canvas:click', (evt) => { - graph.getEdges().forEach((edge) => { - graph.clearItemStates(edge); - }); - graph.getNodes().forEach((node) => { - graph.clearItemStates(node); - }); - }); - - graph.on('keyup', (evt) => { - const srcEleTag = evt.srcElement!.tagName - console.log(srcEleTag) - if (evt.key === 'Backspace' && editabel && srcEleTag === 'BODY') { - console.log(evt) - graph.getEdges().forEach((edge) => { - edge.getStates().includes('selected') && graph.removeItem(edge); - }); - graph.getNodes().forEach((node) => { - node.getStates().includes('selected') && graph.removeItem(node); - }); - dataChange() - } - }) - - if (typeof window !== 'undefined') - window.onresize = () => { - if (!graph || graph.get('destroyed')) return; - if (!container || !container.scrollWidth || !container.scrollHeight) return; - graph.changeSize(container.scrollWidth, container.scrollHeight); - }; - return graph -} - - diff --git a/tg-web/src/components/svgIcon/index.vue b/tg-web/src/components/svgIcon/index.vue deleted file mode 100644 index f51c532ee295311348a294edc81e61e000a4838a..0000000000000000000000000000000000000000 --- a/tg-web/src/components/svgIcon/index.vue +++ /dev/null @@ -1,42 +0,0 @@ - diff --git a/tg-web/src/config.ts b/tg-web/src/config.ts deleted file mode 100644 index 7c0bc8e696041db7c9540305d9d94d1fff7af270..0000000000000000000000000000000000000000 --- a/tg-web/src/config.ts +++ /dev/null @@ -1,5 +0,0 @@ -const baseURL = import.meta.env.VITE_API_BASE_URL - -export { - baseURL, -} \ No newline at end of file diff --git a/tg-web/src/i18n/index.ts b/tg-web/src/i18n/index.ts deleted file mode 100644 index a45e72cef3660067b573bef5f3e5b7b7dca46243..0000000000000000000000000000000000000000 --- a/tg-web/src/i18n/index.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { createI18n } from 'vue-i18n'; -import pinia from '/@/stores/index'; -import { storeToRefs } from 'pinia'; -import { useThemeConfig } from '/@/stores/themeConfig'; -import zhcnLocale from 'element-plus/lib/locale/lang/zh-cn'; -import enLocale from 'element-plus/lib/locale/lang/en'; -import zhtwLocale from 'element-plus/lib/locale/lang/zh-tw'; - -import nextZhcn from '/@/i18n/lang/zh-cn'; -import nextEn from '/@/i18n/lang/en'; -import nextZhtw from '/@/i18n/lang/zh-tw'; - -import pagesLoginZhcn from '/@/i18n/pages/login/zh-cn'; -import pagesLoginEn from '/@/i18n/pages/login/en'; -import pagesLoginZhtw from '/@/i18n/pages/login/zh-tw'; -import pagesFormI18nZhcn from '/@/i18n/pages/formI18n/zh-cn'; -import pagesFormI18nEn from '/@/i18n/pages/formI18n/en'; -import pagesFormI18nZhtw from '/@/i18n/pages/formI18n/zh-tw'; - -// 定义语言国际化内容 -/** - * 说明: - * /src/i18n/lang 下的 ts 为框架的国际化内容 - * /src/i18n/pages 下的 ts 为各界面的国际化内容 - */ -const messages = { - [zhcnLocale.name]: { - ...zhcnLocale, - message: { - ...nextZhcn, - ...pagesLoginZhcn, - ...pagesFormI18nZhcn, - }, - }, - [enLocale.name]: { - ...enLocale, - message: { - ...nextEn, - ...pagesLoginEn, - ...pagesFormI18nEn, - }, - }, - [zhtwLocale.name]: { - ...zhtwLocale, - message: { - ...nextZhtw, - ...pagesLoginZhtw, - ...pagesFormI18nZhtw, - }, - }, -}; - -// 读取 pinia 默认语言 -const stores = useThemeConfig(pinia); -const { themeConfig } = storeToRefs(stores); - -// 导出语言国际化 -// https://vue-i18n.intlify.dev/guide/essentials/fallback.html#explicit-fallback-with-one-locale -export const i18n = createI18n({ - silentTranslationWarn: true, - missingWarn: false, - silentFallbackWarn: true, - fallbackWarn: false, - locale: themeConfig.value.globalI18n, - fallbackLocale: zhcnLocale.name, - messages, -}); diff --git a/tg-web/src/i18n/lang/en.ts b/tg-web/src/i18n/lang/en.ts deleted file mode 100644 index 46ae8302d8b6b610b780b1afa413e3a801d974f5..0000000000000000000000000000000000000000 --- a/tg-web/src/i18n/lang/en.ts +++ /dev/null @@ -1,180 +0,0 @@ -// 定义内容 -export default { - router: { - home: 'home', - system: 'system', - systemMenu: 'systemMenu', - systemRole: 'systemRole', - systemUser: 'systemUser', - systemDept: 'systemDept', - systemDic: 'systemDic', - limits: 'limits', - limitsFrontEnd: 'FrontEnd', - limitsFrontEndPage: 'FrontEndPage', - limitsFrontEndBtn: 'FrontEndBtn', - limitsBackEnd: 'BackEnd', - limitsBackEndEndPage: 'BackEndEndPage', - menu: 'menu', - menu1: 'menu1', - menu11: 'menu11', - menu12: 'menu12', - menu121: 'menu121', - menu122: 'menu122', - menu13: 'menu13', - menu2: 'menu2', - funIndex: 'function', - funTagsView: 'funTagsView', - funCountup: 'countup', - funWangEditor: 'wangEditor', - funCropper: 'cropper', - funQrcode: 'qrcode', - funEchartsMap: 'EchartsMap', - funPrintJs: 'PrintJs', - funClipboard: 'Copy cut', - funGridLayout: 'Drag layout', - funSplitpanes: 'Pane splitter', - funDragVerify: 'Validator', - pagesIndex: 'pages', - pagesFiltering: 'Filtering', - pagesFilteringDetails: 'FilteringDetails', - pagesFilteringDetails1: 'FilteringDetails1', - pagesIocnfont: 'iconfont icon', - pagesElement: 'element icon', - pagesAwesome: 'awesome icon', - pagesFormAdapt: 'FormAdapt', - pagesTableRules: 'pagesTableRules', - pagesFormI18n: 'FormI18n', - pagesFormRules: 'Multi form validation', - pagesDynamicForm: 'Dynamic complex form', - pagesWorkflow: 'Workflow', - pagesListAdapt: 'ListAdapt', - pagesWaterfall: 'Waterfall', - pagesSteps: 'Steps', - pagesPreview: 'Large preview', - pagesWaves: 'Wave effect', - pagesTree: 'tree alter table', - pagesDrag: 'Drag command', - pagesLazyImg: 'Image lazy loading', - makeIndex: 'makeIndex', - makeSelector: 'Icon selector', - makeNoticeBar: 'notification bar', - makeSvgDemo: 'Svgicon demo', - paramsIndex: 'Routing parameters', - paramsCommon: 'General routing', - paramsDynamic: 'Dynamic routing', - paramsCommonDetails: 'General routing details', - paramsDynamicDetails: 'Dynamic routing details', - chartIndex: 'chartIndex', - visualizingIndex: 'visualizingIndex', - visualizingLinkDemo1: 'visualizingLinkDemo1', - visualizingLinkDemo2: 'visualizingLinkDemo2', - personal: 'personal', - tools: 'tools', - layoutLinkView: 'LinkView', - layoutIfameView: 'IfameView', - }, - staticRoutes: { - signIn: 'signIn', - notFound: 'notFound', - noPower: 'noPower', - }, - user: { - title0: 'Component size', - title1: 'Language switching', - title2: 'Menu search', - title3: 'Layout configuration', - title4: 'news', - title5: 'Full screen on', - title6: 'Full screen off', - dropdownLarge: 'large', - dropdownDefault: 'default', - dropdownSmall: 'small', - dropdown1: 'home page', - dropdown2: 'Personal Center', - dropdown3: '404', - dropdown4: '401', - dropdown5: 'Log out', - dropdown6: 'Code warehouse', - searchPlaceholder: 'Menu search: support Chinese, routing path', - newTitle: 'notice', - newBtn: 'All read', - newGo: 'Go to the notification center', - newDesc: 'No notice', - logOutTitle: 'Tips', - logOutMessage: 'This operation will log out. Do you want to continue?', - logOutConfirm: 'determine', - logOutCancel: 'cancel', - logOutExit: 'Exiting', - }, - tagsView: { - refresh: 'refresh', - close: 'close', - closeOther: 'closeOther', - closeAll: 'closeAll', - fullscreen: 'fullscreen', - closeFullscreen: 'closeFullscreen', - }, - notFound: { - foundTitle: 'Wrong address input, please re-enter the address~', - foundMsg: 'You can check the web address first, and then re-enter or give us feedback.', - foundBtn: 'Back to home page', - }, - noAccess: { - accessTitle: 'You are not authorized to operate~', - accessMsg: 'Contact information: add QQ group discussion 665452019', - accessBtn: 'Reauthorization', - }, - layout: { - configTitle: 'Layout configuration', - oneTitle: 'Global Themes', - twoTopTitle: 'top bar set up', - twoMenuTitle: 'Menu set up', - twoColumnsTitle: 'Columns set up', - twoTopBar: 'Top bar background', - twoTopBarColor: 'Top bar default font color', - twoIsTopBarColorGradual: 'Top bar gradient', - twoMenuBar: 'Menu background', - twoMenuBarColor: 'Menu default font color', - twoIsMenuBarColorGradual: 'Menu gradient', - twoColumnsMenuBar: 'Column menu background', - twoColumnsMenuBarColor: 'Default font color bar menu', - twoIsColumnsMenuBarColorGradual: 'Column gradient', - threeTitle: 'Interface settings', - threeIsCollapse: 'Menu horizontal collapse', - threeIsUniqueOpened: 'Menu accordion', - threeIsFixedHeader: 'Fixed header', - threeIsClassicSplitMenu: 'Classic layout split menu', - threeIsLockScreen: 'Open the lock screen', - threeLockScreenTime: 'screen locking(s/s)', - fourTitle: 'Interface display', - fourIsShowLogo: 'Sidebar logo', - fourIsBreadcrumb: 'Open breadcrumb', - fourIsBreadcrumbIcon: 'Open breadcrumb icon', - fourIsTagsview: 'Open tagsview', - fourIsTagsviewIcon: 'Open tagsview Icon', - fourIsCacheTagsView: 'Enable tagsview cache', - fourIsSortableTagsView: 'Enable tagsview drag', - fourIsShareTagsView: 'Enable tagsview sharing', - fourIsFooter: 'Open footer', - fourIsGrayscale: 'Grey model', - fourIsInvert: 'Color weak mode', - fourIsDark: 'Dark Mode', - fourIsWartermark: 'Turn on watermark', - fourWartermarkText: 'Watermark copy', - fiveTitle: 'Other settings', - fiveTagsStyle: 'Tagsview style', - fiveAnimation: 'page animation', - fiveColumnsAsideStyle: 'Column style', - fiveColumnsAsideLayout: 'Column layout', - sixTitle: 'Layout switch', - sixDefaults: 'One', - sixClassic: 'Two', - sixTransverse: 'Three', - sixColumns: 'Four', - tipText: 'Click the button below to copy the layout configuration to `/src/stores/themeConfig.ts` It has been modified in.', - copyText: 'replication configuration', - resetText: 'restore default', - copyTextSuccess: 'Copy succeeded!', - copyTextError: 'Copy failed!', - }, -}; diff --git a/tg-web/src/i18n/lang/zh-cn.ts b/tg-web/src/i18n/lang/zh-cn.ts deleted file mode 100644 index 79ef328ddb13a2ac4bf7488097cf2d6c1a85080a..0000000000000000000000000000000000000000 --- a/tg-web/src/i18n/lang/zh-cn.ts +++ /dev/null @@ -1,180 +0,0 @@ -// 定义内容 -export default { - router: { - home: '首页', - system: '系统设置', - systemMenu: '菜单管理', - systemRole: '角色管理', - systemUser: '用户管理', - systemDept: '部门管理', - systemDic: '字典管理', - limits: '权限管理', - limitsFrontEnd: '前端控制', - limitsFrontEndPage: '页面权限', - limitsFrontEndBtn: '按钮权限', - limitsBackEnd: '后端控制', - limitsBackEndEndPage: '页面权限', - menu: '菜单嵌套', - menu1: '菜单1', - menu11: '菜单11', - menu12: '菜单12', - menu121: '菜单121', - menu122: '菜单122', - menu13: '菜单13', - menu2: '菜单2', - funIndex: '功能', - funTagsView: 'tagsView 操作', - funCountup: '数字滚动', - funWangEditor: 'Editor 编辑器', - funCropper: '图片裁剪', - funQrcode: '二维码生成', - funEchartsMap: '地理坐标/地图', - funPrintJs: '页面打印', - funClipboard: '复制剪切', - funGridLayout: '拖拽布局', - funSplitpanes: '窗格拆分器', - funDragVerify: '验证器', - pagesIndex: '页面', - pagesFiltering: '过滤筛选组件', - pagesFilteringDetails: '过滤筛选组件详情', - pagesFilteringDetails1: '过滤筛选组件详情111', - pagesIocnfont: 'ali 字体图标', - pagesElement: 'ele 字体图标', - pagesAwesome: 'awe 字体图标', - pagesFormAdapt: '表单自适应', - pagesTableRules: '表单表格验证', - pagesFormI18n: '表单国际化', - pagesFormRules: '多表单验证', - pagesDynamicForm: '动态复杂表单', - pagesWorkflow: '工作流', - pagesListAdapt: '列表自适应', - pagesWaterfall: '瀑布屏', - pagesSteps: '步骤条', - pagesPreview: '大图预览', - pagesWaves: '波浪效果', - pagesTree: '树形改表格', - pagesDrag: '拖动指令', - pagesLazyImg: '图片懒加载', - makeIndex: '组件封装', - makeSelector: '图标选择器', - makeNoticeBar: '滚动通知栏', - makeSvgDemo: 'svgIcon 演示', - paramsIndex: '路由参数', - paramsCommon: '普通路由', - paramsDynamic: '动态路由', - paramsCommonDetails: '普通路由详情', - paramsDynamicDetails: '动态路由详情', - chartIndex: '大数据图表', - visualizingIndex: '数据可视化', - visualizingLinkDemo1: '数据可视化演示1', - visualizingLinkDemo2: '数据可视化演示2', - personal: '个人中心', - tools: '工具类集合', - layoutLinkView: '外链', - layoutIfameView: '内嵌 iframe', - }, - staticRoutes: { - signIn: '登录', - notFound: '找不到此页面', - noPower: '没有权限', - }, - user: { - title0: '组件大小', - title1: '语言切换', - title2: '菜单搜索', - title3: '布局配置', - title4: '消息', - title5: '开全屏', - title6: '关全屏', - dropdownLarge: '大型', - dropdownDefault: '默认', - dropdownSmall: '小型', - dropdown1: '首页', - dropdown2: '个人中心', - dropdown3: '404', - dropdown4: '401', - dropdown5: '退出登录', - dropdown6: '代码仓库', - searchPlaceholder: '菜单搜索:支持中文、路由路径', - newTitle: '通知', - newBtn: '全部已读', - newGo: '前往通知中心', - newDesc: '暂无通知', - logOutTitle: '提示', - logOutMessage: '此操作将退出登录, 是否继续?', - logOutConfirm: '确定', - logOutCancel: '取消', - logOutExit: '退出中', - }, - tagsView: { - refresh: '刷新', - close: '关闭', - closeOther: '关闭其它', - closeAll: '全部关闭', - fullscreen: '当前页全屏', - closeFullscreen: '关闭全屏', - }, - notFound: { - foundTitle: '地址输入错误,请重新输入地址~', - foundMsg: '您可以先检查网址,然后重新输入或给我们反馈问题。', - foundBtn: '返回首页', - }, - noAccess: { - accessTitle: '您未被授权,没有操作权限~', - accessMsg: '联系方式:加QQ群探讨 665452019', - accessBtn: '重新授权', - }, - layout: { - configTitle: '布局配置', - oneTitle: '全局主题', - twoTopTitle: '顶栏设置', - twoMenuTitle: '菜单设置', - twoColumnsTitle: '分栏设置', - twoTopBar: '顶栏背景', - twoTopBarColor: '顶栏默认字体颜色', - twoIsTopBarColorGradual: '顶栏背景渐变', - twoMenuBar: '菜单背景', - twoMenuBarColor: '菜单默认字体颜色', - twoIsMenuBarColorGradual: '菜单背景渐变', - twoColumnsMenuBar: '分栏菜单背景', - twoColumnsMenuBarColor: '分栏菜单默认字体颜色', - twoIsColumnsMenuBarColorGradual: '分栏菜单背景渐变', - threeTitle: '界面设置', - threeIsCollapse: '菜单水平折叠', - threeIsUniqueOpened: '菜单手风琴', - threeIsFixedHeader: '固定 Header', - threeIsClassicSplitMenu: '经典布局分割菜单', - threeIsLockScreen: '开启锁屏', - threeLockScreenTime: '自动锁屏(s/秒)', - fourTitle: '界面显示', - fourIsShowLogo: '侧边栏 Logo', - fourIsBreadcrumb: '开启 Breadcrumb', - fourIsBreadcrumbIcon: '开启 Breadcrumb 图标', - fourIsTagsview: '开启 Tagsview', - fourIsTagsviewIcon: '开启 Tagsview 图标', - fourIsCacheTagsView: '开启 TagsView 缓存', - fourIsSortableTagsView: '开启 TagsView 拖拽', - fourIsShareTagsView: '开启 TagsView 共用', - fourIsFooter: '开启 Footer', - fourIsGrayscale: '灰色模式', - fourIsInvert: '色弱模式', - fourIsDark: '深色模式', - fourIsWartermark: '开启水印', - fourWartermarkText: '水印文案', - fiveTitle: '其它设置', - fiveTagsStyle: 'Tagsview 风格', - fiveAnimation: '主页面切换动画', - fiveColumnsAsideStyle: '分栏高亮风格', - fiveColumnsAsideLayout: '分栏布局风格', - sixTitle: '布局切换', - sixDefaults: '默认', - sixClassic: '经典', - sixTransverse: '横向', - sixColumns: '分栏', - tipText: '点击下方按钮,复制布局配置去 `src/stores/themeConfig.ts` 中修改。', - copyText: '一键复制配置', - resetText: '一键恢复默认', - copyTextSuccess: '复制成功!', - copyTextError: '复制失败!', - }, -}; diff --git a/tg-web/src/i18n/lang/zh-tw.ts b/tg-web/src/i18n/lang/zh-tw.ts deleted file mode 100644 index d900abb52d12749caeb7858482e7cd6a9683b43f..0000000000000000000000000000000000000000 --- a/tg-web/src/i18n/lang/zh-tw.ts +++ /dev/null @@ -1,180 +0,0 @@ -// 定义内容 -export default { - router: { - home: '首頁', - system: '系統設置', - systemMenu: '選單管理', - systemRole: '角色管理', - systemUser: '用戶管理', - systemDept: '部門管理', - systemDic: '字典管理', - limits: '許可權管理', - limitsFrontEnd: '前端控制', - limitsFrontEndPage: '頁面許可權', - limitsFrontEndBtn: '按鈕許可權', - limitsBackEnd: '後端控制', - limitsBackEndEndPage: '頁面許可權', - menu: '選單嵌套', - menu1: '選單1', - menu11: '選單11', - menu12: '選單12', - menu121: '選單121', - menu122: '選單122', - menu13: '選單13', - menu2: '選單2', - funIndex: '功能', - funTagsView: 'tagsView 操作', - funCountup: '數位滾動', - funWangEditor: 'Editor 編輯器', - funCropper: '圖片裁剪', - funQrcode: '二維碼生成', - funEchartsMap: '地理座標/地圖', - funPrintJs: '頁面列印', - funClipboard: '複製剪切', - funGridLayout: '拖拽佈局', - funSplitpanes: '窗格折開器', - funDragVerify: '驗證器', - pagesIndex: '頁面', - pagesFiltering: '過濾篩選組件', - pagesFilteringDetails: '過濾篩選組件詳情', - pagesFilteringDetails1: '過濾篩選組件詳情111', - pagesIocnfont: 'ali 字體圖標', - pagesElement: 'ele 字體圖標', - pagesAwesome: 'awe 字體圖標', - pagesFormAdapt: '表單自我調整', - pagesTableRules: '表單表格驗證', - pagesFormI18n: '表單國際化', - pagesFormRules: '多表單驗證', - pagesDynamicForm: '動態複雜表單', - pagesWorkflow: '工作流', - pagesListAdapt: '清單自我調整', - pagesWaterfall: '瀑布屏', - pagesSteps: '步驟條', - pagesPreview: '大圖預覽', - pagesWaves: '波浪效果', - pagesTree: '樹形改表格', - pagesDrag: '拖動指令', - pagesLazyImg: '圖片懶加載', - makeIndex: '組件封裝', - makeSelector: '圖標選擇器', - makeNoticeBar: '滾動通知欄', - makeSvgDemo: 'svgIcon 演示', - paramsIndex: '路由參數', - paramsCommon: '普通路由', - paramsDynamic: '動態路由', - paramsCommonDetails: '普通路由詳情', - paramsDynamicDetails: '動態路由詳情', - chartIndex: '大資料圖表', - visualizingIndex: '數據視覺化', - visualizingLinkDemo1: '數據視覺化演示1', - visualizingLinkDemo2: '數據視覺化演示2', - personal: '個人中心', - tools: '工具類集合', - layoutLinkView: '外鏈', - layoutIfameView: '内嵌 iframe', - }, - staticRoutes: { - signIn: '登入', - notFound: '找不到此頁面', - noPower: '沒有許可權', - }, - user: { - title0: '組件大小', - title1: '語言切換', - title2: '選單蒐索', - title3: '佈局配寘', - title4: '消息', - title5: '開全屏', - title6: '關全屏', - dropdownLarge: '大型', - dropdownDefault: '默認', - dropdownSmall: '小型', - dropdown1: '首頁', - dropdown2: '個人中心', - dropdown3: '404', - dropdown4: '401', - dropdown5: '登出', - dropdown6: '程式碼倉庫', - searchPlaceholder: '選單蒐索:支援中文、路由路徑', - newTitle: '通知', - newBtn: '全部已讀', - newGo: '前往通知中心', - newDesc: '暫無通知', - logOutTitle: '提示', - logOutMessage: '此操作將登出,是否繼續?', - logOutConfirm: '確定', - logOutCancel: '取消', - logOutExit: '退出中', - }, - tagsView: { - refresh: '重繪', - close: '關閉', - closeOther: '關閉其它', - closeAll: '全部關閉', - fullscreen: '當前頁全屏', - closeFullscreen: '關閉全屏', - }, - notFound: { - foundTitle: '地址輸入錯誤,請重新輸入地址~', - foundMsg: '您可以先檢查網址,然後重新輸入或給我們迴響問題。', - foundBtn: '返回首頁', - }, - noAccess: { - accessTitle: '您未被授權,沒有操作許可權~', - accessMsg: '聯繫方式:加QQ群探討665452019', - accessBtn: '重新授權', - }, - layout: { - configTitle: '佈局配寘', - oneTitle: '全域主題', - twoTopTitle: '頂欄設定', - twoMenuTitle: '選單設定', - twoColumnsTitle: '分欄設定', - twoTopBar: '頂欄背景', - twoTopBarColor: '頂欄默認字體顏色', - twoIsTopBarColorGradual: '頂欄背景漸變', - twoMenuBar: '選單背景', - twoMenuBarColor: '選單默認字體顏色', - twoIsMenuBarColorGradual: '選單背景漸變', - twoColumnsMenuBar: '分欄選單背景', - twoColumnsMenuBarColor: '分欄選單默認字體顏色', - twoIsColumnsMenuBarColorGradual: '分欄選單背景漸變', - threeTitle: '介面設定', - threeIsCollapse: '選單水准折疊', - threeIsUniqueOpened: '選單手風琴', - threeIsFixedHeader: '固定 Header', - threeIsClassicSplitMenu: '經典佈局分割選單', - threeIsLockScreen: '開啟鎖屏', - threeLockScreenTime: '自動鎖屏(s/秒)', - fourTitle: '介面顯示', - fourIsShowLogo: '側邊欄 Logo', - fourIsBreadcrumb: '開啟 Breadcrumb', - fourIsBreadcrumbIcon: '開啟 Breadcrumb 圖標', - fourIsTagsview: '開啟 Tagsview', - fourIsTagsviewIcon: '開啟 Tagsview 圖標', - fourIsCacheTagsView: '開啟 TagsView 緩存', - fourIsSortableTagsView: '開啟 TagsView 拖拽', - fourIsShareTagsView: '開啟 TagsView 共用', - fourIsFooter: '開啟 Footer', - fourIsGrayscale: '灰色模式', - fourIsInvert: '色弱模式', - fourIsDark: '深色模式', - fourIsWartermark: '開啟浮水印', - fourWartermarkText: '浮水印文案', - fiveTitle: '其它設定', - fiveTagsStyle: 'Tagsview 風格', - fiveAnimation: '主頁面切換動畫', - fiveColumnsAsideStyle: '分欄高亮風格', - fiveColumnsAsideLayout: '分欄佈局風格', - sixTitle: '佈局切換', - sixDefaults: '默認', - sixClassic: '經典', - sixTransverse: '橫向', - sixColumns: '分欄', - tipText: '點擊下方按鈕,複製佈局配寘去`src/stores/themeConfig.ts`中修改。', - copyText: '一鍵複製配寘', - resetText: '一鍵恢復默認', - copyTextSuccess: '複製成功!', - copyTextError: '複製失敗!', - }, -}; diff --git a/tg-web/src/i18n/pages/formI18n/en.ts b/tg-web/src/i18n/pages/formI18n/en.ts deleted file mode 100644 index b3c54d608a7dc67602ef4e2feb7a12cff96cd3d3..0000000000000000000000000000000000000000 --- a/tg-web/src/i18n/pages/formI18n/en.ts +++ /dev/null @@ -1,13 +0,0 @@ -// 定义内容 -export default { - formI18nLabel: { - name: 'name', - email: 'email', - autograph: 'autograph', - }, - formI18nPlaceholder: { - name: 'Please enter your name', - email: 'Please enter the users Department', - autograph: 'Please enter the login account name', - }, -}; diff --git a/tg-web/src/i18n/pages/formI18n/zh-cn.ts b/tg-web/src/i18n/pages/formI18n/zh-cn.ts deleted file mode 100644 index 0bed3ec36fb71abb80d275dcc3ed97d086a93606..0000000000000000000000000000000000000000 --- a/tg-web/src/i18n/pages/formI18n/zh-cn.ts +++ /dev/null @@ -1,13 +0,0 @@ -// 定义内容 -export default { - formI18nLabel: { - name: '姓名', - email: '用户归属部门', - autograph: '登陆账户名', - }, - formI18nPlaceholder: { - name: '请输入姓名', - email: '请输入用户归属部门', - autograph: '请输入登陆账户名', - }, -}; diff --git a/tg-web/src/i18n/pages/formI18n/zh-tw.ts b/tg-web/src/i18n/pages/formI18n/zh-tw.ts deleted file mode 100644 index 393ac03b73ebd41bec9e0fc64681c455b6726ce1..0000000000000000000000000000000000000000 --- a/tg-web/src/i18n/pages/formI18n/zh-tw.ts +++ /dev/null @@ -1,13 +0,0 @@ -// 定义内容 -export default { - formI18nLabel: { - name: '姓名', - email: '用戶歸屬部門', - autograph: '登入帳戶名', - }, - formI18nPlaceholder: { - name: '請輸入姓名', - email: '請輸入用戶歸屬部門', - autograph: '請輸入登入帳戶名', - }, -}; diff --git a/tg-web/src/i18n/pages/login/en.ts b/tg-web/src/i18n/pages/login/en.ts deleted file mode 100644 index 2654a188c4c3880393fd4fd8f50d6fb0bf6ecf4a..0000000000000000000000000000000000000000 --- a/tg-web/src/i18n/pages/login/en.ts +++ /dev/null @@ -1,29 +0,0 @@ -// 定义内容 -export default { - label: { - one1: 'User name login', - two2: 'Mobile number', - }, - link: { - one3: 'Third party login', - two4: 'Links', - }, - account: { - accountPlaceholder1: 'The user name admin or not is common', - accountPlaceholder2: 'Password: 123456', - accountPlaceholder3: 'Please enter the verification code', - accountBtnText: 'Sign in', - }, - mobile: { - placeholder1: 'Please input mobile phone number', - placeholder2: 'Please enter the verification code', - codeText: 'Get code', - btnText: 'Sign in', - msgText: - 'Warm tip: it is recommended to use Google, Microsoft edge, version 79.0.1072.62 and above browsers, and 360 browser, please use speed mode', - }, - scan: { - text: 'Open the mobile phone to scan and quickly log in / register', - }, - signInText: 'welcome back!', -}; diff --git a/tg-web/src/i18n/pages/login/zh-cn.ts b/tg-web/src/i18n/pages/login/zh-cn.ts deleted file mode 100644 index 3367b539f2d1cc68641673c007bc04f84048288f..0000000000000000000000000000000000000000 --- a/tg-web/src/i18n/pages/login/zh-cn.ts +++ /dev/null @@ -1,28 +0,0 @@ -// 定义内容 -export default { - label: { - one1: '用户名登录', - two2: '手机号登录', - }, - link: { - one3: '第三方登录', - two4: '友情链接', - }, - account: { - accountPlaceholder1: '用户名 admin 或不输均为 common', - accountPlaceholder2: '密码:123456', - accountPlaceholder3: '请输入验证码', - accountBtnText: '登 录', - }, - mobile: { - placeholder1: '请输入手机号', - placeholder2: '请输入验证码', - codeText: '获取验证码', - btnText: '登 录', - msgText: '* 温馨提示:建议使用谷歌、Microsoft Edge,版本 79.0.1072.62 及以上浏览器,360浏览器请使用极速模式', - }, - scan: { - text: '打开手机扫一扫,快速登录/注册', - }, - signInText: '欢迎回来!', -}; diff --git a/tg-web/src/i18n/pages/login/zh-tw.ts b/tg-web/src/i18n/pages/login/zh-tw.ts deleted file mode 100644 index 138e8c826ab2835238f038627349338bbbde73f5..0000000000000000000000000000000000000000 --- a/tg-web/src/i18n/pages/login/zh-tw.ts +++ /dev/null @@ -1,28 +0,0 @@ -// 定义内容 -export default { - label: { - one1: '用戶名登入', - two2: '手機號登入', - }, - link: { - one3: '協力廠商登入', - two4: '友情連結', - }, - account: { - accountPlaceholder1: '用戶名admin或不輸均為common', - accountPlaceholder2: '密碼:123456', - accountPlaceholder3: '請輸入驗證碼', - accountBtnText: '登入', - }, - mobile: { - placeholder1: '請輸入手機號', - placeholder2: '請輸入驗證碼', - codeText: '獲取驗證碼', - btnText: '登入', - msgText: '* 溫馨提示:建議使用穀歌、Microsoft Edge,版本79.0.1072.62及以上瀏覽器,360瀏覽器請使用極速模式', - }, - scan: { - text: '打開手機掃一掃,快速登錄/注册', - }, - signInText: '歡迎回來!', -}; diff --git a/tg-web/src/layout/component/aside.vue b/tg-web/src/layout/component/aside.vue deleted file mode 100644 index d4ee363b54e9b29e54a76663f7687a11d6b6c96b..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/component/aside.vue +++ /dev/null @@ -1,163 +0,0 @@ - - - diff --git a/tg-web/src/layout/component/columnsAside.vue b/tg-web/src/layout/component/columnsAside.vue deleted file mode 100644 index 7fd7806b1c9ca39baba67eb4f9eb505e12ae77ae..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/component/columnsAside.vue +++ /dev/null @@ -1,292 +0,0 @@ - - - - - diff --git a/tg-web/src/layout/component/header.vue b/tg-web/src/layout/component/header.vue deleted file mode 100644 index 21c9e2dea5e360e2615239e940ca146aeec2cd29..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/component/header.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - diff --git a/tg-web/src/layout/component/main.vue b/tg-web/src/layout/component/main.vue deleted file mode 100644 index 18eba607e209233c22cc5d2d2084873821d848ce..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/component/main.vue +++ /dev/null @@ -1,101 +0,0 @@ - - - diff --git a/tg-web/src/layout/footer/index.vue b/tg-web/src/layout/footer/index.vue deleted file mode 100644 index ef005914fa7c870f40706bc3b378f0c12f497372..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/footer/index.vue +++ /dev/null @@ -1,47 +0,0 @@ - - - - - diff --git a/tg-web/src/layout/index.vue b/tg-web/src/layout/index.vue deleted file mode 100644 index 50643a49f855a8e7a0844b96a6b92fe4dbedc3d4..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/index.vue +++ /dev/null @@ -1,54 +0,0 @@ - - - diff --git a/tg-web/src/layout/lockScreen/index.vue b/tg-web/src/layout/lockScreen/index.vue deleted file mode 100644 index b9173c2af291cb15ae3665c004000c4cd2cb82b0..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/lockScreen/index.vue +++ /dev/null @@ -1,372 +0,0 @@ - - - - - diff --git a/tg-web/src/layout/logo/index.vue b/tg-web/src/layout/logo/index.vue deleted file mode 100644 index ac808625fa155db7eebbe988c13bafa58bdfdd56..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/logo/index.vue +++ /dev/null @@ -1,81 +0,0 @@ - - - - - diff --git a/tg-web/src/layout/main/classic.vue b/tg-web/src/layout/main/classic.vue deleted file mode 100644 index b92290f168458dd2feca7938efca378abaed3b22..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/main/classic.vue +++ /dev/null @@ -1,35 +0,0 @@ - - - diff --git a/tg-web/src/layout/main/columns.vue b/tg-web/src/layout/main/columns.vue deleted file mode 100644 index 0aa1d3112444924a860b8706b8b482e4258c5883..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/main/columns.vue +++ /dev/null @@ -1,41 +0,0 @@ - - - diff --git a/tg-web/src/layout/main/defaults.vue b/tg-web/src/layout/main/defaults.vue deleted file mode 100644 index 0cabb0c1473fc6ce04b5058d2a00a02be5aa5b08..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/main/defaults.vue +++ /dev/null @@ -1,47 +0,0 @@ - - - diff --git a/tg-web/src/layout/main/transverse.vue b/tg-web/src/layout/main/transverse.vue deleted file mode 100644 index 538f911161268654bac6654b9db1433a556bb2cc..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/main/transverse.vue +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/tg-web/src/layout/navBars/breadcrumb/breadcrumb.vue b/tg-web/src/layout/navBars/breadcrumb/breadcrumb.vue deleted file mode 100644 index 609dee94cc9c347ecad94ee60c8df8b9927229b2..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/navBars/breadcrumb/breadcrumb.vue +++ /dev/null @@ -1,163 +0,0 @@ - - - - - diff --git a/tg-web/src/layout/navBars/breadcrumb/business.vue b/tg-web/src/layout/navBars/breadcrumb/business.vue deleted file mode 100644 index 2301913da33dd8992b0f3ff91a962304c9773211..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/navBars/breadcrumb/business.vue +++ /dev/null @@ -1,55 +0,0 @@ - - - - diff --git a/tg-web/src/layout/navBars/breadcrumb/closeFull.vue b/tg-web/src/layout/navBars/breadcrumb/closeFull.vue deleted file mode 100644 index 6c786bb1bc8a2e46b7ab2745e084eabeb6ea31f7..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/navBars/breadcrumb/closeFull.vue +++ /dev/null @@ -1,61 +0,0 @@ - - - - - diff --git a/tg-web/src/layout/navBars/breadcrumb/index.vue b/tg-web/src/layout/navBars/breadcrumb/index.vue deleted file mode 100644 index 2810718bb200d1cf47f84d71632730eceae90d93..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/navBars/breadcrumb/index.vue +++ /dev/null @@ -1,119 +0,0 @@ - - - - - diff --git a/tg-web/src/layout/navBars/breadcrumb/search.vue b/tg-web/src/layout/navBars/breadcrumb/search.vue deleted file mode 100644 index d2a57133ad22ff6a0288f32a48c2d5143569ed59..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/navBars/breadcrumb/search.vue +++ /dev/null @@ -1,138 +0,0 @@ - - - - - diff --git a/tg-web/src/layout/navBars/breadcrumb/setings.vue b/tg-web/src/layout/navBars/breadcrumb/setings.vue deleted file mode 100644 index 8b7db89b4f8579a21d3789814dd04631747460d5..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/navBars/breadcrumb/setings.vue +++ /dev/null @@ -1,817 +0,0 @@ - - - - - diff --git a/tg-web/src/layout/navBars/breadcrumb/user.vue b/tg-web/src/layout/navBars/breadcrumb/user.vue deleted file mode 100644 index 4f78bb500810aac823114b1733e962064d83e604..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/navBars/breadcrumb/user.vue +++ /dev/null @@ -1,317 +0,0 @@ - - - - - \ No newline at end of file diff --git a/tg-web/src/layout/navBars/breadcrumb/userNews.vue b/tg-web/src/layout/navBars/breadcrumb/userNews.vue deleted file mode 100644 index 99bf20494f17441f953f4e7bb6ab57ad26cbdeea..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/navBars/breadcrumb/userNews.vue +++ /dev/null @@ -1,115 +0,0 @@ - - - - - diff --git a/tg-web/src/layout/navBars/index.vue b/tg-web/src/layout/navBars/index.vue deleted file mode 100644 index f41a0cf9898ae1039e2abaa3cd38ef4a58b028fd..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/navBars/index.vue +++ /dev/null @@ -1,40 +0,0 @@ - - - - - diff --git a/tg-web/src/layout/navBars/tagsView/contextmenu.vue b/tg-web/src/layout/navBars/tagsView/contextmenu.vue deleted file mode 100644 index c717aae314444cf2dbe769c40e9be08d442d2b6a..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/navBars/tagsView/contextmenu.vue +++ /dev/null @@ -1,138 +0,0 @@ - - - - - diff --git a/tg-web/src/layout/navBars/tagsView/tagsView.vue b/tg-web/src/layout/navBars/tagsView/tagsView.vue deleted file mode 100644 index 83f272d171d2790c03310d79eb475c8b96e24418..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/navBars/tagsView/tagsView.vue +++ /dev/null @@ -1,734 +0,0 @@ - - - - - diff --git a/tg-web/src/layout/navMenu/horizontal.vue b/tg-web/src/layout/navMenu/horizontal.vue deleted file mode 100644 index 022668b4cd1a4db5b82bb60c9433bd1ef72c0c65..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/navMenu/horizontal.vue +++ /dev/null @@ -1,157 +0,0 @@ - - - - - diff --git a/tg-web/src/layout/navMenu/subItem.vue b/tg-web/src/layout/navMenu/subItem.vue deleted file mode 100644 index 3fcefd3d153846962ddfa102d8c17f241f6969e1..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/navMenu/subItem.vue +++ /dev/null @@ -1,48 +0,0 @@ - - - diff --git a/tg-web/src/layout/navMenu/vertical.vue b/tg-web/src/layout/navMenu/vertical.vue deleted file mode 100644 index 1bfa825eca15b6640223616782ab5fb0f23108ec..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/navMenu/vertical.vue +++ /dev/null @@ -1,101 +0,0 @@ - - - diff --git a/tg-web/src/layout/routerView/iframes.vue b/tg-web/src/layout/routerView/iframes.vue deleted file mode 100644 index 43e71c51fcde9f3db4ce5ea12be3d53e2c2871ad..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/routerView/iframes.vue +++ /dev/null @@ -1,66 +0,0 @@ - - - diff --git a/tg-web/src/layout/routerView/link.vue b/tg-web/src/layout/routerView/link.vue deleted file mode 100644 index a48f00223a0debe3401fe900fc7695585cb31472..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/routerView/link.vue +++ /dev/null @@ -1,61 +0,0 @@ - - - diff --git a/tg-web/src/layout/routerView/parent.vue b/tg-web/src/layout/routerView/parent.vue deleted file mode 100644 index db22141ab2753949d3bb1510eba35ef447da5386..0000000000000000000000000000000000000000 --- a/tg-web/src/layout/routerView/parent.vue +++ /dev/null @@ -1,88 +0,0 @@ - - - diff --git a/tg-web/src/main.ts b/tg-web/src/main.ts deleted file mode 100644 index 987cb33f79e9252b85497cc5aca20284bab6f11d..0000000000000000000000000000000000000000 --- a/tg-web/src/main.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { createApp } from 'vue'; -import pinia from '/@/stores/index'; -import App from './App.vue'; -import router from './router'; -import { directive } from '/@/utils/directive'; -import { i18n } from '@/i18n'; -import other from '/@/utils/other'; - -import ElementPlus from 'element-plus'; -import 'element-plus/dist/index.css'; -import '/@/theme/index.scss'; -import mitt from 'mitt'; -import VueGridLayout from 'vue-grid-layout'; -import naive from "@/plugins/naive.js"; - -const app = createApp(App); - -directive(app); -other.elSvg(app); - -app.use(pinia).use(router).use(ElementPlus, { i18n: i18n.global.t }).use(i18n).use(VueGridLayout).use(naive).mount('#app'); - -app.config.globalProperties.mittBus = mitt(); diff --git a/tg-web/src/plugins/naive.ts b/tg-web/src/plugins/naive.ts deleted file mode 100644 index 3325abc65dbd3ef2e9da4723a1d7c091421749ec..0000000000000000000000000000000000000000 --- a/tg-web/src/plugins/naive.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { - create, - NAlert, - NAvatar, - NBreadcrumb, - NBreadcrumbItem, - NButton, - NCard, - NCheckbox, - NDataTable, - NDescriptions, - NDescriptionsItem, - NDialog, - NDialogProvider, - NDrawer, - NDrawerContent, - NEllipsis, - NForm, - NFormItem, - NGrid, - NGi, - NH5, - NIcon, - NInput, - NInputNumber, - NLayout, - NLayoutContent, - NLayoutHeader, - NLayoutSider, - NList, - NListItem, - NMenu, - NMessageProvider, - NNotificationProvider, - NPagination, - NPopover, - NPopselect, - NRadio, - NRadioButton, - NRadioGroup, - NSelect, - NSkeleton, - NSlider, - NSpace, - NSpin, - NSwitch, - NTag, - NText, - NThing, - NTooltip, -} from "naive-ui"; - -const naive = create({ - components: [ - NButton, - NSlider, - NTooltip, - NTag, - NPopover, - NNotificationProvider, - NLayout, - NRadio, - NRadioGroup, - NLayoutContent, - NLayoutHeader, - NLayoutSider, - NIcon, - NMenu, - NSpace, - NBreadcrumb, - NBreadcrumbItem, - NPopselect, - NDataTable, - NMessageProvider, - NSelect, - NSpin, - NDialog, - NDialogProvider, - NSkeleton, - NForm, - NFormItem, - NInput, - NText, - NDrawer, - NDrawerContent, - NEllipsis, - NList, - NListItem, - NThing, - NInputNumber, - NPagination, - NDescriptions, - NDescriptionsItem, - NSwitch, - NH5, - NAlert, - NCard, - NRadioGroup, - NRadioButton, - NCheckbox, - NAvatar, - NGrid, - NGi, - ], -}); - -export default naive; diff --git a/tg-web/src/router/backEnd.ts b/tg-web/src/router/backEnd.ts deleted file mode 100644 index c690ee0decad932177e532fdf6889b20f96eaa52..0000000000000000000000000000000000000000 --- a/tg-web/src/router/backEnd.ts +++ /dev/null @@ -1,145 +0,0 @@ -import { RouteRecordRaw } from 'vue-router'; -import pinia from '/@/stores/index'; -import { useUserInfo } from '/@/stores/userInfo'; -import { useRequestOldRoutes } from '/@/stores/requestOldRoutes'; -import { NextLoading } from '/@/utils/loading'; -import { dynamicRoutes, notFoundAndNoPower } from '/@/router/route'; -import { formatTwoStageRoutes, formatFlatteningRoutes, router } from '@/router/index'; -import { useRoutesList } from '/@/stores/routesList'; -import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes'; -import { formatMenus } from '/@/utils/menu'; - -const layouModules: any = import.meta.glob('../layout/routerView/*.{vue,tsx}'); -const viewsModules: any = import.meta.glob('../views/**/*.{vue,tsx}'); - -// 后端控制路由 - -/** - * 获取目录下的 .vue、.tsx 全部文件 - * @method import.meta.glob - * @link 参考:https://cn.vitejs.dev/guide/features.html#json - */ -const dynamicViewsModules: Record = Object.assign({}, { ...layouModules }, { ...viewsModules }); - -/** - * 后端控制路由:初始化方法,防止刷新时路由丢失 - * @method NextLoading 界面 loading 动画开始执行 - * @method useUserInfo().setUserInfos() 触发初始化用户信息 pinia - * @method useRequestOldRoutes().setRequestOldRoutes() 存储接口原始路由(未处理component),根据需求选择使用 - * @method setAddRoute 添加动态路由 - * @method setFilterMenuAndCacheTagsViewRoutes 设置路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组 - */ -export async function initBackEndControlRoutes() { - // 界面 loading 动画开始执行 - if (window.nextLoading === undefined) NextLoading.start(); - // 无 token 停止执行下一步 - // if (!Session.get('token')) return false; - // 触发初始化用户信息 pinia - // https://gitee.com/lyt-top/vue-next-admin/issues/I5F1HP - await useUserInfo().setUserInfos(); - // 获取路由菜单数据 - const menu = await getBackEndControlRoutes(); - // const res = await getBackEndControlRoutes(); - // 存储接口原始路由(未处理component),根据需求选择使用 - await useRequestOldRoutes().setRequestOldRoutes(JSON.parse(JSON.stringify(menu))); - // 处理路由(component),替换 dynamicRoutes(/@/router/route)第一个顶级 children 的路由 - // dynamicRoutes[0].children = await backEndComponent(res.data); - dynamicRoutes[0].children = [...(dynamicRoutes[0].children as Array), ...await backEndComponent(menu)]; - console.log(dynamicRoutes) - // 添加动态路由 - await setAddRoute(); - // 设置路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组 - await setFilterMenuAndCacheTagsViewRoutes(); -} - -/** - * 设置路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组 - * @description 用于左侧菜单、横向菜单的显示 - * @description 用于 tagsView、菜单搜索中:未过滤隐藏的(isHide) - */ -export function setFilterMenuAndCacheTagsViewRoutes() { - const storesRoutesList = useRoutesList(pinia); - storesRoutesList.setRoutesList(dynamicRoutes[0].children as any); - setCacheTagsViewRoutes(); -} - -/** - * 缓存多级嵌套数组处理后的一维数组 - * @description 用于 tagsView、菜单搜索中:未过滤隐藏的(isHide) - */ -export function setCacheTagsViewRoutes() { - const storesTagsView = useTagsViewRoutes(pinia); - storesTagsView.setTagsViewRoutes(formatTwoStageRoutes(formatFlatteningRoutes(dynamicRoutes))[0].children); -} - -/** - * 处理路由格式及添加捕获所有路由或 404 Not found 路由 - * @description 替换 dynamicRoutes(/@/router/route)第一个顶级 children 的路由 - * @returns 返回替换后的路由数组 - */ -export function setFilterRouteEnd() { - let filterRouteEnd: any = formatTwoStageRoutes(formatFlatteningRoutes(dynamicRoutes)); - filterRouteEnd[0].children = [...filterRouteEnd[0].children, ...notFoundAndNoPower]; - return filterRouteEnd; -} - -/** - * 添加动态路由 - * @method router.addRoute - * @description 此处循环为 dynamicRoutes(/@/router/route)第一个顶级 children 的路由一维数组,非多级嵌套 - * @link 参考:https://next.router.vuejs.org/zh/api/#addroute - */ -export async function setAddRoute() { - await setFilterRouteEnd().forEach((route: RouteRecordRaw) => { - router.addRoute(route); - }); -} - -/** - * 请求后端路由菜单接口 - * @description isRequestRoutes 为 true,则开启后端控制路由 - * @returns 返回后端路由菜单数据 - */ -export async function getBackEndControlRoutes() { - const menusUpm = { code: 0, data: { list: []} } - let menus = []; - if (menusUpm && menusUpm.code === 0) { - menus = formatMenus(menusUpm.data.list) - } - return menus; -} - -/** - * 后端路由 component 转换 - * @param routes 后端返回的路由表数组 - * @returns 返回处理成函数后的 component - */ -export function backEndComponent(routes: any) { - if (!routes) return; - return routes.map((item: any) => { - if (item.component) item.component = dynamicImport(dynamicViewsModules, item.component as string); - item.children && backEndComponent(item.children); - return item; - }); -} - -/** - * 后端路由 component 转换函数 - * @param dynamicViewsModules 获取目录下的 .vue、.tsx 全部文件 - * @param component 当前要处理项 component - * @returns 返回处理成函数后的 component - */ -export function dynamicImport(dynamicViewsModules: Record, component: string) { - const keys = Object.keys(dynamicViewsModules); - const matchKeys = keys.filter((key) => { - const k = key.replace(/..\/views|../, ''); - return k.startsWith(`${component}.`) || k.startsWith(`/${component}.`); - }); - if (matchKeys?.length === 1) { - const matchKey = matchKeys[0]; - return dynamicViewsModules[matchKey]; - } - if (matchKeys?.length > 1) { - return false; - } -} diff --git a/tg-web/src/router/frontEnd.ts b/tg-web/src/router/frontEnd.ts deleted file mode 100644 index 897f2e3bdc7b51378df1408d182785e62611848a..0000000000000000000000000000000000000000 --- a/tg-web/src/router/frontEnd.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { RouteRecordRaw } from 'vue-router'; -import { storeToRefs } from 'pinia'; -import { formatTwoStageRoutes, formatFlatteningRoutes, router } from '@/router/index'; -import { dynamicRoutes, notFoundAndNoPower } from '/@/router/route'; -import pinia from '/@/stores/index'; -import { useUserInfo } from '/@/stores/userInfo'; -import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes'; -import { useRoutesList } from '/@/stores/routesList'; -import { NextLoading } from '/@/utils/loading'; - -// 前端控制路由 - -/** - * 前端控制路由:初始化方法,防止刷新时路由丢失 - * @method NextLoading 界面 loading 动画开始执行 - * @method useUserInfo(pinia).setUserInfos() 触发初始化用户信息 pinia - * @method setAddRoute 添加动态路由 - * @method setFilterMenuAndCacheTagsViewRoutes 设置递归过滤有权限的路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组 - */ -export async function initFrontEndControlRoutes() { - // 界面 loading 动画开始执行 - if (window.nextLoading === undefined) NextLoading.start(); - // 无 token 停止执行下一步 - // if (!Session.get('token')) return false; - // // 触发初始化用户信息 pinia - // // https://gitee.com/lyt-top/vue-next-admin/issues/I5F1HP - // await useUserInfo(pinia).setUserInfos(); - // 添加动态路由 - await setAddRoute(); - // 设置递归过滤有权限的路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组 - await setFilterMenuAndCacheTagsViewRoutes(); -} - -/** - * 添加动态路由 - * @method router.addRoute - * @description 此处循环为 dynamicRoutes(/@/router/route)第一个顶级 children 的路由一维数组,非多级嵌套 - * @link 参考:https://next.router.vuejs.org/zh/api/#addroute - */ -export async function setAddRoute() { - await setFilterRouteEnd().forEach((route: RouteRecordRaw) => { - router.addRoute(route); - }); -} - -/** - * 获取有当前用户权限标识的路由数组,进行对原路由的替换 - * @description 替换 dynamicRoutes(/@/router/route)第一个顶级 children 的路由 - * @returns 返回替换后的路由数组 - */ -export function setFilterRouteEnd() { - let filterRouteEnd: any = formatTwoStageRoutes(formatFlatteningRoutes(dynamicRoutes)); - filterRouteEnd[0].children = [...setFilterRoute(filterRouteEnd[0].children), ...notFoundAndNoPower]; - return filterRouteEnd; -} - -/** - * 获取当前用户权限标识去比对路由表(未处理成多级嵌套路由) - * @description 这里主要用于动态路由的添加,router.addRoute - * @link 参考:https://next.router.vuejs.org/zh/api/#addroute - * @param chil dynamicRoutes(/@/router/route)第一个顶级 children 的下路由集合 - * @returns 返回有当前用户权限标识的路由数组 - */ -export function setFilterRoute(chil: any) { - const stores = useUserInfo(pinia); - const { userInfos } = storeToRefs(stores); - let filterRoute: any = []; - chil.forEach((route: any) => { - if (route.meta.roles) { - route.meta.roles.forEach((metaRoles: any) => { - userInfos.value.roles.forEach((roles: any) => { - if (metaRoles === roles) filterRoute.push({ ...route }); - }); - }); - } - }); - return filterRoute; -} - -/** - * 缓存多级嵌套数组处理后的一维数组 - * @description 用于 tagsView、菜单搜索中:未过滤隐藏的(isHide) - */ -export function setCacheTagsViewRoutes() { - // 获取有权限的路由,否则 tagsView、菜单搜索中无权限的路由也将显示 - const stores = useUserInfo(pinia); - const storesTagsView = useTagsViewRoutes(pinia); - const { userInfos } = storeToRefs(stores); - let rolesRoutes = setFilterHasRolesMenu(dynamicRoutes, userInfos.value.roles); - // 添加到 pinia setTagsViewRoutes 中 - storesTagsView.setTagsViewRoutes(formatTwoStageRoutes(formatFlatteningRoutes(rolesRoutes))[0].children); -} - -/** - * 设置递归过滤有权限的路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组 - * @description 用于左侧菜单、横向菜单的显示 - * @description 用于 tagsView、菜单搜索中:未过滤隐藏的(isHide) - */ -export function setFilterMenuAndCacheTagsViewRoutes() { - const stores = useUserInfo(pinia); - const storesRoutesList = useRoutesList(pinia); - const { userInfos } = storeToRefs(stores); - storesRoutesList.setRoutesList(setFilterHasRolesMenu(dynamicRoutes[0].children, userInfos.value.roles)); - setCacheTagsViewRoutes(); -} - -/** - * 判断路由 `meta.roles` 中是否包含当前登录用户权限字段 - * @param roles 用户权限标识,在 userInfos(用户信息)的 roles(登录页登录时缓存到浏览器)数组 - * @param route 当前循环时的路由项 - * @returns 返回对比后有权限的路由项 - */ -export function hasRoles(roles: any, route: any) { - if (route.meta && route.meta.roles) return roles.some((role: any) => route.meta.roles.includes(role)); - else return true; -} - -/** - * 获取当前用户权限标识去比对路由表,设置递归过滤有权限的路由 - * @param routes 当前路由 children - * @param roles 用户权限标识,在 userInfos(用户信息)的 roles(登录页登录时缓存到浏览器)数组 - * @returns 返回有权限的路由数组 `meta.roles` 中控制 - */ -export function setFilterHasRolesMenu(routes: any, roles: any) { - const menu: any = []; - routes.forEach((route: any) => { - const item = { ...route }; - if (hasRoles(roles, item)) { - if (item.children) item.children = setFilterHasRolesMenu(item.children, roles); - menu.push(item); - } - }); - return menu; -} diff --git a/tg-web/src/router/index.ts b/tg-web/src/router/index.ts deleted file mode 100644 index 3a51876e59f349ebe9622e837eb50b5edd078da8..0000000000000000000000000000000000000000 --- a/tg-web/src/router/index.ts +++ /dev/null @@ -1,140 +0,0 @@ -import { createRouter, createWebHashHistory } from 'vue-router'; -import NProgress from 'nprogress'; -import 'nprogress/nprogress.css'; -import pinia from '/@/stores/index'; -import { storeToRefs } from 'pinia'; -import { useKeepALiveNames } from '/@/stores/keepAliveNames'; -import { useRoutesList } from '/@/stores/routesList'; -import { useThemeConfig } from '/@/stores/themeConfig'; -import { staticRoutes } from '/@/router/route'; -import { initFrontEndControlRoutes } from '/@/router/frontEnd'; -import { initBackEndControlRoutes } from '/@/router/backEnd'; -import { useUserInfo } from '/@/stores/userInfo'; -import { Session } from '/@/utils/storage'; - -/** - * 1、前端控制路由时:isRequestRoutes 为 false,需要写 roles,需要走 setFilterRoute 方法。 - * 2、后端控制路由时:isRequestRoutes 为 true,不需要写 roles,不需要走 setFilterRoute 方法), - * 相关方法已拆解到对应的 `backEnd.ts` 与 `frontEnd.ts`(他们互不影响,不需要同时改 2 个文件)。 - * 特别说明: - * 1、前端控制:路由菜单由前端去写(无菜单管理界面,有角色管理界面),角色管理中有 roles 属性,需返回到 userInfo 中。 - * 2、后端控制:路由菜单由后端返回(有菜单管理界面、有角色管理界面) - */ - -// 读取 `/src/stores/themeConfig.ts` 是否开启后端控制路由配置 -const storesThemeConfig = useThemeConfig(pinia); -const { themeConfig } = storeToRefs(storesThemeConfig); -const { isRequestRoutes } = themeConfig.value; - -/** - * 创建一个可以被 Vue 应用程序使用的路由实例 - * @method createRouter(options: RouterOptions): Router - * @link 参考:https://next.router.vuejs.org/zh/api/#createrouter - */ -export const router = createRouter({ - history: createWebHashHistory(), - routes: staticRoutes, -}); - -/** - * 路由多级嵌套数组处理成一维数组 - * @param arr 传入路由菜单数据数组 - * @returns 返回处理后的一维路由菜单数组 - */ -export function formatFlatteningRoutes(arr: any) { - if (arr.length <= 0) return false; - for (let i = 0; i < arr.length; i++) { - if (arr[i].children) { - arr = arr.slice(0, i + 1).concat(arr[i].children, arr.slice(i + 1)); - } - } - return arr; -} - -/** - * 一维数组处理成多级嵌套数组(只保留二级:也就是二级以上全部处理成只有二级,keep-alive 支持二级缓存) - * @description isKeepAlive 处理 `name` 值,进行缓存。顶级关闭,全部不缓存 - * @link 参考:https://v3.cn.vuejs.org/api/built-in-components.html#keep-alive - * @param arr 处理后的一维路由菜单数组 - * @returns 返回将一维数组重新处理成 `定义动态路由(dynamicRoutes)` 的格式 - */ -export function formatTwoStageRoutes(arr: any) { - if (arr.length <= 0) return false; - const newArr: any = []; - const cacheList: Array = []; - arr.forEach((v: any) => { - if (v.path === '/') { - newArr.push({ component: v.component, name: v.name, path: v.path, redirect: v.redirect, meta: v.meta, children: [] }); - } else { - // 判断是否是动态路由(xx/:id/:name),用于 tagsView 等中使用 - // 修复:https://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G - if (v.path.indexOf('/:') > -1) { - v.meta['isDynamic'] = true; - v.meta['isDynamicPath'] = v.path; - } - newArr[0].children.push({ ...v }); - // 存 name 值,keep-alive 中 include 使用,实现路由的缓存 - // 路径:/@/layout/routerView/parent.vue - if (newArr[0].meta.isKeepAlive && v.meta.isKeepAlive) { - cacheList.push(v.name); - const stores = useKeepALiveNames(pinia); - stores.setCacheKeepAlive(cacheList); - } - } - }); - return newArr; -} - -const initUserInfo = async () => { - const user: any = { code: 0 } - if (user && user.code === 0) { - const roles = ['common', 'admin']; - const userInfo = { - userName: 'test', - username: 'test', - photo: '', - time: new Date().getTime(), - roles, - authBtnList: [], - }; - Session.set('token', 'test'); - Session.set('userName', 'test'); - Session.set('userInfo', userInfo); - window.userInfo = userInfo - // 触发初始化用户信息 - useUserInfo().setUserInfos(); - } -} - -await initUserInfo(); - -// 路由加载前 -router.beforeEach(async (to, from, next) => { - NProgress.configure({ showSpinner: false }); - if (to.meta.title) NProgress.start(); - const storesRoutesList = useRoutesList(pinia); - const { routesList } = storeToRefs(storesRoutesList); - if (routesList.value.length === 0) { - if (isRequestRoutes) { - // 后端控制路由:路由数据初始化,防止刷新时丢失 - await initBackEndControlRoutes(); - // 动态添加路由:防止非首页刷新时跳转回首页的问题 - // 确保 addRoute() 时动态添加的路由已经被完全加载上去 - next({ ...to, replace: true }); - } else { - // https://gitee.com/lyt-top/vue-next-admin/issues/I5F1HP - await initFrontEndControlRoutes(); - next({ ...to, replace: true }); - } - } else { - next(); - } -}); - -// 路由加载后 -router.afterEach(() => { - NProgress.done(); -}); - -// 导出路由 -export default router; diff --git a/tg-web/src/router/route.ts b/tg-web/src/router/route.ts deleted file mode 100644 index 92b54e702befe8ddfa492df694c247adb7e7e326..0000000000000000000000000000000000000000 --- a/tg-web/src/router/route.ts +++ /dev/null @@ -1,190 +0,0 @@ -import { RouteRecordRaw } from 'vue-router'; - -/** - * 路由meta对象参数说明 - * meta: { - * title: 菜单栏及 tagsView 栏、菜单搜索名称(国际化) - * isLink: 是否超链接菜单,开启外链条件,`1、isLink: 链接地址不为空` - * isHide: 是否隐藏此路由 - * isKeepAlive: 是否缓存组件状态 - * isAffix: 是否固定在 tagsView 栏上 - * isIframe: 是否内嵌窗口,开启条件,`1、isIframe:true 2、isLink:链接地址不为空` - * roles: 当前路由权限标识,取角色管理。控制路由显示、隐藏。超级管理员:admin 普通角色:common - * icon: 菜单、tagsView 图标,阿里:加 `iconfont xxx`,fontawesome:加 `fa xxx` - * } - */ - -/** - * 定义动态路由 - * 前端添加路由,请在顶级节点的 `children 数组` 里添加 - * @description 未开启 isRequestRoutes 为 true 时使用(前端控制路由),开启时第一个顶级 children 的路由将被替换成接口请求回来的路由数据 - * @description 各字段请查看 `/@/views/system/menu/component/addMenu.vue 下的 ruleForm` - * @returns 返回路由菜单数据 - */ -export const dynamicRoutes: Array = [ - { - path: '/', - name: '/', - component: () => import('/@/layout/index.vue'), - redirect: '/home', - meta: { - isKeepAlive: true, - }, - children: [ - { - path: '/home', - name: 'home', - component: () => import('/@/views/home/index.vue'), - meta: { - title: 'message.router.home', - isLink: '', - isHide: true, - isKeepAlive: true, - isAffix: true, - isIframe: false, - roles: ['admin', 'common'], - icon: '', - }, - }, - { - path: '/strategy', - name: 'strategy', - component: () => import("/@/views/strategy/system/system.vue"), - meta: { - title: '策略管理', - isLink: '', - isHide: false, - isKeepAlive: true, - isAffix: true, - isIframe: false, - roles: ['admin', 'common'], - icon: 'ele-Operation', - }, - children: [ - { - path: '/strategy-system', - name: 'strategy-system', - component: () => import("/@/views/strategy/system/system.vue"), - meta: { - title: '系统管理', - isLink: '', - isHide: false, - isKeepAlive: true, - isAffix: true, - isIframe: false, - roles: ['admin', 'common'], - icon: '', - }, - }, - { - path: '/strategy-scenes', - name: 'strategy-scenes', - component: () => import("/@/views/strategy/scenes/scenes.vue"), - meta: { - title: '场景管理', - isLink: '', - isHide: false, - isKeepAlive: true, - isAffix: true, - isIframe: false, - roles: ['admin', 'common'], - icon: '', - }, - }, - { - path: '/strategy-experiment', - name: 'strategy-experiment', - component: () => import("/@/views/strategy/experiment/experiment.vue"), - meta: { - title: '流程管理', - isLink: '', - isHide: false, - isKeepAlive: true, - isAffix: true, - isIframe: false, - roles: ['admin', 'common'], - icon: '', - }, - }, - { - path: '/strategy-module', - name: 'strategy-module', - component: () => import("/@/views/strategy/module/module.vue"), - meta: { - title: '模块管理', - isLink: '', - isHide: false, - isKeepAlive: true, - isAffix: true, - isIframe: false, - roles: ['admin', 'common'], - icon: '', - }, - }, - ] - }, - ], - }, -]; - -/** - * 定义404、401界面 - * @link 参考:https://next.router.vuejs.org/zh/guide/essentials/history-mode.html#netlify - */ -export const notFoundAndNoPower = [ - { - path: '/:path(.*)*', - name: 'notFound', - component: () => import('/@/views/error/404.vue'), - meta: { - title: 'message.staticRoutes.notFound', - isHide: true, - }, - }, - { - path: '/401', - name: 'noPower', - component: () => import('/@/views/error/401.vue'), - meta: { - title: 'message.staticRoutes.noPower', - isHide: true, - }, - }, -]; - -/** - * 定义静态路由(默认路由) - * 此路由不要动,前端添加路由的话,请在 `dynamicRoutes 数组` 中添加 - * @description 前端控制直接改 dynamicRoutes 中的路由,后端控制不需要修改,请求接口路由数据时,会覆盖 dynamicRoutes 第一个顶级 children 的内容(全屏,不包含 layout 中的路由出口) - * @returns 返回路由菜单数据 - */ -export const staticRoutes: Array = [ - // { - // path: '/login', - // name: 'login', - // component: () => import('/@/views/login/index.vue'), - // meta: { - // title: '登录', - // }, - // }, - // /** - // * 提示:写在这里的为全屏界面,不建议写在这里 - // * 请写在 `dynamicRoutes` 路由数组中 - // */ - // { - // path: '/visualizingDemo1', - // name: 'visualizingDemo1', - // component: () => import('/@/views/visualizing/demo1.vue'), - // meta: { - // title: 'message.router.visualizingLinkDemo1', - // }, - // }, - // { - // path: '/visualizingDemo2', - // name: 'visualizingDemo2', - // component: () => import('/@/views/visualizing/demo2.vue'), - // meta: { - // title: 'message.router.visualizingLinkDemo2', - // }, - // }, -]; diff --git a/tg-web/src/stores/index.ts b/tg-web/src/stores/index.ts deleted file mode 100644 index 27c377ed5fd25a4dd52c1f739a720e9f3b316e1d..0000000000000000000000000000000000000000 --- a/tg-web/src/stores/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -// https://pinia.vuejs.org/ -import { createPinia } from 'pinia'; - -// 创建 -const pinia = createPinia(); - -// 导出 -export default pinia; diff --git a/tg-web/src/stores/interface/index.ts b/tg-web/src/stores/interface/index.ts deleted file mode 100644 index cd14a37d0915619d6b3e8cef9ae05fc3a80e4634..0000000000000000000000000000000000000000 --- a/tg-web/src/stores/interface/index.ts +++ /dev/null @@ -1,91 +0,0 @@ -/** - * 定义接口来定义对象的类型 - * `stores` 全部类型定义在这里 - */ - -// 用户信息 -export interface UserInfosState { - authBtnList: string[]; - photo: string; - roles: string[]; - time: number; - userName: string; - businessId?: number; -} -export interface UserInfosStates { - userInfos: UserInfosState; -} - -// 路由缓存列表 -export interface KeepAliveNamesState { - keepAliveNames: string[]; - cachedViews: string[]; -} - -// 后端返回原始路由(未处理时) -export interface RequestOldRoutesState { - requestOldRoutes: string[]; -} - -// TagsView 路由列表 -export interface TagsViewRoutesState { - tagsViewRoutes: string[]; - isTagsViewCurrenFull: Boolean; -} - -// 路由列表 -export interface RoutesListState { - routesList: string[]; - isColumnsMenuHover: Boolean; - isColumnsNavHover: Boolean; -} - -// 布局配置 -export interface ThemeConfigState { - isDrawer: boolean; - primary: string; - topBar: string; - topBarColor: string; - isTopBarColorGradual: boolean; - menuBar: string; - menuBarColor: string; - isMenuBarColorGradual: boolean; - columnsMenuBar: string; - columnsMenuBarColor: string; - isColumnsMenuBarColorGradual: boolean; - isCollapse: boolean; - isUniqueOpened: boolean; - isFixedHeader: boolean; - isFixedHeaderChange: boolean; - isClassicSplitMenu: boolean; - isLockScreen: boolean; - lockScreenTime: number; - isShowLogo: boolean; - isShowLogoChange: boolean; - isBreadcrumb: boolean; - isTagsview: boolean; - isBreadcrumbIcon: boolean; - isTagsviewIcon: boolean; - isCacheTagsView: boolean; - isSortableTagsView: boolean; - isShareTagsView: boolean; - isFooter: boolean; - isGrayscale: boolean; - isInvert: boolean; - isIsDark: boolean; - isWartermark: boolean; - wartermarkText: string; - tagsStyle: string; - animation: string; - columnsAsideStyle: string; - columnsAsideLayout: string; - layout: string; - isRequestRoutes: boolean; - globalTitle: string; - globalViceTitle: string; - globalI18n: string; - globalComponentSize: string; -} -export interface ThemeConfigStates { - themeConfig: ThemeConfigState; -} diff --git a/tg-web/src/stores/keepAliveNames.ts b/tg-web/src/stores/keepAliveNames.ts deleted file mode 100644 index 32e03892c845a26ece5a698b0be111857b94e343..0000000000000000000000000000000000000000 --- a/tg-web/src/stores/keepAliveNames.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { defineStore } from 'pinia'; -import { KeepAliveNamesState } from './interface'; - -/** - * 路由缓存列表 - * @methods setCacheKeepAlive 设置要缓存的路由 names(开启 Tagsview) - * @methods addCachedView 添加要缓存的路由 names(关闭 Tagsview) - * @methods delCachedView 删除要缓存的路由 names(关闭 Tagsview) - * @methods delOthersCachedViews 右键菜单`关闭其它`,删除要缓存的路由 names(关闭 Tagsview) - * @methods delAllCachedViews 右键菜单`全部关闭`,删除要缓存的路由 names(关闭 Tagsview) - */ -export const useKeepALiveNames = defineStore('keepALiveNames', { - state: (): KeepAliveNamesState => ({ - keepAliveNames: [], - cachedViews: [], - }), - actions: { - async setCacheKeepAlive(data: Array) { - this.keepAliveNames = data; - }, - async addCachedView(view: any) { - if (this.cachedViews.includes(view.name)) return; - if (view.meta.isKeepAlive) this.cachedViews.push(view.name); - }, - async delCachedView(view: any) { - const index = this.cachedViews.indexOf(view.name); - index > -1 && this.cachedViews.splice(index, 1); - }, - async delOthersCachedViews(view: any) { - if (view.meta.isKeepAlive) this.cachedViews = [view.name]; - else this.cachedViews = []; - }, - async delAllCachedViews() { - this.cachedViews = []; - }, - }, -}); diff --git a/tg-web/src/stores/requestOldRoutes.ts b/tg-web/src/stores/requestOldRoutes.ts deleted file mode 100644 index be9b5cd4ae3941b754ca1d1527ebba52d1829476..0000000000000000000000000000000000000000 --- a/tg-web/src/stores/requestOldRoutes.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { defineStore } from 'pinia'; -import { RequestOldRoutesState } from './interface'; - -/** - * 后端返回原始路由(未处理时) - * @methods setCacheKeepAlive 设置接口原始路由数据 - */ -export const useRequestOldRoutes = defineStore('requestOldRoutes', { - state: (): RequestOldRoutesState => ({ - requestOldRoutes: [], - }), - actions: { - async setRequestOldRoutes(routes: Array) { - this.requestOldRoutes = routes; - }, - }, -}); diff --git a/tg-web/src/stores/routesList.ts b/tg-web/src/stores/routesList.ts deleted file mode 100644 index 7dd2b28f549b1776846ec190c1df5aac3eb8152a..0000000000000000000000000000000000000000 --- a/tg-web/src/stores/routesList.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { defineStore } from 'pinia'; -import { RoutesListState } from './interface'; - -/** - * 路由列表 - * @methods setRoutesList 设置路由数据 - * @methods setColumnsMenuHover 设置分栏布局菜单鼠标移入 boolean - * @methods setColumnsNavHover 设置分栏布局最左侧导航鼠标移入 boolean - */ -export const useRoutesList = defineStore('routesList', { - state: (): RoutesListState => ({ - routesList: [], - isColumnsMenuHover: false, - isColumnsNavHover: false, - }), - actions: { - async setRoutesList(data: Array) { - this.routesList = data; - }, - async setColumnsMenuHover(bool: Boolean) { - this.isColumnsMenuHover = bool; - }, - async setColumnsNavHover(bool: Boolean) { - this.isColumnsNavHover = bool; - }, - }, -}); diff --git a/tg-web/src/stores/tagsViewRoutes.ts b/tg-web/src/stores/tagsViewRoutes.ts deleted file mode 100644 index 7a5e6f403e1b25dbbc0e6fa5efb53aaa5b8e1791..0000000000000000000000000000000000000000 --- a/tg-web/src/stores/tagsViewRoutes.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { defineStore } from 'pinia'; -import { TagsViewRoutesState } from './interface'; -import { Session } from '/@/utils/storage'; - -/** - * TagsView 路由列表 - * @methods setTagsViewRoutes 设置 TagsView 路由列表 - * @methods setCurrenFullscreen 设置开启/关闭全屏时的 boolean 状态 - */ -export const useTagsViewRoutes = defineStore('tagsViewRoutes', { - state: (): TagsViewRoutesState => ({ - tagsViewRoutes: [], - isTagsViewCurrenFull: false, - }), - actions: { - async setTagsViewRoutes(data: Array) { - this.tagsViewRoutes = data; - }, - setCurrenFullscreen(bool: Boolean) { - Session.set('isTagsViewCurrenFull', bool); - this.isTagsViewCurrenFull = bool; - }, - }, -}); diff --git a/tg-web/src/stores/themeConfig.ts b/tg-web/src/stores/themeConfig.ts deleted file mode 100644 index 006caaa24ef0c885b65d7f2ceece43a44db57d13..0000000000000000000000000000000000000000 --- a/tg-web/src/stores/themeConfig.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { defineStore } from 'pinia'; -import { ThemeConfigStates, ThemeConfigState } from './interface'; - -/** - * 布局配置 - * 修复:https://gitee.com/lyt-top/vue-next-admin/issues/I567R1,感谢@lanbao123 - * 2020.05.28 by lyt 优化。开发时配置不生效问题 - * 修改配置时: - * 1、需要每次都清理 `window.localStorage` 浏览器永久缓存 - * 2、或者点击布局配置最底部 `一键恢复默认` 按钮即可看到效果 - */ -export const useThemeConfig = defineStore('themeConfig', { - state: (): ThemeConfigStates => ({ - themeConfig: { - // 是否开启布局配置抽屉 - isDrawer: false, - - /** - * 全局主题 - */ - // 默认 primary 主题颜色 - primary: '#409eff', - - /** - * 菜单 / 顶栏 - * 注意:v1.0.17 版本去除设置布局切换,重置主题样式(initSetLayoutChange), - * 切换布局需手动设置样式,设置的样式自动同步各布局, - * 代码位置:/@/layout/navBars/breadcrumb/setings.vue - */ - // 默认顶栏导航背景颜色 - topBar: '#1d2128', - // 默认顶栏导航字体颜色 - topBarColor: '#ffffff', - // 是否开启顶栏背景颜色渐变 - isTopBarColorGradual: false, - // 默认菜单导航背景颜色 - menuBar: '#ffffff', - // 默认菜单导航字体颜色 - menuBarColor: '#000000', - // 是否开启菜单背景颜色渐变 - isMenuBarColorGradual: false, - // 默认分栏菜单背景颜色 - columnsMenuBar: '#545c64', - // 默认分栏菜单字体颜色 - columnsMenuBarColor: '#e6e6e6', - // 是否开启分栏菜单背景颜色渐变 - isColumnsMenuBarColorGradual: false, - - /** - * 界面设置 - */ - // 是否开启菜单水平折叠效果 - isCollapse: false, - // 是否开启菜单手风琴效果 - isUniqueOpened: false, - // 是否开启固定 Header - isFixedHeader: false, - // 初始化变量,用于更新菜单 el-scrollbar 的高度,请勿删除 - isFixedHeaderChange: false, - // 是否开启经典布局分割菜单(仅经典布局生效) - isClassicSplitMenu: false, - // 是否开启自动锁屏 - isLockScreen: false, - // 开启自动锁屏倒计时(s/秒) - lockScreenTime: 30, - - /** - * 界面显示 - */ - // 是否开启侧边栏 Logo - isShowLogo: true, - // 初始化变量,用于 el-scrollbar 的高度更新,请勿删除 - isShowLogoChange: false, - // 是否开启 Breadcrumb,强制经典、横向布局不显示 - isBreadcrumb: true, - // 是否开启 Tagsview - isTagsview: false, - // 是否开启 Breadcrumb 图标 - isBreadcrumbIcon: false, - // 是否开启 Tagsview 图标 - isTagsviewIcon: false, - // 是否开启 TagsView 缓存 - isCacheTagsView: false, - // 是否开启 TagsView 拖拽 - isSortableTagsView: true, - // 是否开启 TagsView 共用 - isShareTagsView: false, - // 是否开启 Footer 底部版权信息 - isFooter: false, - // 是否开启灰色模式 - isGrayscale: false, - // 是否开启色弱模式 - isInvert: false, - // 是否开启深色模式 - isIsDark: false, - // 是否开启水印 - isWartermark: false, - // 水印文案 - wartermarkText: 'small@小柒', - - /** - * 其它设置 - */ - // Tagsview 风格:可选值"",默认 tags-style-five - // 定义的值与 `/src/layout/navBars/tagsView/tagsView.vue` 中的 class 同名 - tagsStyle: 'tags-style-five', - // 主页面切换动画:可选值"",默认 slide-right - animation: 'slide-right', - // 分栏高亮风格:可选值"",默认 columns-round - columnsAsideStyle: 'columns-round', - // 分栏布局风格:可选值"",默认 columns-horizontal - columnsAsideLayout: 'columns-vertical', - - /** - * 布局切换 - * 注意:为了演示,切换布局时,颜色会被还原成默认,代码位置:/@/layout/navBars/breadcrumb/setings.vue - * 中的 `initSetLayoutChange(设置布局切换,重置主题样式)` 方法 - */ - // 布局切换:可选值"",默认 defaults - layout: 'classic', - - /** - * 后端控制路由 - */ - // 是否开启后端控制路由 - isRequestRoutes: false, - - /** - * 全局网站标题 / 副标题 - */ - // 网站主标题(菜单导航、浏览器当前网页标题) - globalTitle: import.meta.env.VITE_TITLE, - // 网站副标题(登录页顶部文字) - globalViceTitle: import.meta.env.VITE_TITLE, - // 默认初始语言,可选值"",默认 zh-cn - globalI18n: 'zh-cn', - // 默认全局组件大小,可选值"",默认 'large' - globalComponentSize: 'large', - }, - }), - actions: { - setThemeConfig(data: ThemeConfigState) { - this.themeConfig = data; - }, - }, -}); diff --git a/tg-web/src/stores/userInfo.ts b/tg-web/src/stores/userInfo.ts deleted file mode 100644 index 6ae3b6c44ad967f17d331a82ada78cb574c2c074..0000000000000000000000000000000000000000 --- a/tg-web/src/stores/userInfo.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { defineStore } from 'pinia'; -import Cookies from 'js-cookie'; -import { UserInfosStates } from './interface'; -import { Session } from '/@/utils/storage'; - -/** - * 用户信息 - * @methods setUserInfos 设置用户信息 - */ -export const useUserInfo = defineStore('userInfo', { - state: (): UserInfosStates => ({ - userInfos: { - userName: '', - photo: '', - time: 0, - roles: [], - authBtnList: [], - }, - }), - actions: { - async setUserInfos() { - // 存储用户信息到浏览器缓存 - if (Session.get('userInfo')) { - this.userInfos = Session.get('userInfo'); - } else { - const userInfos: any = await this.getApiUserInfo(); - this.userInfos = userInfos; - } - }, - // 模拟接口数据 - // https://gitee.com/lyt-top/vue-next-admin/issues/I5F1HP - async getApiUserInfo() { - return new Promise((resolve) => { - setTimeout(() => { - // 模拟数据,请求接口时,记得删除多余代码及对应依赖的引入 - const userName = Cookies.get('userName'); - // 模拟数据 - let defaultRoles: Array = []; - let defaultAuthBtnList: Array = []; - // admin 页面权限标识,对应路由 meta.roles,用于控制路由的显示/隐藏 - let adminRoles: Array = ['admin']; - // admin 按钮权限标识 - let adminAuthBtnList: Array = ['btn.add', 'btn.del', 'btn.edit', 'btn.link']; - // test 页面权限标识,对应路由 meta.roles,用于控制路由的显示/隐藏 - let testRoles: Array = ['common']; - // test 按钮权限标识 - let testAuthBtnList: Array = ['btn.add', 'btn.link']; - // 不同用户模拟不同的用户权限 - if (userName === 'admin') { - defaultRoles = adminRoles; - defaultAuthBtnList = adminAuthBtnList; - } else { - defaultRoles = testRoles; - defaultAuthBtnList = testAuthBtnList; - } - // 用户信息模拟数据 - const userInfos = { - userName: userName, - photo: - userName === 'admin' - ? 'https://img2.baidu.com/it/u=1978192862,2048448374&fm=253&fmt=auto&app=138&f=JPEG?w=504&h=500' - : 'https://img2.baidu.com/it/u=2370931438,70387529&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500', - time: new Date().getTime(), - roles: defaultRoles, - authBtnList: defaultAuthBtnList, - }; - resolve(userInfos); - }, 3000); - }); - }, - }, -}); diff --git a/tg-web/src/theme/app.scss b/tg-web/src/theme/app.scss deleted file mode 100644 index 8dc1bafaee2b722a20b911820058131fc83af274..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/app.scss +++ /dev/null @@ -1,286 +0,0 @@ -/* 初始化样式 -------------------------------- */ -* { - margin: 0; - padding: 0; - box-sizing: border-box; - outline: none !important; -} - -:root { - --next-color-white: #ffffff; - --next-bg-main-color: #f8f8f8; - --next-bg-color: #f5f5ff; - --next-border-color-light: #f1f2f3; - --next-color-primary-lighter: #ecf5ff; - --next-color-success-lighter: #f0f9eb; - --next-color-warning-lighter: #fdf6ec; - --next-color-danger-lighter: #fef0f0; - --next-color-dark-hover: #0000001a; - --next-color-menu-hover: rgba(0, 0, 0, 0.2); - --next-color-user-hover: rgba(0, 0, 0, 0.04); - --next-color-seting-main: #e9eef3; - --next-color-seting-aside: #d3dce6; - --next-color-seting-header: #b3c0d1; -} - -html, -body, -#app { - margin: 0; - padding: 0; - width: 100%; - height: 100%; - font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif; - font-weight: 400; - -webkit-font-smoothing: antialiased; - -webkit-tap-highlight-color: transparent; - background-color: var(--next-bg-main-color); - font-size: 14px; - overflow: hidden; - position: relative; -} - -.n-data-table { - font-size: 12px; -} - -/* 主布局样式 -------------------------------- */ -.layout-container { - width: 100%; - height: 100%; - .layout-aside { - background: var(--next-bg-menuBar); - box-shadow: 2px 0 6px rgb(0 21 41 / 1%); - height: inherit; - position: relative; - z-index: 1; - display: flex; - flex-direction: column; - overflow-x: hidden !important; - .el-scrollbar__view { - height: 100%; - overflow: hidden; - } - } - .layout-header { - padding: 0 !important; - } - .layout-main { - padding: 0 !important; - overflow: hidden; - width: 100%; - background-color: var(--next-bg-main-color); - } - .el-scrollbar { - width: 100%; - } - // 此字段多次用到,建议不删除,如需修改,请重写覆盖样式 - .layout-view-bg-white { - background: var(--el-color-white); - width: 100%; - height: 100%; - border-radius: 4px; - border: 1px solid var(--el-border-color-light, #ebeef5); - } - .layout-el-aside-br-color { - border-right: 1px solid var(--el-border-color-light, #ebeef5); - } - // pc端左侧导航样式 - .layout-aside-pc-220 { - width: 220px !important; - transition: width 0.3s ease; - } - .layout-aside-pc-64 { - width: 64px !important; - transition: width 0.3s ease; - } - .layout-aside-pc-1 { - width: 1px !important; - transition: width 0.3s ease; - } - // 手机端左侧导航样式 - .layout-aside-mobile { - position: fixed; - top: 0; - left: -220px; - width: 220px; - z-index: 9999999; - } - .layout-aside-mobile-close { - left: -220px; - transition: all 0.3s cubic-bezier(0.39, 0.58, 0.57, 1); - } - .layout-aside-mobile-open { - left: 0; - transition: all 0.3s cubic-bezier(0.22, 0.61, 0.36, 1); - } - .layout-aside-mobile-mode { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - height: 100%; - background-color: rgba(0, 0, 0, 0.5); - z-index: 9999998; - animation: error-img 0.3s; - } - .layout-scrollbar { - @extend .el-scrollbar; - padding: 15px; - } - .layout-mian-height-50 { - height: calc(100vh - 50px); - } - .layout-columns-warp { - flex: 1; - display: flex; - overflow: hidden; - } - .layout-hide { - display: none; - } -} - -/* element plus 全局样式 -------------------------------- */ -.layout-breadcrumb-seting { - .el-divider { - background-color: rgb(230, 230, 230); - } -} - -/* nprogress 进度条跟随主题颜色 -------------------------------- */ -#nprogress { - .bar { - background: var(--el-color-primary) !important; - z-index: 9999999 !important; - } -} - -/* flex 弹性布局 -------------------------------- */ -.flex { - display: flex; -} -.flex-auto { - flex: 1; - overflow: hidden; -} -.flex-center { - @extend .flex; - flex-direction: column; - width: 100%; - overflow: hidden; -} -.flex-margin { - margin: auto; -} -.flex-warp { - display: flex; - flex-wrap: wrap; - align-content: flex-start; - margin: 0 -5px; - .flex-warp-item { - padding: 5px; - .flex-warp-item-box { - width: 100%; - height: 100%; - } - } -} - -/* cursor 鼠标形状 -------------------------------- */ -// 默认 -.cursor-default { - cursor: default !important; -} -// 帮助 -.cursor-help { - cursor: help !important; -} -// 手指 -.cursor-pointer { - cursor: pointer !important; -} -// 移动 -.cursor-move { - cursor: move !important; -} - -/* 宽高 100% -------------------------------- */ -.w100 { - width: 100% !important; -} -.h100 { - height: 100% !important; -} -.vh100 { - height: 100vh !important; -} -.max100vh { - max-height: 100vh !important; -} -.min100vh { - min-height: 100vh !important; -} - -/* 颜色值 -------------------------------- */ -.color-primary { - color: var(--el-color-primary); -} -.color-success { - color: var(--el-color-success); -} -.color-warning { - color: var(--el-color-warning); -} -.color-danger { - color: var(--el-color-danger); -} -.color-info { - color: var(--el-color-info); -} - -/* 字体大小全局样式 -------------------------------- */ -@for $i from 10 through 32 { - .font#{$i} { - font-size: #{$i}px !important; - } -} - -/* 外边距、内边距全局样式 -------------------------------- */ -@for $i from 1 through 35 { - .mt#{$i} { - margin-top: #{$i}px !important; - } - .mr#{$i} { - margin-right: #{$i}px !important; - } - .mb#{$i} { - margin-bottom: #{$i}px !important; - } - .ml#{$i} { - margin-left: #{$i}px !important; - } - .pt#{$i} { - padding-top: #{$i}px !important; - } - .pr#{$i} { - padding-right: #{$i}px !important; - } - .pb#{$i} { - padding-bottom: #{$i}px !important; - } - .pl#{$i} { - padding-left: #{$i}px !important; - } -} diff --git a/tg-web/src/theme/common/transition.scss b/tg-web/src/theme/common/transition.scss deleted file mode 100644 index a03a7bb8ef50a7e9325fe8ab3aae791cdaef4f22..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/common/transition.scss +++ /dev/null @@ -1,94 +0,0 @@ -/* 页面切换动画 -------------------------------- */ -.slide-right-enter-active, -.slide-right-leave-active, -.slide-left-enter-active, -.slide-left-leave-active { - will-change: transform; - transition: all 0.3s ease; -} -// slide-right -.slide-right-enter-from { - opacity: 0; - transform: translateX(-20px); -} -.slide-right-leave-to { - opacity: 0; - transform: translateX(20px); -} -// slide-left -.slide-left-enter-from { - @extend .slide-right-leave-to; -} -.slide-left-leave-to { - @extend .slide-right-enter-from; -} -// opacitys -.opacitys-enter-active, -.opacitys-leave-active { - will-change: transform; - transition: all 0.3s ease; -} -.opacitys-enter-from, -.opacitys-leave-to { - opacity: 0; -} - -/* Breadcrumb 面包屑过渡动画 -------------------------------- */ -.breadcrumb-enter-active, -.breadcrumb-leave-active { - transition: all 0.5s ease; -} -.breadcrumb-enter-from, -.breadcrumb-leave-active { - opacity: 0; - transform: translateX(20px); -} -.breadcrumb-leave-active { - position: absolute; - z-index: -1; -} - -/* logo 过渡动画 -------------------------------- */ -@keyframes logoAnimation { - 0% { - transform: scale(0); - } - 80% { - transform: scale(1.2); - } - 100% { - transform: scale(1); - } -} - -/* 404、401 过渡动画 -------------------------------- */ -@keyframes error-num { - 0% { - transform: translateY(60px); - opacity: 0; - } - 100% { - transform: translateY(0); - opacity: 1; - } -} -@keyframes error-img { - 0% { - opacity: 0; - } - 100% { - opacity: 1; - } -} -@keyframes error-img-two { - 0% { - opacity: 1; - } - 100% { - opacity: 0; - } -} diff --git a/tg-web/src/theme/dark.scss b/tg-web/src/theme/dark.scss deleted file mode 100644 index c922da12757353079c963c42da4cf0683c132a96..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/dark.scss +++ /dev/null @@ -1,236 +0,0 @@ -/* 深色模式样式 -------------------------------- */ -[data-theme='dark'] { - // 变量(自定义时,只需修改这里的值) - --next-bg-main: #1f1f1f; - --next-color-white: #ffffff; - --next-color-disabled: #191919; - --next-color-bar: #dadada; - --next-color-primary: #303030; - --next-border-color: #424242; - --next-border-black: #333333; - --next-border-columns: #2a2a2a; - --next-color-seting: #505050; - --next-text-color-regular: #9b9da1; - --next-text-color-placeholder: #7a7a7a; - --next-color-hover: #3c3c3c; - --next-color-hover-rgba: rgba(0, 0, 0, 0.3); - - // root - --next-bg-main-color: var(--next-bg-main) !important; - --next-bg-topBar: var(--next-color-disabled) !important; - --next-bg-topBarColor: var(--next-color-bar) !important; - --next-bg-menuBar: var(--next-color-disabled) !important; - --next-bg-menuBarColor: var(--next-color-bar) !important; - --next-bg-columnsMenuBar: var(--next-color-disabled) !important; - --next-bg-columnsMenuBarColor: var(--next-color-bar) !important; - --next-border-color-light: var(--next-border-black) !important; - --next-color-primary-lighter: var(--next-color-primary) !important; - --next-color-success-lighter: var(--next-color-primary) !important; - --next-color-warning-lighter: var(--next-color-primary) !important; - --next-color-danger-lighter: var(--next-color-primary) !important; - --next-bg-color: var(--next-color-primary) !important; - --next-color-dark-hover: var(--next-color-hover) !important; - --next-color-menu-hover: var(--next-color-hover-rgba) !important; - --next-color-user-hover: var(--next-color-hover-rgba) !important; - --next-color-seting-main: var(--next-color-seting) !important; - --next-color-seting-aside: var(--next-color-hover) !important; - --next-color-seting-header: var(--next-color-primary) !important; - - // element plus - --el-color-white: var(--next-color-disabled) !important; - --el-text-color-primary: var(--next-color-bar) !important; - --el-border-color: var(--next-border-black) !important; - --el-border-color-light: var(--next-border-black) !important; - --el-border-color-lighter: var(--next-border-black) !important; - --el-border-color-extra-light: var(--el-color-primary-light-8) !important; - --el-text-color-regular: var(--next-text-color-regular) !important; - --el-bg-color: var(--next-color-disabled) !important; - --el-color-primary-light-9: var(--next-color-hover) !important; - --el-text-color-disabled: var(--next-text-color-placeholder) !important; - --el-text-color-disabled-base: var(--el-color-primary) !important; - --el-text-color-placeholder: var(--next-text-color-placeholder) !important; - --el-disabled-bg-color: var(--next-color-disabled) !important; - --el-fill-base: var(--next-color-white) !important; - --el-fill-colo: var(--next-color-hover-rgba) !important; - --el-fill-color: var(--next-color-hover-rgba) !important; - --el-fill-color-blank: var(--next-color-disabled) !important; - --el-fill-color-light: var(--next-color-hover-rgba) !important; - --el-bg-color-overlay: var(--el-color-primary-light-9) !important; - --el-mask-color: rgb(42 42 42 / 80%); - - // button - .el-button { - &:hover { - border-color: var(--next-border-color) !important; - } - } - .el-button--primary, - .el-button--info, - .el-button--danger, - .el-button--success, - .el-button--warning { - --el-button-text-color: var(--next-color-white) !important; - --el-button-hover-text-color: var(--next-color-white) !important; - --el-button-disabled-text-color: var(--next-color-white) !important; - &:hover { - border-color: var(--el-button-hover-border-color, var(--el-button-hover-bg-color)) !important; - } - } - - // drawer - .el-divider__text { - background-color: var(--el-color-white) !important; - } - .el-drawer { - border-left: 1px solid var(--next-border-color-light) !important; - } - - // tabs - .el-tabs--border-card { - background-color: var(--el-color-white) !important; - } - .el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active { - background: var(--next-color-primary-lighter); - } - - // alert / notice-bar - .home-card-item { - border: 1px solid var(--next-border-color-light) !important; - } - .el-alert, - .notice-bar { - border: 1px solid var(--next-border-color) !important; - background-color: var(--next-color-disabled) !important; - } - - // menu - .layout-aside { - border-right: 1px solid var(--next-border-color-light) !important; - } - - // colorPicker - .el-color-picker__mask { - background: unset !important; - } - .el-color-picker__trigger { - border: 1px solid var(--next-border-color-light) !important; - } - - // popper / dropdown - .el-popper { - border: 1px solid var(--next-border-color) !important; - color: var(--el-text-color-primary) !important; - .el-popper__arrow:before { - background: var(--el-color-white) !important; - border: 1px solid var(--next-border-color); - } - a { - color: var(--el-text-color-primary) !important; - } - } - .el-popper, - .el-dropdown-menu { - background: var(--el-color-white) !important; - } - .el-dropdown-menu__item:hover:not(.is-disabled) { - background: var(--el-bg-color) !important; - } - .el-dropdown-menu__item.is-disabled { - font-weight: 700 !important; - } - - // input - .el-input-group__append, - .el-input-group__prepend { - border: var(--el-input-border) !important; - border-right: none !important; - background: var(--next-color-disabled) !important; - border-left: 0 !important; - } - .el-input-number__decrease, - .el-input-number__increase { - background: var(--next-color-disabled) !important; - } - - // tag - .el-select .el-select__tags .el-tag { - background-color: var(--next-bg-color) !important; - } - - // pagination - .el-pagination.is-background .el-pager li:not(.disabled).active { - color: var(--next-color-white) !important; - } - .el-pagination.is-background .btn-next, - .el-pagination.is-background .btn-prev, - .el-pagination.is-background .el-pager li { - background-color: var(--next-bg-color); - } - - // radio - .el-radio-button:not(.is-active) .el-radio-button__inner { - border: 1px solid var(--next-border-color-light) !important; - border-left: 0 !important; - } - .el-radio-button.is-active .el-radio-button__inner { - color: var(--next-color-white) !important; - } - - // countup - .countup-card-item-flex { - color: var(--el-text-color-primary) !important; - } - - // editor - .editor-container { - .w-e-toolbar { - background: var(--el-color-white) !important; - border: 1px solid var(--next-border-color-light) !important; - .w-e-menu:hover { - background: var(--next-color-user-hover) !important; - i { - color: var(--el-text-color-primary) !important; - } - } - } - .w-e-text-container { - border: 1px solid var(--next-border-color-light) !important; - border-top: none !important; - .w-e-text { - background: var(--el-color-white) !important; - } - } - } - - // date-picker - .el-picker-panel { - background: var(--el-color-white) !important; - } - - // dialog - .el-dialog { - border: 1px solid var(--el-border-color-lighter); - .el-dialog__header { - color: var(--el-text-color-primary) !important; - } - } - - // columns - .layout-columns-aside ul .layout-columns-active { - color: var(--next-color-white) !important; - } - .layout-columns-aside { - border-right: 1px solid var(--next-border-columns); - } - - // tagsView - .tags-style-one { - .is-active { - color: var(--el-text-color-primary) !important; - } - .layout-navbars-tagsview-ul-li:hover { - border-color: var(--el-border-color-lighter) !important; - } - } -} diff --git a/tg-web/src/theme/element.scss b/tg-web/src/theme/element.scss deleted file mode 100644 index 11c720b1cd78c6d56e29c449e4533426362ea468..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/element.scss +++ /dev/null @@ -1,293 +0,0 @@ -@import 'mixins/index.scss'; - -/* Button 按钮 -------------------------------- */ -// 第三方字体图标大小 -.el-button i.el-icon, -.el-button i.iconfont, -.el-button i.fa, -.el-button--default i.iconfont, -.el-button--default i.fa { - font-size: 14px !important; - margin-right: 5px; -} -.el-button--small i.iconfont, -.el-button--small i.fa { - font-size: 12px !important; - margin-right: 5px; -} - -/* Input 输入框、InputNumber 计数器 -------------------------------- */ -.el-input { - height: 100%; -} -// 菜单搜索 -.el-autocomplete-suggestion__wrap { - max-height: 280px !important; -} - -/* Form 表单 -------------------------------- */ -.el-form { - // 用于修改弹窗时表单内容间隔太大问题,如系统设置的新增菜单弹窗里的表单内容 - .el-form-item:last-of-type { - margin-bottom: 0 !important; - } - // 修复行内表单最后一个 el-form-item 位置下移问题 - &.el-form--inline { - .el-form-item--large.el-form-item:last-of-type { - margin-bottom: 22px !important; - } - .el-form-item--default.el-form-item:last-of-type, - .el-form-item--small.el-form-item:last-of-type { - margin-bottom: 18px !important; - } - } -} - -/* Alert 警告 -------------------------------- */ -.el-alert { - border: 1px solid; -} -.el-alert__title { - word-break: break-all; -} - -/* Message 消息提示 -------------------------------- */ -.el-message { - min-width: unset !important; - padding: 15px !important; - box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.02); -} - -/* NavMenu 导航菜单 -------------------------------- */ -// 鼠标 hover 时颜色 -.el-menu-hover-bg-color { - background-color: var(--next-color-menu-hover) !important; -} -// 默认样式修改 -.el-menu { - border-right: none !important; - width: 220px; -} -.el-menu-item { - height: 56px !important; - line-height: 56px !important; -} -.el-menu-item, -.el-sub-menu__title { - color: var(--next-bg-menuBarColor); -} -// 修复点击左侧菜单折叠再展开时,宽度不跟随问题 -.el-menu--collapse { - width: 64px !important; -} -// 外部链接时 -.el-menu-item a, -.el-menu-item a:hover, -.el-menu-item i, -.el-sub-menu__title i { - color: inherit; - text-decoration: none; -} -// 第三方图标字体间距/大小设置 -.el-menu-item .iconfont, -.el-sub-menu .iconfont, -.el-menu-item .fa, -.el-sub-menu .fa { - @include generalIcon; -} -// 水平菜单、横向菜单高亮 背景色,鼠标 hover 时,有子级菜单的背景色 -.el-menu-item.is-active, -.el-sub-menu.is-active .el-sub-menu__title, -.el-sub-menu:not(.is-opened):hover .el-sub-menu__title { - @extend .el-menu-hover-bg-color; -} -.el-sub-menu.is-active.is-opened .el-sub-menu__title { - background-color: unset !important; -} -// 子级菜单背景颜色 -// .el-menu--inline { -// background: var(--next-bg-menuBar-light-1); -// } -// 水平菜单、横向菜单折叠 a 标签 -.el-popper.is-dark a { - color: var(--el-color-white) !important; - text-decoration: none; -} -// 水平菜单、横向菜单折叠背景色 -.el-popper.is-pure.is-light { - // 水平菜单 - .el-menu--vertical { - background: var(--next-bg-menuBar); - .el-sub-menu.is-active .el-sub-menu__title { - color: var(--el-menu-active-color); - } - .el-popper.is-pure.is-light { - .el-menu--vertical { - .el-sub-menu .el-sub-menu__title { - background-color: unset !important; - color: var(--next-bg-menuBarColor); - } - .el-sub-menu.is-active .el-sub-menu__title { - color: var(--el-menu-active-color); - } - } - } - } - // 横向菜单 - .el-menu--horizontal { - background: var(--next-bg-topBar); - .el-menu-item, - .el-sub-menu { - height: 50px !important; - line-height: 50px !important; - color: var(--next-bg-topBarColor); - .el-sub-menu__title { - height: 50px !important; - line-height: 50px !important; - color: var(--next-bg-topBarColor); - } - .el-popper.is-pure.is-light { - .el-menu--horizontal { - .el-sub-menu .el-sub-menu__title { - background-color: unset !important; - color: var(--next-bg-topBarColor); - } - .el-sub-menu.is-active .el-sub-menu__title { - color: var(--el-menu-active-color); - } - } - } - } - .el-menu-item.is-active, - .el-sub-menu.is-active .el-sub-menu__title { - color: var(--el-menu-active-color); - } - } -} -// 横向菜单(经典、横向)布局 -.el-menu.el-menu--horizontal { - border-bottom: none !important; - width: 100% !important; - .el-menu-item, - .el-sub-menu__title { - height: 50px !important; - color: var(--next-bg-topBarColor); - } - .el-menu-item:not(.is-active):hover, - .el-sub-menu:not(.is-active):hover .el-sub-menu__title { - color: var(--next-bg-topBarColor); - } -} - -/* Tabs 标签页 -------------------------------- */ -.el-tabs__nav-wrap::after { - height: 1px !important; -} - -/* Dropdown 下拉菜单 -------------------------------- */ -.el-dropdown-menu { - list-style: none !important; /*修复 Dropdown 下拉菜单样式问题 2022.03.04*/ -} -.el-dropdown-menu .el-dropdown-menu__item { - white-space: nowrap; - &:not(.is-disabled):hover { - background-color: var(--el-dropdown-menuItem-hover-fill); - color: var(--el-dropdown-menuItem-hover-color); - } -} - -/* Steps 步骤条 -------------------------------- */ -.el-step__icon-inner { - font-size: 30px !important; - font-weight: 400 !important; -} -.el-step__title { - font-size: 14px; -} - -/* Dialog 对话框 -------------------------------- */ -.el-overlay { - overflow: hidden; - .el-overlay-dialog { - display: flex; - align-items: center; - justify-content: center; - position: unset !important; - width: 100%; - height: 100%; - .el-dialog { - margin: 0 auto !important; - position: absolute; - .el-dialog__body { - padding: 20px !important; - } - } - } -} -.el-dialog__body { - max-height: calc(90vh - 111px) !important; - overflow-y: auto; - overflow-x: hidden; -} - -/* Card 卡片 -------------------------------- */ -.el-card__header { - padding: 15px 20px; -} - -/* Table 表格 element plus 2.2.0 版本 -------------------------------- */ -.el-table { - .el-button.is-text { - padding: 0; - } -} - -/* scrollbar -------------------------------- */ -.el-scrollbar__bar { - z-index: 4; -} -.el-scrollbar__wrap { - max-height: 100%; /*防止页面切换时,滚动条高度不变的问题(滚动条高度非滚动条滚动高度)*/ -} -.el-select-dropdown .el-scrollbar__wrap { - overflow-x: scroll !important; -} -.el-select-dropdown__wrap { - max-height: 274px !important; /*修复Select 选择器高度问题*/ -} -.el-cascader-menu__wrap.el-scrollbar__wrap { - height: 204px !important; /*修复Cascader 级联选择器高度问题*/ -} - -/* Drawer 抽屉 -------------------------------- */ -.el-drawer { - --el-drawer-padding-primary: unset !important; - .el-drawer__header { - padding: 0 15px !important; - height: 50px; - display: flex; - align-items: center; - margin-bottom: 0 !important; - border-bottom: 1px solid var(--el-border-color); - color: var(--el-text-color-primary); - } - .el-drawer__body { - width: 100%; - height: 100%; - overflow: auto; - } -} diff --git a/tg-web/src/theme/iconSelector.scss b/tg-web/src/theme/iconSelector.scss deleted file mode 100644 index 970201e4eb675156ed0f30ce805b9897f84170df..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/iconSelector.scss +++ /dev/null @@ -1,70 +0,0 @@ -/* Popover 弹出框(图标选择器) -------------------------------- */ -.icon-selector-popper { - padding: 0 !important; - .icon-selector-warp { - height: 260px; - overflow: hidden; - .icon-selector-warp-title { - height: 40px; - line-height: 40px; - padding: 0 15px; - .icon-selector-warp-title-tab { - span { - cursor: pointer; - &:hover { - color: var(--el-color-primary); - text-decoration: underline; - } - } - .span-active { - color: var(--el-color-primary); - text-decoration: underline; - } - } - } - .icon-selector-warp-row { - height: 230px; - overflow: hidden; - border-top: 1px solid var(--el-border-color); - .el-row { - padding: 15px; - } - .el-scrollbar__bar.is-horizontal { - display: none; - } - .icon-selector-warp-item { - display: flex; - border: 1px solid var(--el-border-color); - padding: 5px; - border-radius: 5px; - margin-bottom: 10px; - .icon-selector-warp-item-value { - i { - font-size: 20px; - color: var(--el-text-color-regular); - } - } - &:hover { - cursor: pointer; - background-color: var(--el-color-primary-light-9); - border: 1px solid var(--el-color-primary-light-5); - .icon-selector-warp-item-value { - i { - color: var(--el-color-primary); - } - } - } - } - .icon-selector-active { - background-color: var(--el-color-primary-light-9); - border: 1px solid var(--el-color-primary-light-5); - .icon-selector-warp-item-value { - i { - color: var(--el-color-primary); - } - } - } - } - } -} diff --git a/tg-web/src/theme/index.scss b/tg-web/src/theme/index.scss deleted file mode 100644 index c574e006f70a89ec96f668504ca7a0432f12263a..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/index.scss +++ /dev/null @@ -1,8 +0,0 @@ -@import './app.scss'; -@import 'common/transition.scss'; -@import './other.scss'; -@import './element.scss'; -@import './iconSelector.scss'; -@import './media/media.scss'; -@import './waves.scss'; -@import './dark.scss'; diff --git a/tg-web/src/theme/loading.scss b/tg-web/src/theme/loading.scss deleted file mode 100644 index c28c7b9dc9a240c988200779e424580b5aedff1b..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/loading.scss +++ /dev/null @@ -1,51 +0,0 @@ -.loading-next { - width: 100%; - height: 100%; -} -.loading-next .loading-next-box { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); -} -.loading-next .loading-next-box-warp { - width: 80px; - height: 80px; -} -.loading-next .loading-next-box-warp .loading-next-box-item { - width: 33.333333%; - height: 33.333333%; - background: var(--el-color-primary); - float: left; - animation: loading-next-animation 1.2s infinite ease; - border-radius: 1px; -} -.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(7) { - animation-delay: 0s; -} -.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(4), -.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(8) { - animation-delay: 0.1s; -} -.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(1), -.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(5), -.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(9) { - animation-delay: 0.2s; -} -.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(2), -.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(6) { - animation-delay: 0.3s; -} -.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(3) { - animation-delay: 0.4s; -} -@keyframes loading-next-animation { - 0%, - 70%, - 100% { - transform: scale3D(1, 1, 1); - } - 35% { - transform: scale3D(0, 0, 1); - } -} diff --git a/tg-web/src/theme/media/chart.scss b/tg-web/src/theme/media/chart.scss deleted file mode 100644 index 8485e39c21dcc115a5cff5ec3a6d9fefe488bb5e..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/media/chart.scss +++ /dev/null @@ -1,94 +0,0 @@ -@import './index.scss'; - -/* 页面宽度小于768px -------------------------------- */ -@media screen and (max-width: $sm) { - .big-data-down-left { - width: 100% !important; - flex-direction: unset !important; - flex-wrap: wrap; - .flex-warp-item { - min-height: 196.24px; - padding: 0 7.5px 15px 15px !important; - .flex-warp-item-box { - border: none !important; - border-bottom: 1px solid #ebeef5 !important; - } - } - } - .big-data-down-center { - width: 100% !important; - .big-data-down-center-one, - .big-data-down-center-two { - min-height: 196.24px; - padding-left: 15px !important; - .big-data-down-center-one-content { - border: none !important; - border-bottom: 1px solid #ebeef5 !important; - } - .flex-warp-item-box { - @extend .big-data-down-center-one-content; - } - } - } - .big-data-down-right { - .flex-warp-item { - .flex-warp-item-box { - border: none !important; - border-bottom: 1px solid #ebeef5 !important; - } - &:nth-of-type(2) { - padding-left: 15px !important; - } - &:last-of-type { - .flex-warp-item-box { - border: none !important; - } - } - } - } -} - -/* 页面宽度大于768px小于1200px -------------------------------- */ -@media screen and (min-width: $sm) and (max-width: $lg) { - .chart-warp-bottom { - .big-data-down-left { - width: 50% !important; - } - .big-data-down-center { - width: 50% !important; - } - .big-data-down-right { - .flex-warp-item { - width: 50% !important; - &:nth-of-type(2) { - padding-left: 7.5px !important; - } - } - } - } -} - -/* 页面宽度小于1200px -------------------------------- */ -@media screen and (max-width: $lg) { - .chart-warp-top { - .up-left { - display: none; - } - } - .chart-warp-bottom { - overflow-y: auto !important; - flex-wrap: wrap; - .big-data-down-right { - width: 100% !important; - flex-direction: unset !important; - flex-wrap: wrap; - .flex-warp-item { - min-height: 196.24px; - padding: 0 7.5px 15px 15px !important; - } - } - } -} diff --git a/tg-web/src/theme/media/cityLinkage.scss b/tg-web/src/theme/media/cityLinkage.scss deleted file mode 100644 index 1394156ee1d9a3f7d595b8ab3f056b5a1f8704d8..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/media/cityLinkage.scss +++ /dev/null @@ -1,10 +0,0 @@ -@import './index.scss'; - -/* 页面宽度小于576px -------------------------------- */ -@media screen and (max-width: $xs) { - .el-cascader__dropdown.el-popper { - overflow: auto; - max-width: 100%; - } -} diff --git a/tg-web/src/theme/media/date.scss b/tg-web/src/theme/media/date.scss deleted file mode 100644 index 1a503970683aa0c271d3c318b3b11d8821d16c2a..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/media/date.scss +++ /dev/null @@ -1,25 +0,0 @@ -@import './index.scss'; - -/* 页面宽度小于768px -------------------------------- */ -@media screen and (max-width: $sm) { - // 时间选择器适配 - .el-date-range-picker { - width: 100vw; - .el-picker-panel__body { - min-width: 100%; - .el-date-range-picker__content { - .el-date-range-picker__header div { - margin-left: 22px; - margin-right: 0px; - } - & + .el-date-range-picker__content { - .el-date-range-picker__header div { - margin-left: 0px; - margin-right: 22px; - } - } - } - } - } -} diff --git a/tg-web/src/theme/media/dialog.scss b/tg-web/src/theme/media/dialog.scss deleted file mode 100644 index 023ccae0eb6439ba7b43cba414c0dd0692bb268f..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/media/dialog.scss +++ /dev/null @@ -1,12 +0,0 @@ -@import './index.scss'; - -/* 页面宽度小于800px -------------------------------- */ -@media screen and (max-width: 800px) { - .el-dialog { - width: 90% !important; - } - .el-dialog.is-fullscreen { - width: 100% !important; - } -} diff --git a/tg-web/src/theme/media/error.scss b/tg-web/src/theme/media/error.scss deleted file mode 100644 index f35015fda673cd46a7e03dfc1a76e672f011bc8c..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/media/error.scss +++ /dev/null @@ -1,45 +0,0 @@ -@import './index.scss'; - -/* 页面宽度小于768px -------------------------------- */ -@media screen and (max-width: $sm) { - .error { - .error-flex { - flex-direction: column-reverse !important; - height: auto !important; - width: 100% !important; - } - .right, - .left { - flex: unset !important; - display: flex !important; - } - .left-item { - margin: auto !important; - } - .right img { - max-width: 450px !important; - @extend .left-item; - } - } -} - -/* 页面宽度大于768px小于992px -------------------------------- */ -@media screen and (min-width: $sm) and (max-width: $md) { - .error { - .error-flex { - padding-left: 30px !important; - } - } -} - -/* 页面宽度小于1200px -------------------------------- */ -@media screen and (max-width: $lg) { - .error { - .error-flex { - padding: 0 30px; - } - } -} diff --git a/tg-web/src/theme/media/form.scss b/tg-web/src/theme/media/form.scss deleted file mode 100644 index 6fe0a8ca2ff9e8fe9909e7f2851fc06b537b7f2c..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/media/form.scss +++ /dev/null @@ -1,18 +0,0 @@ -@import './index.scss'; - -/* 页面宽度小于576px -------------------------------- */ -@media screen and (max-width: $xs) { - .el-form-item__label { - width: 100% !important; - text-align: left !important; - // 移动端 label 右对齐问题 - justify-content: flex-start !important; - } - .el-form-item__content { - margin-left: 0 !important; - } - .el-form-item { - display: unset !important; - } -} diff --git a/tg-web/src/theme/media/home.scss b/tg-web/src/theme/media/home.scss deleted file mode 100644 index 5a2417e18d38d7cb47064cf5392ee7726ddfe66a..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/media/home.scss +++ /dev/null @@ -1,23 +0,0 @@ -@import './index.scss'; - -/* 页面宽度小于768px -------------------------------- */ -@media screen and (max-width: $sm) { - .home-media, - .home-media-sm { - margin-top: 15px; - } -} - -/* 页面宽度小于1200px -------------------------------- */ -@media screen and (max-width: $lg) { - .home-media-lg { - margin-top: 15px; - } - .home-monitor { - .flex-warp-item { - width: 33.33% !important; - } - } -} diff --git a/tg-web/src/theme/media/index.scss b/tg-web/src/theme/media/index.scss deleted file mode 100644 index 4761c0c895046f9d03ea364ac195a1f02a068408..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/media/index.scss +++ /dev/null @@ -1,15 +0,0 @@ -/* 栅格布局(媒体查询变量) -* https://developer.mozilla.org/zh-CN/docs/Learn/CSS/CSS_layout/Media_queries -* $us ≥376px 响应式栅格 -* $xs ≥576px 响应式栅格 -* $sm ≥768px 响应式栅格 -* $md ≥992px 响应式栅格 -* $lg ≥1200px 响应式栅格 -* $xl ≥1920px 响应式栅格 -------------------------------- */ -$us: 376px; -$xs: 576px; -$sm: 768px; -$md: 992px; -$lg: 1200px; -$xl: 1920px; diff --git a/tg-web/src/theme/media/layout.scss b/tg-web/src/theme/media/layout.scss deleted file mode 100644 index 77cbec0ca35812a35e42481a8c41c22bc6beab44..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/media/layout.scss +++ /dev/null @@ -1,55 +0,0 @@ -@import './index.scss'; - -/* 页面宽度小于576px -------------------------------- */ -@media screen and (max-width: $xs) { - // MessageBox 弹框 - .el-message-box { - width: 80% !important; - } -} - -/* 页面宽度小于768px -------------------------------- */ -@media screen and (max-width: $sm) { - // Breadcrumb 面包屑 - .layout-navbars-breadcrumb-hide { - display: none; - } - // 外链视图 - .layout-view-link { - a { - max-width: 80%; - text-align: center; - } - } - // 菜单搜索 - .layout-search-dialog { - .el-autocomplete { - width: 80% !important; - } - } -} - -/* 页面宽度小于1000px -------------------------------- */ -@media screen and (max-width: 1000px) { - // 布局配置 - .layout-drawer-content-flex { - position: relative; - &::after { - content: '手机版不支持切换布局'; - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1; - text-align: center; - height: 140px; - line-height: 140px; - background: rgba(255, 255, 255, 0.9); - color: #666666; - } - } -} diff --git a/tg-web/src/theme/media/login.scss b/tg-web/src/theme/media/login.scss deleted file mode 100644 index 41a015977f63e3f3d300011d719f68138e33adb8..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/media/login.scss +++ /dev/null @@ -1,63 +0,0 @@ -@import './index.scss'; - -/* 页面宽度小于992px -------------------------------- */ -@media screen and (max-width: $lg) { - .login-container { - .login-icon-group { - &::before { - content: ''; - height: 70% !important; - transition: all 0.3s ease; - } - &::after { - content: ''; - width: 100px !important; - height: 200px !important; - transition: all 0.3s ease; - } - } - } -} - -/* 页面宽度小于992px -------------------------------- */ -@media screen and (max-width: $md) { - .login-content { - right: unset !important; - left: 50% !important; - transform: translate(-50%, -50%) translate3d(0, 0, 0) !important; - } -} - -/* 页面宽度小于576px -------------------------------- */ -@media screen and (max-width: $xs) { - .login-container { - .login-icon-group { - display: none !important; - } - .login-content { - width: 100% !important; - height: 100% !important; - padding: 20px 0 !important; - border-radius: 0 !important; - box-shadow: unset !important; - border: none !important; - } - .el-form-item { - display: flex !important; - } - } -} - -/* 页面宽度小于375px -------------------------------- */ -@media screen and (max-width: $us) { - .login-container { - .login-content-title { - font-size: 18px !important; - transition: all 0.3s ease; - } - } -} diff --git a/tg-web/src/theme/media/media.scss b/tg-web/src/theme/media/media.scss deleted file mode 100644 index bed1c356a2193e185be340cd3351dd7b163a732e..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/media/media.scss +++ /dev/null @@ -1,13 +0,0 @@ -@import './login.scss'; -@import './error.scss'; -@import './layout.scss'; -@import './personal.scss'; -@import './tagsView.scss'; -@import './home.scss'; -@import './chart.scss'; -@import './form.scss'; -@import './scrollbar.scss'; -@import './pagination.scss'; -@import './dialog.scss'; -@import './cityLinkage.scss'; -@import './date.scss'; diff --git a/tg-web/src/theme/media/pagination.scss b/tg-web/src/theme/media/pagination.scss deleted file mode 100644 index 400ebaaf58b4036d3e8c7e08ad6a3e6a136d5ef8..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/media/pagination.scss +++ /dev/null @@ -1,15 +0,0 @@ -@import './index.scss'; - -/* 页面宽度小于576px -------------------------------- */ -@media screen and (max-width: $xs) { - .el-pager, - .el-pagination__jump { - display: none !important; - } -} - -// 默认居中对齐 -.el-pagination { - text-align: center !important; -} diff --git a/tg-web/src/theme/media/personal.scss b/tg-web/src/theme/media/personal.scss deleted file mode 100644 index 7ec0d4abcc85b515fcb86c4f264670191887ae02..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/media/personal.scss +++ /dev/null @@ -1,16 +0,0 @@ -@import './index.scss'; - -/* 页面宽度小于768px -------------------------------- */ -@media screen and (max-width: $sm) { - .personal-info { - padding-left: 0 !important; - margin-top: 15px; - } - .personal-recommend-col { - margin-bottom: 15px; - &:last-of-type { - margin-bottom: 0; - } - } -} diff --git a/tg-web/src/theme/media/scrollbar.scss b/tg-web/src/theme/media/scrollbar.scss deleted file mode 100644 index 968a79d59520558d40ca4ffaf6c1a4fee5929fca..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/media/scrollbar.scss +++ /dev/null @@ -1,56 +0,0 @@ -@import './index.scss'; - -/* 页面宽度小于768px -------------------------------- */ -@media screen and (max-width: $sm) { - // 滚动条的宽度 - ::-webkit-scrollbar { - width: 3px !important; - height: 3px !important; - } - ::-webkit-scrollbar-track-piece { - background-color: var(--next-bg-main-color); - } - // 滚动条的设置 - ::-webkit-scrollbar-thumb { - background-color: rgba(144, 147, 153, 0.3); - background-clip: padding-box; - min-height: 28px; - border-radius: 5px; - transition: 0.3s background-color; - } - ::-webkit-scrollbar-thumb:hover { - background-color: rgba(144, 147, 153, 0.5); - } - // element plus scrollbar - .el-scrollbar__bar.is-vertical { - width: 2px !important; - } - .el-scrollbar__bar.is-horizontal { - height: 2px !important; - } -} - -/* 页面宽度大于768px -------------------------------- */ -@media screen and (min-width: 769px) { - // 滚动条的宽度 - ::-webkit-scrollbar { - width: 7px; - height: 7px; - } - ::-webkit-scrollbar-track-piece { - background-color: var(--next-bg-main-color); - } - // 滚动条的设置 - ::-webkit-scrollbar-thumb { - background-color: rgba(144, 147, 153, 0.3); - background-clip: padding-box; - min-height: 28px; - border-radius: 5px; - transition: 0.3s background-color; - } - ::-webkit-scrollbar-thumb:hover { - background-color: rgba(144, 147, 153, 0.5); - } -} diff --git a/tg-web/src/theme/media/tagsView.scss b/tg-web/src/theme/media/tagsView.scss deleted file mode 100644 index b71674ef43f6c877d9cc48705e8fd299910de0a4..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/media/tagsView.scss +++ /dev/null @@ -1,11 +0,0 @@ -@import './index.scss'; - -/* 页面宽度小于768px -------------------------------- */ -@media screen and (max-width: $sm) { - .tags-view-form { - .tags-view-form-col { - margin-bottom: 20px; - } - } -} diff --git a/tg-web/src/theme/mixins/index.scss b/tg-web/src/theme/mixins/index.scss deleted file mode 100644 index 61f3c6bdae8ef1977cc6d352913dc55eb524d365..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/mixins/index.scss +++ /dev/null @@ -1,56 +0,0 @@ -/* 第三方图标字体间距/大小设置 -------------------------------- */ -@mixin generalIcon { - font-size: 14px !important; - display: inline-block; - vertical-align: middle; - margin-right: 5px; - width: 24px; - text-align: center; - justify-content: center; -} - -/* 文本不换行 -------------------------------- */ -@mixin text-no-wrap() { - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; -} - -/* 多行文本溢出 - ------------------------------- */ -@mixin text-ellipsis($line: 2) { - overflow: hidden; - word-break: break-all; - text-overflow: ellipsis; - display: -webkit-box; - -webkit-line-clamp: $line; - -webkit-box-orient: vertical; -} - -/* 滚动条(页面未使用) div 中使用: - ------------------------------- */ -// .test { -// @include scrollBar; -// } -@mixin scrollBar { - // 滚动条凹槽的颜色,还可以设置边框属性 - &::-webkit-scrollbar-track-piece { - background-color: #f8f8f8; - } - // 滚动条的宽度 - &::-webkit-scrollbar { - width: 9px; - height: 9px; - } - // 滚动条的设置 - &::-webkit-scrollbar-thumb { - background-color: #dddddd; - background-clip: padding-box; - min-height: 28px; - } - &::-webkit-scrollbar-thumb:hover { - background-color: #bbb; - } -} diff --git a/tg-web/src/theme/other.scss b/tg-web/src/theme/other.scss deleted file mode 100644 index a0451b8a12190911d5e559876c4dac124934d18b..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/other.scss +++ /dev/null @@ -1,36 +0,0 @@ -/* wangeditor富文本编辑器 -------------------------------- */ -.editor-container { - z-index: 9999; - .w-e-toolbar { - border: 1px solid var(--el-border-color-light, #ebeef5) !important; - border-bottom: 1px solid var(--el-border-color-light, #ebeef5) !important; - border-top-left-radius: 3px; - border-top-right-radius: 3px; - z-index: 2 !important; - } - .w-e-text-container { - border: 1px solid var(--el-border-color-light, #ebeef5) !important; - border-top: none !important; - border-bottom-left-radius: 3px; - border-bottom-right-radius: 3px; - z-index: 1 !important; - } -} - -[data-theme='dark'] { - // textarea - css vars - --w-e-textarea-bg-color: var(--el-color-white) !important; - --w-e-textarea-color: var(--el-text-color-primary) !important; - - // toolbar - css vars - --w-e-toolbar-color: var(--el-text-color-primary) !important; - --w-e-toolbar-bg-color: var(--el-color-white) !important; - --w-e-toolbar-active-color: var(--el-text-color-primary) !important; - --w-e-toolbar-active-bg-color: var(--next-color-menu-hover) !important; - --w-e-toolbar-border-color: var(--el-border-color-light, #ebeef5) !important; - - // modal - css vars - --w-e-modal-button-bg-color: var(--el-color-primary) !important; - --w-e-modal-button-border-color: var(--el-color-primary) !important; -} diff --git a/tg-web/src/theme/waves.scss b/tg-web/src/theme/waves.scss deleted file mode 100644 index 23add2cb11f157d558ffff08aed3e51aa6bd9f50..0000000000000000000000000000000000000000 --- a/tg-web/src/theme/waves.scss +++ /dev/null @@ -1,101 +0,0 @@ -/* Waves v0.6.0 -* http://fian.my.id/Waves -* -* Copyright 2014 Alfiana E. Sibuea and other contributors -* Released under the MIT license -* https://github.com/fians/Waves/blob/master/LICENSE -*/ -.waves-effect { - position: relative; - cursor: pointer; - display: inline-block; - overflow: hidden; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-tap-highlight-color: transparent; - vertical-align: middle; - z-index: 1; - will-change: opacity, transform; - transition: all 0.3s ease-out; -} -.waves-effect .waves-ripple { - position: absolute; - border-radius: 50%; - width: 20px; - height: 20px; - margin-top: -10px; - margin-left: -10px; - opacity: 0; - background: rgba(0, 0, 0, 0.2); - transition: all 0.7s ease-out; - transition-property: opacity, -webkit-transform; - transition-property: transform, opacity; - transition-property: transform, opacity, -webkit-transform; - -webkit-transform: scale(0); - transform: scale(0); - pointer-events: none; -} -.waves-effect.waves-light .waves-ripple { - background-color: rgba(255, 255, 255, 0.45); -} -.waves-effect.waves-red .waves-ripple { - background-color: rgba(244, 67, 54, 0.7); -} -.waves-effect.waves-yellow .waves-ripple { - background-color: rgba(255, 235, 59, 0.7); -} -.waves-effect.waves-orange .waves-ripple { - background-color: rgba(255, 152, 0, 0.7); -} -.waves-effect.waves-purple .waves-ripple { - background-color: rgba(156, 39, 176, 0.7); -} -.waves-effect.waves-green .waves-ripple { - background-color: rgba(76, 175, 80, 0.7); -} -.waves-effect.waves-teal .waves-ripple { - background-color: rgba(0, 150, 136, 0.7); -} -.waves-effect input[type='button'], -.waves-effect input[type='reset'], -.waves-effect input[type='submit'] { - border: 0; - font-style: normal; - font-size: inherit; - text-transform: inherit; - background: none; -} -.waves-notransition { - transition: none !important; -} -.waves-circle { - -webkit-transform: translateZ(0); - transform: translateZ(0); - -webkit-mask-image: -webkit-radial-gradient(circle, #fff 100%, #000 100%); -} -.waves-input-wrapper { - border-radius: 0.2em; - vertical-align: bottom; -} -.waves-input-wrapper .waves-button-input { - position: relative; - top: 0; - left: 0; - z-index: 1; -} -.waves-circle { - text-align: center; - width: 2.5em; - height: 2.5em; - line-height: 2.5em; - border-radius: 50%; - -webkit-mask-image: none; -} -.waves-block { - display: block; -} -a.waves-effect .waves-ripple { - z-index: -1; -} diff --git a/tg-web/src/types/globalInterface.ts b/tg-web/src/types/globalInterface.ts deleted file mode 100644 index b7ad61758d2f71e8e4575aa790919b75f2568930..0000000000000000000000000000000000000000 --- a/tg-web/src/types/globalInterface.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface valueAndLabelI { - value: string; - label: string; -} \ No newline at end of file diff --git a/tg-web/src/utils/arrayOperation.ts b/tg-web/src/utils/arrayOperation.ts deleted file mode 100644 index 1fe035939b30da50e60711ef283e5f4269be1b42..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/arrayOperation.ts +++ /dev/null @@ -1,67 +0,0 @@ -/** - * 判断两数组是否相同 - * @param news 新数据 - * @param old 源数据 - * @returns 两数组相同返回 `true`,反之则反 - */ -export function judementSameArr(news: unknown[] | string[], old: string[]): boolean { - let count = 0; - const leng = old.length; - for (let i in old) { - for (let j in news) { - if (old[i] === news[j]) count++; - } - } - return count === leng ? true : false; -} - -/** - * 判断两个对象是否相同 - * @param a 要比较的对象一 - * @param b 要比较的对象二 - * @returns 相同返回 true,反之则反 - */ -export function isObjectValueEqual(a: { [key: string]: any }, b: { [key: string]: any }) { - if (!a || !b) return false; - let aProps = Object.getOwnPropertyNames(a); - let bProps = Object.getOwnPropertyNames(b); - if (aProps.length != bProps.length) return false; - for (let i = 0; i < aProps.length; i++) { - let propName = aProps[i]; - let propA = a[propName]; - let propB = b[propName]; - if (!b.hasOwnProperty(propName)) return false; - if (propA instanceof Object) { - if (!isObjectValueEqual(propA, propB)) return false; - } else if (propA !== propB) { - return false; - } - } - return true; -} - -export function arr2Obj(arr: any[], key: string) { - const obj: any = {}; - arr.map(item => { - if (item.hasOwnProperty(key)) { - obj[key] = item[key]; - } - }) - return obj; -} - -export function sortByKey(arr: any[], key: any, desc = false) { - const compare = function(key: string, desc: boolean) { - return function(a: any, b: any) { - const aVal = a[key]; - const bVal = b[key]; - if (desc) { - return bVal - aVal; - } else { - return aVal - bVal; - } - } - } - const newArr = arr.sort(compare(key, desc)); - return newArr; -} diff --git a/tg-web/src/utils/authDirective.ts b/tg-web/src/utils/authDirective.ts deleted file mode 100644 index 5971e64fa6d8475154cc881d9f55596c64b8512f..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/authDirective.ts +++ /dev/null @@ -1,40 +0,0 @@ -import type { App } from 'vue'; -import { useUserInfo } from '/@/stores/userInfo'; -import { judementSameArr } from '/@/utils/arrayOperation'; - -/** - * 用户权限指令 - * @directive 单个权限验证(v-auth="xxx") - * @directive 多个权限验证,满足一个则显示(v-auths="[xxx,xxx]") - * @directive 多个权限验证,全部满足则显示(v-auth-all="[xxx,xxx]") - */ -export function authDirective(app: App) { - // 单个权限验证(v-auth="xxx") - app.directive('auth', { - mounted(el, binding) { - const stores = useUserInfo(); - if (!stores.userInfos.authBtnList.some((v: string) => v === binding.value)) el.parentNode.removeChild(el); - }, - }); - // 多个权限验证,满足一个则显示(v-auths="[xxx,xxx]") - app.directive('auths', { - mounted(el, binding) { - let flag = false; - const stores = useUserInfo(); - stores.userInfos.authBtnList.map((val: string) => { - binding.value.map((v: string) => { - if (val === v) flag = true; - }); - }); - if (!flag) el.parentNode.removeChild(el); - }, - }); - // 多个权限验证,全部满足则显示(v-auth-all="[xxx,xxx]") - app.directive('auth-all', { - mounted(el, binding) { - const stores = useUserInfo(); - const flag = judementSameArr(binding.value, stores.userInfos.authBtnList); - if (!flag) el.parentNode.removeChild(el); - }, - }); -} diff --git a/tg-web/src/utils/authFunction.ts b/tg-web/src/utils/authFunction.ts deleted file mode 100644 index 84c0ab468572b85c6889b3bdf37e0853096c6f20..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/authFunction.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { useUserInfo } from '/@/stores/userInfo'; -import { judementSameArr } from '/@/utils/arrayOperation'; - -/** - * 单个权限验证 - * @param value 权限值 - * @returns 有权限,返回 `true`,反之则反 - */ -export function auth(value: string): boolean { - const stores = useUserInfo(); - return stores.userInfos.authBtnList.some((v: string) => v === value); -} - -/** - * 多个权限验证,满足一个则为 true - * @param value 权限值 - * @returns 有权限,返回 `true`,反之则反 - */ -export function auths(value: Array): boolean { - let flag = false; - const stores = useUserInfo(); - stores.userInfos.authBtnList.map((val: string) => { - value.map((v: string) => { - if (val === v) flag = true; - }); - }); - return flag; -} - -/** - * 多个权限验证,全部满足则为 true - * @param value 权限值 - * @returns 有权限,返回 `true`,反之则反 - */ -export function authAll(value: Array): boolean { - const stores = useUserInfo(); - return judementSameArr(value, stores.userInfos.authBtnList); -} diff --git a/tg-web/src/utils/commonFunction.ts b/tg-web/src/utils/commonFunction.ts deleted file mode 100644 index 1c069e61993205cb6325f79d5df27b3c3821054b..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/commonFunction.ts +++ /dev/null @@ -1,65 +0,0 @@ -// 通用函数 -import useClipboard from 'vue-clipboard3'; -import { ElMessage } from 'element-plus'; -import { formatDate } from '/@/utils/formatTime'; -import { useI18n } from 'vue-i18n'; - -export default function () { - const { t } = useI18n(); - const { toClipboard } = useClipboard(); - //百分比格式化 - const percentFormat = (row: any, column: number, cellValue: any) => { - return cellValue ? `${cellValue}%` : '-'; - }; - //列表日期时间格式化 - const dateFormatYMD = (row: any, column: number, cellValue: any) => { - if (!cellValue) return '-'; - return formatDate(new Date(cellValue), 'YYYY-mm-dd'); - }; - //列表日期时间格式化 - const dateFormatYMDHMS = (row: any, column: number, cellValue: any) => { - if (!cellValue) return '-'; - return formatDate(new Date(cellValue), 'YYYY-mm-dd HH:MM:SS'); - }; - //列表日期时间格式化 - const dateFormatHMS = (row: any, column: number, cellValue: any) => { - if (!cellValue) return '-'; - let time = 0; - if (typeof row === 'number') time = row; - if (typeof cellValue === 'number') time = cellValue; - return formatDate(new Date(time * 1000), 'HH:MM:SS'); - }; - // 小数格式化 - const scaleFormat = (value: any = 0, scale: number = 4) => { - return Number.parseFloat(value).toFixed(scale); - }; - // 小数格式化 - const scale2Format = (value: any = 0) => { - return Number.parseFloat(value).toFixed(2); - }; - // 点击复制文本 - const copyText = (text: string) => { - return new Promise((resolve, reject) => { - try { - //复制 - toClipboard(text); - //下面可以设置复制成功的提示框等操作 - ElMessage.success(t('message.layout.copyTextSuccess')); - resolve(text); - } catch (e) { - //复制失败 - ElMessage.error(t('message.layout.copyTextError')); - reject(e); - } - }); - }; - return { - percentFormat, - dateFormatYMD, - dateFormatYMDHMS, - dateFormatHMS, - scaleFormat, - scale2Format, - copyText, - }; -} diff --git a/tg-web/src/utils/copy.ts b/tg-web/src/utils/copy.ts deleted file mode 100644 index fd0d06e93364099ee1eacde7e597d44224568d76..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/copy.ts +++ /dev/null @@ -1,47 +0,0 @@ -export function deepcopy(o :any) { - return JSON.parse(JSON.stringify(o)) -} - -export function copyToClipboard(value: any, successfully: any, failure: any) { - const clipboard = navigator.clipboard - if (clipboard !== undefined) { - navigator.clipboard.writeText(value).then(successfully, failure) - } else { - // fallback to execCommand - let isSuccess = false - - if (document.queryCommandSupported && document.queryCommandSupported('copy')) { - const el = document.createElement('textarea') - el.value = value - el.style.top = '0' - el.style.left = '0' - el.style.position = 'fixed' // Prevent scrolling to bottom of page in Microsoft Edge. - document.body.appendChild(el) - - el.focus() - el.select() - - // Security exception may be thrown by some browsers. - try { - if (document.execCommand('copy')) { - isSuccess = true - } - } catch (ex) { - console.warn('Copy to clipboard failed.', ex) - } finally { - document.body.removeChild(el) - } - } - - // callback - if (isSuccess) { - if (successfully !== undefined) { - successfully() - } - } else { - if (failure !== undefined) { - failure() - } - } - } -} \ No newline at end of file diff --git a/tg-web/src/utils/customDirective.ts b/tg-web/src/utils/customDirective.ts deleted file mode 100644 index c67350f555ecb3609b0ceb452df80e8a2db44dfc..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/customDirective.ts +++ /dev/null @@ -1,178 +0,0 @@ -import type { App } from 'vue'; - -/** - * 按钮波浪指令 - * @directive 默认方式:v-waves,如 `
` - * @directive 参数方式:v-waves=" |light|red|orange|purple|green|teal",如 `
` - */ -export function wavesDirective(app: App) { - app.directive('waves', { - mounted(el, binding) { - el.classList.add('waves-effect'); - binding.value && el.classList.add(`waves-${binding.value}`); - function setConvertStyle(obj: { [key: string]: unknown }) { - let style: string = ''; - for (let i in obj) { - if (obj.hasOwnProperty(i)) style += `${i}:${obj[i]};`; - } - return style; - } - function onCurrentClick(e: { [key: string]: unknown }) { - let elDiv = document.createElement('div'); - elDiv.classList.add('waves-ripple'); - el.appendChild(elDiv); - let styles = { - left: `${e.layerX}px`, - top: `${e.layerY}px`, - opacity: 1, - transform: `scale(${(el.clientWidth / 100) * 10})`, - 'transition-duration': `750ms`, - 'transition-timing-function': `cubic-bezier(0.250, 0.460, 0.450, 0.940)`, - }; - elDiv.setAttribute('style', setConvertStyle(styles)); - setTimeout(() => { - elDiv.setAttribute( - 'style', - setConvertStyle({ - opacity: 0, - transform: styles.transform, - left: styles.left, - top: styles.top, - }) - ); - setTimeout(() => { - elDiv && el.removeChild(elDiv); - }, 750); - }, 450); - } - el.addEventListener('mousedown', onCurrentClick, false); - }, - unmounted(el) { - el.addEventListener('mousedown', () => {}); - }, - }); -} - -/** - * 自定义拖动指令 - * @description 使用方式:v-drag="[dragDom,dragHeader]",如 `
` - * @description dragDom 要拖动的元素,dragHeader 要拖动的 Header 位置 - * @link 注意:https://github.com/element-plus/element-plus/issues/522 - * @lick 参考:https://blog.csdn.net/weixin_46391323/article/details/105228020?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-10&spm=1001.2101.3001.4242 - */ -export function dragDirective(app: App) { - app.directive('drag', { - mounted(el, binding) { - if (!binding.value) return false; - - const dragDom = document.querySelector(binding.value[0]) as HTMLElement; - const dragHeader = document.querySelector(binding.value[1]) as HTMLElement; - - dragHeader.onmouseover = () => (dragHeader.style.cursor = `move`); - - function down(e: any, type: string) { - // 鼠标按下,计算当前元素距离可视区的距离 - const disX = type === 'pc' ? e.clientX - dragHeader.offsetLeft : e.touches[0].clientX - dragHeader.offsetLeft; - const disY = type === 'pc' ? e.clientY - dragHeader.offsetTop : e.touches[0].clientY - dragHeader.offsetTop; - - // body当前宽度 - const screenWidth = document.body.clientWidth; - // 可见区域高度(应为body高度,可某些环境下无法获取) - const screenHeight = document.documentElement.clientHeight; - - // 对话框宽度 - const dragDomWidth = dragDom.offsetWidth; - // 对话框高度 - const dragDomheight = dragDom.offsetHeight; - - const minDragDomLeft = dragDom.offsetLeft; - const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth; - - const minDragDomTop = dragDom.offsetTop; - const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomheight; - - // 获取到的值带px 正则匹配替换 - let styL: any = getComputedStyle(dragDom).left; - let styT: any = getComputedStyle(dragDom).top; - - // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px - if (styL.includes('%')) { - styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100); - styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100); - } else { - styL = +styL.replace(/\px/g, ''); - styT = +styT.replace(/\px/g, ''); - } - - return { - disX, - disY, - minDragDomLeft, - maxDragDomLeft, - minDragDomTop, - maxDragDomTop, - styL, - styT, - }; - } - - function move(e: any, type: string, obj: any) { - let { disX, disY, minDragDomLeft, maxDragDomLeft, minDragDomTop, maxDragDomTop, styL, styT } = obj; - - // 通过事件委托,计算移动的距离 - let left = type === 'pc' ? e.clientX - disX : e.touches[0].clientX - disX; - let top = type === 'pc' ? e.clientY - disY : e.touches[0].clientY - disY; - - // 边界处理 - if (-left > minDragDomLeft) { - left = -minDragDomLeft; - } else if (left > maxDragDomLeft) { - left = maxDragDomLeft; - } - - if (-top > minDragDomTop) { - top = -minDragDomTop; - } else if (top > maxDragDomTop) { - top = maxDragDomTop; - } - - // 移动当前元素 - dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`; - } - - /** - * pc端 - * onmousedown 鼠标按下触发事件 - * onmousemove 鼠标按下时持续触发事件 - * onmouseup 鼠标抬起触发事件 - */ - dragHeader.onmousedown = (e) => { - const obj = down(e, 'pc'); - document.onmousemove = (e) => { - move(e, 'pc', obj); - }; - document.onmouseup = () => { - document.onmousemove = null; - document.onmouseup = null; - }; - }; - - /** - * 移动端 - * ontouchstart 当按下手指时,触发ontouchstart - * ontouchmove 当移动手指时,触发ontouchmove - * ontouchend 当移走手指时,触发ontouchend - */ - dragHeader.ontouchstart = (e) => { - const obj = down(e, 'app'); - document.ontouchmove = (e) => { - move(e, 'app', obj); - }; - document.ontouchend = () => { - document.ontouchmove = null; - document.ontouchend = null; - }; - }; - }, - }); -} diff --git a/tg-web/src/utils/debounce.ts b/tg-web/src/utils/debounce.ts deleted file mode 100644 index 4a82b50d166f26a4ea31fa96624c8844d01a11c4..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/debounce.ts +++ /dev/null @@ -1,11 +0,0 @@ -export function debounce(fn : Function, delay : number) { - let timer = null as any; - return function(...arg : any){ - if(timer) clearTimeout(timer) - timer && clearTimeout(timer) - timer = setTimeout(() => { - //@ts-ignore - fn.call(this,arg) - },delay) - } -} \ No newline at end of file diff --git a/tg-web/src/utils/directive.ts b/tg-web/src/utils/directive.ts deleted file mode 100644 index a75b187e01ea15ac902c401282cb48531d28feff..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/directive.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { App } from 'vue'; -import { authDirective } from '/@/utils/authDirective'; -import { wavesDirective, dragDirective } from '/@/utils/customDirective'; - -/** - * 导出指令方法:v-xxx - * @methods authDirective 用户权限指令,用法:v-auth - * @methods wavesDirective 按钮波浪指令,用法:v-waves - * @methods dragDirective 自定义拖动指令,用法:v-drag - */ -export function directive(app: App) { - // 用户权限指令 - authDirective(app); - // 按钮波浪指令 - wavesDirective(app); - // 自定义拖动指令 - dragDirective(app); -} diff --git a/tg-web/src/utils/download.ts b/tg-web/src/utils/download.ts deleted file mode 100644 index 0085db38db802bb9a4effd76b49e4a34bd2ec248..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/download.ts +++ /dev/null @@ -1,17 +0,0 @@ -function downloadData(data: string, filename: string, type: string) { - const file = new Blob([data], { type: type }); - const a = document.createElement("a"); - const url = URL.createObjectURL(file); - a.href = url; - a.download = filename; - document.body.appendChild(a); - a.click(); - setTimeout(function () { - document.body.removeChild(a); - window.URL.revokeObjectURL(url); - }, 0); -} - -export { - downloadData -} \ No newline at end of file diff --git a/tg-web/src/utils/filter.ts b/tg-web/src/utils/filter.ts deleted file mode 100644 index 95271c8cc9f24681daaafcd0b3165e64711aa8cf..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/filter.ts +++ /dev/null @@ -1,45 +0,0 @@ - -/** - * Formatting time - */ -const formatDate = (value: any, fmt: any) => { - fmt = fmt || 'YYYY-MM-DD HH:mm:ss' - if (value === null) { - return '-' - } else { - // return dayjs(formatISODate(value)).format(fmt) - } -} -/** - * Formatting iso date - */ -const formatISODate =( date: any) => { - const [datetime, timezone] = date.split('+') - if (!timezone || timezone.indexOf(':') >= 0) return date - const hourOfTz = timezone.substring(0, 2) || '00' - const secondOfTz = timezone.substring(2, 4) || '00' - return `${datetime}+${hourOfTz}:${secondOfTz}` -} -/** - * filter null - */ -const filterNull = (value: any) => { - if (value === null || value === '') { - return '-' - } else { - return value - } -} - -function dateFilter(date: any) { - if (!date) { - return '-' - } - - const d = new Date(date) - return d.toLocaleString() -} - -export { - formatDate, filterNull, dateFilter -} \ No newline at end of file diff --git a/tg-web/src/utils/formatTime.ts b/tg-web/src/utils/formatTime.ts deleted file mode 100644 index e0205ff1fbf0f60e40cd24615e67779c4489cc15..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/formatTime.ts +++ /dev/null @@ -1,148 +0,0 @@ -/** - * 时间日期转换 - * @param date 当前时间,new Date() 格式 - * @param format 需要转换的时间格式字符串 - * @description format 字符串随意,如 `YYYY-mm、YYYY-mm-dd` - * @description format 季度:"YYYY-mm-dd HH:MM:SS QQQQ" - * @description format 星期:"YYYY-mm-dd HH:MM:SS WWW" - * @description format 几周:"YYYY-mm-dd HH:MM:SS ZZZ" - * @description format 季度 + 星期 + 几周:"YYYY-mm-dd HH:MM:SS WWW QQQQ ZZZ" - * @returns 返回拼接后的时间字符串 - */ -export function formatDate(date: Date, format: string): string { - let we = date.getDay(); // 星期 - let z = getWeek(date); // 周 - let qut = Math.floor((date.getMonth() + 3) / 3).toString(); // 季度 - const opt: { [key: string]: string } = { - 'Y+': date.getFullYear().toString(), // 年 - 'm+': (date.getMonth() + 1).toString(), // 月(月份从0开始,要+1) - 'd+': date.getDate().toString(), // 日 - 'H+': date.getHours().toString(), // 时 - 'M+': date.getMinutes().toString(), // 分 - 'S+': date.getSeconds().toString(), // 秒 - 'q+': qut, // 季度 - }; - // 中文数字 (星期) - const week: { [key: string]: string } = { - '0': '日', - '1': '一', - '2': '二', - '3': '三', - '4': '四', - '5': '五', - '6': '六', - }; - // 中文数字(季度) - const quarter: { [key: string]: string } = { - '1': '一', - '2': '二', - '3': '三', - '4': '四', - }; - if (/(W+)/.test(format)) - format = format.replace(RegExp.$1, RegExp.$1.length > 1 ? (RegExp.$1.length > 2 ? '星期' + week[we] : '周' + week[we]) : week[we]); - if (/(Q+)/.test(format)) format = format.replace(RegExp.$1, RegExp.$1.length == 4 ? '第' + quarter[qut] + '季度' : quarter[qut]); - if (/(Z+)/.test(format)) format = format.replace(RegExp.$1, RegExp.$1.length == 3 ? '第' + z + '周' : z + ''); - for (let k in opt) { - let r = new RegExp('(' + k + ')').exec(format); - // 若输入的长度不为1,则前面补零 - if (r) format = format.replace(r[1], RegExp.$1.length == 1 ? opt[k] : opt[k].padStart(RegExp.$1.length, '0')); - } - return format; -} - -/** - * 获取当前日期是第几周 - * @param dateTime 当前传入的日期值 - * @returns 返回第几周数字值 - */ -export function getWeek(dateTime: Date): number { - let temptTime = new Date(dateTime.getTime()); - // 周几 - let weekday = temptTime.getDay() || 7; - // 周1+5天=周六 - temptTime.setDate(temptTime.getDate() - weekday + 1 + 5); - let firstDay = new Date(temptTime.getFullYear(), 0, 1); - let dayOfWeek = firstDay.getDay(); - let spendDay = 1; - if (dayOfWeek != 0) spendDay = 7 - dayOfWeek + 1; - firstDay = new Date(temptTime.getFullYear(), 0, 1 + spendDay); - let d = Math.ceil((temptTime.valueOf() - firstDay.valueOf()) / 86400000); - let result = Math.ceil(d / 7); - return result; -} - -/** - * 将时间转换为 `几秒前`、`几分钟前`、`几小时前`、`几天前` - * @param param 当前时间,new Date() 格式或者字符串时间格式 - * @param format 需要转换的时间格式字符串 - * @description param 10秒: 10 * 1000 - * @description param 1分: 60 * 1000 - * @description param 1小时: 60 * 60 * 1000 - * @description param 24小时:60 * 60 * 24 * 1000 - * @description param 3天: 60 * 60* 24 * 1000 * 3 - * @returns 返回拼接后的时间字符串 - */ -export function formatPast(param: string | Date, format: string = 'YYYY-mm-dd'): string { - // 传入格式处理、存储转换值 - let t: any, s: number; - // 获取js 时间戳 - let time: number = new Date().getTime(); - // 是否是对象 - typeof param === 'string' || 'object' ? (t = new Date(param).getTime()) : (t = param); - // 当前时间戳 - 传入时间戳 - time = Number.parseInt(`${time - t}`); - if (time < 10000) { - // 10秒内 - return '刚刚'; - } else if (time < 60000 && time >= 10000) { - // 超过10秒少于1分钟内 - s = Math.floor(time / 1000); - return `${s}秒前`; - } else if (time < 3600000 && time >= 60000) { - // 超过1分钟少于1小时 - s = Math.floor(time / 60000); - return `${s}分钟前`; - } else if (time < 86400000 && time >= 3600000) { - // 超过1小时少于24小时 - s = Math.floor(time / 3600000); - return `${s}小时前`; - } else if (time < 259200000 && time >= 86400000) { - // 超过1天少于3天内 - s = Math.floor(time / 86400000); - return `${s}天前`; - } else { - // 超过3天 - let date = typeof param === 'string' || 'object' ? new Date(param) : param; - return formatDate(date, format); - } -} - -/** - * 时间问候语 - * @param param 当前时间,new Date() 格式 - * @description param 调用 `formatAxis(new Date())` 输出 `上午好` - * @returns 返回拼接后的时间字符串 - */ -export function formatAxis(param: Date): string { - let hour: number = new Date(param).getHours(); - if (hour < 6) return '凌晨好'; - else if (hour < 9) return '早上好'; - else if (hour < 12) return '上午好'; - else if (hour < 14) return '中午好'; - else if (hour < 17) return '下午好'; - else if (hour < 19) return '傍晚好'; - else if (hour < 22) return '晚上好'; - else return '夜里好'; -} - - //格林尼治2019-03-19T16:00:00.000Z ==>> 2019-03-20 00:00:00 与北京时间8小时时差 -export function ISOtoBeijing(param: string, len = 10): string { - if (param === "") { - return ""; - } else { - var dateee = new Date(param).toJSON(); - var date = new Date(+new Date(dateee) + 8 * 3600 * 1000).toISOString().replace(/T/g, ' ').replace(/\.[\d]{3}Z/, ''); - return date.slice(0, len); - } -} \ No newline at end of file diff --git a/tg-web/src/utils/getStyleSheets.ts b/tg-web/src/utils/getStyleSheets.ts deleted file mode 100644 index 90252c3700575d9b7829218583ed72130f2efd47..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/getStyleSheets.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { nextTick } from 'vue'; -import * as svg from '@element-plus/icons-vue'; - -// 获取阿里字体图标 -const getAlicdnIconfont = () => { - return new Promise((resolve, reject) => { - nextTick(() => { - const styles: any = document.styleSheets; - let sheetsList = []; - let sheetsIconList = []; - for (let i = 0; i < styles.length; i++) { - if (styles[i].href && styles[i].href.indexOf('at.alicdn.com') > -1) { - sheetsList.push(styles[i]); - } - } - for (let i = 0; i < sheetsList.length; i++) { - for (let j = 0; j < sheetsList[i].cssRules.length; j++) { - if (sheetsList[i].cssRules[j].selectorText && sheetsList[i].cssRules[j].selectorText.indexOf('.icon-') > -1) { - sheetsIconList.push( - `${sheetsList[i].cssRules[j].selectorText.substring(1, sheetsList[i].cssRules[j].selectorText.length).replace(/\:\:before/gi, '')}` - ); - } - } - } - if (sheetsIconList.length > 0) resolve(sheetsIconList); - else reject('未获取到值,请刷新重试'); - }); - }); -}; - -// 初始化获取 css 样式,获取 element plus 自带 svg 图标,增加了 ele- 前缀,使用时:ele-Aim -const getElementPlusIconfont = () => { - return new Promise((resolve, reject) => { - nextTick(() => { - const icons = svg as any; - const sheetsIconList = []; - for (const i in icons) { - sheetsIconList.push(`ele-${icons[i].name}`); - } - if (sheetsIconList.length > 0) resolve(sheetsIconList); - else reject('未获取到值,请刷新重试'); - }); - }); -}; - -// 初始化获取 css 样式,这里使用 fontawesome 的图标 -const getAwesomeIconfont = () => { - return new Promise((resolve, reject) => { - nextTick(() => { - const styles: any = document.styleSheets; - let sheetsList = []; - let sheetsIconList = []; - for (let i = 0; i < styles.length; i++) { - if (styles[i].href && styles[i].href.indexOf('netdna.bootstrapcdn.com') > -1) { - sheetsList.push(styles[i]); - } - } - for (let i = 0; i < sheetsList.length; i++) { - for (let j = 0; j < sheetsList[i].cssRules.length; j++) { - if ( - sheetsList[i].cssRules[j].selectorText && - sheetsList[i].cssRules[j].selectorText.indexOf('.fa-') === 0 && - sheetsList[i].cssRules[j].selectorText.indexOf(',') === -1 - ) { - if (/::before/.test(sheetsList[i].cssRules[j].selectorText)) { - sheetsIconList.push( - `${sheetsList[i].cssRules[j].selectorText.substring(1, sheetsList[i].cssRules[j].selectorText.length).replace(/\:\:before/gi, '')}` - ); - } - } - } - } - if (sheetsIconList.length > 0) resolve(sheetsIconList.reverse()); - else reject('未获取到值,请刷新重试'); - }); - }); -}; - -/** - * 获取字体图标 `document.styleSheets` - * @method ali 获取阿里字体图标 `` - * @method ele 获取 element plus 自带图标 `` - * @method ali 获取 fontawesome 的图标 `` - */ -const initIconfont = { - // iconfont - ali: () => { - return getAlicdnIconfont(); - }, - // element plus - ele: () => { - return getElementPlusIconfont(); - }, - // fontawesome - awe: () => { - return getAwesomeIconfont(); - }, -}; - -// 导出方法 -export default initIconfont; diff --git a/tg-web/src/utils/index.ts b/tg-web/src/utils/index.ts deleted file mode 100644 index f832053143f8fd0b9d19d9748ea43fb5a940a056..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -export const typeOptions = [ - { - value: "string", - label: "string", - }, - { - value: "int", - label: "int", - }, - { - value: "float", - label: "float", - }, - { - value: "bool", - label: "bool", - }, -] as any[] diff --git a/tg-web/src/utils/loading.ts b/tg-web/src/utils/loading.ts deleted file mode 100644 index c23fb775374cfa674220866c07a382b95496a6ce..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/loading.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { nextTick } from 'vue'; -import '/@/theme/loading.scss'; - -/** - * 页面全局 Loading - * @method start 创建 loading - * @method done 移除 loading - */ -export const NextLoading = { - // 创建 loading - start: () => { - const bodys: Element = document.body; - const div = document.createElement('div'); - div.setAttribute('class', 'loading-next'); - const htmls = ` -
-
-
-
-
-
-
-
-
-
-
-
-
- `; - div.innerHTML = htmls; - bodys.insertBefore(div, bodys.childNodes[0]); - window.nextLoading = true; - }, - // 移除 loading - done: () => { - nextTick(() => { - window.nextLoading = false; - const el = document.querySelector('.loading-next'); - el?.parentNode?.removeChild(el); - }); - }, -}; diff --git a/tg-web/src/utils/menu.ts b/tg-web/src/utils/menu.ts deleted file mode 100644 index eb3cc7f21db888fd14671ed2059e7e8450e3bdab..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/menu.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { sortByKey } from '../utils/arrayOperation'; -// 只处理到二级菜单 -export function formatMenus(menusUpm: Array) { - menusUpm = sortByKey(menusUpm, 'sortVal'); - const rootMenu: any[] = []; - menusUpm.map((item: any) => { - if (item.pid === 0) { - rootMenu.push(makeMenu(item)); - } - }) - for (let i = 0; i < rootMenu.length; i++) { - const rootMenuItem = rootMenu[i]; - const children: any[] = []; - for (let i = 0; i < menusUpm.length; i++) { - const subMenu = menusUpm[i]; - const isMenu = subMenu.isMenu; - if (!isMenu || subMenu.pid !== rootMenuItem.id) { - continue; - } - children.push(makeMenu(subMenu)); - } - rootMenuItem.children = sortByKey(children, 'sortVal'); - } - return rootMenu; -} - -function makeMenu(menuUpm: any) { - const childMenu = { - id: menuUpm.id, - path: menuUpm.url, - name: menuUpm.name, - component: menuUpm.featureKey, - meta: { - title: menuUpm.name, - isLink: '', - isHide: false, - isKeepAlive: true, - isAffix: true, - isIframe: false, - roles: ['common'], - icon: menuUpm.icon, - }, - } - return childMenu; -} \ No newline at end of file diff --git a/tg-web/src/utils/normalRules.ts b/tg-web/src/utils/normalRules.ts deleted file mode 100644 index 0959d7d2254e096fe9782a120f587421d2d616a9..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/normalRules.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const normal = (title: string) => ([{ - required: true, - message: `请输入${title}`, - trigger: "blur", -}]) diff --git a/tg-web/src/utils/other.ts b/tg-web/src/utils/other.ts deleted file mode 100644 index 6bb4fbde8394f892db616499789bc1b7554eebde..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/other.ts +++ /dev/null @@ -1,200 +0,0 @@ -import { nextTick } from 'vue'; -import type { App } from 'vue'; -import * as svg from '@element-plus/icons-vue'; -import router from '/@/router/index'; -import pinia from '/@/stores/index'; -import { storeToRefs } from 'pinia'; -import { useThemeConfig } from '/@/stores/themeConfig'; -import { i18n } from '/@/i18n/index'; -import { Local } from '/@/utils/storage'; -import SvgIcon from '/@/components/svgIcon/index.vue'; - -/** - * 导出全局注册 element plus svg 图标 - * @param app vue 实例 - * @description 使用:https://element-plus.gitee.io/zh-CN/component/icon.html - */ -export function elSvg(app: App) { - const icons = svg as any; - for (const i in icons) { - app.component(`ele-${icons[i].name}`, icons[i]); - } - app.component('SvgIcon', SvgIcon); -} - -/** - * 设置浏览器标题国际化 - * @method const title = useTitle(); ==> title() - */ -export function useTitle() { - const stores = useThemeConfig(pinia); - const { themeConfig } = storeToRefs(stores); - nextTick(() => { - let webTitle = ''; - let globalTitle: string = themeConfig.value.globalTitle; - const { path, meta } = router.currentRoute.value; - if (path === '/login') { - webTitle = meta.title; - } else { - webTitle = setTagsViewNameI18n(router.currentRoute.value); - } - document.title = `${webTitle} - ${globalTitle}` || globalTitle; - }); -} - -/** - * 设置 自定义 tagsView 名称、 自定义 tagsView 名称国际化 - * @param params 路由 query、params 中的 tagsViewName - * @returns 返回当前 tagsViewName 名称 - */ -export function setTagsViewNameI18n(item: any) { - let tagsViewName: any = ''; - const { query, params, meta } = item; - if (query?.tagsViewName || params?.tagsViewName) { - if (/\/zh-cn|en|zh-tw\//.test(query?.tagsViewName) || /\/(zh-cn|en|zh-tw)\//.test(params?.tagsViewName)) { - // 国际化 - const urlTagsParams = (query?.tagsViewName && JSON.parse(query?.tagsViewName)) || (params?.tagsViewName && JSON.parse(params?.tagsViewName)); - tagsViewName = urlTagsParams[i18n.global.locale]; - } else { - // 非国际化 - tagsViewName = query?.tagsViewName || params?.tagsViewName; - } - } else { - // 非自定义 tagsView 名称 - tagsViewName = i18n.global.t(meta.title); - } - return tagsViewName; -} - -/** - * 图片懒加载 - * @param el dom 目标元素 - * @param arr 列表数据 - * @description data-xxx 属性用于存储页面或应用程序的私有自定义数据 - */ -export const lazyImg = (el: any, arr: any) => { - const io = new IntersectionObserver((res) => { - res.forEach((v: any) => { - if (v.isIntersecting) { - const { img, key } = v.target.dataset; - v.target.src = img; - v.target.onload = () => { - io.unobserve(v.target); - arr[key]['loading'] = false; - }; - } - }); - }); - nextTick(() => { - document.querySelectorAll(el).forEach((img) => io.observe(img)); - }); -}; - -/** - * 全局组件大小 - * @returns 返回 `window.localStorage` 中读取的缓存值 `globalComponentSize` - */ -export const globalComponentSize = (): string => { - const stores = useThemeConfig(pinia); - const { themeConfig } = storeToRefs(stores); - return Local.get('themeConfig')?.globalComponentSize || themeConfig.value?.globalComponentSize; -}; - -/** - * 对象深克隆 - * @param obj 源对象 - * @returns 克隆后的对象 - */ -export function deepClone(obj: any) { - let newObj: any; - try { - newObj = obj.push ? [] : {}; - } catch (error) { - newObj = {}; - } - for (let attr in obj) { - if (obj[attr] && typeof obj[attr] === 'object') { - newObj[attr] = deepClone(obj[attr]); - } else { - newObj[attr] = obj[attr]; - } - } - return newObj; -} - -/** - * 判断是否是移动端 - */ -export function isMobile() { - if ( - navigator.userAgent.match( - /('phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone')/i - ) - ) { - return true; - } else { - return false; - } -} - -/** - * 判断数组对象中所有属性是否为空,为空则删除当前行对象 - * @description @感谢大黄 - * @param list 数组对象 - * @returns 删除空值后的数组对象 - */ -export function handleEmpty(list: any) { - const arr = []; - for (const i in list) { - const d = []; - for (const j in list[i]) { - d.push(list[i][j]); - } - const leng = d.filter((item) => item === '').length; - if (leng !== d.length) { - arr.push(list[i]); - } - } - return arr; -} - -/** - * 统一批量导出 - * @method elSvg 导出全局注册 element plus svg 图标 - * @method useTitle 设置浏览器标题国际化 - * @method setTagsViewNameI18n 设置 自定义 tagsView 名称、 自定义 tagsView 名称国际化 - * @method lazyImg 图片懒加载 - * @method globalComponentSize() element plus 全局组件大小 - * @method deepClone 对象深克隆 - * @method isMobile 判断是否是移动端 - * @method handleEmpty 判断数组对象中所有属性是否为空,为空则删除当前行对象 - */ -const other = { - elSvg: (app: App) => { - elSvg(app); - }, - useTitle: () => { - useTitle(); - }, - setTagsViewNameI18n(route: any) { - return setTagsViewNameI18n(route); - }, - lazyImg: (el: any, arr: any) => { - lazyImg(el, arr); - }, - globalComponentSize: () => { - return globalComponentSize(); - }, - deepClone: (obj: any) => { - return deepClone(obj); - }, - isMobile: () => { - return isMobile(); - }, - handleEmpty: (list: any) => { - return handleEmpty(list); - }, -}; - -// 统一批量导出 -export default other; diff --git a/tg-web/src/utils/param.ts b/tg-web/src/utils/param.ts deleted file mode 100644 index b6d6ba772100399e965f538c7bcfe6cc1ba98a07..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/param.ts +++ /dev/null @@ -1,15 +0,0 @@ - -const REF_KEY = '$ref' - -export function fromRef(o: any) { - if (o[REF_KEY] === undefined) { - o[REF_KEY] = '' - } - return o[REF_KEY] -} - -export function toRef(s: any) { - return { - [REF_KEY]: s - } -} diff --git a/tg-web/src/utils/random.ts b/tg-web/src/utils/random.ts deleted file mode 100644 index 44169c486f049e6bcec536674a21a051d1bcc4c8..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/random.ts +++ /dev/null @@ -1,7 +0,0 @@ -export function Random(min: number, max: number) { - return Math.round(Math.random() * (max - min)) + min -} - -export function getRandomCode() { - return Random(0, 9999999) -} diff --git a/tg-web/src/utils/renderComponents.ts b/tg-web/src/utils/renderComponents.ts deleted file mode 100644 index 8cb7499dc7edbd467bf586bb55c2b51cf0738156..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/renderComponents.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { h ,withModifiers} from "vue"; -import { NTooltip, NIcon, NIconWrapper } from "naive-ui"; -import { - SyncSharp, - ArrowDownCircleOutline, - AddCircleOutline, - RemoveCircleOutline, - EllipsisHorizontalCircleOutline, - PauseCircleOutline, - TimeOutline, - ReloadCircleOutline, - NavigateCircleOutline, -} from "@vicons/ionicons5"; - -export const renderTooltip = ( - text: string, - click: () => void, - size?: number -) => { - return h(NTooltip, null, { - default: () => text, - trigger: () => { - return h( - "p", - { - onClick: withModifiers(click, ['stop']), - - style: { - color: colorAndType[text].color, - margin: "0", - cursor:"pointer" - }, - }, - { default: () => text } - // NIconWrapper, - // { - // style: { - // margin: "0 5px", - // }, - // color: colorAndType[text].color, - // }, - // [ - // h( - // NIcon, - // { - // size: size ? size : 24, - // onClick: click, - // }, - // { - // default: () => h(colorAndType[text].icon), - // } - // ), - // ] - ); - }, - }); -}; - -const colorAndType = { - ["修改"]: { - icon: SyncSharp, - color: "#2080f0", - }, - ["提交"]: { - icon: SyncSharp, - color: "#2080f0", - }, - ["导出"]: { - icon: ArrowDownCircleOutline, - color: "#2080f0", - }, - ["导入"]: { - icon: ArrowDownCircleOutline, - color:"#2080f0", - }, - ["复制"]: { - icon: AddCircleOutline, - color: "#2080f0", - }, - ["删除"]: { - icon: RemoveCircleOutline, - color: "#d03050", - }, - ["详情"]: { - icon: EllipsisHorizontalCircleOutline, - color: "#2080f0", - }, - ["更新"]: { - icon: ReloadCircleOutline, - color: "#2080f0", - }, - ["部署"]: { - icon: PauseCircleOutline, - color: "#2080f0", - }, - ["下线"]: { - icon: ArrowDownCircleOutline, - color: "#2080f0", - }, - ["运行历史"]: { - icon: TimeOutline, - color: "#2080f0", - }, - ["例行"]: { - icon: NavigateCircleOutline, - color: "#2080f0", - }, -} as any; -// 操作数据配置 diff --git a/tg-web/src/utils/setIconfont.ts b/tg-web/src/utils/setIconfont.ts deleted file mode 100644 index a6acf68bc32c418ea8244bda0d90898db43b6d60..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/setIconfont.ts +++ /dev/null @@ -1,48 +0,0 @@ -// 字体图标 url -const cssCdnUrlList: Array = [ - '//at.alicdn.com/t/font_2298093_y6u00apwst.css', - '//netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css', -]; -// 第三方 js url -const jsCdnUrlList: Array = []; - -// 动态批量设置字体图标 -export function setCssCdn() { - if (cssCdnUrlList.length <= 0) return false; - cssCdnUrlList.map((v) => { - let link = document.createElement('link'); - link.rel = 'stylesheet'; - link.href = v; - link.crossOrigin = 'anonymous'; - document.getElementsByTagName('head')[0].appendChild(link); - }); -} - -// 动态批量设置第三方js -export function setJsCdn() { - if (jsCdnUrlList.length <= 0) return false; - jsCdnUrlList.map((v) => { - let link = document.createElement('script'); - link.src = v; - document.body.appendChild(link); - }); -} - -/** - * 批量设置字体图标、动态js - * @method cssCdn 动态批量设置字体图标 - * @method jsCdn 动态批量设置第三方js - */ -const setIntroduction = { - // 设置css - cssCdn: () => { - setCssCdn(); - }, - // 设置js - jsCdn: () => { - setJsCdn(); - }, -}; - -// 导出函数方法 -export default setIntroduction; diff --git a/tg-web/src/utils/storage.ts b/tg-web/src/utils/storage.ts deleted file mode 100644 index a983f80039fe6d293b3ef23d8ed2c26c8a11b9ba..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/storage.ts +++ /dev/null @@ -1,59 +0,0 @@ -import Cookies from 'js-cookie'; - -/** - * window.localStorage 浏览器永久缓存 - * @method set 设置永久缓存 - * @method get 获取永久缓存 - * @method remove 移除永久缓存 - * @method clear 移除全部永久缓存 - */ -export const Local = { - // 设置永久缓存 - set(key: string, val: any) { - window.localStorage.setItem(key, JSON.stringify(val)); - }, - // 获取永久缓存 - get(key: string) { - let json: any = window.localStorage.getItem(key); - return JSON.parse(json); - }, - // 移除永久缓存 - remove(key: string) { - window.localStorage.removeItem(key); - }, - // 移除全部永久缓存 - clear() { - window.localStorage.clear(); - }, -}; - -/** - * window.sessionStorage 浏览器临时缓存 - * @method set 设置临时缓存 - * @method get 获取临时缓存 - * @method remove 移除临时缓存 - * @method clear 移除全部临时缓存 - */ -export const Session = { - // 设置临时缓存 - set(key: string, val: any) { - if (key === 'token') return Cookies.set(key, val); - window.sessionStorage.setItem(key, JSON.stringify(val)); - }, - // 获取临时缓存 - get(key: string) { - if (key === 'token') return Cookies.get(key); - let json: any = window.sessionStorage.getItem(key); - return JSON.parse(json); - }, - // 移除临时缓存 - remove(key: string) { - if (key === 'token') return Cookies.remove(key); - window.sessionStorage.removeItem(key); - }, - // 移除全部临时缓存 - clear() { - Cookies.remove('token'); - window.sessionStorage.clear(); - }, -}; diff --git a/tg-web/src/utils/theme.ts b/tg-web/src/utils/theme.ts deleted file mode 100644 index 5561e648275a78c77eb0d4d54511ca7cfdc3db23..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/theme.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { ElMessage } from 'element-plus'; - -/** - * hex颜色转rgb颜色 - * @param str 颜色值字符串 - * @returns 返回处理后的颜色值 - */ -export function hexToRgb(str: any) { - let hexs: any = ''; - let reg = /^\#?[0-9A-Fa-f]{6}$/; - if (!reg.test(str)) return ElMessage.warning('输入错误的hex'); - str = str.replace('#', ''); - hexs = str.match(/../g); - for (let i = 0; i < 3; i++) hexs[i] = parseInt(hexs[i], 16); - return hexs; -} - -/** - * rgb颜色转Hex颜色 - * @param r 代表红色 - * @param g 代表绿色 - * @param b 代表蓝色 - * @returns 返回处理后的颜色值 - */ -export function rgbToHex(r: any, g: any, b: any) { - let reg = /^\d{1,3}$/; - if (!reg.test(r) || !reg.test(g) || !reg.test(b)) return ElMessage.warning('输入错误的rgb颜色值'); - let hexs = [r.toString(16), g.toString(16), b.toString(16)]; - for (let i = 0; i < 3; i++) if (hexs[i].length == 1) hexs[i] = `0${hexs[i]}`; - return `#${hexs.join('')}`; -} - -/** - * 加深颜色值 - * @param color 颜色值字符串 - * @param level 加深的程度,限0-1之间 - * @returns 返回处理后的颜色值 - */ -export function getDarkColor(color: string, level: number) { - let reg = /^\#?[0-9A-Fa-f]{6}$/; - if (!reg.test(color)) return ElMessage.warning('输入错误的hex颜色值'); - let rgb = hexToRgb(color); - for (let i = 0; i < 3; i++) rgb[i] = Math.floor(rgb[i] * (1 - level)); - return rgbToHex(rgb[0], rgb[1], rgb[2]); -} - -/** - * 变浅颜色值 - * @param color 颜色值字符串 - * @param level 加深的程度,限0-1之间 - * @returns 返回处理后的颜色值 - */ -export function getLightColor(color: string, level: number) { - let reg = /^\#?[0-9A-Fa-f]{6}$/; - if (!reg.test(color)) return ElMessage.warning('输入错误的hex颜色值'); - let rgb = hexToRgb(color); - for (let i = 0; i < 3; i++) rgb[i] = Math.floor((255 - rgb[i]) * level + rgb[i]); - return rgbToHex(rgb[0], rgb[1], rgb[2]); -} diff --git a/tg-web/src/utils/toolsValidate.ts b/tg-web/src/utils/toolsValidate.ts deleted file mode 100644 index 164bb654d65975a46c66f379b4ee9b1ff791d663..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/toolsValidate.ts +++ /dev/null @@ -1,378 +0,0 @@ -/** - * 2020.11.29 lyt 整理 - * 工具类集合,适用于平时开发 - * 新增多行注释信息,鼠标放到方法名即可查看 - */ - -/** - * 解决ts中, string类型不能应用于对象的索引 - */ - - export function isValidKey(key: string | number | symbol, object: object): key is keyof typeof object { - return key in object; -} - -/** - * 验证百分比(不可以小数) - * @param val 当前值字符串 - * @returns 返回处理后的字符串 - */ -export function verifyNumberPercentage(val: string): string { - // 匹配空格 - let v = val.replace(/(^\s*)|(\s*$)/g, ''); - // 只能是数字和小数点,不能是其他输入 - v = v.replace(/[^\d]/g, ''); - // 不能以0开始 - v = v.replace(/^0/g, ''); - // 数字超过100,赋值成最大值100 - v = v.replace(/^[1-9]\d\d{1,3}$/, '100'); - // 返回结果 - return v; -} - -/** - * 验证百分比(可以小数) - * @param val 当前值字符串 - * @returns 返回处理后的字符串 - */ -export function verifyNumberPercentageFloat(val: string): string { - let v = verifyNumberIntegerAndFloat(val); - // 数字超过100,赋值成最大值100 - v = v.replace(/^[1-9]\d\d{1,3}$/, '100'); - // 超过100之后不给再输入值 - v = v.replace(/^100\.$/, '100'); - // 返回结果 - return v; -} - -/** - * 小数或整数(不可以负数) - * @param val 当前值字符串 - * @returns 返回处理后的字符串 - */ -export function verifyNumberIntegerAndFloat(val: string) { - // 匹配空格 - let v = val.replace(/(^\s*)|(\s*$)/g, ''); - // 只能是数字和小数点,不能是其他输入 - v = v.replace(/[^\d.]/g, ''); - // 以0开始只能输入一个 - v = v.replace(/^0{2}$/g, '0'); - // 保证第一位只能是数字,不能是点 - v = v.replace(/^\./g, ''); - // 小数只能出现1位 - v = v.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.'); - // 小数点后面保留2位 - v = v.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3'); - // 返回结果 - return v; -} - -/** - * 正整数验证 - * @param val 当前值字符串 - * @returns 返回处理后的字符串 - */ -export function verifiyNumberInteger(val: string) { - // 匹配空格 - let v = val.replace(/(^\s*)|(\s*$)/g, ''); - // 去掉 '.' , 防止贴贴的时候出现问题 如 0.1.12.12 - v = v.replace(/[\.]*/g, ''); - // 去掉以 0 开始后面的数, 防止贴贴的时候出现问题 如 00121323 - v = v.replace(/(^0[\d]*)$/g, '0'); - // 首位是0,只能出现一次 - v = v.replace(/^0\d$/g, '0'); - // 只匹配数字 - v = v.replace(/[^\d]/g, ''); - // 返回结果 - return v; -} - -/** - * 去掉中文及空格 - * @param val 当前值字符串 - * @returns 返回处理后的字符串 - */ -export function verifyCnAndSpace(val: string) { - // 匹配中文与空格 - let v = val.replace(/[\u4e00-\u9fa5\s]+/g, ''); - // 匹配空格 - v = v.replace(/(^\s*)|(\s*$)/g, ''); - // 返回结果 - return v; -} - -/** - * 去掉英文及空格 - * @param val 当前值字符串 - * @returns 返回处理后的字符串 - */ -export function verifyEnAndSpace(val: string) { - // 匹配英文与空格 - let v = val.replace(/[a-zA-Z]+/g, ''); - // 匹配空格 - v = v.replace(/(^\s*)|(\s*$)/g, ''); - // 返回结果 - return v; -} - -/** - * 禁止输入空格 - * @param val 当前值字符串 - * @returns 返回处理后的字符串 - */ -export function verifyAndSpace(val: string) { - // 匹配空格 - let v = val.replace(/(^\s*)|(\s*$)/g, ''); - // 返回结果 - return v; -} - -/** - * 金额用 `,` 区分开 - * @param val 当前值字符串 - * @returns 返回处理后的字符串 - */ -export function verifyNumberComma(val: string) { - // 调用小数或整数(不可以负数)方法 - let v: any = verifyNumberIntegerAndFloat(val); - // 字符串转成数组 - v = v.toString().split('.'); - // \B 匹配非单词边界,两边都是单词字符或者两边都是非单词字符 - v[0] = v[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); - // 数组转字符串 - v = v.join('.'); - // 返回结果 - return v; -} - -/** - * 匹配文字变色(搜索时) - * @param val 当前值字符串 - * @param text 要处理的字符串值 - * @param color 搜索到时字体高亮颜色 - * @returns 返回处理后的字符串 - */ -export function verifyTextColor(val: string, text = '', color = 'red') { - // 返回内容,添加颜色 - let v = text.replace(new RegExp(val, 'gi'), `${val}`); - // 返回结果 - return v; -} - -/** - * 数字转中文大写 - * @param val 当前值字符串 - * @param unit 默认:仟佰拾亿仟佰拾万仟佰拾元角分 - * @returns 返回处理后的字符串 - */ -export function verifyNumberCnUppercase(val: any, unit = '仟佰拾亿仟佰拾万仟佰拾元角分', v = '') { - // 当前内容字符串添加 2个0,为什么?? - val += '00'; - // 返回某个指定的字符串值在字符串中首次出现的位置,没有出现,则该方法返回 -1 - let lookup = val.indexOf('.'); - // substring:不包含结束下标内容,substr:包含结束下标内容 - if (lookup >= 0) val = val.substring(0, lookup) + val.substr(lookup + 1, 2); - // 根据内容 val 的长度,截取返回对应大写 - unit = unit.substr(unit.length - val.length); - // 循环截取拼接大写 - for (let i = 0; i < val.length; i++) { - v += '零壹贰叁肆伍陆柒捌玖'.substr(val.substr(i, 1), 1) + unit.substr(i, 1); - } - // 正则处理 - v = v - .replace(/零角零分$/, '整') - .replace(/零[仟佰拾]/g, '零') - .replace(/零{2,}/g, '零') - .replace(/零([亿|万])/g, '$1') - .replace(/零+元/, '元') - .replace(/亿零{0,3}万/, '亿') - .replace(/^元/, '零元'); - // 返回结果 - return v; -} - -/** - * 手机号码 - * @param val 当前值字符串 - * @returns 返回 true: 手机号码正确 - */ -export function verifyPhone(val: string) { - // false: 手机号码不正确 - if (!/^((12[0-9])|(13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0|1,5-9]))\d{8}$/.test(val)) return false; - // true: 手机号码正确 - else return true; -} - -/** - * 国内电话号码 - * @param val 当前值字符串 - * @returns 返回 true: 国内电话号码正确 - */ -export function verifyTelPhone(val: string) { - // false: 国内电话号码不正确 - if (!/\d{3}-\d{8}|\d{4}-\d{7}/.test(val)) return false; - // true: 国内电话号码正确 - else return true; -} - -/** - * 登录账号 (字母开头,允许5-16字节,允许字母数字下划线) - * @param val 当前值字符串 - * @returns 返回 true: 登录账号正确 - */ -export function verifyAccount(val: string) { - // false: 登录账号不正确 - if (!/^[a-zA-Z][a-zA-Z0-9_]{4,15}$/.test(val)) return false; - // true: 登录账号正确 - else return true; -} - -/** - * 密码 (以字母开头,长度在6~16之间,只能包含字母、数字和下划线) - * @param val 当前值字符串 - * @returns 返回 true: 密码正确 - */ -export function verifyPassword(val: string) { - // false: 密码不正确 - if (!/^[a-zA-Z]\w{5,15}$/.test(val)) return false; - // true: 密码正确 - else return true; -} - -/** - * 强密码 (字母+数字+特殊字符,长度在6-16之间) - * @param val 当前值字符串 - * @returns 返回 true: 强密码正确 - */ -export function verifyPasswordPowerful(val: string) { - // false: 强密码不正确 - if (!/^(?![a-zA-z]+$)(?!\d+$)(?![!@#$%^&\.*]+$)(?![a-zA-z\d]+$)(?![a-zA-z!@#$%^&\.*]+$)(?![\d!@#$%^&\.*]+$)[a-zA-Z\d!@#$%^&\.*]{6,16}$/.test(val)) - return false; - // true: 强密码正确 - else return true; -} - -/** - * 密码强度 - * @param val 当前值字符串 - * @description 弱:纯数字,纯字母,纯特殊字符 - * @description 中:字母+数字,字母+特殊字符,数字+特殊字符 - * @description 强:字母+数字+特殊字符 - * @returns 返回处理后的字符串:弱、中、强 - */ -export function verifyPasswordStrength(val: string) { - let v = ''; - // 弱:纯数字,纯字母,纯特殊字符 - if (/^(?:\d+|[a-zA-Z]+|[!@#$%^&\.*]+){6,16}$/.test(val)) v = '弱'; - // 中:字母+数字,字母+特殊字符,数字+特殊字符 - if (/^(?![a-zA-z]+$)(?!\d+$)(?![!@#$%^&\.*]+$)[a-zA-Z\d!@#$%^&\.*]{6,16}$/.test(val)) v = '中'; - // 强:字母+数字+特殊字符 - if (/^(?![a-zA-z]+$)(?!\d+$)(?![!@#$%^&\.*]+$)(?![a-zA-z\d]+$)(?![a-zA-z!@#$%^&\.*]+$)(?![\d!@#$%^&\.*]+$)[a-zA-Z\d!@#$%^&\.*]{6,16}$/.test(val)) - v = '强'; - // 返回结果 - return v; -} - -/** - * IP地址 - * @param val 当前值字符串 - * @returns 返回 true: IP地址正确 - */ -export function verifyIPAddress(val: string) { - // false: IP地址不正确 - if ( - !/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/.test( - val - ) - ) - return false; - // true: IP地址正确 - else return true; -} - -/** - * 邮箱 - * @param val 当前值字符串 - * @returns 返回 true: 邮箱正确 - */ -export function verifyEmail(val: string) { - // false: 邮箱不正确 - if ( - !/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test( - val - ) - ) - return false; - // true: 邮箱正确 - else return true; -} - -/** - * 身份证 - * @param val 当前值字符串 - * @returns 返回 true: 身份证正确 - */ -export function verifyIdCard(val: string) { - // false: 身份证不正确 - if (!/^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/.test(val)) return false; - // true: 身份证正确 - else return true; -} - -/** - * 姓名 - * @param val 当前值字符串 - * @returns 返回 true: 姓名正确 - */ -export function verifyFullName(val: string) { - // false: 姓名不正确 - if (!/^[\u4e00-\u9fa5]{1,6}(·[\u4e00-\u9fa5]{1,6}){0,2}$/.test(val)) return false; - // true: 姓名正确 - else return true; -} - -/** - * 邮政编码 - * @param val 当前值字符串 - * @returns 返回 true: 邮政编码正确 - */ -export function verifyPostalCode(val: string) { - // false: 邮政编码不正确 - if (!/^[1-9][0-9]{5}$/.test(val)) return false; - // true: 邮政编码正确 - else return true; -} - -/** - * url 处理 - * @param val 当前值字符串 - * @returns 返回 true: url 正确 - */ -export function verifyUrl(val: string) { - // false: url不正确 - if ( - !/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test( - val - ) - ) - return false; - // true: url正确 - else return true; -} - -/** - * 车牌号 - * @param val 当前值字符串 - * @returns 返回 true:车牌号正确 - */ -export function verifyCarNum(val: string) { - // false: 车牌号不正确 - if ( - !/^(([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z](([0-9]{5}[DF])|([DF]([A-HJ-NP-Z0-9])[0-9]{4})))|([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳使领]))$/.test( - val - ) - ) - return false; - // true:车牌号正确 - else return true; -} diff --git a/tg-web/src/utils/wartermark.ts b/tg-web/src/utils/wartermark.ts deleted file mode 100644 index b897ed1956f0f62860d4c457d4edb6b16ecaecd9..0000000000000000000000000000000000000000 --- a/tg-web/src/utils/wartermark.ts +++ /dev/null @@ -1,47 +0,0 @@ -// 页面添加水印效果 -const setWatermark = (str: string) => { - const id = '1.23452384164.123412416'; - if (document.getElementById(id) !== null) document.body.removeChild(document.getElementById(id)); - const can = document.createElement('canvas'); - can.width = 200; - can.height = 130; - const cans: any = can.getContext('2d'); - cans.rotate((-20 * Math.PI) / 180); - cans.font = '12px Vedana'; - cans.fillStyle = 'rgba(200, 200, 200, 0.30)'; - cans.textBaseline = 'Middle'; - cans.fillText(str, can.width / 10, can.height / 2); - const div = document.createElement('div'); - div.id = id; - div.style.pointerEvents = 'none'; - div.style.top = '15px'; - div.style.left = '0px'; - div.style.position = 'fixed'; - div.style.zIndex = '10000000'; - div.style.width = `${document.documentElement.clientWidth}px`; - div.style.height = `${document.documentElement.clientHeight}px`; - div.style.background = `url(${can.toDataURL('image/png')}) left top repeat`; - document.body.appendChild(div); - return id; -}; - -/** - * 页面添加水印效果 - * @method set 设置水印 - * @method del 删除水印 - */ -const watermark = { - // 设置水印 - set: (str: string) => { - let id = setWatermark(str); - if (document.getElementById(id) === null) id = setWatermark(str); - }, - // 删除水印 - del: () => { - let id = '1.23452384164.123412416'; - if (document.getElementById(id) !== null) document.body.removeChild(document.getElementById(id)); - }, -}; - -// 导出方法 -export default watermark; diff --git a/tg-web/src/views/error/401.vue b/tg-web/src/views/error/401.vue deleted file mode 100644 index b031696b3fcf086d8bf465401bd353e49aba815f..0000000000000000000000000000000000000000 --- a/tg-web/src/views/error/401.vue +++ /dev/null @@ -1,90 +0,0 @@ - - - - - diff --git a/tg-web/src/views/error/404.vue b/tg-web/src/views/error/404.vue deleted file mode 100644 index 33afc3a8deb05aeafea925bb11490af7470f3425..0000000000000000000000000000000000000000 --- a/tg-web/src/views/error/404.vue +++ /dev/null @@ -1,91 +0,0 @@ - - - - - diff --git a/tg-web/src/views/home/index.vue b/tg-web/src/views/home/index.vue deleted file mode 100644 index 10191f7e9fe9b6bfb151b10b1171750a5ae19065..0000000000000000000000000000000000000000 --- a/tg-web/src/views/home/index.vue +++ /dev/null @@ -1,24 +0,0 @@ - - - - - diff --git a/tg-web/src/views/strategy/experiment/experiment.vue b/tg-web/src/views/strategy/experiment/experiment.vue deleted file mode 100644 index ee7c375fd122dcb211de420647bef6e5d984e5da..0000000000000000000000000000000000000000 --- a/tg-web/src/views/strategy/experiment/experiment.vue +++ /dev/null @@ -1,934 +0,0 @@ - - - - - diff --git a/tg-web/src/views/strategy/experiment/historyVersion.vue b/tg-web/src/views/strategy/experiment/historyVersion.vue deleted file mode 100644 index 9155382cf4e882938bec64675bf7b7472ea16078..0000000000000000000000000000000000000000 --- a/tg-web/src/views/strategy/experiment/historyVersion.vue +++ /dev/null @@ -1,109 +0,0 @@ - - - - - \ No newline at end of file diff --git a/tg-web/src/views/strategy/experiment/requireConfig.vue b/tg-web/src/views/strategy/experiment/requireConfig.vue deleted file mode 100644 index a5dc6f251bf6e4dbd45e88dba06c0165dadf5388..0000000000000000000000000000000000000000 --- a/tg-web/src/views/strategy/experiment/requireConfig.vue +++ /dev/null @@ -1,51 +0,0 @@ - - - - - \ No newline at end of file diff --git a/tg-web/src/views/strategy/experiment/showX6params.vue b/tg-web/src/views/strategy/experiment/showX6params.vue deleted file mode 100644 index 106ca716133287839a9e1d3760183c9142a8ead9..0000000000000000000000000000000000000000 --- a/tg-web/src/views/strategy/experiment/showX6params.vue +++ /dev/null @@ -1,131 +0,0 @@ - - - - - \ No newline at end of file diff --git a/tg-web/src/views/strategy/experiment/updateForm.vue b/tg-web/src/views/strategy/experiment/updateForm.vue deleted file mode 100644 index 8f30187c594c32fd9939e581385007814210a86b..0000000000000000000000000000000000000000 --- a/tg-web/src/views/strategy/experiment/updateForm.vue +++ /dev/null @@ -1,62 +0,0 @@ - - - - - \ No newline at end of file diff --git a/tg-web/src/views/strategy/experiment/vis.vue b/tg-web/src/views/strategy/experiment/vis.vue deleted file mode 100644 index d9ab1a310b191af7d88406a5d17f14c369375a71..0000000000000000000000000000000000000000 --- a/tg-web/src/views/strategy/experiment/vis.vue +++ /dev/null @@ -1,680 +0,0 @@ - - - - - diff --git a/tg-web/src/views/strategy/module/ModuleBox.vue b/tg-web/src/views/strategy/module/ModuleBox.vue deleted file mode 100644 index 6410c5e93b46f499465c5c8641e033f098a22294..0000000000000000000000000000000000000000 --- a/tg-web/src/views/strategy/module/ModuleBox.vue +++ /dev/null @@ -1,201 +0,0 @@ - - - - - diff --git a/tg-web/src/views/strategy/module/module.vue b/tg-web/src/views/strategy/module/module.vue deleted file mode 100644 index 289e3b095b52e4b2f04e464cbacea2ad4ded7f68..0000000000000000000000000000000000000000 --- a/tg-web/src/views/strategy/module/module.vue +++ /dev/null @@ -1,126 +0,0 @@ - - - - - diff --git a/tg-web/src/views/strategy/scenes/formData.vue b/tg-web/src/views/strategy/scenes/formData.vue deleted file mode 100644 index b7d2c3e4e493188b20d42565b631d846bd326cd9..0000000000000000000000000000000000000000 --- a/tg-web/src/views/strategy/scenes/formData.vue +++ /dev/null @@ -1,245 +0,0 @@ - - - - - diff --git a/tg-web/src/views/strategy/scenes/scenes.vue b/tg-web/src/views/strategy/scenes/scenes.vue deleted file mode 100644 index 0b177219d40a5c8d8d09523afbe721b93539ae6b..0000000000000000000000000000000000000000 --- a/tg-web/src/views/strategy/scenes/scenes.vue +++ /dev/null @@ -1,347 +0,0 @@ - - - - - diff --git a/tg-web/src/views/strategy/system/formData.vue b/tg-web/src/views/strategy/system/formData.vue deleted file mode 100644 index e69b9f8fb6b16c3f31970574491398ca2ba23bbf..0000000000000000000000000000000000000000 --- a/tg-web/src/views/strategy/system/formData.vue +++ /dev/null @@ -1,187 +0,0 @@ - - - - - \ No newline at end of file diff --git a/tg-web/src/views/strategy/system/system.vue b/tg-web/src/views/strategy/system/system.vue deleted file mode 100644 index a1f46a4822aac3dba7c595c73cc4a3ee6ec00d35..0000000000000000000000000000000000000000 --- a/tg-web/src/views/strategy/system/system.vue +++ /dev/null @@ -1,333 +0,0 @@ - - - - - diff --git a/tg-web/tsconfig.json b/tg-web/tsconfig.json deleted file mode 100644 index 577bad2279bb674d576a078ddb3c681292aac76b..0000000000000000000000000000000000000000 --- a/tg-web/tsconfig.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "compilerOptions": { - /* Visit https://aka.ms/tsconfig.json to read more about this file */ - - /* Basic Options */ - // "incremental": true, /* Enable incremental compilation */ - "target": "esnext" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, - "module": "esnext" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, - "lib": ["esnext", "dom", "dom.iterable", "scripthost"] /* Specify library files to be included in the compilation. */, - // "allowJs": true, /* Allow javascript files to be compiled. */ - // "checkJs": true, /* Report errors in .js files. */ - "jsx": "preserve" /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */, - // "declaration": true /* Generates corresponding '.d.ts' file. */, - // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ - // "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - // "outDir": "./", /* Redirect output structure to the directory. */ - // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ - // "composite": true, /* Enable project compilation */ - // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ - // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true /* Import emit helpers from 'tslib'. */, - // "downlevelIteration": true /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */, - // "isolatedModules": true /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */, - - /* Strict Type-Checking Options */ - "strict": true /* Enable all strict type-checking options. */, - // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* Enable strict null checks. */ - // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ - // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ - - /* Module Resolution Options */ - "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, - "baseUrl": "." /* Base directory to resolve non-absolute module names. */, - "paths": { - "/@/*": ["src/*"], - "@/*":["src/*"] - } /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */, - // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - "types": ["vite/client"] /* Type declaration files to be included in compilation. */, - "allowSyntheticDefaultImports": true /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */, - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, - // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - - /* Source Map Options */ - // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - - /* Advanced Options */ - "skipLibCheck": true /* Skip type checking of declaration files. */, - "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ - } -} diff --git a/tg-web/vite.config.ts b/tg-web/vite.config.ts deleted file mode 100644 index 1ced882a49a4b8a11b03a1f24d045e3e2fb8f21b..0000000000000000000000000000000000000000 --- a/tg-web/vite.config.ts +++ /dev/null @@ -1,71 +0,0 @@ -import vue from '@vitejs/plugin-vue'; -import { resolve } from 'path'; -import { defineConfig, loadEnv, ConfigEnv } from 'vite'; -import topLevelAwait from 'vite-plugin-top-level-await'; - -const pathResolve = (dir: string): any => { - return resolve(__dirname, '.', dir); -}; - -const alias: Record = { - '@': pathResolve('./src/'), - '/@': pathResolve('./src/'), - 'vue-i18n': 'vue-i18n/dist/vue-i18n.cjs.js', -}; - -const viteConfig = defineConfig((mode: ConfigEnv) => { - const env = loadEnv(mode.mode, process.cwd()); - return { - plugins: [ - vue(), - topLevelAwait({promiseExportName: '__tla', promiseImportName: i => `__tla_${i}`}) - ], - root: process.cwd(), - resolve: { alias }, - base: mode.command === 'serve' ? './' : env.VITE_PUBLIC_PATH, - hmr: true, - optimizeDeps: { - include: ['element-plus/lib/locale/lang/zh-cn', 'element-plus/lib/locale/lang/en', 'element-plus/lib/locale/lang/zh-tw'], - }, - server: { - host: '0.0.0.0', - port: 9990, - open: env.VITE_OPEN, - proxy:{ - // TODO develop api address - '/api': { - target: 'http://10.193.196.45:8052/point_arch/point-admin', - ws: true, - changeOrigin: false, - rewrite: (path) => path.replace('/api','') - }, - } - }, - build: { - outDir: 'dist', - sourcemap: false, - chunkSizeWarningLimit: 1500, - rollupOptions: { - output: { - entryFileNames: `assets/[name].${new Date().getTime()}.js`, - chunkFileNames: `assets/[name].${new Date().getTime()}.js`, - assetFileNames: `assets/[name].${new Date().getTime()}.[ext]`, - compact: true, - manualChunks: { - vue: ['vue', 'vue-router', 'pinia'], - echarts: ['echarts'], - }, - }, - }, - }, - css: { preprocessorOptions: { css: { charset: false } } }, - define: { - __VUE_I18N_LEGACY_API__: JSON.stringify(false), - __VUE_I18N_FULL_INSTALL__: JSON.stringify(false), - __INTLIFY_PROD_DEVTOOLS__: JSON.stringify(false), - }, - envDir: './env', - }; -}); - -export default viteConfig; diff --git a/user_manual.html b/user_manual.html deleted file mode 100644 index 3c642038fbdd989a597bc19926250d1a14928b89..0000000000000000000000000000000000000000 --- a/user_manual.html +++ /dev/null @@ -1,314 +0,0 @@ - - - - - tg-flow 使用手册 - - - -
-

tg-flow 使用手册

-
-
-

1. 编写目的

-

通过对本公司的 tg-flow 软件产品操作过程的描述,使用户可以自主对软件进行使用和操作。

- -

2. 下载与安装

- -

2.1 下载安装包

-

git clone https://github.com/didi/tg-flow

- -

2.2 安装和启动

- -

tg-service 的安装和启动:

-
    -
  1. 将 tg-service 软件包拷贝到要安装的目录;
  2. -
  3. 进入 tg-service 目录,执行 ./build.sh,会生成 output 文件夹;
  4. -
  5. 执行:cd output 进入 output 目录,执行:nohup ./control.sh start > nohup.log 2>&1 &,启动服务。
  6. -
- -

tg-web 的安装步骤:

-
    -
  1. 将 tg-web 软件包拷贝到要安装的目录;
  2. -
  3. 通过命令行方式,进入到 tg-web 所在目录,执行如下命令:npm install,即可完成 tg-web 部分的安装;
  4. -
  5. 通过命令行方式,进入到 tg-web 所在目录,执行如下命令:npm start,即可完成 tg-web 的启动;
  6. -
  7. 打开浏览器地址栏,输入 http://localhost:8888/,可以打开登录页,说明安装成功。
  8. -
- -

3. tg-core 是应用系统使用时需要导入的组件,不需要单独安装。

- -

3. 登录

- -

3.1 账号分配

-

初次安装时,系统会默认生成一个管理员账号 admin,密码 admin,可以使用该账号进行后续的登录和分配其他子账号。

- -

3.2 登录系统

-

第一次打开系统的时候,系统会自动跳转至登录页面,这个时候可以使用管理员账号或者子管理员账号,输入账号、密码、验证码进行登录。

-
- 登录 -
- -

3.3 注销登录

-

进入系统后,可以通过点击系统的右上角“退出登录”按钮注销登录。

- -

4. 系统管理

-

tg-flow 支持同时接入并管理多个系统和应用,每个系统都有独立的系统ID和系统名称,通过系统管理页面可以查看当前接入的所有业务系统。

-
- 登录 -
-

图4.1 系统管理界面

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
属性名称描述
id系统 ID
app_name系统名称
machine_room系统所部署的集群
node_name系统所在机房
operator系统创建和修改人员
create_time系统创建时间
update_time系统更新时间
git_url系统代码所属的代码仓库地址
- -

在策略管理 -> 系统管理页面可以进行新增,修改,导出和删除系统等相关操作。

-
- 登录 -
-

图4.2 新增系统对话框

-

其中系统编号,系统名称,部署机房和节点名称都为必填项,填写完成后点击保存按钮即可完成系统新增。

-
- 登录 -
-

图4.3 修改系统对话框

-

系统条目右侧的导出按钮并点击确认导出可以导出对应系统所有场景下的流程信息,并作为 zip 压缩包的形式下载到本地并用于对应的系统中。

- -

5. 场景管理

- -

5.1 场景列表

-

该列表页展示在当前平台注册的所有的场景信息,系统与场景属于一对多的关系。场景信息所含字段如下图所示。搜索栏中可通过输入“场景名称”或者“系统名称”来获取相应的场景信息。

-
- 登录 -
-

5.2 场景配置

-

场景列表页存在四个可操作按钮:

-
    -
  • 新增:可手动添加某个系统下的场景信息;
  • -
  • 刷新:手动触发获取最新的场景列表;
  • -
  • 修改:针对单一场景修改其描述内容,除了场景编号之外其他内容均可修改;
  • -
  • 删除:删除某个场景;
  • -
- -

6 工作流引擎代码接入

-

6.1 代码框架

-

如下图为一个待接入工作流引擎的应用系统的项目代码,其中logic目录下为业务层代码,接入工作流引擎时,可以在业务层添加相关的接入代码,主要有:

-
    -
  1. 工作流引擎初始化代码,类似下图中的workflow_task.go文件;
  2. -
  3. 工作流引擎调度执行代码,类似下图中的dispatcher_genrec.go;
  4. -
  5. 工作流节点对应的算子实现代码,算子有多个,可以放到不同子目录分组存放,类似下图中的module为上述子目录的父目录;
  6. -
  7. 算子注册代码,用于将算子注册到工作流引擎,类似下图中的module_init.go文件.
  8. -
-
- 登录 -
-

6.2 工作流引擎初始化

-

我们提供了三种工作流引擎初始化的方式:从本地工作流配置文件初始化、从全局配置中心提取配置信息初始化,以及从redis提取配置信息初始化。下面介绍的是第一种,从本地文件初始化,可以在自己的系统初始化模块中调用(其中workflowPath为工作流配置文件根目录):

-
-
-func LoadWorkflowData(ctx context.Context) {
-   moduleObj := module.ModuleObject{}
-   workflowEngine, err := wfengine.NewWorkflowEngineFromFile(moduleObj, workflowPath)
-   if err != nil {
-      tlog.ErrorCount(ctx, "cron_task_workflow_err", fmt.Sprintf("workflow engine init fail, AppId=%v, error=%v", constants.CurrentAppId, err))
-      return
-   }
-
-   global.WorkflowEngine = workflowEngine
-   tlog.Handler.Infof(ctx, consts.DLTagCronTask, "workflow engine update successful, appId=%v, workflowEngine=%v", constants.CurrentAppId, global.WorkflowEngine)
-}
-
-
- -

6.3 工作流引擎调度执行

-

使用工作流引擎调度执行工作流,只需要在调度相关模块中添加下面的代码即可:

-
-
-global.WorkflowEngine.Run(ctx, sc)
-errMap := sc.GetErrorMap()
-errMap.Range(func(key, val interface{}) bool {
-   log.Println(fmt.Sprintf("workflowengine error, key=%v, val=%v", key, val))
-)
-   return true
-})
-
-
- -

6.4 工作流算子开发

-

通常一个应用系统中可能会有多个业务场景,每个场景下可能需要配置多个不同的工作流,应用系统对外提供服务时,需要根据实际业务场景或实验分组情况选择使用不同的工作流来执行,工作流则由若干个执行节点组成,每个执行节点对应的是一个算子,在golang语言中这些算子对应的是struct。我们需要在要接入tg-flow的应用系统中定义这些算子,下面为一个名为RecallSampAction的算子定义示例:

-
-
-package recall
-
-import (
-   "context"
-   "fmt"
-   "github.com/didi/tg-flow/tg-core/model"
-   "github.com/didi/tg-flow/tg-core/wfengine"
-   "time"
-)
-
-type RecallSampAction struct {
-   wfengine.ModelBase
-}
-
-func (r RecallSampAction) DoAction(ctx context.Context, sc *model.StrategyContext) interface{} {
-   //此处添加相关业务逻辑
-   return nil
-}
-
-func (r RecallSampAction) OnTimeout(context.Context, *model.StrategyContext){
-   //此处添加超时处理逻辑
-}
-
-
- -

6.5 工作流算子注册

-

为了将开发好的算子注册给工作流引擎,需要进行算子注册,如下图中的case语句部分,即为工作流算子注册函数,我们只需要自己实现一个下面的函数,并在函数中的case语句中添加自己的实际开发的算子相关注册代码即可:

-
-
-func (moduleObj ModuleObject) NewObj(moduleName string, vMap map[string]string) wfengine.IModelBase {
-   switch moduleName {
-       case “data.DataPrepareSamp1”: return &data.DataPrepareSamp1{}
-       case “recall.RecallSamp1”: return &recall.RecallSamp1{}
-       case “recall.RecallSamp2”: return &recall.RecallSamp2{}
-   }
-   return nil
-}
-
-
- -

6.6 代码仓库注册

-

在应用系统中完成上述代码编写后,可以将代码提交到git代码仓库,并将git仓库地址拷贝出来,然后进入系统管理页面,如下图所示,点击“修改”按钮,将该代码仓库的地址填写到弹出层中的“git仓库”文本框,如下图红色矩形框所示,然后点击“保存“按钮即可。

-
- 登录 -
-

7 工作流管理

-

7.1 工作流列表

-

点击左侧的“流程管理”目录,可以打开流程列表的管理页面,如下图所示。

- -
- 登录 -
-
    -

    选择列表上方的“系统”下拉框,点击查询,可以查到对应的应用系统已经添加的所有流程。

    -

    选择“场景名称”,点击查询,可以列出指定系统及场景下的所有工作流。

    -

    点击“新建”按钮,可以打开工作流编辑页面,开始一个新工作流的创建,下节会详细介绍新工作流的编辑功能。

    -

    工作流列表中有:修改、导出、复制、导入、删除等5个按钮。

    -

    点击“修改“按钮,可以打开工作流编辑页,后面的工作流编辑部分会详细介绍。

    -

    点击“导出”按钮,可以将当前工作流配置信息导出为一个json文件,点击确认后可以下载到本地,后面可以拷贝到待接入的应用系统工程目录下,应用系统在启动时,会初始化工作流引擎,工作流引擎初始化时可以通过本地方式加载上述配置。注意:此处是对单个工作流配置进行导出,如果要将某个系统下所有工作流打包导出,则需要进入到系统管理页操作。

    -

    点击“复制”按钮,可以新建一个同样的工作流配置,然后后面就可以在这个工作流上进行相关修改并保存。

    -

    点击“导入”按钮,会弹出一个对话框,这时可以将在外部编写的工作流配置信息复制并粘贴到这个对话框中的“导入内容(Json)”文本框中,点击“确认”按钮,即可完成工作流配置信息的导入,注意:工作流节点中的action_id的取值格式为:action-{场景ID}-{工作流ID},导入工作流时如果相关actionId中的场景ID和工作流ID与当前要导入的场景ID和工作流ID不一致,系统会自动帮忙将actionId中的后面两部分的值调整为当前的场景ID和工作流ID。

    -
    - 工作流编辑页面 -
    - -

    7.2 工作流编辑

    -

    打开工作流编辑页,系统会自动读取前面配置好的git仓库中的代码模块,获取代码中的算子列表,并在工作流编辑页面的左侧算子列表中展示,供后续的工作流编辑用。(注意:工作流中的条件节点已经在工作流引擎中做了内置的模块实现,所以无需单独在应用层再做实现,当然如果有需要,也可以自定义条件节点后,注册到工作流引擎)。如下图,为工作流编辑页面。工作流编辑页面包括三个区域:左侧为工作流节点列表,中间为流程构建区域,右侧为工作流及节点属性编辑区域。

    -
    - 工作流编辑页面 -
    -

    其中:

    -

    在后台管理系统中打开工作流编辑页面时,系统会从后台管理系统中配置的代码仓库中拉取代码模块名称,并以组件的方式显示在左侧组件栏。左侧的组件有两种类型:一是应用层节点,用户打开工作流图编辑界面后,会自动从对应的应用代码的git仓库中拉取对应的算子列表,展示在左侧的节点列表中。二是工作流引擎内置的条件节点和缺省节点(当git仓库未完成代码提交时,左侧无法拉取到代码模块名称,这时可以手动添加缺省节点,然后给缺省节点重新命名)。

    -

    从左侧组件栏中依次拖拽节点、添加节点之间的连线,可以逐步构建出类似下图中的主流程图和子流程图。

    -

    针对图中的每个节点,可以依次点击节点,然后在右侧的属性编辑区域编辑该节点的属性,如:节点名称、节点参数、节点描述信息等,完成所有节点属性的编辑后点击“保存”按钮,相关的工作流配置信息便会以json字符串格式存入数据库。

    - -
    - 工作流编辑页面2 -
    - -

    7.3 工作流配置发布

    -

    上一节中已存入数据库的工作流配置信息并不能自动发布到在线应用系统,需要在系统管理页面中点击“提交”按钮,将上述配置发布到一个具有存储全局配置功能的存储服务中,一般可基于zookeeper或redis开发,以供应用系统从配置中心读取上述配置信息。相应地,我们在工作流引擎也提供了从redis、zookeeper及本地文件中加载工作流配置的方法,前面工作流引擎接入部分已有介绍不作详述。

    - - -

    7.4 工作流导出与导入

    -

    然而,由于部分应用系统出于安全或者降低外部依赖的角度考虑,并不希望通过与后台管理系统进行联动的方式,动态更新工作流配置信息,因此我们在系统管理页面提供了工作流配置信息导出功能,用户可以直接将工作流配置信息导出为zip包,然后将上述zip包解压后直接添加到其应用系统的项目的本地目录下,应用系统在初始化工作流引擎时,可以直接使用工作流引擎提供的相关方法从本地目录加载工作流配置。

    - -
    - - \ No newline at end of file diff --git a/tg-core/wfengine/condition.go b/wfengine/condition.go similarity index 100% rename from tg-core/wfengine/condition.go rename to wfengine/condition.go diff --git a/tg-core/wfengine/engine.go b/wfengine/engine.go similarity index 67% rename from tg-core/wfengine/engine.go rename to wfengine/engine.go index 2d84e3acb0c60b30b0f5c01cca3b8131194b6f1e..522a1f7d4a0dd64bd5a010320314fdda36781d94 100644 --- a/tg-core/wfengine/engine.go +++ b/wfengine/engine.go @@ -1,4 +1,5 @@ -/** +/* +* Description : workflow engine v3.1 Author : dayunzhangyunfeng@didiglobal.com Date : 2021-05-14 @@ -9,9 +10,9 @@ import ( "context" "errors" "fmt" - "github.com/didi/tg-flow/tg-core/common/tlog" - "github.com/didi/tg-flow/tg-core/consts" - "github.com/didi/tg-flow/tg-core/model" + "github.com/didi/tg-flow/common/tlog" + "github.com/didi/tg-flow/consts" + "github.com/didi/tg-flow/model" "strings" "sync" "time" @@ -25,37 +26,63 @@ const ( type WorkflowEngine struct { sceneModuleMap map[int64]*SceneModule `json:"scene_module_map"` workflowMap map[int64]*Workflow `json:"workflows"` - modelBaseMap map[string]IModelBase `json:"modules"` + modelBaseMap map[string]IModelBase `json:"modules"` updateTime string `json:"update_time"` condExecutors *CondExecutors `json:"cond_executors"` + FlowSelectors map[int]FlowSelector `json:"flow_selectors"` } -func NewWorkflowEngine(moduleObj ModuleObjBase, appId int64) (*WorkflowEngine, error) { - //更新系统下全部场景的节点对象 - smMap, err := LoadSceneModuleMap(appId) - if err != nil { - return nil, err - } +func (w *WorkflowEngine) SetCustomFlowSelector(flowSelector FlowSelector) { + w.FlowSelectors[consts.FLOW_BY_CUSTOM] = flowSelector +} - //load workflow - wfMap, err := LoadWorkflow(appId, smMap) - if err != nil { - return nil, err +func (w *WorkflowEngine) GetWorkflow(workflowId int64) (*Workflow, bool) { + workflow, ok := w.workflowMap[workflowId] + return workflow, ok +} + +func (w *WorkflowEngine) SelectWorkflow(ctx context.Context, sc *model.StrategyContext) (*Workflow, error) { + sceneModule, okE := w.sceneModuleMap[sc.SceneId] + if !okE { + return nil, fmt.Errorf("no sceneModule found for scene_id:%v", sc.SceneId) } - //TODO ZYF err - resetWorkflows(wfMap) + var flowId int64 + var groupName string + var err error + if sc.FlowId > 0 { //测试 + flowId = sc.FlowId + } else { + //根据该场景设置的分流方式,获取workflowId + fs, ok := w.FlowSelectors[sceneModule.FlowType] + if !ok { + return nil, fmt.Errorf("no flow selector found for your flow type:%v", sceneModule.FlowType) + } - mbMap, err := createModelMap(moduleObj, wfMap) - if err != nil { - return nil, err + flowId, groupName, err = fs.SelectWorkflowId(sc, sceneModule) + // use default workflow if no flowId found + if err != nil || flowId <= 0 { + flowId = sceneModule.DefaultWorkflowId + tlog.Handler.ErrorCount(ctx, "select_workflow_err", fmt.Sprintf("select workflow error:%v, use default workflow:%v", err, flowId)) + err = nil + } + + sc.FlowId = flowId + } + //根据分流选出的workflow_id,取得对应的实验策略配置 + flow, okW := w.GetWorkflow(sc.FlowId) + if !okW { + return nil, fmt.Errorf("no workflow found, flowId=%v||groupId=%v||err=%v", sc.FlowId, groupName, err) } - workfowEngine := newWorkflowEngine(smMap, wfMap, mbMap) - return workfowEngine, nil + sc.Set("flow", flow) + sc.Set("groupId", groupName) + sc.Set("scene", sceneModule) + return flow, nil } func resetWorkflows(wfMap map[int64]*Workflow) { + //fmt.Println("wfMap.len=", len(wfMap)) if len(wfMap) == 0 { return } @@ -63,7 +90,7 @@ func resetWorkflows(wfMap map[int64]*Workflow) { for _, workflow := range wfMap { err := resetWorkflow(wfMap, workflow) if err != nil { - tlog.ErrorCount(context.TODO(), "resetWorkflow err", fmt.Sprintf("workflow=%+v", workflow)) + tlog.Handler.ErrorCount(context.TODO(), "resetWorkflow err", fmt.Sprintf("workflow=%+v", workflow)) continue } } @@ -73,28 +100,29 @@ func resetWorkflow(wfMap map[int64]*Workflow, workflow *Workflow) error { if workflow == nil { return errors.New("workflow is nil:%v") } - + //fmt.Println("开始for循环处理flowAction") for { flowActionMap := make(map[string]*Action) + //fmt.Println("workflow.FlowCharts.ActionMap.len===>", len(workflow.FlowCharts.ActionMap), workflow.FlowCharts.HashCondition) for _, action := range workflow.FlowCharts.ActionMap { if action.ActionType == ActionTypeFlow { if action.RefWorkflowId <= 0 { - tlog.ErrorCount(context.TODO(), "resetWorkflow_err", fmt.Sprintf("ref_workflow_id must >0, flowAction.Action=%+v", action)) - continue + tlog.Handler.ErrorCount(context.TODO(), "resetWorkflow_err", fmt.Sprintf("ref_workflow_id must >0, flowAction.Action=%+v", action)) + continue } flowActionMap[action.ActionId] = action } } if len(flowActionMap) < 1 { - return nil + break } - + //fmt.Println() //对所有flowAction for _, flowAction := range flowActionMap { //get workflowid refWf := wfMap[flowAction.RefWorkflowId] if refWf == nil { - tlog.ErrorCount(context.TODO(), "resetWorkflow_err", fmt.Sprintf("reference workflow not exist, flowAction.Action=%+v", flowAction)) + tlog.Handler.ErrorCount(context.TODO(), "resetWorkflow_err", fmt.Sprintf("reference workflow not exist, flowAction.Action=%+v", flowAction)) continue } @@ -108,13 +136,13 @@ func resetWorkflow(wfMap map[int64]*Workflow, workflow *Workflow) error { firstActionId := refWf.FlowCharts.FirstActionId if flowAction.ActionId == workflow.FlowCharts.FirstActionId { workflow.FlowCharts.FirstActionId = firstActionId - }else { + } else { for _, prevId := range flowAction.PrevActionIds { strNextActionIds := strings.Join(workflow.FlowCharts.ActionMap[prevId].NextActionIds, ",") strNewNextActionIds := "" - if flowAction.Timeout >0 { + if flowAction.Timeout > 0 { strNewNextActionIds = strNextActionIds + "," + firstActionId - }else { + } else { strNewNextActionIds = strings.ReplaceAll(strNextActionIds, flowAction.ActionId, firstActionId) } workflow.FlowCharts.ActionMap[prevId].NextActionIds = strings.Split(strNewNextActionIds, ",") @@ -128,7 +156,7 @@ func resetWorkflow(wfMap map[int64]*Workflow, workflow *Workflow) error { lastActionId := refWf.FlowCharts.LastActionId if flowAction.ActionId == workflow.FlowCharts.LastActionId { workflow.FlowCharts.LastActionId = lastActionId - }else { + } else { for _, nextId := range flowAction.NextActionIds { strPrevActionIds := strings.Join(workflow.FlowCharts.ActionMap[nextId].PrevActionIds, ",") strNewPrevActionIds := "" @@ -146,72 +174,48 @@ func resetWorkflow(wfMap map[int64]*Workflow, workflow *Workflow) error { //删除 if flowAction.Timeout > 0 { flowAction.ActionType = ActionTypeTimeout - }else{ + } else { delete(workflow.FlowCharts.ActionMap, flowAction.ActionId) } } } + //fmt.Println("before workflow.FlowCharts.HashCondition=>", workflow.FlowCharts.HashCondition) for _, action := range workflow.FlowCharts.ActionMap { + //fmt.Println("actionId=", action.ActionId, "action.ActionType=", action.ActionType) if action.ActionType == ActionTypeCond { workflow.FlowCharts.HashCondition = true break } - } - return nil -} -func NewWorkflowEngineFromFile(moduleObj ModuleObjBase, configPath string) (*WorkflowEngine, error) { - smMap, err := LoadSceneModuleMapFromFile(configPath + "/scene.json") - if err != nil { - return nil, err } - - //更新workflow - wfMap, err := LoadWorkflowFromFile(configPath, smMap) - if err != nil { - return nil, err - } - - resetWorkflows(wfMap) - - mbMap, err := createModelMap(moduleObj, wfMap) - if err != nil { - return nil, err - } - - workfowEngine := newWorkflowEngine(smMap, wfMap, mbMap) - return workfowEngine, nil + //fmt.Println("after workflow.FlowCharts.HashCondition, workflowId=",workflow.Id, "hasCondition=",workflow.FlowCharts.HashCondition) + return nil } -func NewWorkflowEngineFromApollo(moduleObj ModuleObjBase, namespace, configName string) (*WorkflowEngine, error) { - smMap, wfMap, err := LoadSceneModuleWorkflowFromApollo(namespace, configName) - if err != nil { - return nil, err - } - resetWorkflows(wfMap) +func NewWorkflowEngine(sceneModuleMap map[int64]*SceneModule, workflowMap map[int64]*Workflow, version string, moduleObj ModuleObjBase) (*WorkflowEngine, error) { + //TODO ZYF err + resetWorkflows(workflowMap) - mbMap, err := createModelMap(moduleObj, wfMap) + modelBaseMap, err := createModelMap(moduleObj, workflowMap) if err != nil { return nil, err } - - workfowEngine := newWorkflowEngine(smMap, wfMap, mbMap) - return workfowEngine, nil -} - -func newWorkflowEngine(sceneModuleMap map[int64]*SceneModule, workflowMap map[int64]*Workflow, modelBaseMap map[string]IModelBase) *WorkflowEngine { - ut := fmt.Sprintf("%v", time.Now().Format("2006-01-02 15:04:05")) + //ut := fmt.Sprintf("%v", time.Now().Format("2006-01-02 15:04:05")) cExecutors := GetCondExecutors() + flowSelectors := make(map[int]FlowSelector) + flowSelectors[consts.FLOW_BY_ONLINE_RANDOM] = &RandomSelector{} + flowSelectors[consts.FLOW_BY_APOLLO] = &GroupSelector{} wfe := &WorkflowEngine{ sceneModuleMap: sceneModuleMap, workflowMap: workflowMap, modelBaseMap: modelBaseMap, - updateTime: ut, + updateTime: version, condExecutors: cExecutors, + FlowSelectors: flowSelectors, } - return wfe + return wfe, nil } func createModelMap(moduleObj ModuleObjBase, wfMap map[int64]*Workflow) (map[string]IModelBase, error) { @@ -223,7 +227,7 @@ func createModelMap(moduleObj ModuleObjBase, wfMap map[int64]*Workflow) (map[str modelBaseMap := make(map[string]IModelBase) for _, wf := range wfMap { if wf.FlowCharts == nil { - tlog.ErrorCount(ctx, "create_modelbase_err", fmt.Sprintf("flow_charts is nil, workflow=%v", wf)) + tlog.Handler.ErrorCount(ctx, "create_modelbase_err", fmt.Sprintf("flow_charts is nil, workflow=%v", wf)) continue } @@ -234,7 +238,7 @@ func createModelMap(moduleObj ModuleObjBase, wfMap map[int64]*Workflow) (map[str mb, err := createModelBase(moduleObj, action) if mb == nil || err != nil { - tlog.ErrorCount(ctx, "create_modelbase_err", fmt.Sprintf("workflow=%v, action=%v, mb=%v, err=%v", wf, action, mb, err)) + tlog.Handler.ErrorCount(ctx, "create_modelbase_err", fmt.Sprintf("workflow=%v, action=%v, mb=%v, err=%v", wf, action, mb, err)) continue } modelBaseMap[actionId] = mb @@ -250,24 +254,31 @@ func createModelBase(moduleObj ModuleObjBase, action *Action) (IModelBase, error return nil, fmt.Errorf("action or moduleObj empty, action:%v,moduleObj:%v", action, moduleObj) } + mb := moduleObj.NewObj(action.ActionName) + if mb == nil { + return mb, fmt.Errorf("create ModelBase instance error, action:%v", action) + } + + mb.SetName(action.ActionName) + vMap := make(map[string]string) if len(action.Params) > 0 { for _, param := range action.Params { vMap[param.Name] = param.Value } } - vMap["Name"] = action.ActionName - mb := moduleObj.NewObj(action.ActionName, vMap) - if mb == nil { - return mb, fmt.Errorf("create ModelBase instance error, action:%v, vMap:%v", action, vMap) + err := reflectModuleField(mb, vMap) + if err != nil { + tlog.Handler.ErrorCount(context.TODO(), "createModelBase_err", fmt.Sprintf("set module field fail, actionName:%v, vMap:%v, error:%v", action.ActionName, vMap, err)) } return mb, nil } -func (w *WorkflowEngine) GetUpdateTime() string { +func (w *WorkflowEngine) GetVersion() string { return w.updateTime } + func (w *WorkflowEngine) RegisterCondExecutor(conditionName string, executor interface{}) { w.condExecutors.RegisterCondExecutor(conditionName, executor) } @@ -279,10 +290,10 @@ func (w *WorkflowEngine) Run(ctx context.Context, sc *model.StrategyContext) { sc.SetError(action0, err) } }() - //选择一个workflow策略 - flow, err := w.selectWorkFlow(ctx, sc) + + flow, err := w.SelectWorkflow(ctx, sc) if err != nil { - sc.SetError(action0, fmt.Errorf("flow:%v, err:%v", flow, err)) + sc.SetError(action0, fmt.Errorf("no workflow found, flowId=%v, err=%v", sc.FlowId, err)) return } @@ -292,8 +303,7 @@ func (w *WorkflowEngine) Run(ctx context.Context, sc *model.StrategyContext) { return } - wgMap,tsMap := flowChart.CreateWaitMap() - + wgMap, tsMap := flowChart.CreateWaitMap() waitedMap := &sync.Map{} wgn := &sync.WaitGroup{} wgn.Add(1) @@ -303,51 +313,14 @@ func (w *WorkflowEngine) Run(ctx context.Context, sc *model.StrategyContext) { wgn.Wait() } -func (w *WorkflowEngine) selectWorkFlow(ctx context.Context, sc *model.StrategyContext) (*Workflow, error) { - sceneModule, okE := w.sceneModuleMap[sc.SceneId] - if !okE { - return nil, fmt.Errorf("no sceneModule found for scene_id:%v", sc.SceneId) - } +/* +* - var flowId int64 - var slotId int - var groupName string - var err error - if sc.FlowId > 0 { //测试 - flowId = sc.FlowId - } else { - //根据该场景设置的分流方式,获取workflowId - if sceneModule.FlowType == consts.FLOW_BY_ONLINE_RANDOM { - flowId, slotId = FlowByOnlineRandom(sc, sceneModule) - } else if sceneModule.FlowType == consts.FLOW_BY_APOLLO { - flowId, groupName, err = FlowByApollo(sc, sceneModule) - } - - // 如果没有找到 flowId,采用默认的 Workflow - if err != nil || flowId == 0 { - tlog.ErrorCount(ctx, "select_workflow_err", fmt.Sprintf("select workflow by apollo error, err=%v, use default workflow", err)) - flowId = sceneModule.DefaultWorkflowId - err = nil - } - - sc.FlowId = flowId - } - //根据分流选出的workflow_id,取得对应的实验策略配置 - flow, okW := w.workflowMap[flowId] - if !okW { - err := fmt.Errorf("no workflow found, slotId=%v||flowId=%v||groupId=%v||err=%v", slotId, flowId, groupName, err) - return nil, err - } - sc.Set("flow", flow) - sc.Set("groupId", slotId) - sc.Set("scene", sceneModule) - return flow, err -} - -/** 新版本(v1.2.11)后因为有动态条件节点,原流程执行模式有较大变化,不再包含预处理,需实时判断节点走向和执行、跳过节点等操作。 -**/ -func (w *WorkflowEngine) doExecuteModule(ctx context.Context, sc *model.StrategyContext, flowChart *WorkflowChart, skipedActionIdPairs *sync.Map, wgMap map[string]*sync.WaitGroup, tsMap map[string]*TimeWaiter, waitedMap *sync.Map, actionId string, wgn *sync.WaitGroup) { + +* +*/ +func (w *WorkflowEngine) doExecuteModule(ctx context.Context, sc *model.StrategyContext, flowChart *WorkflowChart, skipedActionIdPairs *sync.Map, wgMap map[string]*sync.WaitGroup, tsMap map[string]*TimeWaiter, waitedMap *sync.Map, actionId string, wgn *sync.WaitGroup) { action, ok := flowChart.ActionMap[actionId] if !ok { return @@ -370,7 +343,7 @@ func (w *WorkflowEngine) doExecuteModule(ctx context.Context, sc *model.Strategy if timeoutActionId == "" { wgMap[action.ActionId].Wait() - }else { + } else { go func() { wgMap[action.ActionId].Wait() if tsMap[timeoutActionId] != nil { @@ -382,7 +355,7 @@ func (w *WorkflowEngine) doExecuteModule(ctx context.Context, sc *model.Strategy if mb, _ := w.modelBaseMap[timeoutActionId]; mb != nil { if flowChart.ActionMap[timeoutActionId].TimeoutAsync { go mb.OnTimeout(ctx, sc) - }else{ + } else { mb.OnTimeout(ctx, sc) } } @@ -412,13 +385,13 @@ func (w *WorkflowEngine) doExecuteModule(ctx context.Context, sc *model.Strategy } -func (w *WorkflowEngine) skipBranch(flowChart *WorkflowChart, wgMap map[string]*sync.WaitGroup, skipedActionIdPairs *sync.Map, toExcludeActionId string, prevAction *Action, action *Action){ +func (w *WorkflowEngine) skipBranch(flowChart *WorkflowChart, wgMap map[string]*sync.WaitGroup, skipedActionIdPairs *sync.Map, toExcludeActionId string, prevAction *Action, action *Action) { if prevAction == nil || action == nil { return } - if len(action.PrevActionIds)>1 { - if _, ok := skipedActionIdPairs.LoadOrStore(prevAction.ActionId + "_" + action.ActionId, ""); !ok { + if len(action.PrevActionIds) > 1 { + if _, ok := skipedActionIdPairs.LoadOrStore(prevAction.ActionId+"_"+action.ActionId, ""); !ok { wgMap[action.ActionId].Done() } } @@ -429,46 +402,51 @@ func (w *WorkflowEngine) skipBranch(flowChart *WorkflowChart, wgMap map[string]* return } - for _, nextActionId := range action.NextActionIds { + nextCount := len(action.NextActionIds) + for i := nextCount - 1; i >= 0; i-- { + nextActionId := action.NextActionIds[i] nextAction := flowChart.ActionMap[nextActionId] w.skipBranch(flowChart, wgMap, skipedActionIdPairs, toExcludeActionId, action, nextAction) } } -func (w *WorkflowEngine) executeModule(ctx context.Context, sc *model.StrategyContext, flowChart *WorkflowChart, action *Action, skipedActionIdPairs *sync.Map, wgMap map[string]*sync.WaitGroup, tsMap map[string]*TimeWaiter, wgn *sync.WaitGroup) string { +func (w *WorkflowEngine) executeModule(ctx context.Context, sc *model.StrategyContext, flowChart *WorkflowChart, action *Action, skipedActionIdPairs *sync.Map, wgMap map[string]*sync.WaitGroup, tsMap map[string]*TimeWaiter, wgn *sync.WaitGroup) string { toExeActionId := "" defer func() { if err := recover(); err != nil { - tlog.ErrorCount(ctx, "executeModule_err", fmt.Sprintf("actionId=%+v,err=%+v", action.ActionId, err)) + tlog.Handler.ErrorCount(ctx, "executeModule_err", fmt.Sprintf("actionId=%+v,err=%+v", action.ActionId, err)) sc.SetError(action.ActionId, fmt.Errorf("%v", err)) sc.Skip(ErrNoUnknown, fmt.Sprintf("executeModule_err, actionId=%+v, err=%+v", action.ActionId, err)) } - for _, nextActionId := range action.NextActionIds { + nextCount := len(action.NextActionIds) + for i := nextCount - 1; i >= 0; i-- { + nextActionId := action.NextActionIds[i] nextAction, ok := flowChart.ActionMap[nextActionId] if !ok { continue } if action.ActionType == ActionTypeCond { - //condition if nextActionId != toExeActionId { w.skipBranch(flowChart, wgMap, skipedActionIdPairs, toExeActionId, action, nextAction) } - }else{ - //task - if len(nextAction.PrevActionIds) > 1 { + } + + if len(nextAction.PrevActionIds) > 1 { + if _, ok := skipedActionIdPairs.LoadOrStore(action.ActionId+"_"+nextActionId, ""); !ok { wgMap[nextActionId].Done() } } + } if action.ActionId == flowChart.LastActionId { wgn.Done() } - //fmt.Println(fmt.Sprintf("====>Finish time=%v ,actionId=%v, actionName=%v", time.Now().Format("2006-01-02 15:04:05.000"), action.ActionId, action.ActionName)) + //fmt.Println(fmt.Sprintf("====>Finish time=%v ,actionId=%v, actionName=%v, action=%+v", time.Now().Format("2006-01-02 15:04:05.000"), action.ActionId, action.ActionName,action)) }() if action == nil { @@ -479,7 +457,7 @@ func (w *WorkflowEngine) executeModule(ctx context.Context, sc *model.StrategyCo var err error toExeActionId, err = action.executeCond(sc.ContextMap) if err != nil { - tlog.ErrorCount(ctx, "executeCond_err", fmt.Sprintf("execute condition error, actionId=%+v, toExeActionId=%+v, err=%+v", action.ActionId, toExeActionId, err)) + tlog.Handler.ErrorCount(ctx, "executeCond_err", fmt.Sprintf("execute condition error, actionId=%+v, toExeActionId=%+v, err=%+v", action.ActionId, toExeActionId, err)) sc.SetError(action.ActionId, fmt.Errorf("action.executeCond error, ActionName:%v, err:%v", action.ActionName, err)) } return toExeActionId @@ -488,10 +466,10 @@ func (w *WorkflowEngine) executeModule(ctx context.Context, sc *model.StrategyCo if moduleBase, ok := w.modelBaseMap[action.ActionId]; ok { if !sc.IsSkip() { startTime := time.Now().UnixNano() / 1e6 - var result interface{} - if action.Timeout>0 && action.ActionType != ActionTypeTimeout { + sc.TC.StartSectionCount(action.ActionName) + if action.Timeout > 0 && action.ActionType != ActionTypeTimeout { go func() { - result = moduleBase.DoAction(ctx, sc) + moduleBase.DoAction(ctx, sc) if tsMap[action.ActionId] != nil { tsMap[action.ActionId].Done() } @@ -500,10 +478,10 @@ func (w *WorkflowEngine) executeModule(ctx context.Context, sc *model.StrategyCo sc.AddTimeoutAction(action.ActionName) if action.TimeoutAsync { go moduleBase.OnTimeout(ctx, sc) - }else{ + } else { moduleBase.OnTimeout(ctx, sc) } - }else{ + } else { if action.TimeoutDynamic { for _, nextActionId := range action.NextActionIds { if ts, ok := tsMap[nextActionId]; ok { @@ -513,12 +491,11 @@ func (w *WorkflowEngine) executeModule(ctx context.Context, sc *model.StrategyCo } } } - }else{ - result = moduleBase.DoAction(ctx, sc) + } else { + moduleBase.DoAction(ctx, sc) } - endTime := time.Now().UnixNano() / 1e6 - sc.SetModuleResult(action.ActionId, action.ActionName, endTime-startTime, result) + sc.TC.StopSectionCount(action.ActionName) } } else { sc.SetError(action.ActionId, fmt.Errorf("module not found in map, moduleMap:%v, moduleName:%v", w.modelBaseMap, action.ActionName)) @@ -527,4 +504,3 @@ func (w *WorkflowEngine) executeModule(ctx context.Context, sc *model.StrategyCo return "" } - diff --git a/tg-core/wfengine/workflow_apollo_dao.go b/wfengine/engine_from_apollo.go similarity index 39% rename from tg-core/wfengine/workflow_apollo_dao.go rename to wfengine/engine_from_apollo.go index b1374ceace17a36fd5e1515bb61f0c7951ccc6d1..c37c8c091d7c30bf865d5ce9a2347faa1f00ebad 100644 --- a/tg-core/wfengine/workflow_apollo_dao.go +++ b/wfengine/engine_from_apollo.go @@ -1,7 +1,7 @@ /** - Description : loader of workflow config info from apollo config - Author : dayunzhangyunfeng@didiglobal.com - Date : 2023-01-09 14:30 +Description : loader of workflow config info from apollo config +Author : dayunzhangyunfeng@didiglobal.com +Date : 2023-01-09 14:30 */ package wfengine @@ -10,52 +10,65 @@ import ( "context" "encoding/json" "fmt" - "github.com/didi/tg-flow/tg-core/common/tlog" - "github.com/didi/tg-flow/tg-core/wfengine/apollo" + "github.com/didi/tg-flow/common/tlog" "strconv" "strings" ) const ( - dftRange = "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99" - sceneKey = "scene" - ) - -func LoadSceneModuleWorkflowFromApollo(namespace, configName string) (map[int64]*SceneModule, map[int64]*Workflow, error) { - apolloConfig, err := apollo.NewApolloConfig(namespace, configName) - if err != nil || apolloConfig == nil { - return nil, nil, fmt.Errorf("init apolloConfig fail, namespace=%v, configName=%v, err=%v", namespace, configName, err) + dftRange = "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99" + sceneKey = "scene" + versionKey = "version" +) + +//func GetLatestVersionFromApollo(namespace, configName string) (string, error) { +// apolloConfig, err := apollo.NewApolloConfig(namespace, configName) +// if err != nil || apolloConfig == nil { +// return "", fmt.Errorf("NewApolloConfig error, namespace=%v, configName=%v, err=%v", namespace, configName, err) +// } +// +// configParams := apolloConfig.GetConfigs() +// if configParams == nil || configParams[versionKey] == "" { +// return "", fmt.Errorf("GetConfigs fail, configParam is nil or version empty, namespace=%v, configName=%v, configParams.lenth=%v", namespace, configName, len(configParams)) +// } +// +// return configParams[versionKey], nil +//} + +func NewWorkflowEngineFromConfig(moduleObj ModuleObjBase, configParams map[string]string) (*WorkflowEngine, error) { + smMap, wfMap, version, err := loadSceneModuleWorkflowFromApollo(configParams) + if err != nil { + return nil, err } - configParams := apolloConfig.GetConfigs() - if configParams == nil || configParams[sceneKey] == "" { - return nil, nil, fmt.Errorf("apollo GetConfigs fail, some keys not found namespace=%v, configName=%v, configParams=%v", namespace, configName, configParams) + return NewWorkflowEngine(smMap, wfMap, version, moduleObj) +} + +func loadSceneModuleWorkflowFromApollo(configParams map[string]string) (map[int64]*SceneModule, map[int64]*Workflow, string, error) { + if configParams == nil { + return nil, nil, "", fmt.Errorf("GetConfigs error, configParams is nil") } - sceneModuleString := "" - for key, val := range configParams { - if key == sceneKey { - sceneModuleString = val - break - } + if configParams[sceneKey] == "" { + return nil, nil, "", fmt.Errorf("configParams error, sceneKey[%v] is empty", sceneKey) } - smMap, err := loadSceneModuleString(sceneModuleString) + smMap, err := loadSceneModuleString(configParams[sceneKey]) if err != nil { - return nil, nil, err + return nil, nil, "", err } //更新workflow wfMap, err := LoadWorkflowFromApollo(configParams) if err != nil { - return nil, nil, err + return nil, nil, "", err } - return smMap, wfMap, nil + return smMap, wfMap, configParams[versionKey], nil } func loadSceneModuleString(sceneModuleMapString string) (map[int64]*SceneModule, error) { - if len(sceneModuleMapString) <=0 { + if len(sceneModuleMapString) <= 0 { return nil, fmt.Errorf("the param sceneModuleMapString:[%v] must not be empty", sceneModuleMapString) } @@ -69,24 +82,24 @@ func loadSceneModuleString(sceneModuleMapString string) (map[int64]*SceneModule, } func LoadWorkflowFromApollo(configParams map[string]string) (map[int64]*Workflow, error) { - if configParams == nil || len(configParams)<=0 { + if configParams == nil || len(configParams) <= 0 { return nil, fmt.Errorf("configParam is empty:%v", configParams) } //对每个文件逐个加到map wfMap := make(map[int64]*Workflow) for key, val := range configParams { - if key == sceneKey { + if key == sceneKey || key == versionKey { continue } wf, err := createWorkflowFromKV(key, val) if wf == nil || err != nil { - tlog.ErrorCount(context.TODO(),"loadWorkflowFromKV_err", fmt.Sprintf("wf:%v,err:%v", wf, err)) + tlog.Handler.ErrorCount(context.TODO(), "loadWorkflowFromKV_err", fmt.Sprintf("wf:%v,err:%v", wf, err)) continue } wf.FlowCharts, err = NewWorkflowChart(wf.FlowChart) if err != nil { - tlog.ErrorCount(context.TODO(),"NewWorkflowChart_err", fmt.Sprintf("wf:%v,err:%v", wf, err)) + tlog.Handler.ErrorCount(context.TODO(), "NewWorkflowChart_err", fmt.Sprintf("wf:%v,err:%v", wf, err)) continue } wfMap[wf.Id] = wf @@ -97,7 +110,7 @@ func LoadWorkflowFromApollo(configParams map[string]string) (map[int64]*Workflow func createWorkflowFromKV(key, val string) (*Workflow, error) { strs := strings.Split(key, "-") - if len(strs)<3 { + if len(strs) < 3 { return nil, fmt.Errorf("invalid key:%v, it must start with :workflow-sceneId-workflowId", key) } @@ -105,25 +118,25 @@ func createWorkflowFromKV(key, val string) (*Workflow, error) { if err != nil { return nil, fmt.Errorf("invalid sceneId:%v in key:%v,err=%v", strs[1], key, err) } - workflowId, err := strconv.ParseInt(strs[2], 10, 64) + workflowId, err := strconv.ParseInt(strs[2], 10, 64) if err != nil { return nil, fmt.Errorf("invalid workflowId:%v in key:%v,err=%v", strs[2], key, err) } workflow := &Workflow{ - Id : workflowId, - DimensionId : -1, - SceneId : sceneId, - FlowChart : val, - FlowCharts : nil, - FlowBranch : nil, - IsDefault : 1, - Range1 : dftRange, - Range2 : "", - Remark : "", + Id: workflowId, + DimensionId: -1, + SceneId: sceneId, + FlowChart: val, + FlowCharts: nil, + FlowBranch: nil, + IsDefault: 1, + Range1: dftRange, + Range2: "", + Remark: "", //UpdateTime:, - GroupName : "", + GroupName: "", } return workflow, nil -} \ No newline at end of file +} diff --git a/tg-core/wfengine/workflow_store.go b/wfengine/engine_from_file.go similarity index 39% rename from tg-core/wfengine/workflow_store.go rename to wfengine/engine_from_file.go index cb96a1ab21be01c1eedcbc38deb1b3111e9ab9d1..1b7fdc39c04959e5eb71ce5449941b7b174b1b9c 100644 --- a/tg-core/wfengine/workflow_store.go +++ b/wfengine/engine_from_file.go @@ -1,15 +1,16 @@ /** - Description : loader of workflow config info from files - Author : dayunzhangyunfeng@didiglobal.com - Date : 2021-05-14 +Description : loader of workflow config info from files +Author : dayunzhangyunfeng@didiglobal.com +Date : 2021-05-14 */ package wfengine import ( "context" + "encoding/json" "fmt" - "github.com/didi/tg-flow/tg-core/common/tlog" + "github.com/didi/tg-flow/common/tlog" "io/ioutil" "os" "strconv" @@ -17,12 +18,69 @@ import ( ) const ( - defaultRange = "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99" + defaultRange = "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99" + versionFileName = "/version" ) +func GetLatestVersionFromFile(path string) (string, error) { + jsonFile, err := os.Open(path + versionFileName) + if err != nil { + return "", fmt.Errorf("os.open error, file:%v, err:%v", path, err) + } + defer jsonFile.Close() + + byteValue, err := ioutil.ReadAll(jsonFile) + if err != nil { + return "", fmt.Errorf("ioutil.ReadAll error, byteValue:%v,err=%v", string(byteValue), err) + } + + return string(byteValue), nil +} + +func NewWorkflowEngineFromFile(moduleObj ModuleObjBase, configPath string) (*WorkflowEngine, error) { + smMap, err := LoadSceneModuleMapFromFile(configPath + "/scene.json") + if err != nil { + return nil, err + } + + //更新workflow + wfMap, err := LoadWorkflowFromFile(configPath, smMap) + if err != nil { + return nil, err + } + + version, err1 := GetLatestVersionFromFile(configPath) + if err1 != nil { + tlog.Handler.ErrorCount(context.TODO(), "GetLatestVersionFromRedis_err", fmt.Sprintf("configPath=%v, err=%v", configPath, err1)) + } + + return NewWorkflowEngine(smMap, wfMap, version, moduleObj) +} + +func LoadSceneModuleMapFromFile(path string) (map[int64]*SceneModule, error) { + jsonFile, err := os.Open(path) + if err != nil { + return nil, fmt.Errorf("os.open error, file:%v, err:%v", path, err) + } + defer jsonFile.Close() + + byteValue, err := ioutil.ReadAll(jsonFile) + if err != nil { + return nil, fmt.Errorf("ioutil.ReadAll error, byteValue:%v,err=%v", string(byteValue), err) + } + + var sceneModuleMap map[int64]*SceneModule + err = json.Unmarshal(byteValue, &sceneModuleMap) + if err != nil { + return nil, fmt.Errorf("json.Unmarshal error, byteValue:%v,err=%v", string(byteValue), err) + } + + return sceneModuleMap, nil +} + func LoadWorkflowFromFile(dirPath string, smMap map[int64]*SceneModule) (map[int64]*Workflow, error) { //1.遍历目录 - filePaths:= make(map[string]string) + filePaths := make(map[string]string) err := getWorkflowFiles(dirPath, filePaths) if err != nil { return nil, err @@ -33,12 +91,12 @@ func LoadWorkflowFromFile(dirPath string, smMap map[int64]*SceneModule) (map[int for filePath, _ := range filePaths { wf, err := createWorkflowFromFile(filePath) if wf == nil || err != nil { - tlog.ErrorCount(context.TODO(),"loadWorkflowFromFile_err", fmt.Sprintf("wf:%v,err:%v", wf, err)) + tlog.Handler.ErrorCount(context.TODO(), "loadWorkflowFromFile_err", fmt.Sprintf("wf:%v,err:%v", wf, err)) continue } wf.FlowCharts, err = NewWorkflowChart(wf.FlowChart) if err != nil { - tlog.ErrorCount(context.TODO(),"NewWorkflowChart_err", fmt.Sprintf("wf:%v,err:%v", wf, err)) + tlog.Handler.ErrorCount(context.TODO(), "NewWorkflowChart_err", fmt.Sprintf("wf:%v,err:%v", wf, err)) continue } wfMap[wf.Id] = wf @@ -48,8 +106,8 @@ func LoadWorkflowFromFile(dirPath string, smMap map[int64]*SceneModule) (map[int } func getWorkflowFiles(path string, filePaths map[string]string) error { - if !strings.HasSuffix(path,"/"){ - path = path +"/" + if !strings.HasSuffix(path, "/") { + path = path + "/" } rd, err := ioutil.ReadDir(path) @@ -60,9 +118,9 @@ func getWorkflowFiles(path string, filePaths map[string]string) error { for _, fi := range rd { if fi.IsDir() { getWorkflowFiles(path+fi.Name(), filePaths) - }else if strings.HasPrefix(fi.Name(),"workflow-") { + } else if strings.HasPrefix(fi.Name(), "workflow-") { filePath := path + fi.Name() - filePaths[filePath]= "" + filePaths[filePath] = "" } } @@ -80,14 +138,14 @@ func createWorkflowFromFile(path string) (*Workflow, error) { idx := strings.Index(fileName, ".") fileName = fileName[:idx] strs := strings.Split(fileName, "-") - if len(strs)<3 { - return nil, fmt.Errorf("invalid workflow file name:%v, it must start with :workflow-sceneId-workflowId",jsonFile.Name()) + if len(strs) < 3 { + return nil, fmt.Errorf("invalid workflow file name:%v, it must start with :workflow-sceneId-workflowId", jsonFile.Name()) } sceneId, err := strconv.ParseInt(strs[1], 10, 64) if err != nil { return nil, fmt.Errorf("invalid sceneId:%v in file name:%v,err=%v", strs[1], fileName, err) } - workflowId, err := strconv.ParseInt(strs[2], 10, 64) + workflowId, err := strconv.ParseInt(strs[2], 10, 64) if err != nil { return nil, fmt.Errorf("invalid workflowId:%v in file name:%v,err=%v", strs[2], fileName, err) } @@ -99,19 +157,19 @@ func createWorkflowFromFile(path string) (*Workflow, error) { flowChartStr := string(byteValue) workflow := &Workflow{ - Id : workflowId, - DimensionId : -1, - SceneId : sceneId, - FlowChart : flowChartStr, - FlowCharts : nil, - FlowBranch : nil, - IsDefault : 1, - Range1 : defaultRange, - Range2 : "", - Remark : "", + Id: workflowId, + DimensionId: -1, + SceneId: sceneId, + FlowChart: flowChartStr, + FlowCharts: nil, + FlowBranch: nil, + IsDefault: 1, + Range1: defaultRange, + Range2: "", + Remark: "", //UpdateTime:, - GroupName : "", + GroupName: "", } return workflow, nil -} \ No newline at end of file +} diff --git a/tg-core/wfengine/workflow_dao.go b/wfengine/engine_from_redis.go similarity index 38% rename from tg-core/wfengine/workflow_dao.go rename to wfengine/engine_from_redis.go index a83a575b0033f8f7291ea2a5ad614131b92eb983..4762f895e341e5f743d96be1b953b5b936e441f2 100644 --- a/tg-core/wfengine/workflow_dao.go +++ b/wfengine/engine_from_redis.go @@ -10,19 +10,30 @@ import ( "context" "encoding/json" "fmt" - "github.com/didi/tg-flow/tg-core/common/redis" - "github.com/didi/tg-flow/tg-core/common/tlog" + "github.com/didi/tg-flow/common/tlog" ) const ( - RedisKeyWorkflow = "workflow_app_" + RedisKeySceneModule = "scene_module_app_" + RedisKeyWorkflow = "workflow_app_" + RedisKeyVersion = "version_app_" ) -func LoadWorkflow(appId int64, smMap map[int64]*SceneModule) (map[int64]*Workflow, error) { - workflowMapStr, err := redis.Handler.Get(context.TODO(), fmt.Sprintf("%v%v",RedisKeyWorkflow, appId)) +//func GetLatestVersionFromRedis(appId int64) (string, error) { +// return redis.Handler.Get(context.TODO(), fmt.Sprintf("%v%v", RedisKeyVersion, appId)) +//} + +func NewWorkflowEngineFromKV(moduleObj ModuleObjBase, sceneModuleMapString, workflowMapStr, version string) (*WorkflowEngine, error) { + var sceneModuleMap map[int64]*SceneModule + err := json.Unmarshal([]byte(sceneModuleMapString), &sceneModuleMap) if err != nil { - return nil, err + return nil, fmt.Errorf("err:%v, sceneModule:%v", err, sceneModuleMapString) } + /*for sceneId, sceneModule := range sceneModuleMap { + if sceneModule.AppId != appId { + delete(sceneModuleMap, sceneId) + } + }*/ var workflowMap map[int64]*Workflow err = json.Unmarshal([]byte(workflowMapStr), &workflowMap) @@ -32,15 +43,15 @@ func LoadWorkflow(appId int64, smMap map[int64]*SceneModule) (map[int64]*Workflo wfMap := make(map[int64]*Workflow) for workflowId, workflow := range workflowMap { - if _, ok := smMap[workflow.SceneId]; ok { + if _, ok := sceneModuleMap[workflow.SceneId]; ok { workflow.FlowCharts, err = NewWorkflowChart(workflow.FlowChart) if err != nil { - tlog.ErrorCount(context.TODO(),"NewWorkflowChart_err", fmt.Sprintf("wf:%v,err:%v", workflow, err)) + tlog.Handler.ErrorCount(context.TODO(), "NewWorkflowChart_err", fmt.Sprintf("wf:%v,err:%v", workflow, err)) continue } wfMap[workflowId] = workflow } } - return wfMap, nil -} \ No newline at end of file + return NewWorkflowEngine(sceneModuleMap, wfMap, version, moduleObj) +} diff --git a/wfengine/flow_selector.go b/wfengine/flow_selector.go new file mode 100644 index 0000000000000000000000000000000000000000..e29f9777f011566e1b5732d8d8a5ed320c0ae581 --- /dev/null +++ b/wfengine/flow_selector.go @@ -0,0 +1,15 @@ +package wfengine + +import "github.com/didi/tg-flow/model" + +/* +* +there are 3 flow selector: + + 1: random + 2: custom + 3: apollo (apollo platform in didi) +*/ +type FlowSelector interface { + SelectWorkflowId(sc *model.StrategyContext, sceneModule *SceneModule) (int64, string, error) +} diff --git a/wfengine/group_selector.go b/wfengine/group_selector.go new file mode 100644 index 0000000000000000000000000000000000000000..8b4498bd5682cce3f54cf1e1f175058e3798e9e9 --- /dev/null +++ b/wfengine/group_selector.go @@ -0,0 +1,39 @@ +package wfengine + +import ( + "fmt" + "github.com/didi/tg-flow/model" +) + +type GroupSelector struct { + FlowSelector +} + +/* +* +apollo分流, +如果出现error,就取缺省分桶,同时返回error信息 +*/ +func (a *GroupSelector) SelectWorkflowId(sc *model.StrategyContext, sceneModule *SceneModule) (int64, string, error) { + //var err error + //if a.ApolloInfo == nil { + // return -1, "", fmt.Errorf("apollo info not initialized") + //} + // + //// 优先采用 ApolloInfo 中设置的分流实验名称,没有的话采用场景中配置的分流实验名称 + //if a.ApolloInfo.GetDispatchExperimentName() == "" { + // a.ApolloInfo.SetDispatchExperimentName(sceneModule.DispatchExperimentName) + //} + // + //groupName, err := a.ApolloInfo.GetDispatchGroupName() + //if err != nil { + // return -1, groupName, fmt.Errorf("get dispatch groupName fail,groupName=%v, err=%v", groupName, err) + //} + + workflowId, err := sceneModule.GetWorkflowId(sc.GroupName) + if err == nil { + return workflowId, sc.GroupName, nil + } + + return -1, sc.GroupName, fmt.Errorf("select workflowId error, groupName=%v,workflowId=%v,err=%v", sc.GroupName, workflowId, err) +} diff --git a/tg-core/wfengine/inneraction/timeout_action.go b/wfengine/inneraction/timeout_action.go similarity index 84% rename from tg-core/wfengine/inneraction/timeout_action.go rename to wfengine/inneraction/timeout_action.go index ad34ae26e735c3ae2bce0c08c00c72732725ec84..87e4aa16921c2f8f82921b56b3c041ef2639ccf2 100644 --- a/tg-core/wfengine/inneraction/timeout_action.go +++ b/wfengine/inneraction/timeout_action.go @@ -2,8 +2,8 @@ package inneraction import ( "context" - "github.com/didi/tg-flow/tg-core/model" - "github.com/didi/tg-flow/tg-core/wfengine" + "github.com/didi/tg-flow/model" + "github.com/didi/tg-flow/wfengine" ) type TimeoutAction struct { @@ -19,4 +19,4 @@ func (t TimeoutAction) DoAction(ctx context.Context, sc *model.StrategyContext) func (m TimeoutAction) OnTimeout(context.Context, *model.StrategyContext) { //this is a sample, you can do sth when timeout happen //fmt.Println("default OnTimeout function, nothing to do !!!") -} \ No newline at end of file +} diff --git a/tg-core/wfengine/module_base.go b/wfengine/module_base.go similarity index 72% rename from tg-core/wfengine/module_base.go rename to wfengine/module_base.go index 2bad9b2a6cc46209e62318391465abf54a4d4350..409a1419db331531a2cfefe057da7f64a9514c72 100644 --- a/tg-core/wfengine/module_base.go +++ b/wfengine/module_base.go @@ -1,7 +1,7 @@ /** - Description : ModelBase interface define - Author : dayunzhangyunfeng@didiglobal.com - Date : 2021-05-14 +Description : ModelBase interface define +Author : dayunzhangyunfeng@didiglobal.com +Date : 2021-05-14 */ package wfengine @@ -9,13 +9,13 @@ package wfengine import ( "context" "fmt" - "github.com/didi/tg-flow/tg-core/common/tlog" - "github.com/didi/tg-flow/tg-core/model" + "github.com/didi/tg-flow/common/tlog" + "github.com/didi/tg-flow/model" "reflect" "strconv" ) -type IModelBase interface{ +type IModelBase interface { DoAction(context.Context, *model.StrategyContext) interface{} OnTimeout(context.Context, *model.StrategyContext) SetName(string) @@ -24,10 +24,10 @@ type IModelBase interface{ type ModelBase struct { IModelBase - Name string + Name string } -func (m *ModelBase) DoAction(context.Context, *model.StrategyContext) interface{}{ +func (m *ModelBase) DoAction(context.Context, *model.StrategyContext) interface{} { return nil } @@ -44,24 +44,29 @@ func (m *ModelBase) GetName() string { } type ModuleObjBase interface { - NewObj(moduleName string, vMap map[string]string) IModelBase + NewObj(moduleName string) IModelBase } -func ReflectModuleField(obj interface{}, reflectType reflect.Type, vMap map[string]string) error { +func reflectModuleField(obj interface{}, vMap map[string]string) error { + if len(vMap) == 0 { + return nil + } + v := reflect.ValueOf(obj) if v.Kind() == reflect.Ptr && !v.Elem().CanSet() { err := fmt.Errorf("this obj is not match reflect") - tlog.ErrorCount(context.TODO(),"ReflectModuleField_err", fmt.Sprintf("obj:%v, err:%v", obj, err)) + tlog.Handler.ErrorCount(context.TODO(), "ReflectModuleField_err", fmt.Sprintf("obj:%v, err:%v", obj, err)) return err } + reflectType := reflect.Indirect(v).Type() v = v.Elem() for i := 0; i < reflectType.NumField(); i++ { field := reflectType.Field(i) fieldValue := v.FieldByName(field.Name) if !fieldValue.IsValid() { err := fmt.Errorf("this obj(" + fmt.Sprintf("%v", obj) + ") field(" + field.Name + ")") - tlog.ErrorCount(context.TODO(),"ReflectModuleField_err", fmt.Sprintf("%v", err)) + tlog.Handler.ErrorCount(context.TODO(), "ReflectModuleField_err", fmt.Sprintf("%v", err)) continue } @@ -76,7 +81,7 @@ func ReflectModuleField(obj interface{}, reflectType reflect.Type, vMap map[stri tempInt, err := strconv.ParseInt(vMap[field.Name], 10, 64) if err != nil { err := fmt.Errorf("obj(" + fmt.Sprintf("%v", obj) + ") field(" + field.Name + ")'s value(" + vMap[field.Name] + ")") - tlog.ErrorCount(context.TODO(),"ReflectModuleField_err", fmt.Sprintf("%v", err)) + tlog.Handler.ErrorCount(context.TODO(), "ReflectModuleField_err", fmt.Sprintf("%v", err)) continue } fieldValue.SetInt(tempInt) @@ -85,7 +90,7 @@ func ReflectModuleField(obj interface{}, reflectType reflect.Type, vMap map[stri tempFolat, err := strconv.ParseFloat(vMap[field.Name], 64) if err != nil { err := fmt.Errorf("obj(" + fmt.Sprintf("%v", obj) + ") field(" + field.Name + ")'s value(" + vMap[field.Name] + ")") - tlog.ErrorCount(context.TODO(),"ReflectModuleField_err", fmt.Sprintf("%v", err)) + tlog.Handler.ErrorCount(context.TODO(), "ReflectModuleField_err", fmt.Sprintf("%v", err)) continue } fieldValue.SetFloat(tempFolat) diff --git a/tg-core/wfengine/flow_splitter.go b/wfengine/random_selector.go similarity index 30% rename from tg-core/wfengine/flow_splitter.go rename to wfengine/random_selector.go index 01e53390da3af992e36480306e6d5c951d4e34b1..c7850c05a2947916e5312d4f3e8ce01c62f97e23 100644 --- a/tg-core/wfengine/flow_splitter.go +++ b/wfengine/random_selector.go @@ -1,24 +1,28 @@ -/** -Description : flow splitter -Author : dayunzhangyunfeng@didiglobal.com -Date : 2021-05-14 -*/ package wfengine import ( "fmt" - "github.com/didi/tg-flow/tg-core/model" + "github.com/didi/tg-flow/model" "hash/crc32" + "strconv" "time" ) -//在线随机分流 -func FlowByOnlineRandom(sc *model.StrategyContext, sceneModule *SceneModule) (int64, int) { +type RandomSelector struct { + FlowSelector +} + +// 在线随机分流 +func (r *RandomSelector) SelectWorkflowId(sc *model.StrategyContext, sceneModule *SceneModule) (int64, string, error) { //1、根据用户id,算出一个0-99的数字 slotId := getSlotId(sc.UserId, sceneModule.BucketType) - //2、在对应的维度id内,根据slotId,选择对应的workflow - return sceneModule.SlotMap[slotId], slotId + workflowId, ok := sceneModule.SlotMap[slotId] + if !ok { + return -1, "", fmt.Errorf("no workflowId found, UserId=%v, BucketType=%v", sc.UserId, sceneModule.BucketType) + } + + return workflowId, strconv.Itoa(slotId), nil } func getSlotId(str string, bucketType int) int { @@ -32,28 +36,3 @@ func getSlotId(str string, bucketType int) int { } return v % 100 } - -// FlowByApollo apollo分流 -func FlowByApollo(sc *model.StrategyContext, sceneModule *SceneModule) (int64, string, error) { - var err error - if sc.ApolloInfo == nil { - return 0, "", fmt.Errorf("apollo info not initialized") - } - - // 优先采用 ApolloInfo 中设置的分流实验名称,没有的话采用场景中配置的分流实验名称 - if sc.ApolloInfo.GetDispatchExperimentName() == "" { - sc.ApolloInfo.SetDispatchExperimentName(sceneModule.DispatchExperimentName) - } - - groupName, err := sc.ApolloInfo.GetDispatchGroupName() - if err != nil { - return 0, "", err - } - - workflowId, err := sceneModule.GetWorkflowId(groupName) - if err == nil { - return workflowId, groupName, nil - } else { - return workflowId, groupName, err - } -} diff --git a/tg-core/wfengine/scene_module.go b/wfengine/scene_module.go similarity index 100% rename from tg-core/wfengine/scene_module.go rename to wfengine/scene_module.go diff --git a/tg-core/wfengine/test/condition_external.go b/wfengine/test/condition_external.go similarity index 100% rename from tg-core/wfengine/test/condition_external.go rename to wfengine/test/condition_external.go diff --git a/tg-core/wfengine/time_waiter.go b/wfengine/time_waiter.go similarity index 100% rename from tg-core/wfengine/time_waiter.go rename to wfengine/time_waiter.go diff --git a/tg-core/wfengine/workflow.go b/wfengine/workflow.go similarity index 86% rename from tg-core/wfengine/workflow.go rename to wfengine/workflow.go index f580d08be523dcd83c734d9fc20f5c951cc70bc4..150ee53ed23fb4bf42e858cb3b8c7e8d56e18990 100644 --- a/tg-core/wfengine/workflow.go +++ b/wfengine/workflow.go @@ -87,14 +87,14 @@ func NewWorkflowChart(flowChartStr string) (*WorkflowChart, error) { if len(flowChartStr) == 0 { return nil, errors.New("create WorkflowChart fail, flowChartStr is empty") } - + flowChart := &WorkflowChart{} //读取的数据为json格式,需要进行解码 err := json.Unmarshal([]byte(flowChartStr), flowChart) if err != nil { return nil, fmt.Errorf("create WorkflowChart fail, invalid json:%v, err:%v", flowChartStr, err) } - + err = flowChart.setFirstActionId() if err != nil { return nil, fmt.Errorf("create WorkflowChart fail, err:%v", err) @@ -114,7 +114,7 @@ func (w *WorkflowChart) setPrevActionIds(actionId string){ if actionId == w.FirstActionId { action.PrevActionIds = []string{} } - + nextActionIds := action.NextActionIds for _, nextActionId := range nextActionIds { nextAction, ok := w.ActionMap[nextActionId] @@ -122,7 +122,7 @@ func (w *WorkflowChart) setPrevActionIds(actionId string){ //报个error? continue } - + if nextAction.PrevActionIds == nil || len(nextAction.PrevActionIds) == 0 { nextAction.PrevActionIds = []string{actionId} }else{ @@ -138,7 +138,7 @@ func (w *WorkflowChart) setPrevActionIds(actionId string){ nextAction.PrevActionIds = append(nextAction.PrevActionIds, actionId) } } - + w.setPrevActionIds(nextActionId) } } @@ -153,19 +153,19 @@ func (w *WorkflowChart) setFirstActionId() error { w.LastActionId = action.ActionId continue } - + for _, nextId := range action.NextActionIds { nextActionIds[nextId] = true } } - + for actionId,_ := range w.ActionMap { if _, ok := nextActionIds[actionId]; !ok { w.FirstActionId = actionId return nil } } - + return errors.New("first action not found") } @@ -184,7 +184,7 @@ func (w *WorkflowChart) CreateWaitMap() (map[string]*sync.WaitGroup, map[string] tsMap[actionId] = NewTimeWaiter(action.Timeout) } } - + return wgMap,tsMap } @@ -250,30 +250,44 @@ func (a *Action) createParamSlice(paramValues *sync.Map) ([]interface{}, error) } func (a *Action) Detach(prevAction *Action) { - if prevAction == nil { + if prevAction == nil || len(a.PrevActionIds)==0 { //todo error return } - pActionIds := make([]string, len(a.PrevActionIds)-1) - previ := 0 - for _, prevActionId := range a.PrevActionIds { - if prevActionId != prevAction.ActionId { - pActionIds[previ] = prevActionId - previ++ + prevId := -1 + for pId, prevActionId := range a.PrevActionIds { + if prevActionId == prevAction.ActionId { + prevId = pId + break } } - a.PrevActionIds = pActionIds + if prevId > -1{ + a.PrevActionIds = append(a.PrevActionIds[:prevId], a.PrevActionIds[prevId+1:]...) + } - nActionIds := make([]string, len(prevAction.NextActionIds)-1) - nexti := 0 - for _, nextActionId := range prevAction.NextActionIds { - if nextActionId != a.ActionId { - nActionIds[nexti] = nextActionId - nexti++ + nextId := -1 + for nId, nextActionId := range prevAction.NextActionIds { + if nextActionId == a.ActionId { + nextId = nId + break + } + } + //fmt.Println("nextId============>", nextId) + //fmt.Println("before set prevAction.NextActionIds===>", strings.Join(prevAction.NextActionIds,",")) + if nextId>-1 { + prevAction.NextActionIds = append(prevAction.NextActionIds[:nextId], prevAction.NextActionIds[nextId+1:]...) + //fmt.Println("after set prevAction.NextActionIds===>", strings.Join(prevAction.NextActionIds,",")) + if len(prevAction.NextConditions)> nextId { + prevAction.NextConditions = append(prevAction.NextConditions[:nextId], prevAction.NextConditions[nextId+1:]...) } + //fmt.Println("after set prevAction.NextConditions===>", strings.Join(prevAction.NextConditions,",")) } - prevAction.NextActionIds = nActionIds + //fmt.Println("\nfinish detach, prevActionId, actionId:", prevAction.ActionId, a.ActionId) +} + +func (a *Action) toString() string { + return fmt.Sprintf("actionId:%+v, nextActionIds:%+v, nextConditions:%+v, prevActionIds:%+v",a.ActionId, strings.Join(a.NextActionIds,","),strings.Join(a.NextConditions,",")) } func (a *Action) clone() *Action { @@ -306,6 +320,7 @@ func (w *WorkflowChart) clone() *WorkflowChart { chart := &WorkflowChart{} chart.FirstActionId = w.FirstActionId chart.LastActionId = w.LastActionId + chart.HashCondition = w.HashCondition actionMap := make(map[string]*Action) for actionId, action := range w.ActionMap { @@ -329,6 +344,7 @@ func copyStringArray(sources []string) []string { } func (a *Action) executeCond(paramValues *sync.Map) (retActionId string, err error) { + //fmt.Println("\n\n\n开始执行executeCond:",fmt.Sprintf("action:%+v", a)) //若报错,有缺省用缺省,无缺省用最后一个。条件必含后继,配置保存时校验 defaultIndex := len(a.NextActionIds) - 1 for idx, cdt := range a.NextConditions { @@ -336,8 +352,10 @@ func (a *Action) executeCond(paramValues *sync.Map) (retActionId string, err err defaultIndex = idx } } + //fmt.Println("defaultIndex=======>", defaultIndex) retActionId = a.NextActionIds[defaultIndex] + //fmt.Println("retActionId=>", retActionId) err = nil defer func() { if err0 := recover(); err0 != nil { @@ -350,8 +368,9 @@ func (a *Action) executeCond(paramValues *sync.Map) (retActionId string, err err err = fmt.Errorf("createParamSlice error, default value: %v used, a.Params:%v, paramValues:%v, err:%v", a.NextActionIds[defaultIndex], a.Params, paramValues, err) return } - + //fmt.Println("prepare to exe:", a.ActionName, params) val, err := GetCondExecutors().Execute(a.ActionName, params) + //fmt.Println("条件执行结果 result: val====>", val, "err====>", err) if err != nil { err = fmt.Errorf("GetCondExecutors().Execute error, default value: %v used, actionName:%v, params:%v, err:%v", a.NextActionIds[defaultIndex], a.ActionName, params, err) return @@ -389,25 +408,6 @@ func (w *WorkflowChart) newWorkflowBranch() *WorkflowBranch { } } -/*func (w *WorkflowBranch) selectBranchKey(params map[string]interface{}) (string, error) { - if !w.hasBranch() { - return BranchKeyDefault, nil - } - - branchMap := make(map[string]int) - for _, actionId := range w.SortedBranch { - idx, err := w.ActionMap[actionId].executeCond(params) - if err != nil { - return "", fmt.Errorf("execute cond error:%v", err) - } - branchMap[actionId] = idx - } - - branchKey := w.getBranchKey(branchMap) - - return branchKey, nil -}*/ - func (w *WorkflowBranch) getCurrentBranchKey() string { return w.getBranchKey(w.CurrentBranch) } diff --git a/tg-core/wfengine/workflow.json b/wfengine/workflow.json similarity index 100% rename from tg-core/wfengine/workflow.json rename to wfengine/workflow.json