tuqin
5 天以前 400a10f478a3de3e165dae55f5d2b9fc32803829
feat(bpm): 蓝羽流程模型-流程管理员固定超级管理员 + 步骤可自由切换

需求一:流程管理员固定为超级管理员
- 新建/修改模型时流程管理员统一默认为超级管理员(admin,id=1),
不再默认当前登录用户。
- 基本信息页去掉「选择人员」按钮与移除(X)按钮,流程管理员只读展示。

需求二:模型步骤可自由前进/返回
- 原 handleStepClick 逻辑错误:点击任意步骤都会校验其他所有步骤,
导致从「表单设计」点「基本信息」返回时会触发表单校验而报
「请先完善当前步骤必填信息」,点「流程设计」也进不去。
- 改为直接切换步骤,不再做步骤间校验;
保存/发布时仍通过 validateAllSteps 统一校验,数据完整性不受影响。
已修改2个文件
84 ■■■■■ 文件已修改
src/views/bpm/model/form/index.vue 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/bpm/model/form/modules/basic-info.vue 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/bpm/model/form/index.vue
@@ -16,7 +16,6 @@
} from '@vben/constants';
import { useTabs } from '@vben/hooks';
import { IconifyIcon } from '@vben/icons';
import { useUserStore } from '@vben/stores';
import { Button, Card, message } from 'ant-design-vue';
@@ -49,7 +48,6 @@
const router = useRouter();
const route = useRoute();
const userStore = useUserStore();
const tabs = useTabs();
const basicInfoRef = ref<InstanceType<typeof BasicInfo>>(); // 基础信息组件引用
@@ -188,8 +186,10 @@
  } else {
    // 情况三:新增场景
    formData.value.startUserType = 0; // 全体
    formData.value.managerUserIds.push(userStore.userInfo?.id);
  }
  // 流程管理员固定为超级管理员(admin,系统账号 id=1),不允许选择/修改
  formData.value.managerUserIds = [1];
  // 获取表单列表
  formList.value = await getFormSimpleList();
@@ -353,29 +353,9 @@
  }
}
/** 步骤切换处理 */
async function handleStepClick(index: number) {
  try {
    if (index !== 0) {
      await validateBasic();
    }
    if (index !== 1) {
      await validateForm();
    }
    if (index !== 2) {
      await validateProcess();
    }
    if (index !== 3) {
      await validateExtra();
    }
    // 切换步骤
    currentStep.value = index;
  } catch (error) {
    console.error('步骤切换失败:', error);
    if (currentStep.value !== 2) {
      message.warning('请先完善当前步骤必填信息');
    }
  }
/** 步骤切换处理:允许自由前进/返回,不做步骤校验(保存/发布时才统一校验) */
function handleStepClick(index: number) {
  currentStep.value = index;
}
/** 返回列表页 */
src/views/bpm/model/form/modules/basic-info.vue
@@ -61,7 +61,6 @@
const selectedStartDepts = ref<SystemDeptApi.Dept[]>([]); // 选中的发起部门
const selectedManagerUsers = ref<SystemUserApi.User[]>([]); // 选中的流程管理员
const currentSelectType = ref<'manager' | 'start'>('start');
const selectedUsers = ref<number[]>(); // 选中的用户
const rules: Record<string, Rule[]> = {
  name: [{ required: true, message: '流程名称不能为空', trigger: 'blur' }],
@@ -121,7 +120,6 @@
/** 打开发起人选择 */
function openStartUserSelect() {
  currentSelectType.value = 'start';
  selectedUsers.value = selectedStartUsers.value.map(
    (user) => user.id,
  ) as number[];
@@ -141,27 +139,12 @@
  };
}
/** 打开管理员选择 */
function openManagerUserSelect() {
  currentSelectType.value = 'manager';
  selectedUsers.value = selectedManagerUsers.value.map(
    (user) => user.id,
  ) as number[];
  userSelectModalApi.setData({ userIds: selectedUsers.value }).open();
}
/** 处理用户选择确认 */
/** 处理用户选择确认(发起人) */
function handleUserSelectConfirm(userList: SystemUserApi.User[]) {
  modelData.value =
    currentSelectType.value === 'start'
      ? {
          ...modelData.value,
          startUserIds: userList.map((u) => u.id),
        }
      : {
          ...modelData.value,
          managerUserIds: userList.map((u) => u.id),
        };
  modelData.value = {
    ...modelData.value,
    startUserIds: userList.map((u) => u.id),
  };
}
/** 用户选择弹窗关闭 */
@@ -219,16 +202,6 @@
    ...modelData.value,
    startDeptIds: modelData.value.startDeptIds.filter(
      (id: number) => id !== dept.id,
    ),
  };
}
/** 移除管理员 */
function handleRemoveManagerUser(user: SystemUserApi.User) {
  modelData.value = {
    ...modelData.value,
    managerUserIds: modelData.value.managerUserIds.filter(
      (id: number) => id !== user.id,
    ),
  };
}
@@ -411,22 +384,7 @@
            <span class="text-gray-700 dark:text-gray-200">
              {{ user.nickname }}
            </span>
            <IconifyIcon
              icon="lucide:x"
              class="ml-2 size-4 cursor-pointer text-gray-400 hover:text-red-500"
              @click="handleRemoveManagerUser(user)"
            />
          </div>
          <Button
            type="link"
            @click="openManagerUserSelect"
            class="flex items-center"
          >
            <template #icon>
              <IconifyIcon icon="lucide:user-plus" class="size-4" />
            </template>
            选择人员
          </Button>
        </div>
      </Form.Item>
    </Form>