Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
F
fk-spider-web
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
周田
fk-spider-web
Commits
87d1de03
Commit
87d1de03
authored
Sep 18, 2025
by
yzh
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:完成了添加编辑任务接口,删除任务接口,获取任务列表接口
parent
b36709fb
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
1261 additions
and
239 deletions
+1261
-239
apiPaths.ts
src/api/apiPaths.ts
+8
-0
spiderTask.ts
src/api/spiderTask.ts
+46
-0
index.ts
src/components/Crontab/index.ts
+2
-0
Crontab.vue
src/components/Crontab/src/Crontab.vue
+841
-0
enum.ts
src/components/Delete/enum.ts
+1
-0
index.vue
src/components/Delete/index.vue
+1
-2
main.ts
src/main.ts
+16
-16
request.ts
src/utils/request.ts
+9
-2
addUserDialog.vue
src/views/os-system/components/addUserDialog.vue
+2
-3
index.vue
src/views/os-system/index.vue
+0
-1
addTaskDialog.vue
src/views/os-taskInformation/components/addTaskDialog.vue
+100
-51
deleteDialog.vue
src/views/os-taskInformation/components/deleteDialog.vue
+53
-0
enum.ts
src/views/os-taskInformation/components/enum.ts
+6
-0
taskCard.vue
src/views/os-taskInformation/components/taskCard.vue
+172
-110
index.vue
src/views/os-taskInformation/index.vue
+3
-53
vite.config.ts
vite.config.ts
+1
-1
No files found.
src/api/apiPaths.ts
View file @
87d1de03
// API路径配置文件
// 这个文件确保所有API路径在一处统一管理,方便修改
import
{
pauseJob
}
from
"./schedule"
export
const
authApi
=
{
login
:
'/auth/login'
,
logout
:
'/auth/logout'
...
...
@@ -88,4 +90,9 @@ export const spiderTaskApi = {
// 爬虫任务相关接口
taskList
:
'/schedule/getJobs'
,
taskRecord
:
'/schedule/scheduleLogs'
,
addTask
:
'/schedule/addJob'
,
deleteTask
:
'/schedule/removeJob'
,
pauseJob
:
'/schedule/pauseJob'
,
resumeJob
:
'/schedule/resumeJob'
,
jobDetail
:
'/schedule/jobDetail'
,
}
as
const
\ No newline at end of file
src/api/spiderTask.ts
View file @
87d1de03
...
...
@@ -18,4 +18,49 @@ export function getSpiderTaskList(data: UserQueryParams) {
method
:
POST
,
data
})
as
unknown
as
Promise
<
ApiResponse
>
}
// 新增/更新爬虫任务
export
function
addSpiderTask
(
data
:
UserQueryParams
)
{
return
request
({
url
:
spiderTaskApi
.
addTask
,
method
:
POST
,
data
})
as
unknown
as
Promise
<
ApiResponse
>
}
// 删除爬虫任务
export
function
deleteSpiderTask
(
data
:
UserQueryParams
)
{
return
request
({
url
:
spiderTaskApi
.
deleteTask
,
method
:
POST
,
data
})
as
unknown
as
Promise
<
ApiResponse
>
}
// 暂停爬虫任务
export
function
pauseSpiderTask
(
data
:
UserQueryParams
)
{
return
request
({
url
:
spiderTaskApi
.
pauseJob
,
method
:
POST
,
data
})
as
unknown
as
Promise
<
ApiResponse
>
}
// 继续爬虫任务
export
function
resumeSpiderTask
(
data
:
UserQueryParams
)
{
return
request
({
url
:
spiderTaskApi
.
resumeJob
,
method
:
POST
,
data
})
as
unknown
as
Promise
<
ApiResponse
>
}
// 获取爬虫任务数据
export
function
getTaskData
(
data
:
UserQueryParams
)
{
return
request
({
url
:
spiderTaskApi
.
jobDetail
,
method
:
POST
,
data
})
as
unknown
as
Promise
<
ApiResponse
>
}
\ No newline at end of file
src/components/Crontab/index.ts
0 → 100644
View file @
87d1de03
import
Crontab
from
'./src/Crontab.vue'
export
{
Crontab
}
src/components/Crontab/src/Crontab.vue
0 → 100644
View file @
87d1de03
<
script
lang=
"ts"
setup
>
import
{
ElMessage
}
from
'element-plus'
import
type
{
PropType
}
from
'vue'
import
{
ref
,
reactive
,
computed
,
watch
,
onMounted
}
from
'vue'
defineOptions
({
name
:
'Crontab'
})
interface
shortcutsType
{
text
:
string
value
:
string
}
const
props
=
defineProps
({
modelValue
:
{
type
:
String
,
default
:
'* * * * * ?'
},
shortcuts
:
{
type
:
Array
as
PropType
<
shortcutsType
[]
>
,
default
:
()
=>
[]
}
})
const
defaultValue
=
ref
(
''
)
const
dialogVisible
=
ref
(
false
)
const
getYear
=
()
=>
{
let
v
:
number
[]
=
[]
let
y
=
new
Date
().
getFullYear
()
for
(
let
i
=
0
;
i
<
11
;
i
++
)
{
v
.
push
(
y
+
i
)
}
return
v
}
const
cronValue
=
reactive
({
second
:
{
type
:
'0'
,
range
:
{
start
:
1
,
end
:
2
},
loop
:
{
start
:
0
,
end
:
1
},
appoint
:
[]
as
string
[]
},
minute
:
{
type
:
'0'
,
range
:
{
start
:
1
,
end
:
2
},
loop
:
{
start
:
0
,
end
:
1
},
appoint
:
[]
as
string
[]
},
hour
:
{
type
:
'0'
,
range
:
{
start
:
1
,
end
:
2
},
loop
:
{
start
:
0
,
end
:
1
},
appoint
:
[]
as
string
[]
},
day
:
{
type
:
'0'
,
range
:
{
start
:
1
,
end
:
2
},
loop
:
{
start
:
1
,
end
:
1
},
appoint
:
[]
as
string
[]
},
month
:
{
type
:
'0'
,
range
:
{
start
:
1
,
end
:
2
},
loop
:
{
start
:
1
,
end
:
1
},
appoint
:
[]
as
string
[]
},
week
:
{
type
:
'5'
,
range
:
{
start
:
'2'
,
end
:
'3'
},
loop
:
{
start
:
0
,
end
:
'2'
},
last
:
'2'
,
appoint
:
[]
as
string
[]
},
year
:
{
type
:
'-1'
,
range
:
{
start
:
getYear
()[
0
],
end
:
getYear
()[
1
]
},
loop
:
{
start
:
getYear
()[
0
],
end
:
1
},
appoint
:
[]
as
string
[]
}
})
const
data
=
reactive
({
second
:
[
'0'
,
'5'
,
'15'
,
'20'
,
'25'
,
'30'
,
'35'
,
'40'
,
'45'
,
'50'
,
'55'
,
'59'
],
minute
:
[
'0'
,
'5'
,
'15'
,
'20'
,
'25'
,
'30'
,
'35'
,
'40'
,
'45'
,
'50'
,
'55'
,
'59'
],
hour
:
[
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'10'
,
'11'
,
'12'
,
'13'
,
'14'
,
'15'
,
'16'
,
'17'
,
'18'
,
'19'
,
'20'
,
'21'
,
'22'
,
'23'
],
day
:
[
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'10'
,
'11'
,
'12'
,
'13'
,
'14'
,
'15'
,
'16'
,
'17'
,
'18'
,
'19'
,
'20'
,
'21'
,
'22'
,
'23'
,
'24'
,
'25'
,
'26'
,
'27'
,
'28'
,
'29'
,
'30'
,
'31'
],
month
:
[
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'10'
,
'11'
,
'12'
],
week
:
[
{
value
:
'1'
,
label
:
'周日'
},
{
value
:
'2'
,
label
:
'周一'
},
{
value
:
'3'
,
label
:
'周二'
},
{
value
:
'4'
,
label
:
'周三'
},
{
value
:
'5'
,
label
:
'周四'
},
{
value
:
'6'
,
label
:
'周五'
},
{
value
:
'7'
,
label
:
'周六'
}
],
year
:
getYear
()
})
const
value_second
=
computed
(()
=>
{
let
v
=
cronValue
.
second
if
(
v
.
type
==
'0'
)
{
return
'*'
}
else
if
(
v
.
type
==
'1'
)
{
return
v
.
range
.
start
+
'-'
+
v
.
range
.
end
}
else
if
(
v
.
type
==
'2'
)
{
return
v
.
loop
.
start
+
'/'
+
v
.
loop
.
end
}
else
if
(
v
.
type
==
'3'
)
{
return
v
.
appoint
.
length
>
0
?
v
.
appoint
.
join
(
','
)
:
'*'
}
else
{
return
'*'
}
})
const
value_minute
=
computed
(()
=>
{
let
v
=
cronValue
.
minute
if
(
v
.
type
==
'0'
)
{
return
'*'
}
else
if
(
v
.
type
==
'1'
)
{
return
v
.
range
.
start
+
'-'
+
v
.
range
.
end
}
else
if
(
v
.
type
==
'2'
)
{
return
v
.
loop
.
start
+
'/'
+
v
.
loop
.
end
}
else
if
(
v
.
type
==
'3'
)
{
return
v
.
appoint
.
length
>
0
?
v
.
appoint
.
join
(
','
)
:
'*'
}
else
{
return
'*'
}
})
const
value_hour
=
computed
(()
=>
{
let
v
=
cronValue
.
hour
if
(
v
.
type
==
'0'
)
{
return
'*'
}
else
if
(
v
.
type
==
'1'
)
{
return
v
.
range
.
start
+
'-'
+
v
.
range
.
end
}
else
if
(
v
.
type
==
'2'
)
{
return
v
.
loop
.
start
+
'/'
+
v
.
loop
.
end
}
else
if
(
v
.
type
==
'3'
)
{
return
v
.
appoint
.
length
>
0
?
v
.
appoint
.
join
(
','
)
:
'*'
}
else
{
return
'*'
}
})
const
value_day
=
computed
(()
=>
{
let
v
=
cronValue
.
day
if
(
v
.
type
==
'0'
)
{
return
'*'
}
else
if
(
v
.
type
==
'1'
)
{
return
v
.
range
.
start
+
'-'
+
v
.
range
.
end
}
else
if
(
v
.
type
==
'2'
)
{
return
v
.
loop
.
start
+
'/'
+
v
.
loop
.
end
}
else
if
(
v
.
type
==
'3'
)
{
return
v
.
appoint
.
length
>
0
?
v
.
appoint
.
join
(
','
)
:
'*'
}
else
if
(
v
.
type
==
'4'
)
{
return
'L'
}
else
if
(
v
.
type
==
'5'
)
{
return
'?'
}
else
{
return
'*'
}
})
const
value_month
=
computed
(()
=>
{
let
v
=
cronValue
.
month
if
(
v
.
type
==
'0'
)
{
return
'*'
}
else
if
(
v
.
type
==
'1'
)
{
return
v
.
range
.
start
+
'-'
+
v
.
range
.
end
}
else
if
(
v
.
type
==
'2'
)
{
return
v
.
loop
.
start
+
'/'
+
v
.
loop
.
end
}
else
if
(
v
.
type
==
'3'
)
{
return
v
.
appoint
.
length
>
0
?
v
.
appoint
.
join
(
','
)
:
'*'
}
else
{
return
'*'
}
})
const
value_week
=
computed
(()
=>
{
let
v
=
cronValue
.
week
if
(
v
.
type
==
'0'
)
{
return
'*'
}
else
if
(
v
.
type
==
'1'
)
{
return
v
.
range
.
start
+
'-'
+
v
.
range
.
end
}
else
if
(
v
.
type
==
'2'
)
{
return
v
.
loop
.
end
+
'#'
+
v
.
loop
.
start
}
else
if
(
v
.
type
==
'3'
)
{
return
v
.
appoint
.
length
>
0
?
v
.
appoint
.
join
(
','
)
:
'*'
}
else
if
(
v
.
type
==
'4'
)
{
return
v
.
last
+
'L'
}
else
if
(
v
.
type
==
'5'
)
{
return
'?'
}
else
{
return
'*'
}
})
const
value_year
=
computed
(()
=>
{
let
v
=
cronValue
.
year
if
(
v
.
type
==
'-1'
)
{
return
''
}
else
if
(
v
.
type
==
'0'
)
{
return
'*'
}
else
if
(
v
.
type
==
'1'
)
{
return
v
.
range
.
start
+
'-'
+
v
.
range
.
end
}
else
if
(
v
.
type
==
'2'
)
{
return
v
.
loop
.
start
+
'/'
+
v
.
loop
.
end
}
else
if
(
v
.
type
==
'3'
)
{
return
v
.
appoint
.
length
>
0
?
v
.
appoint
.
join
(
','
)
:
''
}
else
{
return
''
}
})
watch
(
()
=>
cronValue
.
week
.
type
,
(
val
)
=>
{
if
(
val
!=
'5'
)
{
cronValue
.
day
.
type
=
'5'
}
}
)
watch
(
()
=>
cronValue
.
day
.
type
,
(
val
)
=>
{
if
(
val
!=
'5'
)
{
cronValue
.
week
.
type
=
'5'
}
}
)
watch
(
()
=>
props
.
modelValue
,
()
=>
{
defaultValue
.
value
=
props
.
modelValue
}
)
onMounted
(()
=>
{
defaultValue
.
value
=
props
.
modelValue
})
const
emit
=
defineEmits
([
'update:modelValue'
])
const
select
=
ref
()
watch
(
()
=>
select
.
value
,
()
=>
{
if
(
select
.
value
==
'custom'
)
{
open
()
}
else
{
defaultValue
.
value
=
select
.
value
emit
(
'update:modelValue'
,
defaultValue
.
value
)
}
}
)
const
open
=
()
=>
{
set
()
dialogVisible
.
value
=
true
}
const
set
=
()
=>
{
defaultValue
.
value
=
props
.
modelValue
let
arr
=
(
props
.
modelValue
||
'* * * * * ?'
).
split
(
' '
)
//简单检查
if
(
arr
.
length
<
6
)
{
ElMessage
.
warning
(
'cron表达式错误,已转换为默认表达式'
)
arr
=
'* * * * * ?'
.
split
(
' '
)
}
//秒
if
(
arr
[
0
]
==
'*'
)
{
cronValue
.
second
.
type
=
'0'
}
else
if
(
arr
[
0
].
includes
(
'-'
))
{
cronValue
.
second
.
type
=
'1'
cronValue
.
second
.
range
.
start
=
Number
(
arr
[
0
].
split
(
'-'
)[
0
])
cronValue
.
second
.
range
.
end
=
Number
(
arr
[
0
].
split
(
'-'
)[
1
])
}
else
if
(
arr
[
0
].
includes
(
'/'
))
{
cronValue
.
second
.
type
=
'2'
cronValue
.
second
.
loop
.
start
=
Number
(
arr
[
0
].
split
(
'/'
)[
0
])
cronValue
.
second
.
loop
.
end
=
Number
(
arr
[
0
].
split
(
'/'
)[
1
])
}
else
{
cronValue
.
second
.
type
=
'3'
cronValue
.
second
.
appoint
=
arr
[
0
].
split
(
','
)
}
//分
if
(
arr
[
1
]
==
'*'
)
{
cronValue
.
minute
.
type
=
'0'
}
else
if
(
arr
[
1
].
includes
(
'-'
))
{
cronValue
.
minute
.
type
=
'1'
cronValue
.
minute
.
range
.
start
=
Number
(
arr
[
1
].
split
(
'-'
)[
0
])
cronValue
.
minute
.
range
.
end
=
Number
(
arr
[
1
].
split
(
'-'
)[
1
])
}
else
if
(
arr
[
1
].
includes
(
'/'
))
{
cronValue
.
minute
.
type
=
'2'
cronValue
.
minute
.
loop
.
start
=
Number
(
arr
[
1
].
split
(
'/'
)[
0
])
cronValue
.
minute
.
loop
.
end
=
Number
(
arr
[
1
].
split
(
'/'
)[
1
])
}
else
{
cronValue
.
minute
.
type
=
'3'
cronValue
.
minute
.
appoint
=
arr
[
1
].
split
(
','
)
}
//小时
if
(
arr
[
2
]
==
'*'
)
{
cronValue
.
hour
.
type
=
'0'
}
else
if
(
arr
[
2
].
includes
(
'-'
))
{
cronValue
.
hour
.
type
=
'1'
cronValue
.
hour
.
range
.
start
=
Number
(
arr
[
2
].
split
(
'-'
)[
0
])
cronValue
.
hour
.
range
.
end
=
Number
(
arr
[
2
].
split
(
'-'
)[
1
])
}
else
if
(
arr
[
2
].
includes
(
'/'
))
{
cronValue
.
hour
.
type
=
'2'
cronValue
.
hour
.
loop
.
start
=
Number
(
arr
[
2
].
split
(
'/'
)[
0
])
cronValue
.
hour
.
loop
.
end
=
Number
(
arr
[
2
].
split
(
'/'
)[
1
])
}
else
{
cronValue
.
hour
.
type
=
'3'
cronValue
.
hour
.
appoint
=
arr
[
2
].
split
(
','
)
}
//日
if
(
arr
[
3
]
==
'*'
)
{
cronValue
.
day
.
type
=
'0'
}
else
if
(
arr
[
3
]
==
'L'
)
{
cronValue
.
day
.
type
=
'4'
}
else
if
(
arr
[
3
]
==
'?'
)
{
cronValue
.
day
.
type
=
'5'
}
else
if
(
arr
[
3
].
includes
(
'-'
))
{
cronValue
.
day
.
type
=
'1'
cronValue
.
day
.
range
.
start
=
Number
(
arr
[
3
].
split
(
'-'
)[
0
])
cronValue
.
day
.
range
.
end
=
Number
(
arr
[
3
].
split
(
'-'
)[
1
])
}
else
if
(
arr
[
3
].
includes
(
'/'
))
{
cronValue
.
day
.
type
=
'2'
cronValue
.
day
.
loop
.
start
=
Number
(
arr
[
3
].
split
(
'/'
)[
0
])
cronValue
.
day
.
loop
.
end
=
Number
(
arr
[
3
].
split
(
'/'
)[
1
])
}
else
{
cronValue
.
day
.
type
=
'3'
cronValue
.
day
.
appoint
=
arr
[
3
].
split
(
','
)
}
//月
if
(
arr
[
4
]
==
'*'
)
{
cronValue
.
month
.
type
=
'0'
}
else
if
(
arr
[
4
].
includes
(
'-'
))
{
cronValue
.
month
.
type
=
'1'
cronValue
.
month
.
range
.
start
=
Number
(
arr
[
4
].
split
(
'-'
)[
0
])
cronValue
.
month
.
range
.
end
=
Number
(
arr
[
4
].
split
(
'-'
)[
1
])
}
else
if
(
arr
[
4
].
includes
(
'/'
))
{
cronValue
.
month
.
type
=
'2'
cronValue
.
month
.
loop
.
start
=
Number
(
arr
[
4
].
split
(
'/'
)[
0
])
cronValue
.
month
.
loop
.
end
=
Number
(
arr
[
4
].
split
(
'/'
)[
1
])
}
else
{
cronValue
.
month
.
type
=
'3'
cronValue
.
month
.
appoint
=
arr
[
4
].
split
(
','
)
}
//周
if
(
arr
[
5
]
==
'*'
)
{
cronValue
.
week
.
type
=
'0'
}
else
if
(
arr
[
5
]
==
'?'
)
{
cronValue
.
week
.
type
=
'5'
}
else
if
(
arr
[
5
].
includes
(
'-'
))
{
cronValue
.
week
.
type
=
'1'
cronValue
.
week
.
range
.
start
=
arr
[
5
].
split
(
'-'
)[
0
]
cronValue
.
week
.
range
.
end
=
arr
[
5
].
split
(
'-'
)[
1
]
}
else
if
(
arr
[
5
].
includes
(
'#'
))
{
cronValue
.
week
.
type
=
'2'
cronValue
.
week
.
loop
.
start
=
Number
(
arr
[
5
].
split
(
'#'
)[
1
])
cronValue
.
week
.
loop
.
end
=
arr
[
5
].
split
(
'#'
)[
0
]
}
else
if
(
arr
[
5
].
includes
(
'L'
))
{
cronValue
.
week
.
type
=
'4'
cronValue
.
week
.
last
=
arr
[
5
].
split
(
'L'
)[
0
]
}
else
{
cronValue
.
week
.
type
=
'3'
cronValue
.
week
.
appoint
=
arr
[
5
].
split
(
','
)
}
//年
if
(
!
arr
[
6
])
{
cronValue
.
year
.
type
=
'-1'
}
else
if
(
arr
[
6
]
==
'*'
)
{
cronValue
.
year
.
type
=
'0'
}
else
if
(
arr
[
6
].
includes
(
'-'
))
{
cronValue
.
year
.
type
=
'1'
cronValue
.
year
.
range
.
start
=
Number
(
arr
[
6
].
split
(
'-'
)[
0
])
cronValue
.
year
.
range
.
end
=
Number
(
arr
[
6
].
split
(
'-'
)[
1
])
}
else
if
(
arr
[
6
].
includes
(
'/'
))
{
cronValue
.
year
.
type
=
'2'
cronValue
.
year
.
loop
.
start
=
Number
(
arr
[
6
].
split
(
'/'
)[
1
])
cronValue
.
year
.
loop
.
end
=
Number
(
arr
[
6
].
split
(
'/'
)[
0
])
}
else
{
cronValue
.
year
.
type
=
'3'
cronValue
.
year
.
appoint
=
arr
[
6
].
split
(
','
)
}
}
const
submit
=
()
=>
{
let
year
=
value_year
.
value
?
' '
+
value_year
.
value
:
''
defaultValue
.
value
=
value_second
.
value
+
' '
+
value_minute
.
value
+
' '
+
value_hour
.
value
+
' '
+
value_day
.
value
+
' '
+
value_month
.
value
+
' '
+
value_week
.
value
+
year
emit
(
'update:modelValue'
,
defaultValue
.
value
)
dialogVisible
.
value
=
false
}
const
inputChange
=
()
=>
{
emit
(
'update:modelValue'
,
defaultValue
.
value
)
}
</
script
>
<
template
>
<el-input
v-model=
"defaultValue"
class=
"input-with-select"
v-bind=
"$attrs"
@
input=
"inputChange"
>
<template
#
append
>
<el-select
v-model=
"select"
placeholder=
"生成器"
style=
"width: 115px"
>
<el-option
label=
"每分钟"
value=
"0 * * * * ?"
/>
<el-option
label=
"每小时"
value=
"0 0 * * * ?"
/>
<el-option
label=
"每天零点"
value=
"0 0 0 * * ?"
/>
<el-option
label=
"每月一号零点"
value=
"0 0 0 1 * ?"
/>
<el-option
label=
"每月最后一天零点"
value=
"0 0 0 L * ?"
/>
<el-option
label=
"每周星期日零点"
value=
"0 0 0 ? * 1"
/>
<el-option
v-for=
"(item, index) in shortcuts"
:key=
"index"
:label=
"item.text"
:value=
"item.value"
/>
<el-option
label=
"自定义"
value=
"custom"
/>
</el-select>
</
template
>
</el-input>
<el-dialog
v-model=
"dialogVisible"
:width=
"580"
append-to-body
destroy-on-close
title=
"cron规则生成器"
>
<div
class=
"sc-cron"
>
<el-tabs>
<el-tab-pane>
<
template
#
label
>
<div
class=
"sc-cron-num"
>
<h2>
秒
</h2>
<h4>
{{
value_second
}}
</h4>
</div>
</
template
>
<el-form>
<el-form-item
label=
"类型"
>
<el-radio-group
v-model=
"cronValue.second.type"
>
<el-radio-button
value=
"0"
>
任意值
</el-radio-button>
<el-radio-button
value=
"1"
>
范围
</el-radio-button>
<el-radio-button
value=
"2"
>
间隔
</el-radio-button>
<el-radio-button
value=
"3"
>
指定
</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item
v-if=
"cronValue.second.type == '1'"
label=
"范围"
>
<el-input-number
v-model=
"cronValue.second.range.start"
:max=
"59"
:min=
"0"
controls-position=
"right"
/>
<span
style=
"padding: 0 15px"
>
-
</span>
<el-input-number
v-model=
"cronValue.second.range.end"
:max=
"59"
:min=
"0"
controls-position=
"right"
/>
</el-form-item>
<el-form-item
v-if=
"cronValue.second.type == '2'"
label=
"间隔"
>
<el-input-number
v-model=
"cronValue.second.loop.start"
:max=
"59"
:min=
"0"
controls-position=
"right"
/>
秒开始,每
<el-input-number
v-model=
"cronValue.second.loop.end"
:max=
"59"
:min=
"0"
controls-position=
"right"
/>
秒执行一次
</el-form-item>
<el-form-item
v-if=
"cronValue.second.type == '3'"
label=
"指定"
>
<el-select
v-model=
"cronValue.second.appoint"
multiple
style=
"width: 100%"
>
<el-option
v-for=
"(item, index) in data.second"
:key=
"index"
:label=
"item"
:value=
"item"
/>
</el-select>
</el-form-item>
</el-form>
</el-tab-pane>
<el-tab-pane>
<
template
#
label
>
<div
class=
"sc-cron-num"
>
<h2>
分钟
</h2>
<h4>
{{
value_minute
}}
</h4>
</div>
</
template
>
<el-form>
<el-form-item
label=
"类型"
>
<el-radio-group
v-model=
"cronValue.minute.type"
>
<el-radio-button
value=
"0"
>
任意值
</el-radio-button>
<el-radio-button
value=
"1"
>
范围
</el-radio-button>
<el-radio-button
value=
"2"
>
间隔
</el-radio-button>
<el-radio-button
value=
"3"
>
指定
</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item
v-if=
"cronValue.minute.type == '1'"
label=
"范围"
>
<el-input-number
v-model=
"cronValue.minute.range.start"
:max=
"59"
:min=
"0"
controls-position=
"right"
/>
<span
style=
"padding: 0 15px"
>
-
</span>
<el-input-number
v-model=
"cronValue.minute.range.end"
:max=
"59"
:min=
"0"
controls-position=
"right"
/>
</el-form-item>
<el-form-item
v-if=
"cronValue.minute.type == '2'"
label=
"间隔"
>
<el-input-number
v-model=
"cronValue.minute.loop.start"
:max=
"59"
:min=
"0"
controls-position=
"right"
/>
分钟开始,每
<el-input-number
v-model=
"cronValue.minute.loop.end"
:max=
"59"
:min=
"0"
controls-position=
"right"
/>
分钟执行一次
</el-form-item>
<el-form-item
v-if=
"cronValue.minute.type == '3'"
label=
"指定"
>
<el-select
v-model=
"cronValue.minute.appoint"
multiple
style=
"width: 100%"
>
<el-option
v-for=
"(item, index) in data.minute"
:key=
"index"
:label=
"item"
:value=
"item"
/>
</el-select>
</el-form-item>
</el-form>
</el-tab-pane>
<el-tab-pane>
<
template
#
label
>
<div
class=
"sc-cron-num"
>
<h2>
小时
</h2>
<h4>
{{
value_hour
}}
</h4>
</div>
</
template
>
<el-form>
<el-form-item
label=
"类型"
>
<el-radio-group
v-model=
"cronValue.hour.type"
>
<el-radio-button
value=
"0"
>
任意值
</el-radio-button>
<el-radio-button
value=
"1"
>
范围
</el-radio-button>
<el-radio-button
value=
"2"
>
间隔
</el-radio-button>
<el-radio-button
value=
"3"
>
指定
</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item
v-if=
"cronValue.hour.type == '1'"
label=
"范围"
>
<el-input-number
v-model=
"cronValue.hour.range.start"
:max=
"23"
:min=
"0"
controls-position=
"right"
/>
<span
style=
"padding: 0 15px"
>
-
</span>
<el-input-number
v-model=
"cronValue.hour.range.end"
:max=
"23"
:min=
"0"
controls-position=
"right"
/>
</el-form-item>
<el-form-item
v-if=
"cronValue.hour.type == '2'"
label=
"间隔"
>
<el-input-number
v-model=
"cronValue.hour.loop.start"
:max=
"23"
:min=
"0"
controls-position=
"right"
/>
小时开始,每
<el-input-number
v-model=
"cronValue.hour.loop.end"
:max=
"23"
:min=
"0"
controls-position=
"right"
/>
小时执行一次
</el-form-item>
<el-form-item
v-if=
"cronValue.hour.type == '3'"
label=
"指定"
>
<el-select
v-model=
"cronValue.hour.appoint"
multiple
style=
"width: 100%"
>
<el-option
v-for=
"(item, index) in data.hour"
:key=
"index"
:label=
"item"
:value=
"item"
/>
</el-select>
</el-form-item>
</el-form>
</el-tab-pane>
<el-tab-pane>
<
template
#
label
>
<div
class=
"sc-cron-num"
>
<h2>
日
</h2>
<h4>
{{
value_day
}}
</h4>
</div>
</
template
>
<el-form>
<el-form-item
label=
"类型"
>
<el-radio-group
v-model=
"cronValue.day.type"
>
<el-radio-button
value=
"0"
>
任意值
</el-radio-button>
<el-radio-button
value=
"1"
>
范围
</el-radio-button>
<el-radio-button
value=
"2"
>
间隔
</el-radio-button>
<el-radio-button
value=
"3"
>
指定
</el-radio-button>
<el-radio-button
value=
"4"
>
本月最后一天
</el-radio-button>
<el-radio-button
value=
"5"
>
不指定
</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item
v-if=
"cronValue.day.type == '1'"
label=
"范围"
>
<el-input-number
v-model=
"cronValue.day.range.start"
:max=
"31"
:min=
"1"
controls-position=
"right"
/>
<span
style=
"padding: 0 15px"
>
-
</span>
<el-input-number
v-model=
"cronValue.day.range.end"
:max=
"31"
:min=
"1"
controls-position=
"right"
/>
</el-form-item>
<el-form-item
v-if=
"cronValue.day.type == '2'"
label=
"间隔"
>
<el-input-number
v-model=
"cronValue.day.loop.start"
:max=
"31"
:min=
"1"
controls-position=
"right"
/>
号开始,每
<el-input-number
v-model=
"cronValue.day.loop.end"
:max=
"31"
:min=
"1"
controls-position=
"right"
/>
天执行一次
</el-form-item>
<el-form-item
v-if=
"cronValue.day.type == '3'"
label=
"指定"
>
<el-select
v-model=
"cronValue.day.appoint"
multiple
style=
"width: 100%"
>
<el-option
v-for=
"(item, index) in data.day"
:key=
"index"
:label=
"item"
:value=
"item"
/>
</el-select>
</el-form-item>
</el-form>
</el-tab-pane>
<el-tab-pane>
<
template
#
label
>
<div
class=
"sc-cron-num"
>
<h2>
月
</h2>
<h4>
{{
value_month
}}
</h4>
</div>
</
template
>
<el-form>
<el-form-item
label=
"类型"
>
<el-radio-group
v-model=
"cronValue.month.type"
>
<el-radio-button
value=
"0"
>
任意值
</el-radio-button>
<el-radio-button
value=
"1"
>
范围
</el-radio-button>
<el-radio-button
value=
"2"
>
间隔
</el-radio-button>
<el-radio-button
value=
"3"
>
指定
</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item
v-if=
"cronValue.month.type == '1'"
label=
"范围"
>
<el-input-number
v-model=
"cronValue.month.range.start"
:max=
"12"
:min=
"1"
controls-position=
"right"
/>
<span
style=
"padding: 0 15px"
>
-
</span>
<el-input-number
v-model=
"cronValue.month.range.end"
:max=
"12"
:min=
"1"
controls-position=
"right"
/>
</el-form-item>
<el-form-item
v-if=
"cronValue.month.type == '2'"
label=
"间隔"
>
<el-input-number
v-model=
"cronValue.month.loop.start"
:max=
"12"
:min=
"1"
controls-position=
"right"
/>
月开始,每
<el-input-number
v-model=
"cronValue.month.loop.end"
:max=
"12"
:min=
"1"
controls-position=
"right"
/>
月执行一次
</el-form-item>
<el-form-item
v-if=
"cronValue.month.type == '3'"
label=
"指定"
>
<el-select
v-model=
"cronValue.month.appoint"
multiple
style=
"width: 100%"
>
<el-option
v-for=
"(item, index) in data.month"
:key=
"index"
:label=
"item"
:value=
"item"
/>
</el-select>
</el-form-item>
</el-form>
</el-tab-pane>
<el-tab-pane>
<
template
#
label
>
<div
class=
"sc-cron-num"
>
<h2>
周
</h2>
<h4>
{{
value_week
}}
</h4>
</div>
</
template
>
<el-form>
<el-form>
<el-form-item
label=
"类型"
>
<el-radio-group
v-model=
"cronValue.week.type"
>
<el-radio-button
value=
"0"
>
任意值
</el-radio-button>
<el-radio-button
value=
"1"
>
范围
</el-radio-button>
<el-radio-button
value=
"2"
>
间隔
</el-radio-button>
<el-radio-button
value=
"3"
>
指定
</el-radio-button>
<el-radio-button
value=
"4"
>
本月最后一周
</el-radio-button>
<el-radio-button
value=
"5"
>
不指定
</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item
v-if=
"cronValue.week.type == '1'"
label=
"范围"
>
<el-select
v-model=
"cronValue.week.range.start"
>
<el-option
v-for=
"(item, index) in data.week"
:key=
"index"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
<span
style=
"padding: 0 15px"
>
-
</span>
<el-select
v-model=
"cronValue.week.range.end"
>
<el-option
v-for=
"(item, index) in data.week"
:key=
"index"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</el-form-item>
<el-form-item
v-if=
"cronValue.week.type == '2'"
label=
"间隔"
>
第
<el-input-number
v-model=
"cronValue.week.loop.start"
:max=
"4"
:min=
"1"
controls-position=
"right"
/>
周的星期
<el-select
v-model=
"cronValue.week.loop.end"
>
<el-option
v-for=
"(item, index) in data.week"
:key=
"index"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
执行一次
</el-form-item>
<el-form-item
v-if=
"cronValue.week.type == '3'"
label=
"指定"
>
<el-select
v-model=
"cronValue.week.appoint"
multiple
style=
"width: 100%"
>
<el-option
v-for=
"(item, index) in data.week"
:key=
"index"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</el-form-item>
<el-form-item
v-if=
"cronValue.week.type == '4'"
label=
"最后一周"
>
<el-select
v-model=
"cronValue.week.last"
>
<el-option
v-for=
"(item, index) in data.week"
:key=
"index"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</el-form-item>
</el-form>
</el-form>
</el-tab-pane>
<el-tab-pane>
<
template
#
label
>
<div
class=
"sc-cron-num"
>
<h2>
年
</h2>
<h4>
{{
value_year
}}
</h4>
</div>
</
template
>
<el-form>
<el-form-item
label=
"类型"
>
<el-radio-group
v-model=
"cronValue.year.type"
>
<el-radio-button
value=
"-1"
>
忽略
</el-radio-button>
<el-radio-button
value=
"0"
>
任意值
</el-radio-button>
<el-radio-button
value=
"1"
>
范围
</el-radio-button>
<el-radio-button
value=
"2"
>
间隔
</el-radio-button>
<el-radio-button
value=
"3"
>
指定
</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item
v-if=
"cronValue.year.type == '1'"
label=
"范围"
>
<el-input-number
v-model=
"cronValue.year.range.start"
controls-position=
"right"
/>
<span
style=
"padding: 0 15px"
>
-
</span>
<el-input-number
v-model=
"cronValue.year.range.end"
controls-position=
"right"
/>
</el-form-item>
<el-form-item
v-if=
"cronValue.year.type == '2'"
label=
"间隔"
>
<el-input-number
v-model=
"cronValue.year.loop.start"
controls-position=
"right"
/>
年开始,每
<el-input-number
v-model=
"cronValue.year.loop.end"
:min=
"1"
controls-position=
"right"
/>
年执行一次
</el-form-item>
<el-form-item
v-if=
"cronValue.year.type == '3'"
label=
"指定"
>
<el-select
v-model=
"cronValue.year.appoint"
multiple
style=
"width: 100%"
>
<el-option
v-for=
"(item, index) in data.year"
:key=
"index"
:label=
"item"
:value=
"item"
/>
</el-select>
</el-form-item>
</el-form>
</el-tab-pane>
</el-tabs>
</div>
<
template
#
footer
>
<el-button
@
click=
"dialogVisible = false"
>
取 消
</el-button>
<el-button
type=
"primary"
@
click=
"submit()"
>
确 认
</el-button>
</
template
>
</el-dialog>
</template>
<
style
scoped
>
.sc-cron
:deep
(
.el-tabs__item
)
{
height
:
auto
;
padding
:
0
7px
;
line-height
:
1
;
vertical-align
:
bottom
;
}
.sc-cron-num
{
width
:
100%
;
margin-bottom
:
15px
;
text-align
:
center
;
}
.sc-cron-num
h2
{
margin-bottom
:
15px
;
font-size
:
12px
;
font-weight
:
normal
;
}
.sc-cron-num
h4
{
display
:
block
;
width
:
100%
;
height
:
32px
;
padding
:
0
15px
;
font-size
:
12px
;
line-height
:
30px
;
background
:
var
(
--el-color-primary-light-9
);
border-radius
:
4px
;
}
.sc-cron
:deep
(
.el-tabs__item.is-active
)
.sc-cron-num
h4
{
color
:
#fff
;
background
:
var
(
--el-color-primary
);
}
[
data-theme
=
'dark'
]
.sc-cron-num
h4
{
background
:
var
(
--el-color-white
);
}
.input-with-select
.el-input-group__prepend
{
background-color
:
var
(
--el-fill-color-blank
);
}
</
style
>
src/components/Delete/enum.ts
View file @
87d1de03
...
...
@@ -3,5 +3,6 @@
export
enum
DeleteMode
{
BATCH_DELETE
=
0
,
SINGLE_DELETE
=
1
,
JOB_DELETE
=
2
,
}
src/components/Delete/index.vue
View file @
87d1de03
...
...
@@ -23,7 +23,7 @@ interface deleteDialogPropType {
dialogVisible
:
boolean
,
deleteMode
:
DeleteMode
,
id
:
number
,
ids
:
number
[]
ids
:
number
[]
,
}
const
props
=
defineProps
<
deleteDialogPropType
>
()
const
emit
=
defineEmits
([
'update:dialogVisible'
,
'confirm'
,
'getUserList'
,
'update:deleteMode'
])
...
...
@@ -35,7 +35,6 @@ const handleDelelte = async () => {
await
deleteUser
({
id
:
props
.
id
})
emit
(
'getUserList'
)
deleteDialogVisible
.
value
=
false
}
else
if
(
props
.
deleteMode
==
DeleteMode
.
BATCH_DELETE
)
{
console
.
log
(
props
.
ids
);
...
...
src/main.ts
View file @
87d1de03
...
...
@@ -5,22 +5,22 @@ import router from './router'
import
pinia
from
'./store'
import
ElementPlus
from
'element-plus'
import
'element-plus/dist/index.css'
import
{
UserFilled
,
Lock
,
View
,
Hide
,
CaretBottom
,
HomeFilled
,
Menu
,
Document
,
Tickets
,
List
,
Folder
,
Files
,
Loading
,
VideoPlay
,
Refresh
,
import
{
UserFilled
,
Lock
,
View
,
Hide
,
CaretBottom
,
HomeFilled
,
Menu
,
Document
,
Tickets
,
List
,
Folder
,
Files
,
Loading
,
VideoPlay
,
Refresh
,
Back
,
Upload
,
Plus
,
...
...
src/utils/request.ts
View file @
87d1de03
...
...
@@ -111,6 +111,12 @@ export interface UserQueryParams {
ids
?:
any
scrapydServerId
?:
string
project
?:
string
spiders
?:
any
times
?:
any
spiders
?:
any
times
?:
any
job_id
?:
string
scrapyd_server_id
?:
string
schedule_type
?:
string
spider
?:
string
cron
?:
string
options
?:
string
}
\ No newline at end of file
src/views/os-system/components/addUserDialog.vue
View file @
87d1de03
...
...
@@ -157,12 +157,11 @@ const handleConfirm = async () => {
if
(
!
firstRuleFormRef
.
value
)
{
return
;
}
//
3.
使用Promise形式的validate(不传入回调),确保await生效
// 使用Promise形式的validate(不传入回调),确保await生效
const
valid
=
await
firstRuleFormRef
.
value
.
validate
();
if
(
valid
)
{
// 进入这里即197行附近逻辑
await
addUser
({
nickname
:
firstForm
.
value
.
userName
,
// 注意:根据实际接口字段调整
nickname
:
firstForm
.
value
.
userName
,
username
:
firstForm
.
value
.
userAccount
,
password
:
firstForm
.
value
.
userPassword
,
role
:
userRoleValue
.
value
,
...
...
src/views/os-system/index.vue
View file @
87d1de03
...
...
@@ -37,7 +37,6 @@
<deleteDialog
v-model:dialogVisible=
"showDeleteDialog"
@
get-user-list=
"getUserListData"
:ids=
"userIds"
:deleteMode=
"deleteMode"
:id=
"userId"
/>
<!-- 创建用户弹窗组件 -->
<!-- todo -->
<addUserDialog
v-model:dialogVisible=
"dialogVisible"
:mode=
"mode"
:nickName=
"nickName"
:userName=
"userName"
:id=
"userId"
:userRole=
"userRole"
:userStatus=
"userStatus"
:userPassword=
"userPassword"
@
get-user-list=
"getUserListData"
/>
...
...
src/views/os-taskInformation/components/addTaskDialog.vue
View file @
87d1de03
<
template
>
<el-dialog
v-model=
"currentVisible"
:title=
"currentMode ===
'1' ? '新增' : '修改'"
width=
"610"
center
align-
center
@
close=
"handleClose"
draggable
>
<el-form
:inline=
"true"
v-if=
"currentMode ===
'1'
"
>
<el-dialog
v-model=
"currentVisible"
:title=
"currentMode ===
AddMode.ADD_TASK ? '新增' : '修改'"
width=
"610"
center
align-center
@
close=
"handleClose"
draggable
>
<el-form
:inline=
"true"
v-if=
"currentMode ===
AddMode.ADD_TASK
"
>
<el-form-item
label=
"任务名称:"
>
<el-input
v-model=
"taskName"
placeholder=
"请输入任务名称"
/>
</el-form-item>
<el-form-item
label=
"执行时间:"
>
<el-input
v-model=
"taskFrequency"
placeholder=
"请输入执行时间"
/>
</el-form-item>
</el-form>
<div
class=
"m-t-4"
/>
<el-form
:inline=
"true"
>
<el-form-item
label=
"所属爬虫:"
>
<el-select
v-model=
"spiderTypeValue"
placeholder=
"请选择
爬虫类型
"
style=
"width: 181px"
>
<el-select
v-model=
"spiderTypeValue"
placeholder=
"请选择
所属爬虫
"
style=
"width: 181px"
>
<el-option
v-for=
"item in spiderTypeOptions"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"执行频率:"
>
<
el-input
v-model=
"taskFrequency"
placeholder=
"请输入执行频率
"
/>
<el-form-item
label=
"执行频率
(秒/次)
:"
>
<
Crontab
v-model=
"cronExpression"
style=
"width: 250px;
"
/>
</el-form-item>
</el-form>
<div
class=
"m-t-4"
/>
<el-form
:inline=
"true"
>
<el-form-item
label=
"启用/停止:"
>
<el-form
v-if=
"currentMode === AddMode.UPDATE_TASK"
>
<el-form-item
label=
"执行频率(秒/次):"
>
<Crontab
v-model=
"cronExpression"
/>
</el-form-item>
<!--
<el-form-item
label=
"启用/停止:"
v-if=
"currentMode === AddMode.UPDATE_TASK"
>
<el-switch
v-model=
"taskSwitchValue"
class=
"ml-2"
style=
"--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
/>
</el-form-item>
</el-form-item>
-->
</el-form>
<template
#
footer
>
<div
class=
"dialog-footer"
>
...
...
@@ -35,69 +31,96 @@
</el-button>
</div>
</
template
>
</el-dialog>
</template>
<
script
lang=
"ts"
setup
>
import
{
ref
}
from
'vue'
import
{
onMounted
,
ref
}
from
'vue'
import
{
defineProps
}
from
'vue'
;
import
{
watch
}
from
'vue'
import
{
addSpiderTask
}
from
'@/api/spiderTask'
import
{
AddMode
}
from
'./enum'
import
{
Crontab
}
from
'@/components/Crontab/index'
interface
addDialogPropType
{
dialogVisible
:
boolean
,
mode
:
AddMode
,
jobId
:
string
,
cron
:
string
,
spiderType
:
string
,
options
:
string
,
// frequency: string,
// taskStatus: boolean
}
const
props
=
defineProps
<
addDialogPropType
>
()
const
props
=
defineProps
({
dialogVisible
:
{
type
:
Boolean
,
default
:
false
},
mode
:
{
type
:
String
,
default
:
'1'
},
spiderType
:
{
type
:
String
,
default
:
''
},
frequency
:
{
type
:
String
,
default
:
''
},
taskStatus
:
{
type
:
Boolean
,
default
:
false
}
})
// 向父组件传递dialog值
const
emit
=
defineEmits
([
'update:dialogVisible'
,
'confirm'
])
const
emit
=
defineEmits
([
'update:dialogVisible'
,
'confirm'
,
'update:mode'
,
'getTaskList'
])
// 组件的状态
const
currentVisible
=
ref
(
props
.
dialogVisible
)
const
currentMode
=
ref
(
props
.
mode
)
const
taskName
=
ref
(
''
)
const
taskFrequency
=
ref
(
''
)
const
taskTime
=
ref
(
''
)
const
taskSwitchValue
=
ref
(
false
)
const
spiderTypeValue
=
ref
(
''
)
const
spiderTypeOptions
=
ref
([
{
value
:
'
选项1
'
,
label
:
'
DSN爬虫
'
value
:
'
api_spider
'
,
label
:
'
api_spider
'
},
{
value
:
'
选项2
'
,
label
:
'
ITU爬虫
'
value
:
'
dsn_now
'
,
label
:
'
dsn_now
'
},
{
value
:
'
选项3
'
,
label
:
'
ST爬虫
'
value
:
'
itu_space_explorer
'
,
label
:
'
itu_space_explorer
'
},
])
const
taskParams
=
ref
({
scrapyd_server_id
:
'1'
,
schedule_type
:
'0'
,
project
:
'spiders'
})
const
cronExpression
=
ref
(
''
)
// const shortcuts = [
// { text: '每工作日9点', value: '0 0 9 ? * MON-FRI' },
// { text: '每季度第一天', value: '0 0 0 1 1/3 ?' }
// ]
// 关闭的方法
const
handleClose
=
()
=>
{
taskName
.
value
=
''
taskFrequency
.
value
=
''
cronExpression
.
value
=
''
currentVisible
.
value
=
false
}
// 确定的方法
const
handleConfirm
=
()
=>
{
emit
(
'confirm'
)
currentVisible
.
value
=
false
const
handleConfirm
=
async
()
=>
{
if
(
currentMode
.
value
===
AddMode
.
ADD_TASK
)
{
await
addSpiderTask
({
scrapyd_server_id
:
taskParams
.
value
.
scrapyd_server_id
,
schedule_type
:
taskParams
.
value
.
schedule_type
,
project
:
taskParams
.
value
.
project
,
spider
:
spiderTypeValue
.
value
,
cron
:
cronExpression
.
value
,
options
:
JSON
.
stringify
({
jobName
:
taskName
.
value
})
})
currentVisible
.
value
=
false
emit
(
'getTaskList'
)
}
else
if
(
currentMode
.
value
===
AddMode
.
UPDATE_TASK
)
{
await
addSpiderTask
({
scrapyd_server_id
:
taskParams
.
value
.
scrapyd_server_id
,
schedule_type
:
taskParams
.
value
.
schedule_type
,
project
:
taskParams
.
value
.
project
,
spider
:
props
.
spiderType
,
job_id
:
props
.
jobId
,
cron
:
cronExpression
.
value
,
options
:
props
.
options
})
currentVisible
.
value
=
false
emit
(
'getTaskList'
)
}
}
// 监听props变化,同步给组件内部
...
...
@@ -119,6 +142,28 @@ watch(() => props.mode,
currentMode
.
value
=
newVal
}
)
watch
(()
=>
currentMode
.
value
,
(
newVal
)
=>
{
emit
(
'update:mode'
,
newVal
)
}
)
watch
(
[()
=>
props
.
dialogVisible
,
()
=>
props
.
mode
,
()
=>
props
.
cron
],
([
newVisible
,
newMode
,
newCron
])
=>
{
if
(
newVisible
&&
newMode
===
AddMode
.
UPDATE_TASK
)
{
cronExpression
.
value
=
newCron
;
}
if
(
!
newVisible
)
{
// 清空表单
cronExpression
.
value
=
''
}
},
{
immediate
:
true
}
);
onMounted
(()
=>
{
})
</
script
>
<
style
>
...
...
@@ -133,6 +178,10 @@ watch(() => props.mode,
.el-dialog__title
{
color
:
#ffffff
;
}
.el-input__inner
{
color
:
#ffffff
;
}
}
/* 修改表单样式 */
...
...
src/views/os-taskInformation/components/deleteDialog.vue
0 → 100644
View file @
87d1de03
<
template
>
<el-dialog
v-model=
"deleteDialogVisible"
title=
"删除"
width=
"250"
center
align-center
@
close=
"close"
draggable
>
<div
class=
"text-center"
>
<span
style=
"color: #fff;font-size: 15px;"
>
确定删除吗?
</span>
</div>
<template
#
footer
>
<div
class=
"dialog-footer"
>
<el-button
@
click=
"close"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"handleDelelte"
>
确定
</el-button>
</div>
</
template
>
</el-dialog>
</template>
<
script
lang=
"ts"
setup
>
import
{
ref
,
watch
}
from
'vue'
import
{
defineProps
}
from
'vue'
;
import
{
deleteSpiderTask
}
from
'@/api/spiderTask.ts'
interface
deleteDialogPropType
{
dialogVisible
:
boolean
,
jobId
:
string
}
const
props
=
defineProps
<
deleteDialogPropType
>
()
const
emit
=
defineEmits
([
'update:dialogVisible'
,
'confirm'
,
'getUserList'
,
'update:deleteMode'
])
const
deleteDialogVisible
=
ref
(
props
.
dialogVisible
)
// 删除方法
const
handleDelelte
=
async
()
=>
{
await
deleteSpiderTask
({
job_id
:
props
.
jobId
})
emit
(
'getUserList'
)
deleteDialogVisible
.
value
=
false
}
// 关闭弹窗的方法
const
close
=
()
=>
{
deleteDialogVisible
.
value
=
false
}
// 监听父组件传过来的值
watch
(()
=>
props
.
dialogVisible
,
(
newVal
)
=>
{
deleteDialogVisible
.
value
=
newVal
}
)
// 监听组件内的值并向父组件更新
watch
(()
=>
deleteDialogVisible
.
value
,
(
newVal
)
=>
{
emit
(
'update:dialogVisible'
,
newVal
)
}
)
</
script
>
\ No newline at end of file
src/views/os-taskInformation/components/enum.ts
0 → 100644
View file @
87d1de03
/// @ts-ignore
export
enum
AddMode
{
ADD_TASK
=
0
,
UPDATE_TASK
=
1
,
}
\ No newline at end of file
src/views/os-taskInformation/components/taskCard.vue
View file @
87d1de03
<!-- 任务执行统计卡片组件 -->
<
template
>
<div
class=
"taskCard p-6"
v-for=
"task in taskList"
:key=
"task.taskId"
>
<div
class=
"flex justify-center"
>
<el-form-item>
<span
class=
"titleStyle"
>
任务名称
</span>
</el-form-item>
<div
class=
"text-left p-4 toolbarStyle "
>
<div
class=
"formStyle"
>
<el-form
inline
>
<el-form-item>
<el-text
class=
"mx-1"
style=
"color: #fff;"
>
所属爬虫:
</el-text>
</el-form-item>
<el-form-item>
<div>
<el-select
v-model=
"searchCondition.spiders"
placeholder=
"请选择"
style=
"width: 220px"
>
<el-option
v-for=
"item in taskSelectOptions"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</div>
</el-form-item>
<el-form-item>
<el-text
class=
"mx-1"
style=
"color: #fff;"
>
任务名称:
</el-text>
</el-form-item>
<el-form-item>
<el-input
v-model=
"taskName"
placeholder=
"请输入"
style=
"width: 220px"
/>
</el-form-item>
<el-form-item>
<el-space>
<el-button
type=
"primary"
@
Click=
"getData"
>
查询
</el-button>
</el-space>
</el-form-item>
<el-form-item>
<el-space>
<el-button
type=
"primary"
@
click=
"openTaskDialog"
>
新建任务
</el-button>
</el-space>
</el-form-item>
</el-form>
</div>
<div
class=
"flex justify-center "
>
<el-form-item>
<el-button
type=
"primary"
@
click=
"editTask"
class=
"editButton"
>
编辑
</el-button>
<el-button
type=
"success"
@
click=
"goToTaskRecord"
class=
"recordButton"
>
执行记录
</el-button>
<el-button
type=
"danger"
@
click=
"deleteTask"
class=
"deleteButton"
>
删除
</el-button>
</el-form-item>
</div>
<div
class=
"wordStyle flex justify-center"
>
<el-form-item>
<el-space>
<span
class=
"wordStyle"
>
启用/停止:
</span>
<el-switch
v-model=
"task.status"
:active-value=
"1"
:inactive-value=
"0"
@
change=
"changeStatus(task)"
/>
<span
class=
"wordStyle"
>
执行频率:
{{
task
.
frequency
}}
</span>
</el-space>
</el-form-item>
</div>
<div
class=
"wordStyle flex justify-center"
>
<el-form-item>
<el-space>
<span
class=
"wordStyle"
>
执行次数:
{{
task
.
executeCount
}}
个;
</span>
<span
class=
"wordStyle"
>
成功次数:
{{
task
.
successCount
}}
个
</span>
</el-space>
</el-form-item>
</div>
<div
class=
"wordStyle flex justify-center"
>
<el-form-item>
<el-space>
<span
class=
"wordStyle"
>
失败次数:
{{
task
.
failCount
}}
个;
</span>
<span
class=
"wordStyle"
>
异常记录:
{{
task
.
unusualCount
}}
个
</span>
</el-space>
</el-form-item>
</div>
<div
class=
"cardStyle"
>
<div
class=
"taskCard p-6 "
v-for=
"task in taskList"
:key=
"task.taskId"
>
<div
class=
"taskContent"
>
<div>
<el-form-item>
<span
class=
"titleStyle"
>
{{
task
.
kwargs
.
options
===
''
?
'无名称'
:
JSON
.
parse
(
task
.
kwargs
.
options
).
jobName
}}
</span>
</el-form-item>
</div>
<div>
<el-form-item>
<el-button
type=
"primary"
@
click=
"editTask(task)"
class=
"editButton"
>
编辑
</el-button>
<el-button
type=
"success"
@
click=
"goToTaskRecord"
class=
"recordButton"
>
执行记录
</el-button>
<el-button
type=
"danger"
@
click=
"deleteTask(task)"
class=
"deleteButton"
>
删除
</el-button>
</el-form-item>
</div>
<div
class=
"wordStyle"
>
<el-form-item>
<el-space>
<span
class=
"wordStyle"
>
启用/停止:
</span>
<el-switch
v-model=
"task.status"
:active-value=
"1"
:inactive-value=
"0"
@
change=
"changeStatus(task)"
/>
<span
class=
"wordStyle"
>
执行频率:
{{
task
.
frequency
}}
</span>
</el-space>
</el-form-item>
</div>
<div
class=
"wordStyle"
>
<el-form-item>
<el-space>
<span
class=
"wordStyle"
>
执行次数: 个;
</span>
<span
class=
"wordStyle"
>
成功次数: 个
</span>
</el-space>
</el-form-item>
</div>
<div
class=
"wordStyle "
>
<el-form-item>
<el-space>
<span
class=
"wordStyle"
>
失败次数: 个;
</span>
<span
class=
"wordStyle"
>
异常记录: 个
</span>
</el-space>
</el-form-item>
</div>
</div>
</div>
</div>
<deleteDialog
v-model:dialogVisible=
"showDeleteDialog"
@
confirm=
"handleDeleteConfirm"
@
mode=
"deleteMode"
/>
<addTaskDialog
v-model:dialogVisible=
"showTaskDialog"
@
confirm=
"handleEdit"
:mode=
"editMode"
/>
<addTaskDialog
v-model:dialogVisible=
"showTaskDialog"
@
confirm=
"handleEdit"
:mode=
"editMode"
@
getTaskList=
"getData"
:jobId=
"jobId"
:cron=
"frequency"
:spiderType=
"spiderType"
:options=
"taskOptions"
/>
<deleteDialog
v-model:dialogVisible=
"showDeleteDialog"
@
get-user-list=
"getData"
:jobId=
"jobId"
/>
</
template
>
<
script
lang=
"ts"
setup
>
import
{
ref
,
onMounted
}
from
'vue'
import
{
useRouter
}
from
'vue-router'
import
deleteDialog
from
'@/components/Delete/index.vue'
import
addTaskDialog
from
'./addTaskDialog.vue'
import
{
getSpiderTaskList
}
from
'@/api/spiderTask'
import
{
DeleteMode
}
from
'@/components/Delete/enum.ts'
import
{
AddMode
}
from
'./enum'
import
deleteDialog
from
'./deleteDialog.vue'
defineProps
({
successTask
:
{
type
:
String
,
...
...
@@ -65,82 +106,63 @@ defineProps({
default
:
''
}
})
const
router
=
useRouter
()
const
editMode
=
ref
(
''
)
const
deleteMode
=
ref
(
'1'
)
const
showDeleteDialog
=
ref
(
false
)
const
showTaskDialog
=
ref
(
false
)
const
taskSwitch
=
ref
(
false
)
const
taskList
=
ref
([
const
taskSelectOptions
=
[
{
taskId
:
'1'
,
taskName
:
'任务1'
,
status
:
1
,
frequency
:
'1'
,
executeCount
:
'2'
,
successCount
:
'3'
,
failCount
:
'4'
,
unusualCount
:
'5'
value
:
'api_spider'
,
label
:
'api_spider'
,
},
{
taskId
:
'2'
,
taskName
:
'任务2'
,
status
:
0
,
frequency
:
'6'
,
executeCount
:
'7'
,
successCount
:
'8'
,
failCount
:
'9'
,
unusualCount
:
'10'
value
:
'dsn_now'
,
label
:
'dsn_now'
,
},
{
taskId
:
'3'
,
taskName
:
'任务3'
,
status
:
1
,
frequency
:
'11'
,
executeCount
:
'12'
,
successCount
:
'13'
,
failCount
:
'14'
,
unusualCount
:
'15'
},
{
taskId
:
'4'
,
taskName
:
'任务4'
,
status
:
0
,
frequency
:
'16'
,
executeCount
:
'17'
,
successCount
:
'18'
,
failCount
:
'19'
,
unusualCount
:
'20'
value
:
'itu_space_explorer'
,
label
:
'itu_space_explorer'
,
},
]
const
searchCondition
=
ref
({
spiders
:
''
,
options
:
''
})
const
taskName
=
ref
(
''
)
const
taskValue
=
ref
(
''
)
const
spiderType
=
ref
(
''
)
const
router
=
useRouter
()
const
frequency
=
ref
(
''
)
const
editMode
=
ref
(
AddMode
.
UPDATE_TASK
)
const
deleteMode
=
ref
(
DeleteMode
.
SINGLE_DELETE
)
const
showDeleteDialog
=
ref
(
false
)
const
showTaskDialog
=
ref
(
false
)
const
taskSwitch
=
ref
(
false
)
const
taskOptions
=
ref
(
''
)
const
jobId
=
ref
(
''
)
const
taskList
=
ref
([
{
taskId
:
'5'
,
taskName
:
'任务5
'
,
taskId
:
1
,
name
:
'任务1
'
,
status
:
1
,
frequency
:
'21'
,
executeCount
:
'22'
,
successCount
:
'23'
,
failCount
:
'24'
,
unusualCount
:
'25'
},
{
taskId
:
'6'
,
taskName
:
'任务6'
,
status
:
0
,
frequency
:
'26'
,
executeCount
:
'27'
,
successCount
:
'28'
,
failCount
:
'29'
,
unusualCount
:
'30'
},
frequency
:
'每天'
,
kwargs
:
{
options
:
''
}
}
])
const
deleteTask
=
()
=>
{
deleteMode
.
value
=
'1'
const
deleteTask
=
(
task
:
any
)
=>
{
console
.
log
(
task
);
jobId
.
value
=
task
.
id
deleteMode
.
value
=
DeleteMode
.
SINGLE_DELETE
showDeleteDialog
.
value
=
true
}
const
editTask
=
()
=>
{
editMode
.
value
=
'2'
const
editTask
=
(
task
:
any
)
=>
{
jobId
.
value
=
task
.
id
taskOptions
.
value
=
JSON
.
stringify
(
JSON
.
parse
(
task
.
kwargs
.
options
))
spiderType
.
value
=
task
.
kwargs
.
spider
frequency
.
value
=
task
.
kwargs
.
cron
editMode
.
value
=
AddMode
.
UPDATE_TASK
showTaskDialog
.
value
=
true
// console.log(JSON.stringify(JSON.parse(task.kwargs.options)));
}
const
goToTaskRecord
=
()
=>
{
router
.
push
({
...
...
@@ -157,23 +179,32 @@ const changeStatus = (task: any) => {
const
handleEdit
=
()
=>
{
}
const
handleDeleteConfirm
=
()
=>
{
const
openTaskDialog
=
()
=>
{
editMode
.
value
=
AddMode
.
ADD_TASK
showTaskDialog
.
value
=
true
}
const
getData
=
async
()
=>
{
console
.
log
(
'getData'
);
const
res
=
await
getSpiderTaskList
({
spiders
:[
'api_spider'
]})
// taskList.value = res.data
console
.
log
(
res
);
const
res
=
await
getSpiderTaskList
({
spiders
:
searchCondition
.
value
.
spiders
?
[
searchCondition
.
value
.
spiders
]
:
[]
,
options
:
JSON
.
stringify
({
jobName
:
taskName
.
value
})
})
taskList
.
value
=
res
.
data
}
onMounted
(()
=>
{
getData
()
getData
()
})
</
script
>
<
style
lang=
"scss"
scoped
>
.taskContent
{
display
:
flex
;
flex-direction
:
column
;
//
垂直排列
align-items
:
center
;
//
水平居中
justify-content
:
center
;
//
垂直居中
height
:
100%
;
gap
:
-15px
;
padding
:
10px
0
;
}
//
.editButton
{
//
background
:
none
;
//
background-image
:
url("@/assets/picture/button1.png")
;
...
...
@@ -192,6 +223,15 @@ onMounted(() => {
//
background-size
:
100%
100%
;
//
background-repeat
:
no-repeat
;
//
}
.cardStyle
{
display
:
flex
;
flex-wrap
:
wrap
;
justify-content
:
space-around
;
margin-top
:
1.5%
;
padding
:
8px
;
height
:
26vh
;
}
//
任务卡片样式
.taskCard
{
background-image
:
url("@/assets/picture/box2.png")
;
...
...
@@ -202,6 +242,8 @@ onMounted(() => {
font-size
:
20px
;
height
:
100%
;
border-radius
:
7px
;
display
:
flex
;
flex-direction
:
column
;
.titleStyle
{
font-size
:
22px
;
...
...
@@ -216,6 +258,21 @@ onMounted(() => {
}
}
/* 工具栏样式 */
.toolbarStyle
{
background-image
:
url("@/assets/picture/box3.png")
;
background-size
:
100%
100%
;
background-repeat
:
no-repeat
;
}
/* 表单样式 */
.formStyle
{
display
:
flex
;
justify-content
:
space-around
;
margin-top
:
0.5%
;
padding
:
2px
;
}
//
去除按钮边框
.el-button
:focus
{
outline
:
none
;
...
...
@@ -229,4 +286,8 @@ onMounted(() => {
color: #ffffff;
border: none;
} */
.el-input
{
color
:
#FFFFFF
;
}
</
style
>
\ No newline at end of file
src/views/os-taskInformation/index.vue
View file @
87d1de03
...
...
@@ -2,63 +2,27 @@
<div>
<div
class=
"backStyle"
v-if=
"route.query.jump === 'yes'"
@
click=
"goToTaskInformation"
/>
<div
class=
"m-t-10"
/>
<div
class=
"text-left p-4 toolbarStyle"
>
<div
class=
"formStyle"
>
<el-form
inline
>
<el-form-item>
<el-text
class=
"mx-1"
>
所属爬虫:
</el-text>
</el-form-item>
<el-form-item>
<div>
<el-select
v-model=
"taskValue"
placeholder=
"请选择"
style=
"width: 220px"
>
<el-option
v-for=
"item in taskOptions"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</div>
</el-form-item>
<el-form-item>
<el-text
class=
"mx-1"
>
任务名称:
</el-text>
</el-form-item>
<el-form-item>
<el-input
v-model=
"taskValue"
placeholder=
"请输入"
style=
"width: 220px"
/>
</el-form-item>
<el-form-item>
<el-space>
<el-button
type=
"primary"
>
查询
</el-button>
</el-space>
</el-form-item>
<el-form-item>
<el-space>
<el-button
type=
"primary"
@
click=
"openTaskDialog"
>
新建任务
</el-button>
</el-space>
</el-form-item>
</el-form>
</div>
</div>
<div
class=
"cardStyle"
>
<div
>
<taskCard
successTask=
"100"
failTask=
"10"
unusualTask=
"1"
/>
<!--
<div
class=
"pagination w-full flex flex-row-reverse pr-18 m-t-0"
>
<Pagination
:total=
"pageObj.total"
v-model:page=
"pageObj.pageNo"
v-model:limit=
"pageObj.pageSize"
@
pagination=
"getData"
/>
</div>
-->
</div>
<!-- 添加任务对话框组件 -->
<addTaskDialog
v-model:dialogVisible=
"showDialog"
@
confirm=
"handleDeleteConfirm"
:mode=
"editMode"
/>
</div>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
ref
,
onMounted
}
from
'vue'
import
Pagination
from
'@/components/pagination/index.vue'
import
taskCard
from
'./components/taskCard.vue'
import
addTaskDialog
from
'./components/addTaskDialog.vue'
import
{
useRouter
}
from
'vue-router'
import
{
useRoute
}
from
'vue-router'
import
{
getSpiderTaskList
}
from
'@/api/spiderTask'
import
{
getSpiderTaskList
,
getTaskData
}
from
'@/api/spiderTask'
import
{
AddMode
}
from
'./components/enum'
const
route
=
useRoute
()
const
router
=
useRouter
()
const
editMode
=
ref
(
'1'
)
const
taskValue
=
ref
(
''
)
const
taskList
=
ref
([])
const
taskOptions
=
[
...
...
@@ -81,23 +45,9 @@ const pageObj = ref({
pageNo
:
1
})
// 控制对话框显示/隐藏的状态变量
const
showDialog
=
ref
(
false
)
// 处理删除确认
const
handleDeleteConfirm
=
()
=>
{
console
.
log
(
'用户确认删除'
)
}
const
openTaskDialog
=
()
=>
{
showDialog
.
value
=
true
}
const
goToTaskInformation
=
()
=>
{
router
.
push
({
path
:
'/osSpiderManager/list'
})
}
onMounted
(()
=>
{
})
</
script
>
<
style
scoped
>
...
...
vite.config.ts
View file @
87d1de03
...
...
@@ -30,7 +30,7 @@ export default defineConfig({
proxy
:
{
// 代理API请求,使用更精确的路径匹配
'/api'
:
{
target
:
'http://1
92.168.0.200
:5001/'
,
target
:
'http://1
27.0.0.1
:5001/'
,
changeOrigin
:
true
,
},
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment