diff --git a/backend/conf/config.yml b/backend/conf/config.yml index 90fa8fe1..e5dcb1f9 100644 --- a/backend/conf/config.yml +++ b/backend/conf/config.yml @@ -46,4 +46,4 @@ notification: senderIdentity: '' smtp: user: '' - password: '' + password: '' \ No newline at end of file diff --git a/backend/main.go b/backend/main.go index a7a07002..4a84462d 100644 --- a/backend/main.go +++ b/backend/main.go @@ -138,79 +138,99 @@ func main() { } authGroup := app.Group("/", middlewares.AuthorizationMiddleware()) { - // 路由 // 节点 - authGroup.GET("/nodes", routes.GetNodeList) // 节点列表 - authGroup.GET("/nodes/:id", routes.GetNode) // 节点详情 - authGroup.POST("/nodes/:id", routes.PostNode) // 修改节点 - authGroup.GET("/nodes/:id/tasks", routes.GetNodeTaskList) // 节点任务列表 - authGroup.GET("/nodes/:id/system", routes.GetSystemInfo) // 节点任务列表 - authGroup.DELETE("/nodes/:id", routes.DeleteNode) // 删除节点 - authGroup.GET("/nodes/:id/langs", routes.GetLangList) // 节点语言环境列表 - authGroup.GET("/nodes/:id/deps", routes.GetDepList) // 节点第三方依赖列表 - authGroup.GET("/nodes/:id/deps/installed", routes.GetInstalledDepList) // 节点已安装第三方依赖列表 - authGroup.POST("/nodes/:id/deps/install", routes.InstallDep) // 节点安装依赖 - authGroup.POST("/nodes/:id/deps/uninstall", routes.UninstallDep) // 节点卸载依赖 - authGroup.POST("/nodes/:id/langs/install", routes.InstallLang) // 节点安装语言 + { + authGroup.GET("/nodes", routes.GetNodeList) // 节点列表 + authGroup.GET("/nodes/:id", routes.GetNode) // 节点详情 + authGroup.POST("/nodes/:id", routes.PostNode) // 修改节点 + authGroup.GET("/nodes/:id/tasks", routes.GetNodeTaskList) // 节点任务列表 + authGroup.GET("/nodes/:id/system", routes.GetSystemInfo) // 节点任务列表 + authGroup.DELETE("/nodes/:id", routes.DeleteNode) // 删除节点 + authGroup.GET("/nodes/:id/langs", routes.GetLangList) // 节点语言环境列表 + authGroup.GET("/nodes/:id/deps", routes.GetDepList) // 节点第三方依赖列表 + authGroup.GET("/nodes/:id/deps/installed", routes.GetInstalledDepList) // 节点已安装第三方依赖列表 + authGroup.POST("/nodes/:id/deps/install", routes.InstallDep) // 节点安装依赖 + authGroup.POST("/nodes/:id/deps/uninstall", routes.UninstallDep) // 节点卸载依赖 + authGroup.POST("/nodes/:id/langs/install", routes.InstallLang) // 节点安装语言 + } // 爬虫 - authGroup.GET("/spiders", routes.GetSpiderList) // 爬虫列表 - authGroup.GET("/spiders/:id", routes.GetSpider) // 爬虫详情 - authGroup.PUT("/spiders", routes.PutSpider) // 添加爬虫 - authGroup.POST("/spiders", routes.UploadSpider) // 上传爬虫 - authGroup.POST("/spiders/:id", routes.PostSpider) // 修改爬虫 - authGroup.POST("/spiders/:id/publish", routes.PublishSpider) // 发布爬虫 - authGroup.POST("/spiders/:id/upload", routes.UploadSpiderFromId) // 上传爬虫(ID) - authGroup.DELETE("/spiders/:id", routes.DeleteSpider) // 删除爬虫 - authGroup.GET("/spiders/:id/tasks", routes.GetSpiderTasks) // 爬虫任务列表 - authGroup.GET("/spiders/:id/file/tree", routes.GetSpiderFileTree) // 爬虫文件目录树读取 - authGroup.GET("/spiders/:id/file", routes.GetSpiderFile) // 爬虫文件读取 - authGroup.POST("/spiders/:id/file", routes.PostSpiderFile) // 爬虫文件更改 - authGroup.PUT("/spiders/:id/file", routes.PutSpiderFile) // 爬虫文件创建 - authGroup.PUT("/spiders/:id/dir", routes.PutSpiderDir) // 爬虫目录创建 - authGroup.DELETE("/spiders/:id/file", routes.DeleteSpiderFile) // 爬虫文件删除 - authGroup.POST("/spiders/:id/file/rename", routes.RenameSpiderFile) // 爬虫文件重命名 - authGroup.GET("/spiders/:id/dir", routes.GetSpiderDir) // 爬虫目录 - authGroup.GET("/spiders/:id/stats", routes.GetSpiderStats) // 爬虫统计数据 - authGroup.GET("/spiders/:id/schedules", routes.GetSpiderSchedules) // 爬虫定时任务 + { + authGroup.GET("/spiders", routes.GetSpiderList) // 爬虫列表 + authGroup.GET("/spiders/:id", routes.GetSpider) // 爬虫详情 + authGroup.PUT("/spiders", routes.PutSpider) // 添加爬虫 + authGroup.POST("/spiders", routes.UploadSpider) // 上传爬虫 + authGroup.POST("/spiders/:id", routes.PostSpider) // 修改爬虫 + authGroup.POST("/spiders/:id/publish", routes.PublishSpider) // 发布爬虫 + authGroup.POST("/spiders/:id/upload", routes.UploadSpiderFromId) // 上传爬虫(ID) + authGroup.DELETE("/spiders/:id", routes.DeleteSpider) // 删除爬虫 + authGroup.GET("/spiders/:id/tasks", routes.GetSpiderTasks) // 爬虫任务列表 + authGroup.GET("/spiders/:id/file/tree", routes.GetSpiderFileTree) // 爬虫文件目录树读取 + authGroup.GET("/spiders/:id/file", routes.GetSpiderFile) // 爬虫文件读取 + authGroup.POST("/spiders/:id/file", routes.PostSpiderFile) // 爬虫文件更改 + authGroup.PUT("/spiders/:id/file", routes.PutSpiderFile) // 爬虫文件创建 + authGroup.PUT("/spiders/:id/dir", routes.PutSpiderDir) // 爬虫目录创建 + authGroup.DELETE("/spiders/:id/file", routes.DeleteSpiderFile) // 爬虫文件删除 + authGroup.POST("/spiders/:id/file/rename", routes.RenameSpiderFile) // 爬虫文件重命名 + authGroup.GET("/spiders/:id/dir", routes.GetSpiderDir) // 爬虫目录 + authGroup.GET("/spiders/:id/stats", routes.GetSpiderStats) // 爬虫统计数据 + authGroup.GET("/spiders/:id/schedules", routes.GetSpiderSchedules) // 爬虫定时任务 + } // 可配置爬虫 - authGroup.GET("/config_spiders/:id/config", routes.GetConfigSpiderConfig) // 获取可配置爬虫配置 - authGroup.POST("/config_spiders/:id/config", routes.PostConfigSpiderConfig) // 更改可配置爬虫配置 - authGroup.PUT("/config_spiders", routes.PutConfigSpider) // 添加可配置爬虫 - authGroup.POST("/config_spiders/:id", routes.PostConfigSpider) // 修改可配置爬虫 - authGroup.POST("/config_spiders/:id/upload", routes.UploadConfigSpider) // 上传可配置爬虫 - authGroup.POST("/config_spiders/:id/spiderfile", routes.PostConfigSpiderSpiderfile) // 上传可配置爬虫 - authGroup.GET("/config_spiders_templates", routes.GetConfigSpiderTemplateList) // 获取可配置爬虫模版列表 + { + authGroup.GET("/config_spiders/:id/config", routes.GetConfigSpiderConfig) // 获取可配置爬虫配置 + authGroup.POST("/config_spiders/:id/config", routes.PostConfigSpiderConfig) // 更改可配置爬虫配置 + authGroup.PUT("/config_spiders", routes.PutConfigSpider) // 添加可配置爬虫 + authGroup.POST("/config_spiders/:id", routes.PostConfigSpider) // 修改可配置爬虫 + authGroup.POST("/config_spiders/:id/upload", routes.UploadConfigSpider) // 上传可配置爬虫 + authGroup.POST("/config_spiders/:id/spiderfile", routes.PostConfigSpiderSpiderfile) // 上传可配置爬虫 + authGroup.GET("/config_spiders_templates", routes.GetConfigSpiderTemplateList) // 获取可配置爬虫模版列表 + } // 任务 - authGroup.GET("/tasks", routes.GetTaskList) // 任务列表 - authGroup.GET("/tasks/:id", routes.GetTask) // 任务详情 - authGroup.PUT("/tasks", routes.PutTask) // 派发任务 - authGroup.DELETE("/tasks/:id", routes.DeleteTask) // 删除任务 - authGroup.DELETE("/tasks_multiple", routes.DeleteMultipleTask) // 删除多个任务 - authGroup.DELETE("/tasks_by_status", routes.DeleteTaskByStatus) //删除指定状态的任务 - authGroup.POST("/tasks/:id/cancel", routes.CancelTask) // 取消任务 - authGroup.GET("/tasks/:id/log", routes.GetTaskLog) // 任务日志 - authGroup.GET("/tasks/:id/results", routes.GetTaskResults) // 任务结果 - authGroup.GET("/tasks/:id/results/download", routes.DownloadTaskResultsCsv) // 下载任务结果 + { + authGroup.GET("/tasks", routes.GetTaskList) // 任务列表 + authGroup.GET("/tasks/:id", routes.GetTask) // 任务详情 + authGroup.PUT("/tasks", routes.PutTask) // 派发任务 + authGroup.DELETE("/tasks/:id", routes.DeleteTask) // 删除任务 + authGroup.DELETE("/tasks_multiple", routes.DeleteMultipleTask) // 删除多个任务 + authGroup.DELETE("/tasks_by_status", routes.DeleteTaskByStatus) //删除指定状态的任务 + authGroup.POST("/tasks/:id/cancel", routes.CancelTask) // 取消任务 + authGroup.GET("/tasks/:id/log", routes.GetTaskLog) // 任务日志 + authGroup.GET("/tasks/:id/results", routes.GetTaskResults) // 任务结果 + authGroup.GET("/tasks/:id/results/download", routes.DownloadTaskResultsCsv) // 下载任务结果 + } // 定时任务 - authGroup.GET("/schedules", routes.GetScheduleList) // 定时任务列表 - authGroup.GET("/schedules/:id", routes.GetSchedule) // 定时任务详情 - authGroup.PUT("/schedules", routes.PutSchedule) // 创建定时任务 - authGroup.POST("/schedules/:id", routes.PostSchedule) // 修改定时任务 - authGroup.DELETE("/schedules/:id", routes.DeleteSchedule) // 删除定时任务 - authGroup.POST("/schedules/:id/disable", routes.DisableSchedule) // 禁用定时任务 - authGroup.POST("/schedules/:id/enable", routes.EnableSchedule) // 启用定时任务 + { + authGroup.GET("/schedules", routes.GetScheduleList) // 定时任务列表 + authGroup.GET("/schedules/:id", routes.GetSchedule) // 定时任务详情 + authGroup.PUT("/schedules", routes.PutSchedule) // 创建定时任务 + authGroup.POST("/schedules/:id", routes.PostSchedule) // 修改定时任务 + authGroup.DELETE("/schedules/:id", routes.DeleteSchedule) // 删除定时任务 + authGroup.POST("/schedules/:id/disable", routes.DisableSchedule) // 禁用定时任务 + authGroup.POST("/schedules/:id/enable", routes.EnableSchedule) // 启用定时任务 + } + // 用户 + { + authGroup.GET("/users", routes.GetUserList) // 用户列表 + authGroup.GET("/users/:id", routes.GetUser) // 用户详情 + authGroup.POST("/users/:id", routes.PostUser) // 更改用户 + authGroup.DELETE("/users/:id", routes.DeleteUser) // 删除用户 + authGroup.GET("/me", routes.GetMe) // 获取自己账户 + authGroup.POST("/me", routes.PostMe) // 修改自己账户 + } + // 系统 + { + authGroup.GET("/system/deps/:lang", routes.GetAllDepList) // 节点所有第三方依赖列表 + authGroup.GET("/system/deps/:lang/:dep_name/json", routes.GetDepJson) // 节点第三方依赖JSON + } + // 全局变量 + { + authGroup.POST("/variable", routes.PostVariable) // 新增 + authGroup.PUT("/variable/:id", routes.PutVariable) //修改 + authGroup.DELETE("/variable/:id", routes.DeleteVariable) //删除 + authGroup.GET("/variables", routes.GetVariableList) // 列表 + } // 统计数据 authGroup.GET("/stats/home", routes.GetHomeStats) // 首页统计数据 - // 用户 - authGroup.GET("/users", routes.GetUserList) // 用户列表 - authGroup.GET("/users/:id", routes.GetUser) // 用户详情 - authGroup.POST("/users/:id", routes.PostUser) // 更改用户 - authGroup.DELETE("/users/:id", routes.DeleteUser) // 删除用户 - authGroup.GET("/me", routes.GetMe) // 获取自己账户 - authGroup.POST("/me", routes.PostMe) // 修改自己账户 - // 系统 - authGroup.GET("/system/deps/:lang", routes.GetAllDepList) // 节点所有第三方依赖列表 - authGroup.GET("/system/deps/:lang/:dep_name/json", routes.GetDepJson) // 节点第三方依赖JSON // 文件 authGroup.GET("/file", routes.GetFile) // 获取文件 } diff --git a/backend/model/variable.go b/backend/model/variable.go new file mode 100644 index 00000000..3af2188e --- /dev/null +++ b/backend/model/variable.go @@ -0,0 +1,97 @@ +package model + +import ( + "crawlab/database" + "errors" + "github.com/apex/log" + "github.com/globalsign/mgo/bson" + "runtime/debug" +) + +/** +全局变量 +*/ + +type Variable struct { + Id bson.ObjectId `json:"_id" bson:"_id"` + Key string `json:"key" bson:"key"` + Value string `json:"value" bson:"value"` + Remark string `json:"remark" bson:"remark"` +} + +func (model *Variable) Save() error { + s, c := database.GetCol("variable") + defer s.Close() + + if err := c.UpdateId(model.Id, model); err != nil { + log.Errorf("update variable error: %s", err.Error()) + return err + } + return nil +} + +func (model *Variable) Add() error { + s, c := database.GetCol("variable") + defer s.Close() + + // key 去重 + _, err := GetByKey(model.Key) + if err == nil { + return errors.New("key already exists") + } + + model.Id = bson.NewObjectId() + if err := c.Insert(model); err != nil { + log.Errorf("add variable error: %s", err.Error()) + debug.PrintStack() + return err + } + return nil +} + +func (model *Variable) Delete() error { + s, c := database.GetCol("variable") + defer s.Close() + + if err := c.RemoveId(model.Id); err != nil { + log.Errorf("remove variable error: %s", err.Error()) + debug.PrintStack() + return err + } + return nil +} + +func GetByKey(key string) (Variable, error) { + s, c := database.GetCol("variable") + defer s.Close() + + var model Variable + if err := c.Find(bson.M{"key": key}).One(&model); err != nil { + log.Errorf("variable found error: %s, key: %s", err.Error(), key) + return model, err + } + return model, nil +} + +func GetVariable(id bson.ObjectId) (Variable, error) { + s, c := database.GetCol("variable") + defer s.Close() + + var model Variable + if err := c.FindId(id).One(&model); err != nil { + log.Errorf("variable found error: %s", err.Error()) + return model, err + } + return model, nil +} + +func GetVariableList() []Variable { + s, c := database.GetCol("variable") + defer s.Close() + + var list []Variable + if err := c.Find(nil).All(&list); err != nil { + + } + return list +} diff --git a/backend/routes/variable.go b/backend/routes/variable.go new file mode 100644 index 00000000..56f51ed7 --- /dev/null +++ b/backend/routes/variable.go @@ -0,0 +1,62 @@ +package routes + +import ( + "crawlab/model" + "github.com/gin-gonic/gin" + "github.com/globalsign/mgo/bson" + "net/http" +) + +// 新增 +func PostVariable(c *gin.Context) { + var variable model.Variable + if err := c.ShouldBindJSON(&variable); err != nil { + HandleError(http.StatusBadRequest, c, err) + return + } + if err := variable.Add(); err != nil { + HandleError(http.StatusInternalServerError, c, err) + return + } + HandleSuccess(c) +} + +// 修改 +func PutVariable(c *gin.Context) { + var id = c.Param("id") + var variable model.Variable + if err := c.ShouldBindJSON(&variable); err != nil { + HandleError(http.StatusBadRequest, c, err) + return + } + variable.Id = bson.ObjectIdHex(id) + if err := variable.Save(); err != nil { + HandleError(http.StatusInternalServerError, c, err) + return + } + HandleSuccess(c) +} + +// 删除 +func DeleteVariable(c *gin.Context) { + var idStr = c.Param("id") + var id = bson.ObjectIdHex(idStr) + variable, err := model.GetVariable(id) + if err != nil { + HandleError(http.StatusInternalServerError, c, err) + return + } + variable.Id = id + if err := variable.Delete(); err != nil { + HandleError(http.StatusInternalServerError, c, err) + return + } + HandleSuccess(c) + +} + +// 列表 +func GetVariableList(c *gin.Context) { + list := model.GetVariableList() + HandleSuccessData(c, list) +} diff --git a/backend/services/schedule.go b/backend/services/schedule.go index b5268a88..a179b50f 100644 --- a/backend/services/schedule.go +++ b/backend/services/schedule.go @@ -200,6 +200,12 @@ func (s *Scheduler) Update() error { return err } + user, err := model.GetUserByUsername("admin") + if err != nil { + log.Errorf("get admin user error: %s", err.Error()) + return err + } + // 遍历任务列表 for i := 0; i < len(sList); i++ { // 单个任务 @@ -209,6 +215,11 @@ func (s *Scheduler) Update() error { continue } + // 兼容以前版本 + if job.UserId.Hex() == "" { + job.UserId = user.Id + } + // 添加到定时任务 if err := s.AddJob(job); err != nil { log.Errorf("add job error: %s, job: %s, cron: %s", err.Error(), job.Name, job.Cron) diff --git a/backend/services/spider.go b/backend/services/spider.go index e97c7992..fe162f12 100644 --- a/backend/services/spider.go +++ b/backend/services/spider.go @@ -12,12 +12,11 @@ import ( "github.com/apex/log" "github.com/globalsign/mgo" "github.com/globalsign/mgo/bson" - uuid "github.com/satori/go.uuid" + "github.com/satori/go.uuid" "github.com/spf13/viper" "os" "path/filepath" "runtime/debug" - "strings" ) type SpiderFileData struct { @@ -192,21 +191,14 @@ func PublishSpider(spider model.Spider) { md5 := filepath.Join(path, spider_handler.Md5File) if !utils.Exists(md5) { log.Infof("md5 file not found: %s", md5) - spiderSync.RemoveSpiderFile() - spiderSync.Download() - spiderSync.CreateMd5File(gfFile.Md5) + spiderSync.RemoveDownCreate(gfFile.Md5) return } // md5值不一样,则下载 - md5Str := utils.ReadFileOneLine(md5) - // 去掉空格以及换行符 - md5Str = strings.Replace(md5Str, " ", "", -1) - md5Str = strings.Replace(md5Str, "\n", "", -1) + md5Str := utils.GetSpiderMd5Str(md5) if gfFile.Md5 != md5Str { log.Infof("md5 is different, gf-md5:%s, file-md5:%s", gfFile.Md5, md5Str) - spiderSync.RemoveSpiderFile() - spiderSync.Download() - spiderSync.CreateMd5File(gfFile.Md5) + spiderSync.RemoveDownCreate(gfFile.Md5) return } } diff --git a/backend/services/spider_handler/spider.go b/backend/services/spider_handler/spider.go index c3a2500d..cd8a1dbe 100644 --- a/backend/services/spider_handler/spider.go +++ b/backend/services/spider_handler/spider.go @@ -38,6 +38,12 @@ func (s *SpiderSync) CreateMd5File(md5 string) { } } +func (s *SpiderSync) RemoveDownCreate(md5 string) { + s.RemoveSpiderFile() + s.Download() + s.CreateMd5File(md5) +} + // 获得下载锁的key func (s *SpiderSync) GetLockDownloadKey(spiderId string) string { node, _ := model.GetCurrentNode() diff --git a/backend/services/task.go b/backend/services/task.go index da4eabc8..15513977 100644 --- a/backend/services/task.go +++ b/backend/services/task.go @@ -7,6 +7,7 @@ import ( "crawlab/lib/cron" "crawlab/model" "crawlab/services/notification" + "crawlab/services/spider_handler" "crawlab/utils" "encoding/json" "errors" @@ -144,7 +145,11 @@ func SetEnv(cmd *exec.Cmd, envs []model.Env, taskId string, dataCol string) *exe cmd.Env = append(cmd.Env, env.Name+"="+env.Value) } - // TODO 全局环境变量 + // 全局环境变量 + variables := model.GetVariableList() + for _, variable := range variables { + cmd.Env = append(cmd.Env, variable.Key+"="+variable.Value) + } return cmd } @@ -446,15 +451,9 @@ func ExecuteTask(id int) { t.Status = constants.StatusRunning // 任务状态 t.WaitDuration = t.StartTs.Sub(t.CreateTs).Seconds() // 等待时长 - // 判断爬虫文件是否存在 - gfFile := model.GetGridFs(spider.FileId) - if gfFile == nil { - t.Error = "找不到爬虫文件,请重新上传" - t.Status = constants.StatusError - t.FinishTs = time.Now() // 结束时间 - t.RuntimeDuration = t.FinishTs.Sub(t.StartTs).Seconds() // 运行时长 - t.TotalDuration = t.FinishTs.Sub(t.CreateTs).Seconds() // 总时长 - _ = t.Save() + // 文件检查 + if err := SpiderFileCheck(t, spider); err != nil { + log.Errorf("spider file check error: %s", err.Error()) return } @@ -534,6 +533,30 @@ func ExecuteTask(id int) { log.Infof(GetWorkerPrefix(id) + "任务(ID:" + t.Id + ")" + "执行完毕. 消耗时间:" + durationStr + "秒") } +func SpiderFileCheck(t model.Task, spider model.Spider) error { + // 判断爬虫文件是否存在 + gfFile := model.GetGridFs(spider.FileId) + if gfFile == nil { + t.Error = "找不到爬虫文件,请重新上传" + t.Status = constants.StatusError + t.FinishTs = time.Now() // 结束时间 + t.RuntimeDuration = t.FinishTs.Sub(t.StartTs).Seconds() // 运行时长 + t.TotalDuration = t.FinishTs.Sub(t.CreateTs).Seconds() // 总时长 + _ = t.Save() + return errors.New(t.Error) + } + + // 判断md5值是否一致 + path := filepath.Join(viper.GetString("spider.path"), spider.Name) + md5File := filepath.Join(path, spider_handler.Md5File) + md5 := utils.GetSpiderMd5Str(md5File) + if gfFile.Md5 != md5 { + spiderSync := spider_handler.SpiderSync{Spider: spider} + spiderSync.RemoveDownCreate(gfFile.Md5) + } + return nil +} + func GetTaskLog(id string) (logStr string, err error) { task, err := model.GetTask(id) @@ -676,19 +699,6 @@ func AddTask(t model.Task) error { return nil } -func HandleTaskError(t model.Task, err error) { - log.Error("handle task error:" + err.Error()) - t.Status = constants.StatusError - t.Error = err.Error() - t.FinishTs = time.Now() - if err := t.Save(); err != nil { - log.Errorf(err.Error()) - debug.PrintStack() - return - } - debug.PrintStack() -} - func GetTaskEmailMarkdownContent(t model.Task, s model.Spider) string { n, _ := model.GetNode(t.NodeId) errMsg := "" diff --git a/backend/utils/file.go b/backend/utils/file.go index c71b2cb0..bfe92bd3 100644 --- a/backend/utils/file.go +++ b/backend/utils/file.go @@ -33,7 +33,14 @@ func ReadFileOneLine(fileName string) string { return "" } return line +} +func GetSpiderMd5Str(file string) string { + md5Str := ReadFileOneLine(file) + // 去掉空格以及换行符 + md5Str = strings.Replace(md5Str, " ", "", -1) + md5Str = strings.Replace(md5Str, "\n", "", -1) + return md5Str } // 创建文件 diff --git a/frontend/.env.development b/frontend/.env.development index 73ca1a55..ba21c0c6 100644 --- a/frontend/.env.development +++ b/frontend/.env.development @@ -1,3 +1,3 @@ NODE_ENV='development' VUE_APP_BASE_URL=http://localhost:8000 -VUE_APP_CRAWLAB_BASE_URL=https://api.crawlab.cn +VUE_APP_CRAWLAB_BASE_URL=https://api.crawlab.cn \ No newline at end of file diff --git a/frontend/src/i18n/zh.js b/frontend/src/i18n/zh.js index 82b52d27..254d3dcd 100644 --- a/frontend/src/i18n/zh.js +++ b/frontend/src/i18n/zh.js @@ -365,6 +365,11 @@ export default { 'Never': '从不', 'DingTalk Robot Webhook': '钉钉机器人 Webhook', 'Wechat Robot Webhook': '微信机器人 Webhook', + 'Password Settings': '密码设置', + 'Notify Settings': '通知设置', + 'Global Variable': '全局变量', + 'Add Global Variable': '新增全局变量', + 'Are you sure to delete this global variable': '确定删除该全局变量?', // 其他 tagsView: { diff --git a/frontend/src/store/modules/user.js b/frontend/src/store/modules/user.js index af778816..3324ba15 100644 --- a/frontend/src/store/modules/user.js +++ b/frontend/src/store/modules/user.js @@ -9,6 +9,8 @@ const user = { avatar: '', roles: [], userList: [], + globalVariableList: [], + globalVariableForm: {}, userForm: {}, userInfo: undefined, adminPaths: [ @@ -61,6 +63,9 @@ const user = { }, SET_TOTAL_COUNT: (state, value) => { state.totalCount = value + }, + SET_GLOBAL_VARIABLE_LIST: (state, value) => { + state.globalVariableList = value } }, @@ -148,6 +153,23 @@ const user = { // 添加用户 addUser ({ dispatch, commit, state }) { return request.put('/users', state.userForm) + }, + // 新增全局变量 + addGlobalVariable ({ commit, state }) { + return request.post(`/variable`, state.globalVariableForm) + .then(() => { + state.globalVariableForm = {} + }) + }, + // 获取全局变量列表 + getGlobalVariable ({ commit, state }) { + request.get('/variables').then((response) => { + commit('SET_GLOBAL_VARIABLE_LIST', response.data.data) + }) + }, + // 删除全局变量 + deleteGlobalVariable ({ commit, state }, id) { + return request.delete(`/variable/${id}`) } } } diff --git a/frontend/src/views/setting/Setting.vue b/frontend/src/views/setting/Setting.vue index e82d47b6..0eade556 100644 --- a/frontend/src/views/setting/Setting.vue +++ b/frontend/src/views/setting/Setting.vue @@ -1,47 +1,98 @@