Эх сурвалжийг харах

Merge pull request #89 from GoldenZqqq/bpm-2st-stage

流程模型列表UI重构以及数组分类分组展示逻辑
芋道源码 10 сар өмнө
parent
commit
1d01955b8b

+ 456 - 0
src/views/bpm/model/index_new.vue

@@ -0,0 +1,456 @@
+<template>
+  <ContentWrap>
+    <div class="flex justify-between pl-20px items-center">
+      <h3 class="font-extrabold">表单管理</h3>
+      <!-- 搜索工作栏 -->
+      <el-form
+        class="-mb-15px flex"
+        :model="queryParams"
+        ref="queryFormRef"
+        :inline="true"
+        label-width="68px"
+      >
+        <el-form-item align="right" prop="key" class="ml-auto">
+          <el-input
+            v-model="queryParams.key"
+            placeholder="搜索流程"
+            clearable
+            @keyup.enter="handleQuery"
+            class="!w-240px"
+          >
+            <template #prefix>
+              <Icon icon="ep:search" class="mx-10px" />
+            </template>
+          </el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="openForm('create')" v-hasPermi="['bpm:model:create']">
+            <Icon icon="ep:plus" class="mr-5px" /> 新建流程
+          </el-button>
+        </el-form-item>
+
+        <el-form-item>
+          <el-dropdown placement="bottom-end">
+            <el-button class="w-30px" plain>
+              <Icon icon="ep:setting" />
+            </el-button>
+            <template #dropdown>
+              <el-dropdown-menu>
+                <el-dropdown-item>
+                  <Icon icon="ep:circle-plus" size="13" class="mr-5px" />
+                  新建分组
+                </el-dropdown-item>
+                <el-dropdown-item>
+                  <Icon icon="fa:sort-amount-desc" size="13" class="mr-5px" />
+                  分组排序
+                </el-dropdown-item>
+              </el-dropdown-menu>
+            </template>
+          </el-dropdown>
+        </el-form-item>
+      </el-form>
+    </div>
+
+    <el-divider />
+
+    <!-- 分类卡片组 -->
+    <div class="px-15px">
+      <ContentWrap :body-style="{ padding: 0 }" v-for="(list, title) in categoryGroup" :key="title">
+        <!-- 默认使其全部展开 -->
+        <el-collapse :modelValue="title">
+          <el-collapse-item :name="title">
+            <template #icon="{ isActive }">
+              <div
+                class="ml-20px flex items-center"
+                :class="['transition-transform duration-300', isActive ? 'rotate-180' : 'rotate-0']"
+              >
+                <Icon icon="ep:arrow-down-bold" color="#999" />
+              </div>
+              <div class="ml-auto mr-30px">
+                <el-button link type="info" class="mr-10px" @click.stop="handleSort">
+                  <Icon icon="fa:sort-amount-desc" class="mr-5px" />
+                  排序
+                </el-button>
+                <el-button link type="info" @click.stop="handleGroup">
+                  <Icon icon="ep:setting" class="mr-5px" />
+                  分组
+                </el-button>
+              </div>
+            </template>
+            <template #title>
+              <div class="flex items-center">
+                <h3 class="ml-20px mr-8px text-18px">{{ title }}</h3>
+                <div class="color-gray-600 text-16px"> ({{ list?.length || 0 }}) </div>
+              </div>
+            </template>
+
+            <el-table
+              :header-cell-style="{ backgroundColor: isDark ? '' : '#edeff0' }"
+              v-loading="loading"
+              :data="list"
+            >
+              <el-table-column label="流程名" prop="name" min-width="150">
+                <template #default="scope">
+                  <div class="flex items-center">
+                    <el-image :src="scope.row.icon" class="h-32px w-32px mr-10px rounded" />
+                    {{ scope.row.name }}
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="可见范围" prop="startUserIds" min-width="100">
+                <template #default="scope">
+                  <el-text v-if="!scope.row.startUsers || scope.row.startUsers.length === 0">
+                    全部可见
+                  </el-text>
+                  <el-text v-else-if="scope.row.startUsers.length == 1">
+                    {{ scope.row.startUsers[0].nickname }}
+                  </el-text>
+                  <el-text v-else>
+                    <el-tooltip
+                      class="box-item"
+                      effect="dark"
+                      placement="top"
+                      :content="scope.row.startUsers.map((user: any) => user.nickname).join('、')"
+                    >
+                      {{ scope.row.startUsers[0].nickname }}等
+                      {{ scope.row.startUsers.length }} 人可见
+                    </el-tooltip>
+                  </el-text>
+                </template>
+              </el-table-column>
+              <el-table-column label="表单信息" prop="formType" min-width="200">
+                <template #default="scope">
+                  <el-button
+                    v-if="scope.row.formType === 10"
+                    type="primary"
+                    link
+                    @click="handleFormDetail(scope.row)"
+                  >
+                    <span>{{ scope.row.formName }}</span>
+                  </el-button>
+                  <el-button
+                    v-else-if="scope.row.formType === 20"
+                    type="primary"
+                    link
+                    @click="handleFormDetail(scope.row)"
+                  >
+                    <span>{{ scope.row.formCustomCreatePath }}</span>
+                  </el-button>
+                  <label v-else>暂无表单</label>
+                </template>
+              </el-table-column>
+              <el-table-column label="最后发布" prop="deploymentTime" min-width="250">
+                <template #default="scope">
+                  <span v-if="scope.row.processDefinition">
+                    {{ formatDate(scope.row.processDefinition.deploymentTime) }}
+                  </span>
+                  <el-tag v-if="scope.row.processDefinition" class="ml-10px">
+                    v{{ scope.row.processDefinition.version }}
+                  </el-tag>
+                  <el-tag v-else type="warning">未部署</el-tag>
+                  <el-tag
+                    v-if="scope.row.processDefinition?.suspensionState === 2"
+                    type="warning"
+                    class="ml-10px"
+                  >
+                    已停用
+                  </el-tag>
+                </template>
+              </el-table-column>
+              <el-table-column label="操作" width="200" fixed="right">
+                <template #default="scope">
+                  <el-button
+                    link
+                    type="primary"
+                    @click="openForm('update', scope.row.id)"
+                    v-hasPermi="['bpm:model:update']"
+                    :disabled="!isManagerUser(scope.row)"
+                  >
+                    修改
+                  </el-button>
+                  <el-button
+                    link
+                    class="!ml-5px"
+                    type="primary"
+                    @click="handleDesign(scope.row)"
+                    v-hasPermi="['bpm:model:update']"
+                    :disabled="!isManagerUser(scope.row)"
+                  >
+                    设计
+                  </el-button>
+                  <el-button
+                    link
+                    class="!ml-5px"
+                    type="primary"
+                    @click="handleDeploy(scope.row)"
+                    v-hasPermi="['bpm:model:deploy']"
+                    :disabled="!isManagerUser(scope.row)"
+                  >
+                    发布
+                  </el-button>
+                  <el-dropdown
+                    class="!align-middle ml-5px"
+                    @command="(command) => handleCommand(command, scope.row)"
+                    v-hasPermi="[
+                      'bpm:process-definition:query',
+                      'bpm:model:update',
+                      'bpm:model:delete'
+                    ]"
+                  >
+                    <el-button type="primary" link>更多</el-button>
+                    <template #dropdown>
+                      <el-dropdown-menu>
+                        <el-dropdown-item
+                          command="handleDefinitionList"
+                          v-if="checkPermi(['bpm:process-definition:query'])"
+                        >
+                          历史
+                        </el-dropdown-item>
+                        <el-dropdown-item
+                          command="handleChangeState"
+                          v-if="checkPermi(['bpm:model:update']) && scope.row.processDefinition"
+                          :disabled="!isManagerUser(scope.row)"
+                        >
+                          {{ scope.row.processDefinition.suspensionState === 1 ? '停用' : '启用' }}
+                        </el-dropdown-item>
+                        <el-dropdown-item
+                          type="danger"
+                          command="handleDelete"
+                          v-if="checkPermi(['bpm:model:delete'])"
+                          :disabled="!isManagerUser(scope.row)"
+                        >
+                          删除
+                        </el-dropdown-item>
+                      </el-dropdown-menu>
+                    </template>
+                  </el-dropdown>
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-collapse-item>
+        </el-collapse>
+      </ContentWrap>
+    </div>
+  </ContentWrap>
+
+  <!-- 表单弹窗:添加/修改流程 -->
+  <ModelForm ref="formRef" @success="getList" />
+
+  <!-- 弹窗:表单详情 -->
+  <Dialog title="表单详情" v-model="formDetailVisible" width="800">
+    <form-create :rule="formDetailPreview.rule" :option="formDetailPreview.option" />
+  </Dialog>
+</template>
+
+<script lang="ts" setup>
+import { formatDate } from '@/utils/formatTime'
+import * as ModelApi from '@/api/bpm/model'
+import * as FormApi from '@/api/bpm/form'
+import ModelForm from './ModelForm.vue'
+import { setConfAndFields2 } from '@/utils/formCreate'
+import { CategoryApi } from '@/api/bpm/category'
+import { BpmModelType } from '@/utils/constants'
+import { checkPermi } from '@/utils/permission'
+import { useUserStoreWithOut } from '@/store/modules/user'
+import { useAppStore } from '@/store/modules/app'
+import { groupBy } from 'lodash-es'
+
+defineOptions({ name: 'BpmModel' })
+
+const appStore = useAppStore()
+const message = useMessage() // 消息弹窗
+const isDark = computed(() => appStore.getIsDark)
+const { t } = useI18n() // 国际化
+const { push } = useRouter() // 路由
+const userStore = useUserStoreWithOut() // 用户信息缓存
+const loading = ref(true) // 列表的加载中
+const queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  key: undefined,
+  name: undefined,
+  category: undefined
+})
+const queryFormRef = ref() // 搜索的表单
+const categoryList = ref([]) // 流程分类列表
+const categoryGroup = ref<any>({}) // 按照category分组的数据
+
+/** 查询列表 */
+const getList = async () => {
+  loading.value = true
+  try {
+    // TODO 芋艿:这里需要一个不分页查全部的流程模型接口
+    const data = await ModelApi.getModelPage(queryParams)
+    categoryGroup.value = groupBy(data.list, 'categoryName')
+  } finally {
+    loading.value = false
+  }
+}
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.pageNo = 1
+  getList()
+}
+
+/** '更多'操作按钮 */
+const handleCommand = (command: string, row: any) => {
+  switch (command) {
+    case 'handleDefinitionList':
+      handleDefinitionList(row)
+      break
+    case 'handleDelete':
+      handleDelete(row)
+      break
+    case 'handleChangeState':
+      handleChangeState(row)
+      break
+    default:
+      break
+  }
+}
+
+/** 添加/修改操作 */
+const formRef = ref()
+const openForm = (type: string, id?: number) => {
+  formRef.value.open(type, id)
+}
+
+/** 删除按钮操作 */
+const handleDelete = async (row: any) => {
+  try {
+    // 删除的二次确认
+    await message.delConfirm()
+    // 发起删除
+    await ModelApi.deleteModel(row.id)
+    message.success(t('common.delSuccess'))
+    // 刷新列表
+    await getList()
+  } catch {}
+}
+
+/** 更新状态操作 */
+const handleChangeState = async (row: any) => {
+  const state = row.processDefinition.suspensionState
+  const newState = state === 1 ? 2 : 1
+  try {
+    // 修改状态的二次确认
+    const id = row.id
+    debugger
+    const statusState = state === 1 ? '停用' : '启用'
+    const content = '是否确认' + statusState + '流程名字为"' + row.name + '"的数据项?'
+    await message.confirm(content)
+    // 发起修改状态
+    await ModelApi.updateModelState(id, newState)
+    message.success(statusState + '成功')
+    // 刷新列表
+    await getList()
+  } catch {}
+}
+
+/** 设计流程 */
+const handleDesign = (row: any) => {
+  if (row.type == BpmModelType.BPMN) {
+    push({
+      name: 'BpmModelEditor',
+      query: {
+        modelId: row.id
+      }
+    })
+  } else {
+    push({
+      name: 'SimpleWorkflowDesignEditor',
+      query: {
+        modelId: row.id
+      }
+    })
+  }
+}
+
+/** 发布流程 */
+const handleDeploy = async (row: any) => {
+  try {
+    // 删除的二次确认
+    await message.confirm('是否部署该流程!!')
+    // 发起部署
+    await ModelApi.deployModel(row.id)
+    message.success(t('部署成功'))
+    // 刷新列表
+    await getList()
+  } catch {}
+}
+
+/** 跳转到指定流程定义列表 */
+const handleDefinitionList = (row) => {
+  push({
+    name: 'BpmProcessDefinition',
+    query: {
+      key: row.key
+    }
+  })
+}
+
+/** 流程表单的详情按钮操作 */
+const formDetailVisible = ref(false)
+const formDetailPreview = ref({
+  rule: [],
+  option: {}
+})
+const handleFormDetail = async (row: any) => {
+  if (row.formType == 10) {
+    // 设置表单
+    const data = await FormApi.getForm(row.formId)
+    setConfAndFields2(formDetailPreview, data.conf, data.fields)
+    // 弹窗打开
+    formDetailVisible.value = true
+  } else {
+    await push({
+      path: row.formCustomCreatePath
+    })
+  }
+}
+
+/** 判断是否可以操作 */
+const isManagerUser = (row: any) => {
+  const userId = userStore.getUser.id
+  return row.managerUserIds && row.managerUserIds.includes(userId)
+}
+
+/* 排序 */
+const handleSort = () => {
+  console.log('排序')
+}
+
+/* 分组 */
+const handleGroup = () => {
+  console.log('分组')
+}
+
+/** 初始化 **/
+onMounted(async () => {
+  await getList()
+  // 查询流程分类列表
+  categoryList.value = await CategoryApi.getCategorySimpleList()
+})
+</script>
+
+<style lang="scss" scoped>
+:deep() {
+  .el-form--inline .el-form-item {
+    margin-right: 10px;
+  }
+  .el-divider--horizontal {
+    margin-top: 6px;
+  }
+  .el-collapse,
+  .el-collapse-item__header,
+  .el-collapse-item__wrap {
+    border: none;
+  }
+  .el-collapse-item__arrow {
+    margin-left: 10px;
+    font-size: 20px;
+    font-weight: 500;
+  }
+}
+</style>