@ruovea/tenant
v1.0.9
Published
租户管理模块(租户 / 租户套餐 / 分配套餐)
Downloads
1,204
Readme
@ruovea/tenant
租户 / 租户套餐 / 分配套餐 多租户管理模块,以 pnpm 源码包 形式提供给各宿主项目复用。
- 源码包——
exports直指./src/*,由宿主 Vite 编译,无需预构建 dist - 依赖注入解耦——
request/auth/i18n/userInfos/getDictList/endpoints全部由宿主装配时注入 - 零侵入——包内不含
/@/等宿主别名引用,可独立运行,不绑定特定宿主
一、目录结构
src/
├─ index.ts # 入口:导出 TenantPlugin + API + 类型 + 路由
├─ plugin.ts # Vue install(校验必填项 / provide / mergeLocaleMessage)
├─ context.ts # InjectionKey + useTenantContext() + resolveUserInfos()
├─ types.ts # TenantPluginOptions
├─ routes.ts # 2 条静态路由 + tenantDynamicComponents 动态组件映射
├─ api/
│ ├─ index.ts # 汇总导出
│ ├─ http.ts # request 注入点
│ ├─ endpoints.ts # URL 前缀(可覆盖)
│ ├─ tenant.ts # 租户 API(含分配套餐,共 11 个)
│ └─ tenant-package.ts # 租户套餐 API(7 个)
├─ i18n/locales/ # 6 语言(en / fr-fr / ja-jp / vi-vn / zh-cn / zh-tw)
└─ views/
├─ tenant/ # 租户管理
│ ├─ index.vue # 租户列表(分页查询 / 启停 / 分配套餐)
│ └─ component/
│ ├─ editTenant.vue # 新增/编辑租户
│ └─ grantPackage.vue # 分配套餐弹窗
└─ tenantPackage/ # 租户套餐管理
├─ index.vue
└─ component/editPackage.vue二、宿主接入
2.1 安装
# npm
npm install @ruovea/tenant
# pnpm
pnpm add @ruovea/tenant或使用 link: 协议指向本地源码:
{
"dependencies": {
"@ruovea/tenant": "link:../../module/system-tenant-module/packages/tenant"
}
}2.2 Vite 预构建排除
// vite.config.ts
optimizeDeps: {
exclude: ['vue-demi', '@ruovea/tenant'],
},2.3 装配插件
// plugins/tenant.ts
import { type App } from 'vue';
import { storeToRefs } from 'pinia';
import { TenantPlugin } from '@ruovea/tenant';
import request from '/@/utils/request';
import { auth, auths } from '/@/utils/authFunction';
import { i18n } from '/@/i18n/index';
import { useUserInfo } from '/@/stores/userInfo';
export function setupTenant(app: App) {
const { userInfos } = storeToRefs(useUserInfo());
app.use(TenantPlugin, {
request: request as any,
auth,
auths,
i18n: i18n as any,
userInfos,
getDictList: () => userStore.dictList, // 可选
endpoints: {}, // 可选,覆盖 API 路径
});
}// main.ts
import { setupTenant } from '/@/plugins/tenant';
// ... app.use(pinia) 之后
setupTenant(app);无顺序要求——不依赖其他
@ruovea/*包。
2.4 注册路由
后端动态路由组件映射(推荐)
后端菜单下发 Component = "@ruovea/tenant/tenant/index",宿主 backEnd.ts 用 tenantDynamicComponents 映射:
// router/backEnd.ts
import { tenantDynamicComponents } from '@ruovea/tenant';
export function dynamicImport(dynamicViewsModules, component) {
// ...其他包的映射
if (tenantDynamicComponents[component]) return tenantDynamicComponents[component];
// ...
}菜单 Component 字符串指向:
| Component 字符串 | 页面 |
|---|---|
| @ruovea/tenant/tenant/index | 租户管理 |
| @ruovea/tenant/tenantPackage/index | 租户套餐管理 |
前端静态路由(可选)
// router/route.ts
import { tenantRoutes } from '@ruovea/tenant';
export const dynamicRoutes = [
{
path: '/',
component: () => import('/@/layout/index.vue'),
children: [
// ...其他路由
...tenantRoutes,
],
},
];三、TenantPluginOptions 说明
| 字段 | 必填 | 说明 |
|---|---|---|
| request | ✅ | 宿主 axios 实例(已配 baseURL / 拦截器 / token) |
| auth | ➖ | (code: string) => boolean,单权限校验,缺省 () => true |
| auths | ➖ | (codes: string[]) => boolean,多权限校验,缺省 () => true |
| i18n | ➖ | 宿主 vue-i18n 实例(传入后自动 merge 模块语言包) |
| registerI18n | ➖ | 是否自动注册 i18n,默认 true |
| userInfos | ➖ | 当前登录用户信息(Ref<any> 或 () => any),缺省空对象 |
| getDictList | ➖ | 字典数据(按 typeCode 分组),缺省空对象 |
| endpoints | ➖ | 覆盖 API URL 前缀 |
四、Endpoints 说明
所有 API 路径均可通过 endpoints 覆盖,默认值:
interface TenantEndpoints {
// 租户
tenantPages: '/SysTenant/Pages'
tenantData: '/SysTenant/Data'
tenantList: '/SysTenant/List'
tenantByName: '/SysTenant/TenantByName'
tenantByWebsite: '/SysTenant/TenantByWebsite'
tenantAddData: '/SysTenant/AddData'
tenantUpdateData: '/SysTenant/UpdateData'
tenantDeleteData: '/SysTenant/DeleteData'
tenantChangeStatus: '/SysTenant/ChangeStatus'
tenantPackageIds: '/SysTenant/TenantPackageIds'
tenantPackages: '/SysTenant/TenantPackages'
tenantGrantPackages: '/SysTenant/GrantPackages'
// 租户套餐
tenantPackagePages: '/SysTenantPackage/Pages'
tenantPackageData: '/SysTenantPackage/Data'
tenantPackageList: '/SysTenantPackage/List'
tenantPackageAddData: '/SysTenantPackage/AddData'
tenantPackageUpdateData: '/SysTenantPackage/UpdateData'
tenantPackageDeleteData: '/SysTenantPackage/DeleteData'
tenantPackageChangeStatus: '/SysTenantPackage/ChangeStatus'
}五、权限编码清单
| 编码 | 位置 | 说明 |
|---|---|---|
| sysTenant:page | 租户 | 查询 |
| sysTenant:add | 租户 | 新增 |
| sysTenant:update | 租户 | 编辑 |
| sysTenant:delete | 租户 | 删除 |
| sysTenant:grantPackages | 租户 | 分配套餐 |
| sysTenant:changeStatus | 租户 | 启停 |
| sysTenantPackage:page | 套餐 | 查询 |
| sysTenantPackage:add | 套餐 | 新增 |
| sysTenantPackage:update | 套餐 | 编辑 |
| sysTenantPackage:delete | 套餐 | 删除 |
| sysTenantPackage:changeStatus | 套餐 | 启停 |
未注入 auth 时所有按钮可见(缺省 () => true)。
六、路由
2 条静态路由一览
| path | name | keepAlive | 隐藏 | 说明 |
|---|---|---|---|---|
| /tenant/tenant | tenantList | ✅ | ❌ | 租户管理 |
| /tenant/package | tenantPackage | ✅ | ❌ | 租户套餐管理 |
七、API 清单
7.1 租户(11 个)
| 函数 | 说明 |
|---|---|
| apiTenantPagesGet | 租户分页查询 |
| apiTenantDataGet | 租户详情 |
| apiTenantListGet | 租户列表(登录页租户选择) |
| apiTenantByNameGet | 按名称获取租户 |
| apiTenantByWebsiteGet | 按域名获取租户 |
| apiTenantAddDataPost | 新增租户 |
| apiTenantUpdateDataPost | 更新租户 |
| apiTenantDeleteDataPost | 删除租户 |
| apiTenantChangeStatusPost | 修改租户状态 |
| apiTenantPackageIdsGet | 获取租户套餐 Id 集合 |
| apiTenantGrantPackagesPost | 分配租户套餐 |
7.2 租户套餐(7 个)
| 函数 | 说明 |
|---|---|
| apiTenantPackagePagesGet | 套餐分页查询 |
| apiTenantPackageDataGet | 套餐详情 |
| apiTenantPackageListGet | 套餐列表 |
| apiTenantPackageAddDataPost | 新增套餐 |
| apiTenantPackageUpdateDataPost | 更新套餐 |
| apiTenantPackageDeleteDataPost | 删除套餐 |
| apiTenantPackageChangeStatusPost | 修改套餐状态 |
八、i18n 注入约定
包内视图使用 message.tenant.xxx、message.tenantPackage.xxx、message.grantPackage.xxx、message.router.xxx 等 key。插件双层 merge(顶层 + message 层),翻译资源自包含。
支持 6 种语言:zh-cn / zh-tw / en / ja-jp / fr-fr / vi-vn。
九、License
MIT
