mirror of
https://github.com/crawlab-team/crawlab.git
synced 2026-01-26 17:49:15 +01:00
加入权限管理
This commit is contained in:
7
backend/constants/auth.go
Normal file
7
backend/constants/auth.go
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
package constants
|
||||||
|
|
||||||
|
const (
|
||||||
|
OwnerTypeAll = "all"
|
||||||
|
OwnerTypeMe = "me"
|
||||||
|
OwnerTypePublic = "public"
|
||||||
|
)
|
||||||
@@ -100,6 +100,14 @@ func main() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
log.Info("initialized challenge service successfully")
|
log.Info("initialized challenge service successfully")
|
||||||
|
|
||||||
|
// 初始化清理服务
|
||||||
|
if err := services.InitCleanService(); err != nil {
|
||||||
|
log.Error("init clean service error:" + err.Error())
|
||||||
|
debug.PrintStack()
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
log.Info("initialized clean service successfully")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化任务执行器
|
// 初始化任务执行器
|
||||||
|
|||||||
@@ -16,11 +16,12 @@ type Project struct {
|
|||||||
Tags []string `json:"tags" bson:"tags"`
|
Tags []string `json:"tags" bson:"tags"`
|
||||||
|
|
||||||
// 前端展示
|
// 前端展示
|
||||||
Spiders []Spider `json:"spiders" bson:"spiders"`
|
Spiders []Spider `json:"spiders" bson:"spiders"`
|
||||||
|
Username string `json:"username" bson:"username"`
|
||||||
|
|
||||||
UserId bson.ObjectId `json:"user_id" bson:"user_id"`
|
UserId bson.ObjectId `json:"user_id" bson:"user_id"`
|
||||||
CreateTs time.Time `json:"create_ts" bson:"create_ts"`
|
CreateTs time.Time `json:"create_ts" bson:"create_ts"`
|
||||||
UpdateTs time.Time `json:"update_ts" bson:"update_ts"`
|
UpdateTs time.Time `json:"update_ts" bson:"update_ts"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Project) Save() error {
|
func (p *Project) Save() error {
|
||||||
@@ -90,15 +91,21 @@ func GetProject(id bson.ObjectId) (Project, error) {
|
|||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetProjectList(filter interface{}, skip int, sortKey string) ([]Project, error) {
|
func GetProjectList(filter interface{}, sortKey string) ([]Project, error) {
|
||||||
s, c := database.GetCol("projects")
|
s, c := database.GetCol("projects")
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
var projects []Project
|
var projects []Project
|
||||||
if err := c.Find(filter).Skip(skip).Limit(constants.Infinite).Sort(sortKey).All(&projects); err != nil {
|
if err := c.Find(filter).Sort(sortKey).All(&projects); err != nil {
|
||||||
debug.PrintStack()
|
debug.PrintStack()
|
||||||
return projects, err
|
return projects, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for i, p := range projects {
|
||||||
|
// 获取用户名称
|
||||||
|
user, _ := GetUser(p.UserId)
|
||||||
|
projects[i].Username = user.Username
|
||||||
|
}
|
||||||
return projects, nil
|
return projects, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ type Schedule struct {
|
|||||||
|
|
||||||
// 前端展示
|
// 前端展示
|
||||||
SpiderName string `json:"spider_name" bson:"spider_name"`
|
SpiderName string `json:"spider_name" bson:"spider_name"`
|
||||||
|
Username string `json:"user_name" bson:"user_name"`
|
||||||
Nodes []Node `json:"nodes" bson:"nodes"`
|
Nodes []Node `json:"nodes" bson:"nodes"`
|
||||||
Message string `json:"message" bson:"message"`
|
Message string `json:"message" bson:"message"`
|
||||||
|
|
||||||
@@ -83,6 +84,10 @@ func GetScheduleList(filter interface{}) ([]Schedule, error) {
|
|||||||
schedule.SpiderName = spider.Name
|
schedule.SpiderName = spider.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取用户名称
|
||||||
|
user, _ := GetUser(schedule.UserId)
|
||||||
|
schedule.Username = user.Username
|
||||||
|
|
||||||
schs = append(schs, schedule)
|
schs = append(schs, schedule)
|
||||||
}
|
}
|
||||||
return schs, nil
|
return schs, nil
|
||||||
@@ -92,11 +97,16 @@ func GetSchedule(id bson.ObjectId) (Schedule, error) {
|
|||||||
s, c := database.GetCol("schedules")
|
s, c := database.GetCol("schedules")
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
var result Schedule
|
var schedule Schedule
|
||||||
if err := c.FindId(id).One(&result); err != nil {
|
if err := c.FindId(id).One(&schedule); err != nil {
|
||||||
return result, err
|
return schedule, err
|
||||||
}
|
}
|
||||||
return result, nil
|
|
||||||
|
// 获取用户名称
|
||||||
|
user, _ := GetUser(schedule.UserId)
|
||||||
|
schedule.Username = user.Username
|
||||||
|
|
||||||
|
return schedule, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateSchedule(id bson.ObjectId, item Schedule) error {
|
func UpdateSchedule(id bson.ObjectId, item Schedule) error {
|
||||||
@@ -147,11 +157,11 @@ func RemoveSchedule(id bson.ObjectId) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetScheduleCount() (int, error) {
|
func GetScheduleCount(filter interface{}) (int, error) {
|
||||||
s, c := database.GetCol("schedules")
|
s, c := database.GetCol("schedules")
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
count, err := c.Count()
|
count, err := c.Find(filter).Count()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ type Spider struct {
|
|||||||
Remark string `json:"remark" bson:"remark"` // 备注
|
Remark string `json:"remark" bson:"remark"` // 备注
|
||||||
Src string `json:"src" bson:"src"` // 源码位置
|
Src string `json:"src" bson:"src"` // 源码位置
|
||||||
ProjectId bson.ObjectId `json:"project_id" bson:"project_id"` // 项目ID
|
ProjectId bson.ObjectId `json:"project_id" bson:"project_id"` // 项目ID
|
||||||
|
IsPublic bool `json:"is_public" bson:"is_public"` // 是否公开
|
||||||
|
|
||||||
// 自定义爬虫
|
// 自定义爬虫
|
||||||
Cmd string `json:"cmd" bson:"cmd"` // 执行命令
|
Cmd string `json:"cmd" bson:"cmd"` // 执行命令
|
||||||
@@ -63,6 +64,7 @@ type Spider struct {
|
|||||||
LastStatus string `json:"last_status"` // 最后执行状态
|
LastStatus string `json:"last_status"` // 最后执行状态
|
||||||
Config entity.ConfigSpiderData `json:"config"` // 可配置爬虫配置
|
Config entity.ConfigSpiderData `json:"config"` // 可配置爬虫配置
|
||||||
LatestTasks []Task `json:"latest_tasks"` // 最近任务列表
|
LatestTasks []Task `json:"latest_tasks"` // 最近任务列表
|
||||||
|
Username string `json:"username""`
|
||||||
|
|
||||||
// 时间
|
// 时间
|
||||||
UserId bson.ObjectId `json:"user_id" bson:"user_id"`
|
UserId bson.ObjectId `json:"user_id" bson:"user_id"`
|
||||||
@@ -83,6 +85,7 @@ func (spider *Spider) Save() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := c.UpdateId(spider.Id, spider); err != nil {
|
if err := c.UpdateId(spider.Id, spider); err != nil {
|
||||||
|
log.Errorf(err.Error())
|
||||||
debug.PrintStack()
|
debug.PrintStack()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -182,10 +185,22 @@ func GetSpiderList(filter interface{}, skip int, limit int, sortStr string) ([]S
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取用户
|
||||||
|
var user User
|
||||||
|
if spider.UserId.Valid() {
|
||||||
|
user, err = GetUser(spider.UserId)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf(err.Error())
|
||||||
|
debug.PrintStack()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 赋值
|
// 赋值
|
||||||
spiders[i].LastRunTs = task.CreateTs
|
spiders[i].LastRunTs = task.CreateTs
|
||||||
spiders[i].LastStatus = task.Status
|
spiders[i].LastStatus = task.Status
|
||||||
spiders[i].LatestTasks = latestTasks
|
spiders[i].LatestTasks = latestTasks
|
||||||
|
spiders[i].Username = user.Username
|
||||||
}
|
}
|
||||||
|
|
||||||
count, _ := c.Find(filter).Count()
|
count, _ := c.Find(filter).Count()
|
||||||
@@ -221,13 +236,21 @@ func GetSpiderByName(name string) Spider {
|
|||||||
s, c := database.GetCol("spiders")
|
s, c := database.GetCol("spiders")
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
var result Spider
|
var spider Spider
|
||||||
if err := c.Find(bson.M{"name": name}).One(&result); err != nil && err != mgo.ErrNotFound {
|
if err := c.Find(bson.M{"name": name}).One(&spider); err != nil && err != mgo.ErrNotFound {
|
||||||
log.Errorf("get spider error: %s, spider_name: %s", err.Error(), name)
|
log.Errorf("get spider error: %s, spider_name: %s", err.Error(), name)
|
||||||
//debug.PrintStack()
|
//debug.PrintStack()
|
||||||
return result
|
return spider
|
||||||
}
|
}
|
||||||
return result
|
|
||||||
|
// 获取用户
|
||||||
|
var user User
|
||||||
|
if spider.UserId.Valid() {
|
||||||
|
user, _ = GetUser(spider.UserId)
|
||||||
|
}
|
||||||
|
spider.Username = user.Username
|
||||||
|
|
||||||
|
return spider
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取爬虫(根据ID)
|
// 获取爬虫(根据ID)
|
||||||
@@ -253,6 +276,14 @@ func GetSpider(id bson.ObjectId) (Spider, error) {
|
|||||||
}
|
}
|
||||||
spider.Config = config
|
spider.Config = config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取用户名称
|
||||||
|
var user User
|
||||||
|
if spider.UserId.Valid() {
|
||||||
|
user, _ = GetUser(spider.UserId)
|
||||||
|
}
|
||||||
|
spider.Username = user.Username
|
||||||
|
|
||||||
return spider, nil
|
return spider, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,11 +355,11 @@ func RemoveAllSpider() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取爬虫总数
|
// 获取爬虫总数
|
||||||
func GetSpiderCount() (int, error) {
|
func GetSpiderCount(filter interface{}) (int, error) {
|
||||||
s, c := database.GetCol("spiders")
|
s, c := database.GetCol("spiders")
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
count, err := c.Count()
|
count, err := c.Find(filter).Count()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ type Task struct {
|
|||||||
// 前端数据
|
// 前端数据
|
||||||
SpiderName string `json:"spider_name"`
|
SpiderName string `json:"spider_name"`
|
||||||
NodeName string `json:"node_name"`
|
NodeName string `json:"node_name"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
|
||||||
UserId bson.ObjectId `json:"user_id" bson:"user_id"`
|
UserId bson.ObjectId `json:"user_id" bson:"user_id"`
|
||||||
CreateTs time.Time `json:"create_ts" bson:"create_ts"`
|
CreateTs time.Time `json:"create_ts" bson:"create_ts"`
|
||||||
@@ -128,6 +129,10 @@ func GetTaskList(filter interface{}, skip int, limit int, sortKey string) ([]Tas
|
|||||||
if node, err := task.GetNode(); err == nil {
|
if node, err := task.GetNode(); err == nil {
|
||||||
tasks[i].NodeName = node.Name
|
tasks[i].NodeName = node.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取用户名称
|
||||||
|
user, _ := GetUser(task.UserId)
|
||||||
|
task.Username = user.Username
|
||||||
}
|
}
|
||||||
return tasks, nil
|
return tasks, nil
|
||||||
}
|
}
|
||||||
@@ -156,6 +161,11 @@ func GetTask(id string) (Task, error) {
|
|||||||
debug.PrintStack()
|
debug.PrintStack()
|
||||||
return task, err
|
return task, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取用户名称
|
||||||
|
user, _ := GetUser(task.UserId)
|
||||||
|
task.Username = user.Username
|
||||||
|
|
||||||
return task, nil
|
return task, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"crawlab/constants"
|
"crawlab/constants"
|
||||||
"crawlab/database"
|
"crawlab/database"
|
||||||
"crawlab/model"
|
"crawlab/model"
|
||||||
|
"crawlab/services"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/globalsign/mgo/bson"
|
"github.com/globalsign/mgo/bson"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -18,8 +19,11 @@ func GetProjectList(c *gin.Context) {
|
|||||||
query["tags"] = tag
|
query["tags"] = tag
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取校验
|
||||||
|
query = services.GetAuthQuery(query, c)
|
||||||
|
|
||||||
// 获取列表
|
// 获取列表
|
||||||
projects, err := model.GetProjectList(query, 0, "+_id")
|
projects, err := model.GetProjectList(query, "+_id")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
HandleError(http.StatusInternalServerError, c, err)
|
HandleError(http.StatusInternalServerError, c, err)
|
||||||
return
|
return
|
||||||
@@ -74,6 +78,9 @@ func PutProject(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UserId
|
||||||
|
p.UserId = services.GetCurrentUserId(c)
|
||||||
|
|
||||||
if err := p.Add(); err != nil {
|
if err := p.Add(); err != nil {
|
||||||
HandleError(http.StatusInternalServerError, c, err)
|
HandleError(http.StatusInternalServerError, c, err)
|
||||||
return
|
return
|
||||||
@@ -9,7 +9,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func GetScheduleList(c *gin.Context) {
|
func GetScheduleList(c *gin.Context) {
|
||||||
results, err := model.GetScheduleList(nil)
|
query := bson.M{}
|
||||||
|
|
||||||
|
// 获取校验
|
||||||
|
query = services.GetAuthQuery(query, c)
|
||||||
|
|
||||||
|
results, err := model.GetScheduleList(query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
HandleError(http.StatusInternalServerError, c, err)
|
HandleError(http.StatusInternalServerError, c, err)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -29,13 +29,14 @@ import (
|
|||||||
// ======== 爬虫管理 ========
|
// ======== 爬虫管理 ========
|
||||||
|
|
||||||
func GetSpiderList(c *gin.Context) {
|
func GetSpiderList(c *gin.Context) {
|
||||||
pageNum, _ := c.GetQuery("page_num")
|
pageNum := c.Query("page_num")
|
||||||
pageSize, _ := c.GetQuery("page_size")
|
pageSize := c.Query("page_size")
|
||||||
keyword, _ := c.GetQuery("keyword")
|
keyword := c.Query("keyword")
|
||||||
pid, _ := c.GetQuery("project_id")
|
pid := c.Query("project_id")
|
||||||
t, _ := c.GetQuery("type")
|
t := c.Query("type")
|
||||||
sortKey, _ := c.GetQuery("sort_key")
|
sortKey := c.Query("sort_key")
|
||||||
sortDirection, _ := c.GetQuery("sort_direction")
|
sortDirection := c.Query("sort_direction")
|
||||||
|
ownerType := c.Query("owner_type")
|
||||||
|
|
||||||
// 筛选-名称
|
// 筛选-名称
|
||||||
filter := bson.M{
|
filter := bson.M{
|
||||||
@@ -65,6 +66,21 @@ func GetSpiderList(c *gin.Context) {
|
|||||||
filter["project_id"] = bson.ObjectIdHex(pid)
|
filter["project_id"] = bson.ObjectIdHex(pid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 筛选-用户
|
||||||
|
if ownerType == constants.OwnerTypeAll {
|
||||||
|
user := services.GetCurrentUser(c)
|
||||||
|
if user.Role == constants.RoleNormal {
|
||||||
|
filter["$or"] = []bson.M{
|
||||||
|
{"user_id": services.GetCurrentUserId(c)},
|
||||||
|
{"is_public": true},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ownerType == constants.OwnerTypeMe {
|
||||||
|
filter["user_id"] = services.GetCurrentUserId(c)
|
||||||
|
} else if ownerType == constants.OwnerTypePublic {
|
||||||
|
filter["is_public"] = true
|
||||||
|
}
|
||||||
|
|
||||||
// 排序
|
// 排序
|
||||||
sortStr := "-_id"
|
sortStr := "-_id"
|
||||||
if sortKey != "" && sortDirection != "" {
|
if sortKey != "" && sortDirection != "" {
|
||||||
@@ -815,7 +831,7 @@ func GetSpiderStats(c *gin.Context) {
|
|||||||
overview.AvgWaitDuration = overview.TotalWaitDuration / taskCount
|
overview.AvgWaitDuration = overview.TotalWaitDuration / taskCount
|
||||||
overview.AvgRuntimeDuration = overview.TotalRuntimeDuration / taskCount
|
overview.AvgRuntimeDuration = overview.TotalRuntimeDuration / taskCount
|
||||||
|
|
||||||
items, err := model.GetDailyTaskStats(bson.M{"spider_id": spider.Id})
|
items, err := model.GetDailyTaskStats(bson.M{"spider_id": spider.Id, "user_id": bson.M{"user_id": services.GetCurrentUserId(c)}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf(err.Error())
|
log.Errorf(err.Error())
|
||||||
HandleError(http.StatusInternalServerError, c, err)
|
HandleError(http.StatusInternalServerError, c, err)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package routes
|
|||||||
import (
|
import (
|
||||||
"crawlab/constants"
|
"crawlab/constants"
|
||||||
"crawlab/model"
|
"crawlab/model"
|
||||||
|
"crawlab/services"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/globalsign/mgo/bson"
|
"github.com/globalsign/mgo/bson"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -22,7 +23,7 @@ func GetHomeStats(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 任务总数
|
// 任务总数
|
||||||
taskCount, err := model.GetTaskCount(nil)
|
taskCount, err := model.GetTaskCount(bson.M{"user_id": services.GetCurrentUserId(c)})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
HandleError(http.StatusInternalServerError, c, err)
|
HandleError(http.StatusInternalServerError, c, err)
|
||||||
return
|
return
|
||||||
@@ -36,21 +37,21 @@ func GetHomeStats(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 爬虫总数
|
// 爬虫总数
|
||||||
spiderCount, err := model.GetSpiderCount()
|
spiderCount, err := model.GetSpiderCount(bson.M{"user_id": services.GetCurrentUserId(c)})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
HandleError(http.StatusInternalServerError, c, err)
|
HandleError(http.StatusInternalServerError, c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 定时任务数
|
// 定时任务数
|
||||||
scheduleCount, err := model.GetScheduleCount()
|
scheduleCount, err := model.GetScheduleCount(bson.M{"user_id": services.GetCurrentUserId(c)})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
HandleError(http.StatusInternalServerError, c, err)
|
HandleError(http.StatusInternalServerError, c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 每日任务数
|
// 每日任务数
|
||||||
items, err := model.GetDailyTaskStats(bson.M{})
|
items, err := model.GetDailyTaskStats(bson.M{"user_id": services.GetCurrentUserId(c)})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
HandleError(http.StatusInternalServerError, c, err)
|
HandleError(http.StatusInternalServerError, c, err)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -47,11 +47,14 @@ func GetTaskList(c *gin.Context) {
|
|||||||
if data.SpiderId != "" {
|
if data.SpiderId != "" {
|
||||||
query["spider_id"] = bson.ObjectIdHex(data.SpiderId)
|
query["spider_id"] = bson.ObjectIdHex(data.SpiderId)
|
||||||
}
|
}
|
||||||
//新增根据任务状态获取task列表
|
// 根据任务状态获取task列表
|
||||||
if data.Status != "" {
|
if data.Status != "" {
|
||||||
query["status"] = data.Status
|
query["status"] = data.Status
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取校验
|
||||||
|
query = services.GetAuthQuery(query, c)
|
||||||
|
|
||||||
// 获取任务列表
|
// 获取任务列表
|
||||||
tasks, err := model.GetTaskList(query, (data.PageNum-1)*data.PageSize, data.PageSize, "-create_ts")
|
tasks, err := model.GetTaskList(query, (data.PageNum-1)*data.PageSize, data.PageSize, "-create_ts")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
20
backend/services/auth.go
Normal file
20
backend/services/auth.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crawlab/constants"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/globalsign/mgo/bson"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetAuthQuery(query bson.M, c *gin.Context) bson.M {
|
||||||
|
user := GetCurrentUser(c)
|
||||||
|
if user.Role == constants.RoleAdmin {
|
||||||
|
// 获得所有数据
|
||||||
|
return query
|
||||||
|
} else {
|
||||||
|
// 只获取自己的数据
|
||||||
|
query["user_id"] = user.Id
|
||||||
|
return query
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
122
backend/services/clean.go
Normal file
122
backend/services/clean.go
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crawlab/constants"
|
||||||
|
"crawlab/model"
|
||||||
|
"github.com/apex/log"
|
||||||
|
"github.com/globalsign/mgo/bson"
|
||||||
|
"runtime/debug"
|
||||||
|
)
|
||||||
|
|
||||||
|
func InitTaskCleanUserIds() {
|
||||||
|
adminUser, err := GetAdminUser()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf(err.Error())
|
||||||
|
debug.PrintStack()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tasks, err := model.GetTaskList(nil, 0, constants.Infinite, "+_id")
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf(err.Error())
|
||||||
|
debug.PrintStack()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, t := range tasks {
|
||||||
|
if !t.ScheduleId.Valid() {
|
||||||
|
t.ScheduleId = bson.ObjectIdHex(constants.ObjectIdNull)
|
||||||
|
if err := t.Save(); err != nil {
|
||||||
|
log.Errorf(err.Error())
|
||||||
|
debug.PrintStack()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !t.UserId.Valid() {
|
||||||
|
t.UserId = adminUser.Id
|
||||||
|
if err := t.Save(); err != nil {
|
||||||
|
log.Errorf(err.Error())
|
||||||
|
debug.PrintStack()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func InitProjectCleanUserIds() {
|
||||||
|
adminUser, err := GetAdminUser()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf(err.Error())
|
||||||
|
debug.PrintStack()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
projects, err := model.GetProjectList(nil, "+_id")
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf(err.Error())
|
||||||
|
debug.PrintStack()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, p := range projects {
|
||||||
|
if !p.UserId.Valid() {
|
||||||
|
p.UserId = adminUser.Id
|
||||||
|
if err := p.Save(); err != nil {
|
||||||
|
log.Errorf(err.Error())
|
||||||
|
debug.PrintStack()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func InitSpiderCleanUserIds() {
|
||||||
|
adminUser, err := GetAdminUser()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf(err.Error())
|
||||||
|
debug.PrintStack()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
spiders, _ := model.GetSpiderAllList(nil)
|
||||||
|
for _, s := range spiders {
|
||||||
|
if !s.UserId.Valid() {
|
||||||
|
s.UserId = adminUser.Id
|
||||||
|
if err := s.Save(); err != nil {
|
||||||
|
log.Errorf(err.Error())
|
||||||
|
debug.PrintStack()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func InitScheduleCleanUserIds() {
|
||||||
|
adminUser, err := GetAdminUser()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf(err.Error())
|
||||||
|
debug.PrintStack()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
schedules, _ := model.GetScheduleList(nil)
|
||||||
|
for _, s := range schedules {
|
||||||
|
if !s.UserId.Valid() {
|
||||||
|
s.UserId = adminUser.Id
|
||||||
|
if err := s.Save(); err != nil {
|
||||||
|
log.Errorf(err.Error())
|
||||||
|
debug.PrintStack()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func InitCleanService() error {
|
||||||
|
if model.IsMaster() {
|
||||||
|
// 清理任务UserIds
|
||||||
|
InitTaskCleanUserIds()
|
||||||
|
// 清理项目UserIds
|
||||||
|
InitProjectCleanUserIds()
|
||||||
|
// 清理爬虫UserIds
|
||||||
|
InitSpiderCleanUserIds()
|
||||||
|
// 清理定时任务UserIds
|
||||||
|
InitScheduleCleanUserIds()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -545,6 +545,9 @@ func InitSpiderService() error {
|
|||||||
if err := GitCron.Start(); err != nil {
|
if err := GitCron.Start(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 清理UserId
|
||||||
|
InitSpiderCleanUserIds()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -120,3 +120,11 @@ func GetCurrentUser(c *gin.Context) *model.User {
|
|||||||
func GetCurrentUserId(c *gin.Context) bson.ObjectId {
|
func GetCurrentUserId(c *gin.Context) bson.ObjectId {
|
||||||
return GetCurrentUser(c).Id
|
return GetCurrentUser(c).Id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetAdminUser() (user *model.User, err error) {
|
||||||
|
u, err := model.GetUserByUsername("admin")
|
||||||
|
if err != nil {
|
||||||
|
return user, err
|
||||||
|
}
|
||||||
|
return &u, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,12 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<codemirror
|
<div class="file-detail">
|
||||||
class="file-content"
|
<codemirror
|
||||||
:options="options"
|
class="file-content"
|
||||||
v-model="fileContent"
|
:options="options"
|
||||||
/>
|
v-model="fileContent"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import {
|
||||||
|
mapState,
|
||||||
|
mapGetters
|
||||||
|
} from 'vuex'
|
||||||
import { codemirror } from 'vue-codemirror-lite'
|
import { codemirror } from 'vue-codemirror-lite'
|
||||||
|
|
||||||
import 'codemirror/lib/codemirror.js'
|
import 'codemirror/lib/codemirror.js'
|
||||||
@@ -29,6 +35,12 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
...mapState('spider', [
|
||||||
|
'spiderForm'
|
||||||
|
]),
|
||||||
|
...mapGetters('user', [
|
||||||
|
'userInfo'
|
||||||
|
]),
|
||||||
fileContent: {
|
fileContent: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state.file.fileContent
|
return this.$store.state.file.fileContent
|
||||||
@@ -46,7 +58,8 @@ export default {
|
|||||||
indentUnit: 4,
|
indentUnit: 4,
|
||||||
lineNumbers: true,
|
lineNumbers: true,
|
||||||
line: true,
|
line: true,
|
||||||
matchBrackets: true
|
matchBrackets: true,
|
||||||
|
readOnly: this.isDisabled ? 'nocursor' : false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
language () {
|
language () {
|
||||||
@@ -69,6 +82,9 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
return 'text'
|
return 'text'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
isDisabled () {
|
||||||
|
return this.spiderForm.is_public && this.spiderForm.username !== this.userInfo.username
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
|
|||||||
@@ -109,6 +109,7 @@
|
|||||||
type="primary"
|
type="primary"
|
||||||
icon="el-icon-plus"
|
icon="el-icon-plus"
|
||||||
slot="reference"
|
slot="reference"
|
||||||
|
:disabled="isDisabled"
|
||||||
@click="onEmptyClick"
|
@click="onEmptyClick"
|
||||||
>
|
>
|
||||||
{{$t('Add')}}
|
{{$t('Add')}}
|
||||||
@@ -133,7 +134,7 @@
|
|||||||
{{$t('Confirm')}}
|
{{$t('Confirm')}}
|
||||||
</el-button>
|
</el-button>
|
||||||
<template slot="reference">
|
<template slot="reference">
|
||||||
<el-button type="danger" size="small" style="margin-right: 10px;">
|
<el-button type="danger" size="small" style="margin-right: 10px;" :disabled="isDisabled">
|
||||||
<font-awesome-icon :icon="['fa', 'trash']"/>
|
<font-awesome-icon :icon="['fa', 'trash']"/>
|
||||||
{{$t('Remove')}}
|
{{$t('Remove')}}
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -148,14 +149,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<template slot="reference">
|
<template slot="reference">
|
||||||
<div>
|
<div>
|
||||||
<el-button type="warning" size="small" style="margin-right: 10px;" @click="onOpenRename">
|
<el-button type="warning" size="small" style="margin-right: 10px;" :disabled="isDisabled" @click="onOpenRename">
|
||||||
<font-awesome-icon :icon="['fa', 'redo']"/>
|
<font-awesome-icon :icon="['fa', 'redo']"/>
|
||||||
{{$t('Rename')}}
|
{{$t('Rename')}}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
<el-button type="success" size="small" style="margin-right: 10px;" @click="onFileSave">
|
<el-button type="success" size="small" style="margin-right: 10px;" :disabled="isDisabled" @click="onFileSave">
|
||||||
<font-awesome-icon :icon="['fa', 'save']"/>
|
<font-awesome-icon :icon="['fa', 'save']"/>
|
||||||
{{$t('Save')}}
|
{{$t('Save')}}
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -176,7 +177,8 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {
|
import {
|
||||||
mapState
|
mapState,
|
||||||
|
mapGetters
|
||||||
} from 'vuex'
|
} from 'vuex'
|
||||||
import FileDetail from './FileDetail'
|
import FileDetail from './FileDetail'
|
||||||
|
|
||||||
@@ -185,7 +187,6 @@ export default {
|
|||||||
components: { FileDetail },
|
components: { FileDetail },
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
code: 'var hello = \'world\'',
|
|
||||||
isEdit: false,
|
isEdit: false,
|
||||||
showFile: false,
|
showFile: false,
|
||||||
name: '',
|
name: '',
|
||||||
@@ -209,11 +210,15 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState('spider', [
|
...mapState('spider', [
|
||||||
'fileTree'
|
'fileTree',
|
||||||
|
'spiderForm'
|
||||||
]),
|
]),
|
||||||
...mapState('file', [
|
...mapState('file', [
|
||||||
'fileList'
|
'fileList'
|
||||||
]),
|
]),
|
||||||
|
...mapGetters('user', [
|
||||||
|
'userInfo'
|
||||||
|
]),
|
||||||
currentPath: {
|
currentPath: {
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('file/SET_CURRENT_PATH', value)
|
this.$store.commit('file/SET_CURRENT_PATH', value)
|
||||||
@@ -238,6 +243,9 @@ export default {
|
|||||||
})
|
})
|
||||||
.filter(d => d.expanded)
|
.filter(d => d.expanded)
|
||||||
.map(d => d.path)
|
.map(d => d.path)
|
||||||
|
},
|
||||||
|
isDisabled () {
|
||||||
|
return this.spiderForm.is_public && this.spiderForm.username !== this.userInfo.username
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|||||||
@@ -16,14 +16,14 @@
|
|||||||
<el-input v-model="spiderForm._id" :placeholder="$t('Spider ID')" disabled></el-input>
|
<el-input v-model="spiderForm._id" :placeholder="$t('Spider ID')" disabled></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('Spider Name')">
|
<el-form-item :label="$t('Spider Name')">
|
||||||
<el-input v-model="spiderForm.display_name" :placeholder="$t('Spider Name')" :disabled="isView"></el-input>
|
<el-input v-model="spiderForm.display_name" :placeholder="$t('Spider Name')" :disabled="isView || isPublic"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('Project')" prop="project_id" required>
|
<el-form-item :label="$t('Project')" prop="project_id" required>
|
||||||
<el-select
|
<el-select
|
||||||
v-model="spiderForm.project_id"
|
v-model="spiderForm.project_id"
|
||||||
:placeholder="$t('Project')"
|
:placeholder="$t('Project')"
|
||||||
filterable
|
filterable
|
||||||
:disabled="isView"
|
:disabled="isView || isPublic"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="p in projectList"
|
v-for="p in projectList"
|
||||||
@@ -41,13 +41,16 @@
|
|||||||
<el-input
|
<el-input
|
||||||
v-model="spiderForm.cmd"
|
v-model="spiderForm.cmd"
|
||||||
:placeholder="$t('Execute Command')"
|
:placeholder="$t('Execute Command')"
|
||||||
:disabled="isView || spiderForm.is_scrapy"
|
:disabled="isView || spiderForm.is_scrapy || isPublic"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
<el-form-item :label="$t('Results Collection')" prop="col">
|
<el-form-item :label="$t('Results Collection')" prop="col">
|
||||||
<el-input v-model="spiderForm.col" :placeholder="$t('Results Collection')"
|
<el-input
|
||||||
:disabled="isView"></el-input>
|
v-model="spiderForm.col"
|
||||||
|
:placeholder="$t('Results Collection')"
|
||||||
|
:disabled="isView || isPublic"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('Spider Type')">
|
<el-form-item :label="$t('Spider Type')">
|
||||||
<el-select v-model="spiderForm.type" :placeholder="$t('Spider Type')" :disabled="true" clearable>
|
<el-select v-model="spiderForm.type" :placeholder="$t('Spider Type')" :disabled="true" clearable>
|
||||||
@@ -56,7 +59,12 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('Remark')">
|
<el-form-item :label="$t('Remark')">
|
||||||
<el-input type="textarea" v-model="spiderForm.remark" :placeholder="$t('Remark')" :disabled="isView"/>
|
<el-input
|
||||||
|
type="textarea"
|
||||||
|
v-model="spiderForm.remark"
|
||||||
|
:placeholder="$t('Remark')"
|
||||||
|
:disabled="isView || isPublic"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
@@ -64,6 +72,7 @@
|
|||||||
<el-switch
|
<el-switch
|
||||||
v-model="spiderForm.is_scrapy"
|
v-model="spiderForm.is_scrapy"
|
||||||
active-color="#13ce66"
|
active-color="#13ce66"
|
||||||
|
:disabled="isView || isPublic"
|
||||||
@change="onIsScrapyChange"
|
@change="onIsScrapyChange"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -73,6 +82,7 @@
|
|||||||
<el-switch
|
<el-switch
|
||||||
v-model="spiderForm.is_git"
|
v-model="spiderForm.is_git"
|
||||||
active-color="#13ce66"
|
active-color="#13ce66"
|
||||||
|
:disabled="isView || isPublic"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -81,6 +91,18 @@
|
|||||||
<el-switch
|
<el-switch
|
||||||
v-model="spiderForm.is_long_task"
|
v-model="spiderForm.is_long_task"
|
||||||
active-color="#13ce66"
|
active-color="#13ce66"
|
||||||
|
:disabled="isView || isPublic"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item v-if="!isView" :label="$t('Is Public')" prop="is_public">
|
||||||
|
<el-switch
|
||||||
|
v-model="spiderForm.is_public"
|
||||||
|
active-color="#13ce66"
|
||||||
|
:disabled="isView || isPublic"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -88,7 +110,7 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row class="button-container" v-if="!isView">
|
<el-row class="button-container" v-if="!isView">
|
||||||
<el-button size="small" v-if="isShowRun" type="danger" @click="onCrawl"
|
<el-button size="small" v-if="isShowRun && !isPublic" type="danger" @click="onCrawl"
|
||||||
icon="el-icon-video-play" style="margin-right: 10px">
|
icon="el-icon-video-play" style="margin-right: 10px">
|
||||||
{{$t('Run')}}
|
{{$t('Run')}}
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -102,11 +124,11 @@
|
|||||||
:file-list="fileList"
|
:file-list="fileList"
|
||||||
style="display:inline-block;margin-right:10px"
|
style="display:inline-block;margin-right:10px"
|
||||||
>
|
>
|
||||||
<el-button size="small" type="primary" icon="el-icon-upload" v-loading="uploadLoading">
|
<el-button v-if="!isPublic" size="small" type="primary" icon="el-icon-upload" v-loading="uploadLoading">
|
||||||
{{$t('Upload')}}
|
{{$t('Upload')}}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
<el-button size="small" type="success" @click="onSave" icon="el-icon-check">
|
<el-button v-if="!isPublic" size="small" type="success" @click="onSave" icon="el-icon-check">
|
||||||
{{$t('Save')}}
|
{{$t('Save')}}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -162,6 +184,7 @@ export default {
|
|||||||
'spiderForm'
|
'spiderForm'
|
||||||
]),
|
]),
|
||||||
...mapGetters('user', [
|
...mapGetters('user', [
|
||||||
|
'userInfo',
|
||||||
'token'
|
'token'
|
||||||
]),
|
]),
|
||||||
...mapState('project', [
|
...mapState('project', [
|
||||||
@@ -173,6 +196,9 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
isPublic () {
|
||||||
|
return this.spiderForm.is_public && this.spiderForm.username !== this.userInfo.username
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|||||||
@@ -222,6 +222,11 @@ export default {
|
|||||||
'Add Variable': '添加变量',
|
'Add Variable': '添加变量',
|
||||||
'Copy Spider': '复制爬虫',
|
'Copy Spider': '复制爬虫',
|
||||||
'New Spider Name': '新爬虫名称',
|
'New Spider Name': '新爬虫名称',
|
||||||
|
'All Spiders': '所有爬虫',
|
||||||
|
'My Spiders': '我的爬虫',
|
||||||
|
'Public Spiders': '公共爬虫',
|
||||||
|
'Is Public': '是否公共',
|
||||||
|
'Owner': '所有者',
|
||||||
|
|
||||||
// 爬虫列表
|
// 爬虫列表
|
||||||
'Name': '名称',
|
'Name': '名称',
|
||||||
|
|||||||
@@ -208,7 +208,9 @@ docker-compose up -d
|
|||||||
},
|
},
|
||||||
logout () {
|
logout () {
|
||||||
this.$store.dispatch('user/logout')
|
this.$store.dispatch('user/logout')
|
||||||
|
this.$store.dispatch('delAllViews')
|
||||||
this.$router.push('/login')
|
this.$router.push('/login')
|
||||||
|
this.$st.sendEv('全局', '登出')
|
||||||
},
|
},
|
||||||
setLang (lang) {
|
setLang (lang) {
|
||||||
window.localStorage.setItem('lang', lang)
|
window.localStorage.setItem('lang', lang)
|
||||||
|
|||||||
@@ -157,9 +157,11 @@ export default {
|
|||||||
this.loading = false
|
this.loading = false
|
||||||
this.$router.push({ path: this.redirect || '/' })
|
this.$router.push({ path: this.redirect || '/' })
|
||||||
this.$store.dispatch('user/getInfo')
|
this.$store.dispatch('user/getInfo')
|
||||||
|
this.$st.sendEv('全局', '登录', '成功')
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
this.$message.error(this.$t('Error when logging in (Please read documentation Q&A)'))
|
this.$message.error(this.$t('Error when logging in (Please read documentation Q&A)'))
|
||||||
this.loading = false
|
this.loading = false
|
||||||
|
this.$st.sendEv('全局', '登录', '失败')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -171,9 +173,11 @@ export default {
|
|||||||
this.$store.dispatch('user/register', this.loginForm).then(() => {
|
this.$store.dispatch('user/register', this.loginForm).then(() => {
|
||||||
this.handleLogin()
|
this.handleLogin()
|
||||||
this.loading = false
|
this.loading = false
|
||||||
|
this.$st.sendEv('全局', '注册', '成功')
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
this.$message.error(this.$t(err))
|
this.$message.error(this.$t(err))
|
||||||
this.loading = false
|
this.loading = false
|
||||||
|
this.$st.sendEv('全局', '注册', '失败')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -91,8 +91,13 @@
|
|||||||
<h4 v-else class="title">{{ $t('No Project') }}</h4>
|
<h4 v-else class="title">{{ $t('No Project') }}</h4>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<div class="spider-count">
|
<div style="display: flex; justify-content: space-between">
|
||||||
|
<span class="spider-count">
|
||||||
{{$t('Spider Count')}}: {{ item.spiders.length }}
|
{{$t('Spider Count')}}: {{ item.spiders.length }}
|
||||||
|
</span>
|
||||||
|
<span class="owner">
|
||||||
|
{{item.username}}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row class="description-wrapper">
|
<el-row class="description-wrapper">
|
||||||
@@ -270,7 +275,8 @@ export default {
|
|||||||
margin: 10px 0 0 0;
|
margin: 10px 0 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list .item .item-card .spider-count {
|
.list .item .item-card .spider-count,
|
||||||
|
.list .item .item-card .owner {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: grey;
|
color: grey;
|
||||||
font-weight: bolder;
|
font-weight: bolder;
|
||||||
@@ -284,6 +290,7 @@ export default {
|
|||||||
|
|
||||||
.list .item .item-card .description {
|
.list .item .item-card .description {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
line-height: 16px;
|
||||||
color: grey;
|
color: grey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -291,7 +291,8 @@ export default {
|
|||||||
{ name: 'scrapy_spider', label: 'Scrapy Spider', width: '150px' },
|
{ name: 'scrapy_spider', label: 'Scrapy Spider', width: '150px' },
|
||||||
{ name: 'param', label: 'Parameters', width: '150px' },
|
{ name: 'param', label: 'Parameters', width: '150px' },
|
||||||
{ name: 'description', label: 'Description', width: '200px' },
|
{ name: 'description', label: 'Description', width: '200px' },
|
||||||
{ name: 'enable', label: 'Enable/Disable', width: '120px' }
|
{ name: 'enable', label: 'Enable/Disable', width: '120px' },
|
||||||
|
{ name: 'username', label: 'Owner', width: '100px' }
|
||||||
// { name: 'status', label: 'Status', width: '100px' }
|
// { name: 'status', label: 'Status', width: '100px' }
|
||||||
],
|
],
|
||||||
isEdit: false,
|
isEdit: false,
|
||||||
@@ -611,7 +612,7 @@ export default {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 爬虫列表
|
// 爬虫列表
|
||||||
request.get('/spiders', {})
|
request.get('/spiders', { owner_type: 'all' })
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.spiderList = response.data.data.list || []
|
this.spiderList = response.data.data.list || []
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ export default {
|
|||||||
await this.$store.dispatch('spider/getTaskList', this.$route.params.id)
|
await this.$store.dispatch('spider/getTaskList', this.$route.params.id)
|
||||||
|
|
||||||
// get spider list
|
// get spider list
|
||||||
await this.$store.dispatch('spider/getSpiderList')
|
await this.$store.dispatch('spider/getSpiderList', { owner_type: 'all' })
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
if (!this.$utils.tour.isFinishedTour('spider-detail')) {
|
if (!this.$utils.tour.isFinishedTour('spider-detail')) {
|
||||||
|
|||||||
@@ -326,6 +326,18 @@
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-select
|
||||||
|
v-model="filter.owner_type"
|
||||||
|
size="small"
|
||||||
|
:placeholder="$t('Owner Type')"
|
||||||
|
@change="getList"
|
||||||
|
>
|
||||||
|
<el-option value="me" :label="$t('My Spiders')"/>
|
||||||
|
<el-option value="all" :label="$t('All Spiders')"/>
|
||||||
|
<el-option value="public" :label="$t('Public Spiders')"/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="filter.keyword"
|
v-model="filter.keyword"
|
||||||
@@ -578,12 +590,22 @@
|
|||||||
<el-table-column :label="$t('Action')" align="left" fixed="right" min-width="220px">
|
<el-table-column :label="$t('Action')" align="left" fixed="right" min-width="220px">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-tooltip :content="$t('View')" placement="top">
|
<el-tooltip :content="$t('View')" placement="top">
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini"
|
<el-button
|
||||||
@click="onView(scope.row, $event)"></el-button>
|
type="primary"
|
||||||
|
icon="el-icon-search"
|
||||||
|
size="mini"
|
||||||
|
:disabled="isDisabled(scope.row)"
|
||||||
|
@click="onView(scope.row, $event)"
|
||||||
|
/>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip :content="$t('Remove')" placement="top">
|
<el-tooltip :content="$t('Remove')" placement="top">
|
||||||
<el-button type="danger" icon="el-icon-delete" size="mini"
|
<el-button
|
||||||
@click="onRemove(scope.row, $event)"></el-button>
|
type="danger"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
size="mini"
|
||||||
|
:disabled="isDisabled(scope.row)"
|
||||||
|
@click="onRemove(scope.row, $event)"
|
||||||
|
/>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip :content="$t('Copy')" placement="top">
|
<el-tooltip :content="$t('Copy')" placement="top">
|
||||||
<el-button
|
<el-button
|
||||||
@@ -594,17 +616,27 @@
|
|||||||
/>
|
/>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip v-if="!isShowRun(scope.row)" :content="$t('No command line')" placement="top">
|
<el-tooltip v-if="!isShowRun(scope.row)" :content="$t('No command line')" placement="top">
|
||||||
<el-button disabled type="success" icon="fa fa-bug" size="mini"
|
<el-button
|
||||||
@click="onCrawl(scope.row, $event)"></el-button>
|
disabled
|
||||||
|
type="success" icon="fa fa-bug" size="mini"
|
||||||
|
@click="onCrawl(scope.row, $event)"
|
||||||
|
/>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip v-else :content="$t('Run')" placement="top">
|
<el-tooltip v-else :content="$t('Run')" placement="top">
|
||||||
<el-button type="success" icon="fa fa-bug" size="mini" @click="onCrawl(scope.row, $event)"></el-button>
|
<el-button
|
||||||
|
type="success"
|
||||||
|
icon="fa fa-bug"
|
||||||
|
size="mini"
|
||||||
|
:disabled="isDisabled(scope.row)"
|
||||||
|
@click="onCrawl(scope.row, $event)"
|
||||||
|
/>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip :content="$t('Latest Tasks')" placement="top">
|
<el-tooltip :content="$t('Latest Tasks')" placement="top">
|
||||||
<el-button
|
<el-button
|
||||||
type="warning"
|
type="warning"
|
||||||
icon="fa fa-tasks"
|
icon="fa fa-tasks"
|
||||||
size="mini"
|
size="mini"
|
||||||
|
:disabled="isDisabled(scope.row)"
|
||||||
@click="onViewRunningTasks(scope.row, $event)"
|
@click="onViewRunningTasks(scope.row, $event)"
|
||||||
/>
|
/>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
@@ -664,7 +696,8 @@ export default {
|
|||||||
filter: {
|
filter: {
|
||||||
project_id: '',
|
project_id: '',
|
||||||
keyword: '',
|
keyword: '',
|
||||||
type: 'all'
|
type: 'all',
|
||||||
|
owner_type: 'me'
|
||||||
},
|
},
|
||||||
sort: {
|
sort: {
|
||||||
sortKey: '',
|
sortKey: '',
|
||||||
@@ -816,6 +849,7 @@ export default {
|
|||||||
'templateList'
|
'templateList'
|
||||||
]),
|
]),
|
||||||
...mapGetters('user', [
|
...mapGetters('user', [
|
||||||
|
'userInfo',
|
||||||
'token'
|
'token'
|
||||||
]),
|
]),
|
||||||
...mapState('lang', [
|
...mapState('lang', [
|
||||||
@@ -846,6 +880,7 @@ export default {
|
|||||||
columns.push({ name: 'last_run_ts', label: 'Last Run', width: '140' })
|
columns.push({ name: 'last_run_ts', label: 'Last Run', width: '140' })
|
||||||
columns.push({ name: 'update_ts', label: 'Update Time', width: '140' })
|
columns.push({ name: 'update_ts', label: 'Update Time', width: '140' })
|
||||||
columns.push({ name: 'create_ts', label: 'Create Time', width: '140' })
|
columns.push({ name: 'create_ts', label: 'Create Time', width: '140' })
|
||||||
|
columns.push({ name: 'username', label: 'Owner', width: '100' })
|
||||||
columns.push({ name: 'remark', label: 'Remark', width: '140' })
|
columns.push({ name: 'remark', label: 'Remark', width: '140' })
|
||||||
return columns
|
return columns
|
||||||
},
|
},
|
||||||
@@ -903,7 +938,7 @@ export default {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.$router.push(`/spiders/${res2.data.data._id}`)
|
this.$router.push(`/spiders/${res2.data.data._id}`)
|
||||||
await this.$store.dispatch('spider/getSpiderList')
|
this.getList()
|
||||||
this.$st.sendEv('爬虫列表', '添加爬虫', '可配置爬虫')
|
this.$st.sendEv('爬虫列表', '添加爬虫', '可配置爬虫')
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -918,7 +953,7 @@ export default {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.$router.push(`/spiders/${res2.data.data._id}`)
|
this.$router.push(`/spiders/${res2.data.data._id}`)
|
||||||
await this.$store.dispatch('spider/getSpiderList')
|
this.getList()
|
||||||
this.$st.sendEv('爬虫列表', '添加爬虫', '自定义爬虫')
|
this.$st.sendEv('爬虫列表', '添加爬虫', '自定义爬虫')
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -1095,7 +1130,8 @@ export default {
|
|||||||
sort_direction: this.sort.sortDirection,
|
sort_direction: this.sort.sortDirection,
|
||||||
keyword: this.filter.keyword,
|
keyword: this.filter.keyword,
|
||||||
type: this.filter.type,
|
type: this.filter.type,
|
||||||
project_id: this.filter.project_id
|
project_id: this.filter.project_id,
|
||||||
|
owner_type: this.filter.owner_type
|
||||||
}
|
}
|
||||||
await this.$store.dispatch('spider/getSpiderList', params)
|
await this.$store.dispatch('spider/getSpiderList', params)
|
||||||
|
|
||||||
@@ -1208,6 +1244,9 @@ export default {
|
|||||||
onCrawlConfirmDialogClose () {
|
onCrawlConfirmDialogClose () {
|
||||||
this.crawlConfirmDialogVisible = false
|
this.crawlConfirmDialogVisible = false
|
||||||
this.isMultiple = false
|
this.isMultiple = false
|
||||||
|
},
|
||||||
|
isDisabled (row) {
|
||||||
|
return row.is_public && row.username !== this.userInfo.username
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async created () {
|
async created () {
|
||||||
|
|||||||
@@ -205,7 +205,8 @@ export default {
|
|||||||
{ name: 'wait_duration', label: 'Wait Duration (sec)', align: 'right' },
|
{ name: 'wait_duration', label: 'Wait Duration (sec)', align: 'right' },
|
||||||
{ name: 'runtime_duration', label: 'Runtime Duration (sec)', align: 'right' },
|
{ name: 'runtime_duration', label: 'Runtime Duration (sec)', align: 'right' },
|
||||||
{ name: 'total_duration', label: 'Total Duration (sec)', width: '80', align: 'right' },
|
{ name: 'total_duration', label: 'Total Duration (sec)', width: '80', align: 'right' },
|
||||||
{ name: 'result_count', label: 'Results Count', width: '80' }
|
{ name: 'result_count', label: 'Results Count', width: '80' },
|
||||||
|
{ name: 'username', label: 'Owner', width: '100' }
|
||||||
// { name: 'avg_num_results', label: 'Average Results Count per Second', width: '80' }
|
// { name: 'avg_num_results', label: 'Average Results Count per Second', width: '80' }
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user