lrf 1 year ago
commit
1e68d872b1
59 changed files with 2613 additions and 0 deletions
  1. 11 0
      .editorconfig
  2. 7 0
      .eslintrc.json
  3. 15 0
      .gitignore
  4. 3 0
      .prettierrc.js
  5. 29 0
      README.md
  6. 29 0
      README.zh-CN.md
  7. 2 0
      bootstrap.js
  8. 6 0
      jest.config.js
  9. 61 0
      package.json
  10. 36 0
      src/config/config.default.ts
  11. 19 0
      src/config/config.local.ts
  12. 7 0
      src/config/config.unittest.ts
  13. 38 0
      src/configuration.ts
  14. 96 0
      src/controller/admin.controller.ts
  15. 89 0
      src/controller/adv.controller.ts
  16. 89 0
      src/controller/article.controller.ts
  17. 89 0
      src/controller/chat.controller.ts
  18. 89 0
      src/controller/doctor.controller.ts
  19. 89 0
      src/controller/group.controller.ts
  20. 9 0
      src/controller/home.controller.ts
  21. 89 0
      src/controller/menus.controller.ts
  22. 89 0
      src/controller/nurse.controller.ts
  23. 89 0
      src/controller/patient.controller.ts
  24. 89 0
      src/controller/role.controller.ts
  25. 32 0
      src/entity/admin.entity.ts
  26. 11 0
      src/entity/adv.entity.ts
  27. 28 0
      src/entity/article.entity.ts
  28. 15 0
      src/entity/chat.entity.ts
  29. 48 0
      src/entity/doctor.entity.ts
  30. 15 0
      src/entity/group.entity.ts
  31. 27 0
      src/entity/menus.entity.ts
  32. 50 0
      src/entity/nurse.entity.ts
  33. 34 0
      src/entity/patient.entity.ts
  34. 17 0
      src/entity/role.entity.ts
  35. 6 0
      src/interface.ts
  36. 71 0
      src/interface/admin.interface.ts
  37. 66 0
      src/interface/adv.interface.ts
  38. 98 0
      src/interface/article.interface.ts
  39. 82 0
      src/interface/chat.interface.ts
  40. 115 0
      src/interface/doctor.interface.ts
  41. 80 0
      src/interface/group.interface.ts
  42. 116 0
      src/interface/menus.interface.ts
  43. 128 0
      src/interface/nurse.interface.ts
  44. 115 0
      src/interface/patient.interface.ts
  45. 87 0
      src/interface/role.interface.ts
  46. 27 0
      src/middleware/report.middleware.ts
  47. 11 0
      src/service/admin.service.ts
  48. 11 0
      src/service/adv.service.ts
  49. 11 0
      src/service/article.service.ts
  50. 11 0
      src/service/chat.service.ts
  51. 11 0
      src/service/doctor.service.ts
  52. 11 0
      src/service/group.service.ts
  53. 11 0
      src/service/menus.service.ts
  54. 11 0
      src/service/nurse.service.ts
  55. 11 0
      src/service/patient.service.ts
  56. 11 0
      src/service/role.service.ts
  57. 20 0
      test/controller/api.test.ts
  58. 21 0
      test/controller/home.test.ts
  59. 25 0
      tsconfig.json

+ 11 - 0
.editorconfig

@@ -0,0 +1,11 @@
+# 🎨 editorconfig.org
+
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+indent_style = space
+indent_size = 2
+trim_trailing_whitespace = true
+insert_final_newline = true

+ 7 - 0
.eslintrc.json

@@ -0,0 +1,7 @@
+{
+  "extends": "./node_modules/mwts/",
+  "ignorePatterns": ["node_modules", "dist", "test", "jest.config.js", "typings"],
+  "env": {
+    "jest": true
+  }
+}

+ 15 - 0
.gitignore

@@ -0,0 +1,15 @@
+logs/
+npm-debug.log
+yarn-error.log
+node_modules/
+package-lock.json
+yarn.lock
+coverage/
+dist/
+.idea/
+run/
+.DS_Store
+*.sw*
+*.un~
+.tsbuildinfo
+.tsbuildinfo.*

+ 3 - 0
.prettierrc.js

@@ -0,0 +1,3 @@
+module.exports = {
+  ...require('mwts/.prettierrc.json')
+}

+ 29 - 0
README.md

@@ -0,0 +1,29 @@
+# my_midway_project
+
+## QuickStart
+
+<!-- add docs here for user -->
+
+see [midway docs][midway] for more detail.
+
+### Development
+
+```bash
+$ npm i
+$ npm run dev
+$ open http://localhost:7001/
+```
+
+### Deploy
+
+```bash
+$ npm start
+```
+
+### npm scripts
+
+- Use `npm run lint` to check code style.
+- Use `npm test` to run unit test.
+
+
+[midway]: https://midwayjs.org

+ 29 - 0
README.zh-CN.md

@@ -0,0 +1,29 @@
+# my_midway_project
+
+## 快速入门
+
+<!-- 在此次添加使用文档 -->
+
+如需进一步了解,参见 [midway 文档][midway]。
+
+### 本地开发
+
+```bash
+$ npm i
+$ npm run dev
+$ open http://localhost:7001/
+```
+
+### 部署
+
+```bash
+$ npm start
+```
+
+### 内置指令
+
+- 使用 `npm run lint` 来做代码风格检查。
+- 使用 `npm test` 来执行单元测试。
+
+
+[midway]: https://midwayjs.org

+ 2 - 0
bootstrap.js

@@ -0,0 +1,2 @@
+const { Bootstrap } = require('@midwayjs/bootstrap');
+Bootstrap.run();

+ 6 - 0
jest.config.js

@@ -0,0 +1,6 @@
+module.exports = {
+  preset: 'ts-jest',
+  testEnvironment: 'node',
+  testPathIgnorePatterns: ['<rootDir>/test/fixtures'],
+  coveragePathIgnorePatterns: ['<rootDir>/test/'],
+};

+ 61 - 0
package.json

@@ -0,0 +1,61 @@
+{
+  "name": "my-midway-project",
+  "version": "1.0.0",
+  "description": "",
+  "private": true,
+  "dependencies": {
+    "@midwayjs/bootstrap": "^3.12.0",
+    "@midwayjs/core": "^3.12.0",
+    "@midwayjs/decorator": "^3.12.0",
+    "@midwayjs/info": "^3.12.0",
+    "@midwayjs/jwt": "^3.8.0",
+    "@midwayjs/koa": "^3.12.0",
+    "@midwayjs/logger": "^2.14.0",
+    "@midwayjs/redis": "^3.9.0",
+    "@midwayjs/swagger": "^3.12.7",
+    "@midwayjs/typegoose": "^3.0.0",
+    "@midwayjs/validate": "^3.12.0",
+    "@typegoose/typegoose": "^9.0.0",
+    "free-midway-component": "^1.0.40",
+    "lodash": "^4.17.21",
+    "mongoose": "^6.0.7"
+  },
+  "devDependencies": {
+    "@midwayjs/cli": "^2.0.0",
+    "@midwayjs/mock": "^3.12.0",
+    "@types/jest": "^29.2.0",
+    "@types/jsonwebtoken": "^8.5.9",
+    "@types/koa": "^2.13.4",
+    "@types/lodash": "^4.14.200",
+    "@types/node": "14",
+    "cross-env": "^6.0.0",
+    "jest": "^29.2.2",
+    "mwts": "^1.3.0",
+    "swagger-ui-dist": "^5.9.0",
+    "ts-jest": "^29.0.3",
+    "typescript": "~4.8.0"
+  },
+  "engines": {
+    "node": ">=12.0.0"
+  },
+  "scripts": {
+    "start": "NODE_ENV=production node ./bootstrap.js",
+    "dev": "cross-env TS_NODE_TYPE_CHECK=false TS_NODE_TRANSPILE_ONLY=true NODE_ENV=local midway-bin dev --ts",
+    "test": "midway-bin test --ts",
+    "cov": "midway-bin cov --ts",
+    "lint": "mwts check",
+    "lint:fix": "mwts fix",
+    "ci": "npm run cov",
+    "build": "midway-bin build -c"
+  },
+  "midway-bin-clean": [
+    ".vscode/.tsbuildinfo",
+    "dist"
+  ],
+  "repository": {
+    "type": "git",
+    "url": ""
+  },
+  "author": "anonymous",
+  "license": "MIT"
+}

+ 36 - 0
src/config/config.default.ts

@@ -0,0 +1,36 @@
+import { MidwayConfig } from '@midwayjs/core';
+const ip = '127.0.0.1';
+const project = 'follow23';
+export default {
+  // use for cookie sign key, should change to your own and keep security
+  keys: '1697684406848_4978',
+  koa: {
+    port: 8890,
+  },
+  jwt: {
+    secret: 'Ziyouyanfa!@#',
+    expiresIn: '2d',
+  },
+  mongoose: {
+    dataSource: {
+      default: {
+        uri: `mongodb://${ip}:27017/${project}`,
+        options: {
+          user: 'admin',
+          pass: 'admin',
+          authSource: 'admin',
+          useNewUrlParser: true,
+        },
+        entities: ['./entity'],
+      },
+    },
+  },
+  redis: {
+    client: {
+      port: 6379, // Redis port
+      host: ip, // Redis host
+      password: '123456',
+      db: 4,
+    },
+  },
+} as MidwayConfig;

+ 19 - 0
src/config/config.local.ts

@@ -0,0 +1,19 @@
+import { MidwayConfig } from '@midwayjs/core';
+const ip = '127.0.0.1';
+const project = 'follow23';
+export default {
+  mongoose: {
+    dataSource: {
+      default: {
+        uri: `mongodb://${ip}:27017/${project}`,
+        options: {
+          user: 'lrf',
+          pass: '1qaz2wsx',
+          authSource: 'admin',
+          useNewUrlParser: true,
+        },
+        entities: ['./entity'],
+      },
+    },
+  },
+} as MidwayConfig;

+ 7 - 0
src/config/config.unittest.ts

@@ -0,0 +1,7 @@
+import { MidwayConfig } from '@midwayjs/core';
+
+export default {
+  koa: {
+    port: null,
+  },
+} as MidwayConfig;

+ 38 - 0
src/configuration.ts

@@ -0,0 +1,38 @@
+import { Configuration, App } from '@midwayjs/core';
+import * as koa from '@midwayjs/koa';
+import * as validate from '@midwayjs/validate';
+import * as info from '@midwayjs/info';
+import { join } from 'path';
+import { ReportMiddleware } from './middleware/report.middleware';
+import * as FreeFrame from 'free-midway-component';
+import * as redis from '@midwayjs/redis';
+import * as swagger from '@midwayjs/swagger';
+
+@Configuration({
+  imports: [
+    koa,
+    validate,
+    FreeFrame,
+    redis,
+    {
+      component: swagger,
+      enabledEnvironment: ['local'],
+    },
+    {
+      component: info,
+      enabledEnvironment: ['local'],
+    },
+  ],
+  importConfigs: [join(__dirname, './config')],
+})
+export class MainConfiguration {
+  @App('koa')
+  app: koa.Application;
+
+  async onReady() {
+    // add middleware
+    this.app.useMiddleware([ReportMiddleware]);
+    // add filter
+    // this.app.useFilter([NotFoundFilter, DefaultErrorFilter]);
+  }
+}

+ 96 - 0
src/controller/admin.controller.ts

@@ -0,0 +1,96 @@
+import {
+  Body,
+  Controller,
+  Del,
+  Get,
+  Inject,
+  Param,
+  Post,
+  Query,
+} from '@midwayjs/decorator';
+import {
+  BaseController,
+  FrameworkErrorEnum,
+  ServiceError,
+} from 'free-midway-component';
+import { AdminService } from '../service/admin.service';
+import {
+  CDTO_admin,
+  CVO_admin,
+  FVO_admin,
+  QDTO_admin,
+  QVO_admin,
+  UDTO_admin,
+  UVAO_admin,
+} from '../interface/admin.interface';
+import { ApiResponse, ApiTags, ApiQuery } from '@midwayjs/swagger';
+import { Validate } from '@midwayjs/validate';
+@ApiTags(['管理员表'])
+@Controller('/admin')
+export class AdminController extends BaseController {
+  @Inject()
+  service: AdminService;
+
+  @Post('/')
+  @Validate()
+  @ApiResponse({ type: CVO_admin })
+  async create(@Body() data: CDTO_admin) {
+    // 禁用!项目初始化生成
+    // const dbData = await this.service.create(data);
+    // const result = new CVO_admin(dbData);
+    return new ServiceError('不提供此服务', FrameworkErrorEnum.SERVICE_FAULT);
+  }
+  @Get('/')
+  @ApiQuery({ name: 'query' })
+  @ApiResponse({ type: QVO_admin })
+  async query(
+    @Query() filter: QDTO_admin,
+    @Query('skip') skip: number,
+    @Query('limit') limit: number
+  ) {
+    const list = await this.service.query(filter, { skip, limit });
+    const data = [];
+    for (const i of list) {
+      const newData = new QVO_admin(i);
+      data.push(newData);
+    }
+    const total = await this.service.count(filter);
+    return { data, total };
+  }
+
+  @Get('/:id')
+  @ApiResponse({ type: FVO_admin })
+  async fetch(@Param('id') id: string) {
+    const data = await this.service.fetch(id);
+    const result = new FVO_admin(data);
+    return result;
+  }
+
+  @Post('/:id')
+  @Validate()
+  @ApiResponse({ type: UVAO_admin })
+  async update(@Param('id') id: string, @Body() body: UDTO_admin) {
+    const result = await this.service.updateOne(id, body);
+    return result;
+  }
+
+  @Del('/:id')
+  @Validate()
+  async delete(@Param('id') id: string) {
+    // 禁用
+    // await this.service.delete(id);
+    // return 'ok';
+    return new ServiceError('不提供此服务', FrameworkErrorEnum.SERVICE_FAULT);
+  }
+  async createMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+
+  async updateMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+
+  async deleteMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+}

+ 89 - 0
src/controller/adv.controller.ts

@@ -0,0 +1,89 @@
+import {
+  Body,
+  Controller,
+  Del,
+  Get,
+  Inject,
+  Param,
+  Post,
+  Query,
+} from '@midwayjs/decorator';
+import { BaseController } from 'free-midway-component';
+import { AdvService } from '../service/adv.service';
+import {
+  CDTO_adv,
+  CVO_adv,
+  FVO_adv,
+  QDTO_adv,
+  QVO_adv,
+  UDTO_adv,
+  UVAO_adv,
+} from '../interface/adv.interface';
+import { ApiResponse, ApiTags, ApiQuery } from '@midwayjs/swagger';
+import { Validate } from '@midwayjs/validate';
+@ApiTags(['广告'])
+@Controller('/adv')
+export class AdvController extends BaseController {
+  @Inject()
+  service: AdvService;
+
+  @Post('/')
+  @Validate()
+  @ApiResponse({ type: CVO_adv })
+  async create(@Body() data: CDTO_adv) {
+    const dbData = await this.service.create(data);
+    const result = new CVO_adv(dbData);
+    return result;
+  }
+  @Get('/')
+  @ApiQuery({ name: 'query' })
+  @ApiResponse({ type: QVO_adv })
+  async query(
+    @Query() filter: QDTO_adv,
+    @Query('skip') skip: number,
+    @Query('limit') limit: number
+  ) {
+    const list = await this.service.query(filter, { skip, limit });
+    const data = [];
+    for (const i of list) {
+      const newData = new QVO_adv(i);
+      data.push(newData);
+    }
+    const total = await this.service.count(filter);
+    return { data, total };
+  }
+
+  @Get('/:id')
+  @ApiResponse({ type: FVO_adv })
+  async fetch(@Param('id') id: string) {
+    const data = await this.service.fetch(id);
+    const result = new FVO_adv(data);
+    return result;
+  }
+
+  @Post('/:id')
+  @Validate()
+  @ApiResponse({ type: UVAO_adv })
+  async update(@Param('id') id: string, @Body() body: UDTO_adv) {
+    const result = await this.service.updateOne(id, body);
+    return result;
+  }
+
+  @Del('/:id')
+  @Validate()
+  async delete(@Param('id') id: string) {
+    await this.service.delete(id);
+    return 'ok';
+  }
+  async createMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+
+  async updateMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+
+  async deleteMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+}

+ 89 - 0
src/controller/article.controller.ts

@@ -0,0 +1,89 @@
+import {
+  Body,
+  Controller,
+  Del,
+  Get,
+  Inject,
+  Param,
+  Post,
+  Query,
+} from '@midwayjs/decorator';
+import { BaseController } from 'free-midway-component';
+import { ArticleService } from '../service/article.service';
+import {
+  CDTO_article,
+  CVO_article,
+  FVO_article,
+  QDTO_article,
+  QVO_article,
+  UDTO_article,
+  UVAO_article,
+} from '../interface/article.interface';
+import { ApiResponse, ApiTags, ApiQuery } from '@midwayjs/swagger';
+import { Validate } from '@midwayjs/validate';
+@ApiTags(['文章'])
+@Controller('/article')
+export class ArticleController extends BaseController {
+  @Inject()
+  service: ArticleService;
+
+  @Post('/')
+  @Validate()
+  @ApiResponse({ type: CVO_article })
+  async create(@Body() data: CDTO_article) {
+    const dbData = await this.service.create(data);
+    const result = new CVO_article(dbData);
+    return result;
+  }
+  @Get('/')
+  @ApiQuery({ name: 'query' })
+  @ApiResponse({ type: QVO_article })
+  async query(
+    @Query() filter: QDTO_article,
+    @Query('skip') skip: number,
+    @Query('limit') limit: number
+  ) {
+    const list = await this.service.query(filter, { skip, limit });
+    const data = [];
+    for (const i of list) {
+      const newData = new QVO_article(i);
+      data.push(newData);
+    }
+    const total = await this.service.count(filter);
+    return { data, total };
+  }
+
+  @Get('/:id')
+  @ApiResponse({ type: FVO_article })
+  async fetch(@Param('id') id: string) {
+    const data = await this.service.fetch(id);
+    const result = new FVO_article(data);
+    return result;
+  }
+
+  @Post('/:id')
+  @Validate()
+  @ApiResponse({ type: UVAO_article })
+  async update(@Param('id') id: string, @Body() body: UDTO_article) {
+    const result = await this.service.updateOne(id, body);
+    return result;
+  }
+
+  @Del('/:id')
+  @Validate()
+  async delete(@Param('id') id: string) {
+    await this.service.delete(id);
+    return 'ok';
+  }
+  async createMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+
+  async updateMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+
+  async deleteMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+}

+ 89 - 0
src/controller/chat.controller.ts

@@ -0,0 +1,89 @@
+import {
+  Body,
+  Controller,
+  Del,
+  Get,
+  Inject,
+  Param,
+  Post,
+  Query,
+} from '@midwayjs/decorator';
+import { BaseController } from 'free-midway-component';
+import { ChatService } from '../service/chat.service';
+import {
+  CDTO_chat,
+  CVO_chat,
+  FVO_chat,
+  QDTO_chat,
+  QVO_chat,
+  UDTO_chat,
+  UVAO_chat,
+} from '../interface/chat.interface';
+import { ApiResponse, ApiTags, ApiQuery } from '@midwayjs/swagger';
+import { Validate } from '@midwayjs/validate';
+@ApiTags(['聊天记录'])
+@Controller('/chat')
+export class ChatController extends BaseController {
+  @Inject()
+  service: ChatService;
+
+  @Post('/')
+  @Validate()
+  @ApiResponse({ type: CVO_chat })
+  async create(@Body() data: CDTO_chat) {
+    const dbData = await this.service.create(data);
+    const result = new CVO_chat(dbData);
+    return result;
+  }
+  @Get('/')
+  @ApiQuery({ name: 'query' })
+  @ApiResponse({ type: QVO_chat })
+  async query(
+    @Query() filter: QDTO_chat,
+    @Query('skip') skip: number,
+    @Query('limit') limit: number
+  ) {
+    const list = await this.service.query(filter, { skip, limit });
+    const data = [];
+    for (const i of list) {
+      const newData = new QVO_chat(i);
+      data.push(newData);
+    }
+    const total = await this.service.count(filter);
+    return { data, total };
+  }
+
+  @Get('/:id')
+  @ApiResponse({ type: FVO_chat })
+  async fetch(@Param('id') id: string) {
+    const data = await this.service.fetch(id);
+    const result = new FVO_chat(data);
+    return result;
+  }
+
+  @Post('/:id')
+  @Validate()
+  @ApiResponse({ type: UVAO_chat })
+  async update(@Param('id') id: string, @Body() body: UDTO_chat) {
+    const result = await this.service.updateOne(id, body);
+    return result;
+  }
+
+  @Del('/:id')
+  @Validate()
+  async delete(@Param('id') id: string) {
+    await this.service.delete(id);
+    return 'ok';
+  }
+  async createMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+
+  async updateMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+
+  async deleteMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+}

+ 89 - 0
src/controller/doctor.controller.ts

@@ -0,0 +1,89 @@
+import {
+  Body,
+  Controller,
+  Del,
+  Get,
+  Inject,
+  Param,
+  Post,
+  Query,
+} from '@midwayjs/decorator';
+import { BaseController } from 'free-midway-component';
+import { DoctorService } from '../service/doctor.service';
+import {
+  CDTO_doctor,
+  CVO_doctor,
+  FVO_doctor,
+  QDTO_doctor,
+  QVO_doctor,
+  UDTO_doctor,
+  UVAO_doctor,
+} from '../interface/doctor.interface';
+import { ApiResponse, ApiTags, ApiQuery } from '@midwayjs/swagger';
+import { Validate } from '@midwayjs/validate';
+@ApiTags(['医生'])
+@Controller('/doctor')
+export class DoctorController extends BaseController {
+  @Inject()
+  service: DoctorService;
+
+  @Post('/')
+  @Validate()
+  @ApiResponse({ type: CVO_doctor })
+  async create(@Body() data: CDTO_doctor) {
+    const dbData = await this.service.create(data);
+    const result = new CVO_doctor(dbData);
+    return result;
+  }
+  @Get('/')
+  @ApiQuery({ name: 'query' })
+  @ApiResponse({ type: QVO_doctor })
+  async query(
+    @Query() filter: QDTO_doctor,
+    @Query('skip') skip: number,
+    @Query('limit') limit: number
+  ) {
+    const list = await this.service.query(filter, { skip, limit });
+    const data = [];
+    for (const i of list) {
+      const newData = new QVO_doctor(i);
+      data.push(newData);
+    }
+    const total = await this.service.count(filter);
+    return { data, total };
+  }
+
+  @Get('/:id')
+  @ApiResponse({ type: FVO_doctor })
+  async fetch(@Param('id') id: string) {
+    const data = await this.service.fetch(id);
+    const result = new FVO_doctor(data);
+    return result;
+  }
+
+  @Post('/:id')
+  @Validate()
+  @ApiResponse({ type: UVAO_doctor })
+  async update(@Param('id') id: string, @Body() body: UDTO_doctor) {
+    const result = await this.service.updateOne(id, body);
+    return result;
+  }
+
+  @Del('/:id')
+  @Validate()
+  async delete(@Param('id') id: string) {
+    await this.service.delete(id);
+    return 'ok';
+  }
+  async createMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+
+  async updateMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+
+  async deleteMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+}

+ 89 - 0
src/controller/group.controller.ts

@@ -0,0 +1,89 @@
+import {
+  Body,
+  Controller,
+  Del,
+  Get,
+  Inject,
+  Param,
+  Post,
+  Query,
+} from '@midwayjs/decorator';
+import { BaseController } from 'free-midway-component';
+import { GroupService } from '../service/group.service';
+import {
+  CDTO_group,
+  CVO_group,
+  FVO_group,
+  QDTO_group,
+  QVO_group,
+  UDTO_group,
+  UVAO_group,
+} from '../interface/group.interface';
+import { ApiResponse, ApiTags, ApiQuery } from '@midwayjs/swagger';
+import { Validate } from '@midwayjs/validate';
+@ApiTags(['群组'])
+@Controller('/group')
+export class GroupController extends BaseController {
+  @Inject()
+  service: GroupService;
+
+  @Post('/')
+  @Validate()
+  @ApiResponse({ type: CVO_group })
+  async create(@Body() data: CDTO_group) {
+    const dbData = await this.service.create(data);
+    const result = new CVO_group(dbData);
+    return result;
+  }
+  @Get('/')
+  @ApiQuery({ name: 'query' })
+  @ApiResponse({ type: QVO_group })
+  async query(
+    @Query() filter: QDTO_group,
+    @Query('skip') skip: number,
+    @Query('limit') limit: number
+  ) {
+    const list = await this.service.query(filter, { skip, limit });
+    const data = [];
+    for (const i of list) {
+      const newData = new QVO_group(i);
+      data.push(newData);
+    }
+    const total = await this.service.count(filter);
+    return { data, total };
+  }
+
+  @Get('/:id')
+  @ApiResponse({ type: FVO_group })
+  async fetch(@Param('id') id: string) {
+    const data = await this.service.fetch(id);
+    const result = new FVO_group(data);
+    return result;
+  }
+
+  @Post('/:id')
+  @Validate()
+  @ApiResponse({ type: UVAO_group })
+  async update(@Param('id') id: string, @Body() body: UDTO_group) {
+    const result = await this.service.updateOne(id, body);
+    return result;
+  }
+
+  @Del('/:id')
+  @Validate()
+  async delete(@Param('id') id: string) {
+    await this.service.delete(id);
+    return 'ok';
+  }
+  async createMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+
+  async updateMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+
+  async deleteMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+}

+ 9 - 0
src/controller/home.controller.ts

@@ -0,0 +1,9 @@
+import { Controller, Get } from '@midwayjs/core';
+
+@Controller('/')
+export class HomeController {
+  @Get('/')
+  async home(): Promise<string> {
+    return 'Hello Midwayjs!';
+  }
+}

+ 89 - 0
src/controller/menus.controller.ts

@@ -0,0 +1,89 @@
+import {
+  Body,
+  Controller,
+  Del,
+  Get,
+  Inject,
+  Param,
+  Post,
+  Query,
+} from '@midwayjs/decorator';
+import { BaseController } from 'free-midway-component';
+import { MenusService } from '../service/menus.service';
+import {
+  CDTO_menus,
+  CVO_menus,
+  FVO_menus,
+  QDTO_menus,
+  QVO_menus,
+  UDTO_menus,
+  UVAO_menus,
+} from '../interface/menus.interface';
+import { ApiResponse, ApiTags, ApiQuery } from '@midwayjs/swagger';
+import { Validate } from '@midwayjs/validate';
+@ApiTags(['菜单'])
+@Controller('/menus')
+export class MenusController extends BaseController {
+  @Inject()
+  service: MenusService;
+
+  @Post('/')
+  @Validate()
+  @ApiResponse({ type: CVO_menus })
+  async create(@Body() data: CDTO_menus) {
+    const dbData = await this.service.create(data);
+    const result = new CVO_menus(dbData);
+    return result;
+  }
+  @Get('/')
+  @ApiQuery({ name: 'query' })
+  @ApiResponse({ type: QVO_menus })
+  async query(
+    @Query() filter: QDTO_menus,
+    @Query('skip') skip: number,
+    @Query('limit') limit: number
+  ) {
+    const list = await this.service.query(filter, { skip, limit });
+    const data = [];
+    for (const i of list) {
+      const newData = new QVO_menus(i);
+      data.push(newData);
+    }
+    const total = await this.service.count(filter);
+    return { data, total };
+  }
+
+  @Get('/:id')
+  @ApiResponse({ type: FVO_menus })
+  async fetch(@Param('id') id: string) {
+    const data = await this.service.fetch(id);
+    const result = new FVO_menus(data);
+    return result;
+  }
+
+  @Post('/:id')
+  @Validate()
+  @ApiResponse({ type: UVAO_menus })
+  async update(@Param('id') id: string, @Body() body: UDTO_menus) {
+    const result = await this.service.updateOne(id, body);
+    return result;
+  }
+
+  @Del('/:id')
+  @Validate()
+  async delete(@Param('id') id: string) {
+    await this.service.delete(id);
+    return 'ok';
+  }
+  async createMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+
+  async updateMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+
+  async deleteMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+}

+ 89 - 0
src/controller/nurse.controller.ts

@@ -0,0 +1,89 @@
+import {
+  Body,
+  Controller,
+  Del,
+  Get,
+  Inject,
+  Param,
+  Post,
+  Query,
+} from '@midwayjs/decorator';
+import { BaseController } from 'free-midway-component';
+import { NurseService } from '../service/nurse.service';
+import {
+  CDTO_nurse,
+  CVO_nurse,
+  FVO_nurse,
+  QDTO_nurse,
+  QVO_nurse,
+  UDTO_nurse,
+  UVAO_nurse,
+} from '../interface/nurse.interface';
+import { ApiResponse, ApiTags, ApiQuery } from '@midwayjs/swagger';
+import { Validate } from '@midwayjs/validate';
+@ApiTags(['护士'])
+@Controller('/nurse')
+export class NurseController extends BaseController {
+  @Inject()
+  service: NurseService;
+
+  @Post('/')
+  @Validate()
+  @ApiResponse({ type: CVO_nurse })
+  async create(@Body() data: CDTO_nurse) {
+    const dbData = await this.service.create(data);
+    const result = new CVO_nurse(dbData);
+    return result;
+  }
+  @Get('/')
+  @ApiQuery({ name: 'query' })
+  @ApiResponse({ type: QVO_nurse })
+  async query(
+    @Query() filter: QDTO_nurse,
+    @Query('skip') skip: number,
+    @Query('limit') limit: number
+  ) {
+    const list = await this.service.query(filter, { skip, limit });
+    const data = [];
+    for (const i of list) {
+      const newData = new QVO_nurse(i);
+      data.push(newData);
+    }
+    const total = await this.service.count(filter);
+    return { data, total };
+  }
+
+  @Get('/:id')
+  @ApiResponse({ type: FVO_nurse })
+  async fetch(@Param('id') id: string) {
+    const data = await this.service.fetch(id);
+    const result = new FVO_nurse(data);
+    return result;
+  }
+
+  @Post('/:id')
+  @Validate()
+  @ApiResponse({ type: UVAO_nurse })
+  async update(@Param('id') id: string, @Body() body: UDTO_nurse) {
+    const result = await this.service.updateOne(id, body);
+    return result;
+  }
+
+  @Del('/:id')
+  @Validate()
+  async delete(@Param('id') id: string) {
+    await this.service.delete(id);
+    return 'ok';
+  }
+  async createMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+
+  async updateMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+
+  async deleteMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+}

+ 89 - 0
src/controller/patient.controller.ts

@@ -0,0 +1,89 @@
+import {
+  Body,
+  Controller,
+  Del,
+  Get,
+  Inject,
+  Param,
+  Post,
+  Query,
+} from '@midwayjs/decorator';
+import { BaseController } from 'free-midway-component';
+import { PatientService } from '../service/patient.service';
+import {
+  CDTO_patient,
+  CVO_patient,
+  FVO_patient,
+  QDTO_patient,
+  QVO_patient,
+  UDTO_patient,
+  UVAO_patient,
+} from '../interface/patient.interface';
+import { ApiResponse, ApiTags, ApiQuery } from '@midwayjs/swagger';
+import { Validate } from '@midwayjs/validate';
+@ApiTags(['病人'])
+@Controller('/patient')
+export class PatientController extends BaseController {
+  @Inject()
+  service: PatientService;
+
+  @Post('/')
+  @Validate()
+  @ApiResponse({ type: CVO_patient })
+  async create(@Body() data: CDTO_patient) {
+    const dbData = await this.service.create(data);
+    const result = new CVO_patient(dbData);
+    return result;
+  }
+  @Get('/')
+  @ApiQuery({ name: 'query' })
+  @ApiResponse({ type: QVO_patient })
+  async query(
+    @Query() filter: QDTO_patient,
+    @Query('skip') skip: number,
+    @Query('limit') limit: number
+  ) {
+    const list = await this.service.query(filter, { skip, limit });
+    const data = [];
+    for (const i of list) {
+      const newData = new QVO_patient(i);
+      data.push(newData);
+    }
+    const total = await this.service.count(filter);
+    return { data, total };
+  }
+
+  @Get('/:id')
+  @ApiResponse({ type: FVO_patient })
+  async fetch(@Param('id') id: string) {
+    const data = await this.service.fetch(id);
+    const result = new FVO_patient(data);
+    return result;
+  }
+
+  @Post('/:id')
+  @Validate()
+  @ApiResponse({ type: UVAO_patient })
+  async update(@Param('id') id: string, @Body() body: UDTO_patient) {
+    const result = await this.service.updateOne(id, body);
+    return result;
+  }
+
+  @Del('/:id')
+  @Validate()
+  async delete(@Param('id') id: string) {
+    await this.service.delete(id);
+    return 'ok';
+  }
+  async createMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+
+  async updateMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+
+  async deleteMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+}

+ 89 - 0
src/controller/role.controller.ts

@@ -0,0 +1,89 @@
+import {
+  Body,
+  Controller,
+  Del,
+  Get,
+  Inject,
+  Param,
+  Post,
+  Query,
+} from '@midwayjs/decorator';
+import { BaseController } from 'free-midway-component';
+import { RoleService } from '../service/role.service';
+import {
+  CDTO_role,
+  CVO_role,
+  FVO_role,
+  QDTO_role,
+  QVO_role,
+  UDTO_role,
+  UVAO_role,
+} from '../interface/role.interface';
+import { ApiResponse, ApiTags, ApiQuery } from '@midwayjs/swagger';
+import { Validate } from '@midwayjs/validate';
+@ApiTags(['角色'])
+@Controller('/role')
+export class RoleController extends BaseController {
+  @Inject()
+  service: RoleService;
+
+  @Post('/')
+  @Validate()
+  @ApiResponse({ type: CVO_role })
+  async create(@Body() data: CDTO_role) {
+    const dbData = await this.service.create(data);
+    const result = new CVO_role(dbData);
+    return result;
+  }
+  @Get('/')
+  @ApiQuery({ name: 'query' })
+  @ApiResponse({ type: QVO_role })
+  async query(
+    @Query() filter: QDTO_role,
+    @Query('skip') skip: number,
+    @Query('limit') limit: number
+  ) {
+    const list = await this.service.query(filter, { skip, limit });
+    const data = [];
+    for (const i of list) {
+      const newData = new QVO_role(i);
+      data.push(newData);
+    }
+    const total = await this.service.count(filter);
+    return { data, total };
+  }
+
+  @Get('/:id')
+  @ApiResponse({ type: FVO_role })
+  async fetch(@Param('id') id: string) {
+    const data = await this.service.fetch(id);
+    const result = new FVO_role(data);
+    return result;
+  }
+
+  @Post('/:id')
+  @Validate()
+  @ApiResponse({ type: UVAO_role })
+  async update(@Param('id') id: string, @Body() body: UDTO_role) {
+    const result = await this.service.updateOne(id, body);
+    return result;
+  }
+
+  @Del('/:id')
+  @Validate()
+  async delete(@Param('id') id: string) {
+    await this.service.delete(id);
+    return 'ok';
+  }
+  async createMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+
+  async updateMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+
+  async deleteMany(...args: any[]) {
+    throw new Error('Method not implemented.');
+  }
+}

+ 32 - 0
src/entity/admin.entity.ts

@@ -0,0 +1,32 @@
+import { modelOptions, prop } from '@typegoose/typegoose';
+import { BaseModel } from 'free-midway-component';
+import { isString } from 'lodash';
+@modelOptions({
+  schemaOptions: { collection: 'admin' },
+})
+export class Admin extends BaseModel {
+  @prop({ required: false, index: false, zh: '账号' })
+  account: string;
+  @prop({
+    required: false,
+    index: false,
+    zh: '密码',
+    select: false,
+    set: (val: string | object) => {
+      if (isString(val)) {
+        return { secret: val };
+      }
+      return val;
+    },
+  })
+  password: {
+    secret: string;
+  };
+  @prop({
+    required: false,
+    index: false,
+    zh: '系统使用名',
+    default: '系统管理员',
+  })
+  name: string;
+}

+ 11 - 0
src/entity/adv.entity.ts

@@ -0,0 +1,11 @@
+import { modelOptions, prop } from '@typegoose/typegoose';
+import { BaseModel } from 'free-midway-component';
+@modelOptions({
+  schemaOptions: { collection: 'adv' },
+})
+export class Adv extends BaseModel {
+  @prop({ required: false, index: false, zh: '图片', remark: 'File类型' })
+  image: string;
+  @prop({ required: false, index: false, zh: '跳转位置' })
+  url: string;
+}

+ 28 - 0
src/entity/article.entity.ts

@@ -0,0 +1,28 @@
+import { modelOptions, prop } from '@typegoose/typegoose';
+import { BaseModel } from 'free-midway-component';
+@modelOptions({
+  schemaOptions: { collection: 'article' },
+})
+export class Article extends BaseModel {
+  @prop({ required: false, index: false, zh: '标题' })
+  title: string;
+  @prop({ required: false, index: true, zh: '医生' })
+  doctor: string;
+  @prop({ required: false, index: false, zh: '来源' })
+  origin: string;
+  @prop({
+    required: false,
+    index: false,
+    zh: '图片',
+    remark: '这个不是文件,就是字符串地址',
+  })
+  img_url: string;
+  @prop({ required: false, index: false, zh: '简介' })
+  brief: string;
+  @prop({ required: false, index: false, zh: '内容' })
+  content: string;
+  @prop({ required: false, index: false, zh: '附件', remark: 'File类型' })
+  files: string;
+  @prop({ required: false, index: false, zh: '备注' })
+  remark: string;
+}

+ 15 - 0
src/entity/chat.entity.ts

@@ -0,0 +1,15 @@
+import { modelOptions, prop } from '@typegoose/typegoose';
+import { BaseModel } from 'free-midway-component';
+@modelOptions({
+  schemaOptions: { collection: 'chat' },
+})
+export class Chat extends BaseModel {
+  @prop({ required: false, index: true, zh: '医护回答人' })
+  doctor_nurse: string;
+  @prop({ required: false, index: true, zh: '患者' })
+  patient: string;
+  @prop({ required: false, index: true, zh: '群组' })
+  group: string;
+  @prop({ required: false, index: false, zh: '内容' })
+  content: string;
+}

+ 48 - 0
src/entity/doctor.entity.ts

@@ -0,0 +1,48 @@
+import { modelOptions, prop } from '@typegoose/typegoose';
+import { BaseModel } from 'free-midway-component';
+import { isString } from 'lodash';
+@modelOptions({
+  schemaOptions: { collection: 'doctor' },
+})
+export class Doctor extends BaseModel {
+  @prop({ required: false, index: true, zh: '姓名' })
+  name: string;
+  @prop({ required: false, index: false, zh: '头像', remark: '文件类型' })
+  icon: string;
+  @prop({ required: false, index: false, zh: '手机' })
+  mobile: string;
+  @prop({
+    required: false,
+    index: false,
+    zh: '密码',
+    select: false,
+    set: (val: string | object) => {
+      if (isString(val)) {
+        return { secret: val };
+      }
+      return val;
+    },
+  })
+  password: {
+    secret: string;
+  };
+  @prop({ required: false, index: false, zh: '医院名称' })
+  hos_name: string;
+  @prop({ required: false, index: false, zh: '科室名称' })
+  dept_name: string;
+  @prop({ required: false, index: false, zh: '职务' })
+  title: string;
+  @prop({ required: false, index: false, zh: '职称' })
+  post: string;
+  @prop({ required: false, index: false, zh: '简介' })
+  content: string;
+  @prop({ required: false, index: false, zh: '微信openid', remark: '小程序的' })
+  openid: string;
+  @prop({
+    required: false,
+    index: true,
+    zh: '账号',
+    remark: '默认手机号,如果填写,则按填写的来',
+  })
+  account: string;
+}

+ 15 - 0
src/entity/group.entity.ts

@@ -0,0 +1,15 @@
+import { modelOptions, prop } from '@typegoose/typegoose';
+import { BaseModel } from 'free-midway-component';
+@modelOptions({
+  schemaOptions: { collection: 'group' },
+})
+export class Group extends BaseModel {
+  @prop({ required: false, index: true, zh: '管理医生', ref: 'Doctor' })
+  doctor: string;
+  @prop({ required: false, index: true, zh: '群组病人', remark: '病人id列表' })
+  patients: Array<any>;
+  @prop({ required: false, index: false, zh: '群组名称' })
+  name: string;
+  @prop({ required: false, index: false, zh: '群简介' })
+  content: string;
+}

+ 27 - 0
src/entity/menus.entity.ts

@@ -0,0 +1,27 @@
+import { modelOptions, prop } from '@typegoose/typegoose';
+import { BaseModel } from 'free-midway-component';
+@modelOptions({
+  schemaOptions: { collection: 'menus' },
+})
+export class Menus extends BaseModel {
+  @prop({ required: false, index: true, zh: '菜单名称' })
+  name: string;
+  @prop({ required: false, index: true, zh: '角色' })
+  role_id: string;
+  @prop({ required: false, index: true, zh: '父级菜单' })
+  parent_id: string;
+  @prop({ required: false, index: false, zh: '显示顺序' })
+  order_num: number;
+  @prop({ required: false, index: false, zh: '路由地址' })
+  path: string;
+  @prop({ required: false, index: false, zh: '组件地址' })
+  component: string;
+  @prop({ required: false, index: true, zh: '菜单类型' })
+  type: string;
+  @prop({ required: false, index: false, zh: '图标' })
+  icon: string;
+  @prop({ required: false, index: false, zh: '备注' })
+  remark: string;
+  @prop({ required: false, index: true, zh: '是否启用', default: '0' })
+  is_use: string;
+}

+ 50 - 0
src/entity/nurse.entity.ts

@@ -0,0 +1,50 @@
+import { modelOptions, prop } from '@typegoose/typegoose';
+import { BaseModel } from 'free-midway-component';
+import { isString } from 'lodash';
+@modelOptions({
+  schemaOptions: { collection: 'nurse' },
+})
+export class Nurse extends BaseModel {
+  @prop({ required: false, index: true, zh: '名称' })
+  name: string;
+  @prop({ required: false, index: false, zh: '头像', remark: '文件类型' })
+  icon: string;
+  @prop({ required: false, index: false, zh: '手机' })
+  mobile: string;
+  @prop({
+    required: false,
+    index: false,
+    zh: '密码',
+    select: false,
+    set: (val: string | object) => {
+      if (isString(val)) {
+        return { secret: val };
+      }
+      return val;
+    },
+  })
+  password: {
+    secret: string;
+  };
+  @prop({ required: false, index: false, zh: '医院名称' })
+  hos_name: string;
+  @prop({ required: false, index: false, zh: '部门名称' })
+  dept_name: string;
+  @prop({ required: true, index: false, zh: '所属医生', ref: 'Doctor' })
+  doctor: string;
+  @prop({ required: false, index: false, zh: '职务' })
+  title: string;
+  @prop({ required: false, index: false, zh: '职称' })
+  post: string;
+  @prop({ required: false, index: false, zh: '简介' })
+  content: string;
+  @prop({ required: false, index: false, zh: '微信openid', remark: '小程序的' })
+  openid: string;
+  @prop({
+    required: false,
+    index: true,
+    zh: '账号',
+    remark: '默认为手机号.如果填写,则按填写的来',
+  })
+  account: string;
+}

+ 34 - 0
src/entity/patient.entity.ts

@@ -0,0 +1,34 @@
+import { modelOptions, prop } from '@typegoose/typegoose';
+import { BaseModel } from 'free-midway-component';
+@modelOptions({
+  schemaOptions: { collection: 'patient' },
+})
+export class Patient extends BaseModel {
+  @prop({ required: false, index: true, zh: '姓名' })
+  name: string;
+  @prop({ required: false, index: false, zh: '头像', remark: 'FIle类型' })
+  icon: string;
+  @prop({ required: false, index: false, zh: '就诊编号/卡号' })
+  card_no: string;
+  @prop({ required: false, index: false, zh: '性别' })
+  gender: string;
+  @prop({ required: false, index: false, zh: '年龄' })
+  age: number;
+  @prop({ required: false, index: false, zh: '住址' })
+  address: string;
+  @prop({ required: false, index: false, zh: '手机' })
+  mobile: string;
+  @prop({ required: false, index: false, zh: '紧急联系人' })
+  urgent_name: string;
+  @prop({ required: false, index: false, zh: '紧急联系人手机' })
+  urgent_mobile: string;
+  @prop({ required: false, index: false, zh: '病例' })
+  emrs: Array<any>;
+  @prop({
+    required: false,
+    index: true,
+    zh: '微信openid',
+    remark: '微信小程序的',
+  })
+  openid: string;
+}

+ 17 - 0
src/entity/role.entity.ts

@@ -0,0 +1,17 @@
+import { modelOptions, prop } from '@typegoose/typegoose';
+import { BaseModel } from 'free-midway-component';
+@modelOptions({
+  schemaOptions: { collection: 'role' },
+})
+export class Role extends BaseModel {
+  @prop({ required: false, index: true, zh: '角色名称' })
+  name: string;
+  @prop({ required: false, index: true, zh: '角色编码' })
+  code: string;
+  @prop({ required: false, index: false, zh: '菜单' })
+  menu: string;
+  @prop({ required: false, index: false, zh: '简介' })
+  brief: string;
+  @prop({ required: false, index: true, zh: '是否使用', default: '0' })
+  is_use: string;
+}

+ 6 - 0
src/interface.ts

@@ -0,0 +1,6 @@
+/**
+ * @description User-Service parameters
+ */
+export interface IUserOptions {
+  uid: number;
+}

+ 71 - 0
src/interface/admin.interface.ts

@@ -0,0 +1,71 @@
+import { Rule, RuleType } from '@midwayjs/validate';
+import { ApiProperty } from '@midwayjs/swagger';
+import { SearchBase } from 'free-midway-component';
+import get = require('lodash/get');
+const dealVO = (cla, data) => {
+  for (const key in cla) {
+    const val = get(data, key);
+    if (val || val === 0) cla[key] = val;
+  }
+};
+export class FVO_admin {
+  constructor(data: object) {
+    dealVO(this, data);
+  }
+  @ApiProperty({ description: '数据id' })
+  _id: string = undefined;
+  @ApiProperty({ description: '账号' })
+  'account': string = undefined;
+  @ApiProperty({ description: '密码' })
+  'password': string = undefined;
+  @ApiProperty({ description: '系统使用名' })
+  'name': string = undefined;
+}
+
+export class QDTO_admin extends SearchBase {
+  constructor() {
+    const like_prop = [];
+    const props = [];
+    const mapping = [];
+    super({ like_prop, props, mapping });
+  }
+}
+
+export class QVO_admin extends FVO_admin {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}
+
+export class CDTO_admin {
+  @ApiProperty({ description: '账号' })
+  @Rule(RuleType['string']().empty(''))
+  'account': string = undefined;
+  @ApiProperty({ description: '密码' })
+  @Rule(RuleType['string']().empty(''))
+  'password': string = undefined;
+  @ApiProperty({ description: '系统使用名' })
+  @Rule(RuleType['string']().empty(''))
+  'name': string = undefined;
+}
+
+export class CVO_admin extends FVO_admin {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}
+
+export class UDTO_admin extends CDTO_admin {
+  @ApiProperty({ description: '数据id' })
+  @Rule(RuleType['string']().empty(''))
+  _id: string = undefined;
+}
+
+export class UVAO_admin extends FVO_admin {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}

+ 66 - 0
src/interface/adv.interface.ts

@@ -0,0 +1,66 @@
+import { Rule, RuleType } from '@midwayjs/validate';
+import { ApiProperty } from '@midwayjs/swagger';
+import { SearchBase } from 'free-midway-component';
+import get = require('lodash/get');
+const dealVO = (cla, data) => {
+  for (const key in cla) {
+    const val = get(data, key);
+    if (val || val === 0) cla[key] = val;
+  }
+};
+export class FVO_adv {
+  constructor(data: object) {
+    dealVO(this, data);
+  }
+  @ApiProperty({ description: '数据id' })
+  _id: string = undefined;
+  @ApiProperty({ description: '图片' })
+  'image': string = undefined;
+  @ApiProperty({ description: '跳转位置' })
+  'url': string = undefined;
+}
+
+export class QDTO_adv extends SearchBase {
+  constructor() {
+    const like_prop = [];
+    const props = [];
+    const mapping = [];
+    super({ like_prop, props, mapping });
+  }
+}
+
+export class QVO_adv extends FVO_adv {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}
+
+export class CDTO_adv {
+  @ApiProperty({ description: '图片' })
+  @Rule(RuleType['string']().empty(''))
+  'image': string = undefined;
+  @ApiProperty({ description: '跳转位置' })
+  @Rule(RuleType['string']().empty(''))
+  'url': string = undefined;
+}
+
+export class CVO_adv extends FVO_adv {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}
+
+export class UDTO_adv extends CDTO_adv {
+  @ApiProperty({ description: '数据id' })
+  @Rule(RuleType['string']().empty(''))
+  _id: string = undefined;
+}
+
+export class UVAO_adv extends FVO_adv {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}

+ 98 - 0
src/interface/article.interface.ts

@@ -0,0 +1,98 @@
+import { Rule, RuleType } from '@midwayjs/validate';
+import { ApiProperty } from '@midwayjs/swagger';
+import { SearchBase } from 'free-midway-component';
+import get = require('lodash/get');
+const dealVO = (cla, data) => {
+  for (const key in cla) {
+    const val = get(data, key);
+    if (val || val === 0) cla[key] = val;
+  }
+};
+export class FVO_article {
+  constructor(data: object) {
+    dealVO(this, data);
+  }
+  @ApiProperty({ description: '数据id' })
+  _id: string = undefined;
+  @ApiProperty({ description: '标题' })
+  'title': string = undefined;
+  @ApiProperty({ description: '医生' })
+  'doctor': string = undefined;
+  @ApiProperty({ description: '来源' })
+  'origin': string = undefined;
+  @ApiProperty({ description: '图片' })
+  'img_url': string = undefined;
+  @ApiProperty({ description: '简介' })
+  'brief': string = undefined;
+  @ApiProperty({ description: '内容' })
+  'content': string = undefined;
+  @ApiProperty({ description: '附件' })
+  'files': string = undefined;
+  @ApiProperty({ description: '备注' })
+  'remark': string = undefined;
+}
+
+export class QDTO_article extends SearchBase {
+  constructor() {
+    const like_prop = [];
+    const props = ['doctor'];
+    const mapping = [];
+    super({ like_prop, props, mapping });
+  }
+  @ApiProperty({ description: '医生' })
+  'doctor': string = undefined;
+}
+
+export class QVO_article extends FVO_article {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}
+
+export class CDTO_article {
+  @ApiProperty({ description: '标题' })
+  @Rule(RuleType['string']().empty(''))
+  'title': string = undefined;
+  @ApiProperty({ description: '医生' })
+  @Rule(RuleType['string']().empty(''))
+  'doctor': string = undefined;
+  @ApiProperty({ description: '来源' })
+  @Rule(RuleType['string']().empty(''))
+  'origin': string = undefined;
+  @ApiProperty({ description: '图片' })
+  @Rule(RuleType['string']().empty(''))
+  'img_url': string = undefined;
+  @ApiProperty({ description: '简介' })
+  @Rule(RuleType['string']().empty(''))
+  'brief': string = undefined;
+  @ApiProperty({ description: '内容' })
+  @Rule(RuleType['string']().empty(''))
+  'content': string = undefined;
+  @ApiProperty({ description: '附件' })
+  @Rule(RuleType['string']().empty(''))
+  'files': string = undefined;
+  @ApiProperty({ description: '备注' })
+  @Rule(RuleType['string']().empty(''))
+  'remark': string = undefined;
+}
+
+export class CVO_article extends FVO_article {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}
+
+export class UDTO_article extends CDTO_article {
+  @ApiProperty({ description: '数据id' })
+  @Rule(RuleType['string']().empty(''))
+  _id: string = undefined;
+}
+
+export class UVAO_article extends FVO_article {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}

+ 82 - 0
src/interface/chat.interface.ts

@@ -0,0 +1,82 @@
+import { Rule, RuleType } from '@midwayjs/validate';
+import { ApiProperty } from '@midwayjs/swagger';
+import { SearchBase } from 'free-midway-component';
+import get = require('lodash/get');
+const dealVO = (cla, data) => {
+  for (const key in cla) {
+    const val = get(data, key);
+    if (val || val === 0) cla[key] = val;
+  }
+};
+export class FVO_chat {
+  constructor(data: object) {
+    dealVO(this, data);
+  }
+  @ApiProperty({ description: '数据id' })
+  _id: string = undefined;
+  @ApiProperty({ description: '医护回答人' })
+  'doctor_nurse': string = undefined;
+  @ApiProperty({ description: '患者' })
+  'patient': string = undefined;
+  @ApiProperty({ description: '群组' })
+  'group': string = undefined;
+  @ApiProperty({ description: '内容' })
+  'content': string = undefined;
+}
+
+export class QDTO_chat extends SearchBase {
+  constructor() {
+    const like_prop = [];
+    const props = ['doctor_nurse', 'patient', 'group'];
+    const mapping = [];
+    super({ like_prop, props, mapping });
+  }
+  @ApiProperty({ description: '医护回答人' })
+  'doctor_nurse': string = undefined;
+  @ApiProperty({ description: '患者' })
+  'patient': string = undefined;
+  @ApiProperty({ description: '群组' })
+  'group': string = undefined;
+}
+
+export class QVO_chat extends FVO_chat {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}
+
+export class CDTO_chat {
+  @ApiProperty({ description: '医护回答人' })
+  @Rule(RuleType['string']().empty(''))
+  'doctor_nurse': string = undefined;
+  @ApiProperty({ description: '患者' })
+  @Rule(RuleType['string']().empty(''))
+  'patient': string = undefined;
+  @ApiProperty({ description: '群组' })
+  @Rule(RuleType['string']().empty(''))
+  'group': string = undefined;
+  @ApiProperty({ description: '内容' })
+  @Rule(RuleType['string']().empty(''))
+  'content': string = undefined;
+}
+
+export class CVO_chat extends FVO_chat {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}
+
+export class UDTO_chat extends CDTO_chat {
+  @ApiProperty({ description: '数据id' })
+  @Rule(RuleType['string']().empty(''))
+  _id: string = undefined;
+}
+
+export class UVAO_chat extends FVO_chat {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}

+ 115 - 0
src/interface/doctor.interface.ts

@@ -0,0 +1,115 @@
+import { Rule, RuleType } from '@midwayjs/validate';
+import { ApiProperty } from '@midwayjs/swagger';
+import { SearchBase } from 'free-midway-component';
+import get = require('lodash/get');
+const dealVO = (cla, data) => {
+  for (const key in cla) {
+    const val = get(data, key);
+    if (val || val === 0) cla[key] = val;
+  }
+};
+export class FVO_doctor {
+  constructor(data: object) {
+    dealVO(this, data);
+  }
+  @ApiProperty({ description: '数据id' })
+  _id: string = undefined;
+  @ApiProperty({ description: '姓名' })
+  'name': string = undefined;
+  @ApiProperty({ description: '头像' })
+  'icon': string = undefined;
+  @ApiProperty({ description: '手机' })
+  'mobile': string = undefined;
+  @ApiProperty({ description: '密码' })
+  'password': string = undefined;
+  @ApiProperty({ description: '医院名称' })
+  'hos_name': string = undefined;
+  @ApiProperty({ description: '科室名称' })
+  'dept_name': string = undefined;
+  @ApiProperty({ description: '职务' })
+  'title': string = undefined;
+  @ApiProperty({ description: '职称' })
+  'post': string = undefined;
+  @ApiProperty({ description: '简介' })
+  'content': string = undefined;
+  @ApiProperty({ description: '微信openid' })
+  'openid': string = undefined;
+  @ApiProperty({ description: '账号' })
+  'account': string = undefined;
+}
+
+export class QDTO_doctor extends SearchBase {
+  constructor() {
+    const like_prop = [];
+    const props = ['name', 'account'];
+    const mapping = [];
+    super({ like_prop, props, mapping });
+  }
+  @ApiProperty({ description: '姓名' })
+  'name': string = undefined;
+  @ApiProperty({ description: '账号' })
+  'account': string = undefined;
+}
+
+export class QVO_doctor extends FVO_doctor {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}
+
+export class CDTO_doctor {
+  @ApiProperty({ description: '姓名' })
+  @Rule(RuleType['string']().empty(''))
+  'name': string = undefined;
+  @ApiProperty({ description: '头像' })
+  @Rule(RuleType['string']().empty(''))
+  'icon': string = undefined;
+  @ApiProperty({ description: '手机' })
+  @Rule(RuleType['string']().empty(''))
+  'mobile': string = undefined;
+  @ApiProperty({ description: '密码' })
+  @Rule(RuleType['string']().empty(''))
+  'password': string = undefined;
+  @ApiProperty({ description: '医院名称' })
+  @Rule(RuleType['string']().empty(''))
+  'hos_name': string = undefined;
+  @ApiProperty({ description: '科室名称' })
+  @Rule(RuleType['string']().empty(''))
+  'dept_name': string = undefined;
+  @ApiProperty({ description: '职务' })
+  @Rule(RuleType['string']().empty(''))
+  'title': string = undefined;
+  @ApiProperty({ description: '职称' })
+  @Rule(RuleType['string']().empty(''))
+  'post': string = undefined;
+  @ApiProperty({ description: '简介' })
+  @Rule(RuleType['string']().empty(''))
+  'content': string = undefined;
+  @ApiProperty({ description: '微信openid' })
+  @Rule(RuleType['string']().empty(''))
+  'openid': string = undefined;
+  @ApiProperty({ description: '账号' })
+  @Rule(RuleType['string']().empty(''))
+  'account': string = undefined;
+}
+
+export class CVO_doctor extends FVO_doctor {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}
+
+export class UDTO_doctor extends CDTO_doctor {
+  @ApiProperty({ description: '数据id' })
+  @Rule(RuleType['string']().empty(''))
+  _id: string = undefined;
+}
+
+export class UVAO_doctor extends FVO_doctor {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}

+ 80 - 0
src/interface/group.interface.ts

@@ -0,0 +1,80 @@
+import { Rule, RuleType } from '@midwayjs/validate';
+import { ApiProperty } from '@midwayjs/swagger';
+import { SearchBase } from 'free-midway-component';
+import get = require('lodash/get');
+const dealVO = (cla, data) => {
+  for (const key in cla) {
+    const val = get(data, key);
+    if (val || val === 0) cla[key] = val;
+  }
+};
+export class FVO_group {
+  constructor(data: object) {
+    dealVO(this, data);
+  }
+  @ApiProperty({ description: '数据id' })
+  _id: string = undefined;
+  @ApiProperty({ description: '管理医生' })
+  'doctor': string = undefined;
+  @ApiProperty({ description: '群组病人' })
+  'patients': Array<any> = undefined;
+  @ApiProperty({ description: '群组名称' })
+  'name': string = undefined;
+  @ApiProperty({ description: '群简介' })
+  'content': string = undefined;
+}
+
+export class QDTO_group extends SearchBase {
+  constructor() {
+    const like_prop = [];
+    const props = ['doctor', 'patients'];
+    const mapping = [];
+    super({ like_prop, props, mapping });
+  }
+  @ApiProperty({ description: '管理医生' })
+  'doctor': string = undefined;
+  @ApiProperty({ description: '群组病人' })
+  'patients': Array<any> = undefined;
+}
+
+export class QVO_group extends FVO_group {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}
+
+export class CDTO_group {
+  @ApiProperty({ description: '管理医生' })
+  @Rule(RuleType['string']().empty(''))
+  'doctor': string = undefined;
+  @ApiProperty({ description: '群组病人' })
+  @Rule(RuleType['array']().empty(''))
+  'patients': Array<any> = undefined;
+  @ApiProperty({ description: '群组名称' })
+  @Rule(RuleType['string']().empty(''))
+  'name': string = undefined;
+  @ApiProperty({ description: '群简介' })
+  @Rule(RuleType['string']().empty(''))
+  'content': string = undefined;
+}
+
+export class CVO_group extends FVO_group {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}
+
+export class UDTO_group extends CDTO_group {
+  @ApiProperty({ description: '数据id' })
+  @Rule(RuleType['string']().empty(''))
+  _id: string = undefined;
+}
+
+export class UVAO_group extends FVO_group {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}

+ 116 - 0
src/interface/menus.interface.ts

@@ -0,0 +1,116 @@
+import { Rule, RuleType } from '@midwayjs/validate';
+import { ApiProperty } from '@midwayjs/swagger';
+import { SearchBase } from 'free-midway-component';
+import get = require('lodash/get');
+const dealVO = (cla, data) => {
+  for (const key in cla) {
+    const val = get(data, key);
+    if (val || val === 0) cla[key] = val;
+  }
+};
+export class FVO_menus {
+  constructor(data: object) {
+    dealVO(this, data);
+  }
+  @ApiProperty({ description: '数据id' })
+  _id: string = undefined;
+  @ApiProperty({ description: '菜单名称' })
+  'name': string = undefined;
+  @ApiProperty({ description: '角色' })
+  'role_id': string = undefined;
+  @ApiProperty({ description: '父级菜单' })
+  'parent_id': string = undefined;
+  @ApiProperty({ description: '显示顺序' })
+  'order_num': number = undefined;
+  @ApiProperty({ description: '路由地址' })
+  'path': string = undefined;
+  @ApiProperty({ description: '组件地址' })
+  'component': string = undefined;
+  @ApiProperty({ description: '菜单类型' })
+  'type': string = undefined;
+  @ApiProperty({ description: '图标' })
+  'icon': string = undefined;
+  @ApiProperty({ description: '备注' })
+  'remark': string = undefined;
+  @ApiProperty({ description: '是否启用' })
+  'is_use': string = undefined;
+}
+
+export class QDTO_menus extends SearchBase {
+  constructor() {
+    const like_prop = [];
+    const props = ['name', 'role_id', 'parent_id', 'type', 'is_use'];
+    const mapping = [];
+    super({ like_prop, props, mapping });
+  }
+  @ApiProperty({ description: '菜单名称' })
+  'name': string = undefined;
+  @ApiProperty({ description: '角色' })
+  'role_id': string = undefined;
+  @ApiProperty({ description: '父级菜单' })
+  'parent_id': string = undefined;
+  @ApiProperty({ description: '菜单类型' })
+  'type': string = undefined;
+  @ApiProperty({ description: '是否启用' })
+  'is_use': string = undefined;
+}
+
+export class QVO_menus extends FVO_menus {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}
+
+export class CDTO_menus {
+  @ApiProperty({ description: '菜单名称' })
+  @Rule(RuleType['string']().empty(''))
+  'name': string = undefined;
+  @ApiProperty({ description: '角色' })
+  @Rule(RuleType['string']().empty(''))
+  'role_id': string = undefined;
+  @ApiProperty({ description: '父级菜单' })
+  @Rule(RuleType['string']().empty(''))
+  'parent_id': string = undefined;
+  @ApiProperty({ description: '显示顺序' })
+  @Rule(RuleType['number']().empty(''))
+  'order_num': number = undefined;
+  @ApiProperty({ description: '路由地址' })
+  @Rule(RuleType['string']().empty(''))
+  'path': string = undefined;
+  @ApiProperty({ description: '组件地址' })
+  @Rule(RuleType['string']().empty(''))
+  'component': string = undefined;
+  @ApiProperty({ description: '菜单类型' })
+  @Rule(RuleType['string']().empty(''))
+  'type': string = undefined;
+  @ApiProperty({ description: '图标' })
+  @Rule(RuleType['string']().empty(''))
+  'icon': string = undefined;
+  @ApiProperty({ description: '备注' })
+  @Rule(RuleType['string']().empty(''))
+  'remark': string = undefined;
+  @ApiProperty({ description: '是否启用' })
+  @Rule(RuleType['string']().empty(''))
+  'is_use': string = undefined;
+}
+
+export class CVO_menus extends FVO_menus {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}
+
+export class UDTO_menus extends CDTO_menus {
+  @ApiProperty({ description: '数据id' })
+  @Rule(RuleType['string']().empty(''))
+  _id: string = undefined;
+}
+
+export class UVAO_menus extends FVO_menus {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}

+ 128 - 0
src/interface/nurse.interface.ts

@@ -0,0 +1,128 @@
+import { Rule, RuleType } from '@midwayjs/validate';
+import { ApiProperty } from '@midwayjs/swagger';
+import {
+  FrameworkErrorEnum,
+  SearchBase,
+  ServiceError,
+} from 'free-midway-component';
+import get = require('lodash/get');
+const dealVO = (cla, data) => {
+  for (const key in cla) {
+    const val = get(data, key);
+    if (val || val === 0) cla[key] = val;
+  }
+};
+export class FVO_nurse {
+  constructor(data: object) {
+    dealVO(this, data);
+  }
+  @ApiProperty({ description: '数据id' })
+  _id: string = undefined;
+  @ApiProperty({ description: '名称' })
+  'name': string = undefined;
+  @ApiProperty({ description: '头像' })
+  'icon': string = undefined;
+  @ApiProperty({ description: '手机' })
+  'mobile': string = undefined;
+  @ApiProperty({ description: '密码' })
+  'password': string = undefined;
+  @ApiProperty({ description: '医院名称' })
+  'hos_name': string = undefined;
+  @ApiProperty({ description: '部门名称' })
+  'dept_name': string = undefined;
+  @ApiProperty({ description: '所属医生' })
+  'doctor': string = undefined;
+  @ApiProperty({ description: '职务' })
+  'title': string = undefined;
+  @ApiProperty({ description: '职称' })
+  'post': string = undefined;
+  @ApiProperty({ description: '简介' })
+  'content': string = undefined;
+  @ApiProperty({ description: '微信openid' })
+  'openid': string = undefined;
+  @ApiProperty({ description: '账号' })
+  'account': string = undefined;
+}
+
+export class QDTO_nurse extends SearchBase {
+  constructor() {
+    const like_prop = [];
+    const props = ['name', 'account'];
+    const mapping = [];
+    super({ like_prop, props, mapping });
+  }
+  @ApiProperty({ description: '名称' })
+  'name': string = undefined;
+  @ApiProperty({ description: '账号' })
+  'account': string = undefined;
+}
+
+export class QVO_nurse extends FVO_nurse {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}
+
+export class CDTO_nurse {
+  @ApiProperty({ description: '名称' })
+  @Rule(RuleType['string']().empty(''))
+  'name': string = undefined;
+  @ApiProperty({ description: '头像' })
+  @Rule(RuleType['string']().empty(''))
+  'icon': string = undefined;
+  @ApiProperty({ description: '手机' })
+  @Rule(RuleType['string']().empty(''))
+  'mobile': string = undefined;
+  @ApiProperty({ description: '密码' })
+  @Rule(RuleType['string']().empty(''))
+  'password': string = undefined;
+  @ApiProperty({ description: '医院名称' })
+  @Rule(RuleType['string']().empty(''))
+  'hos_name': string = undefined;
+  @ApiProperty({ description: '部门名称' })
+  @Rule(RuleType['string']().empty(''))
+  'dept_name': string = undefined;
+  @ApiProperty({ description: '所属医生' })
+  @Rule(
+    RuleType['string']()
+      .required()
+      .error(new ServiceError('缺少所属医生', FrameworkErrorEnum.NEED_BODY))
+  )
+  'doctor': string = undefined;
+  @ApiProperty({ description: '职务' })
+  @Rule(RuleType['string']().empty(''))
+  'title': string = undefined;
+  @ApiProperty({ description: '职称' })
+  @Rule(RuleType['string']().empty(''))
+  'post': string = undefined;
+  @ApiProperty({ description: '简介' })
+  @Rule(RuleType['string']().empty(''))
+  'content': string = undefined;
+  @ApiProperty({ description: '微信openid' })
+  @Rule(RuleType['string']().empty(''))
+  'openid': string = undefined;
+  @ApiProperty({ description: '账号' })
+  @Rule(RuleType['string']().empty(''))
+  'account': string = undefined;
+}
+
+export class CVO_nurse extends FVO_nurse {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}
+
+export class UDTO_nurse extends CDTO_nurse {
+  @ApiProperty({ description: '数据id' })
+  @Rule(RuleType['string']().empty(''))
+  _id: string = undefined;
+}
+
+export class UVAO_nurse extends FVO_nurse {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}

+ 115 - 0
src/interface/patient.interface.ts

@@ -0,0 +1,115 @@
+import { Rule, RuleType } from '@midwayjs/validate';
+import { ApiProperty } from '@midwayjs/swagger';
+import { SearchBase } from 'free-midway-component';
+import get = require('lodash/get');
+const dealVO = (cla, data) => {
+  for (const key in cla) {
+    const val = get(data, key);
+    if (val || val === 0) cla[key] = val;
+  }
+};
+export class FVO_patient {
+  constructor(data: object) {
+    dealVO(this, data);
+  }
+  @ApiProperty({ description: '数据id' })
+  _id: string = undefined;
+  @ApiProperty({ description: '姓名' })
+  'name': string = undefined;
+  @ApiProperty({ description: '头像' })
+  'icon': string = undefined;
+  @ApiProperty({ description: '就诊编号/卡号' })
+  'card_no': string = undefined;
+  @ApiProperty({ description: '性别' })
+  'gender': string = undefined;
+  @ApiProperty({ description: '年龄' })
+  'age': number = undefined;
+  @ApiProperty({ description: '住址' })
+  'address': string = undefined;
+  @ApiProperty({ description: '手机' })
+  'mobile': string = undefined;
+  @ApiProperty({ description: '紧急联系人' })
+  'urgent_name': string = undefined;
+  @ApiProperty({ description: '紧急联系人手机' })
+  'urgent_mobile': string = undefined;
+  @ApiProperty({ description: '病例' })
+  'emrs': Array<any> = undefined;
+  @ApiProperty({ description: '微信openid' })
+  'openid': string = undefined;
+}
+
+export class QDTO_patient extends SearchBase {
+  constructor() {
+    const like_prop = [];
+    const props = ['name', 'openid'];
+    const mapping = [];
+    super({ like_prop, props, mapping });
+  }
+  @ApiProperty({ description: '姓名' })
+  'name': string = undefined;
+  @ApiProperty({ description: '微信openid' })
+  'openid': string = undefined;
+}
+
+export class QVO_patient extends FVO_patient {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}
+
+export class CDTO_patient {
+  @ApiProperty({ description: '姓名' })
+  @Rule(RuleType['string']().empty(''))
+  'name': string = undefined;
+  @ApiProperty({ description: '头像' })
+  @Rule(RuleType['string']().empty(''))
+  'icon': string = undefined;
+  @ApiProperty({ description: '就诊编号/卡号' })
+  @Rule(RuleType['string']().empty(''))
+  'card_no': string = undefined;
+  @ApiProperty({ description: '性别' })
+  @Rule(RuleType['string']().empty(''))
+  'gender': string = undefined;
+  @ApiProperty({ description: '年龄' })
+  @Rule(RuleType['number']().empty(''))
+  'age': number = undefined;
+  @ApiProperty({ description: '住址' })
+  @Rule(RuleType['string']().empty(''))
+  'address': string = undefined;
+  @ApiProperty({ description: '手机' })
+  @Rule(RuleType['string']().empty(''))
+  'mobile': string = undefined;
+  @ApiProperty({ description: '紧急联系人' })
+  @Rule(RuleType['string']().empty(''))
+  'urgent_name': string = undefined;
+  @ApiProperty({ description: '紧急联系人手机' })
+  @Rule(RuleType['string']().empty(''))
+  'urgent_mobile': string = undefined;
+  @ApiProperty({ description: '病例' })
+  @Rule(RuleType['array']().empty(''))
+  'emrs': Array<any> = undefined;
+  @ApiProperty({ description: '微信openid' })
+  @Rule(RuleType['string']().empty(''))
+  'openid': string = undefined;
+}
+
+export class CVO_patient extends FVO_patient {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}
+
+export class UDTO_patient extends CDTO_patient {
+  @ApiProperty({ description: '数据id' })
+  @Rule(RuleType['string']().empty(''))
+  _id: string = undefined;
+}
+
+export class UVAO_patient extends FVO_patient {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}

+ 87 - 0
src/interface/role.interface.ts

@@ -0,0 +1,87 @@
+import { Rule, RuleType } from '@midwayjs/validate';
+import { ApiProperty } from '@midwayjs/swagger';
+import { SearchBase } from 'free-midway-component';
+import get = require('lodash/get');
+const dealVO = (cla, data) => {
+  for (const key in cla) {
+    const val = get(data, key);
+    if (val || val === 0) cla[key] = val;
+  }
+};
+export class FVO_role {
+  constructor(data: object) {
+    dealVO(this, data);
+  }
+  @ApiProperty({ description: '数据id' })
+  _id: string = undefined;
+  @ApiProperty({ description: '角色名称' })
+  'name': string = undefined;
+  @ApiProperty({ description: '角色编码' })
+  'code': string = undefined;
+  @ApiProperty({ description: '菜单' })
+  'menu': string = undefined;
+  @ApiProperty({ description: '简介' })
+  'brief': string = undefined;
+  @ApiProperty({ description: '是否使用' })
+  'is_use': string = undefined;
+}
+
+export class QDTO_role extends SearchBase {
+  constructor() {
+    const like_prop = [];
+    const props = ['name', 'code', 'is_use'];
+    const mapping = [];
+    super({ like_prop, props, mapping });
+  }
+  @ApiProperty({ description: '角色名称' })
+  'name': string = undefined;
+  @ApiProperty({ description: '角色编码' })
+  'code': string = undefined;
+  @ApiProperty({ description: '是否使用' })
+  'is_use': string = undefined;
+}
+
+export class QVO_role extends FVO_role {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}
+
+export class CDTO_role {
+  @ApiProperty({ description: '角色名称' })
+  @Rule(RuleType['string']().empty(''))
+  'name': string = undefined;
+  @ApiProperty({ description: '角色编码' })
+  @Rule(RuleType['string']().empty(''))
+  'code': string = undefined;
+  @ApiProperty({ description: '菜单' })
+  @Rule(RuleType['string']().empty(''))
+  'menu': string = undefined;
+  @ApiProperty({ description: '简介' })
+  @Rule(RuleType['string']().empty(''))
+  'brief': string = undefined;
+  @ApiProperty({ description: '是否使用' })
+  @Rule(RuleType['string']().empty(''))
+  'is_use': string = undefined;
+}
+
+export class CVO_role extends FVO_role {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}
+
+export class UDTO_role extends CDTO_role {
+  @ApiProperty({ description: '数据id' })
+  @Rule(RuleType['string']().empty(''))
+  _id: string = undefined;
+}
+
+export class UVAO_role extends FVO_role {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}

+ 27 - 0
src/middleware/report.middleware.ts

@@ -0,0 +1,27 @@
+import { Middleware, IMiddleware } from '@midwayjs/core';
+import { NextFunction, Context } from '@midwayjs/koa';
+
+@Middleware()
+export class ReportMiddleware implements IMiddleware<Context, NextFunction> {
+  resolve() {
+    return async (ctx: Context, next: NextFunction) => {
+      // 控制器前执行的逻辑
+      const startTime = Date.now();
+      // 执行下一个 Web 中间件,最后执行到控制器
+      // 这里可以拿到下一个中间件或者控制器的返回值
+      const result = await next();
+      // 控制器之后执行的逻辑
+      ctx.logger.info(
+        `Report in "src/middleware/report.middleware.ts", rt = ${
+          Date.now() - startTime
+        }ms`
+      );
+      // 返回给上一个中间件的结果
+      return result;
+    };
+  }
+
+  static getName(): string {
+    return 'report';
+  }
+}

+ 11 - 0
src/service/admin.service.ts

@@ -0,0 +1,11 @@
+import { Provide } from '@midwayjs/decorator';
+import { InjectEntityModel } from '@midwayjs/typegoose';
+import { ReturnModelType } from '@typegoose/typegoose';
+import { BaseService } from 'free-midway-component';
+import { Admin } from '../entity/admin.entity';
+type modelType = ReturnModelType<typeof Admin>;
+@Provide()
+export class AdminService extends BaseService<modelType> {
+  @InjectEntityModel(Admin)
+  model: modelType;
+}

+ 11 - 0
src/service/adv.service.ts

@@ -0,0 +1,11 @@
+import { Provide } from '@midwayjs/decorator';
+import { InjectEntityModel } from '@midwayjs/typegoose';
+import { ReturnModelType } from '@typegoose/typegoose';
+import { BaseService } from 'free-midway-component';
+import { Adv } from '../entity/adv.entity';
+type modelType = ReturnModelType<typeof Adv>;
+@Provide()
+export class AdvService extends BaseService<modelType> {
+  @InjectEntityModel(Adv)
+  model: modelType;
+}

+ 11 - 0
src/service/article.service.ts

@@ -0,0 +1,11 @@
+import { Provide } from '@midwayjs/decorator';
+import { InjectEntityModel } from '@midwayjs/typegoose';
+import { ReturnModelType } from '@typegoose/typegoose';
+import { BaseService } from 'free-midway-component';
+import { Article } from '../entity/article.entity';
+type modelType = ReturnModelType<typeof Article>;
+@Provide()
+export class ArticleService extends BaseService<modelType> {
+  @InjectEntityModel(Article)
+  model: modelType;
+}

+ 11 - 0
src/service/chat.service.ts

@@ -0,0 +1,11 @@
+import { Provide } from '@midwayjs/decorator';
+import { InjectEntityModel } from '@midwayjs/typegoose';
+import { ReturnModelType } from '@typegoose/typegoose';
+import { BaseService } from 'free-midway-component';
+import { Chat } from '../entity/chat.entity';
+type modelType = ReturnModelType<typeof Chat>;
+@Provide()
+export class ChatService extends BaseService<modelType> {
+  @InjectEntityModel(Chat)
+  model: modelType;
+}

+ 11 - 0
src/service/doctor.service.ts

@@ -0,0 +1,11 @@
+import { Provide } from '@midwayjs/decorator';
+import { InjectEntityModel } from '@midwayjs/typegoose';
+import { ReturnModelType } from '@typegoose/typegoose';
+import { BaseService } from 'free-midway-component';
+import { Doctor } from '../entity/doctor.entity';
+type modelType = ReturnModelType<typeof Doctor>;
+@Provide()
+export class DoctorService extends BaseService<modelType> {
+  @InjectEntityModel(Doctor)
+  model: modelType;
+}

+ 11 - 0
src/service/group.service.ts

@@ -0,0 +1,11 @@
+import { Provide } from '@midwayjs/decorator';
+import { InjectEntityModel } from '@midwayjs/typegoose';
+import { ReturnModelType } from '@typegoose/typegoose';
+import { BaseService } from 'free-midway-component';
+import { Group } from '../entity/group.entity';
+type modelType = ReturnModelType<typeof Group>;
+@Provide()
+export class GroupService extends BaseService<modelType> {
+  @InjectEntityModel(Group)
+  model: modelType;
+}

+ 11 - 0
src/service/menus.service.ts

@@ -0,0 +1,11 @@
+import { Provide } from '@midwayjs/decorator';
+import { InjectEntityModel } from '@midwayjs/typegoose';
+import { ReturnModelType } from '@typegoose/typegoose';
+import { BaseService } from 'free-midway-component';
+import { Menus } from '../entity/menus.entity';
+type modelType = ReturnModelType<typeof Menus>;
+@Provide()
+export class MenusService extends BaseService<modelType> {
+  @InjectEntityModel(Menus)
+  model: modelType;
+}

+ 11 - 0
src/service/nurse.service.ts

@@ -0,0 +1,11 @@
+import { Provide } from '@midwayjs/decorator';
+import { InjectEntityModel } from '@midwayjs/typegoose';
+import { ReturnModelType } from '@typegoose/typegoose';
+import { BaseService } from 'free-midway-component';
+import { Nurse } from '../entity/nurse.entity';
+type modelType = ReturnModelType<typeof Nurse>;
+@Provide()
+export class NurseService extends BaseService<modelType> {
+  @InjectEntityModel(Nurse)
+  model: modelType;
+}

+ 11 - 0
src/service/patient.service.ts

@@ -0,0 +1,11 @@
+import { Provide } from '@midwayjs/decorator';
+import { InjectEntityModel } from '@midwayjs/typegoose';
+import { ReturnModelType } from '@typegoose/typegoose';
+import { BaseService } from 'free-midway-component';
+import { Patient } from '../entity/patient.entity';
+type modelType = ReturnModelType<typeof Patient>;
+@Provide()
+export class PatientService extends BaseService<modelType> {
+  @InjectEntityModel(Patient)
+  model: modelType;
+}

+ 11 - 0
src/service/role.service.ts

@@ -0,0 +1,11 @@
+import { Provide } from '@midwayjs/decorator';
+import { InjectEntityModel } from '@midwayjs/typegoose';
+import { ReturnModelType } from '@typegoose/typegoose';
+import { BaseService } from 'free-midway-component';
+import { Role } from '../entity/role.entity';
+type modelType = ReturnModelType<typeof Role>;
+@Provide()
+export class RoleService extends BaseService<modelType> {
+  @InjectEntityModel(Role)
+  model: modelType;
+}

+ 20 - 0
test/controller/api.test.ts

@@ -0,0 +1,20 @@
+import { createApp, close, createHttpRequest } from '@midwayjs/mock';
+import { Framework } from '@midwayjs/koa';
+
+describe('test/controller/home.test.ts', () => {
+
+  it('should POST /api/get_user', async () => {
+    // create app
+    const app = await createApp<Framework>();
+
+    // make request
+    const result = await createHttpRequest(app).get('/api/get_user').query({ uid: 123 });
+
+    // use expect by jest
+    expect(result.status).toBe(200);
+    expect(result.body.message).toBe('OK');
+
+    // close app
+    await close(app);
+  });
+});

+ 21 - 0
test/controller/home.test.ts

@@ -0,0 +1,21 @@
+import { createApp, close, createHttpRequest } from '@midwayjs/mock';
+import { Framework } from '@midwayjs/koa';
+
+describe('test/controller/home.test.ts', () => {
+
+  it('should GET /', async () => {
+    // create app
+    const app = await createApp<Framework>();
+
+    // make request
+    const result = await createHttpRequest(app).get('/');
+
+    // use expect by jest
+    expect(result.status).toBe(200);
+    expect(result.text).toBe('Hello Midwayjs!');
+
+    // close app
+    await close(app);
+  });
+
+});

+ 25 - 0
tsconfig.json

@@ -0,0 +1,25 @@
+{
+  "compileOnSave": true,
+  "compilerOptions": {
+    "target": "es2018",
+    "module": "commonjs",
+    "moduleResolution": "node",
+    "experimentalDecorators": true,
+    "emitDecoratorMetadata": true,
+    "inlineSourceMap":true,
+    "noImplicitThis": true,
+    "noUnusedLocals": true,
+    "stripInternal": true,
+    "skipLibCheck": true,
+    "pretty": true,
+    "declaration": true,
+    "forceConsistentCasingInFileNames": true,
+    "typeRoots": [ "./typings", "./node_modules/@types"],
+    "outDir": "dist"
+  },
+  "exclude": [
+    "dist",
+    "node_modules",
+    "test"
+  ]
+}