import {customerLoaderInstance} from './loader'; import {PassCustomers} from './customers/pass'; import {SubmitCustomer} from './customers/submit'; import {LocationCustomer} from './customers/location'; import {LocalStorageCustomer} from './customers/localStorage'; import {MessageCustomer} from './customers/message'; import {Map} from 'immutable'; import {runTimeType} from '../Container/types'; import {isExpression, parseExpressionString} from '../../util/vm'; import funcCustomer from './funcCustomer'; import {BasicContainerPropsInterface} from '../..'; import {ModalCustomer} from './customers/modal'; customerLoaderInstance.registerCustomer('pass', new PassCustomers()); customerLoaderInstance.registerCustomer('submit', new SubmitCustomer()); customerLoaderInstance.registerCustomer('location', new LocationCustomer()); customerLoaderInstance.registerCustomer('localStorage', new LocalStorageCustomer()); customerLoaderInstance.registerCustomer('message', new MessageCustomer()); customerLoaderInstance.registerCustomer('modal', new ModalCustomer()); export interface CustomerItem { /** * customer名称 */ name: string; /** * customer执行模式 */ mode?: string; /** * customer配置 */ config?: any; /** * customer 函数 */ func?: string; } export interface CustomerGroup { /** * 组合名称 */ name: string; /** * 执行顺序 */ steps: string[]; } export interface CustomerSourceConfig { /** * 单个customer配置 */ customers: CustomerItem[]; /** * 业务组合 */ groups: CustomerGroup[]; } export interface BasicCustomerInstance { exec(config: any, params: CustomerParams): Promise; } /** * 判断一个对象是否是Promise * * @param object * @returns {boolean} */ function isPromise(object: any): boolean { if (Promise && Promise.resolve) { return Promise.resolve(object) === object; } return false; } /** * 把DataCustomerFunc函数变量注入到context中 * * @param {Object} context */ export function injectDataCustomerIntoContext(context: Object) { let customerName = funcCustomer.getAllCustomerName(); let next = customerName.next(); while (!next.done) { let funcName = next.value; context[funcName] = funcCustomer.getCustomer(funcName); next = customerName.next(); } } export interface CustomerParams { runTime: runTimeType; model: string; prev: any; props: BasicContainerPropsInterface; customer: string; context: Object; } /** * DataCustomer是一个数据源输出端 * 它通过注入customer插件的形式, 把各种各样的数据消耗方加载进来 * 针对特殊的业务逻辑场景, 可以使用Group来使用链式调用 */ export class DataCustomer { private customers: Map; private groups: Map; constructor() { this.customers = Map({}); this.groups = Map({}); } public initCustomerConfig(info: CustomerSourceConfig) { this.initCustomer(info); } public getGroups() { return this.groups; } public async execCustomer(params: CustomerParams) { let customer = params.customer; let customerConfig = this.customers.get(customer); let runTime = params.runTime; if (!this.customers.has(customer)) { console.error(`customer: ${customer} is not defined`); return; } if (customerConfig.instance) { let instance = customerConfig.instance; let config = customerConfig.config; // 处理$this的内置customer if (customer === '$SELF_PASS_CUSTOMER' && runTime.$trigger && runTime.$trigger.$SELF_PASS_CUSTOMER) { config.assign = runTime.$trigger.$SELF_PASS_CUSTOMER; } if (!config) { config = `#ES{$trigger.${customer}`; } return await instance.exec(config, params); } else if (customerConfig.func) { let funcStr = customerConfig.func; return await new Promise((resolve, reject) => { injectDataCustomerIntoContext(runTime); try { let func = parseExpressionString(funcStr, runTime); if (typeof func !== 'function') { console.error('提供给func的值需要是一个函数'); } let ret: Promise = func({ ...params, params: params.runTime.$trigger![customer] }); if (isPromise(ret)) { return ret.then(result => resolve(result)).catch(err => reject(err)); } return resolve(ret); } catch (err) { return reject(err); } }); } } private initCustomer(info: CustomerSourceConfig) { let customers = info.customers; let groups = info.groups; if (!(customers instanceof Array)) { console.error('customers should be array'); return; } customers.forEach(customer => { if (!customer.name) { console.error('name property is required for single customer'); return; } let mode = customer.mode; let name = customer.name; let config = customer.config; let func = customer.func; if (mode) { let instance = customerLoaderInstance.getCustomer(mode); if (!instance) { console.error('can not find customer of mode: ' + mode); return; } this.customers = this.customers.set(name, { instance: instance, config: config }); } else if (func) { if (!isExpression(func)) { console.error('func必须是一个ExpressionString调用'); } this.customers = this.customers.set(name, { func: func }); } else { console.error('DataCustomer 需要提供mode或者func属性'); return; } }); if (groups instanceof Array) { groups.forEach(group => { if (!group.name) { console.error('name property is required for group'); return; } if (!group.steps || !Array.isArray(group.steps)) { console.error('steps property is required and it\'s an array type'); return; } let name = group.name; let steps = group.steps; this.groups = this.groups.set(name, steps); }); } } }