<script setup lang="ts" name="Job">
import apis from "@a"
import message from "@@/utils/message"
import dayjs from "dayjs"

const jobTypeOptions = computed(() => {
	return [
		{ label: "接口", value: "1" },
		{ label: "函数", value: "2" }
	]
})
const misfirePolicyOptions = computed(() => {
	return [
		{ label: "立即执行", value: "1" },
		{ label: "执行一次", value: "2" },
		{ label: "放弃执行", value: "3" }
	]
})
const concurrentOptions = computed(() => {
	return [
		{ label: "允许", value: "2" },
		{ label: "禁止", value: "1" }
	]
})
const jobKeysOptions = ref<any[]>([])

const tableRef = ref()
const modalRef = ref()
const opts = reactive<any>({
	columns: [
		{ field: "jobId", name: "编码", width: 100, visible: false, isSort: false, tooltip: true },
		{ field: "jobName", name: "名称", width: "auto", isSort: true, visible: true },
		{ field: "jobGroup", name: "任务分组", width: 100, isSort: true, visible: true },
		{ field: "cronExpression", name: "Cron表达式", width: "auto", isSort: false, visible: true },
		{ field: "invokeTarget", name: "调用目标", width: "auto", isSort: false, visible: true },
		{ field: "status", name: "状态", width: 100, isSort: true, visible: true },
		{ field: "execCount", name: "执行次数", width: 100, isSort: true, visible: true },
		{ field: "failCount", name: "失败次数", width: 100, isSort: true, visible: true },
		{ field: "lastExecTime", name: "上次执行时间", width: 155, isSort: true, visible: true },
		{ field: "nextExecTime", name: "下一次执行时间", width: 155, isSort: true, visible: true },
		{ field: "createdAt", name: "创建时间", width: 185, isSort: true, visible: true },
		{ field: "actions", name: `操作`, width: 150 }
	],
	queryParams: {
		jobName: undefined,
		jobType: undefined,
		invokeTarget: undefined,
		status: undefined
	},
	searchFormItems: [
		{
			field: "jobName",
			label: "名称",
			class: "w-100",
			component: "I",
			listeners: {
				keyup: (e: KeyboardEvent) => {
					if (e.code == "Enter") {
						handleQuery()
					}
				}
			}
		},
		{
			field: "jobGroup",
			label: "任务分组",
			class: "w-100",
			component: "Dict",
			props: {
				showAll: true,
				type: "select",
				clearable: true,
				placeholder: "请选择任务分组",
				dictType: "sys_job_group"
			}
		},
		{
			field: "jobType",
			label: "调用类型",
			class: "w-100",
			component: "VS",
			placeholder: "请选择调用类型",
			data: () => jobTypeOptions.value,
			props: {
				showAll: true,
				valueIsNumber: true,
				type: "select",
				clearable: true
			}
		},
		{
			field: "invokeTarget",
			label: "调用目标",
			class: "w-100",
			component: "I",
			listeners: {
				keyup: (e: KeyboardEvent) => {
					if (e.code == "Enter") {
						handleQuery()
					}
				}
			}
		},
		{
			field: "status",
			label: "状态",
			class: "w-100",
			component: "Dict",
			props: {
				showAll: true,
				type: "select",
				clearable: true,
				valueIsNumber: true,
				placeholder: "请选择状态",
				dictType: "sys_job_status"
			}
		}
	] as any,
	permission: "schedule:job",
	handleFuns: {},
	customBtns: [],
	tableListFun: apis.schedule.jobApi.listJob,
	getEntityFun: apis.schedule.jobApi.getJob,
	deleteEntityFun: apis.schedule.jobApi.delJob,
	formItems: [
		{
			field: "jobName",
			label: "名称",
			class: "w-100",
			component: "I",
			required: true
		},
		{
			field: "jobGroup",
			label: "任务分组",
			class: "w-100",
			required: true,
			component: "Dict",
			props: {
				type: "select",
				clearable: true,
				placeholder: "请选择任务分组",
				dictType: "sys_job_group"
			}
		},
		{
			field: "jobType",
			label: "调用类型",
			class: "w-100",
			required: true,
			component: "VS",
			placeholder: "请选择调用类型",
			data: () => jobTypeOptions.value,
			props: {
				type: "radio",
				valueIsNumber: true,
				clearable: true
			},
			listeners: {
				change: () => {
					form.value.invokeTarget = ""
				}
			}
		},
		{
			show: () => form.value.jobType == 1,
			field: "invokeTarget",
			label: "调用目标",
			class: "w-100",
			component: "I",
			required: true,
			placeholder: "请填写调用接口"
		},
		{
			show: () => form.value.jobType == 2,
			field: "invokeTarget",
			label: "调用目标",
			class: "w-100",
			component: "VS",
			required: true,
			data: () => jobKeysOptions.value,
			props: {
				type: "select",
				clearable: true,
				placeholder: "请选择调用函数"
			}
		},
		{
			field: "args",
			label: "目标参数",
			class: "w-100",
			component: "I",
			required: false
		},
		{
			field: "cronExpression",
			label: "Cron表达式",
			class: "w-100",
			component: "I",
			required: true
		},
		{
			field: "misfirePolicy",
			label: "执行策略",
			class: "w-100",
			required: false,
			component: "VS",
			placeholder: "请选择执行策略",
			data: () => misfirePolicyOptions.value,
			props: {
				type: "radio",
				valueIsNumber: true,
				clearable: true
			}
		},
		{
			field: "concurrent",
			label: "是否并发",
			class: "w-100",
			required: false,
			component: "VS",
			placeholder: "请选择是否并发",
			data: () => concurrentOptions.value,
			props: {
				type: "radio",
				valueIsNumber: true,
				clearable: true
			}
		}
	] as any,
	resetForm: () => {
		form.value = emptyFormData.value
	},
	emptyFormData: {
		jobId: undefined,
		jobName: undefined,
		jobGroup: "DEFAULT",
		jobType: 1,
		cronExpression: undefined,
		invokeTarget: undefined,
		args: undefined,
		misfirePolicy: 1,
		concurrent: undefined,
		status: 2
	}
})
const { emptyFormData } = toRefs(opts)
const queryParams = ref(Object.assign({}, opts.queryParams))
const form = ref<any>(emptyFormData.value)

/** 修改按钮操作 */
function handleUpdate(row: any) {
	tableRef.value.defaultHandleFuns.handleUpdate("", row)
}
/** 删除按钮操作 */
function handleDelete(rows: any[]) {
	tableRef.value.defaultHandleFuns.handleDelete("", rows)
}
/** 提交按钮 */
function submitForm() {
	if (form.value.jobId != undefined) {
		apis.schedule.jobApi.updateJob(form.value).then(() => {
			message.msgSuccess("修改成功")
			handleQuery()
		})
	} else {
		apis.schedule.jobApi.addJob(form.value).then(() => {
			message.msgSuccess("新增成功")
			handleQuery()
		})
	}
}
/** 查询按钮 */
function handleQuery() {
	tableRef.value?.search()
}
/** 查询重置按钮 */
function resetQuery() {
	queryParams.value = opts.queryParams
}

function handleStart(row: any) {
	message
		.confirm("是否确认启动任务？", "提示", {
			confirmButtonText: "确定",
			cancelButtonText: "取消",
			type: "warning"
		})
		.then(() => {
			apis.schedule.jobApi.startJob(row.jobId).then(() => {
				message.msgSuccess("启动成功")
				handleQuery()
			})
		})
}

function handleStop(row: any) {
	message
		.confirm("是否确认停止任务？", "提示", {
			confirmButtonText: "确定",
			cancelButtonText: "取消",
			type: "warning"
		})
		.then(() => {
			apis.schedule.jobApi.stopJob(row.jobId).then(() => {
				message.msgSuccess("停止成功")
				handleQuery()
			})
		})
}

function init() {
	apis.schedule.jobApi.getJobKeys().then((res: any) => {
		if (res.data) {
			jobKeysOptions.value = Object.keys(res.data).map((key: any) => {
				return {
					value: key,
					label: res.data[key]
				}
			})
		}
	})
}

onMounted(() => setTimeout(init, 100))
</script>

<template>
	<div class="app-container">
		<VbDataTable
			ref="tableRef"
			:handle-perm="opts.permission"
			:handle-funs="opts.handleFuns"
			:search-form-items="opts.searchFormItems"
			:columns="opts.columns"
			:custom-btns="opts.customBtns"
			:remote-fun="opts.tableListFun"
			:get-entity-fun="opts.getEntityFun"
			:delete-entity-fun="opts.deleteEntityFun"
			sortField="createdAt"
			sort-order="desc"
			:modal="modalRef"
			:reset-form-fun="opts.resetForm"
			v-model:form-data="form"
			:query-params="queryParams"
			:check-multiple="true"
			:has-checkbox="true"
			:reset-search-form-fun="resetQuery"
			:custom-search-fun="handleQuery">
			<template #jobGroup="{ row }">
				<DictTag :value="row.jobGroup" type="sys_job_group"></DictTag>
			</template>
			<template #status="{ row }">
				<DictTag :value="row.status" valueIsNumber type="sys_job_status"></DictTag>
			</template>
			<template #createdAt="{ row }">
				<span>{{ dayjs(row.createdAt).format("YYYY-MM-DD HH:mm:ss") }}</span>
			</template>
			<template #lastExecTime="{ row }">
				<span>
					{{
						row.lastExecTime < 20240000000000
							? "-"
							: dayjs(row.lastExecTime + "", "YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss")
					}}
				</span>
			</template>
			<template #nextExecTime="{ row }">
				<span>
					{{
						row.nextExecTime < 20240000000000
							? "-"
							: dayjs(row.nextExecTime + "", "YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss")
					}}
				</span>
			</template>
			<template #actions="{ row }">
				<vb-tooltip content="修改" placement="top">
					<el-button link type="primary" @click="handleUpdate(row)">
						<template #icon>
							<VbIcon icon-name="notepad-edit" icon-type="duotone" class="fs-3"></VbIcon>
						</template>
					</el-button>
				</vb-tooltip>
				<vb-tooltip v-if="row.status == 1" content="启动任务" placement="top">
					<el-button link type="success" @click="handleStart(row)">
						<template #icon>
							<VbIcon icon-name="right-square" icon-type="duotone" class="fs-3"></VbIcon>
						</template>
					</el-button>
				</vb-tooltip>
				<vb-tooltip v-if="row.status == 2" content="停止任务" placement="top">
					<el-button link type="danger" @click="handleStop(row)">
						<template #icon>
							<VbIcon icon-name="cross-square" icon-type="duotone" class="fs-3"></VbIcon>
						</template>
					</el-button>
				</vb-tooltip>
				<vb-tooltip content="删除" placement="top">
					<el-button link type="primary" @click="handleDelete([row])">
						<template #icon>
							<VbIcon icon-name="trash-square" icon-type="duotone" class="fs-3"></VbIcon>
						</template>
					</el-button>
				</vb-tooltip>
			</template>
		</VbDataTable>
		<VbModal
			v-model:modal="modalRef"
			:title="opts.modalTitle"
			:form-items="opts.formItems as any"
			:form-data="form"
			@confirm="submitForm"
			append-to-body></VbModal>
	</div>
</template>
