const _ = require('lodash'); const getModelType = (type) => { let modelType = 'string'; if (type === 'Money' || type === 'money') modelType = 'Decimal128'; else if (type === 'ObjectId') modelType = 'ObjectId'; else if (type === 'Array') modelType = 'Array'; else modelType = _.lowerFirst(type); return modelType; }; const ModelContext = (data) => { const result = []; const { name: table_name, columns } = data; const prefix = _.upperFirst(table_name); let fc = []; fc.push(`import { modelOptions, prop } from '@typegoose/typegoose';`); fc.push(`import { BaseModel } from 'free-midway-component';`); const has_money = columns.find((f) => f.type === 'Money' || f.type === 'money'); if (has_money) fc.push(`import { Decimal128 } from 'mongoose';`); fc.push(`@modelOptions({`); fc.push(` schemaOptions: { collection: '${table_name}' },`); fc.push(`})`); fc.push(`export class ${prefix} extends BaseModel {`); // 处理字段 for (const col of columns) { const { type, required, index, title, zh } = col; const prop = { required, index, zh }; const modelType = getModelType(type); fc.push(` @prop(${JSON.stringify(prop)})`); fc.push(` ${title}: ${modelType}`); } fc.push(`}`); // 最后换行转为字符串 const fileContext = fc.join('\n'); return fileContext; }; const ServiceContext = (data) => { const fc = []; const { name: table_name } = data; const prefix = _.upperFirst(table_name); fc.push(`import { Provide } from '@midwayjs/decorator';`); fc.push(`import { InjectEntityModel } from '@midwayjs/typegoose';`); fc.push(`import { ReturnModelType } from '@typegoose/typegoose';`); fc.push(`import { BaseService } from 'free-midway-component';`); fc.push(`import { ${prefix} } from '../entity/${table_name}';`); fc.push(`type modelType = ReturnModelType;`); fc.push(`@Provide()`); fc.push(`export class ${prefix}Service extends BaseService {`); fc.push(` @InjectEntityModel(${prefix})`); fc.push(` model: modelType;`); fc.push(`}`); return fc.join('\n'); }; const ControllerContext = (data) => { const fc = []; const { name: table_name, zh } = data; const prefix = _.upperFirst(table_name); fc.push(`import { Body, Controller, Del, Get, Inject, Param, Post, Query } from '@midwayjs/decorator';`); fc.push(`import { BaseController } from 'free-midway-component';`); fc.push(`import { ${prefix}Service } from '../service/${table_name}.service';`); fc.push(`import { CreateDTO, CreateVO, FetchVO, QueryDTO, QueryVO, UpdateDTO, UpdateVO } from '../interface/${table_name}.interface';`); fc.push(`import { ApiResponse, ApiTags } from '@midwayjs/swagger';`); fc.push(`import { Validate } from '@midwayjs/validate';`); fc.push(`@ApiTags(['${zh}'])`); fc.push(`@Controller('/${prefix}')`); fc.push(`export class ${prefix}Controller extends BaseController {`); fc.push(` @Inject()`); fc.push(` service: ${prefix}Service;`); fc.push('\n'); // create fc.push(`@Post('/') @Validate() @ApiResponse({ type: CreateVO })`); fc.push(` async create(@Body() data: CreateDTO) {`); fc.push(` const result = await this.service.create(data);`); fc.push(` return result;`); fc.push(` }`); // query fc.push(`@Get('/')@ApiResponse({ type: QueryVO })`); fc.push(` async query(@Query('filter') filter: QueryDTO, @Query('skip') skip: number,@Query('limit') limit: number){`); fc.push(` const data = await this.service.query(filter, { skip, limit });`); fc.push(` const total = await this.service.count(filter);`); fc.push(` return { data, total };`); fc.push(` }`); fc.push(`\n`); // fetch fc.push(`@Get('/:id')@ApiResponse({ type: FetchVO })`); fc.push(` async fetch(@Param('id') id: string) {`); fc.push(` const data = await this.service.fetch(id);`); fc.push(` const result = new FetchVO(data);`); fc.push(` return result;`); fc.push(` }`); fc.push(`\n`); // update fc.push(`@Post('/:id')@Validate()@ApiResponse({ type: UpdateVO })`); fc.push(` async update(@Param('id') id: string, @Body() body: UpdateDTO) {`); fc.push(` const result = await this.service.updateOne(id, body);`); fc.push(` return result;`); fc.push(` }`); fc.push(`\n`); // delete fc.push(`@Del('/:id')@Validate()`); fc.push(` async delete(@Param('id') id: string) {`); fc.push(` await this.service.delete(id);`); fc.push(` return 'ok';`); fc.push(` }`); // other bat deal fc.push(` async createMany(...args: any[]) {`); fc.push(` throw new Error('Method not implemented.');`); fc.push(` }`); fc.push(`\n`); fc.push(` async updateMany(...args: any[]) {`); fc.push(` throw new Error('Method not implemented.');`); fc.push(` }`); fc.push(`\n`); fc.push(` async deleteMany(...args: any[]) {`); fc.push(` throw new Error('Method not implemented.');`); fc.push(` }`); fc.push(`\n`); return fc.join(`\n`); }; /** * * @param {Object} col 字段 * @param {boolean} needReq 是否启用必须,针对post设置 * @returns */ const getInterfaceColumn = (col, needReq = false) => { const fc = []; const { type, zh, title, required } = col; const modelType = getModelType(type); fc.push(` @ApiProperty({ description: '${title}' })`); if (needReq && required) { const ruleStr = `@Rule(RuleType['${modelType}']().required().error(new ServiceError('缺少${zh}',FrameworkErrorEnum.${needReq ? 'NEED_BODY' : 'NEED_QUERY'})))`; fc.push(ruleStr); } fc.push(` '${title}': ${modelType} = undefined;`); return fc; }; const interfaceContext = (data) => { const fc = []; const { columns = [] } = data; fc.push(`import { Rule, RuleType } from '@midwayjs/validate';`); fc.push(`import { ApiProperty } from '@midwayjs/swagger';`); fc.push(`import _ = require('lodash');`); fc.push(`import { FrameworkErrorEnum, SearchBase, ServiceError } from 'free-midway-component';`); fc.push(`export class FetchVO {`); fc.push(` constructor(data: object) {`); fc.push(` for (const key of Object.keys(this)) {`); fc.push(` this[key] = _.get(data, key);`); fc.push(` }`); fc.push(` }`); for (const col of columns) { const cfc = getInterfaceColumn(col); fc.push(...cfc); } fc.push(`}`); fc.push(`\n`); fc.push(`export class QueryDTO extends SearchBase {`); fc.push(` constructor() {`); fc.push(` const like_prop = [];`); fc.push(` super({ like_prop });`); fc.push(` }`); for (const col of columns.filter((f) => f.index)) { const cfc = getInterfaceColumn(col); fc.push(...cfc); } fc.push(`}`); fc.push(`\n`); fc.push(`export class QueryVO extends FetchVO {}`); fc.push(`\n`); fc.push(`export class CreateDTO {`); for (const col of columns) { const cfc = getInterfaceColumn(col, true); fc.push(...cfc); } fc.push(`}`); fc.push(`\n`); fc.push(`export class CreateVO extends FetchVO {}`); fc.push(`\n`); fc.push(`export class UpdateDTO extends CreateDTO {}`); fc.push(`\n`); fc.push(`export class UpdateVO extends FetchVO {}`); return fc.join('\n'); }; module.exports = (data) => { let result = `\n========== Model ==========\n`; result += ModelContext(data); result += `\n========== Service ==========\n`; result += ServiceContext(data); result += `\n========== Controller ==========\n`; result += ControllerContext(data); result += `\n========== interface ==========\n`; result += interfaceContext(data); return result; };