mirror of
https://github.com/crawlab-team/crawlab.git
synced 2026-01-22 17:31:03 +01:00
加入权限管理
This commit is contained in:
@@ -1,12 +1,18 @@
|
||||
<template>
|
||||
<codemirror
|
||||
class="file-content"
|
||||
:options="options"
|
||||
v-model="fileContent"
|
||||
/>
|
||||
<div class="file-detail">
|
||||
<codemirror
|
||||
class="file-content"
|
||||
:options="options"
|
||||
v-model="fileContent"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState,
|
||||
mapGetters
|
||||
} from 'vuex'
|
||||
import { codemirror } from 'vue-codemirror-lite'
|
||||
|
||||
import 'codemirror/lib/codemirror.js'
|
||||
@@ -29,6 +35,12 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState('spider', [
|
||||
'spiderForm'
|
||||
]),
|
||||
...mapGetters('user', [
|
||||
'userInfo'
|
||||
]),
|
||||
fileContent: {
|
||||
get () {
|
||||
return this.$store.state.file.fileContent
|
||||
@@ -46,7 +58,8 @@ export default {
|
||||
indentUnit: 4,
|
||||
lineNumbers: true,
|
||||
line: true,
|
||||
matchBrackets: true
|
||||
matchBrackets: true,
|
||||
readOnly: this.isDisabled ? 'nocursor' : false
|
||||
}
|
||||
},
|
||||
language () {
|
||||
@@ -69,6 +82,9 @@ export default {
|
||||
} else {
|
||||
return 'text'
|
||||
}
|
||||
},
|
||||
isDisabled () {
|
||||
return this.spiderForm.is_public && this.spiderForm.username !== this.userInfo.username
|
||||
}
|
||||
},
|
||||
created () {
|
||||
|
||||
@@ -109,6 +109,7 @@
|
||||
type="primary"
|
||||
icon="el-icon-plus"
|
||||
slot="reference"
|
||||
:disabled="isDisabled"
|
||||
@click="onEmptyClick"
|
||||
>
|
||||
{{$t('Add')}}
|
||||
@@ -133,7 +134,7 @@
|
||||
{{$t('Confirm')}}
|
||||
</el-button>
|
||||
<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']"/>
|
||||
{{$t('Remove')}}
|
||||
</el-button>
|
||||
@@ -148,14 +149,14 @@
|
||||
</div>
|
||||
<template slot="reference">
|
||||
<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']"/>
|
||||
{{$t('Rename')}}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</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']"/>
|
||||
{{$t('Save')}}
|
||||
</el-button>
|
||||
@@ -176,7 +177,8 @@
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
mapState,
|
||||
mapGetters
|
||||
} from 'vuex'
|
||||
import FileDetail from './FileDetail'
|
||||
|
||||
@@ -185,7 +187,6 @@ export default {
|
||||
components: { FileDetail },
|
||||
data () {
|
||||
return {
|
||||
code: 'var hello = \'world\'',
|
||||
isEdit: false,
|
||||
showFile: false,
|
||||
name: '',
|
||||
@@ -209,11 +210,15 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
...mapState('spider', [
|
||||
'fileTree'
|
||||
'fileTree',
|
||||
'spiderForm'
|
||||
]),
|
||||
...mapState('file', [
|
||||
'fileList'
|
||||
]),
|
||||
...mapGetters('user', [
|
||||
'userInfo'
|
||||
]),
|
||||
currentPath: {
|
||||
set (value) {
|
||||
this.$store.commit('file/SET_CURRENT_PATH', value)
|
||||
@@ -238,6 +243,9 @@ export default {
|
||||
})
|
||||
.filter(d => d.expanded)
|
||||
.map(d => d.path)
|
||||
},
|
||||
isDisabled () {
|
||||
return this.spiderForm.is_public && this.spiderForm.username !== this.userInfo.username
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
<el-input v-model="spiderForm._id" :placeholder="$t('Spider ID')" disabled></el-input>
|
||||
</el-form-item>
|
||||
<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 :label="$t('Project')" prop="project_id" required>
|
||||
<el-select
|
||||
v-model="spiderForm.project_id"
|
||||
:placeholder="$t('Project')"
|
||||
filterable
|
||||
:disabled="isView"
|
||||
:disabled="isView || isPublic"
|
||||
>
|
||||
<el-option
|
||||
v-for="p in projectList"
|
||||
@@ -41,13 +41,16 @@
|
||||
<el-input
|
||||
v-model="spiderForm.cmd"
|
||||
:placeholder="$t('Execute Command')"
|
||||
:disabled="isView || spiderForm.is_scrapy"
|
||||
:disabled="isView || spiderForm.is_scrapy || isPublic"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<el-form-item :label="$t('Results Collection')" prop="col">
|
||||
<el-input v-model="spiderForm.col" :placeholder="$t('Results Collection')"
|
||||
:disabled="isView"></el-input>
|
||||
<el-input
|
||||
v-model="spiderForm.col"
|
||||
:placeholder="$t('Results Collection')"
|
||||
:disabled="isView || isPublic"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('Spider Type')">
|
||||
<el-select v-model="spiderForm.type" :placeholder="$t('Spider Type')" :disabled="true" clearable>
|
||||
@@ -56,7 +59,12 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<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-row>
|
||||
<el-col :span="6">
|
||||
@@ -64,6 +72,7 @@
|
||||
<el-switch
|
||||
v-model="spiderForm.is_scrapy"
|
||||
active-color="#13ce66"
|
||||
:disabled="isView || isPublic"
|
||||
@change="onIsScrapyChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
@@ -73,6 +82,7 @@
|
||||
<el-switch
|
||||
v-model="spiderForm.is_git"
|
||||
active-color="#13ce66"
|
||||
:disabled="isView || isPublic"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -81,6 +91,18 @@
|
||||
<el-switch
|
||||
v-model="spiderForm.is_long_task"
|
||||
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-col>
|
||||
@@ -88,7 +110,7 @@
|
||||
</el-form>
|
||||
</el-row>
|
||||
<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">
|
||||
{{$t('Run')}}
|
||||
</el-button>
|
||||
@@ -102,11 +124,11 @@
|
||||
:file-list="fileList"
|
||||
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')}}
|
||||
</el-button>
|
||||
</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')}}
|
||||
</el-button>
|
||||
</el-row>
|
||||
@@ -162,6 +184,7 @@ export default {
|
||||
'spiderForm'
|
||||
]),
|
||||
...mapGetters('user', [
|
||||
'userInfo',
|
||||
'token'
|
||||
]),
|
||||
...mapState('project', [
|
||||
@@ -173,6 +196,9 @@ export default {
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
},
|
||||
isPublic () {
|
||||
return this.spiderForm.is_public && this.spiderForm.username !== this.userInfo.username
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -222,6 +222,11 @@ export default {
|
||||
'Add Variable': '添加变量',
|
||||
'Copy Spider': '复制爬虫',
|
||||
'New Spider Name': '新爬虫名称',
|
||||
'All Spiders': '所有爬虫',
|
||||
'My Spiders': '我的爬虫',
|
||||
'Public Spiders': '公共爬虫',
|
||||
'Is Public': '是否公共',
|
||||
'Owner': '所有者',
|
||||
|
||||
// 爬虫列表
|
||||
'Name': '名称',
|
||||
|
||||
@@ -208,7 +208,9 @@ docker-compose up -d
|
||||
},
|
||||
logout () {
|
||||
this.$store.dispatch('user/logout')
|
||||
this.$store.dispatch('delAllViews')
|
||||
this.$router.push('/login')
|
||||
this.$st.sendEv('全局', '登出')
|
||||
},
|
||||
setLang (lang) {
|
||||
window.localStorage.setItem('lang', lang)
|
||||
|
||||
@@ -157,9 +157,11 @@ export default {
|
||||
this.loading = false
|
||||
this.$router.push({ path: this.redirect || '/' })
|
||||
this.$store.dispatch('user/getInfo')
|
||||
this.$st.sendEv('全局', '登录', '成功')
|
||||
}).catch(() => {
|
||||
this.$message.error(this.$t('Error when logging in (Please read documentation Q&A)'))
|
||||
this.loading = false
|
||||
this.$st.sendEv('全局', '登录', '失败')
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -171,9 +173,11 @@ export default {
|
||||
this.$store.dispatch('user/register', this.loginForm).then(() => {
|
||||
this.handleLogin()
|
||||
this.loading = false
|
||||
this.$st.sendEv('全局', '注册', '成功')
|
||||
}).catch(err => {
|
||||
this.$message.error(this.$t(err))
|
||||
this.loading = false
|
||||
this.$st.sendEv('全局', '注册', '失败')
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -91,8 +91,13 @@
|
||||
<h4 v-else class="title">{{ $t('No Project') }}</h4>
|
||||
</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 }}
|
||||
</span>
|
||||
<span class="owner">
|
||||
{{item.username}}
|
||||
</span>
|
||||
</div>
|
||||
</el-row>
|
||||
<el-row class="description-wrapper">
|
||||
@@ -270,7 +275,8 @@ export default {
|
||||
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;
|
||||
color: grey;
|
||||
font-weight: bolder;
|
||||
@@ -284,6 +290,7 @@ export default {
|
||||
|
||||
.list .item .item-card .description {
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
color: grey;
|
||||
}
|
||||
|
||||
|
||||
@@ -291,7 +291,8 @@ export default {
|
||||
{ name: 'scrapy_spider', label: 'Scrapy Spider', width: '150px' },
|
||||
{ name: 'param', label: 'Parameters', width: '150px' },
|
||||
{ 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' }
|
||||
],
|
||||
isEdit: false,
|
||||
@@ -611,7 +612,7 @@ export default {
|
||||
})
|
||||
|
||||
// 爬虫列表
|
||||
request.get('/spiders', {})
|
||||
request.get('/spiders', { owner_type: 'all' })
|
||||
.then(response => {
|
||||
this.spiderList = response.data.data.list || []
|
||||
})
|
||||
|
||||
@@ -255,7 +255,7 @@ export default {
|
||||
await this.$store.dispatch('spider/getTaskList', this.$route.params.id)
|
||||
|
||||
// get spider list
|
||||
await this.$store.dispatch('spider/getSpiderList')
|
||||
await this.$store.dispatch('spider/getSpiderList', { owner_type: 'all' })
|
||||
},
|
||||
mounted () {
|
||||
if (!this.$utils.tour.isFinishedTour('spider-detail')) {
|
||||
|
||||
@@ -326,6 +326,18 @@
|
||||
/>
|
||||
</el-select>
|
||||
</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-input
|
||||
v-model="filter.keyword"
|
||||
@@ -578,12 +590,22 @@
|
||||
<el-table-column :label="$t('Action')" align="left" fixed="right" min-width="220px">
|
||||
<template slot-scope="scope">
|
||||
<el-tooltip :content="$t('View')" placement="top">
|
||||
<el-button type="primary" icon="el-icon-search" size="mini"
|
||||
@click="onView(scope.row, $event)"></el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-search"
|
||||
size="mini"
|
||||
:disabled="isDisabled(scope.row)"
|
||||
@click="onView(scope.row, $event)"
|
||||
/>
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="$t('Remove')" placement="top">
|
||||
<el-button type="danger" icon="el-icon-delete" size="mini"
|
||||
@click="onRemove(scope.row, $event)"></el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
icon="el-icon-delete"
|
||||
size="mini"
|
||||
:disabled="isDisabled(scope.row)"
|
||||
@click="onRemove(scope.row, $event)"
|
||||
/>
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="$t('Copy')" placement="top">
|
||||
<el-button
|
||||
@@ -594,17 +616,27 @@
|
||||
/>
|
||||
</el-tooltip>
|
||||
<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"
|
||||
@click="onCrawl(scope.row, $event)"></el-button>
|
||||
<el-button
|
||||
disabled
|
||||
type="success" icon="fa fa-bug" size="mini"
|
||||
@click="onCrawl(scope.row, $event)"
|
||||
/>
|
||||
</el-tooltip>
|
||||
<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 :content="$t('Latest Tasks')" placement="top">
|
||||
<el-button
|
||||
type="warning"
|
||||
icon="fa fa-tasks"
|
||||
size="mini"
|
||||
:disabled="isDisabled(scope.row)"
|
||||
@click="onViewRunningTasks(scope.row, $event)"
|
||||
/>
|
||||
</el-tooltip>
|
||||
@@ -664,7 +696,8 @@ export default {
|
||||
filter: {
|
||||
project_id: '',
|
||||
keyword: '',
|
||||
type: 'all'
|
||||
type: 'all',
|
||||
owner_type: 'me'
|
||||
},
|
||||
sort: {
|
||||
sortKey: '',
|
||||
@@ -816,6 +849,7 @@ export default {
|
||||
'templateList'
|
||||
]),
|
||||
...mapGetters('user', [
|
||||
'userInfo',
|
||||
'token'
|
||||
]),
|
||||
...mapState('lang', [
|
||||
@@ -846,6 +880,7 @@ export default {
|
||||
columns.push({ name: 'last_run_ts', label: 'Last Run', 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: 'username', label: 'Owner', width: '100' })
|
||||
columns.push({ name: 'remark', label: 'Remark', width: '140' })
|
||||
return columns
|
||||
},
|
||||
@@ -903,7 +938,7 @@ export default {
|
||||
return
|
||||
}
|
||||
this.$router.push(`/spiders/${res2.data.data._id}`)
|
||||
await this.$store.dispatch('spider/getSpiderList')
|
||||
this.getList()
|
||||
this.$st.sendEv('爬虫列表', '添加爬虫', '可配置爬虫')
|
||||
})
|
||||
},
|
||||
@@ -918,7 +953,7 @@ export default {
|
||||
return
|
||||
}
|
||||
this.$router.push(`/spiders/${res2.data.data._id}`)
|
||||
await this.$store.dispatch('spider/getSpiderList')
|
||||
this.getList()
|
||||
this.$st.sendEv('爬虫列表', '添加爬虫', '自定义爬虫')
|
||||
})
|
||||
},
|
||||
@@ -1095,7 +1130,8 @@ export default {
|
||||
sort_direction: this.sort.sortDirection,
|
||||
keyword: this.filter.keyword,
|
||||
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)
|
||||
|
||||
@@ -1208,6 +1244,9 @@ export default {
|
||||
onCrawlConfirmDialogClose () {
|
||||
this.crawlConfirmDialogVisible = false
|
||||
this.isMultiple = false
|
||||
},
|
||||
isDisabled (row) {
|
||||
return row.is_public && row.username !== this.userInfo.username
|
||||
}
|
||||
},
|
||||
async created () {
|
||||
|
||||
@@ -205,7 +205,8 @@ export default {
|
||||
{ name: 'wait_duration', label: 'Wait 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: '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' }
|
||||
],
|
||||
|
||||
|
||||
Reference in New Issue
Block a user