diff --git a/.gitignore b/.gitignore index 13bc3a6..3c95265 100755 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ run/ *.un~ .tsbuildinfo .tsbuildinfo.* +src/app/public/uploads/ diff --git a/src/app/modules/base/controller/admin/comm.ts b/src/app/modules/base/controller/admin/comm.ts index 49c3db0..eef228b 100644 --- a/src/app/modules/base/controller/admin/comm.ts +++ b/src/app/modules/base/controller/admin/comm.ts @@ -1,6 +1,6 @@ import { Provide, Inject, Get, Post, Body, ALL } from '@midwayjs/decorator'; import { Context } from 'egg'; -import { CoolController, BaseController } from 'midwayjs-cool-core'; +import { CoolController, BaseController, CoolFile } from 'midwayjs-cool-core'; import { BaseSysUserEntity } from '../../entity/sys/user'; import { BaseSysPermsService } from '../../service/sys/perms'; import { BaseSysUserService } from '../../service/sys/user'; @@ -21,11 +21,14 @@ export class BaseCommController extends BaseController { @Inject() ctx: Context; + @Inject('cool:file') + coolFile: CoolFile; + /** * 获得个人信息 */ @Get('/person') - public async person() { + async person() { return this.ok(await this.baseSysUserService.person()); } @@ -33,7 +36,7 @@ export class BaseCommController extends BaseController { * 修改个人信息 */ @Post('/personUpdate') - public async personUpdate(@Body(ALL) user: BaseSysUserEntity) { + async personUpdate(@Body(ALL) user: BaseSysUserEntity) { await this.baseSysUserService.personUpdate(user); return this.ok(); } @@ -42,8 +45,24 @@ export class BaseCommController extends BaseController { * 权限菜单 */ @Get('/permmenu') - public async permmenu() { + async permmenu() { return this.ok(await this.baseSysPermsService.permmenu(this.ctx.admin.roleIds)); } + /** + * 文件上传 + */ + @Post('/upload') + async upload() { + return this.ok(await this.coolFile.upload(this.ctx)); + } + + /** + * 文件上传模式,本地或者云存储 + */ + @Get('/uploadMode') + async uploadMode() { + return this.ok(this.coolFile.getMode()); + } + } \ No newline at end of file diff --git a/src/app/modules/base/entity/sys/menu.ts b/src/app/modules/base/entity/sys/menu.ts index 5619c0c..dc34eeb 100644 --- a/src/app/modules/base/entity/sys/menu.ts +++ b/src/app/modules/base/entity/sys/menu.ts @@ -41,4 +41,7 @@ export class BaseSysMenuEntity extends BaseEntity { @Column({ comment: '父菜单名称', default: true }) isShow: boolean; + @Column({ comment: '模块名', nullable: true }) + moduleName: string; + } \ No newline at end of file diff --git a/src/app/modules/base/entity/sys/role.ts b/src/app/modules/base/entity/sys/role.ts index 0abb972..08dfa61 100644 --- a/src/app/modules/base/entity/sys/role.ts +++ b/src/app/modules/base/entity/sys/role.ts @@ -22,4 +22,7 @@ export class BaseSysRoleEntity extends BaseEntity { @Column({ comment: '备注', nullable: true }) remark: string; + @Column({ comment: '数据权限是否关联上下级', default: 1 }) + relevance: number; + } \ No newline at end of file diff --git a/src/app/modules/base/entity/sys/role_menu.ts b/src/app/modules/base/entity/sys/role_menu.ts new file mode 100644 index 0000000..12dd273 --- /dev/null +++ b/src/app/modules/base/entity/sys/role_menu.ts @@ -0,0 +1,17 @@ +import { EntityModel } from '@midwayjs/orm'; +import { BaseEntity } from 'midwayjs-cool-core'; +import { Column } from 'typeorm'; + +/** + * 角色菜单 + */ +@EntityModel('base_sys_role_menu') +export class BaseSysRoleMenuEntity extends BaseEntity { + + @Column({ comment: '角色ID', type: 'bigint' }) + roleId: number; + + @Column({ comment: '菜单ID', type: 'bigint' }) + menuId: number; + +} \ No newline at end of file diff --git a/src/app/modules/base/service/sys/department.ts b/src/app/modules/base/service/sys/department.ts index 1fb8da1..bcdb7e4 100644 --- a/src/app/modules/base/service/sys/department.ts +++ b/src/app/modules/base/service/sys/department.ts @@ -31,17 +31,18 @@ export class BaseSysDepartmentService extends BaseService { */ async list() { // 部门权限 - const permsDepartmentArr = await this.baseSysPermsService.departmentIds(this.ctx.admin.userId); + const permsDepartmentArr = await this.baseSysPermsService.departmentIds(this.ctx.admin.userId); // 过滤部门权限 const find = this.baseSysDepartmentEntity.createQueryBuilder(); if (this.ctx.admin.username !== 'admin') find.andWhere('id in (:ids)', { ids: !_.isEmpty(permsDepartmentArr) ? permsDepartmentArr : [null] }); find.addOrderBy('orderNum', 'ASC'); const departments: BaseSysDepartmentEntity[] = await find.getMany(); - + if (!_.isEmpty(departments)) { departments.forEach(e => { const parentMenu = departments.filter(m => { + e.parentId = parseInt(e.parentId + ''); if (e.parentId == m.id) { return m.name; } diff --git a/src/app/modules/base/service/sys/login.ts b/src/app/modules/base/service/sys/login.ts index 6d66af1..0f725d0 100644 --- a/src/app/modules/base/service/sys/login.ts +++ b/src/app/modules/base/service/sys/login.ts @@ -187,6 +187,7 @@ export class BaseSysLoginService extends BaseService { this.coolConfig.jwt.secret, { expiresIn: refreshExpire, }); + await this.coolCache.set(`admin:passwordVersion:${decoded['userId']}`, decoded['passwordVersion']); return result; } } catch (err) { diff --git a/src/app/modules/base/service/sys/menu.ts b/src/app/modules/base/service/sys/menu.ts index a867e18..888059d 100644 --- a/src/app/modules/base/service/sys/menu.ts +++ b/src/app/modules/base/service/sys/menu.ts @@ -5,6 +5,7 @@ import { Repository } from 'typeorm'; import { BaseSysMenuEntity } from '../../entity/sys/menu'; import * as _ from 'lodash'; import { Context } from 'egg'; +import { BaseSysPermsService } from './perms'; /** * 菜单 @@ -18,6 +19,9 @@ export class BaseSysMenuService extends BaseService { @InjectEntityModel(BaseSysMenuEntity) baseSysMenuEntity: Repository; + @Inject() + baseSysPermsService: BaseSysPermsService; + /** * 获得所有菜单 */ @@ -26,7 +30,8 @@ export class BaseSysMenuService extends BaseService { if (!_.isEmpty(menus)) { menus.forEach(e => { const parentMenu = menus.filter(m => { - if (e.parentId === m.id) { + e.parentId = parseInt(e.parentId); + if (e.parentId == m.id) { return m.name; } }); @@ -135,11 +140,11 @@ export class BaseSysMenuService extends BaseService { 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]); // 刷新admin权限 - await this.ctx.service.sys.perms.refreshPerms(1); + await this.baseSysPermsService.refreshPerms(1); if (!_.isEmpty(users)) { // 刷新其他权限 for (const user of users) { - await this.ctx.service.sys.perms.refreshPerms(user.userId); + await this.baseSysPermsService.refreshPerms(user.userId); } } } diff --git a/src/app/modules/base/service/sys/role.ts b/src/app/modules/base/service/sys/role.ts index 312844c..b926805 100644 --- a/src/app/modules/base/service/sys/role.ts +++ b/src/app/modules/base/service/sys/role.ts @@ -1,10 +1,14 @@ -import { Provide } from '@midwayjs/decorator'; +import { Inject, Provide } from '@midwayjs/decorator'; import { BaseService } from 'midwayjs-cool-core'; import { InjectEntityModel } from '@midwayjs/orm'; import { Repository } from 'typeorm'; import { BaseSysRoleEntity } from '../../entity/sys/role'; import { BaseSysUserRoleEntity } from '../../entity/sys/user_role'; import * as _ from 'lodash'; +import { BaseSysRoleMenuEntity } from '../../entity/sys/role_menu'; +import { BaseSysRoleDepartmentEntity } from '../../entity/sys/role_department'; +import { BaseSysPermsService } from './perms'; +import { Brackets } from 'typeorm'; /** * 角色 @@ -18,6 +22,16 @@ export class BaseSysRoleService extends BaseService { @InjectEntityModel(BaseSysUserRoleEntity) baseSysUserRoleEntity: Repository; + @InjectEntityModel(BaseSysRoleMenuEntity) + baseSysRoleMenuEntity: Repository; + + @InjectEntityModel(BaseSysRoleDepartmentEntity) + baseSysRoleDepartmentEntity: Repository; + + @Inject() + baseSysPermsService: BaseSysPermsService; + + /** * 根据用户ID获得所有用户角色 * @param userId @@ -31,4 +45,75 @@ export class BaseSysRoleService extends BaseService { } return []; } + + /** + * + * @param param + */ + async modifyAfter(param) { + if (param.id) { + await 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(); + } } \ No newline at end of file diff --git a/src/app/modules/base/service/sys/user.ts b/src/app/modules/base/service/sys/user.ts index e0aacca..e1b0cce 100644 --- a/src/app/modules/base/service/sys/user.ts +++ b/src/app/modules/base/service/sys/user.ts @@ -35,7 +35,7 @@ export class BaseSysUserService extends BaseService { * @param query */ async page(query) { - const { keyWord, status, departmentIds = '' } = query; + const { keyWord, status, departmentIds = [] } = query; const permsDepartmentArr = await this.baseSysPermsService.departmentIds(this.ctx.admin.userId); // 部门权限 const sql = ` SELECT diff --git a/src/config/config.default.ts b/src/config/config.default.ts index e2a884f..2bf59ab 100644 --- a/src/config/config.default.ts +++ b/src/config/config.default.ts @@ -62,7 +62,7 @@ export default (appInfo: EggAppInfo) => { // token token: { // 2小时过期,需要用刷新token - expire: 2 * 3600, + expire: 2 * 5, // 15天内,如果没操作过就需要重新登录 refreshExpire: 24 * 3600 * 15 }, @@ -71,7 +71,12 @@ export default (appInfo: EggAppInfo) => { page: { // 分页查询每页条数 size: 15, - } + }, + // 文件上传 + file: { + // 文件路径前缀 本地上传模式下 有效 + domain: 'https://cool-admin.cn.utools.club' + } } // 文件上传