From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目
---
src/views/bpm/processInstance/create/index.vue | 321 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 321 insertions(+), 0 deletions(-)
diff --git a/src/views/bpm/processInstance/create/index.vue b/src/views/bpm/processInstance/create/index.vue
new file mode 100644
index 0000000..2c714d1
--- /dev/null
+++ b/src/views/bpm/processInstance/create/index.vue
@@ -0,0 +1,321 @@
+<template>
+ <!-- 绗竴姝ワ紝閫氳繃娴佺▼瀹氫箟鐨勫垪琛紝閫夋嫨瀵瑰簲鐨勬祦绋� -->
+ <template v-if="!selectProcessDefinition">
+ <el-input
+ v-model="searchName"
+ class="!w-50% mb-15px"
+ placeholder="璇疯緭鍏ユ祦绋嬪悕绉�"
+ clearable
+ @input="handleQuery"
+ @clear="handleQuery"
+ >
+ <template #prefix>
+ <Icon icon="ep:search" />
+ </template>
+ </el-input>
+ <ContentWrap
+ :class="{ 'process-definition-container': filteredProcessDefinitionList?.length }"
+ class="position-relative pb-20px h-700px"
+ v-loading="loading"
+ >
+ <el-row v-if="filteredProcessDefinitionList?.length" :gutter="20" class="!flex-nowrap">
+ <el-col :span="5">
+ <div class="flex flex-col">
+ <div
+ v-for="category in availableCategories"
+ :key="category.code"
+ class="flex items-center p-10px cursor-pointer text-14px rounded-md"
+ :class="categoryActive.code === category.code ? 'text-#3e7bff bg-#e8eeff' : ''"
+ @click="handleCategoryClick(category)"
+ >
+ {{ category.name }}
+ </div>
+ </div>
+ </el-col>
+ <el-col :span="19">
+ <el-scrollbar ref="scrollWrapper" height="700" @scroll="handleScroll">
+ <div
+ class="mb-20px pl-10px"
+ v-for="(definitions, categoryCode) in processDefinitionGroup"
+ :key="categoryCode"
+ :ref="`category-${categoryCode}`"
+ >
+ <h3 class="text-18px font-bold mb-10px mt-5px">
+ {{ getCategoryName(categoryCode as any) }}
+ </h3>
+ <div class="grid grid-cols-3 gap3">
+ <el-tooltip
+ v-for="definition in definitions"
+ :key="definition.id"
+ :content="definition.description"
+ :disabled="!definition.description || definition.description.trim().length === 0"
+ placement="top"
+ >
+ <el-card
+ shadow="hover"
+ class="cursor-pointer definition-item-card"
+ @click="handleSelect(definition)"
+ >
+ <template #default>
+ <div class="flex">
+ <el-image
+ v-if="definition.icon"
+ :src="definition.icon"
+ class="w-32px h-32px"
+ />
+ <div v-else class="flow-icon">
+ <span style="font-size: 12px; color: #fff">
+ {{ subString(definition.name, 0, 2) }}
+ </span>
+ </div>
+ <el-text class="!ml-10px" size="large">{{ definition.name }}</el-text>
+ </div>
+ </template>
+ </el-card>
+ </el-tooltip>
+ </div>
+ </div>
+ </el-scrollbar>
+ </el-col>
+ </el-row>
+ <el-empty class="!py-200px" :image-size="200" description="娌℃湁鎵惧埌鎼滅储缁撴灉" v-else />
+ </ContentWrap>
+ </template>
+
+ <!-- 绗簩姝ワ紝濉啓琛ㄥ崟锛岃繘琛屾祦绋嬬殑鎻愪氦 -->
+ <ProcessDefinitionDetail
+ v-else
+ ref="processDefinitionDetailRef"
+ :selectProcessDefinition="selectProcessDefinition"
+ @cancel="selectProcessDefinition = undefined"
+ />
+</template>
+
+<script lang="ts" setup>
+import * as DefinitionApi from '@/api/bpm/definition'
+import * as ProcessInstanceApi from '@/api/bpm/processInstance'
+import { CategoryApi, CategoryVO } from '@/api/bpm/category'
+import ProcessDefinitionDetail from './ProcessDefinitionDetail.vue'
+import { groupBy } from 'lodash-es'
+import { subString } from '@/utils/index'
+
+defineOptions({ name: 'BpmProcessInstanceCreate' })
+
+const { proxy } = getCurrentInstance() as any
+const route = useRoute() // 璺敱
+const message = useMessage() // 娑堟伅
+
+const searchName = ref('') // 褰撳墠鎼滅储鍏抽敭瀛�
+const processInstanceId: any = route.query.processInstanceId // 娴佺▼瀹炰緥缂栧彿銆傚満鏅細閲嶆柊鍙戣捣鏃�
+const loading = ref(true) // 鍔犺浇涓�
+const categoryList: any = ref([]) // 鍒嗙被鐨勫垪琛�
+const categoryActive: any = ref({}) // 閫変腑鐨勫垎绫�
+const processDefinitionList = ref([]) // 娴佺▼瀹氫箟鐨勫垪琛�
+
+/** 鏌ヨ鍒楄〃 */
+const getList = async () => {
+ loading.value = true
+ try {
+ // 鎵�鏈夋祦绋嬪垎绫绘暟鎹�
+ await getCategoryList()
+ // 鎵�鏈夋祦绋嬪畾涔夋暟鎹�
+ await getProcessDefinitionList()
+
+ // 濡傛灉 processInstanceId 闈炵┖锛岃鏄庢槸閲嶆柊鍙戣捣
+ if (processInstanceId?.length > 0) {
+ const processInstance = await ProcessInstanceApi.getProcessInstance(processInstanceId)
+ if (!processInstance) {
+ message.error('閲嶆柊鍙戣捣娴佺▼澶辫触锛屽師鍥狅細娴佺▼瀹炰緥涓嶅瓨鍦�')
+ return
+ }
+ const processDefinition = processDefinitionList.value.find(
+ (item: any) => item.key == processInstance.processDefinition?.key
+ )
+ if (!processDefinition) {
+ message.error('閲嶆柊鍙戣捣娴佺▼澶辫触锛屽師鍥狅細娴佺▼瀹氫箟涓嶅瓨鍦�')
+ return
+ }
+ await handleSelect(processDefinition, processInstance.formVariables)
+ }
+ } finally {
+ loading.value = false
+ }
+}
+
+/** 鑾峰彇鎵�鏈夋祦绋嬪垎绫绘暟鎹� */
+const getCategoryList = async () => {
+ try {
+ // 娴佺▼鍒嗙被
+ categoryList.value = await CategoryApi.getCategorySimpleList()
+ } finally {
+ }
+}
+
+/** 鑾峰彇鎵�鏈夋祦绋嬪畾涔夋暟鎹� */
+const getProcessDefinitionList = async () => {
+ try {
+ // 娴佺▼瀹氫箟
+ processDefinitionList.value = await DefinitionApi.getProcessDefinitionList({
+ suspensionState: 1
+ })
+ // 鍒濆鍖栬繃婊ゅ垪琛ㄤ负鍏ㄩ儴娴佺▼瀹氫箟
+ filteredProcessDefinitionList.value = processDefinitionList.value
+
+ // 鍦ㄨ幏鍙栧畬鎵�鏈夋暟鎹悗锛岃缃涓�涓湁鏁堝垎绫讳负婵�娲荤姸鎬�
+ if (availableCategories.value.length > 0 && !categoryActive.value?.code) {
+ categoryActive.value = availableCategories.value[0]
+ }
+ } finally {
+ }
+}
+
+/** 鎼滅储娴佺▼ */
+const filteredProcessDefinitionList = ref([]) // 鐢ㄤ簬瀛樺偍鎼滅储杩囨护鍚庣殑娴佺▼瀹氫箟
+const handleQuery = () => {
+ if (searchName.value.trim()) {
+ // 濡傛灉鏈夋悳绱㈠叧閿瓧锛岃繘琛岃繃婊�
+ filteredProcessDefinitionList.value = processDefinitionList.value.filter(
+ (definition: any) => definition.name.toLowerCase().includes(searchName.value.toLowerCase()) // 鍋囪鎼滅储渚濇嵁鏄祦绋嬪畾涔夌殑鍚嶇О
+ )
+ } else {
+ // 濡傛灉娌℃湁鎼滅储鍏抽敭瀛楋紝鎭㈠鎵�鏈夋暟鎹�
+ filteredProcessDefinitionList.value = processDefinitionList.value
+ }
+}
+
+/** 娴佺▼瀹氫箟鐨勫垎缁� */
+const processDefinitionGroup: any = computed(() => {
+ if (!processDefinitionList.value?.length) {
+ return {}
+ }
+
+ const grouped = groupBy(filteredProcessDefinitionList.value, 'category')
+ // 鎸夌収 categoryList 鐨勯『搴忛噸鏂扮粍缁囨暟鎹�
+ const orderedGroup = {}
+ categoryList.value.forEach((category: any) => {
+ if (grouped[category.code]) {
+ orderedGroup[category.code] = grouped[category.code]
+ }
+ })
+ return orderedGroup
+})
+
+/** 宸︿晶鍒嗙被鍒囨崲 */
+const handleCategoryClick = (category: any) => {
+ categoryActive.value = category
+ const categoryRef = proxy.$refs[`category-${category.code}`] // 鑾峰彇鐐瑰嚮鍒嗙被瀵瑰簲鐨� DOM 鍏冪礌
+ if (categoryRef?.length) {
+ const scrollWrapper = proxy.$refs.scrollWrapper // 鑾峰彇鍙充晶婊氬姩瀹瑰櫒
+ const categoryOffsetTop = categoryRef[0].offsetTop
+
+ // 婊氬姩鍒板搴斾綅缃�
+ scrollWrapper.scrollTo({ top: categoryOffsetTop, behavior: 'smooth' })
+ }
+}
+
+/** 閫氳繃鍒嗙被 code 鑾峰彇瀵瑰簲鐨勫悕绉� */
+const getCategoryName = (categoryCode: string) => {
+ return categoryList.value?.find((ctg: any) => ctg.code === categoryCode)?.name
+}
+
+// ========== 琛ㄥ崟鐩稿叧 ==========
+const selectProcessDefinition = ref() // 閫夋嫨鐨勬祦绋嬪畾涔�
+const processDefinitionDetailRef = ref()
+
+/** 澶勭悊閫夋嫨娴佺▼鐨勬寜閽搷浣� **/
+const handleSelect = async (row, formVariables?) => {
+ // 璁剧疆閫夋嫨鐨勬祦绋�
+ selectProcessDefinition.value = row
+ // 鍒濆鍖栨祦绋嬪畾涔夎鎯�
+ await nextTick()
+ processDefinitionDetailRef.value?.initProcessInfo(row, formVariables)
+}
+
+/** 澶勭悊婊氬姩浜嬩欢锛屽拰宸︿晶鍒嗙被鑱斿姩 */
+const handleScroll = (e: any) => {
+ // 鐩存帴浣跨敤浜嬩欢瀵硅薄鑾峰彇婊氬姩浣嶇疆
+ const scrollTop = e.scrollTop
+
+ // 鑾峰彇鎵�鏈夊垎绫诲尯鍩熺殑浣嶇疆淇℃伅
+ const categoryPositions = categoryList.value
+ .map((category: CategoryVO) => {
+ const categoryRef = proxy.$refs[`category-${category.code}`]
+ if (categoryRef?.[0]) {
+ return {
+ code: category.code,
+ offsetTop: categoryRef[0].offsetTop,
+ height: categoryRef[0].offsetHeight
+ }
+ }
+ return null
+ })
+ .filter(Boolean)
+
+ // 鏌ユ壘褰撳墠婊氬姩浣嶇疆瀵瑰簲鐨勫垎绫�
+ let currentCategory = categoryPositions[0]
+ for (const position of categoryPositions) {
+ // 涓轰簡鏇村ソ鐨勭敤鎴蜂綋楠岋紝鍙互娣诲姞涓�涓紦鍐插尯鍩燂紙姣斿 50px锛�
+ if (scrollTop >= position.offsetTop - 50) {
+ currentCategory = position
+ } else {
+ break
+ }
+ }
+
+ // 鏇存柊褰撳墠 active 鐨勫垎绫�
+ if (currentCategory && categoryActive.value.code !== currentCategory.code) {
+ categoryActive.value = categoryList.value.find(
+ (c: CategoryVO) => c.code === currentCategory.code
+ )
+ }
+}
+
+/** 杩囨护鍑烘湁娴佺▼鐨勫垎绫诲垪琛ㄣ�傜洰鐨勶細鍙睍绀烘湁娴佺▼鐨勫垎绫� */
+const availableCategories = computed(() => {
+ if (!categoryList.value?.length || !processDefinitionGroup.value) {
+ return []
+ }
+
+ // 鑾峰彇鎵�鏈夋湁娴佺▼鐨勫垎绫讳唬鐮�
+ const availableCategoryCodes = Object.keys(processDefinitionGroup.value)
+
+ // 杩囨护鍑烘湁娴佺▼鐨勫垎绫�
+ return categoryList.value.filter((category: CategoryVO) =>
+ availableCategoryCodes.includes(category.code)
+ )
+})
+
+/** 鍒濆鍖� */
+onMounted(() => {
+ getList()
+})
+</script>
+
+<style lang="scss" scoped>
+.flow-icon {
+ display: flex;
+ width: 32px;
+ height: 32px;
+ margin-right: 10px;
+ background-color: var(--el-color-primary);
+ border-radius: 0.25rem;
+ align-items: center;
+ justify-content: center;
+}
+
+.process-definition-container::before {
+ position: absolute;
+ left: 20.8%;
+ height: 100%;
+ border-left: 1px solid #e6e6e6;
+ content: '';
+}
+
+:deep() {
+ .definition-item-card {
+ .el-card__body {
+ padding: 14px;
+ }
+ }
+}
+</style>
--
Gitblit v1.8.0