|
@@ -4,7 +4,10 @@
|
|
|
<template #header>
|
|
<template #header>
|
|
|
<div class="card-header">
|
|
<div class="card-header">
|
|
|
<span>流程管理</span>
|
|
<span>流程管理</span>
|
|
|
- <el-button type="primary" @click="handleAdd">新增流程</el-button>
|
|
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <el-button type="warning" @click="openMigrateDialog" style="margin-right: 8px;">流程迁移</el-button>
|
|
|
|
|
+ <el-button type="primary" @click="handleAdd">新增流程</el-button>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
@@ -219,6 +222,31 @@
|
|
|
<el-button type="primary" @click="saveOptions">保存</el-button>
|
|
<el-button type="primary" @click="saveOptions">保存</el-button>
|
|
|
</template>
|
|
</template>
|
|
|
</el-dialog>
|
|
</el-dialog>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 流程迁移弹窗 -->
|
|
|
|
|
+ <el-dialog v-model="migrateDialogVisible" title="流程迁移" width="550px">
|
|
|
|
|
+ <el-form label-width="100px">
|
|
|
|
|
+ <el-form-item label="源流程版本">
|
|
|
|
|
+ <el-select v-model="migrateFromId" placeholder="请选择旧版本流程" style="width: 100%" @change="onMigrateFromChange">
|
|
|
|
|
+ <el-option v-for="def in migrateDefinitionList" :key="def.id" :label="`${def.name}(v${def.version})${def.status === 0 ? ' [设计]' : def.status === 1 ? ' [已发布]' : ' [已停用]'}`" :value="def.id" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="目标版本">
|
|
|
|
|
+ <el-select v-model="migrateToId" placeholder="请选择新版本流程" style="width: 100%" :disabled="!migrateFromId">
|
|
|
|
|
+ <el-option v-for="def in migrateTargetList" :key="def.id" :label="`${def.name}(v${def.version})${def.status === 0 ? ' [设计]' : def.status === 1 ? ' [已发布]' : ' [已停用]'}`" :value="def.id" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ <el-alert type="warning" :closable="false" style="margin-bottom: 12px;">
|
|
|
|
|
+ <template #title>
|
|
|
|
|
+ 迁移将把所有运行中的实例从源版本切换到目标版本,节点按名称匹配。不兼容的实例将被跳过。操作不可逆,请确认后执行。
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-alert>
|
|
|
|
|
+ <template #footer>
|
|
|
|
|
+ <el-button @click="migrateDialogVisible = false">取消</el-button>
|
|
|
|
|
+ <el-button type="warning" :disabled="!migrateFromId || !migrateToId" :loading="migrating" @click="confirmMigrate">确认迁移</el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-dialog>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
@@ -229,6 +257,7 @@ import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
import { QuestionFilled } from '@element-plus/icons-vue'
|
|
import { QuestionFilled } from '@element-plus/icons-vue'
|
|
|
import type { FormInstance, FormRules } from 'element-plus'
|
|
import type { FormInstance, FormRules } from 'element-plus'
|
|
|
import { listDefinition, getDefinition, updateDefinition, deleteDefinition, publishDefinition, stopDefinition, enableDefinition } from '@/api/flow/definition'
|
|
import { listDefinition, getDefinition, updateDefinition, deleteDefinition, publishDefinition, stopDefinition, enableDefinition } from '@/api/flow/definition'
|
|
|
|
|
+import { migrateInstances } from '@/api/flow/instance'
|
|
|
import type { FlowDefinition, FormField, FormFieldOption } from '@/types/flow'
|
|
import type { FlowDefinition, FormField, FormFieldOption } from '@/types/flow'
|
|
|
|
|
|
|
|
const router = useRouter()
|
|
const router = useRouter()
|
|
@@ -495,6 +524,48 @@ async function handleDelete(row: FlowDefinition) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// 流程迁移
|
|
|
|
|
+const migrateDialogVisible = ref(false)
|
|
|
|
|
+const migrateFromId = ref<number | null>(null)
|
|
|
|
|
+const migrateToId = ref<number | null>(null)
|
|
|
|
|
+const migrateDefinitionList = ref<FlowDefinition[]>([])
|
|
|
|
|
+const migrateTargetList = ref<FlowDefinition[]>([])
|
|
|
|
|
+const migrating = ref(false)
|
|
|
|
|
+
|
|
|
|
|
+function openMigrateDialog() {
|
|
|
|
|
+ migrateFromId.value = null
|
|
|
|
|
+ migrateToId.value = null
|
|
|
|
|
+ migrateTargetList.value = []
|
|
|
|
|
+ migrateDefinitionList.value = [...tableData.value]
|
|
|
|
|
+ migrateDialogVisible.value = true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function onMigrateFromChange() {
|
|
|
|
|
+ migrateToId.value = null
|
|
|
|
|
+ const from = migrateDefinitionList.value.find(d => d.id === migrateFromId.value)
|
|
|
|
|
+ if (!from) { migrateTargetList.value = []; return }
|
|
|
|
|
+ migrateTargetList.value = migrateDefinitionList.value.filter(d => d.code === from.code && d.id !== from.id)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+async function confirmMigrate() {
|
|
|
|
|
+ if (!migrateFromId.value || !migrateToId.value) return
|
|
|
|
|
+ try {
|
|
|
|
|
+ await ElMessageBox.confirm(
|
|
|
|
|
+ `确认将所有运行中的实例从源版本 v${migrateDefinitionList.value.find(d => d.id === migrateFromId.value)?.version} 迁移到目标版本 v${migrateTargetList.value.find(d => d.id === migrateToId.value)?.version} 吗?此操作不可逆。`,
|
|
|
|
|
+ '确认迁移', { type: 'warning' }
|
|
|
|
|
+ )
|
|
|
|
|
+ } catch { return }
|
|
|
|
|
+ migrating.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await migrateInstances(migrateFromId.value, migrateToId.value)
|
|
|
|
|
+ ElMessage.success(`迁移完成,共迁移 ${res.migratedCount} 个实例`)
|
|
|
|
|
+ migrateDialogVisible.value = false
|
|
|
|
|
+ loadData()
|
|
|
|
|
+ } catch (e: any) {
|
|
|
|
|
+ ElMessage.error(e?.message || '迁移失败')
|
|
|
|
|
+ } finally { migrating.value = false }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
onMounted(loadData)
|
|
onMounted(loadData)
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|