zs 2 年之前
当前提交
d8cabd610b

+ 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();

+ 20 - 0
ecosystem.config.js

@@ -0,0 +1,20 @@
+'use strict';
+// 开发服务设置
+const app = '中科在线吉林专利市场vue3-服务';
+module.exports = {
+  apps: [
+    {
+      name: app, // 应用名称
+      script: './bootstrap.js', // 实际启动脚本
+      out: `./logs/${app}.log`,
+      error: `./logs/${app}.err`,
+      watch: [
+        // 监控变化的目录,一旦变化,自动重启
+        'dist',
+      ],
+      env: {
+        NODE_ENV: 'production', // 环境参数,当前指定为生产环境
+      },
+    },
+  ],
+};

+ 6 - 0
jest.config.js

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

+ 63 - 0
package.json

@@ -0,0 +1,63 @@
+{
+  "name": "my-midway-project",
+  "version": "1.0.0",
+  "description": "",
+  "private": true,
+  "dependencies": {
+    "@midwayjs/axios": "^3.11.3",
+    "@midwayjs/bootstrap": "^3.0.0",
+    "@midwayjs/core": "^3.0.0",
+    "@midwayjs/decorator": "^3.0.0",
+    "@midwayjs/info": "^3.0.0",
+    "@midwayjs/jwt": "^3.11.3",
+    "@midwayjs/koa": "^3.0.0",
+    "@midwayjs/logger": "^2.14.0",
+    "@midwayjs/redis": "^3.11.3",
+    "@midwayjs/swagger": "^3.11.3",
+    "@midwayjs/typegoose": "^3.11.3",
+    "@midwayjs/validate": "^3.0.0",
+    "@typegoose/typegoose": "^11.0.1",
+    "exceljs": "^4.3.0",
+    "free-midway-component": "^1.0.35",
+    "moment": "^2.29.4",
+    "mongoose": "^7.0.4",
+    "swagger-ui-dist": "^4.18.2"
+  },
+  "devDependencies": {
+    "@midwayjs/cli": "^2.0.0",
+    "@midwayjs/mock": "^3.0.0",
+    "@types/jest": "^29.2.0",
+    "@types/jsonwebtoken": "^9.0.1",
+    "@types/koa": "^2.13.4",
+    "@types/lodash": "^4.14.194",
+    "@types/node": "14",
+    "cross-env": "^6.0.0",
+    "jest": "^29.2.2",
+    "mwts": "^1.0.5",
+    "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 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"
+}

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

@@ -0,0 +1,19 @@
+import { MidwayConfig } from '@midwayjs/core';
+
+const project = 'zkzx';
+export default {
+  // use for cookie sign key, should change to your own and keep security
+  keys: '1672292154640_555',
+  koa: {
+    port: 12002,
+  },
+  jwt: {
+    secret: 'Ziyouyanfa!@#',
+    expiresIn: '2d',
+  },
+  redis_timeout: 300, //s
+  emailConfig: project,
+  axios: {
+    clients: {},
+  },
+} as MidwayConfig;

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

@@ -0,0 +1,39 @@
+import { MidwayConfig } from '@midwayjs/core';
+const ip = '127.0.0.1';
+const project = 'zkzx';
+const mongodb = 'zkzx_v2_patent';
+export default {
+  // use for cookie sign key, should change to your own and keep security
+  keys: '1672292154640_555',
+  koa: {
+    globalPrefix: `/${project}/v2/patent/api`,
+  },
+  swagger: {
+    swaggerPath: `/dev/${project}/v2/patent/api/doc`,
+  },
+  mongoose: {
+    dataSource: {
+      default: {
+        uri: `mongodb://${ip}:27017/${mongodb}`,
+        options: {
+          user: 'admin',
+          pass: 'admin',
+          authSource: 'admin',
+          useNewUrlParser: true,
+        },
+        entities: ['./entity'],
+      },
+    },
+  },
+  // redis: {
+  //   client: {
+  //     port: 6379, // Redis port
+  //     host: '120.48.146.1', // Redis host
+  //     password: '123456',
+  //     db: 4,
+  //   },
+  // },
+  axios: {
+    clients: {},
+  },
+} as MidwayConfig;

+ 43 - 0
src/config/config.prod.ts

@@ -0,0 +1,43 @@
+import { MidwayConfig } from '@midwayjs/core';
+const ip = '127.0.0.1';
+const project = 'zkzx';
+const mongodb = 'zkzx_v2_patent';
+export default {
+  // use for cookie sign key, should change to your own and keep security
+  keys: '1672292154640_555',
+  koa: {
+    globalPrefix: `/${project}/v2/patent/api`,
+  },
+  swagger: {
+    swaggerPath: `/dev/${project}/v2/patent/api/doc`,
+  },
+  mongoose: {
+    dataSource: {
+      default: {
+        uri: `mongodb://${ip}:27017/${mongodb}`,
+        options: {
+          user: 'admin',
+          pass: 'admin',
+          authSource: 'admin',
+          useNewUrlParser: true,
+        },
+        entities: ['./entity'],
+      },
+    },
+  },
+  // redis: {
+  //   client: {
+  //     port: 6379, // Redis port
+  //     host: '120.48.146.1', // Redis host
+  //     password: '123456',
+  //     db: 4,
+  //   },
+  // },
+  axios: {
+    clients: {
+      // email: {
+      //   baseURL: 'http://127.0.0.1:14002/semail/api',
+      // },
+    },
+  },
+} 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;

+ 50 - 0
src/configuration.ts

@@ -0,0 +1,50 @@
+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 * as swagger from '@midwayjs/swagger';
+import * as jwt from '@midwayjs/jwt';
+import * as redis from '@midwayjs/redis';
+import * as axios from '@midwayjs/axios';
+// import { IMidwayContainer } from '@midwayjs/core';
+import { join } from 'path';
+// freemidway组件项目
+import * as FreeFrame from 'free-midway-component';
+// import { FrameworkErrorEnum, ServiceError } from 'free-midway-component';
+// 控制器执行前函数
+import { ReportMiddleware } from './middleware/report.middleware';
+// 请求成功,失败提示
+// const axiosResponse = response => {
+//   if (response.status === 200) return response.data;
+//   else {
+//     console.log(JSON.stringify(response));
+//     throw new ServiceError('请求失败', FrameworkErrorEnum.SERVICE_FAULT);
+//   }
+// };
+// const axiosError = error => {
+//   return Promise.reject(error);
+// };
+@Configuration({
+  imports: [
+    FreeFrame,
+    validate,
+    jwt,
+    redis,
+    axios,
+    swagger,
+    {
+      component: info,
+      enabledEnvironment: ['local'],
+    },
+  ],
+  importConfigs: [join(__dirname, './config')],
+})
+export class ContainerLifeCycle {
+  @App()
+  app: koa.Application;
+
+  async onReady() {
+    this.app.useMiddleware([ReportMiddleware]);
+    // this.app.getMiddleware().insertFirst(ReportMiddleware);
+  }
+}

+ 89 - 0
src/controller/patent.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 { PatentService } from '../service/patent.service';
+import {
+  CDTO_patent,
+  CVO_patent,
+  FVO_patent,
+  QDTO_patent,
+  QVO_patent,
+  UDTO_patent,
+  UVAO_patent,
+} from '../interface/patent.interface';
+import { ApiResponse, ApiTags, ApiQuery } from '@midwayjs/swagger';
+import { Validate } from '@midwayjs/validate';
+@ApiTags(['e专利'])
+@Controller('/patent')
+export class PatentController extends BaseController {
+  @Inject()
+  service: PatentService;
+
+  @Post('/')
+  @Validate()
+  @ApiResponse({ type: CVO_patent })
+  async create(@Body() data: CDTO_patent) {
+    const dbData = await this.service.create(data);
+    const result = new CVO_patent(dbData);
+    return result;
+  }
+  @Get('/')
+  @ApiQuery({ name: 'query' })
+  @ApiResponse({ type: QVO_patent })
+  async query(
+    @Query() filter: QDTO_patent,
+    @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_patent(i);
+      data.push(newData);
+    }
+    const total = await this.service.count(filter);
+    return { data, total };
+  }
+
+  @Get('/:id')
+  @ApiResponse({ type: FVO_patent })
+  async fetch(@Param('id') id: string) {
+    const data = await this.service.fetch(id);
+    const result = new FVO_patent(data);
+    return result;
+  }
+
+  @Post('/:id')
+  @Validate()
+  @ApiResponse({ type: UVAO_patent })
+  async update(@Param('id') id: string, @Body() body: UDTO_patent) {
+    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/patenttrans.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 { PatenttransService } from '../service/patenttrans.service';
+import {
+  CDTO_patenttrans,
+  CVO_patenttrans,
+  FVO_patenttrans,
+  QDTO_patenttrans,
+  QVO_patenttrans,
+  UDTO_patenttrans,
+  UVAO_patenttrans,
+} from '../interface/patenttrans.interface';
+import { ApiResponse, ApiTags, ApiQuery } from '@midwayjs/swagger';
+import { Validate } from '@midwayjs/validate';
+@ApiTags(['专利交易'])
+@Controller('/patenttrans')
+export class PatenttransController extends BaseController {
+  @Inject()
+  service: PatenttransService;
+
+  @Post('/')
+  @Validate()
+  @ApiResponse({ type: CVO_patenttrans })
+  async create(@Body() data: CDTO_patenttrans) {
+    const dbData = await this.service.create(data);
+    const result = new CVO_patenttrans(dbData);
+    return result;
+  }
+  @Get('/')
+  @ApiQuery({ name: 'query' })
+  @ApiResponse({ type: QVO_patenttrans })
+  async query(
+    @Query() filter: QDTO_patenttrans,
+    @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_patenttrans(i);
+      data.push(newData);
+    }
+    const total = await this.service.count(filter);
+    return { data, total };
+  }
+
+  @Get('/:id')
+  @ApiResponse({ type: FVO_patenttrans })
+  async fetch(@Param('id') id: string) {
+    const data = await this.service.fetch(id);
+    const result = new FVO_patenttrans(data);
+    return result;
+  }
+
+  @Post('/:id')
+  @Validate()
+  @ApiResponse({ type: UVAO_patenttrans })
+  async update(@Param('id') id: string, @Body() body: UDTO_patenttrans) {
+    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.');
+  }
+}

+ 105 - 0
src/entity/patent.entity.ts

@@ -0,0 +1,105 @@
+import { modelOptions, prop } from '@typegoose/typegoose';
+import { BaseModel } from 'free-midway-component';
+@modelOptions({
+  schemaOptions: { collection: 'patent' },
+})
+export class Patent extends BaseModel {
+  @prop({ required: false, index: true, zh: '申请号' })
+  create_number: string;
+  @prop({ required: false, index: true, zh: '申请日' })
+  create_date: string;
+  @prop({ required: false, index: true, zh: '公开(公告)号' })
+  success_number: string;
+  @prop({ required: false, index: true, zh: '公开(公告)日' })
+  success_date: string;
+  @prop({ required: false, index: true, zh: '发明人' })
+  inventor: Array<any>;
+  @prop({ required: false, index: false, zh: '代理机构' })
+  agent: string;
+  @prop({ required: false, index: false, zh: '代理人' })
+  agent_personal: string;
+  @prop({ required: false, index: false, zh: '摘要(中文)' })
+  abstract: string;
+  @prop({ required: false, index: true, zh: '发明人地址' })
+  address: string;
+  @prop({ required: false, index: true, zh: '标题(中文)' })
+  name: string;
+  @prop({ required: false, index: true, zh: '申请人' })
+  apply_personal: string;
+  @prop({
+    required: false,
+    index: true,
+    zh: '专利有效性',
+    remark: '字典:patent_term',
+  })
+  term: string;
+  @prop({
+    required: false,
+    index: true,
+    zh: '专利类型',
+    remark: '字典:patent_type',
+  })
+  type: string;
+  @prop({ required: false, index: false, zh: '首页附图(压缩图)' })
+  file: string;
+  @prop({ required: false, index: false, zh: '公开国别' })
+  nationality: string;
+  @prop({ required: false, index: false, zh: 'IPC主分类' })
+  ipc_type: string;
+  @prop({ required: false, index: false, zh: '当前法律状态' })
+  onlegal_status: string;
+  @prop({ required: false, index: false, zh: '法律状态' })
+  legal_status: string;
+  @prop({ required: false, index: false, zh: '法律文书日期' })
+  law_date: string;
+  @prop({ required: false, index: false, zh: '当前权利人' })
+  on_obligee: string;
+  @prop({ required: false, index: false, zh: '申请人地址(其他)' })
+  apply_address: string;
+  @prop({ required: false, index: false, zh: '申请人(其他)' })
+  apply_other: string;
+  @prop({ required: false, index: false, zh: '法律文书编号' })
+  law_num: string;
+  @prop({ required: false, index: false, zh: '首次公开日' })
+  first_opendate: string;
+  @prop({ required: false, index: false, zh: '授权公告日' })
+  empower_date: string;
+  @prop({ required: false, index: false, zh: '失效日' })
+  lose_date: string;
+  @prop({ required: false, index: false, zh: '实质审查生效日' })
+  examine_date: string;
+  @prop({ required: false, index: false, zh: '发明(设计)人(其他)' })
+  invention_design: string;
+  @prop({ required: false, index: false, zh: '链接到incoPat' })
+  incopat_link: string;
+  @prop({ required: false, index: false, zh: '首项权利要求' })
+  first_ask: string;
+  @prop({ required: false, index: true, zh: '第一申请人' })
+  first_apply: string;
+  @prop({ required: false, index: false, zh: '中国申请人城市' })
+  apply_city: string;
+  @prop({ required: false, index: false, zh: '工商统一社会信用代码' })
+  business_code: string;
+  @prop({ required: false, index: false, zh: '工商注册地' })
+  business_address: string;
+  @prop({ required: false, index: true, zh: '第一发明人' })
+  first_inventor: string;
+  @prop({ required: false, index: false, zh: '合享价值度' })
+  shared_value: string;
+  @prop({ required: false, index: false, zh: '技术稳定性' })
+  techol_stable: string;
+  @prop({ required: false, index: false, zh: '技术先进性' })
+  techol_advanced: string;
+  @prop({ required: false, index: false, zh: 'PCT国际申请号' })
+  pct_apply: string;
+  @prop({ required: false, index: false, zh: 'PCT国际公布号' })
+  pct_publish: string;
+  @prop({
+    required: false,
+    index: true,
+    zh: '状态',
+    remark: '字典:common_status',
+    default: '0',
+  })
+  status: string;
+}

+ 78 - 0
src/entity/patenttrans.entity.ts

@@ -0,0 +1,78 @@
+import { modelOptions, prop } from '@typegoose/typegoose';
+import { BaseModel } from 'free-midway-component';
+@modelOptions({
+  schemaOptions: { collection: 'patenttrans' },
+})
+export class Patenttrans extends BaseModel {
+  @prop({ required: false, index: true, zh: '关联用户' })
+  user_id: string;
+  @prop({ required: false, index: true, zh: '关联专利' })
+  patent_id: string;
+  @prop({ required: false, index: true, zh: '专利名称' })
+  patent_name: string;
+  @prop({ required: false, index: true, zh: '专利号' })
+  create_number: string;
+  @prop({ required: false, index: true, zh: '当前权利人(变更前权利人)' })
+  on_obligee: string;
+  @prop({ required: false, index: true, zh: '联系人' })
+  contact: string;
+  @prop({ required: false, index: true, zh: '手机号' })
+  phone: string;
+  @prop({ required: false, index: true, zh: '电子邮箱' })
+  email: string;
+  @prop({ required: false, index: true, zh: '投资预算' })
+  budget: string;
+  @prop({
+    required: false,
+    index: true,
+    zh: '交易类型',
+    remark: '字典:trans_type',
+  })
+  type: string;
+  @prop({
+    required: false,
+    index: false,
+    zh: '免费许可承诺书',
+    remark: '交易类型为免费许可时,需填写免费许可承诺书',
+  })
+  promise_file: string;
+  @prop({
+    required: false,
+    index: true,
+    zh: '是否有评估报告',
+    remark: '字典:common_isno',
+  })
+  is_report: string;
+  @prop({ required: false, index: false, zh: '评估报告' })
+  report: string;
+  @prop({ required: false, index: false, zh: '技术说明' })
+  requirementdesc: string;
+  @prop({ required: false, index: false, zh: '商业预期' })
+  expect: string;
+  @prop({ required: false, index: false, zh: '合作条件及要求' })
+  condition: string;
+  @prop({ required: false, index: false, zh: '摘要' })
+  abstract: string;
+  @prop({ required: false, index: true, zh: '变更后专利权人' })
+  on_afterobligee: string;
+  @prop({ required: false, index: true, zh: '专利权转移日期' })
+  transfer_date: string;
+  @prop({
+    required: false,
+    index: true,
+    zh: '合同类型',
+    remark: '字典:trans_contract_type',
+  })
+  is_contract: string;
+  @prop({ required: false, index: false, zh: '线上合同' })
+  contract: string;
+  @prop({ required: false, index: false, zh: '线下合同' })
+  offine_contract: string;
+  @prop({
+    required: false,
+    index: true,
+    zh: '状态',
+    remark: '字典:trans_status',
+  })
+  status: string;
+}

+ 13 - 0
src/filter/default.filter.ts

@@ -0,0 +1,13 @@
+import { Catch } from '@midwayjs/core';
+import { Context } from '@midwayjs/koa';
+
+@Catch()
+export class DefaultErrorFilter {
+  async catch(err: Error, ctx: Context) {
+    // 所有的未分类错误会到这里
+    return {
+      success: false,
+      message: err.message,
+    };
+  }
+}

+ 10 - 0
src/filter/notfound.filter.ts

@@ -0,0 +1,10 @@
+import { Catch, httpError, MidwayHttpError } from '@midwayjs/core';
+import { Context } from '@midwayjs/koa';
+
+@Catch(httpError.NotFoundError)
+export class NotFoundFilter {
+  async catch(err: MidwayHttpError, ctx: Context) {
+    // 404 错误会到这里
+    ctx.redirect('/404.html');
+  }
+}

+ 6 - 0
src/interface.ts

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

+ 301 - 0
src/interface/patent.interface.ts

@@ -0,0 +1,301 @@
+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_patent {
+  constructor(data: object) {
+    dealVO(this, data);
+  }
+  @ApiProperty({ description: '数据id' })
+  _id: string = undefined;
+  @ApiProperty({ description: '申请号' })
+  'create_number': string = undefined;
+  @ApiProperty({ description: '申请日' })
+  'create_date': string = undefined;
+  @ApiProperty({ description: '公开(公告)号' })
+  'success_number': string = undefined;
+  @ApiProperty({ description: '公开(公告)日' })
+  'success_date': string = undefined;
+  @ApiProperty({ description: '发明人' })
+  'inventor': Array<any> = undefined;
+  @ApiProperty({ description: '代理机构' })
+  'agent': string = undefined;
+  @ApiProperty({ description: '代理人' })
+  'agent_personal': string = undefined;
+  @ApiProperty({ description: '摘要(中文)' })
+  'abstract': string = undefined;
+  @ApiProperty({ description: '发明人地址' })
+  'address': string = undefined;
+  @ApiProperty({ description: '标题(中文)' })
+  'name': string = undefined;
+  @ApiProperty({ description: '申请人' })
+  'apply_personal': string = undefined;
+  @ApiProperty({ description: '专利有效性' })
+  'term': string = undefined;
+  @ApiProperty({ description: '专利类型' })
+  'type': string = undefined;
+  @ApiProperty({ description: '首页附图(压缩图)' })
+  'file': string = undefined;
+  @ApiProperty({ description: '公开国别' })
+  'nationality': string = undefined;
+  @ApiProperty({ description: 'IPC主分类' })
+  'ipc_type': string = undefined;
+  @ApiProperty({ description: '当前法律状态' })
+  'onlegal_status': string = undefined;
+  @ApiProperty({ description: '法律状态' })
+  'legal_status': string = undefined;
+  @ApiProperty({ description: '法律文书日期' })
+  'law_date': string = undefined;
+  @ApiProperty({ description: '当前权利人' })
+  'on_obligee': string = undefined;
+  @ApiProperty({ description: '申请人地址(其他)' })
+  'apply_address': string = undefined;
+  @ApiProperty({ description: '申请人(其他)' })
+  'apply_other': string = undefined;
+  @ApiProperty({ description: '法律文书编号' })
+  'law_num': string = undefined;
+  @ApiProperty({ description: '首次公开日' })
+  'first_opendate': string = undefined;
+  @ApiProperty({ description: '授权公告日' })
+  'empower_date': string = undefined;
+  @ApiProperty({ description: '失效日' })
+  'lose_date': string = undefined;
+  @ApiProperty({ description: '实质审查生效日' })
+  'examine_date': string = undefined;
+  @ApiProperty({ description: '发明(设计)人(其他)' })
+  'invention_design': string = undefined;
+  @ApiProperty({ description: '链接到incoPat' })
+  'incopat_link': string = undefined;
+  @ApiProperty({ description: '首项权利要求' })
+  'first_ask': string = undefined;
+  @ApiProperty({ description: '第一申请人' })
+  'first_apply': string = undefined;
+  @ApiProperty({ description: '中国申请人城市' })
+  'apply_city': string = undefined;
+  @ApiProperty({ description: '工商统一社会信用代码' })
+  'business_code': string = undefined;
+  @ApiProperty({ description: '工商注册地' })
+  'business_address': string = undefined;
+  @ApiProperty({ description: '第一发明人' })
+  'first_inventor': string = undefined;
+  @ApiProperty({ description: '合享价值度' })
+  'shared_value': string = undefined;
+  @ApiProperty({ description: '技术稳定性' })
+  'techol_stable': string = undefined;
+  @ApiProperty({ description: '技术先进性' })
+  'techol_advanced': string = undefined;
+  @ApiProperty({ description: 'PCT国际申请号' })
+  'pct_apply': string = undefined;
+  @ApiProperty({ description: 'PCT国际公布号' })
+  'pct_publish': string = undefined;
+  @ApiProperty({ description: '状态' })
+  'status': string = undefined;
+}
+
+export class QDTO_patent extends SearchBase {
+  constructor() {
+    const like_prop = [];
+    const props = [
+      'create_number',
+      'create_date',
+      'success_number',
+      'success_date',
+      'inventor',
+      'address',
+      'name',
+      'apply_personal',
+      'term',
+      'type',
+      'first_apply',
+      'first_inventor',
+      'status',
+    ];
+    const mapping = [];
+    super({ like_prop, props, mapping });
+  }
+  @ApiProperty({ description: '申请号' })
+  'create_number': string = undefined;
+  @ApiProperty({ description: '申请日' })
+  'create_date': string = undefined;
+  @ApiProperty({ description: '公开(公告)号' })
+  'success_number': string = undefined;
+  @ApiProperty({ description: '公开(公告)日' })
+  'success_date': string = undefined;
+  @ApiProperty({ description: '发明人' })
+  'inventor': Array<any> = undefined;
+  @ApiProperty({ description: '发明人地址' })
+  'address': string = undefined;
+  @ApiProperty({ description: '标题(中文)' })
+  'name': string = undefined;
+  @ApiProperty({ description: '申请人' })
+  'apply_personal': string = undefined;
+  @ApiProperty({ description: '专利有效性' })
+  'term': string = undefined;
+  @ApiProperty({ description: '专利类型' })
+  'type': string = undefined;
+  @ApiProperty({ description: '第一申请人' })
+  'first_apply': string = undefined;
+  @ApiProperty({ description: '第一发明人' })
+  'first_inventor': string = undefined;
+  @ApiProperty({ description: '状态' })
+  'status': string = undefined;
+}
+
+export class QVO_patent extends FVO_patent {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}
+
+export class CDTO_patent {
+  @ApiProperty({ description: '申请号' })
+  @Rule(RuleType['string']().empty(''))
+  'create_number': string = undefined;
+  @ApiProperty({ description: '申请日' })
+  @Rule(RuleType['string']().empty(''))
+  'create_date': string = undefined;
+  @ApiProperty({ description: '公开(公告)号' })
+  @Rule(RuleType['string']().empty(''))
+  'success_number': string = undefined;
+  @ApiProperty({ description: '公开(公告)日' })
+  @Rule(RuleType['string']().empty(''))
+  'success_date': string = undefined;
+  @ApiProperty({ description: '发明人' })
+  @Rule(RuleType['array']().empty(''))
+  'inventor': Array<any> = undefined;
+  @ApiProperty({ description: '代理机构' })
+  @Rule(RuleType['string']().empty(''))
+  'agent': string = undefined;
+  @ApiProperty({ description: '代理人' })
+  @Rule(RuleType['string']().empty(''))
+  'agent_personal': string = undefined;
+  @ApiProperty({ description: '摘要(中文)' })
+  @Rule(RuleType['string']().empty(''))
+  'abstract': string = undefined;
+  @ApiProperty({ description: '发明人地址' })
+  @Rule(RuleType['string']().empty(''))
+  'address': string = undefined;
+  @ApiProperty({ description: '标题(中文)' })
+  @Rule(RuleType['string']().empty(''))
+  'name': string = undefined;
+  @ApiProperty({ description: '申请人' })
+  @Rule(RuleType['string']().empty(''))
+  'apply_personal': string = undefined;
+  @ApiProperty({ description: '专利有效性' })
+  @Rule(RuleType['string']().empty(''))
+  'term': string = undefined;
+  @ApiProperty({ description: '专利类型' })
+  @Rule(RuleType['string']().empty(''))
+  'type': string = undefined;
+  @ApiProperty({ description: '首页附图(压缩图)' })
+  @Rule(RuleType['string']().empty(''))
+  'file': string = undefined;
+  @ApiProperty({ description: '公开国别' })
+  @Rule(RuleType['string']().empty(''))
+  'nationality': string = undefined;
+  @ApiProperty({ description: 'IPC主分类' })
+  @Rule(RuleType['string']().empty(''))
+  'ipc_type': string = undefined;
+  @ApiProperty({ description: '当前法律状态' })
+  @Rule(RuleType['string']().empty(''))
+  'onlegal_status': string = undefined;
+  @ApiProperty({ description: '法律状态' })
+  @Rule(RuleType['string']().empty(''))
+  'legal_status': string = undefined;
+  @ApiProperty({ description: '法律文书日期' })
+  @Rule(RuleType['string']().empty(''))
+  'law_date': string = undefined;
+  @ApiProperty({ description: '当前权利人' })
+  @Rule(RuleType['string']().empty(''))
+  'on_obligee': string = undefined;
+  @ApiProperty({ description: '申请人地址(其他)' })
+  @Rule(RuleType['string']().empty(''))
+  'apply_address': string = undefined;
+  @ApiProperty({ description: '申请人(其他)' })
+  @Rule(RuleType['string']().empty(''))
+  'apply_other': string = undefined;
+  @ApiProperty({ description: '法律文书编号' })
+  @Rule(RuleType['string']().empty(''))
+  'law_num': string = undefined;
+  @ApiProperty({ description: '首次公开日' })
+  @Rule(RuleType['string']().empty(''))
+  'first_opendate': string = undefined;
+  @ApiProperty({ description: '授权公告日' })
+  @Rule(RuleType['string']().empty(''))
+  'empower_date': string = undefined;
+  @ApiProperty({ description: '失效日' })
+  @Rule(RuleType['string']().empty(''))
+  'lose_date': string = undefined;
+  @ApiProperty({ description: '实质审查生效日' })
+  @Rule(RuleType['string']().empty(''))
+  'examine_date': string = undefined;
+  @ApiProperty({ description: '发明(设计)人(其他)' })
+  @Rule(RuleType['string']().empty(''))
+  'invention_design': string = undefined;
+  @ApiProperty({ description: '链接到incoPat' })
+  @Rule(RuleType['string']().empty(''))
+  'incopat_link': string = undefined;
+  @ApiProperty({ description: '首项权利要求' })
+  @Rule(RuleType['string']().empty(''))
+  'first_ask': string = undefined;
+  @ApiProperty({ description: '第一申请人' })
+  @Rule(RuleType['string']().empty(''))
+  'first_apply': string = undefined;
+  @ApiProperty({ description: '中国申请人城市' })
+  @Rule(RuleType['string']().empty(''))
+  'apply_city': string = undefined;
+  @ApiProperty({ description: '工商统一社会信用代码' })
+  @Rule(RuleType['string']().empty(''))
+  'business_code': string = undefined;
+  @ApiProperty({ description: '工商注册地' })
+  @Rule(RuleType['string']().empty(''))
+  'business_address': string = undefined;
+  @ApiProperty({ description: '第一发明人' })
+  @Rule(RuleType['string']().empty(''))
+  'first_inventor': string = undefined;
+  @ApiProperty({ description: '合享价值度' })
+  @Rule(RuleType['string']().empty(''))
+  'shared_value': string = undefined;
+  @ApiProperty({ description: '技术稳定性' })
+  @Rule(RuleType['string']().empty(''))
+  'techol_stable': string = undefined;
+  @ApiProperty({ description: '技术先进性' })
+  @Rule(RuleType['string']().empty(''))
+  'techol_advanced': string = undefined;
+  @ApiProperty({ description: 'PCT国际申请号' })
+  @Rule(RuleType['string']().empty(''))
+  'pct_apply': string = undefined;
+  @ApiProperty({ description: 'PCT国际公布号' })
+  @Rule(RuleType['string']().empty(''))
+  'pct_publish': string = undefined;
+  @ApiProperty({ description: '状态' })
+  @Rule(RuleType['string']().empty(''))
+  'status': string = undefined;
+}
+
+export class CVO_patent extends FVO_patent {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}
+
+export class UDTO_patent extends CDTO_patent {
+  @ApiProperty({ description: '数据id' })
+  @Rule(RuleType['string']().empty(''))
+  _id: string = undefined;
+}
+
+export class UVAO_patent extends FVO_patent {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}

+ 217 - 0
src/interface/patenttrans.interface.ts

@@ -0,0 +1,217 @@
+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_patenttrans {
+  constructor(data: object) {
+    dealVO(this, data);
+  }
+  @ApiProperty({ description: '数据id' })
+  _id: string = undefined;
+  @ApiProperty({ description: '关联用户' })
+  'user_id': string = undefined;
+  @ApiProperty({ description: '关联专利' })
+  'patent_id': string = undefined;
+  @ApiProperty({ description: '专利名称' })
+  'patent_name': string = undefined;
+  @ApiProperty({ description: '专利号' })
+  'create_number': string = undefined;
+  @ApiProperty({ description: '当前权利人(变更前权利人)' })
+  'on_obligee': string = undefined;
+  @ApiProperty({ description: '联系人' })
+  'contact': string = undefined;
+  @ApiProperty({ description: '手机号' })
+  'phone': string = undefined;
+  @ApiProperty({ description: '电子邮箱' })
+  'email': string = undefined;
+  @ApiProperty({ description: '投资预算' })
+  'budget': string = undefined;
+  @ApiProperty({ description: '交易类型' })
+  'type': string = undefined;
+  @ApiProperty({ description: '免费许可承诺书' })
+  'promise_file': string = undefined;
+  @ApiProperty({ description: '是否有评估报告' })
+  'is_report': string = undefined;
+  @ApiProperty({ description: '评估报告' })
+  'report': string = undefined;
+  @ApiProperty({ description: '技术说明' })
+  'requirementdesc': string = undefined;
+  @ApiProperty({ description: '商业预期' })
+  'expect': string = undefined;
+  @ApiProperty({ description: '合作条件及要求' })
+  'condition': string = undefined;
+  @ApiProperty({ description: '摘要' })
+  'abstract': string = undefined;
+  @ApiProperty({ description: '变更后专利权人' })
+  'on_afterobligee': string = undefined;
+  @ApiProperty({ description: '专利权转移日期' })
+  'transfer_date': string = undefined;
+  @ApiProperty({ description: '合同类型' })
+  'is_contract': string = undefined;
+  @ApiProperty({ description: '线上合同' })
+  'contract': string = undefined;
+  @ApiProperty({ description: '线下合同' })
+  'offine_contract': string = undefined;
+  @ApiProperty({ description: '状态' })
+  'status': string = undefined;
+}
+
+export class QDTO_patenttrans extends SearchBase {
+  constructor() {
+    const like_prop = [];
+    const props = [
+      'user_id',
+      'patent_id',
+      'patent_name',
+      'create_number',
+      'on_obligee',
+      'contact',
+      'phone',
+      'email',
+      'budget',
+      'type',
+      'is_report',
+      'on_afterobligee',
+      'transfer_date',
+      'is_contract',
+      'status',
+    ];
+    const mapping = [];
+    super({ like_prop, props, mapping });
+  }
+  @ApiProperty({ description: '关联用户' })
+  'user_id': string = undefined;
+  @ApiProperty({ description: '关联专利' })
+  'patent_id': string = undefined;
+  @ApiProperty({ description: '专利名称' })
+  'patent_name': string = undefined;
+  @ApiProperty({ description: '专利号' })
+  'create_number': string = undefined;
+  @ApiProperty({ description: '当前权利人(变更前权利人)' })
+  'on_obligee': string = undefined;
+  @ApiProperty({ description: '联系人' })
+  'contact': string = undefined;
+  @ApiProperty({ description: '手机号' })
+  'phone': string = undefined;
+  @ApiProperty({ description: '电子邮箱' })
+  'email': string = undefined;
+  @ApiProperty({ description: '投资预算' })
+  'budget': string = undefined;
+  @ApiProperty({ description: '交易类型' })
+  'type': string = undefined;
+  @ApiProperty({ description: '是否有评估报告' })
+  'is_report': string = undefined;
+  @ApiProperty({ description: '变更后专利权人' })
+  'on_afterobligee': string = undefined;
+  @ApiProperty({ description: '专利权转移日期' })
+  'transfer_date': string = undefined;
+  @ApiProperty({ description: '合同类型' })
+  'is_contract': string = undefined;
+  @ApiProperty({ description: '状态' })
+  'status': string = undefined;
+}
+
+export class QVO_patenttrans extends FVO_patenttrans {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}
+
+export class CDTO_patenttrans {
+  @ApiProperty({ description: '关联用户' })
+  @Rule(RuleType['string']().empty(''))
+  'user_id': string = undefined;
+  @ApiProperty({ description: '关联专利' })
+  @Rule(RuleType['string']().empty(''))
+  'patent_id': string = undefined;
+  @ApiProperty({ description: '专利名称' })
+  @Rule(RuleType['string']().empty(''))
+  'patent_name': string = undefined;
+  @ApiProperty({ description: '专利号' })
+  @Rule(RuleType['string']().empty(''))
+  'create_number': string = undefined;
+  @ApiProperty({ description: '当前权利人(变更前权利人)' })
+  @Rule(RuleType['string']().empty(''))
+  'on_obligee': string = undefined;
+  @ApiProperty({ description: '联系人' })
+  @Rule(RuleType['string']().empty(''))
+  'contact': string = undefined;
+  @ApiProperty({ description: '手机号' })
+  @Rule(RuleType['string']().empty(''))
+  'phone': string = undefined;
+  @ApiProperty({ description: '电子邮箱' })
+  @Rule(RuleType['string']().empty(''))
+  'email': string = undefined;
+  @ApiProperty({ description: '投资预算' })
+  @Rule(RuleType['string']().empty(''))
+  'budget': string = undefined;
+  @ApiProperty({ description: '交易类型' })
+  @Rule(RuleType['string']().empty(''))
+  'type': string = undefined;
+  @ApiProperty({ description: '免费许可承诺书' })
+  @Rule(RuleType['string']().empty(''))
+  'promise_file': string = undefined;
+  @ApiProperty({ description: '是否有评估报告' })
+  @Rule(RuleType['string']().empty(''))
+  'is_report': string = undefined;
+  @ApiProperty({ description: '评估报告' })
+  @Rule(RuleType['string']().empty(''))
+  'report': string = undefined;
+  @ApiProperty({ description: '技术说明' })
+  @Rule(RuleType['string']().empty(''))
+  'requirementdesc': string = undefined;
+  @ApiProperty({ description: '商业预期' })
+  @Rule(RuleType['string']().empty(''))
+  'expect': string = undefined;
+  @ApiProperty({ description: '合作条件及要求' })
+  @Rule(RuleType['string']().empty(''))
+  'condition': string = undefined;
+  @ApiProperty({ description: '摘要' })
+  @Rule(RuleType['string']().empty(''))
+  'abstract': string = undefined;
+  @ApiProperty({ description: '变更后专利权人' })
+  @Rule(RuleType['string']().empty(''))
+  'on_afterobligee': string = undefined;
+  @ApiProperty({ description: '专利权转移日期' })
+  @Rule(RuleType['string']().empty(''))
+  'transfer_date': string = undefined;
+  @ApiProperty({ description: '合同类型' })
+  @Rule(RuleType['string']().empty(''))
+  'is_contract': string = undefined;
+  @ApiProperty({ description: '线上合同' })
+  @Rule(RuleType['string']().empty(''))
+  'contract': string = undefined;
+  @ApiProperty({ description: '线下合同' })
+  @Rule(RuleType['string']().empty(''))
+  'offine_contract': string = undefined;
+  @ApiProperty({ description: '状态' })
+  @Rule(RuleType['string']().empty(''))
+  'status': string = undefined;
+}
+
+export class CVO_patenttrans extends FVO_patenttrans {
+  constructor(data: object) {
+    super(data);
+    dealVO(this, data);
+  }
+}
+
+export class UDTO_patenttrans extends CDTO_patenttrans {
+  @ApiProperty({ description: '数据id' })
+  @Rule(RuleType['string']().empty(''))
+  _id: string = undefined;
+}
+
+export class UVAO_patenttrans extends FVO_patenttrans {
+  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/patent.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 { Patent } from '../entity/patent.entity';
+type modelType = ReturnModelType<typeof Patent>;
+@Provide()
+export class PatentService extends BaseService<modelType> {
+  @InjectEntityModel(Patent)
+  model: modelType;
+}

+ 11 - 0
src/service/patenttrans.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 { Patenttrans } from '../entity/patenttrans.entity';
+type modelType = ReturnModelType<typeof Patenttrans>;
+@Provide()
+export class PatenttransService extends BaseService<modelType> {
+  @InjectEntityModel(Patenttrans)
+  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"
+  ]
+}