feat: menu device
This commit is contained in:
parent
2df310b1c0
commit
563c08c233
|
@ -40,3 +40,9 @@ export enum HasInventoryStatusEnum {
|
||||||
Yes = 1, // 有库存
|
Yes = 1, // 有库存
|
||||||
No = 2 // 无库存
|
No = 2 // 无库存
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 权限资源设备类型
|
||||||
|
export enum ResourceDeviceEnum {
|
||||||
|
APP = 0,
|
||||||
|
PC = 1
|
||||||
|
}
|
||||||
|
|
|
@ -132,8 +132,8 @@ export class AuthService {
|
||||||
/**
|
/**
|
||||||
* 获取菜单列表
|
* 获取菜单列表
|
||||||
*/
|
*/
|
||||||
async getMenus(uid: number): Promise<string[]> {
|
async getMenus(uid: number, isApp: number): Promise<string[]> {
|
||||||
return this.menuService.getMenus(uid);
|
return this.menuService.getMenus(uid,isApp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -14,6 +14,8 @@ import { UserService } from '../../user/user.service';
|
||||||
import { AuthService } from '../auth.service';
|
import { AuthService } from '../auth.service';
|
||||||
import { AccountMenus, AccountUpdateDto } from '../dto/account.dto';
|
import { AccountMenus, AccountUpdateDto } from '../dto/account.dto';
|
||||||
import { JwtAuthGuard } from '../guards/jwt-auth.guard';
|
import { JwtAuthGuard } from '../guards/jwt-auth.guard';
|
||||||
|
import { IsMobile } from '~/common/decorators/http.decorator';
|
||||||
|
import { ResourceDeviceEnum } from '~/constants/enum';
|
||||||
|
|
||||||
@ApiTags('Account - 账户模块')
|
@ApiTags('Account - 账户模块')
|
||||||
@ApiSecurityAuth()
|
@ApiSecurityAuth()
|
||||||
|
@ -45,8 +47,11 @@ export class AccountController {
|
||||||
@ApiOperation({ summary: '获取菜单列表' })
|
@ApiOperation({ summary: '获取菜单列表' })
|
||||||
@ApiResult({ type: [AccountMenus] })
|
@ApiResult({ type: [AccountMenus] })
|
||||||
@AllowAnon()
|
@AllowAnon()
|
||||||
async menu(@AuthUser() user: IAuthUser): Promise<string[]> {
|
async menu(@AuthUser() user: IAuthUser, @IsMobile() isApp: boolean): Promise<string[]> {
|
||||||
return this.authService.getMenus(user.uid);
|
return this.authService.getMenus(
|
||||||
|
user.uid,
|
||||||
|
isApp ? ResourceDeviceEnum.APP : ResourceDeviceEnum.PC
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('permissions')
|
@Get('permissions')
|
||||||
|
|
|
@ -53,6 +53,9 @@ export class MaterialsInOutDto {
|
||||||
inOrOut: MaterialsInOrOutEnum;
|
inOrOut: MaterialsInOrOutEnum;
|
||||||
|
|
||||||
@ApiProperty({ description: '时间' })
|
@ApiProperty({ description: '时间' })
|
||||||
|
@Transform(params => {
|
||||||
|
return params.value ? new Date(params.value) : null;
|
||||||
|
})
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
time: Date;
|
time: Date;
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,8 @@ import {
|
||||||
import { MenuDto, MenuQueryDto, MenuUpdateDto } from './menu.dto';
|
import { MenuDto, MenuQueryDto, MenuUpdateDto } from './menu.dto';
|
||||||
import { MenuItemInfo } from './menu.model';
|
import { MenuItemInfo } from './menu.model';
|
||||||
import { MenuService } from './menu.service';
|
import { MenuService } from './menu.service';
|
||||||
|
import { IsMobile } from '~/common/decorators/http.decorator';
|
||||||
|
import { ResourceDeviceEnum } from '~/constants/enum';
|
||||||
|
|
||||||
export const permissions = definePermission('system:menu', {
|
export const permissions = definePermission('system:menu', {
|
||||||
LIST: 'list',
|
LIST: 'list',
|
||||||
|
@ -43,7 +45,9 @@ export class MenuController {
|
||||||
@ApiResult({ type: [MenuItemInfo] })
|
@ApiResult({ type: [MenuItemInfo] })
|
||||||
@Perm(permissions.LIST)
|
@Perm(permissions.LIST)
|
||||||
async list(@Query() dto: MenuQueryDto) {
|
async list(@Query() dto: MenuQueryDto) {
|
||||||
return this.menuService.list(dto);
|
return this.menuService.list({
|
||||||
|
...dto
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
|
|
|
@ -3,6 +3,7 @@ import {
|
||||||
IsBoolean,
|
IsBoolean,
|
||||||
IsIn,
|
IsIn,
|
||||||
IsInt,
|
IsInt,
|
||||||
|
IsNumber,
|
||||||
IsOptional,
|
IsOptional,
|
||||||
IsString,
|
IsString,
|
||||||
Min,
|
Min,
|
||||||
|
@ -15,6 +16,11 @@ export class MenuDto {
|
||||||
@IsIn([0, 1, 2])
|
@IsIn([0, 1, 2])
|
||||||
type: number;
|
type: number;
|
||||||
|
|
||||||
|
@ApiProperty({ description: '客户端设备类型' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsIn([0, 1])
|
||||||
|
device: number;
|
||||||
|
|
||||||
@ApiProperty({ description: '父级菜单' })
|
@ApiProperty({ description: '父级菜单' })
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
parentId: number;
|
parentId: number;
|
||||||
|
@ -85,4 +91,11 @@ export class MenuDto {
|
||||||
|
|
||||||
export class MenuUpdateDto extends PartialType(MenuDto) {}
|
export class MenuUpdateDto extends PartialType(MenuDto) {}
|
||||||
|
|
||||||
export class MenuQueryDto extends PartialType(MenuDto) {}
|
export class MenuQueryDto extends PartialType(MenuDto) {
|
||||||
|
|
||||||
|
@ApiProperty({ description: 'App端的菜单权限' })
|
||||||
|
@IsNumber()
|
||||||
|
@IsOptional()
|
||||||
|
isApp?: number;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -6,28 +6,28 @@ import { RoleEntity } from '../role/role.entity';
|
||||||
|
|
||||||
@Entity({ name: 'sys_menu' })
|
@Entity({ name: 'sys_menu' })
|
||||||
export class MenuEntity extends CommonEntity {
|
export class MenuEntity extends CommonEntity {
|
||||||
@Column({ name: 'parent_id', nullable: true })
|
@Column({ name: 'parent_id', nullable: true, comment: '父级ID' })
|
||||||
parentId: number;
|
parentId: number;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
name: string;
|
name: string;
|
||||||
|
|
||||||
@Column({ nullable: true })
|
@Column({ nullable: true, comment: '前端路径' })
|
||||||
path: string;
|
path: string;
|
||||||
|
|
||||||
@Column({ nullable: true })
|
@Column({ nullable: true, comment: '权限' })
|
||||||
permission: string;
|
permission: string;
|
||||||
|
|
||||||
@Column({ type: 'tinyint', default: 0 })
|
@Column({ type: 'tinyint', default: 0, comment: '类型:0-目录 1-菜单 2-权限' })
|
||||||
type: number;
|
type: number;
|
||||||
|
|
||||||
@Column({ nullable: true, default: '' })
|
@Column({ nullable: true, default: '', comment: '图标' })
|
||||||
icon: string;
|
icon: string;
|
||||||
|
|
||||||
@Column({ name: 'order_no', type: 'int', nullable: true, default: 0 })
|
@Column({ name: 'order_no', type: 'int', nullable: true, default: 0 })
|
||||||
orderNo: number;
|
orderNo: number;
|
||||||
|
|
||||||
@Column({ name: 'component', nullable: true })
|
@Column({ name: 'component', nullable: true, comment: '前端组件文件地址' })
|
||||||
component: string;
|
component: string;
|
||||||
|
|
||||||
@Column({ name: 'is_ext', type: 'boolean', default: false })
|
@Column({ name: 'is_ext', type: 'boolean', default: false })
|
||||||
|
@ -48,6 +48,9 @@ export class MenuEntity extends CommonEntity {
|
||||||
@Column({ type: 'tinyint', default: 1 })
|
@Column({ type: 'tinyint', default: 1 })
|
||||||
status: number;
|
status: number;
|
||||||
|
|
||||||
|
@Column({ type: 'tinyint', default: 1,comment: '用户端类型:0-APP 1-PC' })
|
||||||
|
device: number;
|
||||||
|
|
||||||
@ManyToMany(() => RoleEntity, role => role.menus, {
|
@ManyToMany(() => RoleEntity, role => role.menus, {
|
||||||
onDelete: 'CASCADE'
|
onDelete: 'CASCADE'
|
||||||
})
|
})
|
||||||
|
|
|
@ -18,6 +18,7 @@ import { deleteEmptyChildren, generatorMenu, generatorRouters } from '~/utils';
|
||||||
import { RoleService } from '../role/role.service';
|
import { RoleService } from '../role/role.service';
|
||||||
|
|
||||||
import { MenuDto, MenuQueryDto, MenuUpdateDto } from './menu.dto';
|
import { MenuDto, MenuQueryDto, MenuUpdateDto } from './menu.dto';
|
||||||
|
import { ResourceDeviceEnum } from '~/constants/enum';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MenuService {
|
export class MenuService {
|
||||||
|
@ -32,7 +33,14 @@ export class MenuService {
|
||||||
/**
|
/**
|
||||||
* 获取所有菜单以及权限
|
* 获取所有菜单以及权限
|
||||||
*/
|
*/
|
||||||
async list({ name, path, permission, component, status }: MenuQueryDto): Promise<MenuEntity[]> {
|
async list({
|
||||||
|
name,
|
||||||
|
path,
|
||||||
|
permission,
|
||||||
|
component,
|
||||||
|
status,
|
||||||
|
isApp
|
||||||
|
}: MenuQueryDto): Promise<MenuEntity[]> {
|
||||||
const menus = await this.menuRepository.find({
|
const menus = await this.menuRepository.find({
|
||||||
where: {
|
where: {
|
||||||
...(name && { name: Like(`%${name}%`) }),
|
...(name && { name: Like(`%${name}%`) }),
|
||||||
|
@ -66,20 +74,29 @@ export class MenuService {
|
||||||
/**
|
/**
|
||||||
* 根据角色获取所有菜单
|
* 根据角色获取所有菜单
|
||||||
*/
|
*/
|
||||||
async getMenus(uid: number): Promise<string[]> {
|
async getMenus(uid: number, deviceType: number): Promise<string[]> {
|
||||||
const roleIds = await this.roleService.getRoleIdsByUser(uid);
|
const roleIds = await this.roleService.getRoleIdsByUser(uid);
|
||||||
let menus: MenuEntity[] = [];
|
let menus: MenuEntity[] = [];
|
||||||
|
|
||||||
if (isEmpty(roleIds)) return generatorRouters([]);
|
if (isEmpty(roleIds)) return generatorRouters([]);
|
||||||
|
|
||||||
if (this.roleService.hasAdminRole(roleIds)) {
|
if (this.roleService.hasAdminRole(roleIds)) {
|
||||||
menus = await this.menuRepository.find({ order: { orderNo: 'ASC' } });
|
menus = await this.menuRepository.find({
|
||||||
|
order: { orderNo: 'ASC' },
|
||||||
|
where: {
|
||||||
|
...(isNumber(deviceType) ? { device: deviceType } : null)
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
menus = await this.menuRepository
|
menus = await this.menuRepository
|
||||||
.createQueryBuilder('menu')
|
.createQueryBuilder('menu')
|
||||||
.innerJoinAndSelect('menu.roles', 'role')
|
.innerJoinAndSelect('menu.roles', 'role')
|
||||||
|
.where({
|
||||||
|
...(isNumber(deviceType) ? { device: deviceType } : null)
|
||||||
|
})
|
||||||
.andWhere('role.id IN (:...roleIds)', { roleIds })
|
.andWhere('role.id IN (:...roleIds)', { roleIds })
|
||||||
.orderBy('menu.order_no', 'ASC')
|
.orderBy('menu.order_no', 'ASC')
|
||||||
|
|
||||||
.getMany();
|
.getMany();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,4 +35,9 @@ export class RoleQueryDto extends IntersectionType(PagerDto<RoleDto>, PartialTyp
|
||||||
@IsInt()
|
@IsInt()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
status?: number;
|
status?: number;
|
||||||
|
|
||||||
|
@ApiProperty({ description: '用于下拉框选择', required: false })
|
||||||
|
@IsInt()
|
||||||
|
@IsOptional()
|
||||||
|
useForSelect: number;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,14 +32,17 @@ export class RoleService {
|
||||||
pageSize,
|
pageSize,
|
||||||
name,
|
name,
|
||||||
value,
|
value,
|
||||||
status
|
status,
|
||||||
|
useForSelect
|
||||||
}: RoleQueryDto): Promise<Pagination<RoleEntity>> {
|
}: RoleQueryDto): Promise<Pagination<RoleEntity>> {
|
||||||
const queryBuilder = this.roleRepository.createQueryBuilder('role').where({
|
const queryBuilder = this.roleRepository.createQueryBuilder('role').where({
|
||||||
...(name ? { name: Like(`%${name}%`) } : null),
|
...(name ? { name: Like(`%${name}%`) } : null),
|
||||||
...(value ? { value: Like(`%${value}%`) } : null),
|
...(value ? { value: Like(`%${value}%`) } : null),
|
||||||
...(isNumber(status) ? { status } : null)
|
...(isNumber(status) ? { status } : null)
|
||||||
});
|
});
|
||||||
|
if(useForSelect){
|
||||||
|
queryBuilder.andWhere('role.id != :id', { id: ROOT_ROLE_ID })
|
||||||
|
}
|
||||||
return paginate<RoleEntity>(queryBuilder, {
|
return paginate<RoleEntity>(queryBuilder, {
|
||||||
page,
|
page,
|
||||||
pageSize
|
pageSize
|
||||||
|
|
|
@ -268,7 +268,13 @@ export class UserService {
|
||||||
if (keyword) {
|
if (keyword) {
|
||||||
//关键字模糊查询product的name,productNumber,productSpecification
|
//关键字模糊查询product的name,productNumber,productSpecification
|
||||||
queryBuilder.andWhere(
|
queryBuilder.andWhere(
|
||||||
'(user.nickname like :keyword or user.namePinyin like :keyword or dept.name like :keyword)',
|
`(user.nickname like :keyword or user.namePinyin like :keyword
|
||||||
|
or dept.name like :keyword
|
||||||
|
or user.phone like :keyword
|
||||||
|
or user.email like :keyword
|
||||||
|
or user.qq like :keyword
|
||||||
|
or user.remark like :keyword
|
||||||
|
)`,
|
||||||
{
|
{
|
||||||
keyword: `%${keyword}%`
|
keyword: `%${keyword}%`
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue