feat: 支持迭代器容器
This commit is contained in:
@@ -21,10 +21,16 @@ import EventEmitter from 'events';
|
||||
import { cloneDeep, template } from 'lodash-es';
|
||||
|
||||
import type { AppCore, DataSourceSchema, Id, MNode } from '@tmagic/schema';
|
||||
import { compiledCond, compiledNode, DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX, isObject } from '@tmagic/utils';
|
||||
import {
|
||||
compiledNode,
|
||||
DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX,
|
||||
DSL_NODE_KEY_COPY_PREFIX,
|
||||
getValueByKeyPath,
|
||||
} from '@tmagic/utils';
|
||||
|
||||
import { DataSource, HttpDataSource } from './data-sources';
|
||||
import type { ChangeEvent, DataSourceManagerData, DataSourceManagerOptions } from './types';
|
||||
import { compliedConditions, createIteratorContentData } from './utils';
|
||||
|
||||
class DataSourceManager extends EventEmitter {
|
||||
private static dataSourceClassMap = new Map<string, typeof DataSource>();
|
||||
@@ -189,15 +195,7 @@ class DataSourceManager extends EventEmitter {
|
||||
|
||||
if (!data) return value;
|
||||
|
||||
return fields.reduce((accumulator, currentValue: any) => {
|
||||
if (Array.isArray(accumulator)) return accumulator;
|
||||
|
||||
if (isObject(accumulator)) {
|
||||
return accumulator[currentValue];
|
||||
}
|
||||
|
||||
return '';
|
||||
}, data);
|
||||
return getValueByKeyPath(fields.join('.'), data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,34 +208,39 @@ class DataSourceManager extends EventEmitter {
|
||||
}
|
||||
|
||||
public compliedConds(node: MNode) {
|
||||
if (!node.displayConds || !Array.isArray(node.displayConds) || !node.displayConds.length) return true;
|
||||
return compliedConditions(node, this.data);
|
||||
}
|
||||
|
||||
for (const { cond } of node.displayConds) {
|
||||
if (!cond) continue;
|
||||
public compliedIteratorItems(itemData: any, items: MNode[], dataSourceField: string[] = []) {
|
||||
return items.map((item) => {
|
||||
const keys: string[] = [];
|
||||
const [dsId, ...fields] = dataSourceField;
|
||||
|
||||
let result = true;
|
||||
for (const { op, value, range, field } of cond) {
|
||||
const [sourceId, fieldKey] = field;
|
||||
|
||||
const dsData = this.data[sourceId];
|
||||
|
||||
if (!dsData || !fieldKey) {
|
||||
break;
|
||||
Object.entries(item).forEach(([key, value]) => {
|
||||
if (
|
||||
typeof value === 'string' &&
|
||||
!key.startsWith(DSL_NODE_KEY_COPY_PREFIX) &&
|
||||
value.includes(`${dsId}`) &&
|
||||
/\$\{([\s\S]+?)\}/.test(value)
|
||||
) {
|
||||
keys.push(key);
|
||||
}
|
||||
});
|
||||
|
||||
const fieldValue = dsData[fieldKey];
|
||||
if (!compiledCond(op, fieldValue, value, range)) {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return compiledNode(
|
||||
(value: string) => template(value)(createIteratorContentData(itemData, dsId, fields)),
|
||||
cloneDeep(item),
|
||||
{
|
||||
[dsId]: {
|
||||
[item.id]: {
|
||||
name: '',
|
||||
keys,
|
||||
},
|
||||
},
|
||||
},
|
||||
dsId,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
|
||||
@@ -17,11 +17,12 @@
|
||||
*/
|
||||
import { cloneDeep, union } from 'lodash-es';
|
||||
|
||||
import type { AppCore, MApp, MNode, MPage, MPageFragment } from '@tmagic/schema';
|
||||
import { getDepNodeIds, getNodes, isPage, isPageFragment, replaceChildNode } from '@tmagic/utils';
|
||||
import type { AppCore } from '@tmagic/schema';
|
||||
import { getDepNodeIds, getNodes } from '@tmagic/utils';
|
||||
|
||||
import DataSourceManager from './DataSourceManager';
|
||||
import type { ChangeEvent, DataSourceManagerData } from './types';
|
||||
import { updateNode } from './utils';
|
||||
|
||||
/**
|
||||
* 创建数据源管理器
|
||||
@@ -73,12 +74,3 @@ export const createDataSourceManager = (app: AppCore, useMock?: boolean, initial
|
||||
|
||||
return dataSourceManager;
|
||||
};
|
||||
|
||||
const updateNode = (node: MNode, dsl: MApp) => {
|
||||
if (isPage(node) || isPageFragment(node)) {
|
||||
const index = dsl.items?.findIndex((child: MNode) => child.id === node.id);
|
||||
dsl.items.splice(index, 1, node as MPage | MPageFragment);
|
||||
} else {
|
||||
replaceChildNode(node, dsl!.items);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -19,4 +19,5 @@
|
||||
export { default as DataSourceManager } from './DataSourceManager';
|
||||
export * from './data-sources';
|
||||
export * from './createDataSourceManager';
|
||||
export * from './utils';
|
||||
export * from './types';
|
||||
|
||||
59
packages/data-source/src/utils.ts
Normal file
59
packages/data-source/src/utils.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import type { MApp, MNode, MPage, MPageFragment } from '@tmagic/schema';
|
||||
import { compiledCond, getValueByKeyPath, isPage, isPageFragment, replaceChildNode } from '@tmagic/utils';
|
||||
|
||||
import type { DataSourceManagerData } from './types';
|
||||
|
||||
export const compliedConditions = (node: MNode, data: DataSourceManagerData) => {
|
||||
if (!node.displayConds || !Array.isArray(node.displayConds) || !node.displayConds.length) return true;
|
||||
|
||||
for (const { cond } of node.displayConds) {
|
||||
if (!cond) continue;
|
||||
|
||||
let result = true;
|
||||
for (const { op, value, range, field } of cond) {
|
||||
const [sourceId, ...fields] = field;
|
||||
|
||||
const dsData = data[sourceId];
|
||||
|
||||
if (!dsData || !fields.length) {
|
||||
break;
|
||||
}
|
||||
|
||||
const fieldValue = getValueByKeyPath(fields.join('.'), data[sourceId]);
|
||||
|
||||
if (!compiledCond(op, fieldValue, value, range)) {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
export const updateNode = (node: MNode, dsl: MApp) => {
|
||||
if (isPage(node) || isPageFragment(node)) {
|
||||
const index = dsl.items?.findIndex((child: MNode) => child.id === node.id);
|
||||
dsl.items.splice(index, 1, node as MPage | MPageFragment);
|
||||
} else {
|
||||
replaceChildNode(node, dsl!.items);
|
||||
}
|
||||
};
|
||||
|
||||
export const createIteratorContentData = (itemData: any, dsId: string, fields: string[] = []) => {
|
||||
const data = {
|
||||
[dsId]: {},
|
||||
};
|
||||
|
||||
fields.reduce((obj: any, field, index) => {
|
||||
obj[field] = index === fields.length - 1 ? itemData : {};
|
||||
|
||||
return obj[field];
|
||||
}, data[dsId]);
|
||||
|
||||
return data;
|
||||
};
|
||||
Reference in New Issue
Block a user