mirror of
https://github.com/steedos/steedos-platform
synced 2024-11-22 00:01:52 +00:00
bootstrap 接口慢问题 #2714
This commit is contained in:
parent
01b8c2b08b
commit
47eaaf2c1e
@ -1,7 +1,7 @@
|
||||
import steedosI18n = require("@steedos/i18n");
|
||||
import { getPlugins } from '../';
|
||||
import { requireAuthentication } from './auth'
|
||||
import { getObject, getObjectLayouts, getLayout, getAppConfigs, getAssignedMenus, getAssignedApps } from '@steedos/objectql'
|
||||
import { getObject, getObjectLayouts, getLayout, getAppConfigs, getAssignedMenus, getAssignedApps, FieldPermission } from '@steedos/objectql'
|
||||
require("@steedos/license");
|
||||
const Fiber = require('fibers')
|
||||
const clone = require("clone");
|
||||
@ -166,10 +166,8 @@ export async function getSpaceBootStrap(req, res) {
|
||||
}
|
||||
|
||||
let space = Creator.Collections["spaces"].findOne({ _id: spaceId }, { fields: { name: 1 } })
|
||||
|
||||
//TODO 无需再从getAllPermissions中获取用户的对象权限
|
||||
let result = Creator.getAllPermissions(spaceId, userId);
|
||||
|
||||
let lng = _getLocale(db.users.findOne(userId, { fields: { locale: 1 } }))
|
||||
steedosI18n.translationObjects(lng, result.objects);
|
||||
result.user = userSession
|
||||
@ -183,9 +181,7 @@ export async function getSpaceBootStrap(req, res) {
|
||||
// result.apps = clone(Creator.Apps)
|
||||
result.apps = await getAppConfigs(spaceId);
|
||||
result.assigned_apps = await getAssignedApps(userSession);
|
||||
|
||||
let datasources = Creator.steedosSchema.getDataSources();
|
||||
|
||||
// for (const datasourceName in datasources) {
|
||||
// if(datasourceName != 'default'){
|
||||
// let datasource = datasources[datasourceName];
|
||||
@ -200,6 +196,15 @@ export async function getSpaceBootStrap(req, res) {
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
const spaceProcessDefinition = await getObject("process_definition").find({ filters: [['space', '=', spaceId], ['active', '=', true]] })
|
||||
const spaceObjectsProcessDefinition = _.groupBy(spaceProcessDefinition, 'object_name');
|
||||
|
||||
const dbListViews = await getObject("object_listviews").directFind({ filters: [['space', '=', userSession.spaceId], [['owner', '=', userSession.userId], 'or', ['shared', '=', true]]] })
|
||||
const dbObjectsListViews = _.groupBy(dbListViews, 'object_name');
|
||||
|
||||
const layouts = await getObjectLayouts(userSession.profile, spaceId)
|
||||
const objectsLayouts = _.groupBy(layouts, 'object_name');
|
||||
const objectsFieldsPermissionGroupRole = await FieldPermission.getObjectsFieldsPermissionGroupRole();
|
||||
for (const datasourceName in datasources) {
|
||||
let datasource = datasources[datasourceName];
|
||||
const datasourceObjects = await datasource.getObjects();
|
||||
@ -207,7 +212,13 @@ export async function getSpaceBootStrap(req, res) {
|
||||
const objectConfig = object.metadata;
|
||||
if (!result.objects[objectConfig.name] || objectConfig.name.endsWith("__c")) {
|
||||
try {
|
||||
const userObjectConfig = await getObject(objectConfig.name).getRecordView(userSession);
|
||||
const userObjectConfig = await getObject(objectConfig.name).getRecordView(userSession, {
|
||||
objectConfig: objectConfig,
|
||||
layouts: objectsLayouts[objectConfig.name] || [],
|
||||
spaceProcessDefinition: spaceObjectsProcessDefinition[objectConfig.name] || [],
|
||||
dbListViews: dbObjectsListViews[objectConfig.name] || [],
|
||||
rolesFieldsPermission: objectsFieldsPermissionGroupRole[objectConfig.name] || []
|
||||
});
|
||||
let _objectConfig = null;
|
||||
if (userObjectConfig) {
|
||||
_objectConfig = userObjectConfig
|
||||
@ -217,8 +228,12 @@ export async function getSpaceBootStrap(req, res) {
|
||||
const _obj = Creator.convertObject(_objectConfig, spaceId)
|
||||
_obj.name = objectConfig.name
|
||||
_obj.database_name = datasourceName
|
||||
_obj.permissions = await getObject(objectConfig.name).getUserObjectPermission(userSession)
|
||||
steedosI18n.translationObject(lng, _obj.name, _obj);
|
||||
if (userObjectConfig) {
|
||||
_obj.permission = userObjectConfig.permissions
|
||||
} else {
|
||||
_obj.permissions = await getObject(objectConfig.name).getUserObjectPermission(userSession)
|
||||
steedosI18n.translationObject(lng, _obj.name, _obj);
|
||||
}
|
||||
result.objects[_obj.name] = _obj
|
||||
} catch (error) {
|
||||
console.error(error.message)
|
||||
@ -279,25 +294,23 @@ export async function getSpaceBootStrap(req, res) {
|
||||
result.dashboards = _Dashboards
|
||||
|
||||
result.plugins = getPlugins ? getPlugins() : null
|
||||
|
||||
await getUserObjects(userId, spaceId, result.objects);
|
||||
|
||||
// TODO object layout 是否需要控制审批记录显示?
|
||||
let spaceProcessDefinition = await getObject("process_definition").find({filters: [['space', '=', spaceId], ['active', '=', true]]})
|
||||
|
||||
_.each(spaceProcessDefinition, function(item){
|
||||
if(result.objects[item.object_name]){
|
||||
result.objects[item.object_name].enable_process = true
|
||||
}
|
||||
})
|
||||
|
||||
for (const key in result.objects) {
|
||||
if (Object.prototype.hasOwnProperty.call(result.objects, key)) {
|
||||
const objectConfig = result.objects[key];
|
||||
try {
|
||||
const object = getObject(key);
|
||||
objectConfig.details = await object.getDetailsInfo();
|
||||
objectConfig.masters = await object.getMastersInfo();
|
||||
objectConfig.lookup_details = await object.getLookupDetailsInfo();
|
||||
const relationsInfo = await object.getRelationsInfo();
|
||||
objectConfig.details = relationsInfo.details;
|
||||
objectConfig.masters = relationsInfo.masters;
|
||||
objectConfig.lookup_details = relationsInfo.lookup_details;
|
||||
_.each(objectConfig.triggers, function(trigger, key){
|
||||
if(trigger?.on != 'client'){
|
||||
delete objectConfig.triggers[key];
|
||||
@ -311,8 +324,6 @@ export async function getSpaceBootStrap(req, res) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return res.status(200).send(result);
|
||||
}).run();
|
||||
}
|
||||
@ -332,9 +343,10 @@ async function getObjectConfig(objectName, spaceId, userSession) {
|
||||
objectConfig.name = objectName
|
||||
objectConfig.datasource = object.datasource.name;
|
||||
objectConfig.permissions = await object.getUserObjectPermission(userSession);
|
||||
objectConfig.details = await object.getDetailsInfo();
|
||||
objectConfig.masters = await object.getMastersInfo();
|
||||
objectConfig.lookup_details = await object.getLookupDetailsInfo();
|
||||
const relationsInfo = await object.getRelationsInfo();
|
||||
objectConfig.details = relationsInfo.details;
|
||||
objectConfig.masters = relationsInfo.masters;
|
||||
objectConfig.lookup_details = relationsInfo.lookup_details;
|
||||
return objectConfig;
|
||||
} catch (error) {
|
||||
console.warn('not load object', objectName)
|
||||
@ -381,64 +393,77 @@ export async function getSpaceObjectBootStrap(req, res) {
|
||||
let userSession = req.user;
|
||||
let userId = userSession.userId;
|
||||
let urlParams = req.params;
|
||||
const objectName = urlParams.objectName
|
||||
let spaceId = req.headers['x-space-id'] || urlParams.spaceId
|
||||
if (!userSession) {
|
||||
return res.status(500).send();
|
||||
}
|
||||
let _object = Creator.getCollection('objects').findOne({ name: objectName }) || {}
|
||||
let lng = _getLocale(db.users.findOne(userId, { fields: { locale: 1 } }))
|
||||
let objectConfig: any = {}
|
||||
if (_.isEmpty(_object)) {
|
||||
objectConfig = Creator.getAllPermissions(spaceId, userId).objects[objectName];
|
||||
if (_.isEmpty(objectConfig)) {
|
||||
objectConfig = await getObjectConfig(objectName, spaceId, userSession);
|
||||
}else{
|
||||
const object = getObject(objectName);
|
||||
objectConfig.details = await object.getDetailsInfo();
|
||||
objectConfig.masters = await object.getMastersInfo();
|
||||
objectConfig.lookup_details = await object.getLookupDetailsInfo();
|
||||
}
|
||||
} else {
|
||||
if (userSession.is_space_admin || _object.in_development == '0' && _object.is_enable) {
|
||||
if (_object.datasource == 'meteor') {
|
||||
objectConfig = Creator.getAllPermissions(spaceId, userId).objects[objectName]
|
||||
const object = getObject(objectName);
|
||||
objectConfig.details = await object.getDetailsInfo();
|
||||
objectConfig.masters = await object.getMastersInfo();
|
||||
objectConfig.lookup_details = await object.getLookupDetailsInfo();
|
||||
const objectNames = urlParams.objectNames
|
||||
const objects = {};
|
||||
if (objectNames) {
|
||||
const objectNamesArray = objectNames.split(',');
|
||||
let dbObjects = Creator.getCollection('objects').find({ name: { $in: objectNamesArray } }).fetch() || []
|
||||
let creatorObjects = Creator.getAllPermissions(spaceId, userId).objects;
|
||||
let lng = _getLocale(db.users.findOne(userId, { fields: { locale: 1 } }))
|
||||
for (const objectName of objectNamesArray) {
|
||||
let _object = _.find(dbObjects, function (item) { return item.name === objectName }) || {}
|
||||
let objectConfig: any = {}
|
||||
if (_.isEmpty(_object)) {
|
||||
objectConfig = creatorObjects[objectName];
|
||||
if (_.isEmpty(objectConfig)) {
|
||||
objectConfig = await getObjectConfig(objectName, spaceId, userSession);
|
||||
} else {
|
||||
const object = getObject(objectName);
|
||||
const relationsInfo = await object.getRelationsInfo();
|
||||
objectConfig.details = relationsInfo.details;
|
||||
objectConfig.masters = relationsInfo.masters;
|
||||
objectConfig.lookup_details = relationsInfo.lookup_details;
|
||||
}
|
||||
} else {
|
||||
objectConfig = await getObjectConfig(objectName, spaceId, userSession);
|
||||
if (userSession.is_space_admin || _object.in_development == '0' && _object.is_enable) {
|
||||
if (_object.datasource == 'meteor') {
|
||||
objectConfig = creatorObjects[objectName]
|
||||
const object = getObject(objectName);
|
||||
const relationsInfo = await object.getRelationsInfo();
|
||||
objectConfig.details = relationsInfo.details;
|
||||
objectConfig.masters = relationsInfo.masters;
|
||||
objectConfig.lookup_details = relationsInfo.lookup_details;
|
||||
} else {
|
||||
objectConfig = await getObjectConfig(objectName, spaceId, userSession);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (objectConfig) {
|
||||
delete objectConfig.db
|
||||
// objectConfig.list_views = await getUserObjectListViews(userId, spaceId, objectName)
|
||||
steedosI18n.translationObject(lng, objectConfig.name, objectConfig)
|
||||
|
||||
objectConfig = await getUserObject(userId, spaceId, objectConfig)
|
||||
|
||||
// TODO object layout 是否需要控制审批记录显示?
|
||||
let spaceProcessDefinition = await getObject("process_definition").directFind({ filters: [['space', '=', spaceId], ['object_name', '=', objectName], ['active', '=', true]] })
|
||||
if (spaceProcessDefinition.length > 0) {
|
||||
objectConfig.enable_process = true
|
||||
}
|
||||
|
||||
_.each(objectConfig.triggers, function (trigger, key) {
|
||||
if (trigger?.on != 'client') {
|
||||
delete objectConfig.triggers[key];
|
||||
}
|
||||
})
|
||||
|
||||
delete objectConfig.listeners
|
||||
delete objectConfig.__filename
|
||||
delete objectConfig.extend
|
||||
objects[objectConfig.name] = objectConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (objectConfig) {
|
||||
delete objectConfig.db
|
||||
// objectConfig.list_views = await getUserObjectListViews(userId, spaceId, objectName)
|
||||
steedosI18n.translationObject(lng, objectConfig.name, objectConfig)
|
||||
|
||||
objectConfig = await getUserObject(userId, spaceId, objectConfig)
|
||||
|
||||
// TODO object layout 是否需要控制审批记录显示?
|
||||
let spaceProcessDefinition = await getObject("process_definition").directFind({ filters: [['space', '=', spaceId], ['object_name', '=', objectName], ['active', '=', true]] })
|
||||
if (spaceProcessDefinition.length > 0) {
|
||||
objectConfig.enable_process = true
|
||||
}
|
||||
|
||||
_.each(objectConfig.triggers, function(trigger, key){
|
||||
if(trigger?.on != 'client'){
|
||||
delete objectConfig.triggers[key];
|
||||
}
|
||||
})
|
||||
|
||||
delete objectConfig.listeners
|
||||
delete objectConfig.__filename
|
||||
delete objectConfig.extend
|
||||
}
|
||||
return res.status(200).send(objectConfig || {});
|
||||
return res.status(200).send({
|
||||
objects: objects
|
||||
});
|
||||
}).run();
|
||||
}
|
||||
|
||||
bootStrapExpress.use('/api/bootstrap/:spaceId/:objectName', requireAuthentication, getSpaceObjectBootStrap)
|
||||
bootStrapExpress.use('/api/bootstrap/:spaceId/:objectNames', requireAuthentication, getSpaceObjectBootStrap)
|
||||
bootStrapExpress.use('/api/bootstrap/:spaceId/', requireAuthentication, getSpaceBootStrap)
|
||||
|
||||
|
@ -148,8 +148,8 @@ function getObjectServiceMethodsSchema() {
|
||||
}
|
||||
},
|
||||
getRecordView: {
|
||||
async handler(userSession) {
|
||||
return await this.object.getRecordView(userSession);
|
||||
async handler(userSession, context?) {
|
||||
return await this.object.getRecordView(userSession, context);
|
||||
}
|
||||
},
|
||||
createDefaulRecordView: {
|
||||
@ -472,7 +472,8 @@ function getObjectServiceActionsSchema() {
|
||||
},
|
||||
async handler(ctx) {
|
||||
const userSession = ctx.meta.user;
|
||||
return await this.getRecordView(userSession);
|
||||
const { context } = ctx.params;
|
||||
return await this.getRecordView(userSession, context);
|
||||
}
|
||||
},
|
||||
createDefaulRecordView: {
|
||||
|
@ -159,6 +159,10 @@ class ObjectServiceDispatcher {
|
||||
return await this.callMetadataObjectServiceAction(`getLookupDetailsInfo`, {objectApiName: this.objectApiName});
|
||||
}
|
||||
|
||||
async getRelationsInfo() {
|
||||
return await this.callMetadataObjectServiceAction(`getRelationsInfo`, { objectApiName: this.objectApiName });
|
||||
}
|
||||
|
||||
async getDetailPaths(){
|
||||
return await this.callMetadataObjectServiceAction(`getDetailPaths`, {objectApiName: this.objectApiName});
|
||||
}
|
||||
@ -179,8 +183,8 @@ class ObjectServiceDispatcher {
|
||||
return await this.callAction(`getRecordPermissions`, {record, userSession});
|
||||
}
|
||||
|
||||
async getRecordView(userSession){
|
||||
return await this.callAction(`getRecordView`, {userSession});
|
||||
async getRecordView(userSession, context?) {
|
||||
return await this.callAction(`getRecordView`, { userSession, context });
|
||||
}
|
||||
|
||||
async createDefaulRecordView(userSession){
|
||||
|
@ -23,4 +23,20 @@ export class FieldPermission {
|
||||
})
|
||||
return result;
|
||||
}
|
||||
|
||||
static async getObjectsFieldsPermissionGroupRole() {
|
||||
const permissions = await this.getObjectFieldsPermission('*', '*');
|
||||
const result = {};
|
||||
_.each(permissions, (permission) => {
|
||||
if (!result[permission.object_name]) {
|
||||
result[permission.object_name] = {};
|
||||
}
|
||||
const { permission_set_id, field, editable, readable } = permission.metadata;
|
||||
if (!result[permission.object_name][permission_set_id]) {
|
||||
result[permission.object_name][permission_set_id] = [];
|
||||
}
|
||||
result[permission.object_name][permission_set_id].push({ field: field, read: readable, edit: editable })
|
||||
})
|
||||
return result;
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ export * from "./dashboard";
|
||||
export * from "./object";
|
||||
export * from "./connection";
|
||||
export * from "./object_layouts";
|
||||
export * from "./field_permission";
|
||||
export { SteedosFieldType, SteedosFieldTypeConfig } from "./field";
|
||||
export { SteedosListenerConfig } from './listeners'
|
||||
export { SteedosTriggerType } from './trigger'
|
||||
|
@ -609,7 +609,7 @@ export class SteedosObjectType extends SteedosObjectProperties {
|
||||
return globalPermission
|
||||
}
|
||||
|
||||
async getUserObjectPermission(userSession: SteedosUserSession) {
|
||||
async getUserObjectPermission(userSession: SteedosUserSession, rolesFieldsPermission?: any) {
|
||||
|
||||
if (!userSession) {
|
||||
throw new Error('userSession is required')
|
||||
@ -649,7 +649,9 @@ export class SteedosObjectType extends SteedosObjectProperties {
|
||||
throw new Error('not find user permission');
|
||||
}
|
||||
|
||||
const rolesFieldsPermission = await FieldPermission.getObjectFieldsPermissionGroupRole(this.name);
|
||||
if (!rolesFieldsPermission) {
|
||||
rolesFieldsPermission = await FieldPermission.getObjectFieldsPermissionGroupRole(this.name);
|
||||
}
|
||||
|
||||
roles.forEach((role) => {
|
||||
let rolePermission = objectRolesPermission[role];
|
||||
@ -926,6 +928,13 @@ export class SteedosObjectType extends SteedosObjectProperties {
|
||||
return await this.callMetadataObjectServiceAction(`getLookupDetailsInfo`, {objectApiName: this.name});
|
||||
}
|
||||
|
||||
/**
|
||||
* 此函数返回getDetailsInfo、getMastersInfo、getLookupDetailsInfo 3个请求的结果,用于优化访问速度
|
||||
*/
|
||||
async getRelationsInfo() {
|
||||
return await this.callMetadataObjectServiceAction(`getRelationsInfo`, { objectApiName: this.name });
|
||||
}
|
||||
|
||||
async getRecordPermissions(record, userSession){
|
||||
const permissions = await this.getUserObjectPermission(userSession);
|
||||
const { userId, company_ids: user_company_ids } = userSession;
|
||||
@ -985,22 +994,39 @@ export class SteedosObjectType extends SteedosObjectProperties {
|
||||
return permissions
|
||||
}
|
||||
|
||||
async getRecordView(userSession){
|
||||
async getRecordView(userSession, context?: any) {
|
||||
let objectConfig;
|
||||
let layouts;
|
||||
let spaceProcessDefinition;
|
||||
let dbListViews;
|
||||
let rolesFieldsPermission;
|
||||
|
||||
if (context) {
|
||||
objectConfig = context.objectConfig;
|
||||
layouts = context.layouts;
|
||||
spaceProcessDefinition = context.spaceProcessDefinition;
|
||||
dbListViews = context.dbListViews;
|
||||
rolesFieldsPermission = context.rolesFieldsPermission;
|
||||
}
|
||||
|
||||
const lng = userSession.language;
|
||||
const objectMetadataConfig: any = await this.callMetadataObjectServiceAction('get', {objectApiName: this.name});
|
||||
let objectConfig = objectMetadataConfig.metadata;
|
||||
if (!objectConfig) {
|
||||
const objectMetadataConfig: any = await this.callMetadataObjectServiceAction('get', { objectApiName: this.name });
|
||||
objectConfig = objectMetadataConfig.metadata;
|
||||
}
|
||||
objectConfig.name = this.name
|
||||
objectConfig.datasource = this.datasource.name;
|
||||
objectConfig.permissions = await this.getUserObjectPermission(userSession);
|
||||
objectConfig.details = await this.getDetailsInfo();
|
||||
objectConfig.masters = await this.getMastersInfo();
|
||||
objectConfig.lookup_details = await this.getLookupDetailsInfo();
|
||||
|
||||
objectConfig.permissions = await this.getUserObjectPermission(userSession, rolesFieldsPermission);
|
||||
const relationsInfo = await this.getRelationsInfo();
|
||||
objectConfig.details = relationsInfo.details;
|
||||
objectConfig.masters = relationsInfo.masters;
|
||||
objectConfig.lookup_details = relationsInfo.lookup_details;
|
||||
delete objectConfig.db
|
||||
|
||||
translationObject(lng, objectConfig.name, objectConfig, true);
|
||||
|
||||
const layouts = await getObjectLayouts(userSession.profile, userSession.spaceId, this.name);
|
||||
if (!layouts) {
|
||||
layouts = await getObjectLayouts(userSession.profile, userSession.spaceId, this.name);
|
||||
}
|
||||
if(layouts && layouts.length > 0){
|
||||
const layout = layouts[0];
|
||||
let _fields = {};
|
||||
@ -1101,7 +1127,9 @@ export class SteedosObjectType extends SteedosObjectProperties {
|
||||
objectConfig.fields = userObjectFields
|
||||
|
||||
// TODO object layout 是否需要控制审批记录显示?
|
||||
let spaceProcessDefinition = await getObject("process_definition").directFind({ filters: [['space', '=', userSession.spaceId], ['object_name', '=', this.name], ['active', '=', true]] })
|
||||
if (!spaceProcessDefinition) {
|
||||
spaceProcessDefinition = await getObject("process_definition").directFind({ filters: [['space', '=', userSession.spaceId], ['object_name', '=', this.name], ['active', '=', true]] })
|
||||
}
|
||||
if (spaceProcessDefinition.length > 0) {
|
||||
objectConfig.enable_process = true
|
||||
}
|
||||
@ -1113,8 +1141,9 @@ export class SteedosObjectType extends SteedosObjectProperties {
|
||||
delete objectConfig.triggers[key];
|
||||
}
|
||||
})
|
||||
|
||||
const dbListViews = await getObject("object_listviews").find({ filters: [['space', '=', userSession.spaceId], ['object_name', '=', this.name], [['owner', '=', userSession.userId], 'or', ['shared', '=', true]]] })
|
||||
if (!dbListViews) {
|
||||
dbListViews = await getObject("object_listviews").directFind({ filters: [['space', '=', userSession.spaceId], ['object_name', '=', this.name], [['owner', '=', userSession.userId], 'or', ['shared', '=', true]]] })
|
||||
}
|
||||
objectConfig.list_views = Object.assign({}, objectConfig.list_views)
|
||||
_.each(dbListViews, function(dbListView){
|
||||
delete dbListView.created;
|
||||
|
@ -83,6 +83,12 @@ export class LookupActionHandler {
|
||||
})
|
||||
return _.uniq(detailName);
|
||||
}
|
||||
|
||||
getDetailsInfoKey(objectApiName: string) {
|
||||
return this.getDetailKey(objectApiName, "*");
|
||||
}
|
||||
|
||||
|
||||
async getDetailsInfo(objectApiName: string){
|
||||
const detailsInfo = [];
|
||||
let records = (await this.broker.call('metadata.filter', { key: this.getDetailKey(objectApiName, "*") }, { meta: {} })) || {};
|
||||
|
@ -215,6 +215,9 @@ export class MasterDetailActionHandler{
|
||||
return _.uniq(mastersName);
|
||||
}
|
||||
|
||||
getMastersInfoKey(objectApiName: string) {
|
||||
return this.getMasterKey(objectApiName, "*");
|
||||
}
|
||||
async getMastersInfo(objectApiName: string){
|
||||
const mastersInfo = [];
|
||||
let records = (await this.broker.call('metadata.filter', { key: this.getMasterKey(objectApiName, "*") }, { meta: {} })) || {};
|
||||
@ -257,6 +260,10 @@ export class MasterDetailActionHandler{
|
||||
return _.uniq(detailsName);
|
||||
}
|
||||
|
||||
getDetailsInfoKey(objectApiName: string) {
|
||||
return this.getDetailKey(objectApiName, "*", "*");
|
||||
}
|
||||
|
||||
async getDetailsInfo(objectApiName: string){
|
||||
const detailsInfo = [];
|
||||
let records = (await this.broker.call('metadata.filter', { key: this.getDetailKey(objectApiName, "*", "*") }, { meta: {} })) || {};
|
||||
|
@ -168,6 +168,21 @@ module.exports = {
|
||||
return await this.lookupActionHandler.getDetailsInfo(objectApiName);
|
||||
}
|
||||
},
|
||||
getRelationsInfo: {
|
||||
async handler(ctx) {
|
||||
const { objectApiName } = ctx.params;
|
||||
const detailsInfoKey = this.masterDetailActionHandler.getDetailsInfoKey(objectApiName);
|
||||
const mastersInfo = this.masterDetailActionHandler.getMastersInfoKey(objectApiName);
|
||||
const lookupDetailsInfo = this.lookupActionHandler.getDetailsInfoKey(objectApiName);
|
||||
|
||||
const results = await ctx.broker.call('metadata.mget', { keys: [detailsInfoKey, mastersInfo, lookupDetailsInfo] });
|
||||
return {
|
||||
details: results[0],
|
||||
masters: results[1],
|
||||
lookup_details: results[2],
|
||||
}
|
||||
}
|
||||
},
|
||||
getMasterPaths: {
|
||||
async handler(ctx) {
|
||||
const { objectApiName } = ctx.params;
|
||||
|
@ -6,6 +6,33 @@ import * as _ from 'underscore';
|
||||
|
||||
let savePackageServicesTimeoutID = null;
|
||||
|
||||
const useScan = false;
|
||||
|
||||
async function redisScanKeys(redisClient, match, count = 100): Promise<Array<string>> {
|
||||
if (!useScan) {
|
||||
return await redisClient.keys(match);
|
||||
} else {
|
||||
return await new Promise((resolve, reject) => {
|
||||
var stream = redisClient.scanStream({
|
||||
// only returns keys following the pattern of `user:*`
|
||||
match: match,
|
||||
// returns approximately 100 elements per call
|
||||
count: count
|
||||
});
|
||||
|
||||
var keys = [];
|
||||
stream.on('data', function (resultKeys) {
|
||||
for (var i = 0; i < resultKeys.length; i++) {
|
||||
keys.push(resultKeys[i]);
|
||||
}
|
||||
});
|
||||
stream.on('end', function () {
|
||||
resolve(keys)
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
//////////////// mock for redis cacher ////////////////
|
||||
// let mockCacherData: string[] = [];
|
||||
// let mock_prefix = "";
|
||||
@ -134,17 +161,33 @@ async function addServiceMetadata(ctx) {
|
||||
// });
|
||||
}
|
||||
|
||||
async function mget(ctx, keys) {
|
||||
if (!keys || keys.length == 0) {
|
||||
return [];
|
||||
}
|
||||
const values = await ctx.broker.cacher.client.mget(...keys);
|
||||
const results = [];
|
||||
_.map(values, (item) => {
|
||||
try {
|
||||
if (item) {
|
||||
results.push(JSON.parse(item));
|
||||
} else {
|
||||
results.push(item);
|
||||
}
|
||||
} catch (error) {
|
||||
results.push(item);
|
||||
}
|
||||
})
|
||||
return results;
|
||||
}
|
||||
|
||||
// 这里需要更改
|
||||
async function query(ctx, queryKey) {
|
||||
try {
|
||||
const keyPrefix = ctx.broker.cacher?.prefix || "";
|
||||
const keys = await ctx.broker.cacher.client.keys(`${keyPrefix}${queryKey}`); //TODO 此功能仅支持redis cache
|
||||
const keys = await redisScanKeys(ctx.broker.cacher.client, `${keyPrefix}${queryKey}`) //ctx.broker.cacher.client.keys(`${keyPrefix}${queryKey}`); //TODO 此功能仅支持redis cache
|
||||
// REPLACE: const keys = await mockCacherKeys(ctx, `${keyPrefix}${queryKey}`) //TODO 此功能仅支持redis cache
|
||||
const values = [];
|
||||
for (const key of keys) {
|
||||
values.push(await ctx.broker.cacher.get(getKey(key, keyPrefix)));
|
||||
// REPLACE: values.push(await mockCacherGet(ctx, getKey(key, keyPrefix)));
|
||||
}
|
||||
const values = _.compact(await mget(ctx, keys));
|
||||
return values;
|
||||
} catch (error) {
|
||||
// console.error(`error`, error)
|
||||
@ -243,7 +286,7 @@ async function clearPackageServicesMetadatas(ctx, offlinePackageServices) {
|
||||
async function getMetadataServices(broker) {
|
||||
const queryKey = `${METADATA_SERVICES_PERFIX}.*`;
|
||||
const keyPrefix = broker.cacher?.prefix || "";
|
||||
const keys = await broker.cacher.client.keys(`${keyPrefix}${queryKey}`); //TODO 此功能仅支持redis cache
|
||||
const keys = await redisScanKeys(broker.cacher.client, `${keyPrefix}${queryKey}`) // broker.cacher.client.keys(`${keyPrefix}${queryKey}`); //TODO 此功能仅支持redis cache
|
||||
// REPLACE: const keys = await mockCacherKeys({broker,}, `${keyPrefix}${queryKey}`) //TODO 此功能仅支持redis cache
|
||||
const values = [];
|
||||
for (const key of keys) {
|
||||
@ -280,6 +323,14 @@ export const ActionHandlers = {
|
||||
}
|
||||
// REPLACE: return await mockCacherGet(ctx, ctx.params.key)
|
||||
},
|
||||
async mget(ctx: any): Promise<any> {
|
||||
try {
|
||||
return await mget(ctx, ctx.params.keys);
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
// REPLACE: return await mockCacherGet(ctx, ctx.params.key)
|
||||
},
|
||||
async filter(ctx: any): Promise<Array<any>> {
|
||||
return await query(ctx, ctx.params.key);
|
||||
// const keyPrefix = ctx.broker.cacher.prefix
|
||||
@ -300,7 +351,7 @@ export const ActionHandlers = {
|
||||
async fuzzyDelete(ctx: any){
|
||||
const { key } = ctx.params
|
||||
const keyPrefix = ctx.broker.cacher?.prefix || "";
|
||||
const keys = await ctx.broker.cacher.client.keys(`${keyPrefix}${key}`);
|
||||
const keys = await redisScanKeys(ctx.broker.cacher.client, `${keyPrefix}${key}`) // await ctx.broker.cacher.client.keys(`${keyPrefix}${key}`);
|
||||
for (const _key of keys) {
|
||||
await ctx.broker.cacher.del(getKey(_key, keyPrefix));
|
||||
}
|
||||
|
@ -48,6 +48,11 @@ module.exports = {
|
||||
return await ActionHandlers.get(ctx);
|
||||
}
|
||||
},
|
||||
mget: {
|
||||
async handler(ctx) {
|
||||
return await ActionHandlers.mget(ctx);
|
||||
}
|
||||
},
|
||||
filter: {
|
||||
async handler(ctx) {
|
||||
return await ActionHandlers.filter(ctx);
|
||||
|
Loading…
Reference in New Issue
Block a user