import { HttpRequest,getConnection,closeConnection } from "noomi"; import { EntityFactory, EntityConfig, EntityManager, getEntityManager, Query, BaseEntity, ERelationType} from "relaen"; import { AmModel } from "../../dao/entity/base/ammodel"; import { AmUser } from "../../dao/entity/base/amuser"; import { Util } from "./util"; export class __BaseService{ /** * 特殊字段集合 * 针对用户和时间进行处理 * {amUser:{useLogonUser:true},createTime:{userSystemTime:true},pwd:{defaultValue:'123456}} */ private specialFields:Record; /** * 特殊字段 * @param specialFields */ constructor(specialFields:Record){ this.specialFields = specialFields; } /** * 保存 * @param model 待保存model * @returns 保存后的model */ public async save(request:HttpRequest,model:any,cfg?:EntityConfig,){ let entity = await this.objectToEntity(request,model,cfg) as any; if(this.specialFields){ for(let p of Object.keys(this.specialFields)){ const f = this.specialFields[p] as Record; //设置默认值 if(f.defaultValue !== undefined && entity[p] === undefined){ entity[p] = f.defaultValue; } if(f.useLogonUser){ //使用登录用户 if(request){ if(!entity[p] || f.update){ let logInfo = await (await request.getSession()).get("authInfo") as string; if(logInfo){ logInfo = JSON.parse(logInfo); entity[p] = new AmUser(logInfo['userId']) } } } }else if(f.useSystemTime){ //使用系统时间 if(!entity[p] || f.update){ entity[p] = new Date().getTime(); } }else if(f.encryption && model[p]){ //加密 entity[p] = Util.encrypt(model[p],f.encryption); } } } cfg ||= this.getEntityConfig(model); let idName = cfg.getId().name as string; await entity.save(false); let o:Record = {}; o[idName] = entity[idName]; let idValue:any = entity[idName]; if(typeof idValue === 'object'){ let key = Object.keys(idValue); idValue = idValue[key[0]]; } await this.handleManyToMany(idValue,model,cfg); await this.handleOneToMany(idValue,model,cfg); return o; } /** * 删除 * @param model 待删除model * @returns true/false */ public async delete(model:any){ let cfg = this.getEntityConfig(model); let cfg1; //找到onetoone且不为mappedby的,一并删除 for(let [name,value] of cfg.relations){ if(value.type === ERelationType.OneToOne && !value.mappedBy){ cfg1 = EntityFactory.getEntityConfig(value.entity); } } let idName = cfg.getId().name as string; let params: { [key: string]: any } = {}; params[idName] = { rel: "in", value: model.ids.split(',') }; (cfg.entity as any).deleteMany(params); //onetoone外键实体进行删除 if(cfg1){ cfg1.entity.deleteMany(params); } return true; } /** * 通过id查询 * @param model 模型 * @returns */ public async findById(model:any){ let cfg = this.getEntityConfig(model); let idName = cfg.getId().name as string; if(cfg.hasRelation(idName)){ //外键为主键 let rel = cfg.getRelation(idName); let cfg1 = EntityFactory.getEntityConfig(rel.entity); idName += '.' + cfg1.getId().name; } model.conditions = {}; model.conditions[idName] = model.ids; let fields:string[] = []; this.genRelFields(cfg.entity.name,fields); fields.unshift('*'); model.fields = fields; return await this.queryOne(model); } /** * 查询1个 * @param model 模型 * @param cfg entityconfig * @returns */ public async queryOne(model:any,cfg?:EntityConfig){ cfg ||= this.getEntityConfig(model); await getConnection(); let em: EntityManager = await getEntityManager(); let query: Query = em.createQuery(cfg.entity.name); let r = await query.select(model.fields||'*') .where(model.conditions||{}) .getResult(); //处理manyToMany字段 let ma = this.getManyToMany(true); if(ma.length>0){ for(let f of ma){ await r['get'+f](); } } await em.close(); await closeConnection(); return r; } /** * 查询 * @param model * @param cfg 实体配置对象 * @returns {rows:结果集,total:总记录数} */ public async query(model:any,cfg?:EntityConfig){ cfg ||= this.getEntityConfig(model); let start = 0; let limit = 0; if(model.pageNo>0 && model.pageSize>0){ start = (model.pageNo - 1) * model.pageSize; limit = model.pageSize; } await getConnection(); let em: EntityManager = await getEntityManager(); let query: Query = em.createQuery(cfg.entity.name); //如果传递了查询字段,则使用传递的字段,否则用默认查询字段 let fields:string[]; if(model.fields){ fields = model.fields.split(','); }else{ fields = []; this.genRelFields(cfg.entity.name,fields); fields.unshift('*') } let conditions = model.conditions || {}; let rows = await query.select(fields) .where(conditions) .getResultList(start,limit) as []; //处理manyToMany字段 let ma = this.getManyToMany(true); if(ma.length>0){ for(let f of ma){ for(let r of rows){ await (r as any)['get'+f](); } } } let total = await em.getCount(cfg.entity.name,conditions); await em.close(); await closeConnection(); return {rows:rows,total:total}; } /** * 对象转实体 * @param model 数据对象 * @returns 实体对象 */ public async objectToEntity(request:HttpRequest,model:Record,cfg?:EntityConfig):Promise{ cfg ||= this.getEntityConfig(model); const entity = Reflect.construct(cfg.entity,[]) as any; for(let p of Object.keys(model)){ if(p === '__nullCheckArr'){ continue; } if(typeof model[p] === 'object' && cfg.hasRelation(p) && model[p]){ const rel = cfg.getRelation(p); //onetoone需要设置showName和entityName if(rel.type === ERelationType.OneToOne || rel.type === ERelationType.ManyToOne){ //多对多关系最后处理 const cfg1 = EntityFactory.getEntityConfig(rel.entity); const entity1 = Reflect.construct(cfg1.entity,[]) as any; const idName = cfg1.getId().name as string; let idValue; //无主键和OneToOne,需要先保存 if(!(model[p] as any)[idName] || rel.type==ERelationType.OneToOne){ if(rel.type === ERelationType.OneToOne){ const entName = model.constructor.name.substring(1); (model[p] as any).entityName = entName; const m= await AmModel.findOne({refEntity:entName}); if(m){ (model[p] as any).showName = m.showName; } } let en = await this.save(request,model[p],cfg1); idValue = en[idName]; }else{ idValue = (model[p] as any)[idName]; } entity1[idName] = idValue; entity[p] = entity1; } }else{ entity[p] = model[p]; } } return entity; } private genRelFields(clsName:string,fieldArr:string[],pre?:string){ const cfg = EntityFactory.getEntityConfig(clsName); for(let rel of cfg.relations){ if(rel[1].type == ERelationType.OneToOne){ fieldArr.push(pre?pre+'.'+rel[0]:rel[0]); //one 向上走一级 this.genRelFields(rel[1].entity,fieldArr,rel[0]); }else if(rel[1].type == ERelationType.ManyToOne){ fieldArr.push(pre?pre+'.'+rel[0]:rel[0]); } } } /** * 获取实体类 * @param model 模型(数据驱动) * @returns 实体配置 */ private getEntityConfig(model:any):EntityConfig{ return EntityFactory.getEntityConfig(model.constructor.name.substring(1)); } /** * 处理多对多 * @param idValue 主键值值 * @param model 数据模型 */ private async handleOneToMany(idValue:any,model:any,cfg?:EntityConfig){ if(!this.specialFields){ return; } cfg ||= this.getEntityConfig(model); let relField = model.constructor.name; relField = relField.substring(1,2).toLowerCase() + relField.substring(2); await getConnection(); const em:EntityManager = await getEntityManager(); for(let k of Object.keys(this.specialFields)){ const field = this.specialFields[k] as any; if(field.oneToMany && model[k] && model[k].length>0){ if(cfg.relations.has(k)){ const rel = cfg.getRelation(k); const cfg1 = EntityFactory.getEntityConfig(rel.entity); const col = cfg1.getColumn(relField); const id = cfg1.getIdName(); const sql = `update ${cfg1.table} set ${col.refName} = ${idValue} where ${id} in ?`; try{ const query = em.createNativeQuery(sql); query.setParameter(0,[model[k]]); await query.getResult(); }catch(e){ console.log(e); } } } } await em.close(); await closeConnection(); } /** * 处理多对多 * @param idValue 主键值值 * @param model 数据模型 */ private async handleManyToMany(idValue:any,model:any,cfg?:EntityConfig){ if(!this.specialFields){ return; } let arr = this.getManyToMany(); if(arr.length === 0){ return; } cfg ||= this.getEntityConfig(model); let idName = cfg.getId().name; await getConnection(); const em:EntityManager = await getEntityManager(); //新数据 let isNew = model[idName as string] === undefined; for(let p of arr){ if(model[p] && model[p].length>0 && cfg.relations.has(p)){ handleOne(p); } } await em.close(); await closeConnection(); /** * 处理一个多对多属性 * @param name 属性名 */ async function handleOne(name:string){ const col = (cfg as EntityConfig).getColumn(name); const tblName = col.joinTable; const refName = col.refName; const colName = col.joinColumn; const values = model[name]; if(!isNew){ //非新增,需要处理所有与该idvalue相关联的数据 // const rows = await em.createNativeQuery(`select * from ${tblName} where ${colName}=${idValue}`).getResultList(); // if(rows){ // for(let i=0;iitem===rows[i][refName]); // if(index !== -1){ // values.splice(index,1); // rows.splice(i--,1); // } // } // //多余的需要删除 // if(rows.length>0){ // for(let d of rows){ // await em.createNativeQuery(`delete from ${tblName} where ${colName}=${idValue} and ${refName}=${d[refName]}`).getResult(); // } // } // } //删除与该id相关的数据 await em.createNativeQuery(`delete from ${tblName} where ${colName}=${idValue}`).getResult(); } //添加数据 for(let d of values){ await em.createNativeQuery(`insert into ${tblName}(${colName},${refName}) values (${idValue},${d})`).getResult(); } } } /** * 获取manyToMany字段 * @param firstUP 如果为true,则首字母改成大写 * @returns */ private getManyToMany(firstUp?:boolean){ let a = []; if(this.specialFields){ for(let k of Object.keys(this.specialFields)){ if(this.specialFields[k].manyToMany){ if(firstUp){ a.push(k.substring(0,1).toUpperCase() + k.substring(1)); }else{ a.push(k); } } } } return a; } }