import { NSwitch, NTag, NButton, NSpace, NFlex, NText, NFormItem, NSelect } from 'naive-ui' import { useRoute, useRouter } from 'vue-router' import { useStore } from '@autoDeploy/useStore' import { useDialog, useTable, useTablePage, useModal, useFormHooks, useForm, useModalHooks, useMessage, } from '@baota/naive-ui/hooks' import { useStore as useWorkflowViewStore } from '@autoDeploy/children/workflowView/useStore' import { useError } from '@baota/hooks/error' import AddWorkflowModal from './components/WorkflowModal' import HistoryModal from './components/HistoryModal' import HistoryLogsModal from './components/HistoryLogsModal' import CAManageModal from './components/CAManageModal' import { $t } from '@/locales' import { router } from '@router/index' import { CACertificateAuthorization } from '@config/data' import SvgIcon from '@components/SvgIcon' import { isEmail } from '@baota/utils/business' import type { WorkflowItem, WorkflowListParams, WorkflowHistoryParams, WorkflowHistoryItem } from '@/types/workflow' import type { DataTableColumn } from 'naive-ui' import type { TableColumn } from 'naive-ui/es/data-table/src/interface' import type { EabItem, EabListParams } from '@/types/access' const { refreshTable, fetchWorkflowList, fetchWorkflowHistory, workflowFormData, deleteExistingWorkflow, executeExistingWorkflow, stopExistingWorkflow, setWorkflowActive, setWorkflowExecType, caFormData, fetchEabList, addNewEab, deleteExistingEab, resetCaForm, } = useStore() const { isEdit, workDefalutNodeData, resetWorkflowData, workflowData, detectionRefresh } = useWorkflowViewStore() const { handleError } = useError() const { useFormSlot } = useFormHooks() /** * @description 状态列 * @param {string} key - 状态列的key * @returns {DataTableColumn[]} 返回状态列配置数组 */ const statusCol = >(key: string, title: string): TableColumn => ({ title, key, width: 100, render: (row: T) => { const statusMap: Record = { success: { type: 'success', text: $t('t_0_1747895713179') }, fail: { type: 'error', text: $t('t_4_1746773348957') }, running: { type: 'warning', text: $t('t_1_1747895712756') }, } const status = statusMap[row[key] as string] || { type: 'default', text: $t('t_1_1746773348701'), } if (row[key] === 'running') refreshTable.value = true return ( {status.text} ) }, }) /** * @description 工作流业务逻辑控制器 * @function useController */ export const useController = () => { // 获取当前路由 const route = useRoute() // 获取路由实例 const router = useRouter() // 判断是否为子路由 const hasChildRoutes = computed(() => route.path !== '/auto-deploy') /** * @description 创建表格列配置 * @returns {DataTableColumn[]} 返回表格列配置数组 */ const createColumns = (): DataTableColumn[] => [ { title: $t('t_0_1745215914686'), key: 'name', width: 200, ellipsis: { tooltip: true, }, }, { title: $t('t_1_1746590060448'), key: 'type', width: 100, render: (row: WorkflowItem) => ( { handleSetWorkflowExecType(row) }} checkedValue={'auto'} uncheckedValue={'manual'} /> {row.exec_type === 'auto' ? $t('t_2_1745215915397') : $t('t_3_1745215914237')} ), }, { title: $t('t_7_1745215914189'), key: 'created_at', width: 180, render: (row: WorkflowItem) => row.create_time || '-', }, statusCol('last_run_status', $t('t_0_1746677882486')), { title: $t('t_8_1745215914610'), key: 'actions', fixed: 'right', align: 'right', width: 220, render: (row: WorkflowItem) => ( handleViewHistory(row)}> {$t('t_9_1745215914666')} handleExecuteWorkflow(row)}> {$t('t_10_1745215914342')} handleEditWorkflow(row)}> {$t('t_11_1745215915429')} handleDeleteWorkflow(row)}> {$t('t_12_1745215914312')} ), }, ] // 表格实例 const { component: WorkflowTable, loading, param, data, total, fetch, } = useTable({ config: createColumns(), request: fetchWorkflowList, defaultValue: { p: 1, limit: 10, search: '', }, watchValue: ['p', 'limit'], }) // 分页实例 const { component: WorkflowTablePage } = useTablePage({ param, total, alias: { page: 'p', pageSize: 'limit', }, }) // 节流渲染 const throttleFn = useThrottleFn(() => { setTimeout(() => { fetch() refreshTable.value = false }, 1000) }, 100) watch( () => refreshTable.value, (val) => { if (val) throttleFn() }, ) /** * @description 打开添加工作流弹窗 */ const handleAddWorkflow = () => { detectionRefresh.value = true useModal({ title: $t('t_5_1746667590676'), component: AddWorkflowModal, footer: true, area: 500, onUpdateShow(show) { if (!show) fetch() }, }) } /** * @description 查看工作流执行历史 * @param {number} workflowId - 工作流ID */ const handleViewHistory = async (workflow: WorkflowItem) => { useModal({ title: workflow ? `【${workflow.name}】 - ${$t('t_9_1745215914666')}` : $t('t_9_1745215914666'), component: HistoryModal, area: 850, componentProps: { id: workflow.id.toString() }, }) } /** * @description 执行工作流 * @param {WorkflowItem} workflow - 工作流对象 */ const handleExecuteWorkflow = async ({ name, id }: WorkflowItem) => { useDialog({ title: $t('t_13_1745215915455'), content: $t('t_2_1745227839794', { name }), onPositiveClick: async () => { await executeExistingWorkflow(id) await fetch() }, }) } /** * @description 设置工作流运行方式 * @param {WorkflowItem} workflow - 工作流对象 */ const handleSetWorkflowExecType = ({ id, exec_type }: WorkflowItem) => { useDialog({ title: exec_type === 'manual' ? $t('t_2_1745457488661') : $t('t_3_1745457486983'), content: exec_type === 'manual' ? $t('t_4_1745457497303') : $t('t_5_1745457494695'), onPositiveClick: () => setWorkflowExecType({ id, exec_type }), onNegativeClick: fetch, onClose: fetch, }) } /** * @description 切换工作流状态 * @param active - 工作流状态 */ const handleChangeActive = ({ id, active }: WorkflowItem) => { useDialog({ title: !active ? $t('t_6_1745457487560') : $t('t_7_1745457487185'), content: !active ? $t('t_8_1745457496621') : $t('t_9_1745457500045'), onPositiveClick: () => setWorkflowActive({ id, active }), onNegativeClick: fetch, onClose: fetch, }) } /** * @description 编辑工作流 * @param {WorkflowItem} workflow - 工作流对象 * @todo 实现工作流编辑功能 */ const handleEditWorkflow = (workflow: WorkflowItem) => { const content = JSON.parse(workflow.content) isEdit.value = true workflowData.value = { id: workflow.id, name: workflow.name, content: content, exec_type: workflow.exec_type, active: workflow.active, } workDefalutNodeData.value = { id: workflow.id, name: workflow.name, childNode: content, } detectionRefresh.value = true router.push(`/auto-deploy/workflow-view?isEdit=true`) } /** * @description 删除工作流 * @param {WorkflowItem} workflow - 工作流对象 */ const handleDeleteWorkflow = (workflow: WorkflowItem) => { useDialog({ title: $t('t_16_1745215915209'), content: $t('t_3_1745227841567', { name: workflow.name }), onPositiveClick: async () => { await deleteExistingWorkflow(workflow.id) await fetch() }, }) } /** * @description 检测是否需要添加工作流 */ const isDetectionAddWorkflow = () => { const { type } = route.query if (type?.includes('create')) { handleAddWorkflow() router.push({ query: {} }) } } /** * @description 检测是否需要打开CA授权管理弹窗 */ const isDetectionOpenCAManage = () => { const { type } = route.query if (type?.includes('caManage')) { handleOpenCAManage() router.push({ query: {} }) } } /** * @description 检测是否需要打开添加CA授权弹窗 */ const isDetectionOpenAddCAForm = () => { const { type } = route.query if (type?.includes('addCAForm')) { handleOpenCAManage({ type: 'addCAForm' }) router.push({ query: {} }) } } /** * @description 打开CA授权管理弹窗 */ const handleOpenCAManage = ({ type }: { type: string } = { type: '' }) => { useModal({ title: $t('t_0_1747903670020'), component: CAManageModal, componentProps: { type }, area: 780, }) } return { WorkflowTable, WorkflowTablePage, isDetectionAddWorkflow, // 检测是否需要添加工作流 isDetectionOpenCAManage, // 检测是否需要打开CA授权管理弹窗 isDetectionOpenAddCAForm, // 检测是否需要打开添加CA授权弹窗 handleViewHistory, // 查看工作流执行历史 handleAddWorkflow, // 打开添加工作流弹窗 handleChangeActive, // 切换工作流状态 handleSetWorkflowExecType, // 设置工作流运行方式 handleExecuteWorkflow, // 执行工作流 handleEditWorkflow, // 编辑工作流 handleDeleteWorkflow, // 删除工作流 handleOpenCAManage, // 打开CA授权管理弹窗 hasChildRoutes, fetch, data, loading, param, } } /** * @description 添加工作流业务逻辑控制器 * @returns {Object} 返回添加工作流业务逻辑控制器实例 */ export const useAddWorkflowController = () => { const { confirm } = useModalHooks() // 表单配置 const config = computed(() => [useFormSlot('template')]) // 表单实例 const { component: AddWorkflowForm, data } = useForm({ config, rules: {}, defaultValue: workflowFormData, }) // 确认添加工作流 confirm(async (close) => { try { close() resetWorkflowData() router.push(`/auto-deploy/workflow-view?type=${data.value.templateType}`) } catch (error) { handleError(error) } }) return { AddWorkflowForm } } /** * @description 工作流历史记录业务逻辑控制器 * @param {number} workflowId - 工作流ID * @returns {Object} 返回工作流历史记录业务逻辑控制器实例 */ export const useHistoryController = (id: string) => { /** * @description 工作流历史详情 * @param {number} workflowId - 工作流ID */ const handleViewHistoryDetail = async (workflowId: string) => { useModal({ title: $t('t_0_1746579648713'), component: HistoryLogsModal, area: 730, componentProps: { id: workflowId }, }) } /** * @description 停止工作流执行 * @param {WorkflowHistoryItem} historyItem - 工作流历史记录项 */ const handleStopWorkflow = async (historyItem: WorkflowHistoryItem) => { useDialog({ title: $t('t_0_1749204565782'), content: $t('t_1_1749204570473'), onPositiveClick: async () => { await stopExistingWorkflow(historyItem.id) await fetch() // 刷新历史记录表格 // 触发外部主表格刷新 refreshTable.value = true }, }) } /** * @description 创建历史记录表格列配置 * @returns {DataTableColumn[]} 返回表格列配置数组 */ const createColumns = (): DataTableColumn[] => [ { title: $t('t_4_1745227838558'), key: 'create_time', width: 200, render: (row: WorkflowHistoryItem) => { // 处理数字类型的时间戳 return row.create_time ? row.create_time : '-' }, }, { title: $t('t_5_1745227839906'), key: 'end_time', width: 200, render: (row: WorkflowHistoryItem) => { // 处理数字类型的时间戳 return row.end_time ? row.end_time : '-' }, }, { title: $t('t_6_1745227838798'), key: 'exec_type', width: 120, render: (row: WorkflowHistoryItem) => ( {row.exec_type === 'auto' ? $t('t_2_1745215915397') : $t('t_3_1745215914237')} ), }, statusCol('status', $t('t_7_1745227838093')), { title: $t('t_8_1745215914610'), key: 'actions', fixed: 'right', align: 'right', width: 180, render: (row: WorkflowHistoryItem) => ( {row.status === 'running' && ( handleStopWorkflow(row)}> {$t('t_0_1749204565782')} )} handleViewHistoryDetail(row.id.toString())} > {$t('t_12_1745227838814')} ), }, ] // 表格实例 const { component: WorkflowHistoryTable, loading, param, total, fetch, } = useTable({ config: createColumns(), request: fetchWorkflowHistory, defaultValue: { id, p: 1, limit: 10, }, watchValue: ['p', 'limit'], }) const { component: WorkflowHistoryTablePage } = useTablePage({ param, total, alias: { page: 'p', pageSize: 'limit', }, }) return { WorkflowHistoryTable, WorkflowHistoryTablePage, loading, fetch, } } /** * @description CA授权管理业务逻辑控制器 * @returns {Object} 返回CA授权管理控制器对象 */ export const useCAManageController = (props: { type: string }) => { const { handleError } = useError() // 表格配置 const columns = [ { title: $t('t_2_1745289353944'), key: 'name', ellipsis: { tooltip: true, }, }, { title: $t('t_1_1745735764953'), key: 'mail', ellipsis: { tooltip: true, }, }, { title: $t('t_9_1747903669360'), key: 'ca', width: 120, render: (row: EabItem) => ( {CACertificateAuthorization[row.ca as keyof typeof CACertificateAuthorization].name} ), }, { title: $t('t_7_1745215914189'), key: 'create_time', width: 180, render: (row: EabItem) => (row.create_time ? row.create_time : '--'), }, { title: $t('t_8_1745215914610'), key: 'actions', width: 80, align: 'right' as const, fixed: 'right' as const, render: (row: EabItem) => ( confirmDelete(row.id.toString())}> {$t('t_12_1745215914312')} ), }, ] // 表格实例 const { component: CATable, loading, param, total, fetch, } = useTable({ config: columns, request: fetchEabList, defaultValue: { p: 1, limit: 10, }, watchValue: ['p', 'limit'], }) // 分页实例 const { component: CATablePage } = useTablePage({ param, total, alias: { page: 'p', pageSize: 'limit', }, }) /** * 确认删除CA授权 * @param {string} id - CA授权ID */ const confirmDelete = (id: string) => { useDialog({ title: $t('t_2_1747903672640'), content: $t('t_3_1747903672833'), onPositiveClick: async () => { try { await deleteExistingEab(id) await fetch() } catch (error) { handleError(error) } }, }) } /** * 打开添加CA授权表单 */ const handleOpenAddForm = () => { resetCaForm() useModal({ title: $t('t_4_1747903685371'), area: 500, component: () => import('./components/CAManageForm').then((m) => m.default), footer: true, onUpdateShow: (show) => { if (!show) fetch() }, }) } // 挂载时获取数据 onMounted(() => { fetch() if (props.type === 'addCAForm') handleOpenAddForm() }) return { CATable, CATablePage, loading, param, total, fetch, handleOpenAddForm, } } /** * @description CA授权表单控制器 * @returns {Object} 返回CA授权表单控制器对象 */ export const useCAFormController = () => { const { handleError } = useError() const message = useMessage() const { confirm } = useModalHooks() const { useFormInput, useFormCustom } = useFormHooks() // 表单验证规则 const formRules = { name: { required: true, message: $t('t_25_1746773349596'), trigger: ['blur', 'input'], }, mail: { required: true, message: $t('t_6_1747817644358'), trigger: ['blur', 'input'], validator: (rule: any, value: string) => { if (!value) return true if (!isEmail(value)) { return new Error($t('t_7_1747817613773')) } return true }, }, Kid: { required: true, message: $t('t_5_1747903671439'), trigger: ['blur', 'input'], }, HmacEncoded: { required: true, message: $t('t_6_1747903672931'), trigger: ['blur', 'input'], }, ca: { required: true, message: $t('t_7_1747903678624'), trigger: 'change', }, } // 渲染标签函数 const renderLabel = (option: { value: string; label: string }): VNode => { return ( {option.label} ) } // 渲染单选标签函数 const renderSingleSelectTag = ({ option }: Record): VNode => { return ( {option.label ? ( renderLabel(option) ) : ( {$t('t_7_1747903678624')} )} ) } // 获取CA提供商选项 const caOptions = Object.values(CACertificateAuthorization).map((item) => ({ label: item.name, value: item.type, })) // 表单配置 const formConfig = [ useFormInput($t('t_2_1745289353944'), 'name', { placeholder: $t('t_8_1747903675532'), }), useFormInput($t('t_1_1745735764953'), 'mail', { placeholder: $t('t_0_1747965909665'), }), useFormCustom(() => { return ( { return {$t('t_7_1747903678624')} }, }} /> ) }), useFormInput($t('t_10_1747903662994'), 'Kid', { placeholder: $t('t_11_1747903674802'), }), useFormInput($t('t_12_1747903662994'), 'HmacEncoded', { type: 'textarea', placeholder: $t('t_13_1747903673007'), rows: 3, }), ] // 提交表单 const submitForm = async (formData: any) => { try { await addNewEab(formData) message.success($t('t_40_1745289355715')) return true } catch (error) { handleError(error) return false } } // 表单实例 const { component: CAForm } = useForm({ config: formConfig, rules: formRules, defaultValue: caFormData, request: submitForm, }) // 确认提交表单 confirm(async (close) => { try { await submitForm(caFormData.value) close() } catch (error) { handleError(error) } }) return { CAForm, } }