npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

fc-workflow-components

v1.0.28

Published

基于 `Vue 3` + `Ant Design Vue` 的工作流页面组件包,包含审批列表、审批详情、流程管理、流程配置、流程版本等页面能力。

Readme

fc-workflow-components

基于 Vue 3 + Ant Design Vue 的工作流页面组件包,包含审批列表、审批详情、流程管理、流程配置、流程版本等页面能力。

适用于以下场景:

  • 宿主项目通过后端动态菜单配置页面
  • 宿主项目希望直接复用工作流页面组件
  • 宿主项目已有自己的请求、用户状态、上传/附件/组织弹窗等基础能力,需要注入到工作流组件内使用

安装

npm install fc-workflow-components

宿主项目需要自行安装并保持兼容版本的依赖:

  • vue
  • vue-router
  • ant-design-vue

导出内容

包入口当前导出以下内容:

  • WorkflowApproval:审批列表页
  • WorkflowApprovalDetail:审批详情页
  • WorkflowProcess:流程管理页
  • WorkflowProcessConfiguration:流程配置页
  • WorkflowProcessVersion:流程版本页
  • ApprovalToolbar:审批详情页顶部工具栏
  • workflowEventHub:工作流事件总线
  • getWorkflowEventHub
  • setWorkflowAdapters
  • getWorkflowAdapters
  • resetWorkflowAdapters
  • requireWorkflowAdapter
  • requireWorkflowComponent
  • getWorkflowRequest
  • getWorkflowUserStore
  • getWorkflowComponent
  • getWorkflowComponentResolver
  • createWorkflowPlugin

快速开始

1. 在宿主项目注入适配器

import { createApp } from 'vue';
import App from './App.vue';
import WorkflowPkg from 'fc-workflow-components';

import Request from '@/utils/request/request-util';
import { useUserStore } from '@/store/modules/user';
import { resolveWorkflowComponentByPath } from '@/router/workflow-component-map';

import FileUpload from '@/components/system/FileUpload/index.vue';
import FileDisplayItem from '@/components/system/FileDisplayItem/index.vue';
import OrganizationDrawer from '@/components/system/OrganizationDrawer/index.vue';
import NotFound from '@/components/Exception/404/index.vue';

const app = createApp(App);

app.use(WorkflowPkg, {
  adapters: {
    request: Request,
    userStore: useUserStore,
    resolveComponentByPath,
    routes: {
      home: '/home',
      homeDetail: '/home/detail',
      approvalDetail: '/approval/detail'
    }
  },
  components: {
    FileUpload,
    FileDisplayItem,
    OrganizationDrawer,
    NotFound
  }
});

2. 直接在路由中使用

import {
  WorkflowApproval,
  WorkflowApprovalDetail,
  WorkflowProcess,
  WorkflowProcessConfiguration,
  WorkflowProcessVersion,
  ProcessInstanceTaskApi,
  ProcessApi
} from 'fc-workflow-components';

export default [
  { path: '/approval', component: WorkflowApproval },
  { path: '/approval/detail', component: WorkflowApprovalDetail },
  { path: '/process', component: WorkflowProcess },
  { path: '/process/configuration', component: WorkflowProcessConfiguration },
  { path: '/process/version', component: WorkflowProcessVersion }
];

使用内置 API

import {
  ProcessApi,
  ProcessInstanceApi,
  ProcessInstanceTaskApi,
  ProcessVersionConfigApi
} from 'fc-workflow-components';

const { data } = await ProcessInstanceTaskApi.todoList(params);

适配器说明

必传适配器

  • request 说明:请求实例,至少需要支持 post 方法。
  • userStore 说明:宿主项目的 useUserStore 方法。
  • resolveComponentByPath 说明:根据路径解析页面组件,供审批详情页内部动态加载业务页面使用。

推荐注入的组件适配器

  • FileUpload
  • FileDisplayItem
  • OrganizationDrawer
  • NotFound

说明:

  • 这些组件通过 components 注入
  • 插件安装时会自动同步注册到内部适配器仓库
  • 如果缺少必需组件,运行时会抛出 Missing component adapter 错误

后端动态菜单接入

推荐宿主项目统一维护一份“后端组件路径 -> 实际组件”的映射。

1. 创建工作流路径映射文件

示例:src/router/workflow-component-map.js

import {
  WorkflowApproval,
  WorkflowApprovalDetail,
  WorkflowProcess,
  WorkflowProcessConfiguration,
  WorkflowProcessVersion
} from 'fc-workflow-components';

const MAP = {
  '/workflow/approval/index': WorkflowApproval,
  '/workflow/approval/detail': WorkflowApprovalDetail,
  '/workflow/process/index': WorkflowProcess,
  '/workflow/process/configuration': WorkflowProcessConfiguration,
  '/workflow/process/version': WorkflowProcessVersion
};

export function resolveWorkflowComponentByPath(path) {
  if (!path) return null;
  const normalized = String(path).trim().replace(/\.vue$/i, '').replace(/\/+$/, '');
  return MAP[normalized] || null;
}

2. 动态注册路由时优先走工作流映射

import { resolveWorkflowComponentByPath } from '@/router/workflow-component-map';

const modules = import.meta.glob('/src/views/**/*.vue');

async function resolveLocalView(componentPath) {
  const normalizedPath = String(componentPath || '')
    .trim()
    .replace(/\.vue$/i, '')
    .replace(/^\/+/, '');

  if (!normalizedPath) return null;

  const fullPath = `/src/views/${normalizedPath}.vue`;
  const indexPath = `/src/views/${normalizedPath}/index.vue`;
  const loader = modules[fullPath] || modules[indexPath];
  if (!loader) return null;

  const mod = await loader();
  return mod.default || mod;
}

async function resolveMenuComponent(componentPath) {
  const workflowComponent = resolveWorkflowComponentByPath(componentPath);
  if (workflowComponent) return workflowComponent;

  return await resolveLocalView(componentPath);
}

3. 在工作流插件中复用同一套解析逻辑

WorkflowApprovalDetail 内部也会根据路径动态渲染业务页面,所以 app.use 时注入的 resolveComponentByPath 必须和路由侧保持一致。

推荐写法:

import { resolveWorkflowComponentByPath } from '@/router/workflow-component-map';
import { useUserStore } from '@/store/modules/user';

const modules = import.meta.glob('/src/views/**/*.vue');

function findComponentByPath(menus, targetPath) {
  for (const route of menus || []) {
    if (route.path === targetPath) return route.component;
    if (route.children?.length) {
      const child = findComponentByPath(route.children, targetPath);
      if (child) return child;
    }
  }
  return null;
}

export async function resolveComponentByPath(path) {
  const workflowComponent = resolveWorkflowComponentByPath(path);
  if (workflowComponent) return workflowComponent;

  const componentPath = findComponentByPath(useUserStore().menus, path);
  const normalizedPath = String(componentPath || path || '')
    .trim()
    .replace(/\.vue$/i, '')
    .replace(/^\/+/, '');

  if (!normalizedPath) return null;

  const fullPath = `/src/views/${normalizedPath}.vue`;
  const indexPath = `/src/views/${normalizedPath}/index.vue`;
  const loader = modules[fullPath] || modules[indexPath];
  if (!loader) return null;

  const mod = await loader();
  return mod.default || mod;
}

这套逻辑的好处是:

  • 如果后端返回的是工作流标准路径,例如 /workflow/process/index,会直接命中工作流组件
  • 如果后端返回的是宿主本地页面路径,例如 /business/home/mainProcess,即使菜单未命中,也能兜底从 src/views 直接加载

宿主约定

工作流组件默认会依赖以下宿主能力:

  • 用户信息与菜单树
  • 请求封装
  • 上传组件
  • 附件展示组件
  • 组织选择弹窗
  • 404 页面

如果宿主项目的组件命名不同,建议在接入层统一做一层适配,不要直接修改工作流组件内部逻辑。

EventHub 用法

import { workflowEventHub } from 'fc-workflow-components';

workflowEventHub.emit('refreshFile');

workflowEventHub.on('quoteFile', file => {
  console.log(file);
});

行为说明

审批详情页的页面解析顺序

WorkflowApprovalDetail 会按以下顺序解析业务页面:

  1. 工作流内置路径映射
  2. 宿主菜单树中的 path -> component
  3. 宿主 src/views 下的本地文件兜底加载
  4. 仍未命中时渲染宿主注入的 NotFound

因此页面中间区域出现 404,通常不是浏览器路由没命中,而是“业务组件路径未解析到”。

办理人支持多选

ApprovalSubmitDrawer 中的“办理人”当前支持多选:

  • 下拉框支持多选
  • 组织弹窗选人时会追加并自动去重
  • 提交时仍写回 handlerUserhandlerName
  • 默认以逗号分隔字符串形式提交,方便兼容现有后端接口

常见问题

1. 报错:Missing adapter: request

没有注入 request,或者在宿主安装插件前就提前访问了适配器。

请确认:

  • 已在 app.use(WorkflowPkg, { adapters }) 中注入 request
  • 宿主使用的是当前仓库内最新版代码

2. 报错:Missing component adapter: FileDisplayItem

没有通过 components 注入宿主组件,或者宿主仍在使用旧版本打包产物。

请确认:

  • FileUpload
  • FileDisplayItem
  • OrganizationDrawer
  • NotFound

已在 components 中传入。

3. 页面中间显示 404

通常不是路由没匹配到,而是业务页面组件路径没解析到。

重点检查:

  • 后端返回的 version.data.value
  • workflow-component-map.js 中是否配置了对应工作流路径
  • 宿主 src/views 下是否存在对应文件
  • resolveComponentByPath 是否包含本地 src/views 兜底逻辑

4. 控制台提示 onVisibleChange is deprecated

这是 ant-design-vue 的下拉事件升级提示。

请统一改用:

  • @openChange
  • onOpenChange

不要再使用:

  • @visibleChange
  • onVisibleChange

5. 本地联调时 Vite 报 403 或外部目录不可访问

如果宿主项目通过别名直接引用本地 fc-workflow-components/src/index.js,需要在 Vite 中同时放行宿主目录和组件库目录。

示例:

import { defineConfig, searchForWorkspaceRoot } from 'vite';

export default defineConfig(() => ({
  server: {
    fs: {
      allow: [
        searchForWorkspaceRoot(process.cwd()),
        'D:/project/process/packages/fc-workflow-components'
      ]
    }
  }
}));

本地联调建议

如果宿主项目和组件库在同一工作区,推荐直接把宿主项目的别名指向本地源码,而不是 node_modules 中的旧打包文件。

示例思路:

resolve: {
  alias: {
    'fc-workflow-components': 'D:/project/process/packages/fc-workflow-components/src/index.js'
  }
}

这样联调时改动可以即时生效,也能避免“源码已修、宿主仍跑旧包”的问题。

构建

npm run build

发布前检查建议

  • 确认入口导出与 README 一致
  • 确认适配器名称未变更
  • 确认审批详情页的路径解析逻辑未被破坏
  • 确认 components 注入会同步进入内部适配器仓库
  • 确认宿主联调方式仍可用