mirror of
https://github.com/certd/certd.git
synced 2026-04-23 19:57:27 +08:00
chore: lib-server
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
import { Inject } from '@midwayjs/core';
|
||||
import * as koa from '@midwayjs/koa';
|
||||
import { Constants } from './constants.js';
|
||||
|
||||
export abstract class BaseController {
|
||||
@Inject()
|
||||
ctx: koa.Context;
|
||||
|
||||
/**
|
||||
* 成功返回
|
||||
* @param data 返回数据
|
||||
*/
|
||||
ok(data?: any) {
|
||||
const res = {
|
||||
...Constants.res.success,
|
||||
data: undefined,
|
||||
};
|
||||
if (data) {
|
||||
res.data = data;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
/**
|
||||
* 失败返回
|
||||
* @param msg
|
||||
* @param code
|
||||
*/
|
||||
fail(msg: string, code: any) {
|
||||
return {
|
||||
code: code ? code : Constants.res.error.code,
|
||||
msg: msg ? msg : Constants.res.error.code,
|
||||
};
|
||||
}
|
||||
|
||||
getUserId() {
|
||||
const userId = this.ctx.user?.id;
|
||||
if (userId == null) {
|
||||
throw new Error('Token已过期');
|
||||
}
|
||||
return userId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
import { ValidateException } from './exception/index.js';
|
||||
import * as _ from 'lodash-es';
|
||||
import { PermissionException } from './exception/index.js';
|
||||
import { Repository } from 'typeorm';
|
||||
import { Inject } from '@midwayjs/core';
|
||||
import { TypeORMDataSourceManager } from '@midwayjs/typeorm';
|
||||
import { EntityManager } from 'typeorm/entity-manager/EntityManager.js';
|
||||
|
||||
/**
|
||||
* 服务基类
|
||||
*/
|
||||
export abstract class BaseService<T> {
|
||||
@Inject()
|
||||
dataSourceManager: TypeORMDataSourceManager;
|
||||
|
||||
abstract getRepository(): Repository<T>;
|
||||
|
||||
async transaction(callback: (entityManager: EntityManager) => Promise<any>) {
|
||||
const dataSource = this.dataSourceManager.getDataSource('default');
|
||||
await dataSource.transaction(callback as any);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得单个ID
|
||||
* @param id ID
|
||||
* @param infoIgnoreProperty 忽略返回属性
|
||||
*/
|
||||
async info(id, infoIgnoreProperty?): Promise<T | null> {
|
||||
if (!id) {
|
||||
throw new ValidateException('id不能为空');
|
||||
}
|
||||
const info = await this.getRepository().findOneBy({ id } as any);
|
||||
if (info && infoIgnoreProperty) {
|
||||
for (const property of infoIgnoreProperty) {
|
||||
delete info[property];
|
||||
}
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* 非分页查询
|
||||
* @param options
|
||||
*/
|
||||
async find(options) {
|
||||
return await this.getRepository().find(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
* @param ids 删除的ID集合 如:[1,2,3] 或者 1,2,3
|
||||
*/
|
||||
async delete(ids) {
|
||||
if (ids instanceof Array) {
|
||||
await this.getRepository().delete(ids);
|
||||
} else if (typeof ids === 'string') {
|
||||
await this.getRepository().delete(ids.split(','));
|
||||
} else {
|
||||
//ids是一个condition
|
||||
await this.getRepository().delete(ids);
|
||||
}
|
||||
await this.modifyAfter(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增|修改
|
||||
* @param param 数据
|
||||
*/
|
||||
async addOrUpdate(param) {
|
||||
await this.getRepository().save(param);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增
|
||||
* @param param 数据
|
||||
*/
|
||||
async add(param) {
|
||||
const now = new Date();
|
||||
param.createTime = now;
|
||||
param.updateTime = now;
|
||||
await this.addOrUpdate(param);
|
||||
await this.modifyAfter(param);
|
||||
return {
|
||||
id: param.id,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改
|
||||
* @param param 数据
|
||||
*/
|
||||
async update(param) {
|
||||
if (!param.id) throw new ValidateException('no id');
|
||||
param.updateTime = new Date();
|
||||
await this.addOrUpdate(param);
|
||||
await this.modifyAfter(param);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增|修改|删除 之后的操作
|
||||
* @param data 对应数据
|
||||
*/
|
||||
async modifyAfter(data) {}
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
* @param query 查询条件 bean
|
||||
* @param page
|
||||
* @param order
|
||||
* @param buildQuery
|
||||
*/
|
||||
async page(query, page = { offset: 0, limit: 20 }, order, buildQuery) {
|
||||
if (page.offset == null) {
|
||||
page.offset = 0;
|
||||
}
|
||||
if (page.limit == null) {
|
||||
page.limit = 20;
|
||||
}
|
||||
const qb = this.getRepository().createQueryBuilder('main');
|
||||
if (order && order.prop) {
|
||||
qb.addOrderBy('main.' + order.prop, order.asc ? 'ASC' : 'DESC');
|
||||
}
|
||||
qb.addOrderBy('id', 'DESC');
|
||||
qb.offset(page.offset).limit(page.limit);
|
||||
//根据bean query
|
||||
if (query) {
|
||||
let whereSql = '';
|
||||
let index = 0;
|
||||
_.forEach(query, (value, key) => {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
if (index !== 0) {
|
||||
whereSql += ' and ';
|
||||
}
|
||||
whereSql += ` main.${key} = :${key} `;
|
||||
index++;
|
||||
});
|
||||
if (index > 0) {
|
||||
qb.where(whereSql, query);
|
||||
}
|
||||
}
|
||||
//自定义query
|
||||
if (buildQuery) {
|
||||
buildQuery(qb);
|
||||
}
|
||||
const list = await qb.getMany();
|
||||
const total = await qb.getCount();
|
||||
return {
|
||||
records: list,
|
||||
total,
|
||||
offset: page.offset,
|
||||
limit: page.limit,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
* @param query 查询条件 bean
|
||||
* @param order
|
||||
* @param buildQuery
|
||||
*/
|
||||
async list(query, order, buildQuery) {
|
||||
const qb = this.getRepository().createQueryBuilder('main');
|
||||
if (order && order.prop) {
|
||||
qb.orderBy('main.' + order.prop, order.asc ? 'ASC' : 'DESC');
|
||||
} else {
|
||||
qb.orderBy('id', 'DESC');
|
||||
}
|
||||
//根据bean query
|
||||
if (query) {
|
||||
let whereSql = '';
|
||||
let index = 0;
|
||||
_.forEach(query, (value, key) => {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
if (index !== 0) {
|
||||
whereSql += ' and ';
|
||||
}
|
||||
whereSql += ` main.${key} = :${key} `;
|
||||
index++;
|
||||
});
|
||||
if (index > 0) {
|
||||
qb.where(whereSql, query);
|
||||
}
|
||||
}
|
||||
//自定义query
|
||||
if (buildQuery) {
|
||||
buildQuery(qb);
|
||||
}
|
||||
return await qb.getMany();
|
||||
}
|
||||
|
||||
async checkUserId(id: any = 0, userId, userKey = 'userId') {
|
||||
// @ts-ignore
|
||||
const res = await this.getRepository().findOne({
|
||||
// @ts-ignore
|
||||
select: { [userKey]: true },
|
||||
// @ts-ignore
|
||||
where: {
|
||||
// @ts-ignore
|
||||
id,
|
||||
},
|
||||
});
|
||||
// @ts-ignore
|
||||
if (!res || res[userKey] === userId) {
|
||||
return;
|
||||
}
|
||||
throw new PermissionException('权限不足');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
export const Constants = {
|
||||
dataDir: './data',
|
||||
role: {
|
||||
defaultUser: 3,
|
||||
},
|
||||
per: {
|
||||
//无需登录
|
||||
guest: '_guest_',
|
||||
//无需登录
|
||||
anonymous: '_guest_',
|
||||
//仅需要登录
|
||||
authOnly: '_authOnly_',
|
||||
//仅需要登录
|
||||
loginOnly: '_authOnly_',
|
||||
},
|
||||
res: {
|
||||
serverError(message: string) {
|
||||
return {
|
||||
code: 1,
|
||||
message,
|
||||
};
|
||||
},
|
||||
error: {
|
||||
code: 1,
|
||||
message: 'Internal server error',
|
||||
},
|
||||
success: {
|
||||
code: 0,
|
||||
message: 'success',
|
||||
},
|
||||
validation: {
|
||||
code: 10,
|
||||
message: '参数错误',
|
||||
},
|
||||
needvip: {
|
||||
code: 88,
|
||||
message: '需要VIP',
|
||||
},
|
||||
auth: {
|
||||
code: 401,
|
||||
message: '您还未登录或token已过期',
|
||||
},
|
||||
permission: {
|
||||
code: 402,
|
||||
message: '您没有权限',
|
||||
},
|
||||
preview: {
|
||||
code: 10001,
|
||||
message: '对不起,预览环境不允许修改此数据',
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,61 @@
|
||||
import { ALL, Body, Post, Query } from '@midwayjs/core';
|
||||
import { BaseController } from './base-controller.js';
|
||||
|
||||
export abstract class CrudController<T> extends BaseController {
|
||||
abstract getService<T>();
|
||||
|
||||
@Post('/page')
|
||||
async page(
|
||||
@Body(ALL)
|
||||
body
|
||||
) {
|
||||
const pageRet = await this.getService().page(body?.query, body?.page, body?.sort, null);
|
||||
return this.ok(pageRet);
|
||||
}
|
||||
|
||||
@Post('/list')
|
||||
async list(
|
||||
@Body(ALL)
|
||||
body
|
||||
) {
|
||||
const listRet = await this.getService().list(body, null, null);
|
||||
return this.ok(listRet);
|
||||
}
|
||||
|
||||
@Post('/add')
|
||||
async add(
|
||||
@Body(ALL)
|
||||
bean
|
||||
) {
|
||||
delete bean.id;
|
||||
const id = await this.getService().add(bean);
|
||||
return this.ok(id);
|
||||
}
|
||||
|
||||
@Post('/info')
|
||||
async info(
|
||||
@Query('id')
|
||||
id
|
||||
) {
|
||||
const bean = await this.getService().info(id);
|
||||
return this.ok(bean);
|
||||
}
|
||||
|
||||
@Post('/update')
|
||||
async update(
|
||||
@Body(ALL)
|
||||
bean
|
||||
) {
|
||||
await this.getService().update(bean);
|
||||
return this.ok(null);
|
||||
}
|
||||
|
||||
@Post('/delete')
|
||||
async delete(
|
||||
@Query('id')
|
||||
id
|
||||
) {
|
||||
await this.getService().delete([id]);
|
||||
return this.ok(null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
export class EnumItem {
|
||||
value: string;
|
||||
label: string;
|
||||
color: string;
|
||||
|
||||
constructor(value, label, color) {
|
||||
this.value = value;
|
||||
this.label = label;
|
||||
this.color = color;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { Constants } from '../constants.js';
|
||||
import { BaseException } from './base-exception.js';
|
||||
/**
|
||||
* 授权异常
|
||||
*/
|
||||
export class AuthException extends BaseException {
|
||||
constructor(message) {
|
||||
super(
|
||||
'AuthException',
|
||||
Constants.res.auth.code,
|
||||
message ? message : Constants.res.auth.message
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* 异常基类
|
||||
*/
|
||||
export class BaseException extends Error {
|
||||
status: number;
|
||||
constructor(name, code, message) {
|
||||
super(message);
|
||||
this.name = name;
|
||||
this.status = code;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { Constants } from '../constants.js';
|
||||
import { BaseException } from './base-exception.js';
|
||||
/**
|
||||
* 通用异常
|
||||
*/
|
||||
export class CommonException extends BaseException {
|
||||
constructor(message) {
|
||||
super(
|
||||
'CommonException',
|
||||
Constants.res.error.code,
|
||||
message ? message : Constants.res.error.message
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export * from './auth-exception.js'
|
||||
export * from './base-exception.js'
|
||||
export * from './permission-exception.js'
|
||||
export * from './preview-exception.js'
|
||||
export * from './validation-exception.js'
|
||||
export * from './vip-exception.js'
|
||||
export * from './common-exception.js'
|
||||
@@ -0,0 +1,14 @@
|
||||
import { Constants } from '../constants.js';
|
||||
import { BaseException } from './base-exception.js';
|
||||
/**
|
||||
* 授权异常
|
||||
*/
|
||||
export class PermissionException extends BaseException {
|
||||
constructor(message?: string) {
|
||||
super(
|
||||
'PermissionException',
|
||||
Constants.res.permission.code,
|
||||
message ? message : Constants.res.permission.message
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { Constants } from '../constants.js';
|
||||
import { BaseException } from './base-exception.js';
|
||||
/**
|
||||
* 预览模式
|
||||
*/
|
||||
export class PreviewException extends BaseException {
|
||||
constructor(message) {
|
||||
super(
|
||||
'PreviewException',
|
||||
Constants.res.preview.code,
|
||||
message ? message : Constants.res.preview.message
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { Constants } from '../constants.js';
|
||||
import { BaseException } from './base-exception.js';
|
||||
/**
|
||||
* 校验异常
|
||||
*/
|
||||
export class ValidateException extends BaseException {
|
||||
constructor(message) {
|
||||
super(
|
||||
'ValidateException',
|
||||
Constants.res.validation.code,
|
||||
message ? message : Constants.res.validation.message
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { Constants } from '../constants.js';
|
||||
import { BaseException } from './base-exception.js';
|
||||
/**
|
||||
* 需要vip异常
|
||||
*/
|
||||
export class NeedVIPException extends BaseException {
|
||||
constructor(message) {
|
||||
super('NeedVIPException', Constants.res.needvip.code, message ? message : Constants.res.needvip.message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export * from './base-controller.js';
|
||||
export * from './constants.js';
|
||||
export * from './crud-controller.js';
|
||||
export * from './enum-item.js';
|
||||
export * from './exception/index.js';
|
||||
export * from './result.js';
|
||||
export * from './base-service.js';
|
||||
@@ -0,0 +1,18 @@
|
||||
export class Result<T> {
|
||||
code: number;
|
||||
msg: string;
|
||||
data: T;
|
||||
constructor(code, msg, data?) {
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
static error(code = 1, msg) {
|
||||
return new Result(code, msg, null);
|
||||
}
|
||||
|
||||
static success(msg, data?) {
|
||||
return new Result(0, msg, data);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user