整理代码,新增eslint规则

This commit is contained in:
啊平 2021-03-03 15:31:07 +08:00
parent 46e745b8d1
commit 84b045bff5
56 changed files with 1674 additions and 1510 deletions

View File

@ -1,7 +1,22 @@
{ {
"extends": "./node_modules/mwts/", "extends": "./node_modules/mwts/",
"ignorePatterns": ["node_modules", "dist", "test", "jest.config.js", "typings"], "ignorePatterns": [
"node_modules",
"dist",
"test",
"jest.config.js",
"typings",
"src/app/public/**/**",
"src/app/view/**/**"
],
"env": { "env": {
"jest": true "jest": true
},
"rules": {
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-unused-vars": "off",
"node/no-extraneous-import": "off",
"no-empty": "off",
"node/no-extraneous-require": "off"
} }
} }

2
bootstrap.js vendored
View File

@ -1,6 +1,6 @@
const WebFramework = require('@midwayjs/web').Framework; const WebFramework = require('@midwayjs/web').Framework;
const web = new WebFramework().configure({ const web = new WebFramework().configure({
port: 8001, port: 8001,
}); });
const { Bootstrap } = require('@midwayjs/bootstrap'); const { Bootstrap } = require('@midwayjs/bootstrap');

View File

@ -14,6 +14,8 @@
"jsonwebtoken": "^8.5.1", "jsonwebtoken": "^8.5.1",
"md5": "^2.3.0", "md5": "^2.3.0",
"midwayjs-cool-core": "/Users/ap/Documents/srcs/cool-admin/midway-core/core/dist", "midwayjs-cool-core": "/Users/ap/Documents/srcs/cool-admin/midway-core/core/dist",
"midwayjs-cool-oss": "^1.0.0",
"midwayjs-cool-redis": "/Users/ap/Documents/srcs/cool-admin/midway-core/redis/dist",
"mysql2": "^2.2.5", "mysql2": "^2.2.5",
"svg-captcha": "^1.4.0", "svg-captcha": "^1.4.0",
"svg-to-dataurl": "^1.0.0" "svg-to-dataurl": "^1.0.0"

View File

@ -8,60 +8,62 @@ import { Context } from 'egg';
*/ */
@Provide() @Provide()
export class Utils { export class Utils {
@Inject()
baseDir;
@Inject() /**
baseDir; * IP
*/
async getReqIP(ctx: Context) {
const req = ctx.req;
return (
req.headers['x-forwarded-for'] ||
req.socket.remoteAddress.replace('::ffff:', '')
);
}
/** /**
* IP * IP获得请求地址
*/ * @param ip IP地址
async getReqIP(ctx: Context) { */
const req = ctx.req; async getIpAddr(ctx: Context, ip?: string | string[]) {
return req.headers['x-forwarded-for'] || req.socket.remoteAddress.replace('::ffff:', ''); try {
if (!ip) {
ip = await this.getReqIP(ctx);
}
const bst = new ipdb.BaseStation(
`${this.baseDir}/app/comm/ipipfree.ipdb`
);
const result = bst.findInfo(ip, 'CN');
const addArr: any = [];
if (result) {
addArr.push(result.countryName);
addArr.push(result.regionName);
addArr.push(result.cityName);
return _.uniq(addArr).join('');
}
} catch (err) {
return '无法获取地址信息';
} }
}
/** /**
* IP获得请求地址 *
* @param ip IP地址 * @param obj
*/ */
async getIpAddr(ctx: Context, ip?: string | string[]) { async removeEmptyP(obj) {
try { Object.keys(obj).forEach(key => {
if (!ip) { if (obj[key] === null || obj[key] === '' || obj[key] === 'undefined') {
ip = await this.getReqIP(ctx); delete obj[key];
} }
const bst = new ipdb.BaseStation(`${this.baseDir}/app/comm/ipipfree.ipdb`); });
const result = bst.findInfo(ip, 'CN'); }
const addArr: any = [];
if (result) {
addArr.push(result.countryName);
addArr.push(result.regionName);
addArr.push(result.cityName);
return _.uniq(addArr).join('');
}
// @ts-ignore
} catch (err) {
console.log(err)
return '无法获取地址信息';
}
}
/** /**
* * 线
* @param obj * @param ms
*/ */
async removeEmptyP(obj) { sleep(ms) {
Object.keys(obj).forEach(key => { return new Promise(resolve => setTimeout(resolve, ms));
if (obj[key] === null || obj[key] === '' || obj[key] === 'undefined') { }
delete obj[key];
}
});
}
/**
* 线
* @param ms
*/
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
} }

View File

@ -1,16 +1,16 @@
import { Application } from "egg"; import { Application } from 'egg';
import { ModuleConfig } from 'midwayjs-cool-core'; import { ModuleConfig } from 'midwayjs-cool-core';
/** /**
* *
*/ */
export default (app: Application) => { export default (app: Application) => {
return { return {
// 模块名称 // 模块名称
name: '权限管理', name: '权限管理',
// 模块描述 // 模块描述
description: '基础的权限管理功能,包括登录,权限校验', description: '基础的权限管理功能,包括登录,权限校验',
// 中间件 // 中间件
middlewares: ['baseAuthorityMiddleware', 'baseLogMiddleware'], middlewares: ['baseAuthorityMiddleware', 'baseLogMiddleware'],
} as ModuleConfig; } as ModuleConfig;
}; };

View File

@ -12,70 +12,70 @@ import { BaseSysUserService } from '../../service/sys/user';
@Provide() @Provide()
@CoolController() @CoolController()
export class BaseCommController extends BaseController { export class BaseCommController extends BaseController {
@Inject()
baseSysUserService: BaseSysUserService;
@Inject() @Inject()
baseSysUserService: BaseSysUserService; baseSysPermsService: BaseSysPermsService;
@Inject() @Inject()
baseSysPermsService: BaseSysPermsService; baseSysLoginService: BaseSysLoginService;
@Inject() @Inject()
baseSysLoginService: BaseSysLoginService; ctx: Context;
@Inject() @Inject('cool:file')
ctx: Context; coolFile: CoolFile;
@Inject('cool:file') /**
coolFile: CoolFile; *
*/
@Get('/person')
async person() {
return this.ok(await this.baseSysUserService.person());
}
/** /**
* *
*/ */
@Get('/person') @Post('/personUpdate')
async person() { async personUpdate(@Body(ALL) user: BaseSysUserEntity) {
return this.ok(await this.baseSysUserService.person()); await this.baseSysUserService.personUpdate(user);
} return this.ok();
}
/** /**
* *
*/ */
@Post('/personUpdate') @Get('/permmenu')
async personUpdate(@Body(ALL) user: BaseSysUserEntity) { async permmenu() {
await this.baseSysUserService.personUpdate(user); return this.ok(
return this.ok(); await this.baseSysPermsService.permmenu(this.ctx.admin.roleIds)
} );
}
/** /**
* *
*/ */
@Get('/permmenu') @Post('/upload')
async permmenu() { async upload() {
return this.ok(await this.baseSysPermsService.permmenu(this.ctx.admin.roleIds)); return this.ok(await this.coolFile.upload(this.ctx));
} }
/** /**
* *
*/ */
@Post('/upload') @Get('/uploadMode')
async upload() { async uploadMode() {
return this.ok(await this.coolFile.upload(this.ctx)); return this.ok(this.coolFile.getMode());
} }
/**
*
*/
@Get('/uploadMode')
async uploadMode() {
return this.ok(this.coolFile.getMode());
}
/**
* 退
*/
@Post('/logout')
async logout() {
await this.baseSysLoginService.logout();
return this.ok();
}
/**
* 退
*/
@Post('/logout')
async logout() {
await this.baseSysLoginService.logout();
return this.ok();
}
} }

View File

@ -1,4 +1,12 @@
import { Provide, Body, ALL, Inject, Post, Get, Query } from '@midwayjs/decorator'; import {
Provide,
Body,
ALL,
Inject,
Post,
Get,
Query,
} from '@midwayjs/decorator';
import { Context } from 'egg'; import { Context } from 'egg';
import { CoolController, BaseController } from 'midwayjs-cool-core'; import { CoolController, BaseController } from 'midwayjs-cool-core';
import { LoginDTO } from '../../dto/login'; import { LoginDTO } from '../../dto/login';
@ -11,46 +19,49 @@ import { BaseSysParamService } from '../../service/sys/param';
@Provide() @Provide()
@CoolController() @CoolController()
export class BaseSysOpenController extends BaseController { export class BaseSysOpenController extends BaseController {
@Inject()
baseSysLoginService: BaseSysLoginService;
@Inject() @Inject()
baseSysLoginService: BaseSysLoginService; baseSysParamService: BaseSysParamService;
@Inject() @Inject()
baseSysParamService: BaseSysParamService; ctx: Context;
@Inject() /**
ctx: Context; * key获得网页内容()
*/
@Get('/html')
async htmlByKey(@Query() key: string) {
this.ctx.body = await this.baseSysParamService.htmlByKey(key);
}
/** /**
* key获得网页内容() *
*/ * @param login
@Get('/html') */
async htmlByKey(@Query() key: string) { @Post('/login')
this.ctx.body = await this.baseSysParamService.htmlByKey(key); async login(@Body(ALL) login: LoginDTO) {
} return this.ok(await this.baseSysLoginService.login(login));
}
/** /**
* *
* @param login */
*/ @Get('/captcha')
@Post('/login') async captcha(
async login(@Body(ALL) login: LoginDTO) { @Query() type: string,
return this.ok(await this.baseSysLoginService.login(login)) @Query() width: number,
} @Query() height: number
) {
return this.ok(await this.baseSysLoginService.captcha(type, width, height));
}
/** /**
* * token
*/ */
@Get('/captcha') @Get('/refreshToken')
async captcha(@Query() type: string, @Query() width: number, @Query() height: number) { async refreshToken(@Query() refreshToken: string) {
return this.ok(await this.baseSysLoginService.captcha(type, width, height)); return this.ok(await this.baseSysLoginService.refreshToken(refreshToken));
} }
/**
* token
*/
@Get('/refreshToken')
async refreshToken(@Query() refreshToken: string) {
return this.ok(await this.baseSysLoginService.refreshToken(refreshToken))
}
} }

View File

@ -8,45 +8,44 @@ import { BasePluginInfoService } from '../../../service/plugin/info';
@Provide() @Provide()
@CoolController() @CoolController()
export class BasePluginInfoController extends BaseController { export class BasePluginInfoController extends BaseController {
@Inject()
basePluginInfoService: BasePluginInfoService;
/**
*
*/
@Post('/list')
async list(@Body() keyWord: string) {
return this.ok(await this.basePluginInfoService.list(keyWord));
}
@Inject() /**
basePluginInfoService: BasePluginInfoService; *
/** * @param namespace
* * @param config
*/ */
@Post('/list') @Post('/config')
async list(@Body() keyWord: string) { async config(@Body() namespace: string, @Body() config: any) {
return this.ok(await this.basePluginInfoService.list(keyWord)) await this.basePluginInfoService.config(namespace, config);
} return this.ok();
}
/** /**
* *
* @param namespace * @param namespace
* @param config * @param config
*/ */
@Post('/config') @Get('/getConfig')
async config(@Body() namespace: string, @Body() config: any) { async getConfig(@Query() namespace: string) {
await this.basePluginInfoService.config(namespace, config); return this.ok(await this.basePluginInfoService.getConfig(namespace));
return this.ok(); }
}
/** /**
* *
* @param namespace * @param enable
* @param config */
*/ @Post('/enable')
@Get('/getConfig') async enable(@Body() namespace: string, @Body() enable: number) {
async getConfig(@Query() namespace: string) { await this.basePluginInfoService.enable(namespace, enable);
return this.ok(await this.basePluginInfoService.getConfig(namespace)); return this.ok();
} }
/**
*
* @param enable
*/
@Post('/enable')
async enable(@Body() namespace: string, @Body() enable: number) {
await this.basePluginInfoService.enable(namespace, enable);
return this.ok();
}
} }

View File

@ -8,22 +8,20 @@ import { BaseSysDepartmentService } from '../../../service/sys/department';
*/ */
@Provide() @Provide()
@CoolController({ @CoolController({
api: ['add', 'delete', 'update', 'list'], api: ['add', 'delete', 'update', 'list'],
entity: BaseSysDepartmentEntity, entity: BaseSysDepartmentEntity,
service: BaseSysDepartmentService service: BaseSysDepartmentService,
}) })
export class BaseDepartmentController extends BaseController { export class BaseDepartmentController extends BaseController {
@Inject()
baseDepartmentService: BaseSysDepartmentService;
@Inject() /**
baseDepartmentService: BaseSysDepartmentService; *
*/
/** @Post('/order')
* async order(@Body(ALL) params: any) {
*/ await this.baseDepartmentService.order(params);
@Post('/order') return this.ok();
async order(@Body(ALL) params: Object) { }
await this.baseDepartmentService.order(params);
return this.ok();
}
} }

View File

@ -10,51 +10,50 @@ import { BaseSysLogService } from '../../../service/sys/log';
*/ */
@Provide() @Provide()
@CoolController({ @CoolController({
api: ['page'], api: ['page'],
entity: BaseSysLogEntity, entity: BaseSysLogEntity,
pageQueryOp: { pageQueryOp: {
keyWordLikeFields: ['b.name', 'a.params', 'a.ipAddr'], keyWordLikeFields: ['b.name', 'a.params', 'a.ipAddr'],
select: ['a.*, b.name'], select: ['a.*, b.name'],
leftJoin: [{ leftJoin: [
entity: BaseSysUserEntity, {
alias: 'b', entity: BaseSysUserEntity,
condition: 'a.userId = b.id' alias: 'b',
}] condition: 'a.userId = b.id',
} },
],
},
}) })
export class BaseSysLogController extends BaseController { export class BaseSysLogController extends BaseController {
@Inject()
baseSysLogService: BaseSysLogService;
@Inject() @Inject()
baseSysLogService: BaseSysLogService; baseSysConfService: BaseSysConfService;
@Inject() /**
baseSysConfService: BaseSysConfService; *
*/
@Post('/clear')
public async clear() {
await this.baseSysLogService.clear(true);
return this.ok();
}
/** /**
* *
*/ */
@Post('/clear') @Post('/setKeep')
public async clear() { public async setKeep(@Body() value: number) {
await this.baseSysLogService.clear(true); await this.baseSysConfService.updateVaule('logKeep', value);
return this.ok(); return this.ok();
} }
/**
*
*/
@Post('/setKeep')
public async setKeep(@Body() value: number) {
await this.baseSysConfService.updateVaule('logKeep', value);
return this.ok();
}
/**
*
*/
@Get('/getKeep')
public async getKeep() {
return this.ok(await this.baseSysConfService.getValue('logKeep'));
}
/**
*
*/
@Get('/getKeep')
public async getKeep() {
return this.ok(await this.baseSysConfService.getValue('logKeep'));
}
} }

View File

@ -8,13 +8,11 @@ import { BaseSysMenuService } from '../../../service/sys/menu';
*/ */
@Provide() @Provide()
@CoolController({ @CoolController({
api: ['add', 'delete', 'update', 'info', 'list', 'page'], api: ['add', 'delete', 'update', 'info', 'list', 'page'],
entity: BaseSysMenuEntity, entity: BaseSysMenuEntity,
service: BaseSysMenuService service: BaseSysMenuService,
}) })
export class BaseSysMenuController extends BaseController { export class BaseSysMenuController extends BaseController {
@Inject()
@Inject() baseSysMenuService: BaseSysMenuService;
baseSysMenuService: BaseSysMenuService;
} }

View File

@ -9,26 +9,24 @@ import { BaseSysParamService } from '../../../service/sys/param';
*/ */
@Provide() @Provide()
@CoolController({ @CoolController({
api: ['add', 'delete', 'update', 'info', 'page'], api: ['add', 'delete', 'update', 'info', 'page'],
entity: BaseSysParamEntity, entity: BaseSysParamEntity,
pageQueryOp: { pageQueryOp: {
keyWordLikeFields: ['name', 'keyName'] keyWordLikeFields: ['name', 'keyName'],
} },
}) })
export class BaseSysParamController extends BaseController { export class BaseSysParamController extends BaseController {
@Inject()
baseSysParamService: BaseSysParamService;
@Inject() @Inject()
baseSysParamService: BaseSysParamService; ctx: Context;
@Inject()
ctx: Context;
/**
* key获得网页内容()
*/
@Get('/html')
async htmlByKey(@Query() key: string) {
this.ctx.body = await this.baseSysParamService.htmlByKey(key);
}
/**
* key获得网页内容()
*/
@Get('/html')
async htmlByKey(@Query() key: string) {
this.ctx.body = await this.baseSysParamService.htmlByKey(key);
}
} }

View File

@ -13,24 +13,26 @@ import { BaseSysRoleService } from '../../../service/sys/role';
entity: BaseSysRoleEntity, entity: BaseSysRoleEntity,
service: BaseSysRoleService, service: BaseSysRoleService,
// 新增的时候插入当前用户ID // 新增的时候插入当前用户ID
insertParam: (async (ctx: Context) => { insertParam: async (ctx: Context) => {
return { return {
userId: ctx.admin.userId userId: ctx.admin.userId,
} };
}), },
pageQueryOp: { pageQueryOp: {
keyWordLikeFields: ['name', 'label'], keyWordLikeFields: ['name', 'label'],
where: (async (ctx: Context) => { where: async (ctx: Context) => {
const { userId, roleIds, role } = ctx.admin; const { userId, roleIds, role } = ctx.admin;
return [ return [
// 超级管理员的角色不展示 // 超级管理员的角色不展示
['label != :label', { label: 'admin' }], ['label != :label', { label: 'admin' }],
// 如果不是超管,只能看到自己新建的或者自己有的角色 // 如果不是超管,只能看到自己新建的或者自己有的角色
['(userId=:userId or id in (:roleIds))', { userId, roleIds }, role != 'admin'] [
] '(userId=:userId or id in (:roleIds))',
}) { userId, roleIds },
} role !== 'admin',
],
];
},
},
}) })
export class BaseSysRoleController extends BaseController { export class BaseSysRoleController extends BaseController {}
}

View File

@ -8,22 +8,20 @@ import { BaseSysUserService } from '../../../service/sys/user';
*/ */
@Provide() @Provide()
@CoolController({ @CoolController({
api: ['add', 'delete', 'update', 'info', 'list', 'page'], api: ['add', 'delete', 'update', 'info', 'list', 'page'],
entity: BaseSysUserEntity, entity: BaseSysUserEntity,
service: BaseSysUserService service: BaseSysUserService,
}) })
export class BaseSysUserController extends BaseController { export class BaseSysUserController extends BaseController {
@Inject()
baseSysUserService: BaseSysUserService;
@Inject() /**
baseSysUserService: BaseSysUserService; *
*/
/** @Post('/move')
* async move(@Body() departmentId: number, @Body() userIds: []) {
*/ await this.baseSysUserService.move(departmentId, userIds);
@Post('/move') return this.ok();
async move(@Body() departmentId: number, @Body() userIds: []) { }
await this.baseSysUserService.move(departmentId, userIds);
return this.ok();
}
} }

View File

@ -3,20 +3,19 @@ import { Rule, RuleType } from '@midwayjs/decorator';
* *
*/ */
export class LoginDTO { export class LoginDTO {
// 用户名 // 用户名
@Rule(RuleType.string().required()) @Rule(RuleType.string().required())
username: string; username: string;
// 密码 // 密码
@Rule(RuleType.string().required()) @Rule(RuleType.string().required())
password: number; password: number;
// 验证码ID // 验证码ID
@Rule(RuleType.string().required()) @Rule(RuleType.string().required())
captchaId: string; captchaId: string;
// 验证码
@Rule(RuleType.string().required())
verifyCode: number;
// 验证码
@Rule(RuleType.string().required())
verifyCode: number;
} }

View File

@ -7,14 +7,12 @@ import { Column } from 'typeorm';
*/ */
@EntityModel('base_app_space_info') @EntityModel('base_app_space_info')
export class BaseAppSpaceInfoEntity extends BaseEntity { export class BaseAppSpaceInfoEntity extends BaseEntity {
@Column({ comment: '地址' })
url: string;
@Column({comment: '地址'}) @Column({ comment: '类型' })
url: string; type: string;
@Column({comment: '类型'})
type: string;
@Column({comment:'分类ID', type: 'bigint', nullable: true })
classifyId: number;
@Column({ comment: '分类ID', type: 'bigint', nullable: true })
classifyId: number;
} }

View File

@ -7,11 +7,9 @@ import { Column } from 'typeorm';
*/ */
@EntityModel('base_app_space_type') @EntityModel('base_app_space_type')
export class BaseAppSpaceTypeEntity extends BaseEntity { export class BaseAppSpaceTypeEntity extends BaseEntity {
@Column({ comment: '类别名称' })
name: string;
@Column({ comment: '类别名称' }) @Column({ comment: '父分类ID', type: 'tinyint', nullable: true })
name: string; parentId: number;
@Column({ comment: '父分类ID', type: 'tinyint', nullable: true })
parentId: number;
} }

View File

@ -7,11 +7,10 @@ import { BaseEntity } from 'midwayjs-cool-core';
*/ */
@EntityModel('base_sys_conf') @EntityModel('base_sys_conf')
export class BaseSysConfEntity extends BaseEntity { export class BaseSysConfEntity extends BaseEntity {
@Index({ unique: true })
@Column({ comment: '配置键' })
cKey: string;
@Index({ unique: true }) @Column({ comment: '配置值' })
@Column({ comment: '配置键' }) cValue: string;
cKey: string;
@Column({ comment: '配置值' })
cValue: string;
} }

View File

@ -7,16 +7,14 @@ import { Column } from 'typeorm';
*/ */
@EntityModel('base_sys_department') @EntityModel('base_sys_department')
export class BaseSysDepartmentEntity extends BaseEntity { export class BaseSysDepartmentEntity extends BaseEntity {
@Column({ comment: '部门名称' })
name: string;
@Column({ comment: '部门名称' }) @Column({ comment: '上级部门ID', type: 'bigint', nullable: true })
name: string; parentId: number;
@Column({ comment: '上级部门ID', type: 'bigint', nullable: true })
parentId: number;
@Column({ comment: '排序', default: 0 })
orderNum: number;
// 父菜单名称
parentName: string;
@Column({ comment: '排序', default: 0 })
orderNum: number;
// 父菜单名称
parentName: string;
} }

View File

@ -7,24 +7,22 @@ import { Column, Index } from 'typeorm';
*/ */
@EntityModel('base_sys_log') @EntityModel('base_sys_log')
export class BaseSysLogEntity extends BaseEntity { export class BaseSysLogEntity extends BaseEntity {
@Index()
@Column({ comment: '用户ID', nullable: true, type: 'bigint' })
userId: number;
@Index() @Index()
@Column({ comment: '用户ID', nullable: true, type: 'bigint' }) @Column({ comment: '行为', length: 100 })
userId: number; action: string;
@Index() @Index()
@Column({ comment: '行为', length: 100 }) @Column({ comment: 'ip', nullable: true, length: 50 })
action: string; ip: string;
@Index() @Index()
@Column({ comment: 'ip', nullable: true, length: 50 }) @Column({ comment: 'ip地址', nullable: true, length: 50 })
ip: string; ipAddr: string;
@Index()
@Column({ comment: 'ip地址', nullable: true, length: 50 })
ipAddr: string;
@Column({ comment: '参数', nullable: true, type: 'text' })
params: string;
@Column({ comment: '参数', nullable: true, type: 'text' })
params: string;
} }

View File

@ -7,41 +7,43 @@ import { Column } from 'typeorm';
*/ */
@EntityModel('base_sys_menu') @EntityModel('base_sys_menu')
export class BaseSysMenuEntity extends BaseEntity { export class BaseSysMenuEntity extends BaseEntity {
@Column({ comment: '父菜单ID', type: 'bigint', nullable: true })
parentId: number;
@Column({ comment: '父菜单ID', type: 'bigint', nullable: true }) @Column({ comment: '菜单名称' })
parentId: number; name: string;
@Column({ comment: '菜单名称' }) @Column({ comment: '菜单地址', nullable: true })
name: string; router: string;
@Column({ comment: '菜单地址', nullable: true }) @Column({ comment: '权限标识', nullable: true })
router: string; perms: string;
@Column({ comment: '权限标识', nullable: true }) @Column({
perms: string; comment: '类型 0目录 1菜单 2按钮',
default: 0,
type: 'tinyint',
})
type: number;
@Column({ comment: '类型 0目录 1菜单 2按钮', default: 0, type: 'tinyint' }) @Column({ comment: '图标', nullable: true })
type: number; icon: string;
@Column({ comment: '图标', nullable: true }) @Column({ comment: '排序', default: 0 })
icon: string; orderNum: number;
@Column({ comment: '排序', default: 0 }) @Column({ comment: '视图地址', nullable: true })
orderNum: number; viewPath: string;
@Column({ comment: '视图地址', nullable: true }) @Column({ comment: '路由缓存', default: true })
viewPath: string; keepAlive: boolean;
@Column({ comment: '路由缓存', default: true }) // 父菜单名称
keepAlive: boolean; parentName: string;
// 父菜单名称 @Column({ comment: '父菜单名称', default: true })
parentName: string; isShow: boolean;
@Column({ comment: '父菜单名称', default: true })
isShow: boolean;
@Column({ comment: '模块名', nullable: true })
moduleName: string;
@Column({ comment: '模块名', nullable: true })
moduleName: string;
} }

View File

@ -7,21 +7,23 @@ import { Column, Index } from 'typeorm';
*/ */
@EntityModel('base_sys_param') @EntityModel('base_sys_param')
export class BaseSysParamEntity extends BaseEntity { export class BaseSysParamEntity extends BaseEntity {
@Index()
@Column({ comment: '键位' })
keyName: string;
@Index() @Column({ comment: '名称' })
@Column({ comment: '键位' }) name: string;
keyName: string;
@Column({comment: '名称'}) @Column({ comment: '数据', type: 'text' })
name: string; data: string;
@Column({comment: '数据', type: 'text' }) @Column({
data: string; comment: '数据类型 0:字符串 1数组 2键值对',
default: 0,
@Column({comment: '数据类型 0:字符串 1数组 2键值对', default: 0, type: 'tinyint' }) type: 'tinyint',
dataType: number; })
dataType: number;
@Column({ comment: '备注', nullable: true })
remark: string;
@Column({ comment: '备注', nullable: true })
remark: string;
} }

View File

@ -7,22 +7,20 @@ import { Column, Index } from 'typeorm';
*/ */
@EntityModel('base_sys_role') @EntityModel('base_sys_role')
export class BaseSysRoleEntity extends BaseEntity { export class BaseSysRoleEntity extends BaseEntity {
@Column({ comment: '用户ID' })
userId: string;
@Column({ comment: '用户ID' }) @Index({ unique: true })
userId: string; @Column({ comment: '名称' })
name: string;
@Index({ unique: true }) @Index({ unique: true })
@Column({ comment: '名称' }) @Column({ comment: '角色标签', nullable: true, length: 50 })
name: string; label: string;
@Index({ unique: true }) @Column({ comment: '备注', nullable: true })
@Column({ comment: '角色标签', nullable: true, length: 50 }) remark: string;
label: string;
@Column({ comment: '备注', nullable: true })
remark: string;
@Column({ comment: '数据权限是否关联上下级', default: 1 })
relevance: number;
@Column({ comment: '数据权限是否关联上下级', default: 1 })
relevance: number;
} }

View File

@ -7,11 +7,9 @@ import { Column } from 'typeorm';
*/ */
@EntityModel('base_sys_role_department') @EntityModel('base_sys_role_department')
export class BaseSysRoleDepartmentEntity extends BaseEntity { export class BaseSysRoleDepartmentEntity extends BaseEntity {
@Column({ comment: '角色ID', type: 'bigint' })
roleId: number;
@Column({ comment: '角色ID', type: 'bigint' }) @Column({ comment: '部门ID', type: 'bigint' })
roleId: number; departmentId: number;
@Column({ comment: '部门ID', type: 'bigint' })
departmentId: number;
} }

View File

@ -7,11 +7,9 @@ import { Column } from 'typeorm';
*/ */
@EntityModel('base_sys_role_menu') @EntityModel('base_sys_role_menu')
export class BaseSysRoleMenuEntity extends BaseEntity { export class BaseSysRoleMenuEntity extends BaseEntity {
@Column({ comment: '角色ID', type: 'bigint' })
roleId: number;
@Column({ comment: '角色ID', type: 'bigint' }) @Column({ comment: '菜单ID', type: 'bigint' })
roleId: number; menuId: number;
@Column({ comment: '菜单ID', type: 'bigint' })
menuId: number;
} }

View File

@ -7,44 +7,46 @@ import { Column, Index } from 'typeorm';
*/ */
@EntityModel('base_sys_user') @EntityModel('base_sys_user')
export class BaseSysUserEntity extends BaseEntity { export class BaseSysUserEntity extends BaseEntity {
@Index()
@Column({ comment: '部门ID', type: 'bigint', nullable: true })
departmentId: number;
@Index() @Column({ comment: '姓名', nullable: true })
@Column({ comment: '部门ID', type: 'bigint', nullable: true }) name: string;
departmentId: number;
@Column({ comment: '姓名', nullable: true }) @Index({ unique: true })
name: string; @Column({ comment: '用户名', length: 100 })
username: string;
@Index({ unique: true }) @Column({ comment: '密码' })
@Column({ comment: '用户名', length: 100 }) password: string;
username: string;
@Column({ comment: '密码' }) @Column({
password: string; comment: '密码版本, 作用是改完密码让原来的token失效',
default: 1,
})
passwordV: number;
@Column({ comment: '密码版本, 作用是改完密码让原来的token失效', default: 1 }) @Column({ comment: '昵称', nullable: true })
passwordV: number; nickName: string;
@Column({ comment: '昵称', nullable: true }) @Column({ comment: '头像', nullable: true })
nickName: string; headImg: string;
@Column({ comment: '头像', nullable: true }) @Index()
headImg: string; @Column({ comment: '手机', nullable: true, length: 20 })
phone: string;
@Index() @Column({ comment: '邮箱', nullable: true })
@Column({ comment: '手机', nullable: true, length: 20 }) email: string;
phone: string;
@Column({ comment: '邮箱', nullable: true }) @Column({ comment: '备注', nullable: true })
email: string; remark: string;
@Column({ comment: '备注', nullable: true }) @Column({ comment: '状态 0:禁用 1启用', default: 1, type: 'tinyint' })
remark: string; status: number;
// 部门名称
@Column({ comment: '状态 0:禁用 1启用', default: 1, type: 'tinyint' }) departmentName: string;
status: number; // 角色ID列表
// 部门名称 roleIdList: number[];
departmentName: string;
// 角色ID列表
roleIdList: number[];
} }

View File

@ -7,11 +7,9 @@ import { Column } from 'typeorm';
*/ */
@EntityModel('base_sys_user_role') @EntityModel('base_sys_user_role')
export class BaseSysUserRoleEntity extends BaseEntity { export class BaseSysUserRoleEntity extends BaseEntity {
@Column({ comment: '用户ID', type: 'bigint' })
userId: number;
@Column({ comment: '用户ID', type: 'bigint' }) @Column({ comment: '角色ID', type: 'bigint' })
userId: number; roleId: number;
@Column({ comment: '角色ID', type: 'bigint' })
roleId: number;
} }

View File

@ -10,93 +10,98 @@ import { Context } from 'egg';
*/ */
@Provide() @Provide()
export class BaseAuthorityMiddleware implements IWebMiddleware { export class BaseAuthorityMiddleware implements IWebMiddleware {
@Config('cool')
coolConfig: CoolConfig;
@Config('cool') @Inject('cool:cache')
coolConfig: CoolConfig; coolCache: CoolCache;
@Inject('cool:cache') resolve() {
coolCache: CoolCache; return async (ctx: Context, next: IMidwayWebNext) => {
let statusCode = 200;
resolve() { const { url } = ctx;
return async (ctx: Context, next: IMidwayWebNext) => { const token = ctx.get('Authorization');
let statusCode = 200; const { prefix } = this.coolConfig.router;
const { url } = ctx; const adminUrl = prefix ? `${prefix}/admin/` : '/admin/';
const token = ctx.get('Authorization'); // 路由地址为 admin前缀的 需要权限校验
let { prefix } = this.coolConfig.router; if (_.startsWith(url, adminUrl)) {
const adminUrl = prefix ? `${prefix}/admin/` : '/admin/'; try {
// 路由地址为 admin前缀的 需要权限校验 ctx.admin = jwt.verify(token, this.coolConfig.jwt.secret);
if (_.startsWith(url, adminUrl)) { } catch (err) {}
try { // 不需要登录 无需权限校验
ctx.admin = jwt.verify(token, this.coolConfig.jwt.secret); if (new RegExp(`^${adminUrl}?.*/open/`).test(url)) {
} catch (err) { } await next();
// 不需要登录 无需权限校验 return;
if (new RegExp(`^${adminUrl}?.*/open/`).test(url)) { }
await next(); if (ctx.admin) {
return; // 要登录每个人都有权限的接口
} if (new RegExp(`^${adminUrl}?.*/comm/`).test(url)) {
if (ctx.admin) {
// 要登录每个人都有权限的接口
if (new RegExp(`^${adminUrl}?.*/comm/`).test(url)) {
await next();
return;
}
// 如果传的token是refreshToken则校验失败
if (ctx.admin.isRefresh) {
ctx.status = 401;
ctx.body = {
code: RESCODE.COMMFAIL,
message: '登录失效~',
};
return;
}
// 判断密码版本是否正确
const passwordV = await this.coolCache.get(`admin:passwordVersion:${ctx.admin.userId}`);
if (passwordV !== ctx.admin.passwordVersion) {
ctx.status = 401;
ctx.body = {
code: RESCODE.COMMFAIL,
message: '登录失效~',
};
return;
}
const rToken = await this.coolCache.get(`admin:token:${ctx.admin.userId}`);
if (!rToken) {
ctx.status = 401;
ctx.body = {
code: RESCODE.COMMFAIL,
message: '登录失效或无权限访问~',
};
return;
}
if (rToken !== token && this.coolConfig.sso) {
statusCode = 401;
} else {
let perms = await this.coolCache.get(`admin:perms:${ctx.admin.userId}`);
if (!_.isEmpty(perms)) {
perms = JSON.parse(perms).map(e => {
return e.replace(/:/g, '/');
});
if (!perms.includes(url.split('?')[0].replace('/admin/', ''))) {
statusCode = 403;
}
} else {
statusCode = 403;
}
}
} else {
statusCode = 401;
}
if (statusCode > 200) {
ctx.status = statusCode;
ctx.body = {
code: RESCODE.COMMFAIL,
message: '登录失效或无权限访问~',
};
return;
}
}
await next(); await next();
}; return;
} }
// 如果传的token是refreshToken则校验失败
if (ctx.admin.isRefresh) {
ctx.status = 401;
ctx.body = {
code: RESCODE.COMMFAIL,
message: '登录失效~',
};
return;
}
// 判断密码版本是否正确
const passwordV = await this.coolCache.get(
`admin:passwordVersion:${ctx.admin.userId}`
);
console.log(6666666666, '密码版本', passwordV);
if (passwordV !== ctx.admin.passwordVersion) {
ctx.status = 401;
ctx.body = {
code: RESCODE.COMMFAIL,
message: '登录失效~',
};
return;
}
const rToken = await this.coolCache.get(
`admin:token:${ctx.admin.userId}`
);
if (!rToken) {
ctx.status = 401;
ctx.body = {
code: RESCODE.COMMFAIL,
message: '登录失效或无权限访问~',
};
return;
}
if (rToken !== token && this.coolConfig.sso) {
statusCode = 401;
} else {
let perms = await this.coolCache.get(
`admin:perms:${ctx.admin.userId}`
);
if (!_.isEmpty(perms)) {
perms = JSON.parse(perms).map(e => {
return e.replace(/:/g, '/');
});
if (!perms.includes(url.split('?')[0].replace('/admin/', ''))) {
statusCode = 403;
}
} else {
statusCode = 403;
}
}
} else {
statusCode = 401;
}
if (statusCode > 200) {
ctx.status = statusCode;
ctx.body = {
code: RESCODE.COMMFAIL,
message: '登录失效或无权限访问~',
};
return;
}
}
await next();
};
}
} }

View File

@ -8,15 +8,18 @@ import { Context } from 'egg';
*/ */
@Provide() @Provide()
export class BaseLogMiddleware implements IWebMiddleware { export class BaseLogMiddleware implements IWebMiddleware {
@Inject()
baseSysLogService: BaseSysLogService;
@Inject() resolve() {
baseSysLogService: BaseSysLogService; return async (ctx: Context, next: IMidwayWebNext) => {
this.baseSysLogService.record(
resolve() { ctx,
return async (ctx: Context, next: IMidwayWebNext) => { ctx.url.split('?')[0],
this.baseSysLogService.record(ctx, ctx.url.split('?')[0], ctx.req.method === 'GET' ? ctx.request.query : ctx.request.body, ctx.admin ? ctx.admin.userId : null); ctx.req.method === 'GET' ? ctx.request.query : ctx.request.body,
await next(); ctx.admin ? ctx.admin.userId : null
}; );
} await next();
};
}
} }

View File

@ -8,22 +8,21 @@ import { ILogger } from '@midwayjs/logger';
*/ */
@Provide() @Provide()
@Schedule({ @Schedule({
cron: '0 0 0 * * *', // 每天0点执行 cron: '0 0 0 * * *', // 每天0点执行
type: 'worker' // 指定某一个 worker 执行 type: 'worker', // 指定某一个 worker 执行
}) })
export class BaseLogSchedule implements CommonSchedule { export class BaseLogSchedule implements CommonSchedule {
@Inject()
baseSysLogService: BaseSysLogService;
@Inject() @Inject()
baseSysLogService: BaseSysLogService; logger: ILogger;
@Inject() // 定时执行的具体任务
logger: ILogger; async exec() {
this.logger.info('清除日志定时任务开始执行');
// 定时执行的具体任务 const startTime = Date.now();
async exec() { await this.baseSysLogService.clear();
this.logger.info('清除日志定时任务开始执行'); this.logger.info(`清除日志定时任务结束,耗时:${Date.now() - startTime}ms`);
const startTime = Date.now(); }
await this.baseSysLogService.clear();
this.logger.info(`清除日志定时任务结束,耗时:${(Date.now() - startTime)}ms`);
}
} }

View File

@ -6,38 +6,37 @@ import { BaseService, CoolPlugin } from 'midwayjs-cool-core';
*/ */
@Provide() @Provide()
export class BasePluginInfoService extends BaseService { export class BasePluginInfoService extends BaseService {
@Inject('cool:coolPlugin')
coolPlugin: CoolPlugin;
@Inject('cool:coolPlugin') /**
coolPlugin: CoolPlugin; *
*/
async list(keyWord) {
return this.coolPlugin.list(keyWord);
}
/** /**
* *
*/ */
async list(keyWord) { async config(namespace: string, config) {
return this.coolPlugin.list(keyWord); await this.coolPlugin.setConfig(namespace, config);
} }
/** /**
* *
*/ * @param namespace
async config(namespace: string, config) { */
await this.coolPlugin.setConfig(namespace, config); async getConfig(namespace: string) {
} return await this.coolPlugin.getConfig(namespace);
}
/** /**
* *
* @param namespace * @param namespace
*/ * @param enable
async getConfig(namespace: string) { */
return await this.coolPlugin.getConfig(namespace); async enable(namespace: string, enable: number) {
} await this.coolPlugin.enable(namespace, enable);
}
/**
*
* @param namespace
* @param enable
*/
async enable(namespace: string, enable: number){
await this.coolPlugin.enable(namespace,enable);
}
} }

View File

@ -9,30 +9,30 @@ import { BaseSysConfEntity } from '../../entity/sys/conf';
*/ */
@Provide() @Provide()
export class BaseSysConfService extends BaseService { export class BaseSysConfService extends BaseService {
@InjectEntityModel(BaseSysConfEntity)
baseSysConfEntity: Repository<BaseSysConfEntity>;
@InjectEntityModel(BaseSysConfEntity) /**
baseSysConfEntity: Repository<BaseSysConfEntity>; *
* @param key
/** */
* async getValue(key) {
* @param key const conf = await this.baseSysConfEntity.findOne({ cKey: key });
*/ if (conf) {
async getValue(key) { return conf.cValue;
const conf = await this.baseSysConfEntity.findOne({ cKey: key });
if (conf) {
return conf.cValue;
}
} }
}
/** /**
* *
* @param cKey * @param cKey
* @param cValue * @param cValue
*/ */
async updateVaule(cKey, cValue) { async updateVaule(cKey, cValue) {
await this.baseSysConfEntity.createQueryBuilder() await this.baseSysConfEntity
.update() .createQueryBuilder()
.set({ cKey, cValue }) .update()
.execute(); .set({ cKey, cValue })
} .execute();
}
} }

View File

@ -13,95 +13,112 @@ import { BaseSysPermsService } from './perms';
*/ */
@Provide() @Provide()
export class BaseSysDepartmentService extends BaseService { export class BaseSysDepartmentService extends BaseService {
@InjectEntityModel(BaseSysDepartmentEntity)
baseSysDepartmentEntity: Repository<BaseSysDepartmentEntity>;
@InjectEntityModel(BaseSysDepartmentEntity) @InjectEntityModel(BaseSysRoleDepartmentEntity)
baseSysDepartmentEntity: Repository<BaseSysDepartmentEntity>; baseSysRoleDepartmentEntity: Repository<BaseSysRoleDepartmentEntity>;
@InjectEntityModel(BaseSysRoleDepartmentEntity) @Inject()
baseSysRoleDepartmentEntity: Repository<BaseSysRoleDepartmentEntity>; baseSysPermsService: BaseSysPermsService;
@Inject() @Inject()
baseSysPermsService: BaseSysPermsService; ctx: Context;
@Inject() /**
ctx: Context; *
*/
async list() {
// 部门权限
const permsDepartmentArr = await this.baseSysPermsService.departmentIds(
this.ctx.admin.userId
);
/** // 过滤部门权限
* const find = this.baseSysDepartmentEntity.createQueryBuilder();
*/ if (this.ctx.admin.username !== 'admin')
async list() { find.andWhere('id in (:ids)', {
// 部门权限 ids: !_.isEmpty(permsDepartmentArr) ? permsDepartmentArr : [null],
const permsDepartmentArr = await this.baseSysPermsService.departmentIds(this.ctx.admin.userId); });
find.addOrderBy('orderNum', 'ASC');
const departments: BaseSysDepartmentEntity[] = await find.getMany();
// 过滤部门权限 if (!_.isEmpty(departments)) {
const find = this.baseSysDepartmentEntity.createQueryBuilder(); departments.forEach(e => {
if (this.ctx.admin.username !== 'admin') find.andWhere('id in (:ids)', { ids: !_.isEmpty(permsDepartmentArr) ? permsDepartmentArr : [null] }); const parentMenu = departments.filter(m => {
find.addOrderBy('orderNum', 'ASC'); e.parentId = parseInt(e.parentId + '');
const departments: BaseSysDepartmentEntity[] = await find.getMany(); if (e.parentId === m.id) {
return m.name;
if (!_.isEmpty(departments)) { }
departments.forEach(e => { });
const parentMenu = departments.filter(m => { if (!_.isEmpty(parentMenu)) {
e.parentId = parseInt(e.parentId + ''); e.parentName = parentMenu[0].name;
if (e.parentId == m.id) {
return m.name;
}
});
if (!_.isEmpty(parentMenu)) {
e.parentName = parentMenu[0].name;
}
});
} }
return departments; });
} }
return departments;
}
/** /**
* ID获得部门权限信息 * ID获得部门权限信息
* @param {[]} roleIds * @param {[]} roleIds
* @param isAdmin * @param isAdmin
*/ */
async getByRoleIds(roleIds: number[], isAdmin) { async getByRoleIds(roleIds: number[], isAdmin) {
if (!_.isEmpty(roleIds)) { if (!_.isEmpty(roleIds)) {
if (isAdmin) { if (isAdmin) {
const result = await this.baseSysDepartmentEntity.find(); const result = await this.baseSysDepartmentEntity.find();
return result.map(e => { return result.map(e => {
return e.id; return e.id;
}); });
} }
const result = await this.baseSysRoleDepartmentEntity.createQueryBuilder().where('roleId in (:roleIds)', { roleIds }).getMany(); const result = await this.baseSysRoleDepartmentEntity
if (!_.isEmpty(result)) { .createQueryBuilder()
return _.uniq(result.map(e => { .where('roleId in (:roleIds)', { roleIds })
return e.departmentId; .getMany();
})); if (!_.isEmpty(result)) {
} return _.uniq(
} result.map(e => {
return []; return e.departmentId;
})
);
}
} }
return [];
}
/** /**
* *
* @param params * @param params
*/ */
async order(params) { async order(params) {
for (const e of params) { for (const e of params) {
await this.baseSysDepartmentEntity.update(e.id, e); await this.baseSysDepartmentEntity.update(e.id, e);
}
} }
}
/** /**
* *
*/ */
async delete(ids: number[]) { async delete(ids: number[]) {
let { deleteUser } = this.ctx.request.body; const { deleteUser } = this.ctx.request.body;
await this.baseSysDepartmentEntity.delete(ids); await this.baseSysDepartmentEntity.delete(ids);
if (deleteUser) { if (deleteUser) {
await this.nativeQuery('delete from base_sys_user where departmentId in (?)', [ids]); await this.nativeQuery(
} else { 'delete from base_sys_user where departmentId in (?)',
const topDepartment = await this.baseSysDepartmentEntity.createQueryBuilder().where('parentId is null').getOne(); [ids]
if (topDepartment) { );
await this.nativeQuery('update base_sys_user a set a.departmentId = ? where a.departmentId in (?)', [topDepartment.id, ids]); } else {
} const topDepartment = await this.baseSysDepartmentEntity
} .createQueryBuilder()
.where('parentId is null')
.getOne();
if (topDepartment) {
await this.nativeQuery(
'update base_sys_user a set a.departmentId = ? where a.departmentId in (?)',
[topDepartment.id, ids]
);
}
} }
}
} }

View File

@ -14,57 +14,63 @@ import { BaseSysConfService } from './conf';
*/ */
@Provide() @Provide()
export class BaseSysLogService extends BaseService { export class BaseSysLogService extends BaseService {
@Inject()
ctx: Context;
@Inject() @Inject()
ctx: Context; utils: Utils;
@Inject() @InjectEntityModel(BaseSysLogEntity)
utils: Utils; baseSysLogEntity: Repository<BaseSysLogEntity>;
@InjectEntityModel(BaseSysLogEntity) @Inject()
baseSysLogEntity: Repository<BaseSysLogEntity>; baseSysConfService: BaseSysConfService;
@Inject() /**
baseSysConfService: BaseSysConfService; *
* @param url URL地址
/** * @param params
* * @param userId ID
* @param url URL地址 */
* @param params async record(context: Context, url, params, userId) {
* @param userId ID const ip = await this.utils.getReqIP(context);
*/ const sysLog = new BaseSysLogEntity();
async record(context: Context, url, params, userId) { sysLog.userId = userId;
const ip = await this.utils.getReqIP(context) sysLog.ip = typeof ip === 'string' ? ip : ip.join(',');
const sysLog = new BaseSysLogEntity(); const ipAddrArr = [];
sysLog.userId = userId; for (const e of sysLog.ip.split(','))
sysLog.ip = typeof ip === 'string' ? ip : ip.join(','); ipAddrArr.push(await await this.utils.getIpAddr(context, e));
const ipAddrArr = new Array(); sysLog.ipAddr = ipAddrArr.join(',');
for (const e of sysLog.ip.split(',')) ipAddrArr.push(await await this.utils.getIpAddr(context, e)); sysLog.action = url;
sysLog.ipAddr = ipAddrArr.join(','); if (!_.isEmpty(params)) {
sysLog.action = url; sysLog.params = JSON.stringify(params);
if (!_.isEmpty(params)) {
sysLog.params = JSON.stringify(params);
}
await this.baseSysLogEntity.insert(sysLog);
} }
await this.baseSysLogEntity.insert(sysLog);
}
/** /**
* *
* @param isAll * @param isAll
*/ */
async clear(isAll?) { async clear(isAll?) {
if (isAll) { if (isAll) {
await this.baseSysLogEntity.clear(); await this.baseSysLogEntity.clear();
return; return;
}
const keepDay = await this.baseSysConfService.getValue('logKeep');
if (keepDay) {
const beforeDate = `${moment().add(-keepDay, 'days').format('YYYY-MM-DD')} 00:00:00`;
await this.baseSysLogEntity.createQueryBuilder()
.where('createTime < :createTime', { createTime: beforeDate })
await this.nativeQuery(' delete from base_sys_log where createTime < ? ', [beforeDate]);
} else {
await this.baseSysLogEntity.clear();
}
} }
const keepDay = await this.baseSysConfService.getValue('logKeep');
if (keepDay) {
const beforeDate = `${moment()
.add(-keepDay, 'days')
.format('YYYY-MM-DD')} 00:00:00`;
await this.baseSysLogEntity
.createQueryBuilder()
.where('createTime < :createTime', { createTime: beforeDate });
await this.nativeQuery(
' delete from base_sys_log where createTime < ? ',
[beforeDate]
);
} else {
await this.baseSysLogEntity.clear();
}
}
} }

View File

@ -1,5 +1,11 @@
import { Inject, Provide, Config } from '@midwayjs/decorator'; import { Inject, Provide, Config } from '@midwayjs/decorator';
import { BaseService, CoolCache, CoolCommException, CoolConfig, RESCODE } from 'midwayjs-cool-core'; import {
BaseService,
CoolCache,
CoolCommException,
CoolConfig,
RESCODE,
} from 'midwayjs-cool-core';
import { LoginDTO } from '../../dto/login'; import { LoginDTO } from '../../dto/login';
import * as svgCaptcha from 'svg-captcha'; import * as svgCaptcha from 'svg-captcha';
import * as svgToDataURL from 'svg-to-dataurl'; import * as svgToDataURL from 'svg-to-dataurl';
@ -20,196 +26,221 @@ import { Context } from 'egg';
*/ */
@Provide() @Provide()
export class BaseSysLoginService extends BaseService { export class BaseSysLoginService extends BaseService {
@Inject('cool:cache')
coolCache: CoolCache;
@Inject('cool:cache') @InjectEntityModel(BaseSysUserEntity)
coolCache: CoolCache; baseSysUserEntity: Repository<BaseSysUserEntity>;
@InjectEntityModel(BaseSysUserEntity) @Inject()
baseSysUserEntity: Repository<BaseSysUserEntity>; baseSysRoleService: BaseSysRoleService;
@Inject() @Inject()
baseSysRoleService: BaseSysRoleService; baseSysMenuService: BaseSysMenuService;
@Inject() @Inject()
baseSysMenuService: BaseSysMenuService; baseSysDepartmentService: BaseSysDepartmentService;
@Inject() @Inject()
baseSysDepartmentService: BaseSysDepartmentService; ctx: Context;
@Inject() @Config('cool')
ctx: Context; coolConfig: CoolConfig;
@Config('cool') /**
coolConfig: CoolConfig; *
* @param login
/** */
* async login(login: LoginDTO) {
* @param login const { username, captchaId, verifyCode, password } = login;
*/ // 校验验证码
async login(login: LoginDTO) { const checkV = await this.captchaCheck(captchaId, verifyCode);
const { username, captchaId, verifyCode, password } = login; if (checkV) {
// 校验验证码 const user = await this.baseSysUserEntity.findOne({ username });
const checkV = await this.captchaCheck(captchaId, verifyCode); // 校验用户
if (checkV) { if (user) {
const user = await this.baseSysUserEntity.findOne({ username }); // 校验用户状态及密码
// 校验用户 if (user.status === 0 || user.password !== md5(password)) {
if (user) { throw new CoolCommException('账户或密码不正确~');
// 校验用户状态及密码
if (user.status === 0 || user.password !== md5(password)) {
throw new CoolCommException('账户或密码不正确~');
}
} else {
throw new CoolCommException('账户或密码不正确~');
}
// 校验角色
const roleIds = await this.baseSysRoleService.getByUser(user.id);
if (_.isEmpty(roleIds)) {
throw new CoolCommException('该用户未设置任何角色,无法登录~');
}
// 生成token
const { expire, refreshExpire } = this.coolConfig.jwt.token;
const result = {
expire,
token: await this.generateToken(user, roleIds, expire),
refreshExpire,
refreshToken: await this.generateToken(user, roleIds, refreshExpire, true),
};
// 将用户相关信息保存到缓存
const perms = await this.baseSysMenuService.getPerms(roleIds);
const departments = await this.baseSysDepartmentService.getByRoleIds(roleIds, user.username === 'admin');
await this.coolCache.set(`admin:department:${user.id}`, JSON.stringify(departments));
await this.coolCache.set(`admin:perms:${user.id}`, JSON.stringify(perms));
await this.coolCache.set(`admin:token:${user.id}`, result.token);
await this.coolCache.set(`admin:token:refresh:${user.id}`, result.token);
return result;
} else {
throw new CoolCommException('验证码不正确');
} }
} } else {
throw new CoolCommException('账户或密码不正确~');
}
// 校验角色
const roleIds = await this.baseSysRoleService.getByUser(user.id);
if (_.isEmpty(roleIds)) {
throw new CoolCommException('该用户未设置任何角色,无法登录~');
}
/** // 生成token
* const { expire, refreshExpire } = this.coolConfig.jwt.token;
* @param type svg const result = {
* @param width expire,
* @param height token: await this.generateToken(user, roleIds, expire),
*/ refreshExpire,
async captcha(type: string, width = 150, height = 50) { refreshToken: await this.generateToken(
const svg = svgCaptcha.create({ user,
ignoreChars: 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM', roleIds,
width, refreshExpire,
height, true
}); ),
};
// 将用户相关信息保存到缓存
const perms = await this.baseSysMenuService.getPerms(roleIds);
const departments = await this.baseSysDepartmentService.getByRoleIds(
roleIds,
user.username === 'admin'
);
await this.coolCache.set(
`admin:department:${user.id}`,
JSON.stringify(departments)
);
await this.coolCache.set(`admin:perms:${user.id}`, JSON.stringify(perms));
await this.coolCache.set(`admin:token:${user.id}`, result.token);
await this.coolCache.set(`admin:token:refresh:${user.id}`, result.token);
return result;
} else {
throw new CoolCommException('验证码不正确');
}
}
/**
*
* @param type svg
* @param width
* @param height
*/
async captcha(type: string, width = 150, height = 50) {
const svg = svgCaptcha.create({
ignoreChars: 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM',
width,
height,
});
const result = {
captchaId: uuid(),
data: svg.data.replace(/"/g, "'"),
};
// 文字变白
const rpList = [
'#111',
'#222',
'#333',
'#444',
'#555',
'#666',
'#777',
'#888',
'#999',
];
rpList.forEach(rp => {
result.data = result.data['replaceAll'](rp, '#fff');
});
if (type === 'base64') {
result.data = svgToDataURL(result.data);
}
// 半小时过期
await this.coolCache.set(
`verify:img:${result.captchaId}`,
svg.text.toLowerCase(),
1800
);
return result;
}
/**
* 退
*/
async logout() {
const { userId } = this.ctx.admin;
await this.coolCache.del(`admin:department:${userId}`);
await this.coolCache.del(`admin:perms:${userId}`);
await this.coolCache.del(`admin:token:${userId}`);
await this.coolCache.del(`admin:token:refresh:${userId}`);
}
/**
*
* @param captchaId ID
* @param value
*/
async captchaCheck(captchaId, value) {
const rv = await this.coolCache.get(`verify:img:${captchaId}`);
if (!rv || !value || value.toLowerCase() !== rv) {
return false;
} else {
this.coolCache.del(`verify:img:${captchaId}`);
return true;
}
}
/**
* token
* @param user
* @param roleIds
* @param expire
* @param isRefresh
*/
async generateToken(user, roleIds, expire, isRefresh?) {
await this.coolCache.set(
`admin:passwordVersion:${user.id}`,
user.passwordV
);
const tokenInfo = {
isRefresh: false,
roleIds,
username: user.username,
userId: user.id,
passwordVersion: user.passwordV,
};
if (isRefresh) {
tokenInfo.isRefresh = true;
}
return jwt.sign(tokenInfo, this.coolConfig.jwt.secret, {
expiresIn: expire,
});
}
/**
* token
* @param token
*/
async refreshToken(token: string) {
try {
const decoded = jwt.verify(token, this.coolConfig.jwt.secret);
if (decoded && decoded['isRefresh']) {
delete decoded['exp'];
delete decoded['iat'];
const { expire, refreshExpire } = this.coolConfig.jwt.token;
decoded['isRefresh'] = false;
const result = { const result = {
captchaId: uuid(), expire,
data: svg.data.replace(/\"/g, "'"), token: jwt.sign(decoded, this.coolConfig.jwt.secret, {
};
// 文字变白
const rpList = ['#111', '#222', '#333', '#444', '#555', '#666', '#777', '#888', '#999'];
rpList.forEach(rp => {
// @ts-ignore
result.data = result.data.replaceAll(rp, '#fff');
});
if (type === 'base64') {
result.data = svgToDataURL(result.data);
}
// 半小时过期
await this.coolCache.set(`verify:img:${result.captchaId}`, svg.text.toLowerCase(), 1800);
return result;
}
/**
* 退
*/
async logout() {
const { userId } = this.ctx.admin;
await this.coolCache.del(`admin:department:${userId}`);
await this.coolCache.del(`admin:perms:${userId}`);
await this.coolCache.del(`admin:token:${userId}`);
await this.coolCache.del(`admin:token:refresh:${userId}`);
}
/**
*
* @param captchaId ID
* @param value
*/
async captchaCheck(captchaId, value) {
const rv = await this.coolCache.get(`verify:img:${captchaId}`);
if (!rv || !value || value.toLowerCase() !== rv) {
return false;
} else {
this.coolCache.del(`verify:img:${captchaId}`);
return true;
}
}
/**
* token
* @param user
* @param roleIds
* @param expire
* @param isRefresh
*/
async generateToken(user, roleIds, expire, isRefresh?) {
await this.coolCache.set(`admin:passwordVersion:${user.id}`, user.passwordV);
const tokenInfo = {
isRefresh: false,
roleIds,
username: user.username,
userId: user.id,
passwordVersion: user.passwordV,
};
if (isRefresh) {
tokenInfo.isRefresh = true;
}
return jwt.sign(tokenInfo,
this.coolConfig.jwt.secret, {
expiresIn: expire, expiresIn: expire,
}),
refreshExpire,
refreshToken: '',
};
decoded['isRefresh'] = true;
result.refreshToken = jwt.sign(decoded, this.coolConfig.jwt.secret, {
expiresIn: refreshExpire,
}); });
await this.coolCache.set(
`admin:passwordVersion:${decoded['userId']}`,
decoded['passwordVersion']
);
return result;
}
} catch (err) {
console.log(err);
this.ctx.status = 401;
this.ctx.body = {
code: RESCODE.COMMFAIL,
message: '登录失效~',
};
return;
} }
}
/**
* token
* @param token
*/
async refreshToken(token: string) {
try {
const decoded = jwt.verify(token, this.coolConfig.jwt.secret);
if (decoded && decoded['isRefresh']) {
delete decoded['exp'];
delete decoded['iat'];
const { expire, refreshExpire } = this.coolConfig.jwt.token;
decoded['isRefresh'] = false;
const result = {
expire,
token: jwt.sign(decoded,
this.coolConfig.jwt.secret, {
expiresIn: expire,
}),
refreshExpire,
refreshToken: '',
};
decoded['isRefresh'] = true;
result.refreshToken = jwt.sign(decoded,
this.coolConfig.jwt.secret, {
expiresIn: refreshExpire,
});
await this.coolCache.set(`admin:passwordVersion:${decoded['userId']}`, decoded['passwordVersion']);
return result;
}
} catch (err) {
console.log(err);
this.ctx.status = 401;
this.ctx.body = {
code: RESCODE.COMMFAIL,
message: '登录失效~',
};
return;
}
}
} }

View File

@ -12,140 +12,155 @@ import { BaseSysPermsService } from './perms';
*/ */
@Provide() @Provide()
export class BaseSysMenuService extends BaseService { export class BaseSysMenuService extends BaseService {
@Inject()
ctx: Context;
@Inject() @InjectEntityModel(BaseSysMenuEntity)
ctx: Context; baseSysMenuEntity: Repository<BaseSysMenuEntity>;
@InjectEntityModel(BaseSysMenuEntity) @Inject()
baseSysMenuEntity: Repository<BaseSysMenuEntity>; baseSysPermsService: BaseSysPermsService;
@Inject() /**
baseSysPermsService: BaseSysPermsService; *
*/
/** async list() {
* const menus = await this.getMenus(
*/ this.ctx.admin.roleIds,
async list() { this.ctx.admin.username === 'admin'
const menus = await this.getMenus(this.ctx.admin.roleIds, this.ctx.admin.username === 'admin'); );
if (!_.isEmpty(menus)) { if (!_.isEmpty(menus)) {
menus.forEach(e => { menus.forEach(e => {
const parentMenu = menus.filter(m => { const parentMenu = menus.filter(m => {
e.parentId = parseInt(e.parentId); e.parentId = parseInt(e.parentId);
if (e.parentId == m.id) { if (e.parentId === m.id) {
return m.name; return m.name;
} }
}); });
if (!_.isEmpty(parentMenu)) { if (!_.isEmpty(parentMenu)) {
e.parentName = parentMenu[0].name; e.parentName = parentMenu[0].name;
}
});
} }
return menus; });
} }
return menus;
}
/** /**
* *
* @param param * @param param
*/ */
async modifyAfter(param) { async modifyAfter(param) {
if (param.id) { if (param.id) {
await this.refreshPerms(param.id); await this.refreshPerms(param.id);
}
} }
}
/** /**
* *
* @param {[]} roleIds * @param {[]} roleIds
*/ */
async getPerms(roleIds) { async getPerms(roleIds) {
let perms = []; let perms = [];
if (!_.isEmpty(roleIds)) { if (!_.isEmpty(roleIds)) {
const result = await this.nativeQuery(` const result = await this.nativeQuery(
SELECT a.perms FROM base_sys_menu a ${this.setSql(!roleIds.includes('1'), `
'JOIN base_sys_role_menu b on a.id = b.menuId AND b.roleId in (?)', [roleIds])} SELECT a.perms FROM base_sys_menu a ${this.setSql(
!roleIds.includes('1'),
'JOIN base_sys_role_menu b on a.id = b.menuId AND b.roleId in (?)',
[roleIds]
)}
where 1=1 and a.perms is not NULL where 1=1 and a.perms is not NULL
`, [roleIds]); `,
if (result) { [roleIds]
result.forEach(d => { );
if (d.perms) { if (result) {
perms = perms.concat(d.perms.split(',')); result.forEach(d => {
} if (d.perms) {
}); perms = perms.concat(d.perms.split(','));
} }
perms = _.uniq(perms); });
perms = _.remove(perms, n => { }
return !_.isEmpty(n); perms = _.uniq(perms);
}); perms = _.remove(perms, n => {
} return !_.isEmpty(n);
return _.uniq(perms); });
} }
return _.uniq(perms);
}
/** /**
* *
* @param roleIds * @param roleIds
* @param isAdmin * @param isAdmin
*/ */
async getMenus(roleIds, isAdmin) { async getMenus(roleIds, isAdmin) {
return await this.nativeQuery(` return await this.nativeQuery(`
SELECT SELECT
a.* a.*
FROM FROM
base_sys_menu a base_sys_menu a
${this.setSql(!isAdmin, 'JOIN base_sys_role_menu b on a.id = b.menuId AND b.roleId in (?)', [roleIds])} ${this.setSql(
!isAdmin,
'JOIN base_sys_role_menu b on a.id = b.menuId AND b.roleId in (?)',
[roleIds]
)}
GROUP BY a.id GROUP BY a.id
ORDER BY ORDER BY
orderNum ASC`); orderNum ASC`);
} }
/** /**
* *
* @param ids * @param ids
*/ */
async delete(ids) { async delete(ids) {
let idArr; let idArr;
if (ids instanceof Array) { if (ids instanceof Array) {
idArr = ids; idArr = ids;
} else { } else {
idArr = ids.split(','); idArr = ids.split(',');
}
for (const id of idArr) {
await this.baseSysMenuEntity.delete({ id });
await this.delChildMenu(id);
}
} }
for (const id of idArr) {
await this.baseSysMenuEntity.delete({ id });
await this.delChildMenu(id);
}
}
/** /**
* *
* @param id * @param id
*/ */
private async delChildMenu(id) { private async delChildMenu(id) {
await this.refreshPerms(id); await this.refreshPerms(id);
const delMenu = await this.baseSysMenuEntity.find({ parentId: id }); const delMenu = await this.baseSysMenuEntity.find({ parentId: id });
if (_.isEmpty(delMenu)) { if (_.isEmpty(delMenu)) {
return; return;
}
const delMenuIds = delMenu.map(e => {
return e.id;
});
await this.baseSysMenuEntity.delete(delMenuIds);
for (const menuId of delMenuIds) {
await this.delChildMenu(menuId);
}
} }
const delMenuIds = delMenu.map(e => {
return e.id;
});
await this.baseSysMenuEntity.delete(delMenuIds);
for (const menuId of delMenuIds) {
await this.delChildMenu(menuId);
}
}
/** /**
* *
* @param menuId * @param menuId
*/ */
async refreshPerms(menuId) { async refreshPerms(menuId) {
const users = await this.nativeQuery('select b.userId from base_sys_role_menu a left join base_sys_user_role b on a.roleId = b.roleId where a.menuId = ? group by b.userId', [menuId]); const users = await this.nativeQuery(
// 刷新admin权限 'select b.userId from base_sys_role_menu a left join base_sys_user_role b on a.roleId = b.roleId where a.menuId = ? group by b.userId',
await this.baseSysPermsService.refreshPerms(1); [menuId]
if (!_.isEmpty(users)) { );
// 刷新其他权限 // 刷新admin权限
for (const user of users) { await this.baseSysPermsService.refreshPerms(1);
await this.baseSysPermsService.refreshPerms(user.userId); if (!_.isEmpty(users)) {
} // 刷新其他权限
} for (const user of users) {
await this.baseSysPermsService.refreshPerms(user.userId);
}
} }
}
} }

View File

@ -9,53 +9,52 @@ import { BaseSysParamEntity } from '../../entity/sys/param';
*/ */
@Provide() @Provide()
export class BaseSysParamService extends BaseService { export class BaseSysParamService extends BaseService {
@InjectEntityModel(BaseSysParamEntity)
baseSysParamEntity: Repository<BaseSysParamEntity>;
@InjectEntityModel(BaseSysParamEntity) @Inject('cool:cache')
baseSysParamEntity: Repository<BaseSysParamEntity>; coolCache: CoolCache;
@Inject('cool:cache') /**
coolCache: CoolCache; * key获得对应的参数
* @param key
/** */
* key获得对应的参数 async dataByKey(key) {
* @param key let result = await this.coolCache.get(`param:${key}`);
*/ if (result) {
async dataByKey (key) { result = JSON.parse(result);
let result = await this.coolCache.get(`param:${ key }`); if (result.dataType !== 0) {
if (result) { return JSON.parse(result.data);
result = JSON.parse(result); } else {
if (result.dataType !== 0) { return result.data;
return JSON.parse(result.data); }
} else {
return result.data;
}
}
return;
} }
return;
}
/** /**
* key获得对应的网页数据 * key获得对应的网页数据
* @param key * @param key
*/ */
async htmlByKey (key) { async htmlByKey(key) {
let html = '<html><body>@content</body></html>'; let html = '<html><body>@content</body></html>';
let result = await this.coolCache.get(`param:${ key }`); let result = await this.coolCache.get(`param:${key}`);
if (result) { if (result) {
result = JSON.parse(result); result = JSON.parse(result);
html = html.replace('@content', result.data); html = html.replace('@content', result.data);
} else { } else {
html = html.replace('@content', 'key notfound'); html = html.replace('@content', 'key notfound');
}
return html;
} }
return html;
}
/** /**
* *
*/ */
async modifyAfter () { async modifyAfter() {
const params = await this.baseSysParamEntity.find(); const params = await this.baseSysParamEntity.find();
for (const param of params) { for (const param of params) {
await this.coolCache.set(`param:${ param.keyName }`, JSON.stringify(param)); await this.coolCache.set(`param:${param.keyName}`, JSON.stringify(param));
}
} }
}
} }

View File

@ -10,57 +10,64 @@ import { Context } from 'egg';
*/ */
@Provide() @Provide()
export class BaseSysPermsService extends BaseService { export class BaseSysPermsService extends BaseService {
@Inject('cool:cache')
coolCache: CoolCache;
@Inject('cool:cache') @Inject()
coolCache: CoolCache; baseSysMenuService: BaseSysMenuService;
@Inject() @Inject()
baseSysMenuService: BaseSysMenuService; baseSysRoleService: BaseSysRoleService;
@Inject() @Inject()
baseSysRoleService: BaseSysRoleService; baseSysDepartmentService: BaseSysDepartmentService;
@Inject() @Inject()
baseSysDepartmentService: BaseSysDepartmentService; ctx: Context;
@Inject() /**
ctx: Context; *
* @param userId ID
*/
async refreshPerms(userId) {
const roleIds = await this.baseSysRoleService.getByUser(userId);
const perms = await this.baseSysMenuService.getPerms(roleIds);
await this.coolCache.set(`admin:perms:${userId}`, JSON.stringify(perms));
// 更新部门权限
const departments = await this.baseSysDepartmentService.getByRoleIds(
roleIds,
this.ctx.admin.username === 'admin'
);
await this.coolCache.set(
`admin:department:${userId}`,
JSON.stringify(departments)
);
}
/**
*
* @param roleIds
*/
async permmenu(roleIds: number[]) {
const perms = await this.baseSysMenuService.getPerms(roleIds);
const menus = await this.baseSysMenuService.getMenus(
roleIds,
this.ctx.admin.username === 'admin'
);
return { perms, menus };
}
/** /**
* * ID获得部门权限
* @param userId ID * @param userId
*/ * @return ID数组
async refreshPerms(userId) { */
const roleIds = await this.baseSysRoleService.getByUser(userId); async departmentIds(userId: number) {
const perms = await this.baseSysMenuService.getPerms(roleIds); const department = await this.coolCache.get(`admin:department:${userId}`);
await this.coolCache.set(`admin:perms:${userId}`, JSON.stringify(perms)); if (department) {
// 更新部门权限 return JSON.parse(department);
const departments = await this.baseSysDepartmentService.getByRoleIds(roleIds, this.ctx.admin.username === 'admin'); } else {
await this.coolCache.set(`admin:department:${userId}`, JSON.stringify(departments)); return [];
}
/**
*
* @param roleIds
*/
async permmenu(roleIds: number[]) {
const perms = await this.baseSysMenuService.getPerms(roleIds);
const menus = await this.baseSysMenuService.getMenus(roleIds, this.ctx.admin.username === 'admin');
return { perms, menus };
}
/**
* ID获得部门权限
* @param userId
* @return ID数组
*/
async departmentIds(userId: number) {
const department = await this.coolCache.get(`admin:department:${userId}`);
if (department) {
return JSON.parse(department);
} else {
return [];
}
} }
}
} }

View File

@ -15,105 +15,112 @@ import { Brackets } from 'typeorm';
*/ */
@Provide() @Provide()
export class BaseSysRoleService extends BaseService { export class BaseSysRoleService extends BaseService {
@InjectEntityModel(BaseSysRoleEntity)
baseSysRoleEntity: Repository<BaseSysRoleEntity>;
@InjectEntityModel(BaseSysRoleEntity) @InjectEntityModel(BaseSysUserRoleEntity)
baseSysRoleEntity: Repository<BaseSysRoleEntity>; baseSysUserRoleEntity: Repository<BaseSysUserRoleEntity>;
@InjectEntityModel(BaseSysUserRoleEntity) @InjectEntityModel(BaseSysRoleMenuEntity)
baseSysUserRoleEntity: Repository<BaseSysUserRoleEntity>; baseSysRoleMenuEntity: Repository<BaseSysRoleMenuEntity>;
@InjectEntityModel(BaseSysRoleMenuEntity) @InjectEntityModel(BaseSysRoleDepartmentEntity)
baseSysRoleMenuEntity: Repository<BaseSysRoleMenuEntity>; baseSysRoleDepartmentEntity: Repository<BaseSysRoleDepartmentEntity>;
@InjectEntityModel(BaseSysRoleDepartmentEntity) @Inject()
baseSysRoleDepartmentEntity: Repository<BaseSysRoleDepartmentEntity>; baseSysPermsService: BaseSysPermsService;
@Inject() /**
baseSysPermsService: BaseSysPermsService; * ID获得所有用户角色
* @param userId
*/
async getByUser(userId: number): Promise<number[]> {
const userRole = await this.baseSysUserRoleEntity.find({ userId });
if (!_.isEmpty(userRole)) {
return userRole.map(e => {
return e.roleId;
});
}
return [];
}
/**
*
* @param param
*/
async modifyAfter(param) {
if (param.id) {
this.updatePerms(param.id, param.menuIdList, param.departmentIdList);
}
}
/** /**
* ID获得所有用户角色 *
* @param userId * @param roleId
*/ * @param menuIdList
async getByUser(userId: number): Promise<number[]> { * @param departmentIds
const userRole = await this.baseSysUserRoleEntity.find({ userId }); */
if (!_.isEmpty(userRole)) { async updatePerms(roleId, menuIdList?, departmentIds = []) {
return userRole.map(e => { // 更新菜单权限
return e.roleId; await this.baseSysRoleMenuEntity.delete({ roleId });
for (const e of menuIdList) {
await this.baseSysRoleMenuEntity.save({ roleId, menuId: e });
}
// 更新部门权限
await this.baseSysRoleDepartmentEntity.delete({ roleId });
for (const departmentId of departmentIds) {
await this.baseSysRoleDepartmentEntity.save({ roleId, departmentId });
}
// 刷新权限
const userRoles = await this.baseSysUserRoleEntity.find({ roleId });
for (const userRole of userRoles) {
await this.baseSysPermsService.refreshPerms(userRole.userId);
}
}
/**
*
* @param id
*/
async info(id) {
const info = await this.baseSysRoleEntity.findOne({ id });
if (info) {
const menus = await this.baseSysRoleMenuEntity.find(
id !== 1 ? { roleId: id } : {}
);
const menuIdList = menus.map(e => {
return parseInt(e.menuId + '');
});
const departments = await this.baseSysRoleDepartmentEntity.find(
id !== 1 ? { roleId: id } : {}
);
const departmentIdList = departments.map(e => {
return parseInt(e.departmentId + '');
});
return {
...info,
menuIdList,
departmentIdList,
};
}
return {};
}
async list() {
return this.baseSysRoleEntity
.createQueryBuilder()
.where(
new Brackets(qb => {
qb.where('id !=:id', { id: 1 }); // 超级管理员的角色不展示
// 如果不是超管,只能看到自己新建的或者自己有的角色
if (this.ctx.admin.username !== 'admin') {
qb.andWhere('(userId=:userId or id in (:roleId))', {
userId: this.ctx.admin.userId,
roleId: this.ctx.admin.roleIds,
}); });
} }
return []; })
} )
.getMany();
/** }
*
* @param param
*/
async modifyAfter(param) {
if (param.id) {
this.updatePerms(param.id, param.menuIdList, param.departmentIdList);
}
}
/**
*
* @param roleId
* @param menuIdList
* @param departmentIds
*/
async updatePerms(roleId, menuIdList?, departmentIds = []) {
// 更新菜单权限
await this.baseSysRoleMenuEntity.delete({ roleId });
for (const e of menuIdList) {
await this.baseSysRoleMenuEntity.save({ roleId, menuId: e });
}
// 更新部门权限
await this.baseSysRoleDepartmentEntity.delete({ roleId });
for (const departmentId of departmentIds) {
await this.baseSysRoleDepartmentEntity.save({ roleId, departmentId });
}
// 刷新权限
const userRoles = await this.baseSysUserRoleEntity.find({ roleId });
for (const userRole of userRoles) {
await this.baseSysPermsService.refreshPerms(userRole.userId);
}
}
/**
*
* @param id
*/
async info(id) {
const info = await this.baseSysRoleEntity.findOne({ id });
if (info) {
const menus = await this.baseSysRoleMenuEntity.find(id !== 1 ? { roleId: id } : {});
const menuIdList = menus.map(e => {
return parseInt(e.menuId + '');
});
const departments = await this.baseSysRoleDepartmentEntity.find(id !== 1 ? { roleId: id } : {});
const departmentIdList = departments.map(e => {
return parseInt(e.departmentId + '');
});
return {
...info,
menuIdList,
departmentIdList,
};
}
return {};
}
async list() {
return this.baseSysRoleEntity.createQueryBuilder().where(new Brackets(qb => {
qb.where('id !=:id', { id: 1 }); // 超级管理员的角色不展示
// 如果不是超管,只能看到自己新建的或者自己有的角色
if (this.ctx.admin.username !== 'admin') {
qb.andWhere('(userId=:userId or id in (:roleId))', {
userId: this.ctx.admin.userId,
roleId: this.ctx.admin.roleIds,
});
}
})).getMany();
}
} }

View File

@ -14,30 +14,31 @@ import { BaseSysDepartmentEntity } from '../../entity/sys/department';
*/ */
@Provide() @Provide()
export class BaseSysUserService extends BaseService { export class BaseSysUserService extends BaseService {
@InjectEntityModel(BaseSysUserEntity)
baseSysUserEntity: Repository<BaseSysUserEntity>;
@InjectEntityModel(BaseSysUserEntity) @InjectEntityModel(BaseSysUserRoleEntity)
baseSysUserEntity: Repository<BaseSysUserEntity>; baseSysUserRoleEntity: Repository<BaseSysUserRoleEntity>;
@InjectEntityModel(BaseSysUserRoleEntity) @InjectEntityModel(BaseSysDepartmentEntity)
baseSysUserRoleEntity: Repository<BaseSysUserRoleEntity>; baseSysDepartmentEntity: Repository<BaseSysDepartmentEntity>;
@InjectEntityModel(BaseSysDepartmentEntity) @Inject('cool:cache')
baseSysDepartmentEntity: Repository<BaseSysDepartmentEntity>; coolCache: CoolCache;
@Inject('cool:cache') @Inject()
coolCache: CoolCache; baseSysPermsService: BaseSysPermsService;
@Inject() /**
baseSysPermsService: BaseSysPermsService; *
* @param query
/** */
* async page(query) {
* @param query const { keyWord, status, departmentIds = [] } = query;
*/ const permsDepartmentArr = await this.baseSysPermsService.departmentIds(
async page(query) { this.ctx.admin.userId
const { keyWord, status, departmentIds = [] } = query; ); // 部门权限
const permsDepartmentArr = await this.baseSysPermsService.departmentIds(this.ctx.admin.userId); // 部门权限 const sql = `
const sql = `
SELECT SELECT
a.id,a.name,a.nickName,a.headImg,a.email,a.remark,a.status,a.createTime,a.updateTime,a.username,a.phone,a.departmentId, a.id,a.name,a.nickName,a.headImg,a.email,a.remark,a.status,a.createTime,a.updateTime,a.username,a.phone,a.departmentId,
GROUP_CONCAT(c.name) AS roleName, GROUP_CONCAT(c.name) AS roleName,
@ -48,145 +49,171 @@ export class BaseSysUserService extends BaseService {
LEFT JOIN base_sys_role c ON b.roleId = c.id LEFT JOIN base_sys_role c ON b.roleId = c.id
LEFT JOIN base_sys_department d on a.departmentId = d.id LEFT JOIN base_sys_department d on a.departmentId = d.id
WHERE 1 = 1 WHERE 1 = 1
${this.setSql(!_.isEmpty(departmentIds), 'and a.departmentId in (?)', [departmentIds])} ${this.setSql(
!_.isEmpty(departmentIds),
'and a.departmentId in (?)',
[departmentIds]
)}
${this.setSql(status, 'and a.status = ?', [status])} ${this.setSql(status, 'and a.status = ?', [status])}
${this.setSql(keyWord, 'and (a.name LIKE ? or a.username LIKE ?)', [`%${keyWord}%`, `%${keyWord}%`])} ${this.setSql(keyWord, 'and (a.name LIKE ? or a.username LIKE ?)', [
`%${keyWord}%`,
`%${keyWord}%`,
])}
${this.setSql(true, 'and a.username != ?', ['admin'])} ${this.setSql(true, 'and a.username != ?', ['admin'])}
${this.setSql(this.ctx.admin.username !== 'admin', 'and a.departmentId in (?)', [!_.isEmpty(permsDepartmentArr) ? permsDepartmentArr : [null]])} ${this.setSql(
this.ctx.admin.username !== 'admin',
'and a.departmentId in (?)',
[!_.isEmpty(permsDepartmentArr) ? permsDepartmentArr : [null]]
)}
GROUP BY a.id GROUP BY a.id
`; `;
return this.sqlRenderPage(sql, query); return this.sqlRenderPage(sql, query);
}
/**
*
* @param departmentId
* @param userIds
*/
async move(departmentId, userIds) {
await this.baseSysUserEntity
.createQueryBuilder()
.update()
.set({ departmentId })
.where('id in (:userIds)', { userIds })
.execute();
}
/**
*
*/
async person() {
const info = await this.baseSysUserEntity.findOne({
id: this.ctx.admin.userId,
});
delete info.password;
return info;
}
/**
*
* @param user
*/
async updateUserRole(user) {
if (user.username === 'admin') {
throw new CoolCommException('非法操作~');
} }
await this.baseSysUserRoleEntity.delete({ userId: user.id });
/** if (user.roleIdList) {
* for (const roleId of user.roleIdList) {
* @param departmentId await this.baseSysUserRoleEntity.save({ userId: user.id, roleId });
* @param userIds }
*/
async move(departmentId, userIds) {
await this.baseSysUserEntity.createQueryBuilder()
.update().set({ departmentId })
.where('id in (:userIds)', { userIds })
.execute();
} }
await this.baseSysPermsService.refreshPerms(user.id);
}
/** /**
* *
*/ * @param param
async person() { */
const info = await this.baseSysUserEntity.findOne({ id: this.ctx.admin.userId }); async add(param) {
delete info.password; const exists = await this.baseSysUserEntity.findOne({
return info; username: param.username,
});
if (!_.isEmpty(exists)) {
throw new CoolCommException('用户名已经存在~');
} }
param.password = md5('123456'); // 默认密码 建议未改密码不能登陆
await this.baseSysUserEntity.save(param);
await this.updateUserRole(param);
return param.id;
}
/** /**
* * ID获得信息
* @param user * @param id
*/ */
async updateUserRole(user) { public async info(id) {
if (user.username === 'admin') { const info = await this.baseSysUserEntity.findOne({ id });
throw new CoolCommException('非法操作~'); const userRoles = await this.nativeQuery(
} 'select a.roleId from base_sys_user_role a where a.userId = ?',
await this.baseSysUserRoleEntity.delete({ userId: user.id }); [id]
if (user.roleIdList) { );
for (const roleId of user.roleIdList) { const department = await this.baseSysDepartmentEntity.findOne({
await this.baseSysUserRoleEntity.save({ userId: user.id, roleId }); id: info.departmentId,
} });
} if (info) {
await this.baseSysPermsService.refreshPerms(user.id); delete info.password;
if (userRoles) {
info.roleIdList = userRoles.map(e => {
return parseInt(e.roleId);
});
}
} }
delete info.password;
/** if (department) {
* info.departmentName = department.name;
* @param param
*/
async add(param) {
const exists = await this.baseSysUserEntity.findOne({ username: param.username });
if (!_.isEmpty(exists)) {
throw new CoolCommException('用户名已经存在~');
}
param.password = md5('123456'); // 默认密码 建议未改密码不能登陆
await this.baseSysUserEntity.save(param);
await this.updateUserRole(param);
return param.id;
} }
return info;
}
/** /**
* ID获得信息 *
* @param id * @param param
*/ */
public async info (id) { public async personUpdate(param) {
const info = await this.baseSysUserEntity.findOne({ id }); param.id = this.ctx.admin.userId;
const userRoles = await this.nativeQuery('select a.roleId from base_sys_user_role a where a.userId = ?', [ id ]); if (!_.isEmpty(param.password)) {
const department = await this.baseSysDepartmentEntity.findOne({ id: info.departmentId }); param.password = md5(param.password);
if (info) { const userInfo = await this.baseSysUserEntity.findOne({ id: param.id });
delete info.password; if (!userInfo) {
if (userRoles) { throw new CoolCommException('用户不存在');
info.roleIdList = userRoles.map(e => { }
return parseInt(e.roleId); param.passwordV = userInfo.passwordV + 1;
}); await this.coolCache.set(
} `admin:passwordVersion:${param.id}`,
} param.passwordV
delete info.password; );
if (department) { } else {
info.departmentName = department.name; delete param.password;
}
return info;
} }
await this.baseSysUserEntity.save(param);
}
/** /**
* *
* @param param * @param param
*/ */
public async personUpdate (param) { async update(param) {
param.id = this.ctx.admin.userId; if (param.id && param.username === 'admin') {
if (!_.isEmpty(param.password)) { throw new CoolCommException('非法操作~');
param.password = md5(param.password);
const userInfo = await this.baseSysUserEntity.findOne({ id: param.id });
if (!userInfo) {
throw new CoolCommException('用户不存在');
}
param.passwordV = userInfo.passwordV + 1;
await this.coolCache.set(`admin:passwordVersion:${param.id}`, param.passwordV);
} else {
delete param.password;
}
await this.baseSysUserEntity.save(param);
} }
if (!_.isEmpty(param.password)) {
/** param.password = md5(param.password);
* const userInfo = await this.ctx.repo.sys.User.findOne({ id: param.id });
* @param param if (!userInfo) {
*/ throw new CoolCommException('用户不存在');
async update(param) { }
if (param.id && param.username === 'admin') { param.passwordV = userInfo.passwordV + 1;
throw new CoolCommException('非法操作~'); await this.coolCache.set(
} `admin:passwordVersion:${param.id}`,
if (!_.isEmpty(param.password)) { param.passwordV
param.password = md5(param.password); );
const userInfo = await this.ctx.repo.sys.User.findOne({ id: param.id }); } else {
if (!userInfo) { delete param.password;
throw new CoolCommException('用户不存在');
}
param.passwordV = userInfo.passwordV + 1;
await this.coolCache.set(`admin:passwordVersion:${param.id}`, param.passwordV);
} else {
delete param.password;
}
if (param.status === 0) {
await this.forbidden(param.id);
}
await this.baseSysUserEntity.save(param);
await this.updateUserRole(param);
} }
if (param.status === 0) {
/** await this.forbidden(param.id);
*
* @param userId
*/
async forbidden(userId) {
await this.coolCache.del(`admin:token:${userId}`);
} }
await this.baseSysUserEntity.save(param);
await this.updateUserRole(param);
}
/**
*
* @param userId
*/
async forbidden(userId) {
await this.coolCache.del(`admin:token:${userId}`);
}
} }

View File

@ -11,10 +11,9 @@ import { BaseSysMenuEntity } from '../../../base/entity/sys/menu';
@Provide() @Provide()
@CoolController({ @CoolController({
api: ['add', 'delete', 'update', 'info', 'list', 'page'], api: ['add', 'delete', 'update', 'info', 'list', 'page'],
entity: DemoAppGoodsEntity entity: DemoAppGoodsEntity,
}) })
export class DemoAppGoodsController extends BaseController { export class DemoAppGoodsController extends BaseController {
@InjectEntityModel(BaseSysMenuEntity) @InjectEntityModel(BaseSysMenuEntity)
baseSysMenuEntity: Repository<BaseSysMenuEntity>; baseSysMenuEntity: Repository<BaseSysMenuEntity>;
@ -22,15 +21,15 @@ export class DemoAppGoodsController extends BaseController {
async 123() { async 123() {
const ms = await this.baseSysMenuEntity.find(); const ms = await this.baseSysMenuEntity.find();
for (const item of ms) { for (const item of ms) {
if(item.perms){ if (item.perms) {
let a = item.perms.split(',') let a = item.perms.split(',');
a = a.map(e=>{ a = a.map(e => {
return 'base:'+e; return 'base:' + e;
}) });
item.perms = a.join(',') item.perms = a.join(',');
this.baseSysMenuEntity.update(item.id, item) this.baseSysMenuEntity.update(item.id, item);
} }
} }
return this.ok(122) return this.ok(122);
} }
} }

View File

@ -7,14 +7,12 @@ import { Column } from 'typeorm';
*/ */
@EntityModel('demo_app_goods') @EntityModel('demo_app_goods')
export class DemoAppGoodsEntity extends BaseEntity { export class DemoAppGoodsEntity extends BaseEntity {
@Column({ comment: '标题' })
title: string;
@Column({ comment: '标题' }) @Column({ comment: '图片' })
title: string; pic: string;
@Column({ comment: '图片' })
pic: string;
@Column({ comment: '价格', type: 'decimal', precision: 5, scale: 2 })
price: number;
@Column({ comment: '价格', type: 'decimal', precision: 5, scale: 2 })
price: number;
} }

View File

@ -0,0 +1,16 @@
import { Application } from 'egg';
import { ModuleConfig } from 'midwayjs-cool-core';
/**
*
*/
export default (app: Application) => {
return {
// 模块名称
name: '文件空间',
// 模块描述
description: '上传和管理文件资源',
// 中间件
middlewares: [],
} as ModuleConfig;
};

View File

@ -1,18 +1,16 @@
import { Provide } from '@midwayjs/decorator'; import { Provide } from '@midwayjs/decorator';
import { CoolController, BaseController } from 'midwayjs-cool-core'; import { CoolController, BaseController } from 'midwayjs-cool-core';
import { BaseAppSpaceInfoEntity } from '../../../../entity/app/space/info'; import { BaseAppSpaceInfoEntity } from '../../../base/entity/app/space/info';
/** /**
* *
*/ */
@Provide() @Provide()
@CoolController({ @CoolController({
api: ['add', 'delete', 'update', 'info', 'list', 'page'], api: ['add', 'delete', 'update', 'info', 'list', 'page'],
entity: BaseAppSpaceInfoEntity, entity: BaseAppSpaceInfoEntity,
pageQueryOp: { pageQueryOp: {
fieldEq: ['type', 'classifyId'] fieldEq: ['type', 'classifyId'],
} },
}) })
export class BaseAppSpaceInfoController extends BaseController { export class BaseAppSpaceInfoController extends BaseController {}
}

View File

@ -1,15 +1,13 @@
import { Provide } from '@midwayjs/decorator'; import { Provide } from '@midwayjs/decorator';
import { CoolController, BaseController } from 'midwayjs-cool-core'; import { CoolController, BaseController } from 'midwayjs-cool-core';
import { BaseAppSpaceTypeEntity } from '../../../../entity/app/space/type'; import { BaseAppSpaceTypeEntity } from '../../../base/entity/app/space/type';
/** /**
* *
*/ */
@Provide() @Provide()
@CoolController({ @CoolController({
api: ['add', 'delete', 'update', 'info', 'list', 'page'], api: ['add', 'delete', 'update', 'info', 'list', 'page'],
entity: BaseAppSpaceTypeEntity entity: BaseAppSpaceTypeEntity,
}) })
export class BaseAppSpaceTypeController extends BaseController { export class BaseAppSpaceTypeController extends BaseController {}
}

View File

@ -0,0 +1 @@
编写接口

View File

@ -0,0 +1,18 @@
import { EntityModel } from '@midwayjs/orm';
import { BaseEntity } from 'midwayjs-cool-core';
import { Column } from 'typeorm';
/**
*
*/
@EntityModel('base_app_space_info')
export class BaseAppSpaceInfoEntity extends BaseEntity {
@Column({ comment: '地址' })
url: string;
@Column({ comment: '类型' })
type: string;
@Column({ comment: '分类ID', type: 'bigint', nullable: true })
classifyId: number;
}

View File

@ -0,0 +1,15 @@
import { EntityModel } from '@midwayjs/orm';
import { BaseEntity } from 'midwayjs-cool-core';
import { Column } from 'typeorm';
/**
*
*/
@EntityModel('base_app_space_type')
export class BaseAppSpaceTypeEntity extends BaseEntity {
@Column({ comment: '类别名称' })
name: string;
@Column({ comment: '父分类ID', type: 'tinyint', nullable: true })
parentId: number;
}

View File

@ -1,13 +1,12 @@
const duration = 0.8;
let duration = 0.8; const delay = 0.3;
let delay = 0.3; const revealText = document.querySelector('.reveal');
let revealText = document.querySelector(".reveal"); const letters = revealText.textContent.split('');
let letters = revealText.textContent.split(""); revealText.textContent = '';
revealText.textContent = ""; const middle = letters.filter(e => e !== ' ').length / 2;
let middle = letters.filter(e => e !== " ").length / 2;
letters.forEach((letter, i) => { letters.forEach((letter, i) => {
let span = document.createElement("span"); const span = document.createElement('span');
span.textContent = letter; span.textContent = letter;
span.style.animationDelay = `${delay + Math.abs(i - middle) * 0.1}s`; span.style.animationDelay = `${delay + Math.abs(i - middle) * 0.1}s`;
revealText.append(span); revealText.append(span);
}); });

View File

@ -14,9 +14,7 @@ export default (appInfo: EggAppInfo) => {
// 模板渲染 用法 https://nunjucks.bootcss.com // 模板渲染 用法 https://nunjucks.bootcss.com
config.view = { config.view = {
root: [ root: [path.join(appInfo.baseDir, 'app/view')].join(','),
path.join(appInfo.baseDir, 'app/view'),
].join(','),
defaultViewEngine: 'nunjucks', defaultViewEngine: 'nunjucks',
defaultExtension: '.html', defaultExtension: '.html',
mapping: { mapping: {
@ -37,7 +35,9 @@ export default (appInfo: EggAppInfo) => {
// 修改默认的 favicon.ico // 修改默认的 favicon.ico
config.siteFile = { config.siteFile = {
'/favicon.ico': fs.readFileSync(path.join(appInfo.baseDir, 'app/public/favicon.ico')), '/favicon.ico': fs.readFileSync(
path.join(appInfo.baseDir, 'app/public/favicon.ico')
),
}; };
// 关闭安全校验 // 关闭安全校验
@ -51,7 +51,7 @@ export default (appInfo: EggAppInfo) => {
config.cool = { config.cool = {
// 全局路由前缀 // 全局路由前缀
router: { router: {
prefix: '' prefix: '',
}, },
// 单点登录 // 单点登录
sso: false, sso: false,
@ -64,7 +64,7 @@ export default (appInfo: EggAppInfo) => {
// 2小时过期需要用刷新token // 2小时过期需要用刷新token
expire: 2 * 3600, expire: 2 * 3600,
// 15天内如果没操作过就需要重新登录 // 15天内如果没操作过就需要重新登录
refreshExpire: 24 * 3600 * 15 refreshExpire: 24 * 3600 * 15,
}, },
}, },
// 分页配置 // 分页配置
@ -75,20 +75,20 @@ export default (appInfo: EggAppInfo) => {
// 文件上传 // 文件上传
file: { file: {
// 文件路径前缀 本地上传模式下 有效 // 文件路径前缀 本地上传模式下 有效
domain: 'https://cool-admin.cn.utools.club' domain: 'https://admin.cn.utools.club',
} },
} };
// 文件上传 // 文件上传
config.multipart = { config.multipart = {
fileSize: '100mb', fileSize: '100mb',
mode: 'file' mode: 'file',
}; };
// 将egg日志替换成midway // 将egg日志替换成midway
config.midwayFeature = { config.midwayFeature = {
replaceEggLogger: true replaceEggLogger: true,
} };
return config; return config;
}; };

View File

@ -3,26 +3,26 @@ import { EggAppConfig, EggAppInfo, PowerPartial } from 'egg';
export type DefaultConfig = PowerPartial<EggAppConfig>; export type DefaultConfig = PowerPartial<EggAppConfig>;
export default (appInfo: EggAppInfo) => { export default (appInfo: EggAppInfo) => {
const config = {} as DefaultConfig; const config = {} as DefaultConfig;
config.orm = { config.orm = {
type: 'mysql', type: 'mysql',
host: '127.0.0.1', host: '127.0.0.1',
port: 3306, port: 3306,
username: 'root', username: 'root',
password: '123123', password: '123123',
database: 'cool', database: 'cool',
// 自动建表 注意:线上部署的时候不要使用,有可能导致数据丢失 // 自动建表 注意:线上部署的时候不要使用,有可能导致数据丢失
synchronize: true, synchronize: true,
// 打印日志 // 打印日志
logging: true, logging: true,
} };
config.logger = { config.logger = {
coreLogger: { coreLogger: {
consoleLevel: 'INFO' consoleLevel: 'INFO',
} },
} };
return config; return config;
}; };

View File

@ -3,26 +3,26 @@ import { EggAppConfig, EggAppInfo, PowerPartial } from 'egg';
export type DefaultConfig = PowerPartial<EggAppConfig>; export type DefaultConfig = PowerPartial<EggAppConfig>;
export default (appInfo: EggAppInfo) => { export default (appInfo: EggAppInfo) => {
const config = {} as DefaultConfig; const config = {} as DefaultConfig;
config.orm = { config.orm = {
type: 'mysql', type: 'mysql',
host: '127.0.0.1', host: '127.0.0.1',
port: 3306, port: 3306,
username: 'root', username: 'root',
password: '123123', password: '123123',
database: 'cool-admin-next', database: 'cool-admin-next',
// 自动建表 注意:线上部署的时候不要使用,有可能导致数据丢失 // 自动建表 注意:线上部署的时候不要使用,有可能导致数据丢失
synchronize: false, synchronize: false,
// 打印日志 // 打印日志
logging: false, logging: false,
} };
config.logger = { config.logger = {
coreLogger: { coreLogger: {
consoleLevel: 'ERROR' consoleLevel: 'ERROR',
} },
} };
return config; return config;
}; };

View File

@ -6,5 +6,5 @@ export default {
nunjucks: { nunjucks: {
enable: true, enable: true,
package: 'egg-view-nunjucks', package: 'egg-view-nunjucks',
} },
} as EggPlugin; } as EggPlugin;

View File

@ -3,6 +3,7 @@ import { ILifeCycle, IMidwayContainer } from '@midwayjs/core';
import { Application } from 'egg'; import { Application } from 'egg';
import * as orm from '@midwayjs/orm'; import * as orm from '@midwayjs/orm';
import * as cool from 'midwayjs-cool-core'; import * as cool from 'midwayjs-cool-core';
import * as redis from 'midwayjs-cool-redis';
@Configuration({ @Configuration({
// 注意组件顺序 cool 有依赖orm组件 所以必须放在orm组件之后 cool的其他组件必须放在cool 核心组件之后 // 注意组件顺序 cool 有依赖orm组件 所以必须放在orm组件之后 cool的其他组件必须放在cool 核心组件之后
@ -10,20 +11,17 @@ import * as cool from 'midwayjs-cool-core';
// 必须,不可移除, https://typeorm.io 打不开? https://typeorm.biunav.com/zh/ // 必须,不可移除, https://typeorm.io 打不开? https://typeorm.biunav.com/zh/
orm, orm,
// 必须,不可移除, cool-admin 官方组件 https://www.cool-js.com // 必须,不可移除, cool-admin 官方组件 https://www.cool-js.com
cool cool,
] redis,
],
}) })
export class ContainerLifeCycle implements ILifeCycle { export class ContainerLifeCycle implements ILifeCycle {
@App() @App()
app: Application; app: Application;
// 应用启动完成 // 应用启动完成
async onReady(container?: IMidwayContainer) { async onReady(container?: IMidwayContainer) {
console.log(container.baseDir) console.log(container.baseDir);
} }
// 应用停止 // 应用停止
async onStop() { async onStop() {}
}
} }

View File

@ -8,12 +8,11 @@ import { CoolController, BaseController } from 'midwayjs-cool-core';
@Provide() @Provide()
@CoolController('/') @CoolController('/')
export class WelcomeController extends BaseController { export class WelcomeController extends BaseController {
@Inject()
ctx: Context;
@Inject() @Get('/')
ctx: Context; public async welcome() {
await this.ctx.render('welcome', { text: 'HELLO COOL-ADMIN' });
@Get('/') }
public async welcome () {
await this.ctx.render('welcome', { text: 'HELLO COOL-ADMIN' });
}
} }