parent
6755f06ba3
commit
874e05bc1b
@ -0,0 +1,43 @@ |
|||||||
|
import { AxiosPromise } from "axios"; |
||||||
|
import { PlanFilterConfigOption, WorkflowPageResult } from "@/api/workflow/types"; |
||||||
|
import request from "@/utils/request"; |
||||||
|
|
||||||
|
export function planConfigOption(): AxiosPromise<PlanFilterConfigOption[]> { |
||||||
|
return request({ |
||||||
|
url: "/api/plan_filter_config/v1/option", |
||||||
|
method: "GET", |
||||||
|
}); |
||||||
|
} |
||||||
|
export function addPlanFilterConfig(data: any) { |
||||||
|
return request({ |
||||||
|
url: "/api/workflow/v1/add", |
||||||
|
method: "POST", |
||||||
|
data, |
||||||
|
}); |
||||||
|
} |
||||||
|
export function getWorkflowPage( |
||||||
|
data: SelectForm |
||||||
|
): AxiosPromise<WorkflowPageResult> { |
||||||
|
return request({ |
||||||
|
url: "/api/workflow/v1/page", |
||||||
|
method: "POST", |
||||||
|
data, |
||||||
|
}); |
||||||
|
} |
||||||
|
export function removeWorkflow( |
||||||
|
planId: number |
||||||
|
): AxiosPromise<WorkflowPageResult> { |
||||||
|
return request({ |
||||||
|
url: `/api/workflow/v1/${planId}`, |
||||||
|
method: "DELETE", |
||||||
|
}); |
||||||
|
} |
||||||
|
export function updateWorkflowStatus( |
||||||
|
planId: number, |
||||||
|
status: number |
||||||
|
): AxiosPromise<WorkflowPageResult> { |
||||||
|
return request({ |
||||||
|
url: `/api/workflow/v1/status/${planId}/${status}`, |
||||||
|
method: "PUT", |
||||||
|
}); |
||||||
|
} |
@ -0,0 +1,39 @@ |
|||||||
|
export interface WorkFlowForm { |
||||||
|
planId?: number; |
||||||
|
|
||||||
|
startTime?: string; |
||||||
|
|
||||||
|
endTime?: string; |
||||||
|
|
||||||
|
maxConcurrency?: number; |
||||||
|
|
||||||
|
planName?: string; |
||||||
|
|
||||||
|
planDesc?: string; |
||||||
|
} |
||||||
|
|
||||||
|
export interface PlanFilterForm { |
||||||
|
filterName: string; |
||||||
|
values: string[]; |
||||||
|
} |
||||||
|
export interface PlanFilterConfigOption { |
||||||
|
displayName: string; |
||||||
|
filterName: string; |
||||||
|
options: OptionType[]; |
||||||
|
} |
||||||
|
export interface WorkFlowTable { |
||||||
|
planId?: number; |
||||||
|
|
||||||
|
startTime?: string; |
||||||
|
|
||||||
|
endTime?: string; |
||||||
|
|
||||||
|
createTime?: string; |
||||||
|
|
||||||
|
createUser?: string; |
||||||
|
|
||||||
|
planName?: string; |
||||||
|
|
||||||
|
planStatus?: number; |
||||||
|
} |
||||||
|
export type WorkflowPageResult = PageResult<WorkFlowTable[]>; |
@ -0,0 +1,259 @@ |
|||||||
|
<template> |
||||||
|
<div class="app-container"> |
||||||
|
<el-card v-show="currentPage === 0" shadow="never"> |
||||||
|
<el-form :model="formData" ref="baseFormRef" :rules="baseRules"> |
||||||
|
<el-descriptions :column="2" border> |
||||||
|
<template #title> |
||||||
|
<div style="display: flex; align-items: center"> |
||||||
|
<el-icon size="15" class="mr-1"> |
||||||
|
<Grid /> |
||||||
|
</el-icon> |
||||||
|
<span style="font-weight: 700; font-size: 14px; line-height: 16px" |
||||||
|
>工作流基本信息</span |
||||||
|
> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<el-descriptions-item |
||||||
|
label="工作流名称" |
||||||
|
label-align="left" |
||||||
|
align="center" |
||||||
|
label-class-name="my-label" |
||||||
|
class-name="my-content" |
||||||
|
width="150px" |
||||||
|
> |
||||||
|
<el-form-item prop="planName"> |
||||||
|
<el-input |
||||||
|
v-model="formData.planName" |
||||||
|
placeholder="请输入工作流名称" |
||||||
|
/> |
||||||
|
</el-form-item> |
||||||
|
</el-descriptions-item> |
||||||
|
<el-descriptions-item |
||||||
|
label="最大并发数" |
||||||
|
label-align="left" |
||||||
|
align="center" |
||||||
|
label-class-name="my-label" |
||||||
|
class-name="my-content" |
||||||
|
width="150px" |
||||||
|
> |
||||||
|
<el-form-item prop="maxConcurrency"> |
||||||
|
<el-input |
||||||
|
v-model.number="formData.maxConcurrency" |
||||||
|
placeholder="请输入最大并发数" |
||||||
|
/> |
||||||
|
</el-form-item> |
||||||
|
</el-descriptions-item> |
||||||
|
<el-descriptions-item |
||||||
|
label="开始时间" |
||||||
|
label-align="left" |
||||||
|
align="center" |
||||||
|
label-class-name="my-label" |
||||||
|
class-name="my-content" |
||||||
|
width="150px" |
||||||
|
> |
||||||
|
<el-form-item prop="startTime"> |
||||||
|
<div style="width: 100%"> |
||||||
|
<el-date-picker |
||||||
|
v-model="formData.startTime" |
||||||
|
type="datetime" |
||||||
|
style="width: 100%" |
||||||
|
placeholder="请选择开始时间" |
||||||
|
value-format="YYYY-MM-DD hh:mm:ss" |
||||||
|
/> |
||||||
|
</div> |
||||||
|
</el-form-item> |
||||||
|
</el-descriptions-item> |
||||||
|
<el-descriptions-item |
||||||
|
label="结束时间" |
||||||
|
label-align="left" |
||||||
|
align="center" |
||||||
|
label-class-name="my-label" |
||||||
|
class-name="my-content" |
||||||
|
width="150px" |
||||||
|
> |
||||||
|
<el-form-item prop="endTime"> |
||||||
|
<div style="width: 100%"> |
||||||
|
<el-date-picker |
||||||
|
v-model="formData.endTime" |
||||||
|
type="datetime" |
||||||
|
style="width: 100%" |
||||||
|
placeholder="请选择结束时间" |
||||||
|
value-format="YYYY-MM-DD hh:mm:ss" |
||||||
|
/> |
||||||
|
</div> |
||||||
|
</el-form-item> |
||||||
|
</el-descriptions-item> |
||||||
|
<el-descriptions-item |
||||||
|
label="工作流描述" |
||||||
|
label-align="left" |
||||||
|
align="center" |
||||||
|
label-class-name="my-label" |
||||||
|
class-name="my-content" |
||||||
|
width="150px" |
||||||
|
> |
||||||
|
<el-form-item prop="planDesc"> |
||||||
|
<el-input |
||||||
|
v-model="formData.planDesc" |
||||||
|
type="textarea" |
||||||
|
placeholder="请输入工作流描述" |
||||||
|
/> |
||||||
|
</el-form-item> |
||||||
|
</el-descriptions-item> |
||||||
|
</el-descriptions> |
||||||
|
</el-form> |
||||||
|
<template #footer> |
||||||
|
<div class="flex justify-end"> |
||||||
|
<el-button type="primary" @click="nextForm(baseFormRef)" |
||||||
|
>下一步 |
||||||
|
</el-button> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
</el-card> |
||||||
|
<el-card v-show="currentPage === 1" shadow="never"> |
||||||
|
<el-form :model="configForm" ref="configFormRef" v-loading="loading"> |
||||||
|
<el-descriptions :column="2" border> |
||||||
|
<template #title> |
||||||
|
<div style="display: flex; align-items: center"> |
||||||
|
<el-icon size="15" class="mr-1"> |
||||||
|
<Grid /> |
||||||
|
</el-icon> |
||||||
|
<span style="font-weight: 700; font-size: 14px; line-height: 16px" |
||||||
|
>工作流配置信息</span |
||||||
|
> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<el-descriptions-item |
||||||
|
:key="index" |
||||||
|
v-for="(item, index) in configOptions" |
||||||
|
:label="item.displayName" |
||||||
|
label-align="left" |
||||||
|
align="center" |
||||||
|
label-class-name="my-label" |
||||||
|
class-name="my-content" |
||||||
|
width="150px" |
||||||
|
> |
||||||
|
<el-form-item> |
||||||
|
<el-select v-model="configForm[index].values" multiple> |
||||||
|
<el-option |
||||||
|
v-for="(option, index1) in item.options" |
||||||
|
:key="index1" |
||||||
|
:value="option.value" |
||||||
|
:label="option.label" |
||||||
|
/> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
</el-descriptions-item> |
||||||
|
</el-descriptions> |
||||||
|
</el-form> |
||||||
|
<template #footer> |
||||||
|
<div class="flex justify-end"> |
||||||
|
<el-button type="primary" @click="currentPage = 0">上一步</el-button> |
||||||
|
<el-button type="primary" @click="submitPlanForm">提交表单</el-button> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
</el-card> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script setup lang="ts"> |
||||||
|
import { |
||||||
|
PlanFilterConfigOption, |
||||||
|
PlanFilterForm, |
||||||
|
WorkFlowForm, |
||||||
|
} from "@/api/workflow/types"; |
||||||
|
import { Grid } from "@element-plus/icons-vue"; |
||||||
|
import { FormInstance, FormRules } from "element-plus"; |
||||||
|
import { getDomainOptions } from "@/api/domain"; |
||||||
|
import { addPlanFilterConfig, planConfigOption } from "@/api/workflow"; |
||||||
|
import { confirm } from "@/utils/confirm"; |
||||||
|
|
||||||
|
const loading = ref<boolean>(false); |
||||||
|
const currentPage = ref<number>(0); |
||||||
|
const baseFormRef = ref<FormInstance>(); |
||||||
|
const configFormRef = ref<FormInstance>(); |
||||||
|
const formData = ref<WorkFlowForm>({}); |
||||||
|
const configForm = ref<PlanFilterForm[]>([]); |
||||||
|
const baseRules = reactive<FormRules<WorkFlowForm>>({ |
||||||
|
planName: [{ required: true, message: "请输入工作流名称", trigger: "blur" }], |
||||||
|
maxConcurrency: [ |
||||||
|
{ required: true, message: "请输入最大并发数" }, |
||||||
|
{ type: "number", message: "最大并发数必须是一个整数" }, |
||||||
|
], |
||||||
|
startTime: [{ required: true, message: "请选择开始时间", trigger: "blur" }], |
||||||
|
endTime: [{ required: true, message: "请选择结束时间", trigger: "blur" }], |
||||||
|
}); |
||||||
|
const domainOptions = ref<OptionType[]>([]); |
||||||
|
const configOptions = ref<PlanFilterConfigOption[]>([]); |
||||||
|
|
||||||
|
async function loadDomainOptions() { |
||||||
|
await getDomainOptions().then(({ data }) => { |
||||||
|
domainOptions.value = data; |
||||||
|
}); |
||||||
|
} |
||||||
|
const resetForm = (formEl: FormInstance | undefined) => { |
||||||
|
if (!formEl) return; |
||||||
|
formEl.resetFields(); |
||||||
|
}; |
||||||
|
const nextForm = (formEl: FormInstance | undefined) => { |
||||||
|
if (!formEl) return; |
||||||
|
formEl.validate((valid) => { |
||||||
|
if (valid) { |
||||||
|
currentPage.value = 1; |
||||||
|
if (domainOptions.value.length === 0) { |
||||||
|
loadDomainOptions(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
console.log("error submit!"); |
||||||
|
} |
||||||
|
}); |
||||||
|
}; |
||||||
|
const getPlanConfigOption = () => { |
||||||
|
planConfigOption().then(({ data }) => { |
||||||
|
configOptions.value = data; |
||||||
|
for (let i = 0; i < data.length; i++) { |
||||||
|
configForm.value.push({ |
||||||
|
filterName: data[i].filterName, |
||||||
|
values: [], |
||||||
|
}); |
||||||
|
} |
||||||
|
}); |
||||||
|
}; |
||||||
|
const submitPlanForm = () => { |
||||||
|
confirm("确认提交表单吗", () => { |
||||||
|
let data = { |
||||||
|
planFilterForm: configForm.value, |
||||||
|
workFlowForm: formData.value, |
||||||
|
}; |
||||||
|
loading.value = true; |
||||||
|
addPlanFilterConfig(data) |
||||||
|
.then(() => { |
||||||
|
ElMessage.success({ message: "操作成功", duration: 1000 }); |
||||||
|
currentPage.value = 0; |
||||||
|
resetForm(baseFormRef.value); |
||||||
|
resetForm(configFormRef.value); |
||||||
|
}) |
||||||
|
.finally(() => { |
||||||
|
loading.value = false; |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
onMounted(async () => { |
||||||
|
await getPlanConfigOption(); |
||||||
|
}); |
||||||
|
</script> |
||||||
|
|
||||||
|
<style scoped> |
||||||
|
:deep(.my-label) { |
||||||
|
width: 100px !important; |
||||||
|
text-align: center !important; |
||||||
|
background: var(--el-color-white) !important; |
||||||
|
} |
||||||
|
|
||||||
|
:deep(.el-card__body) { |
||||||
|
padding: 10px 5px 0 5px; |
||||||
|
} |
||||||
|
|
||||||
|
:deep(.el-form-item--default) { |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,203 @@ |
|||||||
|
<template> |
||||||
|
<div class="app-container"> |
||||||
|
<div class="search-container"> |
||||||
|
<el-form :model="queryForm"> |
||||||
|
<el-row> |
||||||
|
<el-col :span="6"> |
||||||
|
<el-form-item label="查询条件" prop="selectName"> |
||||||
|
<el-select |
||||||
|
v-model="queryForm.selectName" |
||||||
|
placeholder="请选择" |
||||||
|
style="width: 240px" |
||||||
|
@change="resetSelect" |
||||||
|
clearable |
||||||
|
> |
||||||
|
<el-option |
||||||
|
v-for="item in options" |
||||||
|
:key="item.value" |
||||||
|
:label="item.label" |
||||||
|
:value="item.value" |
||||||
|
/> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
</el-col> |
||||||
|
<el-col :span="6" v-if="queryForm.selectName !== undefined"> |
||||||
|
<el-form-item prop="selectValue"> |
||||||
|
<el-input |
||||||
|
v-model="queryForm.selectValue" |
||||||
|
placeholder="请输入" |
||||||
|
style="width: 300px" |
||||||
|
/> |
||||||
|
</el-form-item> |
||||||
|
</el-col> |
||||||
|
<el-col :span="buttonColSpan"> |
||||||
|
<el-form-item> |
||||||
|
<el-button type="primary" :icon="Search" @click="handleQuery" |
||||||
|
>搜索 |
||||||
|
</el-button> |
||||||
|
</el-form-item> |
||||||
|
</el-col> |
||||||
|
</el-row> |
||||||
|
</el-form> |
||||||
|
</div> |
||||||
|
<el-card shadow="never"> |
||||||
|
<template #header> |
||||||
|
<div class="flex justify-between"> |
||||||
|
<div style="display: flex; align-items: center"> |
||||||
|
<el-icon size="15"> <Grid /> </el-icon> <span |
||||||
|
style="font-weight: 700; font-size: 14px; line-height: 16px" |
||||||
|
>工作流信息</span |
||||||
|
> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<el-button type="primary" :icon="Plus" @click="addWorkflowPage" |
||||||
|
>新增</el-button |
||||||
|
> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<div class="any-table"> |
||||||
|
<el-table :data="tableData" v-loading="loading"> |
||||||
|
<el-table-column align="center" label="工作流名称" prop="planName" /> |
||||||
|
<el-table-column align="center" label="开始时间" prop="startTime" /> |
||||||
|
<el-table-column align="center" label="结束时间" prop="endTime" /> |
||||||
|
<el-table-column align="center" label="创建时间" prop="createTime" /> |
||||||
|
<el-table-column align="center" label="创建人" prop="createTime" /> |
||||||
|
<el-table-column align="center" label="工作流状态" prop="planStatus"> |
||||||
|
<template #default="scope"> |
||||||
|
<el-tag type="primary" v-if="scope.row.planStatus === 0" |
||||||
|
>初始化</el-tag |
||||||
|
> |
||||||
|
<el-tag type="primary" v-if="scope.row.planStatus === 1" |
||||||
|
>待执行</el-tag |
||||||
|
> |
||||||
|
<el-tag type="primary" v-if="scope.row.planStatus === 2" |
||||||
|
>执行中</el-tag |
||||||
|
> |
||||||
|
<el-tag type="success" v-if="scope.row.planStatus === 3" |
||||||
|
>结束</el-tag |
||||||
|
> |
||||||
|
<el-tag type="danger" v-if="scope.row.planStatus === 4" |
||||||
|
>异常结束</el-tag |
||||||
|
> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="操作" align="center"> |
||||||
|
<template #default="scope"> |
||||||
|
<el-button |
||||||
|
type="danger" |
||||||
|
:icon="Delete" |
||||||
|
@click="handleDelete(scope.row.planId)" |
||||||
|
link |
||||||
|
>删除</el-button |
||||||
|
> |
||||||
|
<el-button |
||||||
|
type="primary" |
||||||
|
v-if="scope.row.planStatus === 0" |
||||||
|
:icon="Position" |
||||||
|
link |
||||||
|
@click="handleUpdateStatus(scope.row.planId, 1)" |
||||||
|
>开始</el-button |
||||||
|
> |
||||||
|
<el-button |
||||||
|
type="primary" |
||||||
|
:icon="Position" |
||||||
|
v-else |
||||||
|
link |
||||||
|
@click="handleUpdateStatus(scope.row.planId, 0)" |
||||||
|
>停止</el-button |
||||||
|
> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<pagination |
||||||
|
v-if="total > 0" |
||||||
|
v-model:total="total" |
||||||
|
v-model:page="queryForm.pageNum" |
||||||
|
v-model:limit="queryForm.pageSize" |
||||||
|
@pagination="handleQuery" |
||||||
|
/> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script setup lang="ts"> |
||||||
|
import { Delete, Grid, Plus, Position, Search } from "@element-plus/icons-vue"; |
||||||
|
import { WorkFlowTable } from "@/api/workflow/types"; |
||||||
|
import { |
||||||
|
getWorkflowPage, |
||||||
|
removeWorkflow, |
||||||
|
updateWorkflowStatus, |
||||||
|
} from "@/api/workflow"; |
||||||
|
import { confirm } from "@/utils/confirm"; |
||||||
|
|
||||||
|
const queryForm = ref<SelectForm>({ |
||||||
|
pageNum: 1, |
||||||
|
pageSize: 10, |
||||||
|
}); |
||||||
|
const loading = ref<boolean>(false); |
||||||
|
const total = ref<number>(0); |
||||||
|
const router = useRouter(); |
||||||
|
const tableData = ref<WorkFlowTable[]>([]); |
||||||
|
const options = ref<OptionType[]>([{ label: "工作流名称", value: "planName" }]); |
||||||
|
const resetSelect = () => { |
||||||
|
queryForm.value.selectValue = undefined; |
||||||
|
}; |
||||||
|
const buttonColSpan = computed(() => { |
||||||
|
return queryForm.value.selectName === undefined ? 18 : 12; |
||||||
|
}); |
||||||
|
const handleQuery = () => { |
||||||
|
let selectValue = queryForm.value.selectValue; |
||||||
|
if (selectValue === "" || selectValue === undefined) { |
||||||
|
ElMessage.error({ message: "请选择查询条件", duration: 1000 }); |
||||||
|
return; |
||||||
|
} |
||||||
|
loading.value = true; |
||||||
|
getWorkflowPage(queryForm.value) |
||||||
|
.then(({ data }) => { |
||||||
|
tableData.value = data.list; |
||||||
|
total.value = data.total; |
||||||
|
}) |
||||||
|
.finally(() => { |
||||||
|
loading.value = false; |
||||||
|
}); |
||||||
|
}; |
||||||
|
const addWorkflowPage = () => { |
||||||
|
router.push({ |
||||||
|
path: `/resources/workflow/add`, |
||||||
|
}); |
||||||
|
}; |
||||||
|
const handleDelete = (planId: number) => { |
||||||
|
confirm("确定删除吗", () => { |
||||||
|
loading.value = true; |
||||||
|
removeWorkflow(planId) |
||||||
|
.then(() => { |
||||||
|
ElMessage.success({ message: "操作成功", duration: 1000 }); |
||||||
|
handleQuery(); |
||||||
|
}) |
||||||
|
.finally(() => { |
||||||
|
loading.value = false; |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
const handleUpdateStatus = (planId: number, status: number) => { |
||||||
|
confirm("确定修改该工作流状态吗", () => { |
||||||
|
loading.value = true; |
||||||
|
updateWorkflowStatus(planId, status) |
||||||
|
.then(() => { |
||||||
|
ElMessage.success({ message: "操作成功", duration: 1000 }); |
||||||
|
handleQuery(); |
||||||
|
}) |
||||||
|
.finally(() => { |
||||||
|
loading.value = false; |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style scoped> |
||||||
|
:deep(.el-card__body) { |
||||||
|
padding: 10px 0 0 0; |
||||||
|
} |
||||||
|
</style> |
Loading…
Reference in new issue