123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- 'use strict';
- const _ = require('lodash');
- const TENANT_MODELS = Symbol('Context#models@tenant');
- // 已废弃
- const _loadModel = (app, tenant) => {
- app.logger.info(`[multi-tenancy] Load tenant models for ${tenant}`);
- const model = {};
- _.forEach(app.model, (val, key) => {
- const modelName = `${val.modelName}@${tenant}`;
- const collName = `_${tenant}.${val.collection.name}`;
- const multiTenancy = val.schema.get('multi-tenancy');
- if (multiTenancy) {
- app.logger.debug(`[multi-tenancy] ${modelName} loaded`);
- model[key] = val.db.model(modelName, val.schema, collName);
- } else {
- app.logger.debug(`[multi-tenancy] skip ${val.modelName}, schema not enable multi-tenancy.`);
- model[key] = val;
- }
- });
- return model;
- };
- const multiTenancyPlugin = (schema, options = {}) => {
- const { defaultTenant = 'master' } = options;
- schema.add({
- _tenant: { type: String, default: defaultTenant, index: true },
- });
- schema.pre('save', async function() {
- const tenant = schema.get('x-tenant');
- if (tenant !== 'global') {
- this._tenant = schema.get('x-tenant');
- }
- });
- const querys = [ 'count', 'countDocuments', 'find', 'findOne', 'findOneAndRemove', 'findOneAndUpdate', 'remove', 'deleteOne', 'deleteMany', 'update', 'updateOne', 'updateMany' ];
- querys.forEach(action => {
- schema.pre(action, async function() {
- const tenant = schema.get('x-tenant');
- if (tenant !== 'global') {
- this.where('_tenant').equals(schema.get('x-tenant'));
- }
- });
- });
- };
- const loadModel2 = (app, tenant) => {
- app.logger.info(`[multi-tenancy] Load tenant models for ${tenant}`);
- let model = {};
- const setModel = (val,key) =>{
- const obj = {};
- const modelName = `${val.modelName}@${tenant}`;
- const collName = `${val.collection.name}`;
- const multiTenancy = val.schema.get('multi-tenancy');
- if (multiTenancy) {
- app.logger.debug(`[multi-tenancy] ${modelName} loaded`);
- const schema = val.schema.clone();
- schema.set('x-tenant', tenant);
- schema.plugin(multiTenancyPlugin, app.config.multiTenancy);
- obj[key] = val.db.model(modelName, schema, collName);
- } else {
- app.logger.debug(`[multi-tenancy] skip ${val.modelName}, schema not enable multi-tenancy.`);
- obj[key] = val;
- }
- return obj;
- }
- _.forEach(app.model, (val, key) => {
- const nval = getAllModel(val);
- // 文件夹分层级后,val不再只是Function,也有可能是Object,添加个方法,获取所有model
- if(!_.isArray(nval)) {
- let mod = {};
- mod = setModel(nval,key);
- model = {...model,...mod};
- }
- else {
- let mods = {};
- mods[key] = {};
- for (const model of nval) {
- const nkey = _.upperFirst(model.modelName);
- let mod = setModel(model,nkey);
- mods[key] = {...mods[key],...mod};
- }
- model = {...model,...mods};
- }
- });
- return model;
- };
- // this 就是 app 对象,在其中可以调用 app 上的其他方法,或访问属性
- module.exports = {
- // 多租户系统中的model对象
- tenantModel(tenant) {
- const { defaultTenant: _defaultTenant } = this.config.multiTenancy || {};
- if (tenant /* && tenant !== _defaultTenant*/) {
- // 非默认租户,加载租户model
- if (!this[TENANT_MODELS]) {
- this[TENANT_MODELS] = [];
- }
- const models = this[TENANT_MODELS];
- if (!models[tenant]) {
- // 加载租户Model
- models[tenant] = loadModel2(this, tenant);
- }
- return models[tenant];
- }
- // 默认租户返回原始model对象
- return this.model;
- },
- };
|