mirror of
https://github.com/crawlab-team/crawlab.git
synced 2026-01-21 17:21:09 +01:00
优化项目管理
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
### 功能 / 优化
|
||||
- **交互式教程**. 引导用户了解 Crawlab 的主要功能.
|
||||
- **加入全局环境变量**. 可以设置全局环境变量,然后传入到所有爬虫程序中. [#177](https://github.com/crawlab-team/crawlab/issues/177)
|
||||
- **项目**. 允许用户将爬虫关联到项目上. [#316](https://github.com/crawlab-team/crawlab/issues/316)
|
||||
- **用户管理优化**. 限制管理用户的权限. [#456](https://github.com/crawlab-team/crawlab/issues/456)
|
||||
- **设置页面优化**.
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
### Features / Enhancement
|
||||
- **Interactive Tutorial**. Guide users through the main functionalities of Crawlab.
|
||||
- **Global Environment Variables**. Allow users to set global environment variables, which will be passed into all spider programs. [#177](https://github.com/crawlab-team/crawlab/issues/177)
|
||||
- **Project**. Allow users to link spiders to projects. [#316](https://github.com/crawlab-team/crawlab/issues/316)
|
||||
- **User Admin Optimization**. Restrict privilleges of admin users. [#456](https://github.com/crawlab-team/crawlab/issues/456)
|
||||
- **Setting Page Optimization**.
|
||||
|
||||
|
||||
@@ -232,6 +232,7 @@ func main() {
|
||||
// 项目
|
||||
{
|
||||
authGroup.GET("/projects", routes.GetProjectList) // 列表
|
||||
authGroup.GET("/projects/tags", routes.GetProjectTags) // 项目标签
|
||||
authGroup.PUT("/projects", routes.PutProject) //修改
|
||||
authGroup.POST("/projects/:id", routes.PostProject) // 新增
|
||||
authGroup.DELETE("/projects/:id", routes.DeleteProject) //删除
|
||||
|
||||
@@ -2,6 +2,7 @@ package routes
|
||||
|
||||
import (
|
||||
"crawlab/constants"
|
||||
"crawlab/database"
|
||||
"crawlab/model"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/globalsign/mgo/bson"
|
||||
@@ -9,15 +10,23 @@ import (
|
||||
)
|
||||
|
||||
func GetProjectList(c *gin.Context) {
|
||||
tag := c.Query("tag")
|
||||
|
||||
// 筛选条件
|
||||
query := bson.M{}
|
||||
if tag != "" {
|
||||
query["tags"] = tag
|
||||
}
|
||||
|
||||
// 获取列表
|
||||
projects, err := model.GetProjectList(nil, 0, "+_id")
|
||||
projects, err := model.GetProjectList(query, 0, "+_id")
|
||||
if err != nil {
|
||||
HandleError(http.StatusInternalServerError, c, err)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取总数
|
||||
total, err := model.GetProjectListTotal(nil)
|
||||
total, err := model.GetProjectListTotal(query)
|
||||
if err != nil {
|
||||
HandleError(http.StatusInternalServerError, c, err)
|
||||
return
|
||||
@@ -34,18 +43,20 @@ func GetProjectList(c *gin.Context) {
|
||||
}
|
||||
|
||||
// 获取未被分配的爬虫数量
|
||||
noProject := model.Project{
|
||||
Id: bson.ObjectIdHex(constants.ObjectIdNull),
|
||||
Name: "No Project",
|
||||
Description: "Not assigned to any project",
|
||||
if tag == "" {
|
||||
noProject := model.Project{
|
||||
Id: bson.ObjectIdHex(constants.ObjectIdNull),
|
||||
Name: "No Project",
|
||||
Description: "Not assigned to any project",
|
||||
}
|
||||
spiders, err := noProject.GetSpiders()
|
||||
if err != nil {
|
||||
HandleError(http.StatusInternalServerError, c, err)
|
||||
return
|
||||
}
|
||||
noProject.Spiders = spiders
|
||||
projects = append(projects, noProject)
|
||||
}
|
||||
spiders, err := noProject.GetSpiders()
|
||||
if err != nil {
|
||||
HandleError(http.StatusInternalServerError, c, err)
|
||||
return
|
||||
}
|
||||
noProject.Spiders = spiders
|
||||
projects = append(projects, noProject)
|
||||
|
||||
c.JSON(http.StatusOK, ListResponse{
|
||||
Status: "ok",
|
||||
@@ -117,3 +128,45 @@ func DeleteProject(c *gin.Context) {
|
||||
Message: "success",
|
||||
})
|
||||
}
|
||||
|
||||
func GetProjectTags(c *gin.Context) {
|
||||
type Result struct {
|
||||
Tag string `json:"tag" bson:"tag"`
|
||||
}
|
||||
|
||||
s, col := database.GetCol("projects")
|
||||
defer s.Close()
|
||||
|
||||
pipeline := []bson.M{
|
||||
{
|
||||
"$unwind": "$tags",
|
||||
},
|
||||
{
|
||||
"$group": bson.M{
|
||||
"_id": "$tags",
|
||||
},
|
||||
},
|
||||
{
|
||||
"$sort": bson.M{
|
||||
"_id": 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
"$addFields": bson.M{
|
||||
"tag": "$_id",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var items []Result
|
||||
if err := col.Pipe(pipeline).All(&items); err != nil {
|
||||
HandleError(http.StatusInternalServerError, c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, Response{
|
||||
Status: "ok",
|
||||
Message: "success",
|
||||
Data: items,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -219,6 +219,9 @@ export default {
|
||||
// 部署
|
||||
'Time': '时间',
|
||||
|
||||
// 项目
|
||||
'All Tags': '全部标签',
|
||||
|
||||
// 定时任务
|
||||
'Schedule Name': '定时任务名称',
|
||||
'Schedule Description': '定时任务描述',
|
||||
|
||||
@@ -43,7 +43,23 @@
|
||||
<!--./add popup-->
|
||||
|
||||
<div class="action-wrapper">
|
||||
<div class="buttons">
|
||||
<div class="left">
|
||||
<el-select
|
||||
v-model="filter.tag"
|
||||
size="small"
|
||||
:placeholder="$t('Select Tag')"
|
||||
@change="onFilterChange"
|
||||
>
|
||||
<el-option value="" :label="$t('All Tags')"/>
|
||||
<el-option
|
||||
v-for="tag in projectTags"
|
||||
:key="tag"
|
||||
:label="tag"
|
||||
:value="tag"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="right">
|
||||
<el-button
|
||||
icon="el-icon-plus"
|
||||
type="primary"
|
||||
@@ -112,19 +128,27 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
defaultTags: [],
|
||||
dialogVisible: false
|
||||
dialogVisible: false,
|
||||
filter: {
|
||||
tag: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState('project', [
|
||||
'projectForm',
|
||||
'projectList'
|
||||
'projectList',
|
||||
'projectTags'
|
||||
])
|
||||
},
|
||||
methods: {
|
||||
onDialogClose () {
|
||||
this.dialogVisible = false
|
||||
},
|
||||
onFilterChange () {
|
||||
this.$store.dispatch('project/getProjectList', this.filter)
|
||||
this.$st.sendEv('项目', '筛选项目')
|
||||
},
|
||||
onAdd () {
|
||||
this.isEdit = false
|
||||
this.dialogVisible = true
|
||||
@@ -193,14 +217,16 @@ export default {
|
||||
}
|
||||
},
|
||||
async created () {
|
||||
await this.$store.dispatch('project/getProjectList')
|
||||
await this.$store.dispatch('project/getProjectList', this.filter)
|
||||
await this.$store.dispatch('project/getProjectTags')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.action-wrapper {
|
||||
text-align: right;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #EBEEF5;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user