16 changed files with 630 additions and 13 deletions
Unified View
Diff Options
-
4.env.development
-
4.eslintrc.js
-
1spider-management-backend-web
-
39src/api/sys/model/scrapyModel.ts
-
56src/api/sys/scrapy.ts
-
1src/layouts/default/content/index.vue
-
30src/router/routes/modules/scrapy.ts
-
17src/store/modules/scrapy.ts
-
70src/utils/http/axios/index.ts
-
1src/views/sys/login/useLogin.ts
-
81src/views/sys/scrapy/createSpider.vue
-
259src/views/sys/scrapy/index.vue
-
55src/views/sys/scrapy/product.data.ts
-
11types/axios.d.ts
-
2vite.config.ts
-
12yarn.lock
@ -1 +0,0 @@ |
|||||
Subproject commit f25cfcc7beafd63ca7c80757785ac3f0cf4b9a3a |
|
||||
@ -0,0 +1,39 @@ |
|||||
|
/** |
||||
|
* @description: getScrapList interface parameters |
||||
|
*/ |
||||
|
|
||||
|
export interface getScrapyParams{ |
||||
|
spiderName: string; |
||||
|
status: string; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* @description: Getscray interface return value |
||||
|
*/ |
||||
|
|
||||
|
export interface getScrapyInfoModel{ |
||||
|
records: recordsModel[]; |
||||
|
total: number; |
||||
|
size:number; |
||||
|
current: number; |
||||
|
pages:number; |
||||
|
} |
||||
|
|
||||
|
export interface recordsModel{ |
||||
|
id: number; |
||||
|
createdTime: string; |
||||
|
updatedTime: string; |
||||
|
spiderName: string; |
||||
|
duration: number; |
||||
|
status: number; |
||||
|
} |
||||
|
|
||||
|
export interface createModel{ |
||||
|
id:number; |
||||
|
} |
||||
|
|
||||
|
export interface getStauts{ |
||||
|
key: number; |
||||
|
value: string; |
||||
|
} |
||||
@ -0,0 +1,56 @@ |
|||||
|
import { defHttp } from "/@/utils/http/axios"; |
||||
|
import { createModel, getStauts, recordsModel } from "/@/api/sys/model/scrapyModel"; |
||||
|
|
||||
|
enum Api { |
||||
|
getScrapyInfo = '/admin/query/spider', |
||||
|
createSpider = '/admin/create/spider', |
||||
|
runSpider = '/admin/run/spider', |
||||
|
getSpiderStatus = '/admin/get/spider/status', |
||||
|
|
||||
|
stopSpiderDuration = '/admin/stop/spider' |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @description:查询爬虫列表 |
||||
|
*/ |
||||
|
export function getScrapyApi(params) { |
||||
|
|
||||
|
return defHttp.get<recordsModel>( |
||||
|
{ |
||||
|
url: Api.getScrapyInfo, |
||||
|
params |
||||
|
}, |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @description:创建爬虫 |
||||
|
*/ |
||||
|
export function createSpiderApi(params) { |
||||
|
return defHttp.post<createModel>( |
||||
|
{ |
||||
|
url: Api.createSpider, |
||||
|
params |
||||
|
}, |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @description:运行爬虫 |
||||
|
*/ |
||||
|
export function runSpiderApi(params) { |
||||
|
return defHttp.post<recordsModel>( |
||||
|
{ |
||||
|
url: Api.runSpider, |
||||
|
params, |
||||
|
}, |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
export function getStatusApi(){ |
||||
|
return defHttp.get<getStauts>( |
||||
|
{ |
||||
|
url:Api.getSpiderStatus, |
||||
|
}, |
||||
|
); |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
import type { AppRouteModule } from '/@/router/types'; |
||||
|
|
||||
|
import { LAYOUT } from '/@/router/constant'; |
||||
|
// import { t } from '/@/hooks/web/useI18n';
|
||||
|
|
||||
|
const scrapy: AppRouteModule = { |
||||
|
path: '/scrapy', |
||||
|
name: 'scrapyName', |
||||
|
component: LAYOUT, |
||||
|
redirect: '/scrapy/index', |
||||
|
meta: { |
||||
|
orderNo: 200, |
||||
|
icon: 'ion:git-compare-outline', |
||||
|
title: '爬虫', |
||||
|
}, |
||||
|
children: [ |
||||
|
{ |
||||
|
path: 'index', |
||||
|
name: 'ScrapyPage', |
||||
|
component: () => import('/@/views/sys/scrapy/index.vue'), |
||||
|
meta: { |
||||
|
title: '爬虫页面', |
||||
|
icon: 'simple-icons:about-dot-me', |
||||
|
hideMenu: true, |
||||
|
}, |
||||
|
}, |
||||
|
], |
||||
|
}; |
||||
|
|
||||
|
export default scrapy; |
||||
@ -0,0 +1,17 @@ |
|||||
|
// import { defineStore } from "pinia";
|
||||
|
// import { getScrapyInfoModel, getScrapyParams } from "/@/api/sys/model/scrapyModel";
|
||||
|
// import { getScrapyApi } from "/@/api/sys/scrapy";
|
||||
|
|
||||
|
// export const useScrapyStore = defineStore({
|
||||
|
// async getScrapyInfo(
|
||||
|
// params: getScrapyParams
|
||||
|
// ):Promise<getScrapyInfoModel | null>{
|
||||
|
// try {
|
||||
|
// const { ...getScrapyParams} = params
|
||||
|
// const data = await getScrapyApi(getScrapyParams);
|
||||
|
// return data
|
||||
|
// }catch (error){
|
||||
|
// return Promise.reject(error);
|
||||
|
// }
|
||||
|
// }
|
||||
|
// })
|
||||
@ -0,0 +1,81 @@ |
|||||
|
<template> |
||||
|
<BasicModal v-bind="$attrs" title="创建爬虫" @ok="createSpider"> |
||||
|
<div class="m-4"> |
||||
|
<BasicForm |
||||
|
:labelWidth="100" |
||||
|
:schemas="schemas" |
||||
|
:actionColOptions="{ span: 24 }" |
||||
|
:showActionButtonGroup="false" |
||||
|
/> |
||||
|
</div> |
||||
|
</BasicModal> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
|
||||
|
import { defineComponent } from 'vue'; |
||||
|
import { BasicModal } from '/@/components/Modal'; |
||||
|
import { BasicForm } from '/@/components/Form'; |
||||
|
import { createSpiderApi } from '/@/api/sys/scrapy'; |
||||
|
|
||||
|
|
||||
|
export default defineComponent({ |
||||
|
name: "CreateSpiderModal", |
||||
|
components:{BasicModal, BasicForm}, |
||||
|
emits:['success'], |
||||
|
setup(props,{emit}){ |
||||
|
|
||||
|
const schemas=[ |
||||
|
{ |
||||
|
field: 'field', |
||||
|
component: 'Input', |
||||
|
label: '爬虫名称', |
||||
|
colProps: { |
||||
|
span: 16, |
||||
|
}, |
||||
|
componentProps: { |
||||
|
placeholder: '请输入爬虫名称', |
||||
|
onChange: handleCreateSpider, |
||||
|
}, |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
const state = { |
||||
|
creatSpiderName:'', |
||||
|
} |
||||
|
|
||||
|
async function createSpider(){ |
||||
|
let res = await createSpiderApi({spiderName:state.creatSpiderName}) |
||||
|
console.log(JSON.stringify(res)); |
||||
|
emit('success',state.creatSpiderName); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
//定义spiderName防抖函数 |
||||
|
let timerCreate = null |
||||
|
function debounceSpiderName(value){ |
||||
|
timerCreate =window.setTimeout(function(){ |
||||
|
state.creatSpiderName = value |
||||
|
},2000) |
||||
|
} |
||||
|
function handleCreateSpider(e) { |
||||
|
if(timerCreate) clearTimeout(Number(timerCreate)) |
||||
|
debounceSpiderName(e.target.value) |
||||
|
} |
||||
|
|
||||
|
return{ |
||||
|
schemas, |
||||
|
createSpider, |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
|
||||
|
</style> |
||||
@ -0,0 +1,259 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<div class="p-4"> |
||||
|
<BasicTable |
||||
|
@register="refreshTable" |
||||
|
:pagination="{ pageSize: 10 }" |
||||
|
> |
||||
|
<template #toolbar> |
||||
|
<a-button type="primary" @click="getStatusList">获取状态列表</a-button> |
||||
|
<a-button type="primary" @click="handleCreate">新建爬虫</a-button> |
||||
|
</template> |
||||
|
|
||||
|
|
||||
|
<template #action="{ record }"> |
||||
|
<TableAction |
||||
|
:actions="[ |
||||
|
{ |
||||
|
icon: 'clarity:note-edit-line', |
||||
|
onClick: handleEdit.bind(null, record), |
||||
|
ifShow:() => record.status === 3, |
||||
|
}, |
||||
|
{ |
||||
|
icon: 'ant-design:delete-outlined', |
||||
|
color: 'error', |
||||
|
popConfirm: { |
||||
|
title: '是否确认删除', |
||||
|
confirm: handleDelete.bind(null, record), |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
title:'运行爬虫', |
||||
|
icon: 'ant-design:caret-right-filled', |
||||
|
color:'success', |
||||
|
onClick:handleRunSpider.bind(null, record), |
||||
|
}, |
||||
|
{ |
||||
|
title:'停止运行', |
||||
|
icon: 'ant-design:stop-outlined', |
||||
|
color: 'warning', |
||||
|
onClick:handleStopSpider.bind(null,record), |
||||
|
} |
||||
|
]" |
||||
|
/> |
||||
|
</template> |
||||
|
|
||||
|
</BasicTable> |
||||
|
</div> |
||||
|
|
||||
|
<CreateSpiderModal @register='register' @success="handleCreateSuccess"></CreateSpiderModal> |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
</template> |
||||
|
<script lang="ts"> |
||||
|
import { defineComponent, reactive, toRefs } from "vue"; |
||||
|
import { useModal } from '/@/components/Modal'; |
||||
|
import { BasicTable, FormProps, useTable, TableAction } from "/@/components/Table"; |
||||
|
import { getScrapyApi, runSpiderApi } from "/@/api/sys/scrapy"; |
||||
|
import { scrapyColumns} from './product.data'; |
||||
|
import CreateSpiderModal from './createSpider.vue' |
||||
|
|
||||
|
|
||||
|
export default defineComponent({ |
||||
|
name: 'Spider', |
||||
|
components: { BasicTable, CreateSpiderModal,TableAction}, |
||||
|
|
||||
|
setup(){ |
||||
|
|
||||
|
const state =reactive({ |
||||
|
spiderName:'', |
||||
|
status:'', |
||||
|
}) |
||||
|
|
||||
|
|
||||
|
const detailSearchForm: FormProps = { |
||||
|
baseColProps: { lg: 6, md: 8 }, |
||||
|
labelWidth: 90, |
||||
|
schemas: [ |
||||
|
{ |
||||
|
label: 'spiderName', |
||||
|
field: 'SpiderName', |
||||
|
component: 'InputSearch', //组件类型 |
||||
|
componentProps: { |
||||
|
onChange: handleSpiderNameChange |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
label: 'status', |
||||
|
field: 'Status', |
||||
|
component: 'Select', |
||||
|
componentProps: { |
||||
|
options:[ |
||||
|
{ label: '成功',value: 1,}, |
||||
|
{ label: '失败', value: 2,}, |
||||
|
{ label: '停止', value: 3,}, |
||||
|
], |
||||
|
onChange: handleStatusChange |
||||
|
} |
||||
|
}, |
||||
|
], |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
const [register, { openModal }] = useModal(); |
||||
|
const [refreshTable, { reload, getDataSource}] = useTable({ |
||||
|
title: '', |
||||
|
api: getScrapyApi, |
||||
|
columns: scrapyColumns, |
||||
|
formConfig: detailSearchForm, |
||||
|
useSearchForm: true, |
||||
|
showTableSetting: true, |
||||
|
bordered: true, |
||||
|
showIndexColumn: false, |
||||
|
searchInfo:{}, |
||||
|
actionColumn: { |
||||
|
width: 120, |
||||
|
title: '操作', |
||||
|
dataIndex: 'action', |
||||
|
slots: { customRender: 'action' }, |
||||
|
fixed: undefined, |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
/** |
||||
|
* @description:编辑爬虫 |
||||
|
*/ |
||||
|
function handleEdit(record:Recordable){ |
||||
|
console.log(record); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* @description:获取状态列表 |
||||
|
*/ |
||||
|
function getStatusList(){ |
||||
|
|
||||
|
const data = getDataSource() |
||||
|
console.log(data); |
||||
|
console.log(data.length); |
||||
|
for(let i = 0;i<data.length; i++){ |
||||
|
if(data[i].status === 1 ){ |
||||
|
data[i].statusChinese = '成功' |
||||
|
}else if(data[i].status ===2){ |
||||
|
data[i].statusChinese = '失败' |
||||
|
}else if(data[i].status ===3){ |
||||
|
data[i].statusChinese = '停止' |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* @description:删除爬虫 |
||||
|
*/ |
||||
|
function handleDelete(record: Recordable) { |
||||
|
console.log('点击了删除', record); |
||||
|
reload(); |
||||
|
getStatusList(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* @description:运行爬虫 |
||||
|
*/ |
||||
|
|
||||
|
async function handleRunSpider(record: Recordable){ |
||||
|
console.log(record.id) |
||||
|
let res = await runSpiderApi({id:record.id}) |
||||
|
console.log(JSON.stringify(res)); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* @description:停止运行爬虫 |
||||
|
*/ |
||||
|
function handleStopSpider(record: Recordable){ |
||||
|
console.log(record); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* @description:关闭创建爬虫弹窗 |
||||
|
*/ |
||||
|
function handleCreateSuccess(value) { |
||||
|
console.log(value); |
||||
|
reload(); |
||||
|
getStatusList(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* @description:获取status |
||||
|
*/ |
||||
|
let timer: null| NodeJS.Timeout = null; |
||||
|
function handleStatusChange(e) { |
||||
|
//console.log(e.target.value); |
||||
|
if(timer) clearTimeout(Number(timer)) |
||||
|
debounceSearch(e) |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//定义status防抖函数 |
||||
|
function debounceSearch(value){ |
||||
|
timer = setTimeout(function(){ |
||||
|
state.status = value |
||||
|
console.log(state.status); |
||||
|
},1000) |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @description:获取spiderName |
||||
|
*/ |
||||
|
let time: null| NodeJS.Timeout = null; |
||||
|
function handleSpiderNameChange(e) { |
||||
|
if(time) clearTimeout(Number(time)) |
||||
|
debounceSearch1(e.target.value) |
||||
|
} |
||||
|
|
||||
|
//定义spiderName防抖函数 |
||||
|
function debounceSearch1(value){ |
||||
|
time = setTimeout(function(){ |
||||
|
state.spiderName = value |
||||
|
console.log(state.spiderName); |
||||
|
},1000) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* @description:弹出创建爬虫弹窗 |
||||
|
*/ |
||||
|
function handleCreate() { |
||||
|
openModal(true, { |
||||
|
isUpdate: false, |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
return { |
||||
|
...toRefs(state), |
||||
|
register, |
||||
|
refreshTable, |
||||
|
handleCreateSuccess, |
||||
|
detailSearchForm, |
||||
|
handleCreate, |
||||
|
handleDelete, |
||||
|
handleEdit, |
||||
|
handleRunSpider, |
||||
|
getStatusList, |
||||
|
handleStopSpider, |
||||
|
}; |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
</script> |
||||
@ -0,0 +1,55 @@ |
|||||
|
import { BasicColumn } from '/@/components/Table'; |
||||
|
export const scrapyColumns: BasicColumn[] = [ |
||||
|
{ |
||||
|
title: 'ID', |
||||
|
dataIndex: 'id', |
||||
|
fixed: 'left', |
||||
|
width: 180, |
||||
|
sorter: true, |
||||
|
}, |
||||
|
{ |
||||
|
title: '爬虫名称', |
||||
|
dataIndex: 'spiderName', |
||||
|
width: 150, |
||||
|
|
||||
|
}, |
||||
|
{ |
||||
|
title: '状态', |
||||
|
dataIndex: 'statusChinese', |
||||
|
width: 80, |
||||
|
|
||||
|
}, |
||||
|
// {
|
||||
|
// title: 'Event',
|
||||
|
// dataIndex: 'event',
|
||||
|
// width: 150,
|
||||
|
//
|
||||
|
// },
|
||||
|
{ |
||||
|
title: '运行周期', |
||||
|
dataIndex: 'duration', |
||||
|
width: 80, |
||||
|
}, |
||||
|
// {
|
||||
|
// title: '状态',
|
||||
|
// dataIndex: 'statusChinese',
|
||||
|
// width: 100,
|
||||
|
//
|
||||
|
// },
|
||||
|
{ |
||||
|
title: '创建时间', |
||||
|
width: 180, |
||||
|
sorter: true, |
||||
|
dataIndex: 'createdTime', |
||||
|
}, |
||||
|
{ |
||||
|
title: '更新时间', |
||||
|
width: 180, |
||||
|
sorter: true, |
||||
|
dataIndex: 'updatedTime', |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
Write
Preview
Loading…
Cancel
Save