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>
|
<script setup>
|
||||||
/**
|
/**
|
||||||
* 系统管理 —— 流程管理:流程定义 / 流程版本 / 流程绑定 / 运行监控 四个页签。
|
* 系统管理 —— 流程管理:流程定义 / 流程绑定 / 运行监控 三个页签。
|
||||||
*
|
*
|
||||||
* 读取全部走通用模块接口(列表视图 v_wf_*,四张视图都已注册且只读),
|
* 读取全部走通用模块接口(列表视图 v_wf_*,都已注册且只读),
|
||||||
* 写入走流程服务:发布、停用、复制版本、绑定、删除都要经过服务端的发布校验与版本约束
|
* 写入走流程服务:发布、停用、复制版本、绑定、删除都要经过服务端的发布校验与版本约束
|
||||||
* (设计 §6.2 / §11 / §12)——流程定义不在列表里直接编辑,b_save_table 为空,通用保存接口不参与。
|
* (设计 §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 { computed, reactive, ref } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { Ban, Copy, Plus, Send, SquarePen, Trash2 } from '@lucide/vue'
|
import { Ban, Copy, Eye, Layers, Plus, Send, SquarePen, Trash2 } from '@lucide/vue'
|
||||||
import { Button, Checkbox, Form, FormItem, Input, Message, Modal, Select, Tabs } from '@/components/ui'
|
import {
|
||||||
|
Button,
|
||||||
|
Checkbox,
|
||||||
|
Drawer,
|
||||||
|
Form,
|
||||||
|
FormItem,
|
||||||
|
Input,
|
||||||
|
Message,
|
||||||
|
Modal,
|
||||||
|
Select,
|
||||||
|
Tabs,
|
||||||
|
} from '@/components/ui'
|
||||||
import { FmsModuleListPage } from '@/components/fms-module-list'
|
import { FmsModuleListPage } from '@/components/fms-module-list'
|
||||||
import { loadDataApi } from '@/services/api'
|
import { loadDataApi } from '@/services/api'
|
||||||
import { escapeSqlText } from '@/components/fms-module-common/queryUtils'
|
import { escapeSqlText } from '@/components/fms-module-common/queryUtils'
|
||||||
@@ -24,18 +41,18 @@ import {
|
|||||||
retireWorkflowVersionApi,
|
retireWorkflowVersionApi,
|
||||||
saveWorkflowBindingApi,
|
saveWorkflowBindingApi,
|
||||||
} from '@/services/workflow'
|
} from '@/services/workflow'
|
||||||
|
import ApprovalDetailDrawer from '@/views/approval/components/ApprovalDetailDrawer.vue'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const TAB_ITEMS = [
|
const TAB_ITEMS = [
|
||||||
{ key: 'definition', label: '流程定义' },
|
{ key: 'definition', label: '流程定义' },
|
||||||
{ key: 'version', label: '流程版本' },
|
|
||||||
{ key: 'binding', label: '流程绑定' },
|
{ key: 'binding', label: '流程绑定' },
|
||||||
{ key: 'instance', label: '运行监控' },
|
{ key: 'instance', label: '运行监控' },
|
||||||
]
|
]
|
||||||
const activeTab = ref('definition')
|
const activeTab = ref('definition')
|
||||||
|
|
||||||
/** 各列表的刷新入口(FmsModuleListPage 暴露 reload) */
|
/** 列表刷新入口(FmsModuleListPage 暴露 reload);版本列表在抽屉里,见下方「流程版本」 */
|
||||||
const definitionListRef = ref(null)
|
const definitionListRef = ref(null)
|
||||||
const versionListRef = ref(null)
|
const versionListRef = ref(null)
|
||||||
const bindingListRef = ref(null)
|
const bindingListRef = ref(null)
|
||||||
@@ -78,21 +95,9 @@ function openDesign(definitionId) {
|
|||||||
router.push({ name: 'system-workflow-design', query: { id: 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(() => [
|
const definitionRowActions = computed(() => [
|
||||||
{ key: 'design', label: '设计', icon: SquarePen, onClick: (row) => openDesign(row.b_id) },
|
{ 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) },
|
{ key: 'delete', label: '删除', icon: Trash2, danger: true, onClick: (row) => handleDeleteDefinition(row) },
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -110,6 +115,7 @@ function handleDeleteDefinition(row) {
|
|||||||
throw error // 保持确认框打开,便于重试
|
throw error // 保持确认框打开,便于重试
|
||||||
}
|
}
|
||||||
Message.success('删除成功')
|
Message.success('删除成功')
|
||||||
|
closeVersionDrawerIfDeleted([row.b_id])
|
||||||
definitionListRef.value?.reload()
|
definitionListRef.value?.reload()
|
||||||
versionListRef.value?.reload()
|
versionListRef.value?.reload()
|
||||||
bindingListRef.value?.reload()
|
bindingListRef.value?.reload()
|
||||||
@@ -141,6 +147,7 @@ function handleBatchDeleteDefinitions() {
|
|||||||
Message.success(`已删除 ${keys.length} 个流程`)
|
Message.success(`已删除 ${keys.length} 个流程`)
|
||||||
selectedDefinitionKeys.value = []
|
selectedDefinitionKeys.value = []
|
||||||
}
|
}
|
||||||
|
closeVersionDrawerIfDeleted(keys)
|
||||||
definitionListRef.value?.reload()
|
definitionListRef.value?.reload()
|
||||||
versionListRef.value?.reload()
|
versionListRef.value?.reload()
|
||||||
bindingListRef.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 才发布,不通过时把第一条错误顶出来 */
|
/** 发布:服务端校验零 error 才发布,不通过时把第一条错误顶出来 */
|
||||||
async function handlePublishVersion(row) {
|
async function handlePublishVersion(row) {
|
||||||
try {
|
try {
|
||||||
@@ -369,6 +417,23 @@ const bindingRowActions = computed(() => [
|
|||||||
{ key: 'edit', label: '编辑', icon: SquarePen, onClick: (row) => openBindingEdit(row) },
|
{ key: 'edit', label: '编辑', icon: SquarePen, onClick: (row) => openBindingEdit(row) },
|
||||||
{ key: 'delete', label: '删除', icon: Trash2, danger: true, onClick: (row) => handleDeleteBinding(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>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -406,14 +471,6 @@ const bindingRowActions = computed(() => [
|
|||||||
</template>
|
</template>
|
||||||
</FmsModuleListPage>
|
</FmsModuleListPage>
|
||||||
|
|
||||||
<FmsModuleListPage
|
|
||||||
v-show="activeTab === 'version'"
|
|
||||||
ref="versionListRef"
|
|
||||||
data-code="v_wf_version"
|
|
||||||
:row-actions="versionRowActions"
|
|
||||||
:inline-action-limit="3"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FmsModuleListPage
|
<FmsModuleListPage
|
||||||
v-show="activeTab === 'binding'"
|
v-show="activeTab === 'binding'"
|
||||||
ref="bindingListRef"
|
ref="bindingListRef"
|
||||||
@@ -437,7 +494,11 @@ const bindingRowActions = computed(() => [
|
|||||||
</template>
|
</template>
|
||||||
</FmsModuleListPage>
|
</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>
|
</div>
|
||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
@@ -467,6 +528,34 @@ const bindingRowActions = computed(() => [
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -493,4 +582,10 @@ const bindingRowActions = computed(() => [
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 抽屉里的版本列表:铺满抽屉内容区,滚动交给列表内部(外层 body 不再出现滚动条) */
|
||||||
|
.wf-version-drawer {
|
||||||
|
height: 100%;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
+1
-1
Submodule code/test/form-js updated: d00e32ab92...39406918f6.
+1
-1
Submodule code/test/vue-vben-admin updated: 2d7087602b...edbc42caaa.
Reference in new issue
Block a user