

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
12345# 多租户(v8.0新增)67多租户(Multi-tenancy)是一种软件架构模式,允许单个应用实例服务多个租户(客户组织)。每个租户的数据是相互隔离的,但共享同一个应用程序代码和基础设施。8910## 主要特点1112- **数据隔离**: 确保不同租户之间的数据严格分离,互不可见13- **资源共享**: 多个租户共享同一套应用程序代码和基础设施14- **独立配置**: 每个租户可以有自己的个性化配置和定制化需求15- **成本优化**: 通过资源共享降低运营和维护成本1617## 实现1819### 1、数据隔离2021多租户的数据隔离有许多种方案,但最为常见的是以列进行隔离的方式。Cool Admin 通过在`BaseEntity`中加入指定的列(租户ID `tenantId`)对数据进行隔离。2223::: tip 小贴士2425v8.0之后,`BaseEntity`已经从`cool-midway/core`中移动至`src/modules/base/entity/base.ts`,方便开发者扩展定制2627:::282930`src/modules/base/entity/base.ts`31```ts32import {33 Index,34 UpdateDateColumn,35 CreateDateColumn,36 PrimaryGeneratedColumn,37 Column,38} from 'typeorm';39import { CoolBaseEntity } from '@cool-midway/core';4041/**42 * 实体基类43 */44export abstract class BaseEntity extends CoolBaseEntity {45 // 默认自增46 @PrimaryGeneratedColumn('increment', {47 comment: 'ID',48 })49 id: number;5051 @Index()52 @CreateDateColumn({ comment: '创建时间' })53 createTime: Date;5455 @Index()56 @UpdateDateColumn({ comment: '更新时间' })57 updateTime: Date;5859 @Index()60 @Column({ comment: '租户ID', nullable: true })61 tenantId: number;62}6364```6566### 2、条件注入6768Cool 改造了 `typeorm`的 `Subscriber`,新增了以下四种监听:6970```ts71/**72 * 当进行select的QueryBuilder构建之后触发73 */74afterSelectQueryBuilder?(queryBuilder: SelectQueryBuilder<any>): void;7576/**77 * 当进行insert的QueryBuilder构建之后触发78 */79afterInsertQueryBuilder?(queryBuilder: InsertQueryBuilder<any>): void;8081/**82 * 当进行update的QueryBuilder构建之后触发83 */84afterUpdateQueryBuilder?(queryBuilder: UpdateQueryBuilder<any>): void;8586/**87 * 当进行delete的QueryBuilder构建之后触发88 */89afterDeleteQueryBuilder?(queryBuilder: DeleteQueryBuilder<any>): void;90```9192在`src/modules/base/db/tenant.ts`中,通过`tenantId`进行条件注入,从而实现数据隔离。9394## 使用9596### 1、开启多租户9798框架默认关闭多租户,需要手动开启,在`src/config/config.default.ts`中开启多租户99100```ts101cool: {102 // 是否开启多租户103 tenant: {104 // 是否开启多租户105 enable: true,106 // 需要过滤多租户的url, 支持通配符,如/admin/**/* 表示admin模块下的所有接口都进行多租户过滤107 urls: [],108 },109 }110```111tenant112### 2、代码中使用113114只要开启了多租户,并配置了`urls`,那么框架会自动注入`tenantId`,开发者原本的代码不需要做任何修改,框架会自动进行数据隔离。115116#### Controller117118@CoolController的`add`、`delete`、`update`、`info`、`list`、`page`方法都支持过滤多租户。119120121#### Service122123`Service`中使用多租户,以下是一个完整的示例,包含有效和无效的情况,开发者需要结合实际业务进行选择。124125```ts126import { Inject, Provide } from '@midwayjs/core';127import { BaseService } from '@cool-midway/core';128import { InjectEntityModel } from '@midwayjs/typeorm';129import { Repository } from 'typeorm';130import { DemoGoodsEntity } from '../entity/goods';131import { UserInfoEntity } from '../../user/entity/info';132import { noTenant } from '../../base/db/tenant';133134/**135 * 商品服务136 */137@Provide()138export class DemoTenantService extends BaseService {139 @InjectEntityModel(DemoGoodsEntity)140 demoGoodsEntity: Repository<DemoGoodsEntity>;141142 @Inject()143 ctx;144145 /**146 * 使用多租户147 */148 async use() {149 await this.demoGoodsEntity.createQueryBuilder().getMany();150 await this.demoGoodsEntity.find();151 }152153 /**154 * 不使用多租户(局部不使用)155 */156 async noUse() {157 // 过滤多租户158 await this.demoGoodsEntity.createQueryBuilder().getMany();159 // 被noTenant包裹,不会过滤多租户160 await noTenant(this.ctx, async () => {161 return await this.demoGoodsEntity.createQueryBuilder().getMany();162 });163 // 过滤多租户164 await this.demoGoodsEntity.find();165 }166167 /**168 * 无效多租户169 */170 async invalid() {171 // 自定义sql,不进行多租户过滤172 await this.nativeQuery('select * from demo_goods');173 // 自定义分页sql,进行多租户过滤174 await this.sqlRenderPage('select * from demo_goods', {});175 }176}177178```
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| cool-team-official/cool-admin-midway.cursor/rules/authority.mdc · 3.3k | Cursor rules | security | 54/100 | today | |
| cool-team-official/cool-admin-midway.cursor/rules/cache.mdc · 3.3k | Cursor rules | no sections | 58/100 | today | |
| cool-team-official/cool-admin-midway.cursor/rules/controller.mdc · 3.3k | Cursor rules | api | 46/100 | today | |
| cool-team-official/cool-admin-midway.cursor/rules/db.mdc · 3.3k | Cursor rules | setupdatabase | 62/100 | today | |
| cool-team-official/cool-admin-midway.cursor/rules/event.mdc · 3.3k | Cursor rules | no sections | 45/100 | today | |
| cool-team-official/cool-admin-midway.cursor/rules/module.mdc · 3.3k | Cursor rules | no sections | 50/100 | today | |
| cool-team-official/cool-admin-midway.cursor/rules/service.mdc · 3.3k | Cursor rules | database | 54/100 | today | |
| cool-team-official/cool-admin-midway.cursor/rules/socket.mdc · 3.3k | Cursor rules | no sections | 58/100 | today | |
| cool-team-official/cool-admin-midway.cursor/rules/task.mdc · 3.3k | Cursor rules | style | 58/100 | today | |
| cool-team-official/cool-admin-midway.cursorrules · 3.3k | .cursorrules | no sections | 39/100 | today |
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| hiromaily/go-crypto-wallet.cursor/rules/typescript.mdc · 126 | Cursor rules | setupbuildtestlint-format+6 | 100/100 | 14 days ago | |
| TechSquidTV/Hermes.cursor/rules/10-hermes-api.mdc · 46 | Cursor rules | testlint-formatstylearch+5 | 100/100 | 14 days ago | |
| Allymahmoud/case-intake-platform.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 14 days ago | |
| deifos/clipmira-subtitles.cursor/rules/frontend.mdc · 1 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 14 days ago | |
| markstev/mark-starter.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+6 | 99/100 | 14 days ago | |
| dodgecfr/combatfilms-webapp.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 14 days ago | |
| langflow-ai/langflow.cursor/rules/docs_development.mdc · 153k | Cursor rules | setupbuildtestlint-format+7 | 97/100 | 14 days ago | |
| TechSquidTV/Hermes.cursor/rules/20-hermes-api-tests.mdc · 46 | Cursor rules | teststyletesting-strategysecurity+3 | 97/100 | 14 days ago |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/cool-team-official-cool-admin-midway-cursor-rules-tenant)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.