diff --git a/README.md b/README.md index 992a19c..bd13e03 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,14 @@ Node版后台基础框架基于[Egg.js](https://eggjs.org/zh-cn/)(阿里出品) * 鉴权:**[egg-jwt](https://www.npmjs.com/package/egg-jwt)** * 网络:**[axios](https://www.npmjs.com/package/axios)** +## 核心组件 +独有cool-admin.com发布的npm组件 +* 路由:**[egg-cool-router](https://www.npmjs.com/package/egg-cool-router)** +* 控制器:**[egg-cool-controller](https://www.npmjs.com/package/egg-cool-controller)** +* 服务层:**[egg-cool-service](https://www.npmjs.com/package/egg-cool-service)** +* 缓存:**[egg-cool-cache](https://www.npmjs.com/package/egg-cool-cache)** +* 模型:**[egg-cool-entity](https://www.npmjs.com/package/egg-cool-entity)** + ## 运行 环境 `Node.js>=8.9.0` `Redis` `mysql` diff --git a/app/controller/user.ts b/app/controller/user.ts index 620ec0c..81f2138 100644 --- a/app/controller/user.ts +++ b/app/controller/user.ts @@ -1,11 +1,9 @@ -import { BaseController } from '../lib/base/controller'; -import routerDecorator from '../lib/router'; -import { Context } from 'egg'; +import { BaseController } from 'egg-cool-controller'; +import router from 'egg-cool-router'; -@routerDecorator.prefix('/user', [ 'add', 'delete', 'update', 'info', 'list', 'page' ]) +@router.prefix('/user', [ 'add', 'delete', 'update', 'info', 'list', 'page' ]) export default class User extends BaseController { - constructor (ctx: Context) { - super(ctx); + init() { this.setEntity(this.ctx.repo.User); } } diff --git a/app/entities/user.ts b/app/entities/user.ts index bcfceb8..8c8b730 100644 --- a/app/entities/user.ts +++ b/app/entities/user.ts @@ -1,4 +1,4 @@ -import { BaseEntity } from '../lib/base/entity'; +import { BaseEntity } from 'egg-cool-entity'; import { Entity, Column } from 'typeorm'; @Entity({ name: 'user' }) diff --git a/app/extend/application.ts b/app/extend/application.ts index ecfb1a9..88fd10e 100644 --- a/app/extend/application.ts +++ b/app/extend/application.ts @@ -2,36 +2,5 @@ * 框架扩展 */ export default class Application { - /** - * redis保存值 - * @param key 键 - * @param value 值 - * @param expire 过期时间 单位:秒 - */ - public static async redisSet (key, value, expire?: any) { - // @ts-ignore - const redis = this.redis; - await redis.set(key, value); - if (expire) { - await redis.expire(key, expire); - } - } - - /** - * redis获得值 - * @param key 键 - */ - public static async redisGet (key) { - // @ts-ignore - return this.redis.get(key); - } - - /** - * redis 删除key - * @param key - */ - public static async redisDel (key) { - // @ts-ignore - return this.redis.del(key); - } + } diff --git a/app/lib/base/controller.ts b/app/lib/base/controller.ts deleted file mode 100644 index c4e3edc..0000000 --- a/app/lib/base/controller.ts +++ /dev/null @@ -1,147 +0,0 @@ -import { Controller, Context } from 'egg'; -import routerDecorator from '../router'; -import { Brackets } from 'typeorm'; - -// 返回参数配置 -interface ResOp { - // 返回数据 - data?: any; - // 是否成功 - isFail?: boolean; - // 返回码 - code?: number; - // 返回消息 - message?: string; -} - -// 分页参数配置 -interface PageOp { - // 模糊查询字段 - keyWordLikeFields?: string[]; - // where - where?: Brackets; - // 全匹配 "=" 字段 - fieldEq?: string[]; - // 排序 - addOrderBy?: {}; -} - -/** - * 控制器基类 - */ -export abstract class BaseController extends Controller { - protected entity; - protected OpService; - protected pageOption: PageOp; - - protected constructor (ctx: Context) { - super(ctx); - this.OpService = this.service.comm.data; - } - - /** - * 设置服务 - * @param service - */ - protected setService (service) { - this.OpService = service; - } - - /** - * 配置分页查询 - * @param option - */ - protected setPageOption (option: PageOp) { - this.pageOption = option; - } - - /** - * 设置操作实体 - * @param entity - */ - protected setEntity (entity) { - this.entity = entity; - } - - /** - * 分页查询数据 - */ - @routerDecorator.get('/page') - protected async page () { - const result = await this.OpService.page(this.ctx.query, this.pageOption, this.entity); - this.res({ data: result }); - } - - /** - * 数据列表 - */ - @routerDecorator.get('/list') - protected async list () { - const result = await this.OpService.list(this.entity); - this.res({ data: result }); - } - - /** - * 信息 - */ - @routerDecorator.get('/info') - protected async info () { - const result = await this.OpService.info(this.ctx.query.id, this.entity); - this.res({ data: result }); - } - - /** - * 新增 - */ - @routerDecorator.post('/add') - protected async add () { - await this.OpService.addOrUpdate(this.ctx.request.body, this.entity); - this.res(); - } - - /** - * 修改 - */ - @routerDecorator.post('/update') - protected async update () { - await this.OpService.addOrUpdate(this.ctx.request.body, this.entity); - this.res(); - } - - /** - * 删除 - */ - @routerDecorator.post('/delete') - protected async delete () { - await this.OpService.delete(this.ctx.request.body.ids, this.entity); - this.res(); - } - - /** - * 返回数据 - * @param op 返回配置,返回失败需要单独配置 - */ - protected res (op?: ResOp) { - if (!op) { - this.ctx.body = { - code: 1000, - message: 'success', - }; - return; - } - if (op.isFail) { - this.ctx.body = { - code: op.code ? op.code : 1001, - data: op.data, - message: op.message ? op.message : 'fail', - }; - } else { - this.ctx.body = { - code: op.code ? op.code : 1000, - message: op.message ? op.message : 'success', - data: op.data, - }; - } - } - -} diff --git a/app/lib/base/entity.ts b/app/lib/base/entity.ts deleted file mode 100644 index f49ec64..0000000 --- a/app/lib/base/entity.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn, Index } from 'typeorm'; -// 实体类基类 -export abstract class BaseEntity { - // ID - @PrimaryGeneratedColumn({ type: 'bigint' }) - id: number; - // 创建时间 - @Index() - @CreateDateColumn() - createTime: Date; - // 更新时间 - @UpdateDateColumn() - updateTime: Date; -} diff --git a/app/lib/base/service.ts b/app/lib/base/service.ts deleted file mode 100644 index 9b77a7f..0000000 --- a/app/lib/base/service.ts +++ /dev/null @@ -1,256 +0,0 @@ -import { Service, Context } from 'egg'; -import { getManager, getConnection, Brackets } from 'typeorm'; -import * as _ from 'lodash'; -// 基础配置 -const conf = { - size: 15, - errTips: { - noEntity: '未设置操作实体~', - }, -}; - -/** - * 服务基类 - */ -export abstract class BaseService extends Service { - public sqlParams; - - public constructor (ctx: Context) { - super(ctx); - this.sqlParams = []; - } - - /** - * 执行SQL并获得分页数据 - * @param sql 执行的sql语句 - * @param query 分页查询条件 - */ - public async sqlRenderPage (sql, query) { - const { size = conf.size, page = 1, order = 'createTime', sort = 'desc' } = query; - if (order && sort) { - if (!await this.paramSafetyCheck(order + sort)) { - throw new Error('非法传参~'); - } - sql += ` ORDER BY ${ order } ${ sort }`; - } - this.sqlParams.push((page - 1) * size); - this.sqlParams.push(parseInt(size)); - sql += ' LIMIT ?,? '; - let params = []; - params = params.concat(this.sqlParams); - const result = await this.nativeQuery(sql, params); - const countResult = await this.nativeQuery(this.getCountSql(sql), params); - return { - list: result, - pagination: { - page: parseInt(page), - size: parseInt(size), - total: parseInt(countResult[0] ? countResult[0].count : 0), - }, - }; - } - - /** - * 原生查询 - * @param sql - * @param params - */ - public async nativeQuery (sql, params?) { - if (_.isEmpty(params)) { - params = this.sqlParams; - } - let newParams = []; - newParams = newParams.concat(params); - this.sqlParams = []; - return await this.getOrmManager().query(sql, newParams); - } - - /** - * 参数安全性检查 - * @param params - */ - public async paramSafetyCheck (params) { - const lp = params.toLowerCase(); - return !(lp.indexOf('update') > -1 || lp.indexOf('select') > -1 || lp.indexOf('delete') > -1 || lp.indexOf('insert') > -1); - } - - /** - * 获得查询个数的SQL - * @param sql - */ - public getCountSql (sql) { - sql = sql.toLowerCase(); - return `select count(*) as count from (${ sql.split('limit')[0] }) a`; - } - - /** - * 单表分页查询 - * @param entity - * @param query - * @param option - */ - public async page (query, option, entity) { - if (!entity) throw new Error(conf.errTips.noEntity); - const find = await this.getPageFind(query, option, entity); - return this.renderPage(await find.getManyAndCount(), query); - } - - /** - * 所有数据 - * @param entity - */ - public async list (entity) { - if (!entity) throw new Error(conf.errTips.noEntity); - return await entity.find(); - } - - /** - * 新增/修改 - * @param entity 实体 - * @param param 数据 - */ - public async addOrUpdate (param, entity) { - if (!entity) throw new Error(conf.errTips.noEntity); - if (param.id) { - await entity.update(param.id, param); - } else { - await entity.save(param); - } - } - - /** - * 根据ID获得信息 - * @param entity 实体 - * @param id id - */ - public async info (id, entity) { - if (!entity) throw new Error(conf.errTips.noEntity); - return await entity.findOne({ id }); - } - - /** - * 删除 - * @param entity - * @param ids - */ - public async delete (ids, entity) { - if (!entity) throw new Error(conf.errTips.noEntity); - if (ids instanceof Array) { - await entity.delete(ids); - } else { - await entity.delete(ids.split(',')); - } - } - - /** - * query - * @param data - * @param query - */ - public renderPage (data, query) { - const { size = conf.size, page = 1 } = query; - return { - list: data[0], - pagination: { - page: parseInt(page), - size: parseInt(size), - total: data[1], - }, - }; - } - - /** - * 构造分页查询条件 - * @param entity 实体 - * @param query 查询条件 - * @param option 配置信息 - */ - public getPageFind (query, option, entity) { - let { size = conf.size, page = 1, order = 'createTime', sort = 'desc', keyWord = '' } = query; - const find = entity - .createQueryBuilder() - .take(parseInt(size)) - .skip(String((page - 1) * size)); - if (option) { - // 默认条件 - if (option.where) { - find.where(option.where); - } - // 附加排序 - if (!_.isEmpty(option.addOrderBy)) { - for (const key in option.addOrderBy) { - find.addOrderBy(key, option.addOrderBy[key].toUpperCase()); - } - } - // 关键字模糊搜索 - if (keyWord) { - keyWord = `%${ keyWord }%`; - find.andWhere(new Brackets(qb => { - const keyWordLikeFields = option.keyWordLikeFields; - for (let i = 0; i < option.keyWordLikeFields.length; i++) { - qb.orWhere(`${ keyWordLikeFields[i] } like :keyWord`, { keyWord }); - } - })); - } - // 字段全匹配 - if (!_.isEmpty(option.fieldEq)) { - for (const key of option.fieldEq) { - const c = {}; - if (query[key]) { - c[key] = query[key]; - find.andWhere(`${ key } = :${ key }`, c); - } - } - } - } - // 接口请求的排序 - if (sort && order) { - find.addOrderBy(order, sort.toUpperCase()); - } - return find; - } - - /** - * 设置sql - * @param condition 条件是否成立 - * @param sql sql语句 - * @param params 参数 - */ - protected setSql (condition, sql, params?: any[]) { - let rSql = false; - if (condition || (condition === 0 && condition !== '')) { - rSql = true; - this.sqlParams = this.sqlParams.concat(params); - } - return rSql ? sql : ''; - } - - /** - * 获得上下文 - */ - public getContext () { - return this.ctx; - } - - /** - * 获得ORM操作对象 - */ - public getRepo () { - return this.ctx.repo; - } - - /** - * 获得ORM管理 - */ - public getOrmManager () { - return getManager(); - } - - /** - * 获得ORM连接类 - */ - public getOrmConnection () { - return getConnection(); - } - -} diff --git a/app/lib/cache/index.d.ts b/app/lib/cache/index.d.ts deleted file mode 100644 index d1ab5d0..0000000 --- a/app/lib/cache/index.d.ts +++ /dev/null @@ -1,8 +0,0 @@ - -export interface Config { - resolver?: (...args: any[]) => string | number; - ttl?: number; // 缓存过期时间 - url?: string; // url包含改前缀才缓存 如api请求时缓存 admin请求时不缓存 -} -export declare function Cache(config?: Config): (target: object, propertyName: string, propertyDesciptor: PropertyDescriptor) => PropertyDescriptor; -export declare function ClearCache(); diff --git a/app/lib/cache/index.js b/app/lib/cache/index.js deleted file mode 100644 index a1c5beb..0000000 --- a/app/lib/cache/index.js +++ /dev/null @@ -1,67 +0,0 @@ -"use strict"; - -const DEFAULT_TTL = 600; -const REDIS_PRE = 'cache'; -const _ = require('lodash'); -const {Repository} = require('typeorm'); - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -function Cache(config) { - if (config === void 0) { - config = {}; - } - return function (target, name, propertyDesciptor) { - let prop = propertyDesciptor.value ? "value" : "get"; - let originalFunction = propertyDesciptor[prop]; - propertyDesciptor[prop] = async function () { - let args = []; - for (let _i = 0; _i < arguments.length; _i++) { - if (!(arguments[_i] instanceof Repository)){ - args[_i] = arguments[_i]; - } - } - const url = this.ctx.url; - if (config.url && _.startsWith(url, config.url) === false) { - return await originalFunction.apply(this, args) - } - let key = REDIS_PRE + ':' + target.pathName + `.${name}` + (config.resolver ? - config.resolver.apply(this, args) : - JSON.stringify(args).split(':').join('=')); - const cacheValue = await this.app.redisGet(key); - if (!_.isEmpty(cacheValue)) { - return JSON.parse(cacheValue).data - } else { - let result = await originalFunction.apply(this, args); - let data = { - data: result - }; - this.ctx.app.redisSet(key, JSON.stringify(data), config.ttl ? config.ttl : DEFAULT_TTL); - return result - } - }; - return propertyDesciptor - }; -} - -exports.Cache = Cache; - -function ClearCache() { - return function (target, name, propertyDesciptor) { - let prop = propertyDesciptor.value ? "value" : "get"; - propertyDesciptor[prop] = async function () { - const key = REDIS_PRE + ':' + target.pathName + '*'; - const keys = await this.ctx.app.redis.keys(key); - if (!_.isEmpty(keys)) { - keys.forEach(key => { - this.ctx.app.redisDel(key) - }); - } - }; - return propertyDesciptor - }; -} - -exports.ClearCache = ClearCache; diff --git a/app/lib/router/index.d.ts b/app/lib/router/index.d.ts deleted file mode 100644 index 6d929b0..0000000 --- a/app/lib/router/index.d.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { Application } from 'egg'; -import { Middleware } from 'koa'; - -/** http装饰器方法类型 */ -declare type HttpFunction = (url: string, ...beforeMiddlewares: Middleware[]) => any; - -declare class RouterDecorator { - get: HttpFunction; - post: HttpFunction; - patch: HttpFunction; - del: HttpFunction; - options: HttpFunction; - put: HttpFunction; - /** - * 记录各个class的prefix以及相关中间件 - * 最后统一设置 - * @private - * @static - * @type {ClassPrefix} - * @memberof RouterDecorator - */ - private static __classPrefix__; - /** - * 记录各个routerUrl的路由配置 - * 最后统一设置 - * @private - * @static - * @type {Router} - * @memberof RouterDecorator - */ - private static __router__; - - constructor (); - - /** 推入路由配置 */ - private __setRouter__; - - /** - * 装饰Controller class的工厂函数 - * 为一整个controller添加prefix - * 可以追加中间件 - * @param {string} prefixUrl - * @param {...Middleware[]} beforeMiddlewares - * @param {[]} baseFn 配置通用的接口 可选 page、add、update、delete、info、list - * @returns 装饰器函数 - * @memberof RouterDecorator - */ - prefix (prefixUrl: string, baseFn?: any[], ...beforeMiddlewares: Middleware[]): (targetControllerClass: any) => any; - - /** - * 注册路由 - * 路由信息是通过装饰器收集的 - * @export - * @param {Application} app eggApp实例 - * @param {string} [options={ prefix: '' }] 举例: { prefix: '/api' } - */ - static initRouter (app: Application, options?: { - prefix: string; - }): void; -} - -/** 暴露注册路由方法 */ -export declare const initRouter: typeof RouterDecorator.initRouter; -declare const _default: RouterDecorator; -/** 暴露实例的prefix和http的各个方法 */ -export default _default; diff --git a/app/lib/router/index.js b/app/lib/router/index.js deleted file mode 100644 index 87736e6..0000000 --- a/app/lib/router/index.js +++ /dev/null @@ -1,135 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", {value: true}); -const _ = require('lodash'); -const tslib_1 = require("tslib"); -/** http方法名 */ -const HTTP_METHODS = ['get', 'post', 'patch', 'del', 'options', 'put']; - -let baseControllerArr = []; - -class RouterDecorator { - constructor() { - HTTP_METHODS.forEach(httpMethod => { - this[httpMethod] = (url, ...beforeMiddlewares) => (target, name) => { - const routerOption = { - httpMethod, - beforeMiddlewares, - handlerName: name, - constructorFn: target.constructor, - className: target.constructor.name, - url: url - }; - if (target.constructor.name === 'BaseController') { - baseControllerArr.push(routerOption) - } else { - this.__setRouter__(url, routerOption); - } - }; - }); - } - - /** 推入路由配置 */ - __setRouter__(url, routerOption) { - RouterDecorator.__router__[url] = RouterDecorator.__router__[url] || []; - RouterDecorator.__router__[url].push(routerOption); - } - - /** - * 装饰Controller class的工厂函数 - * 为一整个controller添加prefix - * 可以追加中间件 - * @param {string} prefixUrl - * @param {...Middleware[]} beforeMiddlewares - * @param {any[]} baseFn - * @returns 装饰器函数 - * @memberof RouterDecorator - */ - prefix(prefixUrl, baseFn = [], ...beforeMiddlewares) { - return function (targetControllerClass) { - RouterDecorator.__classPrefix__[targetControllerClass.name] = { - prefix: prefixUrl, - beforeMiddlewares: beforeMiddlewares, - baseFn: baseFn, - target: targetControllerClass - }; - return targetControllerClass; - }; - } - - /** - * 注册路由 - * 路由信息是通过装饰器收集的 - * @export - * @param {Application} app eggApp实例 - * @param {string} [options={ prefix: '' }] 举例: { prefix: '/api' } - */ - static initRouter(app, options = {prefix: ''}) { - let addUrl = []; - Object.keys(RouterDecorator.__router__).forEach(url => { - RouterDecorator.__router__[url].forEach((opt) => { - const controllerPrefixData = RouterDecorator.__classPrefix__[opt.className] || { - prefix: '', - beforeMiddlewares: [], - baseFn: [], - target: {} - }; - let fullUrl = `${options.prefix}${controllerPrefixData.prefix}${url}`; - console.log(`>>>>>>>>custom register URL * ${opt.httpMethod.toUpperCase()} ${fullUrl} * ${opt.className}.${opt.handlerName}`); - if (!addUrl.includes(fullUrl)) { - app.router[opt.httpMethod](fullUrl, ...controllerPrefixData.beforeMiddlewares, ...opt.beforeMiddlewares, (ctx) => tslib_1.__awaiter(this, void 0, void 0, function* () { - const ist = new opt.constructorFn(ctx); - yield ist[opt.handlerName](ctx); - })); - addUrl.push(fullUrl); - } - }); - }); - // 通用方法 - const cArr = [].concat(_.uniq(baseControllerArr)); - Object.keys(RouterDecorator.__classPrefix__).forEach(cl => { - const controllerPrefixData = RouterDecorator.__classPrefix__[cl] || { - prefix: '', - beforeMiddlewares: [], - baseFn: [], - target: {} - }; - const setCArr = cArr.filter(c => { - if (RouterDecorator.__classPrefix__[cl].baseFn.includes(c.url.replace('/', ''))) { - return c; - } - }); - setCArr.forEach(cf => { - let fullUrl = `${options.prefix}${controllerPrefixData.prefix}${cf.url}`; - console.log(`>>>>>>>>comm register URL * ${cf.httpMethod.toUpperCase()} ${fullUrl} * ${cl}.${cf.handlerName}`); - app.router[cf.httpMethod](fullUrl, ...controllerPrefixData.beforeMiddlewares, ...cf.beforeMiddlewares, (ctx) => tslib_1.__awaiter(this, void 0, void 0, function* () { - const ist = new controllerPrefixData.target(ctx); - yield ist[cf.handlerName](ctx); - })); - }); - }); - } -} - -/** - * 记录各个class的prefix以及相关中间件 - * 最后统一设置 - * @private - * @static - * @type {ClassPrefix} - * @memberof RouterDecorator - */ -RouterDecorator.__classPrefix__ = {}; -/** - * 记录各个routerUrl的路由配置 - * 最后统一设置 - * @private - * @static - * @type {Router} - * @memberof RouterDecorator - */ -RouterDecorator.__router__ = {}; -/** 暴露注册路由方法 */ -exports.initRouter = RouterDecorator.initRouter; -/** 暴露实例的prefix和http的各个方法 */ -exports.default = new RouterDecorator(); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBb0NBLGNBQWM7QUFDZCxNQUFNLFlBQVksR0FBRyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFLdkUsTUFBTSxlQUFlO0lBNkJqQjtRQUNJLFlBQVksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEVBQUU7WUFDOUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBVyxFQUFFLEdBQUcsaUJBQStCLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBVyxFQUFFLElBQVksRUFBRSxFQUFFO2dCQUNsRyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsRUFBRTtvQkFDcEIsVUFBVTtvQkFDVixpQkFBaUI7b0JBQ2pCLFdBQVcsRUFBRSxJQUFJO29CQUNqQixhQUFhLEVBQUUsTUFBTSxDQUFDLFdBQVc7b0JBQ2pDLFNBQVMsRUFBRSxNQUFNLENBQUMsV0FBVyxDQUFDLElBQUk7aUJBQ3JDLENBQUMsQ0FBQztZQUNQLENBQUMsQ0FBQTtRQUNMLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQztJQUVELGFBQWE7SUFDTCxhQUFhLENBQUUsR0FBVyxFQUFFLFlBQTBCO1FBQzFELGVBQWUsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEdBQUcsZUFBZSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDeEUsZUFBZSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDdkQsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0ksTUFBTSxDQUFFLFNBQWlCLEVBQUUsR0FBRyxpQkFBK0I7UUFDaEUsT0FBTyxVQUFVLHFCQUFxQjtZQUNsQyxlQUFlLENBQUMsZUFBZSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxHQUFHO2dCQUMxRCxNQUFNLEVBQUUsU0FBUztnQkFDakIsaUJBQWlCLEVBQUUsaUJBQWlCO2FBQ3ZDLENBQUM7WUFDRixPQUFPLHFCQUFxQixDQUFDO1FBQ2pDLENBQUMsQ0FBQTtJQUNMLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxNQUFNLENBQUMsVUFBVSxDQUFFLEdBQWdCLEVBQUUsT0FBTyxHQUFHLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRTtRQUNoRSxNQUFNLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDbEQsZUFBZSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFpQixFQUFFLEVBQUU7Z0JBQzFELE1BQU0sb0JBQW9CLEdBQUcsZUFBZSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLGlCQUFpQixFQUFFLEVBQUUsRUFBRSxDQUFDO2dCQUNySCxNQUFNLE9BQU8sR0FBRyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUcsb0JBQW9CLENBQUMsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDO2dCQUN4RSxPQUFPLENBQUMsR0FBRyxDQUFDLHVDQUF1QyxHQUFHLENBQUMsVUFBVSxDQUFDLFdBQVcsRUFBRSxJQUFJLE9BQU8sTUFBTSxHQUFHLENBQUMsU0FBUyxJQUFJLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO2dCQUNwSSxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxPQUFPLEVBQUUsR0FBRyxvQkFBb0IsQ0FBQyxpQkFBaUIsRUFBRSxHQUFHLEdBQUcsQ0FBQyxpQkFBaUIsRUFBRSxDQUFPLEdBQUcsRUFBRSxFQUFFO29CQUNuSCxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQ3ZDLE1BQU0sR0FBRyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDcEMsQ0FBQyxDQUFBLENBQUMsQ0FBQztZQUNQLENBQUMsQ0FBQyxDQUFBO1FBQ04sQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDOztBQTlFRDs7Ozs7OztHQU9HO0FBQ1ksK0JBQWUsR0FBZ0IsRUFBRSxDQUFBO0FBRWhEOzs7Ozs7O0dBT0c7QUFDWSwwQkFBVSxHQUFXLEVBQUUsQ0FBQTtBQStEMUMsZUFBZTtBQUNGLFFBQUEsVUFBVSxHQUFHLGVBQWUsQ0FBQyxVQUFVLENBQUM7QUFFckQsNEJBQTRCO0FBQzVCLGtCQUFlLElBQUksZUFBZSxFQUFFLENBQUMifQ== diff --git a/app/router.ts b/app/router.ts index 634d243..feda688 100644 --- a/app/router.ts +++ b/app/router.ts @@ -1,5 +1,5 @@ import { Application } from 'egg'; -import { initRouter } from '../app/lib/router'; +import { initRouter } from 'egg-cool-router'; export default (app: Application) => { initRouter(app); diff --git a/app/service/comm/data.ts b/app/service/comm/data.ts index 55bf793..6b42a53 100644 --- a/app/service/comm/data.ts +++ b/app/service/comm/data.ts @@ -1,4 +1,4 @@ -import { BaseService } from '../../lib/base/service'; +import { BaseService } from 'egg-cool-service'; /** * 基础数据操作服务类 diff --git a/app/service/comm/file.ts b/app/service/comm/file.ts index 41ae78a..ac5f017 100644 --- a/app/service/comm/file.ts +++ b/app/service/comm/file.ts @@ -1,4 +1,4 @@ -import { BaseService } from '../../lib/base/service'; +import { BaseService } from 'egg-cool-service'; import * as moment from 'moment'; import * as uuid from 'uuid/v1'; import axios from 'axios'; diff --git a/app/service/comm/verify.ts b/app/service/comm/verify.ts deleted file mode 100644 index fe78215..0000000 --- a/app/service/comm/verify.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { BaseService } from '../../lib/base/service'; - -import * as uuid from 'uuid/v1'; -import * as svgCaptcha from 'svg-captcha'; -import * as svgToDataURL from 'svg-to-dataurl'; - -/** - * 验证 Service - */ -export default class Verify extends BaseService { - - /** - * 获得svg验证码 验证方式都换为小写比对 有效时间为30分钟 - * @param params type验证码类型,如需在,src下直接赋值,可以传type值为 dataUrl - */ - public async captcha (params) { - const { type, width = 150, height = 50 } = params; - svgCaptcha.options.width = width; - svgCaptcha.options.height = height; - const svg = svgCaptcha.create({ color: true, background: '#fff' }); - const result = { - captchaId: uuid(), - data: svg.data.replace(/\"/g, "'"), - }; - if (type === 'dataUrl') { - result.data = svgToDataURL(result.data); - } - await this.app.redisSet(`verify:img:${ result.captchaId }`, svg.text.toLowerCase(), 1800); - return result; - } - - /** - * 检验图片验证码 - * @param captchaId 验证码ID - * @param value 验证码 - */ - public async check (captchaId, value) { - const rv = await this.app.redisGet(`verify:img:${ captchaId }`); - if (!rv || !value || value.toLowerCase() !== rv) { - return false; - } else { - this.app.redisDel(`verify:img:${ captchaId }`); - return true; - } - } -} diff --git a/config/config.default.ts b/config/config.default.ts index 3cf07e9..08252ab 100644 --- a/config/config.default.ts +++ b/config/config.default.ts @@ -52,14 +52,6 @@ export default (appInfo: EggAppInfo) => { whitelist, }; - config.redis = { - client: { - port: 6379, - host: '127.0.0.1', - password: '', - db: 0, - }, - }; // 新增特殊的业务配置 const bizConfig = { sourceUrl: `https://github.com/eggjs/examples/tree/master/${ appInfo.name }` diff --git a/config/plugin.ts b/config/plugin.ts index a637b85..fcae294 100644 --- a/config/plugin.ts +++ b/config/plugin.ts @@ -13,10 +13,6 @@ const plugin: EggPlugin = { enable: true, package: 'egg-oss', }, - redis: { - enable: true, - package: 'egg-redis', - }, }; export default plugin; diff --git a/package.json b/package.json index cd94932..182dcdc 100644 --- a/package.json +++ b/package.json @@ -27,16 +27,18 @@ "egg": "^2.6.1", "egg-jwt": "^3.1.6", "egg-oss": "^2.0.0", - "egg-redis": "^2.4.0", "egg-scripts": "^2.6.0", "egg-ts-typeorm": "^1.1.12", + "egg-cool-cache": "^1.2.4", + "egg-cool-controller": "^1.2.4", + "egg-cool-entity": "^1.2.3", + "egg-cool-router": "^1.2.2", + "egg-cool-service": "^1.2.2", "ipip-ipdb": "^0.3.0", "lodash": "^4.17.15", "md5": "^2.2.1", "moment": "^2.24.0", - "mysql": "^2.17.1", - "svg-captcha": "^1.4.0", - "svg-to-dataurl": "^1.0.0" + "mysql": "^2.17.1" }, "devDependencies": { "@types/mocha": "^2.2.40",