UNPKG

@lcap/asl

Version:

NetEase Application Specific Language

392 lines (366 loc) 17 kB
import { Resolver } from '../Entity'; import { config, vertexsMap, dataTypesMap, Entity, EntityProperty, Enum, View, LEVEL_ENUM, utils, } from '../..'; import { NameGroup, filterProperty, getFirstDisplayedProperty, genUniqueQueryNameGroup, getParamFromResolver, genEnumSelectBlock, genCallComponentLogic, genCallInterface, genLoadSelectLogic, } from '.'; export function genUpdateFormTemplate( entity: Entity, nameGroup: NameGroup, selectNameGroupMap: Map<string, NameGroup>, ) { const propertyList = entity.propertyList .filter(filterProperty('inForm')); return `<u-form ref="form1"> ${propertyList.map((property) => { const label = property.label || property.name; const required = !!property.required; const rules = []; if (property.rules && property.rules.length) { property.rules.forEach((rule) => rules.push(rule)); } if (required) rules.push('required'); const rulesStr = rules.join(' | '); let formItem = ` <u-form-item label="${label}"${required ? ' required' : ''}${rulesStr.length ? ` rules="${rulesStr}"` : ''}>\n`; if (property.$relationEntity) { // 有外键关联 const relationEntity = vertexsMap.get(property.$relationEntity) as Entity; if (relationEntity) { const relationProperty = vertexsMap.get(property.$relationProperty) as EntityProperty; const displayedProperty = getFirstDisplayedProperty(relationEntity, 'inForm'); if (displayedProperty) { const lowerEntityName = utils.firstLowerCase(relationEntity.name); formItem += ` <u-select clearable placeholder="请选择${label}" :data-source="${selectNameGroupMap.get(relationEntity.id).load}" text-field="${lowerEntityName}.${displayedProperty.name}" value-field="${lowerEntityName}.${relationProperty.name}" pageable remote-paging v-model="${nameGroup.model}.${property.name}"> </u-select> `; } else return ''; } else return ''; } else if (property.typeKey === '#/basicTypes/Boolean') { formItem += `<u-checkbox v-model="${nameGroup.model}.${property.name}"></u-checkbox>`; } else if (property.typeKey === '#/basicTypes/Integer' || property.typeKey === '#/basicTypes/Long') { formItem += `<u-number-input v-model="${nameGroup.model}.${property.name}" placeholder="请输入${label}"></u-number-input>`; } else if (property.typeKey === '#/basicTypes/Decimal') { formItem += `<u-number-input v-model="${nameGroup.model}.${property.name}" :precision="0" :step="0" placeholder="请输入${label}"></u-number-input>`; } else if (property.typeKey === '#/basicTypes/Text') { formItem += `<u-textarea v-model="${nameGroup.model}.${property.name}" placeholder="请输入${label}"></u-textarea>`; } else if (property.typeKey === '#/basicTypes/Date') { formItem += `<u-date-picker clearable :date.sync="${nameGroup.model}.${property.name}" placeholder="请输入${label}"></u-date-picker>`; } else if (property.typeKey === '#/basicTypes/Time') { formItem += `<u-time-picker :time.sync="${nameGroup.model}.${property.name}" placeholder="请输入${label}"></u-time-picker>`; } else if (property.typeKey === '#/basicTypes/DateTime') { formItem += `<u-date-time-picker clearable :date.sync="${nameGroup.model}.${property.name}" placeholder="请输入${label}"></u-date-time-picker>`; } else if (dataTypesMap[property.typeKey].type === 'enum') { formItem += genEnumSelectBlock(dataTypesMap[property.typeKey] as Enum, `${nameGroup.model}.${property.name}`, '', `请选择${label}`); } else { formItem += `<u-input v-model="${nameGroup.model}.${property.name}" placeholder="请输入${label}"></u-input>`; } formItem += ` </u-form-item>\n`; return formItem; }).join('')} <u-form-item> <u-button color="primary" @click="${nameGroup.submit}()">提交修改</u-button> </u-form-item> </u-form>`; } export function genH5UpdateFormTemplate(entity: Entity, nameGroup: NameGroup, selectNameGroupMap: Map<string, NameGroup>) { const propertyList = entity.propertyList .filter(filterProperty('inForm')); return `<van-form ref="form1"> ${propertyList.map((property) => { const label = property.label || property.name; const required = !!property.required; const rules = []; if (property.rules && property.rules.length) { property.rules.forEach((rule) => rules.push(rule)); } if (required) rules.push('required'); const rulesStr = rules.join(' | '); let formItem = ` <van-field drole="other" label="${label}"${required ? ' required' : ''}${rulesStr.length ? ` rules="${rulesStr}"` : ''}>\n`; if (property.$relationEntity) { // 有外键关联 const relationEntity = vertexsMap.get(property.$relationEntity) as Entity; if (relationEntity) { const relationProperty = vertexsMap.get(property.$relationProperty) as EntityProperty; const displayedProperty = getFirstDisplayedProperty(relationEntity, 'inForm'); if (displayedProperty) { const lowerEntityName = utils.firstLowerCase(relationEntity.name); formItem += ` <template #input><van-cascader title="请选择${label}" placeholder="请选择${label}" v-model="${nameGroup.model}.${property.name}" :data-source="${selectNameGroupMap.get(relationEntity.id).load}" text-field="${lowerEntityName}.${displayedProperty.name}" value-field="${lowerEntityName}.${relationProperty.name}" pageable remote-paging></van-cascader></template> `; } else return ''; } else return ''; } else if (property.typeKey === '#/basicTypes/Boolean') { formItem += `<template #input><van-switch v-model="${nameGroup.model}.${property.name}"></van-switch></template>`; } else if (property.typeKey === '#/basicTypes/Integer' || property.typeKey === '#/basicTypes/Long') { formItem += `<template #input><van-stepper v-model="${nameGroup.model}.${property.name}" placeholder="请输入${label}"></van-stepper></template>`; } else if (property.typeKey === '#/basicTypes/Decimal') { formItem += `<template #input><van-stepper v-model="${nameGroup.model}.${property.name}" placeholder="请输入${label}"></van-stepper></template>`; } else if (property.typeKey === '#/basicTypes/Text') { formItem = formItem.replace(/other/g, ''); formItem += `<van-input v-model="${nameGroup.model}.${property.name}" placeholder="请输入${label}"></van-input>`; // @TODO } else if (property.typeKey === '#/basicTypes/Date') { formItem += `<template #input><van-calendar clearable :date.sync="${nameGroup.model}.${property.name}" placeholder="请输入${label}"></van-calendar></template>`; } else if (property.typeKey === '#/basicTypes/Time') { formItem += `<template #input><van-datetime-picker type="time" v-model="${nameGroup.model}.${property.name}" title="请输入${label}"></van-datetime-picker></template>`; } else if (property.typeKey === '#/basicTypes/DateTime') { formItem += `<template #input><van-datetime-picker type="datetime" v-model="${nameGroup.model}.${property.name}" title="请输入${label}"></van-datetime-picker></template>`; } else if (dataTypesMap[property.typeKey].type === 'enum') { formItem += '<template #input>' + genEnumSelectBlock(dataTypesMap[property.typeKey] as Enum, `${nameGroup.model}.${property.name}`, '', `请选择${label}`) + '</template>'; } else { formItem = formItem.replace(/other/g, ''); formItem += `<van-input v-model="${nameGroup.model}.${property.name}" placeholder="请输入${label}"></van-input>`; } formItem += ` </van-field>\n`; formItem = formItem.replace(/>\n<van-input|<\/van-input>/g, ''); return formItem; }).join('')} <div> <van-button round block="blockb" type="info" @click="${nameGroup.submit}()" text="提交修改"></van-button> </div> </van-form>`; } function genSubmitLogic(resolver: Resolver, nameGroup: NameGroup) { const bodyParam = getParamFromResolver(resolver, 'body'); return { level: 'logic', name: nameGroup.submit, params: [] as any, returns: [] as any, variables: [ { level: 'variable', type: 'Identifier', name: 'validateResult', description: '', schema: { $ref: '#/systemTypes/ValidateEvent', }, isLeaf: true, }, ], body: [ { level: 'logicNode', type: 'Start', label: '开始', }, { level: 'logicNode', type: 'AssignmentExpression', label: '赋值', operator: '=', left: { level: 'expressionNode', type: 'Identifier', name: 'validateResult', }, right: genCallComponentLogic('form1', 'validate'), }, { level: 'logicNode', type: 'IfStatement', label: '条件分支', test: { level: 'expressionNode', type: 'MemberExpression', name: 'name', hide: false, object: { level: 'expressionNode', type: 'Identifier', name: 'validateResult', }, property: { level: 'expressionNode', type: 'Identifier', name: 'valid', }, }, consequent: [ genCallInterface(resolver.interface, [ { parentAttr: 'params', level: LEVEL_ENUM.param, type: 'CallInterParam', name: '', callInterParam: `#/${bodyParam.id}`, callInterParamValue: { parentAttr: 'callInterParamValue', level: 'expressionNode', type: 'Identifier', name: nameGroup.model, }, }, ]), { level: 'logicNode', parentAttr: 'consequent', label: '弹出消息', folded: false, type: 'CallMessageShow', arguments: [ { level: 'expressionNode', parentAttr: 'arguments', label: '原子项', folded: false, type: 'StringLiteral', value: '修改成功!', }, ], }, ], alternate: [] as any, }, { level: 'logicNode', type: 'End', label: '结束', }, ], }; } function genLoadLogic(resolver: Resolver, nameGroup: NameGroup) { const getResolver = resolver.entity.resolvers.find((item) => item.name === 'get'); const idParam = getParamFromResolver(getResolver, 'id'); return { level: 'logic', expanded: false, name: nameGroup.load, description: '', params: [] as any, returns: [] as any, body: [ { level: 'logicNode', type: 'Start', label: '开始', }, { level: 'logicNode', type: 'AssignmentExpression', label: '赋值', operator: '=', left: { level: 'expressionNode', type: 'Identifier', name: nameGroup.model, }, right: genCallInterface(getResolver.interface, [ { parentAttr: 'params', level: LEVEL_ENUM.param, type: 'CallInterParam', name: '', callInterParam: `#/${idParam.id}`, callInterParamValue: { parentAttr: 'callInterParamValue', level: 'expressionNode', type: 'Identifier', name: 'id', }, }, ]), }, { level: 'logicNode', type: 'End', label: '结束', }, ], playground: [] as any, serviceType: 'web', }; } export function genUpdateBlock(entity: Entity, view: View) { const resolver = entity.resolvers.find((item) => item.name.startsWith('update')); const modelSchema = { $ref: entity.schemaRef, }; const existingNameSets = { viewLogic: new Set(view.$def.logics.map((logic) => logic.name)), interface: new Set(entity.dataNode.service.interfaces.map((itface) => itface.name)), structure: new Set(entity.dataNode.structures.map((structure) => structure.name)), }; const nameGroup: NameGroup = { model: utils.firstLowerCase(entity.name), }; nameGroup.load = utils.unique('load', existingNameSets.viewLogic); nameGroup.submit = utils.unique('submit', existingNameSets.viewLogic); // 收集所有和本实体关联的实体 const allEntities = [entity]; entity.propertyList.forEach((property) => { if (property.$relationEntity) { // 有外键关联 const relationEntity = vertexsMap.get(property.$relationEntity) as Entity; if (relationEntity) { const displayedProperty = getFirstDisplayedProperty(relationEntity); if (displayedProperty) allEntities.push(relationEntity); } } }); const newStructures: Array<any> = []; const newInterfaces: Array<any> = []; const selectNameGroupMap: Map<string, NameGroup> = new Map(); const loadSelectLogics = allEntities.slice(1).map((entity) => { const selectNameGroup = genUniqueQueryNameGroup(existingNameSets, view.name, 'select', false, entity.name); selectNameGroupMap.set(entity.id, selectNameGroup); return genLoadSelectLogic(entity, selectNameGroup, newStructures, newInterfaces); }); return `<template> ${config.scope === 'h5' ? genH5UpdateFormTemplate(entity, nameGroup, selectNameGroupMap) : genUpdateFormTemplate(entity, nameGroup, selectNameGroupMap)} </template> <definition> { "params": [ { "level": "param", "type": "Identifier", "name": "id", "description": "", "schema": { "type": "integer", "format": "long", "isLeaf": true }, "isLeaf": true } ], "variables": [{ "level": "variable", "type": "Identifier", "name": "${nameGroup.model}", "schema": ${JSON.stringify(modelSchema)} }], "lifecycles": [ { "level": "lifecycle", "name": "created", "logicId": "${nameGroup.load}" } ], "logics": [ ${JSON.stringify(genLoadLogic(resolver, nameGroup))}, ${JSON.stringify(genSubmitLogic(resolver, nameGroup))} ${loadSelectLogics.map((logic) => ',' + JSON.stringify(logic)).join('\n')} ], "interfaces": ${JSON.stringify(newInterfaces)}, "structures": ${JSON.stringify(newStructures)} } </definition> `; } export default genUpdateBlock;