后端前端企业应用MCP 服务【免费下载链接】ever-gauzyEver® Gauzy™ - Open Business Management Platform (ERP/CRM/HRM/ATS/PM) - https://gauzy.co项目地址https://gitcode.com/GitHub_Trending/ev/ever-gauzy点击查看免费下载本文以 Ever Gauzy 开源商业管理平台ERP/CRM/HRM/ATS/PM中的 UI 插件gauzy/plugin-job-employee-ui为核心完整讲解该插件的安装、构建、测试、发布流程并结合仓库源码剖析其插件定义、路由权限、页面组件、数据表配置与前后端联动原理。读完本文你将掌握在 Ever Gauzy 中为「Jobs 员工管理」功能编写、接入与维护一个 Angular UI 插件的完整方法论也能直接复用到其他 Gauzy 插件如 Job Search、Job Matching、Job Proposal的开发实践中。插件是什么Jobs 板块下的「Employee」管理界面gauzy/plugin-job-employee-ui是 Ever Gauzy 平台中负责「Job Employee工作职位员工」管理界面的前端插件。它的职责可以用一句话概括在 Gauzy 的 Jobs 导航板块下为组织管理员提供一个查看与维护「参与职位搜索的员工」的交互页面——包括员工列表、其可用职位数 / 已申请职位数统计、计费费率Billing Rate与最低计费费率编辑以及「是否处于职位搜索状态」的开关切换。从插件定位上看它属于 Ever Gauzy 插件体系中的「UI 插件」类型只负责界面呈现与交互而业务逻辑由后端gauzy/plugin-job-search中的EmployeeJobPostController见 employee-job.controller.ts提供 REST 接口支撑。插件通过 Nx 生成的 Angular library 结构组织其工程元数据记录在 project.json 中tags标注为type:plugin与type:plugin-extension-point说明它既是插件又是平台 UI 的扩展点。该插件的代码量并不大但麻雀虽小五脏俱全一个插件定义、一个 NgModule、一套路由配置、一个主页面组件、一个状态编辑组件与一个服务 provider。下面我们沿着官方 README 的操作主线从安装、构建、测试、发布到源码剖析逐层深入。安装插件插件以 npm 包形式分发。在任意 Node.js 项目中安装gauzy/plugin-job-employee-ui只需一行命令来自 README.mdnpm install gauzy/plugin-job-employee-ui # 或使用 yarn yarn add gauzy/plugin-job-employee-ui需要留意的是插件包的 package.json 声明了若干重要的约束peerDependencies要求angular/common与angular/core均为21.0.7因此宿主应用必须运行在匹配的 Angular 21 版本上dependencies中引用了gauzy/contracts、gauzy/ui-core、gauzy/plugin-ui、nebular/theme、angular2-smart-table、ngx-permissions、ngx-translate/core等库安装时需确保这些依赖能够解析engines声明了node 22、yarn 1.22包本身标记为private: true这意味着在仓库内它仅供内部工作区使用实际对外发布时需由发布流程处理。构建插件在 Ever Gauzy 的 monorepo 工作区中所有包都通过 Nx 统一管理。构建该插件的命令README 原文yarn nx build plugin-job-employee-ui构建由nx/angular:ng-packagr-liteexecutor 执行产物输出到dist/packages/plugins/job-employee-ui见 project.json。工程还内置了两个构建配置# 开发模式构建project.json 中的 defaultConfiguration yarn nx build plugin-job-employee-ui --configurationdevelopment # 生产模式构建使用 tsconfig.lib.prod.json yarn nx build plugin-job-employee-ui --configurationproductionpackage.json 中同步封装了常用脚本yarn lib:build、yarn lib:build:prod与yarn lib:watch监听模式。由于构建目标声明了dependsOn: [^build]Nx 会先构建该插件的隐式依赖contracts、ui-config、ui-core保证依赖包是最新产物。运行单元测试插件的单元测试由 Jest 驱动命令为yarn nx test plugin-job-employee-ui测试入口配置在 jest.config.ts并依赖jest-preset-angular。仓库中现存的测试用例位于 job-employee.component.spec.ts它演示了如何在非 standalone 环境下测试插件组件直接将声明了该组件的JobEmployeeModule作为测试模块的imports导入并为EmployeesService、ActivatedRoute模拟tabsetId: job-employee与dataTableId: job-employee-page路由数据提供 mock最后断言组件能够成功创建await TestBed.configureTestingModule({ imports: [JobEmployeeModule], providers: [ EmployeesService, { provide: ActivatedRoute, useValue: { /* tabsetId / dataTableId mock */ } } ], teardown: { destroyAfterEach: false } }).compileComponents();发布插件构建完成后即可发布。README 给出的发布流程是进入构建产物目录dist/packages/plugins/job-employee-ui然后执行npm publish发布前请确认产物目录中已包含package.jsonng-packagr 会自动生成、README.md、类型声明与编译后的 JS 文件。该插件遵循 AGPL-3.0 许可见 package.json 的license字段对外分发时需遵守相应的许可证条款。在 Gauzy 应用中接入插件安装、构建只是把包准备好了真正让插件「生效」的是在 Gauzy 前端应用apps/gauzy的插件配置中心里注册它。应用的 UI 插件配置位于 apps/gauzy/src/plugin-ui.config.ts它导出一个PluginUiConfig对象其中plugins数组即「当前构建激活的插件清单」。Job Employee 插件被组织在 Jobs 插件组之下作为JobsPlugin的子插件注册配置代码原文如下// apps/gauzy/src/plugin-ui.config.ts import { JobEmployeePlugin } from gauzy/plugin-job-employee-ui; // ... export const uiPluginConfig: PluginUiConfig { // ... i18n / locale 配置 plugins: [ // ... JobsPlugin.init({ plugins: [ JobProposalPlugin, JobEmployeePlugin, JobSearchPlugin, JobMatchingPlugin, JobProposalTemplatePlugin ] }), // ... ] };这种「父插件 子插件」的层级注册方式JobsPlugin.init({ plugins: [...] })正是 Ever Gauzy 插件体系的组织范式父插件作为逻辑分组可以没有自己的 module子插件各自贡献路由、导航与页面最终在应用启动时被扁平化后统一引导。PluginUiDefinition类型的完整字段说明见 packages/plugin-ui/src/lib/plugin-ui.types.ts包括id、module、loadModule、location、plugins、routes、navMenu、permissionKeys、dependsOn等。插件定义源码剖析一份声明式注册清单插件入口 job-employee-plugin.ts 导出一个常量对象JobEmployeePlugin它就是整个插件的「元数据清单」export const JobEmployeePlugin: PluginUiDefinition { id: job-employee, version: 0.1.0, location: jobs-sections, module: JobEmployeeModule, permissionKeys: [PermissionsEnum.ORG_JOB_EMPLOYEE_VIEW], routes: [JOB_EMPLOYEE_PAGE_ROUTE as PluginRouteInput], navMenu: [ { type: section, sectionId: jobs, items: [ { id: jobs-employee, title: Employee, icon: fas fa-user-friends, link: JOB_EMPLOYEE_PAGE_LINK, data: { translationKey: MENU.EMPLOYEES, permissionKeys: [PermissionsEnum.ORG_JOB_EMPLOYEE_VIEW] } } ] } ] };逐一解读各字段的含义id插件唯一标识job-employeeversion插件版本0.1.0与 package.json 的版本号保持一致location声明该插件挂载的页面路由注册位置jobs-sections与JobsPlugin的父板块位置对应module插件的 Angular NgModule 类即JobEmployeeModulepermissionKeys插件激活所需权限这里要求ORG_JOB_EMPLOYEE_VIEWroutes声明式路由列表将注册到PageRouteRegistryServicenavMenu导航菜单贡献在jobssection 下新增一个标题为Employee、图标为fas fa-user-friends、链接指向/pages/jobs/employee的导航项并附带翻译 keyMENU.EMPLOYEES与权限 key。这种声明式设计意味着插件的路由、导航甚至扩展点都可以在「不写一行 Angular 路由代码」的情况下完成注册真正做到了界面功能按插件粒度插拔。路由与权限如何挂到 /pages/jobs/employee路由配置定义在 job-employee.routes.tsexport const JOB_EMPLOYEE_PATH employee; export const JOB_EMPLOYEE_PAGE_LINK /pages/jobs/${JOB_EMPLOYEE_PATH}; export const JOB_EMPLOYEE_PAGE_ROUTE: PageRouteRegistryConfig { location: jobs-sections, path: JOB_EMPLOYEE_PATH, component: JobEmployeeComponent, canActivate: [PermissionsGuard], data: { tabsetId: job-employee, dataTableId: job-employee-page, selectors: { date: true, employee: true, project: false, team: false }, permissions: { only: [PermissionsEnum.ORG_JOB_EMPLOYEE_VIEW], redirectTo: /pages/jobs/search } } };几个值得注意的细节页面完整地址为/pages/jobs/employee在jobs-sections位置注册渲染组件为JobEmployeeComponent通过canActivate: [PermissionsGuard]做进入守卫同时data.permissions.only声明仅拥有ORG_JOB_EMPLOYEE_VIEW权限的用户可访问无权限时重定向到/pages/jobs/searchdata.selectors控制页面顶部的全局筛选器开关日期与员工筛选开启项目与团队筛选关闭tabsetId: job-employee与dataTableId: job-employee-page两个 ID 是页面与 UI 注册中心PageTabRegistryService、PageDataTableRegistryService之间的「契约」组件初始化时从ActivatedRoute快照读取它们见 job-employee.component.ts。后端侧ORG_JOB_EMPLOYEE_VIEW权限由 employee-job.controller.ts 中的GET /employee-job/statistics接口以Permissions(PermissionsEnum.ORG_JOB_EMPLOYEE_VIEW)注解强制校验前端权限守卫与后端权限装饰器形成了双层防护。页面组件三页签与六列表格的完整实现JobEmployeeComponentjob-employee.component.ts是插件的核心视图扩展自PaginationFilterBaseComponent负责分页、筛选与智能表格angular2-smart-table的组装。它注册了三个页签JobSearchTabsEnum页签 ID图标翻译 key内容browseglobe-2-outlineJOB_EMPLOYEE.BROWSE员工数据表格tableLayout模板searchsearch-outlineJOB_EMPLOYEE.SEARCHcomingSoon占位模板historyclock-outlineJOB_EMPLOYEE.HISTORYcomingSoon占位模板数据表注册了 6 列通过PageDataTableRegistryService.registerPageDataTableColumn注册到job-employee-page数据表Employee员工自定义渲染组件EmployeeLinksComponent显示员工姓名、头像与链接支持排序编辑组件为EmployeeLinkEditorComponentAvailable Jobs可用职位数纯文本列valuePrepareFunction将空值归零显示Applied Jobs已申请职位数同 Available Jobs空值归零Billing Rate计费费率可编辑数字列使用NumberEditorComponent展示时经CurrencyPipe按员工billRateCurrency格式化货币Minimum Billing Rate最低计费费率可编辑数字列同样按员工币种格式化Job Search Status职位搜索状态自定义渲染组件ToggleSwitcherComponent开关编辑组件为JobSearchStatusEditorComponent切换后调用服务层持久化。数据加载采用ServerDataSource服务端分页数据源请求端点为${API_PREFIX}/employee-job/statistics即后端GET /api/employee-job/statistics并附带relations: [user]与组织/租户筛选条件const whereClause { tenantId, organizationId, isActive: true, isArchived: false, ...(this.selectedEmployeeId ? { id: this.selectedEmployeeId } : {}), ...(this.filters.where ? this.filters.where : {}) };一个值得展开的权限细节当当前用户没有CHANGE_SELECTED_EMPLOYEE权限时组件会强制把whereClause.id设为自己所属员工 ID即「普通员工只能看到自己的职位统计」这是多租户 SaaS 场景下典型的行级数据隔离实现。列表刷新链路也值得学习组件监听employees$主题Subject经过 100ms 防抖后关闭右侧详情抽屉并重新拉取数据pagination$分页变化与Store中组织/员工选择变化都会触发employees$.next(true)进入刷新链路。编辑费率与求职状态前端交互到后端命令的完整链路行内编辑费率表格的编辑动作编辑、保存、取消三组操作按钮在_loadSmartTableSettings()中配置confirmSave: true使保存前触发确认回调onEditConfirm其实现调用EmployeesService.updateProfile更新minimumBillingRate与billRateValue两个字段携带tenantId、organizationId成功后刷新列表并confirm.resolve失败则confirm.reject。取消编辑则直接调用smartTableSource.refresh()回滚行内改动。该文件内还包含一处颇有价值的实现细节注释操作按钮图标原本依赖[innerHTML]注入字符串而字符串中的nb-icon永远不会被实例化因此组件通过NbIconLibraries.getSvgIcon()从已注册的eva图标包中直接读出 SVG 内容并对翻译标签做了 HTML 转义escapeHtml与无障碍处理sr-only文本同时配合sanitizer: { bypassHtml: true }让 angular2-smart-table 的 DomSanitizer 通道生效——这是插件环境与库渲染机制磨合的典型范例。切换职位搜索状态行内开关的底层服务是 job-search-store.service.ts 中的JobSearchStoreServiceawait this._jobService.updateJobSearchStatus(employee.id, { isJobSearchActive, organizationId, tenantId });其对应的后端接口为PUT /employee-job/:id/job-search-status见 employee-job.controller.ts需要ORG_EMPLOYEES_EDIT或PROFILE_EDIT权限请求体经EmployeeJobStatisticDTO校验最终通过 CQRS 命令总线执行UpdateEmployeeJobSearchStatusCommand见 update-employee-job-search-status.command.ts。服务层在成功与失败时分别弹出 i18n 化的 toast 提示TOASTR.MESSAGE.EMPLOYEE_JOB_STATUS_ACTIVE/EMPLOYEE_JOB_STATUS_INACTIVE。JobSearchStatusEditorComponentjob-search-status-editor.component.ts是DefaultEditor的子类模板直接渲染ngx-toggle-switcher并监听Store.selectedOrganization$获取组织上下文通过cell.getRow().getData()取得当前行员工。注意它在组件级providers中重新提供了JobSearchStoreService——源码注释明确指出这样做的原因是智能表格动态创建的单元格编辑器如行内开关的注入器可能看不到模块级 provider否则会报 NG0201 错误。只读详情抽屉选中行后可通过操作按钮打开右侧详情抽屉view()/buildViewSections()以「字段列表」形式纵向展示员工、可用/已申请职位数、格式化后的计费费率与最低费率、职位搜索状态布尔开关。抽屉数据与表格列的渲染逻辑空值归零、货币格式化保持一致确保两种视图呈现的信息完全等价。插件生命周期声明式注册如何被应用job-employee.module.ts 中的JobEmployeeModule实现了IOnPluginUiBootstrap与IOnPluginUiDestroy两个生命周期接口。在ngOnPluginBootstrap()中调用applyDeclarativeRegistrations(this._pluginDefinition, { navBuilder, pageRouteRegistry })一次性把插件定义里的路由与导航项写入 UI 核心服务模块内通过静态布尔标记_hasAppliedRegistrations保证「每次应用生命周期内只注册一次」ngOnPluginDestroy()时复位该标记避免热重载或多实例场景下重复注册。Angular 的 DI 注入在这里得到了充分运用inject(LoggerService)带JobEmployeeModule上下文、inject(NavMenuBuilderService)、inject(PageRouteRegistryService)以及inject(PLUGIN_DEFINITION, { optional: true })——后者是宿主框架在插件实例化时注入的当前插件定义对象若为空如单元测试中未走 PluginUiModule 引导路径则跳过注册。插件对外暴露的公共 API 面index.ts仅三个导出JobEmployeePlugin插件定义、JobEmployeeModuleAngular 模块、JobEmployeeComponent页面组件保持了「最小公共面」的插件封装原则。小结从 README 到生产级插件的完整知识链回顾整个gauzy/plugin-job-employee-ui工程侧安装npm install/yarn add、构建yarn nx build plugin-job-employee-ui、测试yarn nx test plugin-job-employee-ui、发布cd dist/packages/plugins/job-employee-ui npm publish四条命令即可覆盖插件生命周期的全部常规操作集成侧在 apps/gauzy/src/plugin-ui.config.ts 中通过JobsPlugin.init({ plugins: [...] })挂载为 Jobs 板块子插件实现侧声明式插件定义路由 导航 权限 NgModule 生命周期注册 组件页签/数据表注册 服务端数据源构成一套完整的「前端插件 后端 REST/CQRS」联动模式。对于希望在 Ever Gauzy 中扩展职位管理功能例如为 Browse 页签增加新列、把 Search/History 占位页签实现为真实视图、接入新的职位来源统计的开发者本插件即是现成的参考范本它完整展示了插件如何声明路由、如何受权限门控、如何通过注册中心组装页面元素、以及如何在插件上下文中安全地处理动态单元格编辑器与图标渲染等工程细节。赞分享后端前端企业应用MCP 服务【免费下载链接】ever-gauzyEver® Gauzy™ - Open Business Management Platform (ERP/CRM/HRM/ATS/PM) - https://gauzy.co项目地址https://gitcode.com/GitHub_Trending/ev/ever-gauzy点击查看免费下载相关推荐Ever Gauzy 视频管理 UI 插件 gauzy/plugin-videos-ui 完整实战指南Ever Gauzy 视频管理 UI 插件 gauzy/plugin videos ui 完整实战指南 gauzy/plugin videos ui 是 E后端前端企业应用MCP 服务Ever Gauzy AI 集成 UI 插件gauzy/plugin-integration-ai-ui开发实践与源码解析Ever Gauzy AI 集成 UI 插件gauzy/plugin integration ai ui开发实践与源码解析 Ever® Gauzy™ 的后端前端企业应用MCP 服务在 Ever Gauzy 中集成 Activepiecesgauzy/plugin-integration-activepieces-ui 插件深度解析在 Ever Gauzy 中集成 Activepiecesgauzy/plugin integration activepieces ui 插件深度解析 导后端前端企业应用MCP 服务创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考