20260928220222
This commit is contained in:
1 parent
cbd49ded6f
commit
ebeeca45b6
3 files changed
+127
-32
No files matched your search
@@ -1,18 +1,35 @@
|
||||
<script setup>
|
||||
/**
|
||||
* 系统管理 —— 流程管理:流程定义 / 流程版本 / 流程绑定 / 运行监控 四个页签。
|
||||
* 系统管理 —— 流程管理:流程定义 / 流程绑定 / 运行监控 三个页签。
|
||||
*
|
||||
* 读取全部走通用模块接口(列表视图 v_wf_*,四张视图都已注册且只读),
|
||||
* 读取全部走通用模块接口(列表视图 v_wf_*,都已注册且只读),
|
||||
* 写入走流程服务:发布、停用、复制版本、绑定、删除都要经过服务端的发布校验与版本约束
|
||||
* (设计 §6.2 / §11 / §12)——流程定义不在列表里直接编辑,b_save_table 为空,通用保存接口不参与。
|
||||
*
|
||||
* 页签切换用 v-show 而不是 v-if:四个列表各自保留滚动位置、查询条件与分页,
|
||||
* 流程版本不单独占页签:版本是某个定义的从属数据,在流程定义行上点「版本」开抽屉查看,
|
||||
* 抽屉内仍是同一份只读视图 v_wf_version + 发布 / 停用 / 复制动作。
|
||||
*
|
||||
* 运行监控是「先找单、再看流程」:列表只回答有哪些实例,行上「查看」进审批详情抽屉
|
||||
* (复用审批中心的 ApprovalDetailDrawer,只读:实例摘要 + 运行态流程图 + 节点办理明细)。
|
||||
*
|
||||
* 页签切换用 v-show 而不是 v-if:各列表各自保留滚动位置、查询条件与分页,
|
||||
* 切回来不会重新加载。
|
||||
*/
|
||||
import { computed, reactive, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { Ban, Copy, Plus, Send, SquarePen, Trash2 } from '@lucide/vue'
|
||||
import { Button, Checkbox, Form, FormItem, Input, Message, Modal, Select, Tabs } from '@/components/ui'
|
||||
import { Ban, Copy, Eye, Layers, Plus, Send, SquarePen, Trash2 } from '@lucide/vue'
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
Drawer,
|
||||
Form,
|
||||
FormItem,
|
||||
Input,
|
||||
Message,
|
||||
Modal,
|
||||
Select,
|
||||
Tabs,
|
||||
} from '@/components/ui'
|
||||
import { FmsModuleListPage } from '@/components/fms-module-list'
|
||||
import { loadDataApi } from '@/services/api'
|
||||
import { escapeSqlText } from '@/components/fms-module-common/queryUtils'
|
||||
@@ -24,18 +41,18 @@ import {
|
||||
retireWorkflowVersionApi,
|
||||
saveWorkflowBindingApi,
|
||||
} from '@/services/workflow'
|
||||
import ApprovalDetailDrawer from '@/views/approval/components/ApprovalDetailDrawer.vue'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const TAB_ITEMS = [
|
||||
{ key: 'definition', label: '流程定义' },
|
||||
{ key: 'version', label: '流程版本' },
|
||||
{ key: 'binding', label: '流程绑定' },
|
||||
{ key: 'instance', label: '运行监控' },
|
||||
]
|
||||
const activeTab = ref('definition')
|
||||
|
||||
/** 各列表的刷新入口(FmsModuleListPage 暴露 reload) */
|
||||
/** 列表刷新入口(FmsModuleListPage 暴露 reload);版本列表在抽屉里,见下方「流程版本」 */
|
||||
const definitionListRef = ref(null)
|
||||
const versionListRef = ref(null)
|
||||
const bindingListRef = ref(null)
|
||||
@@ -78,21 +95,9 @@ function openDesign(definitionId) {
|
||||
router.push({ name: 'system-workflow-design', query: { id: definitionId } })
|
||||
}
|
||||
|
||||
/** 复制版本:已发布版本只读,改流程先复制出新草稿(§4.2) */
|
||||
async function handleCopyVersion(row) {
|
||||
try {
|
||||
const version = await loadLatestVersion(row.b_id)
|
||||
await copyWorkflowVersionApi(version.b_id)
|
||||
Message.success('已复制为新草稿')
|
||||
versionListRef.value?.reload()
|
||||
} catch (error) {
|
||||
notifyError('复制版本失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const definitionRowActions = computed(() => [
|
||||
{ key: 'design', label: '设计', icon: SquarePen, onClick: (row) => openDesign(row.b_id) },
|
||||
{ key: 'copy', label: '复制版本', icon: Copy, onClick: (row) => handleCopyVersion(row) },
|
||||
{ key: 'versions', label: '版本', icon: Layers, onClick: (row) => openVersionDrawer(row) },
|
||||
{ key: 'delete', label: '删除', icon: Trash2, danger: true, onClick: (row) => handleDeleteDefinition(row) },
|
||||
])
|
||||
|
||||
@@ -110,6 +115,7 @@ function handleDeleteDefinition(row) {
|
||||
throw error // 保持确认框打开,便于重试
|
||||
}
|
||||
Message.success('删除成功')
|
||||
closeVersionDrawerIfDeleted([row.b_id])
|
||||
definitionListRef.value?.reload()
|
||||
versionListRef.value?.reload()
|
||||
bindingListRef.value?.reload()
|
||||
@@ -141,6 +147,7 @@ function handleBatchDeleteDefinitions() {
|
||||
Message.success(`已删除 ${keys.length} 个流程`)
|
||||
selectedDefinitionKeys.value = []
|
||||
}
|
||||
closeVersionDrawerIfDeleted(keys)
|
||||
definitionListRef.value?.reload()
|
||||
versionListRef.value?.reload()
|
||||
bindingListRef.value?.reload()
|
||||
@@ -149,9 +156,50 @@ function handleBatchDeleteDefinitions() {
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
流程版本
|
||||
流程版本(流程定义行上的「版本」抽屉)
|
||||
============================================================================ */
|
||||
|
||||
const versionDrawer = reactive({ open: false, definitionId: '', definitionName: '' })
|
||||
|
||||
const versionDrawerTitle = computed(() =>
|
||||
versionDrawer.definitionName ? `流程「${versionDrawer.definitionName}」版本` : '流程版本',
|
||||
)
|
||||
|
||||
/** 抽屉只显示当前定义的版本:固定条件拼进列表查询,抽屉里的查询/分页都基于它 */
|
||||
const versionCondition = computed(() =>
|
||||
versionDrawer.definitionId
|
||||
? `b_definition_id = N'${escapeSqlText(versionDrawer.definitionId)}'`
|
||||
: '',
|
||||
)
|
||||
|
||||
function openVersionDrawer(row) {
|
||||
versionDrawer.definitionId = row.b_id
|
||||
versionDrawer.definitionName = row.b_name || row.b_id
|
||||
versionDrawer.open = true
|
||||
}
|
||||
|
||||
/** 流程被删掉后抽屉里的数据已失效,及时关掉避免停在空列表上 */
|
||||
function closeVersionDrawerIfDeleted(definitionIds) {
|
||||
if (versionDrawer.open && definitionIds.includes(versionDrawer.definitionId)) {
|
||||
versionDrawer.open = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 复制版本:已发布版本只读,改流程先复制出新草稿(§4.2);以该流程最新版本为模板 */
|
||||
async function handleCopyVersion() {
|
||||
const definitionId = versionDrawer.definitionId
|
||||
if (!definitionId) return
|
||||
try {
|
||||
const version = await loadLatestVersion(definitionId)
|
||||
await copyWorkflowVersionApi(version.b_id)
|
||||
Message.success('已复制为新草稿')
|
||||
versionListRef.value?.reload()
|
||||
definitionListRef.value?.reload()
|
||||
} catch (error) {
|
||||
notifyError('复制版本失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
/** 发布:服务端校验零 error 才发布,不通过时把第一条错误顶出来 */
|
||||
async function handlePublishVersion(row) {
|
||||
try {
|
||||
@@ -369,6 +417,23 @@ const bindingRowActions = computed(() => [
|
||||
{ key: 'edit', label: '编辑', icon: SquarePen, onClick: (row) => openBindingEdit(row) },
|
||||
{ key: 'delete', label: '删除', icon: Trash2, danger: true, onClick: (row) => handleDeleteBinding(row) },
|
||||
])
|
||||
|
||||
/* ============================================================================
|
||||
运行监控
|
||||
============================================================================ */
|
||||
|
||||
const instanceDetailOpen = ref(false)
|
||||
const instanceDetailId = ref('')
|
||||
|
||||
/** 查看这张单的流程:复用审批中心的详情抽屉,只传实例、不开审批动作,是纯查看 */
|
||||
function openInstanceDetail(row) {
|
||||
instanceDetailId.value = row.b_id
|
||||
instanceDetailOpen.value = true
|
||||
}
|
||||
|
||||
const instanceRowActions = computed(() => [
|
||||
{ key: 'view', label: '查看', icon: Eye, onClick: (row) => openInstanceDetail(row) },
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -406,14 +471,6 @@ const bindingRowActions = computed(() => [
|
||||
</template>
|
||||
</FmsModuleListPage>
|
||||
|
||||
<FmsModuleListPage
|
||||
v-show="activeTab === 'version'"
|
||||
ref="versionListRef"
|
||||
data-code="v_wf_version"
|
||||
:row-actions="versionRowActions"
|
||||
:inline-action-limit="3"
|
||||
/>
|
||||
|
||||
<FmsModuleListPage
|
||||
v-show="activeTab === 'binding'"
|
||||
ref="bindingListRef"
|
||||
@@ -437,7 +494,11 @@ const bindingRowActions = computed(() => [
|
||||
</template>
|
||||
</FmsModuleListPage>
|
||||
|
||||
<FmsModuleListPage v-show="activeTab === 'instance'" data-code="v_wf_instance" />
|
||||
<FmsModuleListPage
|
||||
v-show="activeTab === 'instance'"
|
||||
data-code="v_wf_instance"
|
||||
:row-actions="instanceRowActions"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Modal
|
||||
@@ -467,6 +528,34 @@ const bindingRowActions = computed(() => [
|
||||
</FormItem>
|
||||
</Form>
|
||||
</Modal>
|
||||
|
||||
<!-- 流程版本:内容是同一份只读视图列表,固定条件锁定到当前定义 -->
|
||||
<Drawer
|
||||
v-model:open="versionDrawer.open"
|
||||
:title="versionDrawerTitle"
|
||||
placement="right"
|
||||
width="min(1000px, 96%)"
|
||||
>
|
||||
<div class="wf-version-drawer">
|
||||
<FmsModuleListPage
|
||||
ref="versionListRef"
|
||||
data-code="v_wf_version"
|
||||
:fixed-search-condition="versionCondition"
|
||||
:row-actions="versionRowActions"
|
||||
:inline-action-limit="3"
|
||||
>
|
||||
<template #actions="{ loading }">
|
||||
<Button type="primary" :disabled="loading" @click="handleCopyVersion">
|
||||
<Copy :size="14" />
|
||||
复制版本
|
||||
</Button>
|
||||
</template>
|
||||
</FmsModuleListPage>
|
||||
</div>
|
||||
</Drawer>
|
||||
|
||||
<!-- 运行监控 → 查看:复用审批中心的只读详情抽屉(实例摘要 + 运行态流程图 + 节点办理明细) -->
|
||||
<ApprovalDetailDrawer v-model:open="instanceDetailOpen" :instance-id="instanceDetailId" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -493,4 +582,10 @@ const bindingRowActions = computed(() => [
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
/* 抽屉里的版本列表:铺满抽屉内容区,滚动交给列表内部(外层 body 不再出现滚动条) */
|
||||
.wf-version-drawer {
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user