lrf il y a 2 ans
Parent
commit
44244ad404
4 fichiers modifiés avec 213 ajouts et 4 suppressions
  1. 4 0
      app/controller/.table.js
  2. 196 0
      app/public/ts-template.js
  3. 12 4
      app/service/table.js
  4. 1 0
      app/z_router/table.js

+ 4 - 0
app/controller/.table.js

@@ -41,4 +41,8 @@ module.exports = {
     requestBody: ['!ids'],
     operation: '导出',
   },
+  toExportTS: {
+    requestBody: ['!ids'],
+    operation: '导出',
+  },
 };

+ 196 - 0
app/public/ts-template.js

@@ -0,0 +1,196 @@
+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<typeof ${prefix}>;`);
+  fc.push(`@Provide()`);
+  fc.push(`export class ${prefix}Service extends BaseService<modelType> {`);
+  fc.push(`  @InjectEntityModel(${prefix})`);
+  fc.push(`  model: modelType;`);
+  fc.push(`}`);
+  return fc.join('\n');
+};
+const ControllerContext = (data) => {
+  const fc = [];
+  const { name: table_name } = 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(['团购商品设置'])`);
+  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;
+};

+ 12 - 4
app/service/table.js

@@ -1,17 +1,15 @@
 'use strict';
 const { CrudService } = require('naf-framework-mongoose-free/lib/service');
 const template = require('../public/table-template');
-const { log } = require('../public/deco');
+const TSTemplate = require('../public/ts-template');
 class TableService extends CrudService {
   constructor(ctx) {
     super(ctx, 'table');
     this.model = this.ctx.model.Table;
   }
-  @log('测试')
-  async test(data){
+  async test(data) {
     console.log(data);
   }
-  @log('导出')
   async toExport({ ids }) {
     const res = await this.model.find({ _id: { $in: ids } });
     const data = {};
@@ -21,6 +19,16 @@ class TableService extends CrudService {
     }
     return data;
   }
+
+  async toExportTS({ ids }) {
+    const res = await this.model.find({ _id: { $in: ids } }).lean();
+    const data = {};
+    for (const i of res) {
+      const d = TSTemplate(i);
+      data[i.name_zh ? i.name_zh : i.name] = d;
+    }
+    return data;
+  }
 }
 
 module.exports = TableService;

+ 1 - 0
app/z_router/table.js

@@ -6,6 +6,7 @@ module.exports = (app) => {
   const prefix = config.routePrefix;
   const mware = app.middleware.logDb();
   router.post(`targetExport`, `${prefix}/${target}/export`, mware, controller[target].toExport);
+  router.post(`targetExportTS`, `${prefix}/${target}/exportTS`, controller[target].toExportTS);
   router.resources(target, `${prefix}/${target}`, controller[target]); // index、create、show、destroy
   router.post(target, `${prefix}/${target}/:id`, controller[target].update);
 };