mirror of
https://github.com/crawlab-team/crawlab.git
synced 2026-01-22 17:31:03 +01:00
added virtual scroll list for log view
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
"vue-codemirror-lite": "^1.0.4",
|
||||
"vue-i18n": "^8.9.0",
|
||||
"vue-router": "^3.0.1",
|
||||
"vue-virtual-scroll-list": "^1.3.9",
|
||||
"vuex": "^3.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
<template>
|
||||
<div :class="className" :id="id" :style="{height:height,width:width}"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import echarts from 'echarts'
|
||||
import resize from './mixins/resize'
|
||||
|
||||
export default {
|
||||
mixins: [resize],
|
||||
props: {
|
||||
className: {
|
||||
type: String,
|
||||
default: 'chart'
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
default: 'chart'
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '200px'
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '200px'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
chart: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initChart()
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return
|
||||
}
|
||||
this.chart.dispose()
|
||||
this.chart = null
|
||||
},
|
||||
methods: {
|
||||
initChart() {
|
||||
this.chart = echarts.init(document.getElementById(this.id))
|
||||
|
||||
const xAxisData = []
|
||||
const data = []
|
||||
const data2 = []
|
||||
for (let i = 0; i < 50; i++) {
|
||||
xAxisData.push(i)
|
||||
data.push((Math.sin(i / 5) * (i / 5 - 10) + i / 6) * 5)
|
||||
data2.push((Math.sin(i / 5) * (i / 5 + 10) + i / 6) * 3)
|
||||
}
|
||||
this.chart.setOption(
|
||||
{
|
||||
backgroundColor: '#08263a',
|
||||
grid: {
|
||||
left: '5%',
|
||||
right: '5%'
|
||||
},
|
||||
xAxis: [{
|
||||
show: false,
|
||||
data: xAxisData
|
||||
}, {
|
||||
show: false,
|
||||
data: xAxisData
|
||||
}],
|
||||
visualMap: {
|
||||
show: false,
|
||||
min: 0,
|
||||
max: 50,
|
||||
dimension: 0,
|
||||
inRange: {
|
||||
color: ['#4a657a', '#308e92', '#b1cfa5', '#f5d69f', '#f5898b', '#ef5055']
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
color: '#4a657a'
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#08263f'
|
||||
}
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
series: [{
|
||||
name: 'back',
|
||||
type: 'bar',
|
||||
data: data2,
|
||||
z: 1,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
opacity: 0.4,
|
||||
barBorderRadius: 5,
|
||||
shadowBlur: 3,
|
||||
shadowColor: '#111'
|
||||
}
|
||||
}
|
||||
}, {
|
||||
name: 'Simulate Shadow',
|
||||
type: 'line',
|
||||
data,
|
||||
z: 2,
|
||||
showSymbol: false,
|
||||
animationDelay: 0,
|
||||
animationEasing: 'linear',
|
||||
animationDuration: 1200,
|
||||
lineStyle: {
|
||||
normal: {
|
||||
color: 'transparent'
|
||||
}
|
||||
},
|
||||
areaStyle: {
|
||||
normal: {
|
||||
color: '#08263a',
|
||||
shadowBlur: 50,
|
||||
shadowColor: '#000'
|
||||
}
|
||||
}
|
||||
}, {
|
||||
name: 'front',
|
||||
type: 'bar',
|
||||
data,
|
||||
xAxisIndex: 1,
|
||||
z: 3,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
barBorderRadius: 5
|
||||
}
|
||||
}
|
||||
}],
|
||||
animationEasing: 'elasticOut',
|
||||
animationEasingUpdate: 'elasticOut',
|
||||
animationDelay(idx) {
|
||||
return idx * 20
|
||||
},
|
||||
animationDelayUpdate(idx) {
|
||||
return idx * 20
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,227 +0,0 @@
|
||||
<template>
|
||||
<div :class="className" :id="id" :style="{height:height,width:width}"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import echarts from 'echarts'
|
||||
import resize from './mixins/resize'
|
||||
|
||||
export default {
|
||||
mixins: [resize],
|
||||
props: {
|
||||
className: {
|
||||
type: String,
|
||||
default: 'chart'
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
default: 'chart'
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '200px'
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '200px'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
chart: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initChart()
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return
|
||||
}
|
||||
this.chart.dispose()
|
||||
this.chart = null
|
||||
},
|
||||
methods: {
|
||||
initChart() {
|
||||
this.chart = echarts.init(document.getElementById(this.id))
|
||||
|
||||
this.chart.setOption({
|
||||
backgroundColor: '#394056',
|
||||
title: {
|
||||
top: 20,
|
||||
text: 'Requests',
|
||||
textStyle: {
|
||||
fontWeight: 'normal',
|
||||
fontSize: 16,
|
||||
color: '#F1F1F3'
|
||||
},
|
||||
left: '1%'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
lineStyle: {
|
||||
color: '#57617B'
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
top: 20,
|
||||
icon: 'rect',
|
||||
itemWidth: 14,
|
||||
itemHeight: 5,
|
||||
itemGap: 13,
|
||||
data: ['CMCC', 'CTCC', 'CUCC'],
|
||||
right: '4%',
|
||||
textStyle: {
|
||||
fontSize: 12,
|
||||
color: '#F1F1F3'
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
top: 100,
|
||||
left: '2%',
|
||||
right: '2%',
|
||||
bottom: '2%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: [{
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#57617B'
|
||||
}
|
||||
},
|
||||
data: ['13:00', '13:05', '13:10', '13:15', '13:20', '13:25', '13:30', '13:35', '13:40', '13:45', '13:50', '13:55']
|
||||
}],
|
||||
yAxis: [{
|
||||
type: 'value',
|
||||
name: '(%)',
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#57617B'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
margin: 10,
|
||||
textStyle: {
|
||||
fontSize: 14
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: '#57617B'
|
||||
}
|
||||
}
|
||||
}],
|
||||
series: [{
|
||||
name: 'CMCC',
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 5,
|
||||
showSymbol: false,
|
||||
lineStyle: {
|
||||
normal: {
|
||||
width: 1
|
||||
}
|
||||
},
|
||||
areaStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
|
||||
offset: 0,
|
||||
color: 'rgba(137, 189, 27, 0.3)'
|
||||
}, {
|
||||
offset: 0.8,
|
||||
color: 'rgba(137, 189, 27, 0)'
|
||||
}], false),
|
||||
shadowColor: 'rgba(0, 0, 0, 0.1)',
|
||||
shadowBlur: 10
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: 'rgb(137,189,27)',
|
||||
borderColor: 'rgba(137,189,2,0.27)',
|
||||
borderWidth: 12
|
||||
|
||||
}
|
||||
},
|
||||
data: [220, 182, 191, 134, 150, 120, 110, 125, 145, 122, 165, 122]
|
||||
}, {
|
||||
name: 'CTCC',
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 5,
|
||||
showSymbol: false,
|
||||
lineStyle: {
|
||||
normal: {
|
||||
width: 1
|
||||
}
|
||||
},
|
||||
areaStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
|
||||
offset: 0,
|
||||
color: 'rgba(0, 136, 212, 0.3)'
|
||||
}, {
|
||||
offset: 0.8,
|
||||
color: 'rgba(0, 136, 212, 0)'
|
||||
}], false),
|
||||
shadowColor: 'rgba(0, 0, 0, 0.1)',
|
||||
shadowBlur: 10
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: 'rgb(0,136,212)',
|
||||
borderColor: 'rgba(0,136,212,0.2)',
|
||||
borderWidth: 12
|
||||
|
||||
}
|
||||
},
|
||||
data: [120, 110, 125, 145, 122, 165, 122, 220, 182, 191, 134, 150]
|
||||
}, {
|
||||
name: 'CUCC',
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 5,
|
||||
showSymbol: false,
|
||||
lineStyle: {
|
||||
normal: {
|
||||
width: 1
|
||||
}
|
||||
},
|
||||
areaStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
|
||||
offset: 0,
|
||||
color: 'rgba(219, 50, 51, 0.3)'
|
||||
}, {
|
||||
offset: 0.8,
|
||||
color: 'rgba(219, 50, 51, 0)'
|
||||
}], false),
|
||||
shadowColor: 'rgba(0, 0, 0, 0.1)',
|
||||
shadowBlur: 10
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: 'rgb(219,50,51)',
|
||||
borderColor: 'rgba(219,50,51,0.2)',
|
||||
borderWidth: 12
|
||||
}
|
||||
},
|
||||
data: [220, 182, 125, 145, 122, 191, 134, 150, 120, 110, 165, 122]
|
||||
}]
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,271 +0,0 @@
|
||||
<template>
|
||||
<div :class="className" :id="id" :style="{height:height,width:width}"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import echarts from 'echarts'
|
||||
import resize from './mixins/resize'
|
||||
|
||||
export default {
|
||||
mixins: [resize],
|
||||
props: {
|
||||
className: {
|
||||
type: String,
|
||||
default: 'chart'
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
default: 'chart'
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '200px'
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '200px'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
chart: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initChart()
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return
|
||||
}
|
||||
this.chart.dispose()
|
||||
this.chart = null
|
||||
},
|
||||
methods: {
|
||||
initChart() {
|
||||
this.chart = echarts.init(document.getElementById(this.id))
|
||||
const xData = (function() {
|
||||
const data = []
|
||||
for (let i = 1; i < 13; i++) {
|
||||
data.push(i + 'month')
|
||||
}
|
||||
return data
|
||||
}())
|
||||
this.chart.setOption({
|
||||
backgroundColor: '#344b58',
|
||||
title: {
|
||||
text: 'statistics',
|
||||
x: '20',
|
||||
top: '20',
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontSize: '22'
|
||||
},
|
||||
subtextStyle: {
|
||||
color: '#90979c',
|
||||
fontSize: '16'
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: '5%',
|
||||
right: '5%',
|
||||
borderWidth: 0,
|
||||
top: 150,
|
||||
bottom: 95,
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
x: '5%',
|
||||
top: '10%',
|
||||
textStyle: {
|
||||
color: '#90979c'
|
||||
},
|
||||
data: ['female', 'male', 'average']
|
||||
},
|
||||
calculable: true,
|
||||
xAxis: [{
|
||||
type: 'category',
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#90979c'
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
splitArea: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
interval: 0
|
||||
|
||||
},
|
||||
data: xData
|
||||
}],
|
||||
yAxis: [{
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#90979c'
|
||||
}
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
interval: 0
|
||||
},
|
||||
splitArea: {
|
||||
show: false
|
||||
}
|
||||
}],
|
||||
dataZoom: [{
|
||||
show: true,
|
||||
height: 30,
|
||||
xAxisIndex: [
|
||||
0
|
||||
],
|
||||
bottom: 30,
|
||||
start: 10,
|
||||
end: 80,
|
||||
handleIcon: 'path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z',
|
||||
handleSize: '110%',
|
||||
handleStyle: {
|
||||
color: '#d3dee5'
|
||||
|
||||
},
|
||||
textStyle: {
|
||||
color: '#fff' },
|
||||
borderColor: '#90979c'
|
||||
|
||||
}, {
|
||||
type: 'inside',
|
||||
show: true,
|
||||
height: 15,
|
||||
start: 1,
|
||||
end: 35
|
||||
}],
|
||||
series: [{
|
||||
name: 'female',
|
||||
type: 'bar',
|
||||
stack: 'total',
|
||||
barMaxWidth: 35,
|
||||
barGap: '10%',
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: 'rgba(255,144,128,1)',
|
||||
label: {
|
||||
show: true,
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
},
|
||||
position: 'insideTop',
|
||||
formatter(p) {
|
||||
return p.value > 0 ? p.value : ''
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data: [
|
||||
709,
|
||||
1917,
|
||||
2455,
|
||||
2610,
|
||||
1719,
|
||||
1433,
|
||||
1544,
|
||||
3285,
|
||||
5208,
|
||||
3372,
|
||||
2484,
|
||||
4078
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
name: 'male',
|
||||
type: 'bar',
|
||||
stack: 'total',
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: 'rgba(0,191,183,1)',
|
||||
barBorderRadius: 0,
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
formatter(p) {
|
||||
return p.value > 0 ? p.value : ''
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data: [
|
||||
327,
|
||||
1776,
|
||||
507,
|
||||
1200,
|
||||
800,
|
||||
482,
|
||||
204,
|
||||
1390,
|
||||
1001,
|
||||
951,
|
||||
381,
|
||||
220
|
||||
]
|
||||
}, {
|
||||
name: 'average',
|
||||
type: 'line',
|
||||
stack: 'total',
|
||||
symbolSize: 10,
|
||||
symbol: 'circle',
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: 'rgba(252,230,48,1)',
|
||||
barBorderRadius: 0,
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
formatter(p) {
|
||||
return p.value > 0 ? p.value : ''
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data: [
|
||||
1036,
|
||||
3693,
|
||||
2962,
|
||||
3810,
|
||||
2519,
|
||||
1915,
|
||||
1748,
|
||||
4675,
|
||||
6209,
|
||||
4323,
|
||||
2865,
|
||||
4298
|
||||
]
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,32 +0,0 @@
|
||||
import { debounce } from '@/utils'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
sidebarElm: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.__resizeHandler = debounce(() => {
|
||||
if (this.chart) {
|
||||
this.chart.resize()
|
||||
}
|
||||
}, 100)
|
||||
window.addEventListener('resize', this.__resizeHandler)
|
||||
|
||||
this.sidebarElm = document.getElementsByClassName('sidebar-container')[0]
|
||||
this.sidebarElm && this.sidebarElm.addEventListener('transitionend', this.sidebarResizeHandler)
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('resize', this.__resizeHandler)
|
||||
|
||||
this.sidebarElm && this.sidebarElm.removeEventListener('transitionend', this.sidebarResizeHandler)
|
||||
},
|
||||
methods: {
|
||||
sidebarResizeHandler(e) {
|
||||
if (e.propertyName === 'width') {
|
||||
this.__resizeHandler()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
<template>
|
||||
<el-select ref="dragSelect" v-model="selectVal" v-bind="$attrs" class="drag-select" multiple v-on="$listeners">
|
||||
<slot/>
|
||||
</el-select>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Sortable from 'sortablejs'
|
||||
|
||||
export default {
|
||||
name: 'DragSelect',
|
||||
props: {
|
||||
value: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
selectVal: {
|
||||
get() {
|
||||
return [...this.value]
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('input', [...val])
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.setSort()
|
||||
},
|
||||
methods: {
|
||||
setSort() {
|
||||
const el = this.$refs.dragSelect.$el.querySelectorAll('.el-select__tags > span')[0]
|
||||
this.sortable = Sortable.create(el, {
|
||||
ghostClass: 'sortable-ghost', // Class name for the drop placeholder,
|
||||
setData: function(dataTransfer) {
|
||||
dataTransfer.setData('Text', '')
|
||||
// to avoid Firefox bug
|
||||
// Detail see : https://github.com/RubaXa/Sortable/issues/1012
|
||||
},
|
||||
onEnd: evt => {
|
||||
const targetRow = this.value.splice(evt.oldIndex, 1)[0]
|
||||
this.value.splice(evt.newIndex, 0, targetRow)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.drag-select >>> .sortable-ghost{
|
||||
opacity: .8;
|
||||
color: #fff!important;
|
||||
background: #42b983!important;
|
||||
}
|
||||
|
||||
.drag-select >>> .el-tag{
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
@@ -1,297 +0,0 @@
|
||||
<template>
|
||||
<div :ref="id" :action="url" :id="id" class="dropzone">
|
||||
<input type="file" name="file">
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Dropzone from 'dropzone'
|
||||
import 'dropzone/dist/dropzone.css'
|
||||
// import { getToken } from 'api/qiniu';
|
||||
|
||||
Dropzone.autoDiscover = false
|
||||
|
||||
export default {
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
clickable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
defaultMsg: {
|
||||
type: String,
|
||||
default: '上传图片'
|
||||
},
|
||||
acceptedFiles: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
thumbnailHeight: {
|
||||
type: Number,
|
||||
default: 200
|
||||
},
|
||||
thumbnailWidth: {
|
||||
type: Number,
|
||||
default: 200
|
||||
},
|
||||
showRemoveLink: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
maxFilesize: {
|
||||
type: Number,
|
||||
default: 2
|
||||
},
|
||||
maxFiles: {
|
||||
type: Number,
|
||||
default: 3
|
||||
},
|
||||
autoProcessQueue: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
useCustomDropzoneOptions: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
defaultImg: {
|
||||
default: '',
|
||||
type: [String, Array]
|
||||
},
|
||||
couldPaste: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dropzone: '',
|
||||
initOnce: true
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
defaultImg(val) {
|
||||
if (val.length === 0) {
|
||||
this.initOnce = false
|
||||
return
|
||||
}
|
||||
if (!this.initOnce) return
|
||||
this.initImages(val)
|
||||
this.initOnce = false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const element = document.getElementById(this.id)
|
||||
const vm = this
|
||||
this.dropzone = new Dropzone(element, {
|
||||
clickable: this.clickable,
|
||||
thumbnailWidth: this.thumbnailWidth,
|
||||
thumbnailHeight: this.thumbnailHeight,
|
||||
maxFiles: this.maxFiles,
|
||||
maxFilesize: this.maxFilesize,
|
||||
dictRemoveFile: 'Remove',
|
||||
addRemoveLinks: this.showRemoveLink,
|
||||
acceptedFiles: this.acceptedFiles,
|
||||
autoProcessQueue: this.autoProcessQueue,
|
||||
dictDefaultMessage: '<i style="margin-top: 3em;display: inline-block" class="material-icons">' + this.defaultMsg + '</i><br>Drop files here to upload',
|
||||
dictMaxFilesExceeded: '只能一个图',
|
||||
previewTemplate: '<div class="dz-preview dz-file-preview"> <div class="dz-image" style="width:' + this.thumbnailWidth + 'px;height:' + this.thumbnailHeight + 'px" ><img style="width:' + this.thumbnailWidth + 'px;height:' + this.thumbnailHeight + 'px" data-dz-thumbnail /></div> <div class="dz-details"><div class="dz-size"><span data-dz-size></span></div> <div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div> <div class="dz-error-message"><span data-dz-errormessage></span></div> <div class="dz-success-mark"> <i class="material-icons">done</i> </div> <div class="dz-error-mark"><i class="material-icons">error</i></div></div>',
|
||||
init() {
|
||||
const val = vm.defaultImg
|
||||
if (!val) return
|
||||
if (Array.isArray(val)) {
|
||||
if (val.length === 0) return
|
||||
val.map((v, i) => {
|
||||
const mockFile = { name: 'name' + i, size: 12345, url: v }
|
||||
this.options.addedfile.call(this, mockFile)
|
||||
this.options.thumbnail.call(this, mockFile, v)
|
||||
mockFile.previewElement.classList.add('dz-success')
|
||||
mockFile.previewElement.classList.add('dz-complete')
|
||||
vm.initOnce = false
|
||||
return true
|
||||
})
|
||||
} else {
|
||||
const mockFile = { name: 'name', size: 12345, url: val }
|
||||
this.options.addedfile.call(this, mockFile)
|
||||
this.options.thumbnail.call(this, mockFile, val)
|
||||
mockFile.previewElement.classList.add('dz-success')
|
||||
mockFile.previewElement.classList.add('dz-complete')
|
||||
vm.initOnce = false
|
||||
}
|
||||
},
|
||||
accept: (file, done) => {
|
||||
/* 七牛*/
|
||||
// const token = this.$store.getters.token;
|
||||
// getToken(token).then(response => {
|
||||
// file.token = response.data.qiniu_token;
|
||||
// file.key = response.data.qiniu_key;
|
||||
// file.url = response.data.qiniu_url;
|
||||
// done();
|
||||
// })
|
||||
done()
|
||||
},
|
||||
sending: (file, xhr, formData) => {
|
||||
// formData.append('token', file.token);
|
||||
// formData.append('key', file.key);
|
||||
vm.initOnce = false
|
||||
}
|
||||
})
|
||||
|
||||
if (this.couldPaste) {
|
||||
document.addEventListener('paste', this.pasteImg)
|
||||
}
|
||||
|
||||
this.dropzone.on('success', file => {
|
||||
vm.$emit('dropzone-success', file, vm.dropzone.element)
|
||||
})
|
||||
this.dropzone.on('addedfile', file => {
|
||||
vm.$emit('dropzone-fileAdded', file)
|
||||
})
|
||||
this.dropzone.on('removedfile', file => {
|
||||
vm.$emit('dropzone-removedFile', file)
|
||||
})
|
||||
this.dropzone.on('error', (file, error, xhr) => {
|
||||
vm.$emit('dropzone-error', file, error, xhr)
|
||||
})
|
||||
this.dropzone.on('successmultiple', (file, error, xhr) => {
|
||||
vm.$emit('dropzone-successmultiple', file, error, xhr)
|
||||
})
|
||||
},
|
||||
destroyed() {
|
||||
document.removeEventListener('paste', this.pasteImg)
|
||||
this.dropzone.destroy()
|
||||
},
|
||||
methods: {
|
||||
removeAllFiles() {
|
||||
this.dropzone.removeAllFiles(true)
|
||||
},
|
||||
processQueue() {
|
||||
this.dropzone.processQueue()
|
||||
},
|
||||
pasteImg(event) {
|
||||
const items = (event.clipboardData || event.originalEvent.clipboardData).items
|
||||
if (items[0].kind === 'file') {
|
||||
this.dropzone.addFile(items[0].getAsFile())
|
||||
}
|
||||
},
|
||||
initImages(val) {
|
||||
if (!val) return
|
||||
if (Array.isArray(val)) {
|
||||
val.map((v, i) => {
|
||||
const mockFile = { name: 'name' + i, size: 12345, url: v }
|
||||
this.dropzone.options.addedfile.call(this.dropzone, mockFile)
|
||||
this.dropzone.options.thumbnail.call(this.dropzone, mockFile, v)
|
||||
mockFile.previewElement.classList.add('dz-success')
|
||||
mockFile.previewElement.classList.add('dz-complete')
|
||||
return true
|
||||
})
|
||||
} else {
|
||||
const mockFile = { name: 'name', size: 12345, url: val }
|
||||
this.dropzone.options.addedfile.call(this.dropzone, mockFile)
|
||||
this.dropzone.options.thumbnail.call(this.dropzone, mockFile, val)
|
||||
mockFile.previewElement.classList.add('dz-success')
|
||||
mockFile.previewElement.classList.add('dz-complete')
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.dropzone {
|
||||
border: 2px solid #E5E5E5;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
color: #777;
|
||||
transition: background-color .2s linear;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.dropzone:hover {
|
||||
background-color: #F6F6F6;
|
||||
}
|
||||
|
||||
i {
|
||||
color: #CCC;
|
||||
}
|
||||
|
||||
.dropzone .dz-image img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.dropzone input[name='file'] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dropzone .dz-preview .dz-image {
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
.dropzone .dz-preview:hover .dz-image img {
|
||||
transform: none;
|
||||
-webkit-filter: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.dropzone .dz-preview .dz-details {
|
||||
bottom: 0px;
|
||||
top: 0px;
|
||||
color: white;
|
||||
background-color: rgba(33, 150, 243, 0.8);
|
||||
transition: opacity .2s linear;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.dropzone .dz-preview .dz-details .dz-filename span, .dropzone .dz-preview .dz-details .dz-size span {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.dropzone .dz-preview .dz-details .dz-filename:not(:hover) span {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.dropzone .dz-preview .dz-details .dz-filename:hover span {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.dropzone .dz-preview .dz-remove {
|
||||
position: absolute;
|
||||
z-index: 30;
|
||||
color: white;
|
||||
margin-left: 15px;
|
||||
padding: 10px;
|
||||
top: inherit;
|
||||
bottom: 15px;
|
||||
border: 2px white solid;
|
||||
text-decoration: none;
|
||||
text-transform: uppercase;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 800;
|
||||
letter-spacing: 1.1px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.dropzone .dz-preview:hover .dz-remove {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.dropzone .dz-preview .dz-success-mark, .dropzone .dz-preview .dz-error-mark {
|
||||
margin-left: -40px;
|
||||
margin-top: -50px;
|
||||
}
|
||||
|
||||
.dropzone .dz-preview .dz-success-mark i, .dropzone .dz-preview .dz-error-mark i {
|
||||
color: white;
|
||||
font-size: 5rem;
|
||||
}
|
||||
</style>
|
||||
39
frontend/src/components/ScrollView/LogItem.vue
Normal file
39
frontend/src/components/ScrollView/LogItem.vue
Normal file
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<div class="log-item">
|
||||
<div class="line-no">{{index}}</div>
|
||||
<div class="line-content">{{data}}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'LogItem',
|
||||
props: {
|
||||
index: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
data: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.log-item {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.log-item .line-no {
|
||||
margin-right: 10px;
|
||||
text-align: right;
|
||||
flex-basis: 40px;
|
||||
}
|
||||
|
||||
.log-item .line-content {
|
||||
display: inline-block;
|
||||
flex-basis: calc(100% - 50px);
|
||||
}
|
||||
</style>
|
||||
78
frontend/src/components/ScrollView/LogView.vue
Normal file
78
frontend/src/components/ScrollView/LogView.vue
Normal file
@@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<virtual-list
|
||||
:size="18"
|
||||
:remain="100"
|
||||
:item="item"
|
||||
:itemcount="logData.length"
|
||||
:itemprops="getItemProps"
|
||||
>
|
||||
</virtual-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LogItem from './LogItem'
|
||||
import VirtualList from 'vue-virtual-scroll-list'
|
||||
|
||||
export default {
|
||||
name: 'LogView',
|
||||
components: {
|
||||
VirtualList
|
||||
},
|
||||
props: {
|
||||
data: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
item: LogItem
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
logData () {
|
||||
return this.data.split('\n')
|
||||
.map((d, i) => {
|
||||
return {
|
||||
index: i + 1,
|
||||
data: d
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getItemProps (index) {
|
||||
const logItem = this.logData[index]
|
||||
return {
|
||||
// <item/> will render with itemProps.
|
||||
// https://vuejs.org/v2/guide/render-function.html#createElement-Arguments
|
||||
props: {
|
||||
index: logItem.index,
|
||||
data: logItem.data
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.log-view {
|
||||
min-height: 100%;
|
||||
overflow-y: scroll;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.log-view .log-line {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.log-view .log-line:nth-child(odd) {
|
||||
}
|
||||
|
||||
.log-view .log-line:nth-child(even) {
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -7,11 +7,7 @@
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('Log')" name="log">
|
||||
<el-card>
|
||||
<div class="log-view">
|
||||
<pre>
|
||||
{{taskLog}}
|
||||
</pre>
|
||||
</div>
|
||||
<log-view :data="taskLog"/>
|
||||
</el-card>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('Results')" name="results">
|
||||
@@ -37,10 +33,12 @@ import {
|
||||
} from 'vuex'
|
||||
import TaskOverview from '../../components/Overview/TaskOverview'
|
||||
import GeneralTableView from '../../components/TableView/GeneralTableView'
|
||||
import LogView from '../../components/ScrollView/LogView'
|
||||
|
||||
export default {
|
||||
name: 'TaskDetail',
|
||||
components: {
|
||||
LogView,
|
||||
GeneralTableView,
|
||||
TaskOverview
|
||||
},
|
||||
|
||||
@@ -8493,6 +8493,11 @@ vue-template-es2015-compiler@^1.6.0, vue-template-es2015-compiler@^1.8.2:
|
||||
version "1.8.2"
|
||||
resolved "http://registry.npm.taobao.org/vue-template-es2015-compiler/download/vue-template-es2015-compiler-1.8.2.tgz#dd73e80ba58bb65dd7a8aa2aeef6089cf6116f2a"
|
||||
|
||||
vue-virtual-scroll-list@^1.3.9:
|
||||
version "1.3.9"
|
||||
resolved "https://registry.npm.taobao.org/vue-virtual-scroll-list/download/vue-virtual-scroll-list-1.3.9.tgz#ba3ce6425374fb323ea83ab33daa2727117808ed"
|
||||
integrity sha1-ujzmQlN0+zI+qDqzPaonJxF4CO0=
|
||||
|
||||
vue@^2.3.3:
|
||||
version "2.6.10"
|
||||
resolved "https://registry.npm.taobao.org/vue/download/vue-2.6.10.tgz#a72b1a42a4d82a721ea438d1b6bf55e66195c637"
|
||||
|
||||
Reference in New Issue
Block a user