lrf 10 месяцев назад
Родитель
Сommit
8aec2f5263

+ 6 - 5
src/controller/system/dept.controller.ts

@@ -7,8 +7,9 @@ import { omit, pick } from 'lodash';
 import { ErrorCode, ServiceError } from '../../error/service.error';
 import { CVO_dept, FVO_dept, QVO_dept, UVAO_dept } from '../../interface/system/dept.interface';
 
-@ApiTags(['部门表'])
-@Controller('/dept')
+const namePrefix = '部门';
+@ApiTags([namePrefix])
+@Controller('/dept', { tagName: namePrefix })
 export class DeptController implements BaseController {
   controllerCode = 'system_dept';
   @Inject()
@@ -50,7 +51,7 @@ export class DeptController implements BaseController {
     return result;
   }
 
-  @Post('/')
+  @Post('/', { routerName: `创建${namePrefix}` })
   @ApiTags('创建数据')
   @Validate()
   @ApiResponse({ type: CVO_dept })
@@ -60,7 +61,7 @@ export class DeptController implements BaseController {
     return result;
   }
 
-  @Post('/:id')
+  @Post('/:id', { routerName: `修改${namePrefix}` })
   @ApiTags('修改数据')
   @Validate()
   @ApiResponse({ type: UVAO_dept })
@@ -70,7 +71,7 @@ export class DeptController implements BaseController {
     return result;
   }
 
-  @Del('/:id')
+  @Del('/:id', { routerName: `删除${namePrefix}` })
   @ApiTags('删除数据')
   @Validate()
   async delete(@Param('id') id: number) {

+ 1 - 1
src/entity/system/dept.entity.ts

@@ -1,7 +1,7 @@
 import { Column, Entity } from 'typeorm';
 import { BaseModel } from '../../frame/BaseModel';
 
-@Entity('dept')
+@Entity('dept', { comment: '部门' })
 export class Dept extends BaseModel {
   @Column({ type: 'character varying', comment: '部门名称' })
   name: string;

+ 33 - 0
src/entityLogs/opera.entity.ts

@@ -0,0 +1,33 @@
+import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
+
+@Entity('opera', { comment: '操作日志' })
+export class Opera {
+  @PrimaryGeneratedColumn({ type: 'integer' })
+  id: number;
+  @Column({ type: 'integer', nullable: true, comment: '操作人id' })
+  operator_id: number;
+  @Column({ type: 'character varying', nullable: true, comment: '操作人名称' })
+  operator_name: string;
+  @Column({ type: 'character varying', nullable: true, comment: 'ip' })
+  ip: string;
+  @Column({ type: 'character varying', nullable: true, comment: '设备' })
+  device: string;
+  @Column({ type: 'timestamp without time zone', nullable: true, comment: '时间' })
+  time: Date;
+  @Column({ type: 'character varying', nullable: true, comment: '操作地址' })
+  referer: string;
+  @Column({ type: 'character varying', nullable: true, comment: '请求路由' })
+  path: string;
+  @Column({ type: 'jsonb', nullable: true, comment: '地址参数' })
+  params: object;
+  @Column({ type: 'jsonb', nullable: true, comment: '请求参数' })
+  query: object;
+  @Column({ type: 'jsonb', nullable: true, comment: '方法体' })
+  body: object;
+  @Column({ type: 'character varying', nullable: true, comment: '操作业务' })
+  opera: string;
+  @Column({ type: 'jsonb', nullable: true, comment: '原数据' })
+  origin_data: Array<any>;
+  @Column({ type: 'jsonb', nullable: true, comment: '新数据' })
+  new_data: Array<any>;
+}

+ 56 - 0
src/event/dbSubscriber.ts

@@ -0,0 +1,56 @@
+import { EventSubscriberModel } from '@midwayjs/typeorm';
+import { EntitySubscriberInterface, InsertEvent, UpdateEvent, RemoveEvent } from 'typeorm';
+
+@EventSubscriberModel()
+export class DbSubscriber implements EntitySubscriberInterface {
+  /**
+   * 添加前触发
+   */
+  beforeInsert(event: InsertEvent<any>) {
+    console.log('BEFORE ENTITY INSERTED: ', event.entity);
+    // console.log(this.ctx.request);
+    // console.log(event.metadata.givenTableName);
+  }
+
+  /**
+   * 修改前触发
+   */
+  beforeUpdate(event: UpdateEvent<any>) {
+    console.log('BEFORE ENTITY UPDATED: ', event.entity);
+  }
+
+  /**
+   * 删除前触发
+   */
+  beforeRemove(event: RemoveEvent<any>) {
+    console.log(`BEFORE ENTITY WITH ID ${event.entityId} REMOVED: `, event.entity);
+  }
+
+  /**
+   * 添加后触发
+   */
+  afterInsert(event: InsertEvent<any>) {
+    console.log('AFTER ENTITY INSERTED: ', event.entity);
+  }
+
+  /**
+   * 修改后触发
+   */
+  afterUpdate(event: UpdateEvent<any>) {
+    console.log('AFTER ENTITY UPDATED: ', event.entity);
+  }
+
+  /**
+   * 删除后触发
+   */
+  afterRemove(event: RemoveEvent<any>) {
+    console.log(`AFTER ENTITY WITH ID ${event.entityId} REMOVED: `, event.entity);
+  }
+
+  /**
+   * 查询后触发
+   */
+  async afterLoad(entity: any) {
+    // console.log('AFTER ENTITY LOADED: ', entity);
+  }
+}

+ 24 - 3
src/frame/BaseService.ts

@@ -4,6 +4,7 @@ import * as toqm from 'typeorm';
 import { get, isNull, isObject, isUndefined, pick } from 'lodash';
 import { App, Inject } from '@midwayjs/core';
 import { Opera } from './dbOpera';
+import { OperaService } from '../service/log/opera.service';
 
 export interface QueryOpera {
   column: string;
@@ -11,12 +12,16 @@ export interface QueryOpera {
   /**采用数组的形式,依次嵌套操作 */
   opera: Opera[];
 }
-
+/**
+ * create,udpate,delete: 创建,修改,删除都会记录日志,所以需要用BaseService的直接操作方法,要不不会产生日志
+ */
 export abstract class BaseService<T> {
   @App()
   app: Application;
   @Inject()
   ctx: Context;
+  @Inject()
+  operaLogsService: OperaService;
   abstract model: Repository<T>;
 
   /**
@@ -127,6 +132,9 @@ export abstract class BaseService<T> {
     // 设置 创建数据的人
     if (this.ctx.user) Object.assign(data, { data_owner: this.ctx.user.id });
     const result = await this.model.insert(data);
+    const mn = this.model.metadata.tableName;
+    // 添加,没有原数据,只有新数据
+    await this.operaLogsService.toMakeLogs(null, { [mn]: [data] });
     return result;
   }
 
@@ -148,12 +156,25 @@ export abstract class BaseService<T> {
       if (isNull(val) || isUndefined(val)) continue;
       updateData[column] = val;
     }
+    // 找到原数据
+    const origin_data = await this.model.find({ where });
     const result = await this.model.update(where, updateData);
+    // 修改成新的数据,result只是结果,需要重新查一遍
+    const new_data = await this.model.find({ where });
+    const mn = this.model.metadata.tableName;
+    // 日志
+    await this.operaLogsService.toMakeLogs({ [mn]: origin_data }, { [mn]: new_data });
     return result;
   }
 
   /**删除,单删多删都行,假删除,把删除的数据移到指定删除表中 */
-  async delete(query: object) {
-    return 'in delete';
+  async delete(where: object) {
+    // 删除前,先查出来数据
+    const origin_data = await this.model.find({ where });
+    const result = await this.model.delete(where);
+    const mn = this.model.metadata.tableName;
+    // 日志,只有原数据没有新数据
+    await this.operaLogsService.toMakeLogs({ [mn]: origin_data });
+    return result;
   }
 }

+ 0 - 0
src/frame/ServiceFactory.ts


+ 3 - 3
src/interface/platform/design.interface.ts

@@ -6,7 +6,7 @@ export class FVO_design {
     dealVO(this, data);
   }
   @ApiProperty({ description: '数据id' })
-  id: string = undefined;
+  id: number = undefined;
   @ApiProperty({ description: '标题' })
   'zhTitle': string = undefined;
   @ApiProperty({ description: '英文标题' })
@@ -70,8 +70,8 @@ export class CVO_design extends FVO_design {
 
 export class UDTO_design extends CDTO_design {
   @ApiProperty({ description: '数据id' })
-  @Rule(RuleType['string']().empty(''))
-  _id: string = undefined;
+  @Rule(RuleType['number']().empty(''))
+  id: number = undefined;
 }
 
 export class UVAO_design extends FVO_design {

+ 2 - 2
src/interface/platform/supply.interface.ts

@@ -115,8 +115,8 @@ export class CVO_supply extends FVO_supply {
 
 export class UDTO_supply extends CDTO_supply {
   @ApiProperty({ description: '数据id' })
-  @Rule(RuleType['string']().empty(''))
-  _id: string = undefined;
+  @Rule(RuleType['number']().empty(''))
+  id: number = undefined;
 }
 
 export class UVAO_supply extends FVO_supply {

+ 2 - 2
src/interface/platform/tags.interface.ts

@@ -78,8 +78,8 @@ export class CVO_tags extends FVO_tags {
 
 export class UDTO_tags extends CDTO_tags {
   @ApiProperty({ description: '数据id' })
-  @Rule(RuleType['string']().empty(''))
-  _id: string = undefined;
+  @Rule(RuleType['number']().empty(''))
+  id: number = undefined;
 }
 
 export class UVAO_tags extends FVO_tags {

+ 63 - 0
src/service/log/opera.service.ts

@@ -0,0 +1,63 @@
+import { Inject, MidwayWebRouterService, Provide } from '@midwayjs/core';
+import { InjectEntityModel } from '@midwayjs/typeorm';
+import { Repository } from 'typeorm';
+import { get } from 'lodash';
+import dayjs = require('dayjs');
+import { Context } from '@midwayjs/koa';
+import { TypeORMDataSourceManager } from '@midwayjs/typeorm';
+import { Opera } from '../../entityLogs/opera.entity';
+@Provide()
+export class OperaService {
+  @Inject()
+  ctx: Context;
+  @InjectEntityModel(Opera, 'logs')
+  model: Repository<Opera>;
+  @Inject()
+  webRouterService: MidwayWebRouterService;
+
+  @Inject()
+  dataSourceManager: TypeORMDataSourceManager;
+
+  /**
+   * 生成日志
+   * 原数据和新数据格式:
+   * {
+   *    [表名]:[数据,...数据]
+   * }
+   * @param origin_data 原数据
+   * @param new_data 新数据
+   */
+  async toMakeLogs(origin_data?: object, new_data?: object) {
+    const req = this.ctx.request;
+    const user = this.ctx.user;
+    const logInfo: any = {
+      // 操作人
+      operator_id: user.id,
+      operator_name: get(user, 'nick_name', get(user, 'name')),
+      // ip
+      ip: get(req, 'header.x-forwarded-for', req.ip),
+      // 设备
+      device: get(req, 'header.user-agent'),
+      // 操作时间
+      time: dayjs().format('YYYY-MM-DD HH:mm:ss'),
+      // 操作地址
+      referer: get(req, 'header.referer'),
+      // 请求地址uri
+      path: get(req, 'path'),
+      // 地址参数
+      params: get(req, 'params'),
+      // 请求参数
+      query: get(req, 'query'),
+      // 方法体参数
+      body: get(req, 'body'),
+      // 操作业务:可以通过路由注解的routerName来获取
+      opera: null,
+      // 变动值: 表:[数据] 需要自己组织
+      origin_data: origin_data,
+      new_data: new_data,
+    };
+    const routeInfo = await this.webRouterService.getMatchedRouterInfo(this.ctx.path, this.ctx.method);
+    if (routeInfo) logInfo.opera = get(routeInfo, 'routerName');
+    await this.model.insert(logInfo);
+  }
+}

+ 1 - 1
src/service/platform/match.service.ts

@@ -18,7 +18,7 @@ export class MatchService extends BaseService<Match> {
     const data = { userInfo: {}, is_collection: false };
     // const arr = await this.model.findById(id).lean();
     const arr = await this.model.findOne({ where: { id: Equal(id) } });
-    if (arr && get(arr, '_id')) {
+    if (arr && get(arr, 'id')) {
       // 查询是否收藏该比赛
       // const collection = await this.cModel.findOne({ user: user._id, source: arr._id }).lean();
       const collection = await this.cModel.findOne({ where: { user: Equal(user.id), source: Equal(arr.id) } });

+ 4 - 2
src/service/util.service.ts

@@ -1,4 +1,4 @@
-import { Provide } from '@midwayjs/core';
+import { Inject, Provide } from '@midwayjs/core';
 import * as fs from 'fs';
 import { get, isObject } from 'lodash';
 import path = require('path');
@@ -9,6 +9,7 @@ import { News } from '../entity/platform/news.entity';
 import { Demand } from '../entity/platform/demand.entity';
 import { Expert } from '../entity/users/expert.entity';
 import { Company } from '../entity/users/company.entity';
+import { Context } from '@midwayjs/koa';
 // import { upperFirst } from 'lodash';
 
 // import { User } from '../entity/system/user.entity';
@@ -16,7 +17,8 @@ import { Company } from '../entity/users/company.entity';
 export class UtilService {
   // @InjectEntityModel(User)
   // uModel: ReturnModelType<typeof User>;
-
+  @Inject()
+  ctx: Context;
   randomStr(len = 6) {
     return Math.random().toString(36).slice(-len);
   }