import{EntityFactory, ERelationType, EntityPKey, RelaenManager, UnknownClass} from 'relaen'; import { AmUtil } from './util'; /** * 模型生成器 */ export class AMModelGenerator{ /** * 实体路径 */ private entityPath:string; /** * 存储路径 */ private savePath:string; constructor(entityPath,savePath){ savePath = require('path').resolve(savePath); const fsMdl = require('fs'); if(!fsMdl.existsSync(savePath)){ fsMdl.mkdirSync(savePath,{recursive:true}); } this.savePath = savePath; this.entityPath = entityPath; } /** * 创建 * @param entityPath 实体路径 * @param savePath model存储路径 */ public async genModel(){ await RelaenManager.init({ "dialect": "mysql", "host": "localhost", "port": 3306, "username": "root", "password": "field", "database": "aeromanage", //1、是否开启连接池 "pool": { "min": 1, "max": 10 }, //2、连接超时 "connectTimeout": 1000, //3、连接池空闲超时 "idleTimeout": 10000, "entities": [this.entityPath], //4、是否开启缓存 "cache": true, //5、是否开启调试模式 "debug": false, //6、是否开启文件日志 "fileLog": false, //7、是否开启全表更新删除 "fullTableOperation": true, }); // model 目标目录 const BASEDIR = this.savePath; const BASEIMPORT = [ `/** * AMTool auto generate model */ `, `import {AMModel,AMProp} from "../decorator";` ]; //获取所有relaen实体 const entities = EntityFactory.getAllEntityConfig(); for(let cfg of entities){ let entity = (cfg.entity).name; const MDLNAME = 'Mdl' + entity; let imArr:string[] = []; for(let i of BASEIMPORT){ imArr.push(i); } //模型 imArr.push(` @AMModel({ ref:'${entity}', showName:'${entity}', manageable:true, editable:true, isData:false }) export class ${MDLNAME} { `); let pkey:EntityPKey=cfg.getId(); let findName:boolean = false; for(let col of cfg.columns){ // prop配置属性数组 let parr = [ `showName:'${col[0]}'`, 'showInGrid:true', 'showInDetail:true', ]; //主键 if(col[0] === pkey.name){ parr.push('isId:true'); if(!col[1].type){ //无类型,表示外键即主键 parr.push('editable:true'); }else{ parr.push('editable:false'); } }else{ parr.push('editable:true'); } //无类型则为ref parr.push(`type:'${col[1].type || 'ref'}'`); //类型 if(col[1].type){ //设置默认显示名字项 if(!findName && col[0] !== pkey.name){ parr.push('showInRef:true') findName = true; } } let editStr=''; let validArr:string[] = []; //不能为空 if(!col[1].nullable){ validArr.push(`'require'`); } // 类型:text int double date ref let type = col[1].type?AmUtil.getTsType(col[1].type):null; if(type === 'string'){ //长度>500,则设置为textarea if(col[1].length && col[1].length>500){ editStr = `editOption:{type:'textarea'}`; }else{ editStr = `editOption:{type:'text'}`; } validArr.push(`'maxLength:${col[1].length}'`); }else if(type==='number'){ editStr = `editOption:{type:'number'}`; }else if(type==='date'){ editStr = `editOption:{type:'date'}`; }else{ //外键关系 let rel = cfg.getRelation(col[0]); if(rel){ //不处理被引用属性 if(rel.mappedBy){ continue; } //添加ref parr.push('ref:"Mdl' + rel.entity + '"'); let relEn = EntityFactory.getEntityConfig(rel.entity); let relColumns = relEn.columns; let relPkey = relEn.getId().name; let dispProp = ''; //找到第一个非pkey且不是外键的字段名 for(let c of relColumns){ if(c[0] !== relPkey && !relEn.hasRelation(c[0])){ dispProp = c[0]; break; } } if(rel.entity === 'AmFile'){ //文件类型 editStr = `editOption:{type:'file'}`; }else{ editStr = `editOption:{ type:'select', option:{ multi:${rel.type===ERelationType.ManyToMany?true:false}, refModel:'Mdl${rel.entity}', valueProp:'${relPkey}', displayProp:'${dispProp}' } }`; } } } //编辑项 if(editStr){ parr.push(editStr); } // validator 串 if(validArr.length>0){ parr.push(`validator:[${validArr.join(',')}]`); } imArr.push(` @AMProp({ ${parr.join(',')} }) `) // 属性定义 imArr.push(`\r\npublic ${col[0]};\r\n`); } imArr.push(`}`); //写model文件 let path = require('path').resolve(BASEDIR, MDLNAME.toLowerCase() + '.ts'); let str = imArr.join(''); //美化文件 str = AmUtil.formatTs(str); //写文件 require('fs').writeFileSync(path, str); } } }