liu
昨天 b725cca0ff60728be04ef2ddb4cde5fcdf80bf8e
src/views/bpm/model/index.vue
@@ -1,15 +1,37 @@
<script lang="ts" setup>
import type { ModelCategoryInfo } from '#/api/bpm/model';
import { onActivated, onMounted, reactive, ref, useTemplateRef, watch } from 'vue';
import {
  computed,
  onActivated,
  onMounted,
  reactive,
  ref,
  useTemplateRef,
  watch,
} from 'vue';
import { useAccess } from '@vben/access';
import { Page, useVbenModal } from '@vben/common-ui';
import { IconifyIcon } from '@vben/icons';
import { cloneDeep } from '@vben/utils';
import { useSortable } from '@vueuse/integrations/useSortable';
import { Button, Card, Dropdown, Input, Menu, message } from 'ant-design-vue';
import {
  Button,
  Card,
  Dropdown,
  Input,
  Menu,
  message,
  Switch,
  Tooltip,
} from 'ant-design-vue';
import {
  getAutoApproveList,
  updateGlobalAutoApprove,
} from '#/api/bpm/autoApprove';
import {
  getCategorySimpleList,
  updateCategorySortBatch,
@@ -26,6 +48,17 @@
});
const modelListSpinning = ref(false); // 模型列表加载状态
/** 全局免审批总开关占用的流程 Key(与后端 BpmProcessAutoApproveService.GLOBAL_KEY 保持一致) */
const GLOBAL_AUTO_APPROVE_KEY = '*';
const globalAutoApprove = ref(false); // 全局免审批总开关
const globalAutoApproveLoading = ref(false); // 总开关提交状态
const { hasAccessByCodes } = useAccess();
/** 免审批开关的权限:无权限时开关置灰,避免点了才报错 */
const hasPermiAutoApprove = computed(() => {
  return hasAccessByCodes(['bpm:process-auto-approve:update']);
});
const saveSortLoading = ref(false); // 保存排序状态
const categoryGroup = ref<ModelCategoryInfo[]>([]); // 按照 category 分组的数据
@@ -59,8 +92,22 @@
async function getList() {
  modelListSpinning.value = true;
  try {
    const modelList = await getModelList(queryParams.name);
    const categoryList = await getCategorySimpleList();
    const [modelList, categoryList, autoApproveList] = await Promise.all([
      getModelList(queryParams.name),
      getCategorySimpleList(),
      getAutoApproveList(),
    ]);
    // 免审批配置按「流程 Key」建立映射,合并到模型行数据上,供列表内的免审批开关列直接读取
    const autoApproveMap = new Map<string, boolean>();
    autoApproveList.forEach((config) => {
      autoApproveMap.set(config.processDefinitionKey, config.autoApprove);
    });
    modelList.forEach((model: any) => {
      model.autoApprove = autoApproveMap.get(model.key) ?? false;
    });
    // 全局总开关以特殊 Key 存放在同一条配置里
    globalAutoApprove.value =
      autoApproveMap.get(GLOBAL_AUTO_APPROVE_KEY) ?? false;
    // 按照 category 聚合
    categoryGroup.value = categoryList.map((category: any) => ({
      ...category,
@@ -142,6 +189,28 @@
    sortableInstance.value.option('disabled', true);
  }
}
/** 切换全局免审批总开关:开启后所有流程一律免审批 */
async function handleGlobalAutoApproveChange(checked: boolean) {
  globalAutoApprove.value = checked;
  globalAutoApproveLoading.value = true;
  try {
    await updateGlobalAutoApprove(checked);
    message.success(
      checked
        ? '已开启全局免审批:所有流程提交后将直接通过'
        : '已关闭全局免审批:恢复为按各流程开关判定',
    );
    // 重新拉取列表,同步各流程开关的展示
    await getList();
  } catch (error) {
    // 失败回滚
    globalAutoApprove.value = !checked;
    console.error('设置全局免审批开关失败', error);
  } finally {
    globalAutoApproveLoading.value = false;
  }
}
</script>
<template>
@@ -156,6 +225,16 @@
    >
      <template #extra>
        <div v-if="!isCategorySorting">
          <Tooltip title="开启后所有流程一律免审批(优先于各流程自己的开关)">
            <span class="mr-1">全部免审批</span>
          </Tooltip>
          <Switch
            :checked="globalAutoApprove"
            :loading="globalAutoApproveLoading"
            :disabled="!hasPermiAutoApprove"
            class="mr-3"
            @change="(checked: any) => handleGlobalAutoApproveChange(checked)"
          />
          <Input
            v-model:value="queryParams.name"
            placeholder="搜索流程"